-- v4: mshtml: Implement Cycle Collection for XMLHttpRequest. mshtml: Implement Cycle Collection for HTMLPerformanceTiming. mshtml: Move PerformanceTiming related fields to the window. mshtml: Move HTMLPerformanceNavigation related fields to the window. mshtml: Implement Cycle Collection for inner windows. mshtml: Get rid of NULL checks for the dispex vtbl. mshtml: Implement Cycle Collection for outer windows. mshtml: Implement Cycle Collection for HTMLLocation. mshtml: Separate the HTMLLocation from the outer window. mshtml: Actually traverse the object-specific edges.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 33e01e8a81c..e31f364491d 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -2023,6 +2023,9 @@ static nsresult NSAPI dispex_traverse(void *ccp, void *p, nsCycleCollectionTrave
describe_cc_node(&This->ccref, This->info->desc->name, cb);
+ if(This->info->desc->vtbl->traverse) + This->info->desc->vtbl->traverse(This, cb); + if(!This->dynamic_data) return NS_OK;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmllocation.c | 50 +++++++++++++++++++++++++----------- dlls/mshtml/htmlwindow.c | 32 +++++++++++++++-------- dlls/mshtml/mshtml_private.h | 8 ++++-- 3 files changed, 62 insertions(+), 28 deletions(-)
diff --git a/dlls/mshtml/htmllocation.c b/dlls/mshtml/htmllocation.c index 02f503969db..35446c57bd3 100644 --- a/dlls/mshtml/htmllocation.c +++ b/dlls/mshtml/htmllocation.c @@ -36,19 +36,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
-static inline HTMLOuterWindow *get_window(HTMLLocation *This) -{ - return CONTAINING_RECORD(This, HTMLOuterWindow, location); -} - static IUri *get_uri(HTMLLocation *This) { - return get_window(This)->uri; + return This->window->uri; }
static HRESULT get_url_components(HTMLLocation *This, URL_COMPONENTSW *url) { - const WCHAR *doc_url = get_window(This)->url ? get_window(This)->url : L"about:blank"; + const WCHAR *doc_url = This->window->url ? This->window->url : L"about:blank";
if(!InternetCrackUrlW(doc_url, 0, 0, url)) { FIXME("InternetCrackUrlW failed: 0x%08lx\n", GetLastError()); @@ -93,13 +88,27 @@ static HRESULT WINAPI HTMLLocation_QueryInterface(IHTMLLocation *iface, REFIID r static ULONG WINAPI HTMLLocation_AddRef(IHTMLLocation *iface) { HTMLLocation *This = impl_from_IHTMLLocation(iface); - return IHTMLWindow2_AddRef(&get_window(This)->base.IHTMLWindow2_iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%ld\n", This, ref); + + return ref; }
static ULONG WINAPI HTMLLocation_Release(IHTMLLocation *iface) { HTMLLocation *This = impl_from_IHTMLLocation(iface); - return IHTMLWindow2_Release(&get_window(This)->base.IHTMLWindow2_iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%ld\n", This, ref); + + if(!ref) { + IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); + release_dispex(&This->dispex); + free(This); + } + + return ref; }
static HRESULT WINAPI HTMLLocation_GetTypeInfoCount(IHTMLLocation *iface, UINT *pctinfo) @@ -139,7 +148,7 @@ static HRESULT WINAPI HTMLLocation_put_href(IHTMLLocation *iface, BSTR v)
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
- return navigate_url(get_window(This), v, get_uri(This), BINDING_NAVIGATED); + return navigate_url(This->window, v, get_uri(This), BINDING_NAVIGATED); }
static HRESULT WINAPI HTMLLocation_get_href(IHTMLLocation *iface, BSTR *p) @@ -500,7 +509,7 @@ static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v) memcpy(hash + 1, v, size - sizeof(WCHAR)); }
- hres = navigate_url(get_window(This), hash, get_uri(This), BINDING_NAVIGATED); + hres = navigate_url(This->window, hash, get_uri(This), BINDING_NAVIGATED);
if(hash != v) free(hash); @@ -544,12 +553,12 @@ static HRESULT WINAPI HTMLLocation_reload(IHTMLLocation *iface, VARIANT_BOOL fla TRACE("(%p)->(%x)\n", This, flag);
/* reload is supposed to fail if called from a script with different origin, but IE doesn't care */ - if(!is_main_content_window(get_window(This))) { + if(!is_main_content_window(This->window)) { FIXME("Unsupported on iframe\n"); return E_NOTIMPL; }
- return reload_page(get_window(This)); + return reload_page(This->window); }
static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr) @@ -558,7 +567,7 @@ static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr)
TRACE("(%p)->(%s)\n", This, debugstr_w(bstr));
- return navigate_url(get_window(This), bstr, get_uri(This), BINDING_NAVIGATED | BINDING_REPLACE); + return navigate_url(This->window, bstr, get_uri(This), BINDING_NAVIGATED | BINDING_REPLACE); }
static HRESULT WINAPI HTMLLocation_assign(IHTMLLocation *iface, BSTR bstr) @@ -618,10 +627,21 @@ static dispex_static_data_t HTMLLocation_dispex = { HTMLLocation_iface_tids };
-void HTMLLocation_Init(HTMLLocation *location) +HRESULT create_location(HTMLOuterWindow *window, HTMLLocation **ret) { + HTMLLocation *location; + + if(!(location = calloc(1, sizeof(*location)))) + return E_OUTOFMEMORY; + location->IHTMLLocation_iface.lpVtbl = &HTMLLocationVtbl; + location->ref = 1; + location->window = window; + IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
init_dispatch(&location->dispex, (IUnknown*)&location->IHTMLLocation_iface, &HTMLLocation_dispex, COMPAT_MODE_QUIRKS); + + *ret = location; + return S_OK; } diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index c1a258651cf..7c40ca83188 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -62,13 +62,17 @@ HTMLOuterWindow *mozwindow_to_window(const mozIDOMWindowProxy *mozwindow) return entry ? WINE_RB_ENTRY_VALUE(entry, HTMLOuterWindow, entry) : NULL; }
-static void get_location(HTMLOuterWindow *This, HTMLLocation **ret) +static HRESULT get_location(HTMLOuterWindow *This, HTMLLocation **ret) { - if(!This->location.dispex.outer) - HTMLLocation_Init(&This->location); + if(!This->location) { + HRESULT hres = create_location(This, &This->location); + if(FAILED(hres)) + return hres; + }
- IHTMLLocation_AddRef(&This->location.IHTMLLocation_iface); - *ret = &This->location; + IHTMLLocation_AddRef(&This->location->IHTMLLocation_iface); + *ret = This->location; + return S_OK; }
void get_top_window(HTMLOuterWindow *window, HTMLOuterWindow **ret) @@ -122,8 +126,8 @@ static void detach_inner_window(HTMLInnerWindow *window) if(doc) detach_document_node(doc);
- if(outer_window && outer_window->location.dispex.outer) - dispex_props_unlink(&outer_window->location.dispex); + if(outer_window && outer_window->location) + dispex_props_unlink(&outer_window->location->dispex);
abort_window_bindings(window); remove_target_tasks(window->task_magic); @@ -283,8 +287,8 @@ static void release_outer_window(HTMLOuterWindow *This) if(This->base.inner_window) detach_inner_window(This->base.inner_window);
- if(This->location.dispex.outer) - release_dispex(&This->location.dispex); + if(This->location) + IHTMLLocation_Release(&This->location->IHTMLLocation_iface);
if(This->frame_element) This->frame_element->content_window = NULL; @@ -779,10 +783,14 @@ static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocatio { HTMLWindow *This = impl_from_IHTMLWindow2(iface); HTMLLocation *location; + HRESULT hres;
TRACE("(%p)->(%p)\n", This, p);
- get_location(This->outer_window, &location); + hres = get_location(This->outer_window, &location); + if(FAILED(hres)) + return hres; + *p = &location->IHTMLLocation_iface; return S_OK; } @@ -4080,7 +4088,9 @@ static HRESULT IHTMLWindow2_location_hook(DispatchEx *dispex, WORD flags, DISPPA
TRACE("forwarding to location.href\n");
- get_location(This->base.outer_window, &location); + hres = get_location(This->base.outer_window, &location); + if(FAILED(hres)) + return hres;
hres = IDispatchEx_InvokeEx(&location->dispex.IDispatchEx_iface, DISPID_VALUE, 0, flags, dp, res, ei, caller); IHTMLLocation_Release(&location->IHTMLLocation_iface); diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 5d117d70e29..757bc0feb79 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -521,6 +521,10 @@ typedef struct { struct HTMLLocation { DispatchEx dispex; IHTMLLocation IHTMLLocation_iface; + + LONG ref; + + HTMLOuterWindow *window; };
typedef struct { @@ -599,7 +603,7 @@ struct HTMLOuterWindow { BOOL readystate_pending;
HTMLInnerWindow *pending_window; - HTMLLocation location; + HTMLLocation *location; IMoniker *mon; IUri *uri; IUri *uri_nofrag; @@ -1013,7 +1017,7 @@ void get_top_window(HTMLOuterWindow*,HTMLOuterWindow**); HRESULT HTMLOptionElementFactory_Create(HTMLInnerWindow*,HTMLOptionElementFactory**); HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow*,HTMLImageElementFactory**); HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow*,HTMLXMLHttpRequestFactory**); -void HTMLLocation_Init(HTMLLocation*); +HRESULT create_location(HTMLOuterWindow*,HTMLLocation**); HRESULT create_navigator(compat_mode_t,IOmNavigator**); HRESULT create_html_screen(compat_mode_t,IHTMLScreen**); HRESULT create_performance(HTMLInnerWindow*,IHTMLPerformance**);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmllocation.c | 49 ++++++++++++++++++++++++++++-------- dlls/mshtml/mshtml_private.h | 2 -- 2 files changed, 38 insertions(+), 13 deletions(-)
diff --git a/dlls/mshtml/htmllocation.c b/dlls/mshtml/htmllocation.c index 35446c57bd3..5941c383db4 100644 --- a/dlls/mshtml/htmllocation.c +++ b/dlls/mshtml/htmllocation.c @@ -73,7 +73,7 @@ static HRESULT WINAPI HTMLLocation_QueryInterface(IHTMLLocation *iface, REFIID r *ppv = NULL; FIXME("(%p)->(IID_IMarshal %p)\n", This, ppv); return E_NOINTERFACE; - }else if(dispex_query_interface_no_cc(&This->dispex, riid, ppv)) { + }else if(dispex_query_interface(&This->dispex, riid, ppv)) { return *ppv ? S_OK : E_NOINTERFACE; }else { *ppv = NULL; @@ -88,7 +88,7 @@ static HRESULT WINAPI HTMLLocation_QueryInterface(IHTMLLocation *iface, REFIID r static ULONG WINAPI HTMLLocation_AddRef(IHTMLLocation *iface) { HTMLLocation *This = impl_from_IHTMLLocation(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ref_incr(&This->dispex);
TRACE("(%p) ref=%ld\n", This, ref);
@@ -98,16 +98,10 @@ static ULONG WINAPI HTMLLocation_AddRef(IHTMLLocation *iface) static ULONG WINAPI HTMLLocation_Release(IHTMLLocation *iface) { HTMLLocation *This = impl_from_IHTMLLocation(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ref_decr(&This->dispex);
TRACE("(%p) ref=%ld\n", This, ref);
- if(!ref) { - IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -616,13 +610,47 @@ static const IHTMLLocationVtbl HTMLLocationVtbl = { HTMLLocation_toString };
+static inline HTMLLocation *impl_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLLocation, dispex); +} + +static void HTMLLocation_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLLocation *This = impl_from_DispatchEx(dispex); + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); +} + +static void HTMLLocation_unlink(DispatchEx *dispex) +{ + HTMLLocation *This = impl_from_DispatchEx(dispex); + if(This->window) { + HTMLOuterWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } +} + +static void HTMLLocation_destructor(DispatchEx *dispex) +{ + HTMLLocation *This = impl_from_DispatchEx(dispex); + free(This); +} + +static const dispex_static_data_vtbl_t HTMLLocation_dispex_vtbl = { + .destructor = HTMLLocation_destructor, + .traverse = HTMLLocation_traverse, + .unlink = HTMLLocation_unlink +}; + static const tid_t HTMLLocation_iface_tids[] = { IHTMLLocation_tid, 0 }; static dispex_static_data_t HTMLLocation_dispex = { "Location", - NULL, + &HTMLLocation_dispex_vtbl, DispHTMLLocation_tid, HTMLLocation_iface_tids }; @@ -635,7 +663,6 @@ HRESULT create_location(HTMLOuterWindow *window, HTMLLocation **ret) return E_OUTOFMEMORY;
location->IHTMLLocation_iface.lpVtbl = &HTMLLocationVtbl; - location->ref = 1; location->window = window; IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 757bc0feb79..05203c53897 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -522,8 +522,6 @@ struct HTMLLocation { DispatchEx dispex; IHTMLLocation IHTMLLocation_iface;
- LONG ref; - HTMLOuterWindow *window; };
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 129 ++++++++++++++++++++++++----------- dlls/mshtml/mshtml_private.h | 2 + dlls/mshtml/nsembed.c | 1 + 3 files changed, 93 insertions(+), 39 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 7c40ca83188..5619eb6e7c9 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -45,6 +45,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
+static ExternalCycleCollectionParticipant outer_window_ccp; + static int window_map_compare(const void *key, const struct wine_rb_entry *entry) { HTMLOuterWindow *window = WINE_RB_ENTRY_VALUE(entry, HTMLOuterWindow, entry); @@ -255,62 +257,37 @@ static HRESULT WINAPI outer_window_QueryInterface(IHTMLWindow2 *iface, REFIID ri if(hres != S_FALSE) return hres;
- return EventTarget_QI_no_cc(&This->base.inner_window->event_target, riid, ppv); + if(IsEqualGUID(&IID_nsXPCOMCycleCollectionParticipant, riid)) { + *ppv = &outer_window_ccp; + return S_OK; + }else if(IsEqualGUID(&IID_nsCycleCollectionISupports, riid)) { + *ppv = &This->base.IHTMLWindow2_iface; + return S_OK; + }else { + return EventTarget_QI_no_cc(&This->base.inner_window->event_target, riid, ppv); + } }
static ULONG WINAPI outer_window_AddRef(IHTMLWindow2 *iface) { HTMLOuterWindow *This = HTMLOuterWindow_from_IHTMLWindow2(iface); - LONG ref = InterlockedIncrement(&This->base.ref); + LONG ref = ccref_incr(&This->ccref, (nsISupports*)&This->base.IHTMLWindow2_iface);
TRACE("(%p) ref=%ld\n", This, ref);
return ref; }
-static void release_outer_window(HTMLOuterWindow *This) -{ - if(This->browser) { - list_remove(&This->browser_entry); - This->browser = NULL; - } - - if(This->pending_window) { - abort_window_bindings(This->pending_window); - This->pending_window->base.outer_window = NULL; - IHTMLWindow2_Release(&This->pending_window->base.IHTMLWindow2_iface); - } - - remove_target_tasks(This->task_magic); - set_current_mon(This, NULL, 0); - set_current_uri(This, NULL); - if(This->base.inner_window) - detach_inner_window(This->base.inner_window); - - if(This->location) - IHTMLLocation_Release(&This->location->IHTMLLocation_iface); - - if(This->frame_element) - This->frame_element->content_window = NULL; - - if(This->nswindow) - nsIDOMWindow_Release(This->nswindow); - if(This->window_proxy) - mozIDOMWindowProxy_Release(This->window_proxy); - - wine_rb_remove(&window_map, &This->entry); - free(This); -} - static ULONG WINAPI outer_window_Release(IHTMLWindow2 *iface) { HTMLOuterWindow *This = HTMLOuterWindow_from_IHTMLWindow2(iface); - LONG ref = InterlockedDecrement(&This->base.ref); + LONG task_magic = This->task_magic; + LONG ref = ccref_decr(&This->ccref, (nsISupports*)&This->base.IHTMLWindow2_iface, &outer_window_ccp);
TRACE("(%p) ref=%ld\n", This, ref);
if(!ref) - release_outer_window(This); + remove_target_tasks(task_magic);
return ref; } @@ -4198,6 +4175,79 @@ static dispex_static_data_t HTMLWindow_dispex = { HTMLWindow_init_dispex_info };
+static nsresult NSAPI outer_window_traverse(void *ccp, void *p, nsCycleCollectionTraversalCallback *cb) +{ + HTMLOuterWindow *window = HTMLOuterWindow_from_IHTMLWindow2(p); + + describe_cc_node(&window->ccref, "OuterWindow", cb); + + if(window->pending_window) + note_cc_edge((nsISupports*)&window->pending_window->base.IHTMLWindow2_iface, "pending_window", cb); + if(window->base.inner_window) + note_cc_edge((nsISupports*)&window->base.inner_window->base.IHTMLWindow2_iface, "inner_window", cb); + if(window->location) + note_cc_edge((nsISupports*)&window->location->IHTMLLocation_iface, "location", cb); + if(window->nswindow) + note_cc_edge((nsISupports*)window->nswindow, "nswindow", cb); + if(window->window_proxy) + note_cc_edge((nsISupports*)window->window_proxy, "window_proxy", cb); + return NS_OK; +} + +static nsresult NSAPI outer_window_unlink(void *p) +{ + HTMLOuterWindow *window = HTMLOuterWindow_from_IHTMLWindow2(p); + + if(window->browser) { + list_remove(&window->browser_entry); + window->browser = NULL; + } + if(window->pending_window) { + HTMLInnerWindow *pending_window = window->pending_window; + abort_window_bindings(pending_window); + pending_window->base.outer_window = NULL; + window->pending_window = NULL; + IHTMLWindow2_Release(&pending_window->base.IHTMLWindow2_iface); + } + + set_current_mon(window, NULL, 0); + set_current_uri(window, NULL); + if(window->base.inner_window) + detach_inner_window(window->base.inner_window); + if(window->location) { + HTMLLocation *location = window->location; + window->location = NULL; + IHTMLLocation_Release(&location->IHTMLLocation_iface); + } + if(window->frame_element) { + window->frame_element->content_window = NULL; + window->frame_element = NULL; + } + unlink_ref(&window->nswindow); + if(window->window_proxy) { + unlink_ref(&window->window_proxy); + wine_rb_remove(&window_map, &window->entry); + } + return NS_OK; +} + +static void NSAPI outer_window_delete_cycle_collectable(void *p) +{ + HTMLOuterWindow *window = HTMLOuterWindow_from_IHTMLWindow2(p); + outer_window_unlink(p); + free(window); +} + +void init_window_cc(void) +{ + static const CCObjCallback ccp_callback = { + outer_window_traverse, + outer_window_unlink, + outer_window_delete_cycle_collectable + }; + ccp_init(&outer_window_ccp, &ccp_callback); +} + static void *alloc_window(size_t size) { HTMLWindow *window; @@ -4219,7 +4269,6 @@ static void *alloc_window(size_t size) window->IProvideMultipleClassInfo_iface.lpVtbl = &ProvideMultipleClassInfoVtbl; window->IWineHTMLWindowPrivate_iface.lpVtbl = &WineHTMLWindowPrivateVtbl; window->IWineHTMLWindowCompatPrivate_iface.lpVtbl = &WineHTMLWindowCompatPrivateVtbl; - window->ref = 1;
return window; } @@ -4248,6 +4297,7 @@ static HRESULT create_inner_window(HTMLOuterWindow *outer_window, IMoniker *mon, window->base.outer_window = outer_window; window->base.inner_window = window;
+ window->base.ref = 1; EventTarget_Init(&window->event_target, (IUnknown*)&window->base.IHTMLWindow2_iface, &HTMLWindow_dispex, COMPAT_MODE_NONE);
@@ -4278,6 +4328,7 @@ HRESULT create_outer_window(GeckoBrowser *browser, mozIDOMWindowProxy *mozwindow window->base.inner_window = NULL; window->browser = browser; list_add_head(&browser->outer_windows, &window->browser_entry); + ccref_init(&window->ccref, 1);
mozIDOMWindowProxy_AddRef(mozwindow); window->window_proxy = mozwindow; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 05203c53897..d19baffd820 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -586,6 +586,7 @@ struct HTMLWindow { struct HTMLOuterWindow { HTMLWindow base;
+ nsCycleCollectingAutoRefCnt ccref; LONG task_magic;
nsIDOMWindow *nswindow; @@ -1078,6 +1079,7 @@ void set_viewer_zoom(GeckoBrowser*,float); float get_viewer_zoom(GeckoBrowser*);
void init_dispex_cc(void); +void init_window_cc(void);
HRESULT nsuri_to_url(LPCWSTR,BOOL,BSTR*);
diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c index d2053235c03..1b31e4f7159 100644 --- a/dlls/mshtml/nsembed.c +++ b/dlls/mshtml/nsembed.c @@ -597,6 +597,7 @@ static BOOL init_xpcom(const PRUnichar *gre_path) }
init_dispex_cc(); + init_window_cc();
return TRUE; }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 23 +++++++++++------------ dlls/mshtml/htmlevent.c | 10 +++++----- 2 files changed, 16 insertions(+), 17 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index e31f364491d..53198840170 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -639,7 +639,7 @@ static inline dispex_dynamic_data_t *get_dynamic_data(DispatchEx *This) if(!This->dynamic_data) return NULL;
- if(This->info->desc->vtbl && This->info->desc->vtbl->populate_props) + if(This->info->desc->vtbl->populate_props) This->info->desc->vtbl->populate_props(This);
return This->dynamic_data; @@ -736,7 +736,7 @@ static HRESULT dispex_value(DispatchEx *This, LCID lcid, WORD flags, DISPPARAMS { HRESULT hres;
- if(This->info->desc->vtbl && This->info->desc->vtbl->value) + if(This->info->desc->vtbl->value) return This->info->desc->vtbl->value(This, lcid, flags, params, res, ei, caller);
switch(flags) { @@ -1054,7 +1054,7 @@ static HRESULT get_builtin_id(DispatchEx *This, BSTR name, DWORD grfdex, DISPID min = n+1; }
- if(This->info->desc->vtbl && This->info->desc->vtbl->get_dispid) { + if(This->info->desc->vtbl->get_dispid) { HRESULT hres;
hres = This->info->desc->vtbl->get_dispid(This, name, grfdex, ret); @@ -1706,7 +1706,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
switch(get_dispid_type(id)) { case DISPEXPROP_CUSTOM: - if(!This->info->desc->vtbl || !This->info->desc->vtbl->invoke) + if(!This->info->desc->vtbl->invoke) return DISP_E_MEMBERNOTFOUND; return This->info->desc->vtbl->invoke(This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
@@ -1759,7 +1759,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc case DISPEXPROP_BUILTIN: if(wFlags == DISPATCH_CONSTRUCT) { if(id == DISPID_VALUE) { - if(This->info->desc->vtbl && This->info->desc->vtbl->value) { + if(This->info->desc->vtbl->value) { return This->info->desc->vtbl->value(This, lcid, wFlags, pdp, pvarRes, pei, pspCaller); } FIXME("DISPATCH_CONSTRUCT flag but missing value function\n"); @@ -1801,7 +1801,7 @@ static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID
TRACE("(%p)->(%lx)\n", This, id);
- if(is_custom_dispid(id) && This->info->desc->vtbl && This->info->desc->vtbl->delete) + if(is_custom_dispid(id) && This->info->desc->vtbl->delete) return This->info->desc->vtbl->delete(This, id);
if(dispex_compat_mode(This) < COMPAT_MODE_IE8) { @@ -1844,7 +1844,7 @@ static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BS return E_OUTOFMEMORY;
if(is_custom_dispid(id)) { - if(This->info->desc->vtbl && This->info->desc->vtbl->get_name) + if(This->info->desc->vtbl->get_name) return This->info->desc->vtbl->get_name(This, id, pbstrName); return DISP_E_MEMBERNOTFOUND; } @@ -1928,7 +1928,7 @@ static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, id = DISPID_STARTENUM; }
- if(This->info->desc->vtbl && This->info->desc->vtbl->next_dispid) { + if(This->info->desc->vtbl->next_dispid) { hres = This->info->desc->vtbl->next_dispid(This, id, pid); if(hres != S_FALSE) return hres; @@ -2110,7 +2110,7 @@ void release_dispex(DispatchEx *This) { dynamic_prop_t *prop;
- if(This->info->desc->vtbl && This->info->desc->vtbl->unlink) + if(This->info->desc->vtbl->unlink) This->info->desc->vtbl->unlink(This);
if(!This->dynamic_data) @@ -2140,8 +2140,7 @@ void release_dispex(DispatchEx *This) free(This->dynamic_data);
destructor: - if(This->info->desc->vtbl) - This->info->desc->vtbl->destructor(This); + This->info->desc->vtbl->destructor(This); }
void init_dispatch(DispatchEx *dispex, IUnknown *outer, dispex_static_data_t *data, compat_mode_t compat_mode) @@ -2153,7 +2152,7 @@ void init_dispatch(DispatchEx *dispex, IUnknown *outer, dispex_static_data_t *da dispex->dynamic_data = NULL; ccref_init(&dispex->ccref, 1);
- if(data->vtbl && data->vtbl->get_compat_mode) { + if(data->vtbl->get_compat_mode) { /* delayed init */ if(!data->delayed_init_info) { EnterCriticalSection(&cs_dispex_static_data); diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 13fa4e5b505..f38998f0d20 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -3730,7 +3730,7 @@ static void call_event_handlers(EventTarget *event_target, DOMEvent *event, disp free(listeners);
if(event->phase != DEP_CAPTURING_PHASE && event_info[event->event_id].dispid - && (vtbl = dispex_get_vtbl(&event_target->dispex)) && vtbl->get_cp_container) + && (vtbl = dispex_get_vtbl(&event_target->dispex))->get_cp_container) cp_container = vtbl->get_cp_container(&event_target->dispex); if(cp_container) { if(cp_container->cps) { @@ -3823,7 +3823,7 @@ static HRESULT dispatch_event_object(EventTarget *event_target, DOMEvent *event,
target_chain[chain_cnt++] = iter;
- if(!(vtbl = dispex_get_vtbl(&iter->dispex)) || !vtbl->get_parent_event_target) + if(!(vtbl = dispex_get_vtbl(&iter->dispex))->get_parent_event_target) break; iter = vtbl->get_parent_event_target(&iter->dispex); } while(iter); @@ -3835,7 +3835,7 @@ static HRESULT dispatch_event_object(EventTarget *event_target, DOMEvent *event, }
target_vtbl = dispex_get_vtbl(&event_target->dispex); - if(target_vtbl && target_vtbl->set_current_event) + if(target_vtbl->set_current_event) prev_event = target_vtbl->set_current_event(&event_target->dispex, event->event_obj);
if(event->target) @@ -3862,7 +3862,7 @@ static HRESULT dispatch_event_object(EventTarget *event_target, DOMEvent *event, if(r) *r = variant_bool(!event->prevent_default);
- if(target_vtbl && target_vtbl->set_current_event) { + if(target_vtbl->set_current_event) { IHTMLEventObj *prev = target_vtbl->set_current_event(&event_target->dispex, prev_event); if(prev) IHTMLEventObj_Release(prev); @@ -3875,7 +3875,7 @@ static HRESULT dispatch_event_object(EventTarget *event_target, DOMEvent *event, BOOL prevent_default = event->prevent_default; for(i = 0; !prevent_default && i < chain_cnt; i++) { vtbl = dispex_get_vtbl(&target_chain[i]->dispex); - if(!vtbl || !vtbl->handle_event_default) + if(!vtbl->handle_event_default) continue; hres = vtbl->handle_event_default(&event_target->dispex, event->event_id, event->nsevent, &prevent_default);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 12 ++++++++- dlls/mshtml/htmlwindow.c | 52 ++++++++++++++++++++++++++++++------ dlls/mshtml/mshtml_private.h | 13 +++------ 3 files changed, 59 insertions(+), 18 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 53198840170..c7e497014bf 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -33,7 +33,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
#define MAX_ARGS 16
-ExternalCycleCollectionParticipant dispex_ccp; +static ExternalCycleCollectionParticipant dispex_ccp;
static CRITICAL_SECTION cs_dispex_static_data; static CRITICAL_SECTION_DEBUG cs_dispex_static_data_dbg = @@ -2016,6 +2016,16 @@ BOOL dispex_query_interface_no_cc(DispatchEx *This, REFIID riid, void **ppv) return TRUE; }
+LONG dispex_ref_decr(DispatchEx *dispex) +{ + LONG ref = ccref_decr(&dispex->ccref, (nsISupports*)&dispex->IDispatchEx_iface, &dispex_ccp); + + if(!ref && dispex->info->desc->vtbl->last_release) + dispex->info->desc->vtbl->last_release(dispex); + + return ref; +} + static nsresult NSAPI dispex_traverse(void *ccp, void *p, nsCycleCollectionTraversalCallback *cb) { DispatchEx *This = impl_from_IDispatchEx(p); diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 5619eb6e7c9..e3e13b41907 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -220,13 +220,13 @@ static HRESULT WINAPI HTMLWindow2_QueryInterface(IHTMLWindow2 *iface, REFIID rii if(hres != S_FALSE) return hres;
- return EventTarget_QI_no_cc(&This->event_target, riid, ppv); + return EventTarget_QI(&This->event_target, riid, ppv); }
static ULONG WINAPI HTMLWindow2_AddRef(IHTMLWindow2 *iface) { HTMLInnerWindow *This = HTMLInnerWindow_from_IHTMLWindow2(iface); - LONG ref = InterlockedIncrement(&This->base.ref); + LONG ref = dispex_ref_incr(&This->event_target.dispex);
TRACE("(%p) ref=%ld\n", This, ref);
@@ -236,13 +236,10 @@ static ULONG WINAPI HTMLWindow2_AddRef(IHTMLWindow2 *iface) static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface) { HTMLInnerWindow *This = HTMLInnerWindow_from_IHTMLWindow2(iface); - LONG ref = InterlockedDecrement(&This->base.ref); + LONG ref = dispex_ref_decr(&This->event_target.dispex);
TRACE("(%p) ref=%ld\n", This, ref);
- if(!ref) - release_dispex(&This->event_target.dispex); - return ref; }
@@ -264,7 +261,7 @@ static HRESULT WINAPI outer_window_QueryInterface(IHTMLWindow2 *iface, REFIID ri *ppv = &This->base.IHTMLWindow2_iface; return S_OK; }else { - return EventTarget_QI_no_cc(&This->base.inner_window->event_target, riid, ppv); + return EventTarget_QI(&This->base.inner_window->event_target, riid, ppv); } }
@@ -3827,6 +3824,38 @@ static inline HTMLInnerWindow *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLInnerWindow, event_target.dispex); }
+static void HTMLWindow_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLInnerWindow *This = impl_from_DispatchEx(dispex); + HTMLOuterWindow *child; + + LIST_FOR_EACH_ENTRY(child, &This->children, HTMLOuterWindow, sibling_entry) + note_cc_edge((nsISupports*)&child->base.IHTMLWindow2_iface, "child", cb); + if(This->doc) + note_cc_edge((nsISupports*)&This->doc->node.IHTMLDOMNode_iface, "doc", cb); + if(This->console) + note_cc_edge((nsISupports*)This->console, "console", cb); + if(This->image_factory) + note_cc_edge((nsISupports*)&This->image_factory->IHTMLImageElementFactory_iface, "image_factory", cb); + if(This->option_factory) + note_cc_edge((nsISupports*)&This->option_factory->IHTMLOptionElementFactory_iface, "option_factory", cb); + if(This->xhr_factory) + note_cc_edge((nsISupports*)&This->xhr_factory->IHTMLXMLHttpRequestFactory_iface, "xhr_factory", cb); + if(This->mutation_observer_ctor) + note_cc_edge((nsISupports*)This->mutation_observer_ctor, "mutation_observer_ctor", cb); + if(This->screen) + note_cc_edge((nsISupports*)This->screen, "screen", cb); + if(This->history) + note_cc_edge((nsISupports*)&This->history->IOmHistory_iface, "history", cb); + if(This->navigator) + note_cc_edge((nsISupports*)This->navigator, "navigator", cb); + if(This->session_storage) + note_cc_edge((nsISupports*)This->session_storage, "session_storage", cb); + if(This->local_storage) + note_cc_edge((nsISupports*)This->local_storage, "local_storage", cb); + traverse_variant(&This->performance, "performance", cb); +} + static void HTMLWindow_unlink(DispatchEx *dispex) { HTMLInnerWindow *This = impl_from_DispatchEx(dispex); @@ -3905,6 +3934,12 @@ static void HTMLWindow_destructor(DispatchEx *dispex) free(This); }
+static void HTMLWindow_last_release(DispatchEx *dispex) +{ + HTMLInnerWindow *This = impl_from_DispatchEx(dispex); + remove_target_tasks(This->task_magic); +} + static HRESULT HTMLWindow_get_name(DispatchEx *dispex, DISPID id, BSTR *name) { HTMLInnerWindow *This = impl_from_DispatchEx(dispex); @@ -4151,7 +4186,9 @@ static IHTMLEventObj *HTMLWindow_set_current_event(DispatchEx *dispex, IHTMLEven static const event_target_vtbl_t HTMLWindow_event_target_vtbl = { { .destructor = HTMLWindow_destructor, + .traverse = HTMLWindow_traverse, .unlink = HTMLWindow_unlink, + .last_release = HTMLWindow_last_release, .get_name = HTMLWindow_get_name, .invoke = HTMLWindow_invoke, .next_dispid = HTMLWindow_next_dispid, @@ -4297,7 +4334,6 @@ static HRESULT create_inner_window(HTMLOuterWindow *outer_window, IMoniker *mon, window->base.outer_window = outer_window; window->base.inner_window = window;
- window->base.ref = 1; EventTarget_Init(&window->event_target, (IUnknown*)&window->base.IHTMLWindow2_iface, &HTMLWindow_dispex, COMPAT_MODE_NONE);
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index d19baffd820..361da1644f5 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -358,6 +358,9 @@ typedef struct { void (*traverse)(DispatchEx*,nsCycleCollectionTraversalCallback*); void (*unlink)(DispatchEx*);
+ /* Called on the last release, when the refcount reaches 0 */ + void (*last_release)(DispatchEx*); + /* Called when the object wants to handle DISPID_VALUE invocations */ HRESULT (*value)(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*);
@@ -427,17 +430,11 @@ extern void (__cdecl *ccp_init)(ExternalCycleCollectionParticipant*,const CCObjC extern void (__cdecl *describe_cc_node)(nsCycleCollectingAutoRefCnt*,const char*,nsCycleCollectionTraversalCallback*); extern void (__cdecl *note_cc_edge)(nsISupports*,const char*,nsCycleCollectionTraversalCallback*);
-extern ExternalCycleCollectionParticipant dispex_ccp; - static inline LONG dispex_ref_incr(DispatchEx *dispex) { return ccref_incr(&dispex->ccref, (nsISupports*)&dispex->IDispatchEx_iface); } - -static inline LONG dispex_ref_decr(DispatchEx *dispex) -{ - return ccref_decr(&dispex->ccref, (nsISupports*)&dispex->IDispatchEx_iface, &dispex_ccp); -} +extern LONG dispex_ref_decr(DispatchEx*);
void init_dispatch(DispatchEx*,IUnknown*,dispex_static_data_t*,compat_mode_t); void release_dispex(DispatchEx*); @@ -577,8 +574,6 @@ struct HTMLWindow { IWineHTMLWindowPrivate IWineHTMLWindowPrivate_iface; IWineHTMLWindowCompatPrivate IWineHTMLWindowCompatPrivate_iface;
- LONG ref; - HTMLInnerWindow *inner_window; HTMLOuterWindow *outer_window; };
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 6 +++--- dlls/mshtml/navigate.c | 6 +++--- dlls/mshtml/omnavigator.c | 32 +++++++++++++++++++++----------- 3 files changed, 27 insertions(+), 17 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 361da1644f5..e446d48d088 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -535,9 +535,6 @@ typedef struct {
LONG ref;
- ULONG navigation_type; - ULONG redirect_count; - ULONGLONG navigation_start_time; ULONGLONG unload_event_start_time; ULONGLONG unload_event_end_time; @@ -647,6 +644,9 @@ struct HTMLInnerWindow { IDispatch *mutation_observer_ctor; nsChannelBSC *bscallback; struct list bindings; + + ULONG navigation_type; + ULONG redirect_count; };
typedef enum { diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index 3583fb91069..b13570f3ca3 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -1351,9 +1351,9 @@ static HRESULT nsChannelBSC_start_binding(BSCallback *bsc) DWORD flags = This->bsc.window->base.outer_window->load_flags;
if(flags & BINDING_FROMHIST) - This->bsc.window->performance_timing->navigation_type = 2; /* TYPE_BACK_FORWARD */ + This->bsc.window->navigation_type = 2; /* TYPE_BACK_FORWARD */ if(flags & BINDING_REFRESH) - This->bsc.window->performance_timing->navigation_type = 1; /* TYPE_RELOAD */ + This->bsc.window->navigation_type = 1; /* TYPE_RELOAD */
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(); @@ -1726,7 +1726,7 @@ static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG progress, ULONG t break; case BINDSTATUS_REDIRECTING: if(This->is_doc_channel) { - This->bsc.window->performance_timing->redirect_count++; + This->bsc.window->redirect_count++; if(!This->bsc.window->performance_timing->redirect_time) This->bsc.window->performance_timing->redirect_time = get_time_stamp(); } diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 9713e9c0b80..1f645b9b7e2 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1977,7 +1977,7 @@ typedef struct { DispatchEx dispex; IHTMLPerformanceNavigation IHTMLPerformanceNavigation_iface;
- HTMLPerformanceTiming *timing; + HTMLInnerWindow *window; } HTMLPerformanceNavigation;
static inline HTMLPerformanceNavigation *impl_from_IHTMLPerformanceNavigation(IHTMLPerformanceNavigation *iface) @@ -2068,7 +2068,7 @@ static HRESULT WINAPI HTMLPerformanceNavigation_get_type(IHTMLPerformanceNavigat
TRACE("(%p)->(%p)\n", This, p);
- *p = This->timing->navigation_type; + *p = This->window->navigation_type; return S_OK; }
@@ -2078,7 +2078,7 @@ static HRESULT WINAPI HTMLPerformanceNavigation_get_redirectCount(IHTMLPerforman
TRACE("(%p)->(%p)\n", This, p);
- *p = This->timing->redirect_count; + *p = This->window->redirect_count; return S_OK; }
@@ -2120,17 +2120,17 @@ static inline HTMLPerformanceNavigation *HTMLPerformanceNavigation_from_Dispatch static void HTMLPerformanceNavigation_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLPerformanceNavigation *This = HTMLPerformanceNavigation_from_DispatchEx(dispex); - if(This->timing) - note_cc_edge((nsISupports*)&This->timing->IHTMLPerformanceTiming_iface, "timing", cb); + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); }
static void HTMLPerformanceNavigation_unlink(DispatchEx *dispex) { HTMLPerformanceNavigation *This = HTMLPerformanceNavigation_from_DispatchEx(dispex); - if(This->timing) { - HTMLPerformanceTiming *timing = This->timing; - This->timing = NULL; - IHTMLPerformanceTiming_Release(&timing->IHTMLPerformanceTiming_iface); + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); } }
@@ -2161,6 +2161,7 @@ typedef struct { DispatchEx dispex; IHTMLPerformance IHTMLPerformance_iface;
+ HTMLInnerWindow *window; IHTMLPerformanceNavigation *navigation; HTMLPerformanceTiming *timing; } HTMLPerformance; @@ -2262,8 +2263,8 @@ static HRESULT WINAPI HTMLPerformance_get_navigation(IHTMLPerformance *iface, return E_OUTOFMEMORY;
navigation->IHTMLPerformanceNavigation_iface.lpVtbl = &HTMLPerformanceNavigationVtbl; - navigation->timing = This->timing; - IHTMLPerformanceTiming_AddRef(&This->timing->IHTMLPerformanceTiming_iface); + navigation->window = This->window; + IHTMLWindow2_AddRef(&This->window->base.IHTMLWindow2_iface);
init_dispatch(&navigation->dispex, (IUnknown*)&navigation->IHTMLPerformanceNavigation_iface, &HTMLPerformanceNavigation_dispex, dispex_compat_mode(&This->dispex)); @@ -2323,6 +2324,8 @@ static inline HTMLPerformance *HTMLPerformance_from_DispatchEx(DispatchEx *iface static void HTMLPerformance_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLPerformance *This = HTMLPerformance_from_DispatchEx(dispex); + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); if(This->navigation) note_cc_edge((nsISupports*)This->navigation, "navigation", cb); if(This->timing) @@ -2332,6 +2335,11 @@ static void HTMLPerformance_traverse(DispatchEx *dispex, nsCycleCollectionTraver static void HTMLPerformance_unlink(DispatchEx *dispex) { HTMLPerformance *This = HTMLPerformance_from_DispatchEx(dispex); + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } unlink_ref(&This->navigation); if(This->timing) { HTMLPerformanceTiming *timing = This->timing; @@ -2373,6 +2381,8 @@ HRESULT create_performance(HTMLInnerWindow *window, IHTMLPerformance **ret) return E_OUTOFMEMORY;
performance->IHTMLPerformance_iface.lpVtbl = &HTMLPerformanceVtbl; + performance->window = window; + IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
init_dispatch(&performance->dispex, (IUnknown*)&performance->IHTMLPerformance_iface, &HTMLPerformance_dispex, compat_mode);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 8 -- dlls/mshtml/mshtml_private.h | 43 ++++------ dlls/mshtml/mutation.c | 2 +- dlls/mshtml/navigate.c | 20 ++--- dlls/mshtml/nsevents.c | 25 +++--- dlls/mshtml/omnavigator.c | 155 ++++++++++++++++++----------------- dlls/mshtml/view.c | 4 +- 7 files changed, 123 insertions(+), 134 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index e3e13b41907..1c97e63789a 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3913,7 +3913,6 @@ static void HTMLWindow_unlink(DispatchEx *dispex) This->local_storage = NULL; IHTMLStorage_Release(local_storage); } - IHTMLPerformanceTiming_Release(&This->performance_timing->IHTMLPerformanceTiming_iface); unlink_variant(&This->performance); }
@@ -4313,19 +4312,12 @@ 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; window->base.IHTMLWindow2_iface.lpVtbl = &HTMLWindow2Vtbl;
- hres = create_performance_timing(&window->performance_timing); - if(FAILED(hres)) { - 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 e446d48d088..d3e26f5262f 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -529,30 +529,6 @@ typedef struct { HTMLInnerWindow *window; } OmHistory;
-typedef struct { - DispatchEx dispex; - IHTMLPerformanceTiming IHTMLPerformanceTiming_iface; - - LONG ref; - - ULONGLONG navigation_start_time; - ULONGLONG unload_event_start_time; - ULONGLONG unload_event_end_time; - ULONGLONG redirect_time; - ULONGLONG dns_lookup_time; - ULONGLONG connect_time; - ULONGLONG request_time; - ULONGLONG response_start_time; - 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; - ULONGLONG load_event_start_time; - ULONGLONG load_event_end_time; - ULONGLONG first_paint_time; -} HTMLPerformanceTiming; - typedef struct nsChannelBSC nsChannelBSC;
struct HTMLWindow { @@ -628,7 +604,6 @@ struct HTMLInnerWindow {
BOOL performance_initialized; VARIANT performance; - HTMLPerformanceTiming *performance_timing;
unsigned blocking_depth; unsigned parser_callback_cnt; @@ -647,6 +622,23 @@ struct HTMLInnerWindow {
ULONG navigation_type; ULONG redirect_count; + + ULONGLONG navigation_start_time; + ULONGLONG unload_event_start_time; + ULONGLONG unload_event_end_time; + ULONGLONG redirect_time; + ULONGLONG dns_lookup_time; + ULONGLONG connect_time; + ULONGLONG request_time; + ULONGLONG response_start_time; + 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; + ULONGLONG load_event_start_time; + ULONGLONG load_event_end_time; + ULONGLONG first_paint_time; };
typedef enum { @@ -1015,7 +1007,6 @@ HRESULT create_location(HTMLOuterWindow*,HTMLLocation**); HRESULT create_navigator(compat_mode_t,IOmNavigator**); HRESULT create_html_screen(compat_mode_t,IHTMLScreen**); HRESULT create_performance(HTMLInnerWindow*,IHTMLPerformance**); -HRESULT create_performance_timing(HTMLPerformanceTiming**); HRESULT create_history(HTMLInnerWindow*,OmHistory**); HRESULT create_namespace_collection(compat_mode_t,IHTMLNamespaceCollection**); HRESULT create_dom_implementation(HTMLDocumentNode*,IHTMLDOMImplementation**); diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index 1abb2d88839..7c93d27d829 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -313,7 +313,7 @@ static nsresult run_end_load(HTMLDocumentNode *This, nsISupports *arg1, nsISuppo bind_event_scripts(This);
if(This->window == window) { - window->performance_timing->dom_interactive_time = get_time_stamp(); + window->dom_interactive_time = get_time_stamp(); set_ready_state(This->outer_window, READYSTATE_INTERACTIVE); } IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index b13570f3ca3..8172abd8040 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -1095,7 +1095,7 @@ static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream) IWinInetHttpInfo *wininet_info;
if(This->is_doc_channel) - This->bsc.window->performance_timing->response_start_time = get_time_stamp(); + This->bsc.window->response_start_time = get_time_stamp();
This->response_processed = TRUE; if(This->bsc.binding) { @@ -1356,7 +1356,7 @@ static HRESULT nsChannelBSC_start_binding(BSCallback *bsc) This->bsc.window->navigation_type = 1; /* TYPE_RELOAD */
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(); + This->bsc.window->navigation_start_time = get_time_stamp(); }
return S_OK; @@ -1524,7 +1524,7 @@ static HRESULT nsChannelBSC_stop_binding(BSCallback *bsc, HRESULT result) nsChannelBSC *This = nsChannelBSC_from_BSCallback(bsc);
if(This->is_doc_channel && This->bsc.window) { - This->bsc.window->performance_timing->response_end_time = get_time_stamp(); + This->bsc.window->response_end_time = get_time_stamp(); if(result != E_ABORT) { if(FAILED(result)) handle_navigation_error(This, result); @@ -1727,21 +1727,21 @@ static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG progress, ULONG t case BINDSTATUS_REDIRECTING: if(This->is_doc_channel) { This->bsc.window->redirect_count++; - if(!This->bsc.window->performance_timing->redirect_time) - This->bsc.window->performance_timing->redirect_time = get_time_stamp(); + if(!This->bsc.window->redirect_time) + This->bsc.window->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(); + if(This->is_doc_channel && !This->bsc.window->dns_lookup_time) + This->bsc.window->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(); + This->bsc.window->connect_time = get_time_stamp(); break; case BINDSTATUS_SENDINGREQUEST: if(This->is_doc_channel) - This->bsc.window->performance_timing->request_time = get_time_stamp(); + This->bsc.window->request_time = get_time_stamp(); break; case BINDSTATUS_BEGINDOWNLOADDATA: { IWinInetHttpInfo *http_info; @@ -1798,7 +1798,7 @@ static HRESULT nsChannelBSC_on_response(BSCallback *bsc, DWORD response_code, HRESULT hres;
if(This->is_doc_channel) - This->bsc.window->performance_timing->response_start_time = get_time_stamp(); + This->bsc.window->response_start_time = get_time_stamp();
This->response_processed = TRUE; This->nschannel->response_status = response_code; diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index 76a3f4ab4c6..78a54c83955 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -238,7 +238,7 @@ static nsresult handle_dom_content_loaded(HTMLDocumentNode *doc, nsIDOMEvent *ns HRESULT hres;
if(doc->window) - doc->window->performance_timing->dom_content_loaded_event_start_time = get_time_stamp(); + doc->window->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)) { @@ -247,7 +247,7 @@ static nsresult handle_dom_content_loaded(HTMLDocumentNode *doc, nsIDOMEvent *ns }
if(doc->window) - doc->window->performance_timing->dom_content_loaded_event_end_time = get_time_stamp(); + doc->window->dom_content_loaded_event_end_time = get_time_stamp();
return NS_OK; } @@ -345,7 +345,7 @@ static nsresult handle_load(HTMLDocumentNode *doc, nsIDOMEvent *event) if(doc_obj) handle_docobj_load(doc_obj);
- doc->window->performance_timing->dom_complete_time = get_time_stamp(); + doc->window->dom_complete_time = get_time_stamp(); set_ready_state(doc->outer_window, READYSTATE_COMPLETE);
if(doc_obj) { @@ -363,7 +363,7 @@ static nsresult handle_load(HTMLDocumentNode *doc, nsIDOMEvent *event) IUnknown_Release(doc_obj->outer_unk); }
- doc->window->performance_timing->load_event_start_time = get_time_stamp(); + doc->window->load_event_start_time = get_time_stamp();
if(doc->dom_document) { hres = create_document_event(doc, EVENTID_LOAD, &load_event); @@ -381,7 +381,7 @@ static nsresult handle_load(HTMLDocumentNode *doc, nsIDOMEvent *event) IDOMEvent_Release(&load_event->IDOMEvent_iface); }
- doc->window->performance_timing->load_event_end_time = get_time_stamp(); + doc->window->load_event_end_time = get_time_stamp(); return NS_OK; }
@@ -406,8 +406,7 @@ static nsresult handle_beforeunload(HTMLDocumentNode *doc, nsIDOMEvent *nsevent)
static nsresult handle_unload(HTMLDocumentNode *doc, nsIDOMEvent *nsevent) { - HTMLPerformanceTiming *timing = NULL; - HTMLInnerWindow *window; + HTMLInnerWindow *window, *pending_window; DOMEvent *event; HRESULT hres;
@@ -415,11 +414,9 @@ static nsresult handle_unload(HTMLDocumentNode *doc, nsIDOMEvent *nsevent) 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(); + pending_window = window->base.outer_window->pending_window; + if(pending_window) + pending_window->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)) { @@ -427,8 +424,8 @@ static nsresult handle_unload(HTMLDocumentNode *doc, nsIDOMEvent *nsevent) IDOMEvent_Release(&event->IDOMEvent_iface); }
- if(timing) - timing->unload_event_end_time = get_time_stamp(); + if(pending_window) + pending_window->unload_event_end_time = get_time_stamp();
return NS_OK; } diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 1f645b9b7e2..d0c16ac61f0 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1558,6 +1558,14 @@ HRESULT create_navigator(compat_mode_t compat_mode, IOmNavigator **navigator) return S_OK; }
+typedef struct { + DispatchEx dispex; + IHTMLPerformanceTiming IHTMLPerformanceTiming_iface; + + LONG ref; + HTMLInnerWindow *window; +} HTMLPerformanceTiming; + static inline HTMLPerformanceTiming *impl_from_IHTMLPerformanceTiming(IHTMLPerformanceTiming *iface) { return CONTAINING_RECORD(iface, HTMLPerformanceTiming, IHTMLPerformanceTiming_iface); @@ -1602,12 +1610,8 @@ static ULONG WINAPI HTMLPerformanceTiming_Release(IHTMLPerformanceTiming *iface)
TRACE("(%p) ref=%ld\n", This, ref);
- if(!ref) { - if(This->dispex.outer) - release_dispex(&This->dispex); - else - free(This); - } + if(!ref) + release_dispex(&This->dispex);
return ref; } @@ -1649,20 +1653,22 @@ static HRESULT WINAPI HTMLPerformanceTiming_Invoke(IHTMLPerformanceTiming *iface
static ULONGLONG get_fetch_time(HTMLPerformanceTiming *This) { + HTMLInnerWindow *window = This->window; + /* 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(!window->unload_event_end_time && !window->redirect_time) + return window->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; + if(window->dns_lookup_time) + return window->dns_lookup_time; + if(window->connect_time) + return window->connect_time; + if(window->request_time) + return window->request_time; + if(window->unload_event_end_time) + return window->unload_event_end_time;
- return This->redirect_time; + return window->redirect_time; }
static HRESULT WINAPI HTMLPerformanceTiming_get_navigationStart(IHTMLPerformanceTiming *iface, ULONGLONG *p) @@ -1671,7 +1677,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_navigationStart(IHTMLPerformance
TRACE("(%p)->(%p)\n", This, p);
- *p = This->navigation_start_time; + *p = This->window->navigation_start_time; return S_OK; }
@@ -1681,7 +1687,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_unloadEventStart(IHTMLPerformanc
TRACE("(%p)->(%p)\n", This, p);
- *p = This->unload_event_start_time; + *p = This->window->unload_event_start_time; return S_OK; }
@@ -1691,7 +1697,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_unloadEventEnd(IHTMLPerformanceT
TRACE("(%p)->(%p)\n", This, p);
- *p = This->unload_event_end_time; + *p = This->window->unload_event_end_time; return S_OK; }
@@ -1701,7 +1707,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_redirectStart(IHTMLPerformanceTi
TRACE("(%p)->(%p)\n", This, p);
- *p = This->redirect_time; + *p = This->window->redirect_time; return S_OK; }
@@ -1711,7 +1717,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_redirectEnd(IHTMLPerformanceTimi
TRACE("(%p)->(%p)\n", This, p);
- *p = This->redirect_time ? get_fetch_time(This) : 0; + *p = This->window->redirect_time ? get_fetch_time(This) : 0; return S_OK; }
@@ -1731,7 +1737,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domainLookupStart(IHTMLPerforman
TRACE("(%p)->(%p)\n", This, p);
- *p = This->dns_lookup_time ? This->dns_lookup_time : get_fetch_time(This); + *p = This->window->dns_lookup_time ? This->window->dns_lookup_time : get_fetch_time(This); return S_OK; }
@@ -1741,8 +1747,8 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domainLookupEnd(IHTMLPerformance
TRACE("(%p)->(%p)\n", This, p);
- *p = This->connect_time ? This->connect_time : - This->dns_lookup_time ? This->dns_lookup_time : get_fetch_time(This); + *p = This->window->connect_time ? This->window->connect_time : + This->window->dns_lookup_time ? This->window->dns_lookup_time : get_fetch_time(This); return S_OK; }
@@ -1752,8 +1758,8 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_connectStart(IHTMLPerformanceTim
TRACE("(%p)->(%p)\n", This, p);
- *p = This->connect_time ? This->connect_time : - This->dns_lookup_time ? This->dns_lookup_time : get_fetch_time(This); + *p = This->window->connect_time ? This->window->connect_time : + This->window->dns_lookup_time ? This->window->dns_lookup_time : get_fetch_time(This); return S_OK; }
@@ -1763,9 +1769,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_connectEnd(IHTMLPerformanceTimin
TRACE("(%p)->(%p)\n", This, p);
- *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); + *p = This->window->request_time ? This->window->request_time : + This->window->connect_time ? This->window->connect_time : + This->window->dns_lookup_time ? This->window->dns_lookup_time : get_fetch_time(This); return S_OK; }
@@ -1775,9 +1781,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_requestStart(IHTMLPerformanceTim
TRACE("(%p)->(%p)\n", This, p);
- *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); + *p = This->window->request_time ? This->window->request_time : + This->window->connect_time ? This->window->connect_time : + This->window->dns_lookup_time ? This->window->dns_lookup_time : get_fetch_time(This); return S_OK; }
@@ -1787,7 +1793,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_responseStart(IHTMLPerformanceTi
TRACE("(%p)->(%p)\n", This, p);
- *p = This->response_start_time; + *p = This->window->response_start_time; return S_OK; }
@@ -1797,7 +1803,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_responseEnd(IHTMLPerformanceTimi
TRACE("(%p)->(%p)\n", This, p);
- *p = This->response_end_time; + *p = This->window->response_end_time; return S_OK; }
@@ -1808,7 +1814,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domLoading(IHTMLPerformanceTimin TRACE("(%p)->(%p)\n", This, p);
/* Make sure this is after responseEnd, when the Gecko parser starts */ - *p = This->response_end_time; + *p = This->window->response_end_time; return S_OK; }
@@ -1818,7 +1824,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domInteractive(IHTMLPerformanceT
TRACE("(%p)->(%p)\n", This, p);
- *p = This->dom_interactive_time; + *p = This->window->dom_interactive_time; return S_OK; }
@@ -1828,7 +1834,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domContentLoadedEventStart(IHTML
TRACE("(%p)->(%p)\n", This, p);
- *p = This->dom_content_loaded_event_start_time; + *p = This->window->dom_content_loaded_event_start_time; return S_OK; }
@@ -1838,7 +1844,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domContentLoadedEventEnd(IHTMLPe
TRACE("(%p)->(%p)\n", This, p);
- *p = This->dom_content_loaded_event_end_time; + *p = This->window->dom_content_loaded_event_end_time; return S_OK; }
@@ -1848,7 +1854,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domComplete(IHTMLPerformanceTimi
TRACE("(%p)->(%p)\n", This, p);
- *p = This->dom_complete_time; + *p = This->window->dom_complete_time; return S_OK; }
@@ -1858,7 +1864,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_loadEventStart(IHTMLPerformanceT
TRACE("(%p)->(%p)\n", This, p);
- *p = This->load_event_start_time; + *p = This->window->load_event_start_time; return S_OK; }
@@ -1868,7 +1874,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_loadEventEnd(IHTMLPerformanceTim
TRACE("(%p)->(%p)\n", This, p);
- *p = This->load_event_end_time; + *p = This->window->load_event_end_time; return S_OK; }
@@ -1878,7 +1884,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_msFirstPaint(IHTMLPerformanceTim
TRACE("(%p)->(%p)\n", This, p);
- *p = This->first_paint_time; + *p = This->window->first_paint_time; return S_OK; }
@@ -1936,6 +1942,16 @@ static inline HTMLPerformanceTiming *HTMLPerformanceTiming_from_DispatchEx(Dispa return CONTAINING_RECORD(iface, HTMLPerformanceTiming, dispex); }
+static void HTMLPerformanceTiming_unlink(DispatchEx *dispex) +{ + HTMLPerformanceTiming *This = HTMLPerformanceTiming_from_DispatchEx(dispex); + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } +} + static void HTMLPerformanceTiming_destructor(DispatchEx *dispex) { HTMLPerformanceTiming *This = HTMLPerformanceTiming_from_DispatchEx(dispex); @@ -1944,6 +1960,7 @@ static void HTMLPerformanceTiming_destructor(DispatchEx *dispex)
static const dispex_static_data_vtbl_t HTMLPerformanceTiming_dispex_vtbl = { .destructor = HTMLPerformanceTiming_destructor, + .unlink = HTMLPerformanceTiming_unlink };
static const tid_t HTMLPerformanceTiming_iface_tids[] = { @@ -1957,22 +1974,6 @@ static dispex_static_data_t HTMLPerformanceTiming_dispex = { HTMLPerformanceTiming_iface_tids };
-HRESULT create_performance_timing(HTMLPerformanceTiming **ret) -{ - HTMLPerformanceTiming *timing; - - timing = calloc(1, 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; @@ -2163,7 +2164,7 @@ typedef struct {
HTMLInnerWindow *window; IHTMLPerformanceNavigation *navigation; - HTMLPerformanceTiming *timing; + IHTMLPerformanceTiming *timing; } HTMLPerformance;
static inline HTMLPerformance *impl_from_IHTMLPerformance(IHTMLPerformance *iface) @@ -2282,7 +2283,25 @@ static HRESULT WINAPI HTMLPerformance_get_timing(IHTMLPerformance *iface, IHTMLP
TRACE("(%p)->(%p)\n", This, p);
- IHTMLPerformanceTiming_AddRef(*p = &This->timing->IHTMLPerformanceTiming_iface); + if(!This->timing) { + HTMLPerformanceTiming *timing; + + timing = calloc(1, sizeof(*timing)); + if(!timing) + return E_OUTOFMEMORY; + + timing->IHTMLPerformanceTiming_iface.lpVtbl = &HTMLPerformanceTimingVtbl; + timing->ref = 1; + timing->window = This->window; + IHTMLWindow2_AddRef(&This->window->base.IHTMLWindow2_iface); + + 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; }
@@ -2329,7 +2348,7 @@ static void HTMLPerformance_traverse(DispatchEx *dispex, nsCycleCollectionTraver if(This->navigation) note_cc_edge((nsISupports*)This->navigation, "navigation", cb); if(This->timing) - note_cc_edge((nsISupports*)&This->timing->IHTMLPerformanceTiming_iface, "timing", cb); + note_cc_edge((nsISupports*)This->timing, "timing", cb); }
static void HTMLPerformance_unlink(DispatchEx *dispex) @@ -2341,11 +2360,7 @@ static void HTMLPerformance_unlink(DispatchEx *dispex) IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); } unlink_ref(&This->navigation); - if(This->timing) { - HTMLPerformanceTiming *timing = This->timing; - This->timing = NULL; - IHTMLPerformanceTiming_Release(&timing->IHTMLPerformanceTiming_iface); - } + unlink_ref(&This->timing); }
static void HTMLPerformance_destructor(DispatchEx *dispex) @@ -2387,12 +2402,6 @@ HRESULT create_performance(HTMLInnerWindow *window, IHTMLPerformance **ret) init_dispatch(&performance->dispex, (IUnknown*)&performance->IHTMLPerformance_iface, &HTMLPerformance_dispex, compat_mode);
- performance->timing = window->performance_timing; - IHTMLPerformanceTiming_AddRef(&performance->timing->IHTMLPerformanceTiming_iface); - - init_dispatch(&performance->timing->dispex, (IUnknown*)&performance->timing->IHTMLPerformanceTiming_iface, - &HTMLPerformanceTiming_dispex, compat_mode); - *ret = &performance->IHTMLPerformance_iface; return S_OK; } diff --git a/dlls/mshtml/view.c b/dlls/mshtml/view.c index 43ebc5284f5..fe7448ec0cf 100644 --- a/dlls/mshtml/view.c +++ b/dlls/mshtml/view.c @@ -50,8 +50,8 @@ 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(); + if(This->window && This->window->base.inner_window && !This->window->base.inner_window->first_paint_time) + This->window->base.inner_window->first_paint_time = get_time_stamp();
GetClientRect(This->hwnd, &rect);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/omnavigator.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index d0c16ac61f0..e851debd128 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1562,7 +1562,6 @@ typedef struct { DispatchEx dispex; IHTMLPerformanceTiming IHTMLPerformanceTiming_iface;
- LONG ref; HTMLInnerWindow *window; } HTMLPerformanceTiming;
@@ -1581,7 +1580,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_QueryInterface(IHTMLPerformanceTimin *ppv = &This->IHTMLPerformanceTiming_iface; }else if(IsEqualGUID(&IID_IHTMLPerformanceTiming, riid)) { *ppv = &This->IHTMLPerformanceTiming_iface; - }else if(dispex_query_interface_no_cc(&This->dispex, riid, ppv)) { + }else if(dispex_query_interface(&This->dispex, riid, ppv)) { return *ppv ? S_OK : E_NOINTERFACE; }else { WARN("Unsupported interface %s\n", debugstr_mshtml_guid(riid)); @@ -1596,7 +1595,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_QueryInterface(IHTMLPerformanceTimin static ULONG WINAPI HTMLPerformanceTiming_AddRef(IHTMLPerformanceTiming *iface) { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ref_incr(&This->dispex);
TRACE("(%p) ref=%ld\n", This, ref);
@@ -1606,13 +1605,10 @@ static ULONG WINAPI HTMLPerformanceTiming_AddRef(IHTMLPerformanceTiming *iface) static ULONG WINAPI HTMLPerformanceTiming_Release(IHTMLPerformanceTiming *iface) { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ref_decr(&This->dispex);
TRACE("(%p) ref=%ld\n", This, ref);
- if(!ref) - release_dispex(&This->dispex); - return ref; }
@@ -1942,6 +1938,13 @@ static inline HTMLPerformanceTiming *HTMLPerformanceTiming_from_DispatchEx(Dispa return CONTAINING_RECORD(iface, HTMLPerformanceTiming, dispex); }
+static void HTMLPerformanceTiming_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLPerformanceTiming *This = HTMLPerformanceTiming_from_DispatchEx(dispex); + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); +} + static void HTMLPerformanceTiming_unlink(DispatchEx *dispex) { HTMLPerformanceTiming *This = HTMLPerformanceTiming_from_DispatchEx(dispex); @@ -1960,6 +1963,7 @@ static void HTMLPerformanceTiming_destructor(DispatchEx *dispex)
static const dispex_static_data_vtbl_t HTMLPerformanceTiming_dispex_vtbl = { .destructor = HTMLPerformanceTiming_destructor, + .traverse = HTMLPerformanceTiming_traverse, .unlink = HTMLPerformanceTiming_unlink };
@@ -2291,7 +2295,6 @@ static HRESULT WINAPI HTMLPerformance_get_timing(IHTMLPerformance *iface, IHTMLP return E_OUTOFMEMORY;
timing->IHTMLPerformanceTiming_iface.lpVtbl = &HTMLPerformanceTimingVtbl; - timing->ref = 1; timing->window = This->window; IHTMLWindow2_AddRef(&This->window->base.IHTMLWindow2_iface);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 57 ++++++++++-------------------------- dlls/mshtml/htmlevent.c | 21 ------------- dlls/mshtml/mshtml_private.h | 3 -- dlls/mshtml/xmlhttprequest.c | 33 ++++++++++++++------- 4 files changed, 38 insertions(+), 76 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index c7e497014bf..38e95e61856 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1994,28 +1994,6 @@ BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv) return TRUE; }
-BOOL dispex_query_interface_no_cc(DispatchEx *This, REFIID riid, void **ppv) -{ - if(IsEqualGUID(&IID_IDispatch, riid)) - *ppv = &This->IDispatchEx_iface; - else if(IsEqualGUID(&IID_IDispatchEx, riid)) - *ppv = &This->IDispatchEx_iface; - else if(IsEqualGUID(&IID_IDispatchJS, riid)) - *ppv = NULL; - else if(IsEqualGUID(&IID_UndocumentedScriptIface, riid)) - *ppv = NULL; - else if(IsEqualGUID(&IID_IMarshal, riid)) - *ppv = NULL; - else if(IsEqualGUID(&IID_IManagedObject, riid)) - *ppv = NULL; - else - return FALSE; - - if(*ppv) - IUnknown_AddRef((IUnknown*)*ppv); - return TRUE; -} - LONG dispex_ref_decr(DispatchEx *dispex) { LONG ref = ccref_decr(&dispex->ccref, (nsISupports*)&dispex->IDispatchEx_iface, &dispex_ccp); @@ -2098,26 +2076,6 @@ static nsresult NSAPI dispex_unlink(void *p) static void NSAPI dispex_delete_cycle_collectable(void *p) { DispatchEx *This = impl_from_IDispatchEx(p); - release_dispex(This); -} - -void init_dispex_cc(void) -{ - static const CCObjCallback dispex_ccp_callback = { - dispex_traverse, - dispex_unlink, - dispex_delete_cycle_collectable - }; - ccp_init(&dispex_ccp, &dispex_ccp_callback); -} - -const void *dispex_get_vtbl(DispatchEx *dispex) -{ - return dispex->info->desc->vtbl; -} - -void release_dispex(DispatchEx *This) -{ dynamic_prop_t *prop;
if(This->info->desc->vtbl->unlink) @@ -2153,6 +2111,21 @@ destructor: This->info->desc->vtbl->destructor(This); }
+void init_dispex_cc(void) +{ + static const CCObjCallback dispex_ccp_callback = { + dispex_traverse, + dispex_unlink, + dispex_delete_cycle_collectable + }; + ccp_init(&dispex_ccp, &dispex_ccp_callback); +} + +const void *dispex_get_vtbl(DispatchEx *dispex) +{ + return dispex->info->desc->vtbl; +} + void init_dispatch(DispatchEx *dispex, IUnknown *outer, dispex_static_data_t *data, compat_mode_t compat_mode) { assert(compat_mode < COMPAT_MODE_CNT); diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index f38998f0d20..59cb44a6475 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -4560,27 +4560,6 @@ HRESULT EventTarget_QI(EventTarget *event_target, REFIID riid, void **ppv) return E_NOINTERFACE; }
-HRESULT EventTarget_QI_no_cc(EventTarget *event_target, REFIID riid, void **ppv) -{ - if(IsEqualGUID(riid, &IID_IEventTarget)) { - if(use_event_quirks(event_target)) { - WARN("IEventTarget queried, but not supported by in document mode\n"); - *ppv = NULL; - return E_NOINTERFACE; - } - IEventTarget_AddRef(&event_target->IEventTarget_iface); - *ppv = &event_target->IEventTarget_iface; - return S_OK; - } - - if(dispex_query_interface_no_cc(&event_target->dispex, riid, ppv)) - return *ppv ? S_OK : E_NOINTERFACE; - - WARN("(%p)->(%s %p)\n", event_target, debugstr_mshtml_guid(riid), ppv); - *ppv = NULL; - return E_NOINTERFACE; -} - void EventTarget_init_dispex_info(dispex_data_t *dispex_info, compat_mode_t compat_mode) { static const dispex_hook_t IEventTarget_hooks[] = { diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index d3e26f5262f..1ea9e79a18a 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -437,9 +437,7 @@ static inline LONG dispex_ref_incr(DispatchEx *dispex) extern LONG dispex_ref_decr(DispatchEx*);
void init_dispatch(DispatchEx*,IUnknown*,dispex_static_data_t*,compat_mode_t); -void release_dispex(DispatchEx*); BOOL dispex_query_interface(DispatchEx*,REFIID,void**); -BOOL dispex_query_interface_no_cc(DispatchEx*,REFIID,void**); void dispex_props_unlink(DispatchEx*); HRESULT change_type(VARIANT*,VARIANT*,VARTYPE,IServiceProvider*); HRESULT dispex_get_dprop_ref(DispatchEx*,const WCHAR*,BOOL,VARIANT**); @@ -1209,7 +1207,6 @@ void HTMLElement_Init(HTMLElement*,HTMLDocumentNode*,nsIDOMElement*,dispex_stati
void EventTarget_Init(EventTarget*,IUnknown*,dispex_static_data_t*,compat_mode_t); HRESULT EventTarget_QI(EventTarget*,REFIID,void**); -HRESULT EventTarget_QI_no_cc(EventTarget*,REFIID,void**); void EventTarget_init_dispex_info(dispex_data_t*,compat_mode_t);
HRESULT HTMLDOMNode_QI(HTMLDOMNode*,REFIID,void**); diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index 07c141b10bd..c062b117c5d 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -136,7 +136,6 @@ struct HTMLXMLHttpRequest { IHTMLXMLHttpRequest2 IHTMLXMLHttpRequest2_iface; IWineXMLHttpRequestPrivate IWineXMLHttpRequestPrivate_iface; IProvideClassInfo2 IProvideClassInfo2_iface; - LONG ref; LONG task_magic; LONG ready_state; response_type_t response_type; @@ -526,7 +525,7 @@ static HRESULT WINAPI HTMLXMLHttpRequest_QueryInterface(IHTMLXMLHttpRequest *ifa }else if(IsEqualGUID(&IID_IProvideClassInfo2, riid)) { *ppv = &This->IProvideClassInfo2_iface; }else { - return EventTarget_QI_no_cc(&This->event_target, riid, ppv); + return EventTarget_QI(&This->event_target, riid, ppv); }
IUnknown_AddRef((IUnknown*)*ppv); @@ -536,7 +535,7 @@ static HRESULT WINAPI HTMLXMLHttpRequest_QueryInterface(IHTMLXMLHttpRequest *ifa static ULONG WINAPI HTMLXMLHttpRequest_AddRef(IHTMLXMLHttpRequest *iface) { HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ref_incr(&This->event_target.dispex);
TRACE("(%p) ref=%ld\n", This, ref);
@@ -546,13 +545,10 @@ static ULONG WINAPI HTMLXMLHttpRequest_AddRef(IHTMLXMLHttpRequest *iface) static ULONG WINAPI HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest *iface) { HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ref_decr(&This->event_target.dispex);
TRACE("(%p) ref=%ld\n", This, ref);
- if(!ref) - release_dispex(&This->event_target.dispex); - return ref; }
@@ -1521,10 +1517,20 @@ static inline HTMLXMLHttpRequest *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, event_target.dispex); }
+static void HTMLXMLHttpRequest_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); + if(This->pending_progress_event) + note_cc_edge((nsISupports*)&This->pending_progress_event->IDOMEvent_iface, "pending_progress_event", cb); + if(This->nsxhr) + note_cc_edge((nsISupports*)This->nsxhr, "nsxhr", cb); +} + static void HTMLXMLHttpRequest_unlink(DispatchEx *dispex) { HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); - remove_target_tasks(This->task_magic); if(This->event_listener) { XMLHttpReqEventListener *event_listener = This->event_listener; This->event_listener = NULL; @@ -1550,6 +1556,12 @@ static void HTMLXMLHttpRequest_destructor(DispatchEx *dispex) free(This); }
+static void HTMLXMLHttpRequest_last_release(DispatchEx *dispex) +{ + HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); + remove_target_tasks(This->task_magic); +} + static nsISupports *HTMLXMLHttpRequest_get_gecko_target(DispatchEx *dispex) { HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); @@ -1595,7 +1607,9 @@ static void HTMLXMLHttpRequest_init_dispex_info(dispex_data_t *info, compat_mode static const event_target_vtbl_t HTMLXMLHttpRequest_event_target_vtbl = { { .destructor = HTMLXMLHttpRequest_destructor, - .unlink = HTMLXMLHttpRequest_unlink + .traverse = HTMLXMLHttpRequest_traverse, + .unlink = HTMLXMLHttpRequest_unlink, + .last_release = HTMLXMLHttpRequest_last_release }, .get_gecko_target = HTMLXMLHttpRequest_get_gecko_target, .bind_event = HTMLXMLHttpRequest_bind_event @@ -1736,7 +1750,6 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactor ret->IProvideClassInfo2_iface.lpVtbl = &ProvideClassInfo2Vtbl; EventTarget_Init(&ret->event_target, (IUnknown*)&ret->IHTMLXMLHttpRequest_iface, &HTMLXMLHttpRequest_dispex, This->window->doc->document_mode); - ret->ref = 1;
/* Always register the handlers because we need them to track state */ event_listener->nsIDOMEventListener_iface.lpVtbl = &XMLHttpReqEventListenerVtbl;