Commit 6bd162d9 authored by Gabriel Ivăncescu's avatar Gabriel Ivăncescu Committed by Alexandre Julliard

mshtml: Grab refs to windows upfront before sending pagehide events.

parent 3c2b4171
...@@ -414,45 +414,73 @@ HRESULT call_set_active_object(IOleInPlaceUIWindow *window, IOleInPlaceActiveObj ...@@ -414,45 +414,73 @@ HRESULT call_set_active_object(IOleInPlaceUIWindow *window, IOleInPlaceActiveObj
return IOleInPlaceUIWindow_SetActiveObject(window, act_obj, act_obj ? html_documentW : NULL); return IOleInPlaceUIWindow_SetActiveObject(window, act_obj, act_obj ? html_documentW : NULL);
} }
static void send_unload_events_impl(HTMLInnerWindow *window) static unsigned get_window_list_num(HTMLInnerWindow *window)
{ {
HTMLOuterWindow *child; HTMLOuterWindow *child;
unsigned ret = 1;
LIST_FOR_EACH_ENTRY(child, &window->children, HTMLOuterWindow, sibling_entry)
ret += get_window_list_num(child->base.inner_window);
return ret;
}
static HTMLInnerWindow **get_window_list(HTMLInnerWindow *window, HTMLInnerWindow **output)
{
HTMLOuterWindow *child;
*output++ = window;
IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
LIST_FOR_EACH_ENTRY(child, &window->children, HTMLOuterWindow, sibling_entry)
output = get_window_list(child->base.inner_window, output);
return output;
}
static void send_unload_events(HTMLDocumentObj *doc)
{
HTMLInnerWindow **windows, *window;
DOMEvent *event; DOMEvent *event;
unsigned i, num;
HRESULT hres; HRESULT hres;
if(!window) if(!doc->window || !doc->doc_node->content_ready)
return;
window = doc->window->base.inner_window;
/* Grab list of all windows ahead, and keep refs,
since it can be detached from under our feet. */
num = get_window_list_num(window);
if(!(windows = malloc(num * sizeof(*windows))))
return; return;
get_window_list(window, windows);
for(i = 0; i < num; i++) {
window = windows[i];
if(window->doc && !window->doc->unload_sent) { if(window->doc && !window->doc->unload_sent) {
window->doc->unload_sent = TRUE; window->doc->unload_sent = TRUE;
/* Native sends pagehide events prior to unload on the same window
before it moves on to the next window, so they're interleaved. */
if(window->doc->document_mode >= COMPAT_MODE_IE11) {
hres = create_document_event(window->doc, EVENTID_PAGEHIDE, &event);
if(SUCCEEDED(hres)) {
dispatch_event(&window->event_target, event);
IDOMEvent_Release(&event->IDOMEvent_iface);
}
}
/* Native sends pagehide events prior to unload on the same window hres = create_document_event(window->doc, EVENTID_UNLOAD, &event);
before it moves on to the next window, so they're interleaved. */
if(window->doc->document_mode >= COMPAT_MODE_IE11) {
hres = create_document_event(window->doc, EVENTID_PAGEHIDE, &event);
if(SUCCEEDED(hres)) { if(SUCCEEDED(hres)) {
dispatch_event(&window->event_target, event); dispatch_event(&window->event_target, event);
IDOMEvent_Release(&event->IDOMEvent_iface); IDOMEvent_Release(&event->IDOMEvent_iface);
} }
} }
hres = create_document_event(window->doc, EVENTID_UNLOAD, &event); IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
if(SUCCEEDED(hres)) {
dispatch_event(&window->event_target, event);
IDOMEvent_Release(&event->IDOMEvent_iface);
}
} }
LIST_FOR_EACH_ENTRY(child, &window->children, HTMLOuterWindow, sibling_entry) free(windows);
send_unload_events_impl(child->base.inner_window);
}
static void send_unload_events(HTMLDocumentObj *doc)
{
if(!doc->window || !doc->doc_node->content_ready)
return;
send_unload_events_impl(doc->window->base.inner_window);
} }
/********************************************************** /**********************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment