-- v2: jscript: Get rid of the funcprot argument. mshtml: Release the node if there's no script global when handling events. jscript: Obtain the jsdisp for host objects in other contexts. mshtml: Keep the link from the inner window to the outer window even when
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Until the outer window is actually unlinked.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlanchor.c | 4 ++-- dlls/mshtml/htmldoc.c | 20 ++++++++++---------- dlls/mshtml/htmlform.c | 2 +- dlls/mshtml/htmlframe.c | 2 +- dlls/mshtml/htmlstorage.c | 1 - dlls/mshtml/htmlwindow.c | 25 ++++++++++++++++++++----- dlls/mshtml/mshtml_private.h | 8 ++++++++ dlls/mshtml/mutation.c | 2 +- dlls/mshtml/navigate.c | 8 ++++---- dlls/mshtml/nsevents.c | 6 +++--- dlls/mshtml/olecmd.c | 2 +- dlls/mshtml/script.c | 6 +++--- dlls/mshtml/tests/events.c | 3 --- 13 files changed, 54 insertions(+), 35 deletions(-)
diff --git a/dlls/mshtml/htmlanchor.c b/dlls/mshtml/htmlanchor.c index 6f328b8173c..15d2c50cf17 100644 --- a/dlls/mshtml/htmlanchor.c +++ b/dlls/mshtml/htmlanchor.c @@ -49,7 +49,7 @@ static HRESULT navigate_href_new_window(HTMLElement *element, nsAString *href_st IUri *uri; HRESULT hres;
- if(!element->node.doc->window->base.outer_window) + if(is_detached_window(element->node.doc->window)) return S_OK;
nsAString_GetData(href_str, &href); @@ -114,7 +114,7 @@ static HRESULT navigate_href(HTMLElement *element, nsAString *href_str, nsAStrin const PRUnichar *href; HRESULT hres;
- if(!element->node.doc->window->base.outer_window) + if(is_detached_window(element->node.doc->window)) return S_OK;
window = get_target_window(element->node.doc->window->base.outer_window, target_str, &use_new_window); diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 6ae7ccb36e4..ffd594291f3 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -816,7 +816,7 @@ static HRESULT WINAPI HTMLDocument_get_frames(IHTMLDocument2 *iface, IHTMLFrames /* Not implemented by IE */ return E_NOTIMPL; } - if(!This->window->base.outer_window) + if(is_detached_window(This->window)) return E_FAIL; return IHTMLWindow2_get_frames(&This->window->base.outer_window->base.IHTMLWindow2_iface, p); } @@ -1000,7 +1000,7 @@ static HRESULT WINAPI HTMLDocument_put_URL(IHTMLDocument2 *iface, BSTR v)
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
- if(!This->window || !This->window->base.outer_window) { + if(!This->window || is_detached_window(This->window)) { FIXME("No window available\n"); return E_FAIL; } @@ -1015,7 +1015,7 @@ static HRESULT WINAPI HTMLDocument_get_URL(IHTMLDocument2 *iface, BSTR *p)
TRACE("(%p)->(%p)\n", iface, p);
- if(This->window && !This->window->base.outer_window) { + if(This->window && is_detached_window(This->window)) { WARN("detached document\n"); return E_FAIL; } @@ -1064,7 +1064,7 @@ static HRESULT WINAPI HTMLDocument_get_domain(IHTMLDocument2 *iface, BSTR *p) return E_NOTIMPL; }
- if(This->window && (!This->window->base.outer_window || !This->window->base.outer_window->uri)) + if(This->window && (is_detached_window(This->window) || !This->window->base.outer_window->uri)) return E_FAIL;
nsAString_Init(&nsstr, NULL); @@ -1094,7 +1094,7 @@ static HRESULT WINAPI HTMLDocument_put_cookie(IHTMLDocument2 *iface, BSTR v)
if(!This->window) return S_OK; - if(!This->window->base.outer_window) + if(is_detached_window(This->window)) return E_FAIL;
bret = InternetSetCookieExW(This->window->base.outer_window->url, NULL, v, 0, 0); @@ -1118,7 +1118,7 @@ static HRESULT WINAPI HTMLDocument_get_cookie(IHTMLDocument2 *iface, BSTR *p) *p = NULL; return S_OK; } - if(!This->window->base.outer_window) + if(is_detached_window(This->window)) return E_FAIL;
size = 0; @@ -1367,7 +1367,7 @@ static HRESULT WINAPI HTMLDocument_open(IHTMLDocument2 *iface, BSTR url, VARIANT
*pomWindowResult = NULL;
- if(!This->window || !This->window->base.outer_window) + if(!This->window || is_detached_window(This->window)) return E_FAIL;
if(!This->dom_document) { @@ -2224,7 +2224,7 @@ static HRESULT WINAPI HTMLDocument3_get_documentElement(IHTMLDocument3 *iface, I TRACE("(%p)->(%p)\n", This, p);
if(This->window) { - if(!This->window->base.outer_window) + if(is_detached_window(This->window)) return E_FAIL; if(This->window->base.outer_window->readystate == READYSTATE_UNINITIALIZED) { *p = NULL; @@ -4493,7 +4493,7 @@ static void HTMLDocumentNode_on_advise(IUnknown *iface, cp_static_data_t *cp) { HTMLDocumentNode *This = CONTAINING_RECORD((IHTMLDocument2*)iface, HTMLDocumentNode, IHTMLDocument2_iface);
- if(This->window && This->window->base.outer_window) + if(This->window && !is_detached_window(This->window)) update_doc_cp_events(This, cp); }
@@ -5589,7 +5589,7 @@ static HRESULT HTMLDocumentNode_location_hook(DispatchEx *dispex, WORD flags, DI
if(!(flags & DISPATCH_PROPERTYPUT) || !This->window) return S_FALSE; - if(!This->window->base.outer_window) + if(is_detached_window(This->window)) return E_FAIL;
return IWineJSDispatchHost_InvokeEx(&This->window->event_target.dispex.IWineJSDispatchHost_iface, diff --git a/dlls/mshtml/htmlform.c b/dlls/mshtml/htmlform.c index 153133493f6..1b90a7bd0e1 100644 --- a/dlls/mshtml/htmlform.c +++ b/dlls/mshtml/htmlform.c @@ -519,7 +519,7 @@ static HRESULT WINAPI HTMLFormElement_submit(IHTMLFormElement *iface)
if(This->element.node.doc) { HTMLDocumentNode *doc = This->element.node.doc; - if(doc->window && doc->window->base.outer_window) + if(doc->window && !is_detached_window(doc->window)) this_window = doc->window->base.outer_window; } if(!this_window) { diff --git a/dlls/mshtml/htmlframe.c b/dlls/mshtml/htmlframe.c index 193be9f6323..62a826ffbae 100644 --- a/dlls/mshtml/htmlframe.c +++ b/dlls/mshtml/htmlframe.c @@ -79,7 +79,7 @@ static HRESULT WINAPI HTMLFrameBase_put_src(IHTMLFrameBase *iface, BSTR v)
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
- if(!This->content_window || !This->element.node.doc || !This->element.node.doc->window || !This->element.node.doc->window->base.outer_window) { + if(!This->content_window || !This->element.node.doc || !This->element.node.doc->window || is_detached_window(This->element.node.doc->window)) { nsAString nsstr; nsresult nsres;
diff --git a/dlls/mshtml/htmlstorage.c b/dlls/mshtml/htmlstorage.c index 8fb5679089a..98c1202e315 100644 --- a/dlls/mshtml/htmlstorage.c +++ b/dlls/mshtml/htmlstorage.c @@ -332,7 +332,6 @@ static HRESULT send_storage_event(HTMLStorage *storage, BSTR key, BSTR old_value
ctx.url = NULL;
- /* FIXME: Events are actually sent to the current window on native, even if we're detached. */ if(!window->base.outer_window) goto done;
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index b56c6a327cc..07ad4d88233 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -111,6 +111,10 @@ static void detach_inner_window(HTMLInnerWindow *window) HTMLOuterWindow *outer_window = window->base.outer_window; HTMLDocumentNode *doc = window->doc, *doc_iter;
+ /* Check if already detached */ + if(!list_empty(&window->outer_window_entry)) + return; + while(!list_empty(&window->children)) { HTMLOuterWindow *child = LIST_ENTRY(list_tail(&window->children), HTMLOuterWindow, sibling_entry);
@@ -138,11 +142,13 @@ static void detach_inner_window(HTMLInnerWindow *window) abort_window_bindings(window); release_script_hosts(window); unlink_ref(&window->jscript); - window->base.outer_window = NULL;
- if(outer_window && outer_window->base.inner_window == window) { - outer_window->base.inner_window = NULL; - IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + if(outer_window) { + list_add_tail(&outer_window->detached_inner_windows, &window->outer_window_entry); + if(outer_window->base.inner_window == window) { + outer_window->base.inner_window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } } }
@@ -3779,6 +3785,7 @@ static void HTMLWindow_destructor(DispatchEx *dispex) HTMLInnerWindow *This = impl_from_DispatchEx(dispex); unsigned i;
+ list_remove(&This->outer_window_entry); VariantClear(&This->performance);
for(i = 0; i < This->global_prop_cnt; i++) @@ -4318,6 +4325,12 @@ static nsresult NSAPI outer_window_unlink(void *p) unlink_ref(&window->window_proxy); wine_rb_remove(&window_map, &window->entry); } + while(!list_empty(&window->detached_inner_windows)) { + HTMLInnerWindow *inner_window = LIST_ENTRY(list_head(&window->detached_inner_windows), HTMLInnerWindow, outer_window_entry); + list_remove(&inner_window->outer_window_entry); + list_init(&inner_window->outer_window_entry); + inner_window->base.outer_window = NULL; + } return NS_OK; }
@@ -4396,6 +4409,7 @@ static HRESULT create_inner_window(HTMLOuterWindow *outer_window, IMoniker *mon, list_init(&window->script_hosts); list_init(&window->bindings); list_init(&window->script_queue); + list_init(&window->outer_window_entry);
window->base.outer_window = outer_window; window->base.inner_window = window; @@ -4431,6 +4445,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); + list_init(&window->detached_inner_windows); ccref_init(&window->ccref, 1);
mozIDOMWindowProxy_AddRef(mozwindow); @@ -4483,7 +4498,7 @@ HRESULT create_pending_window(HTMLOuterWindow *outer_window, nsChannelBSC *chann
if(outer_window->pending_window) { abort_window_bindings(outer_window->pending_window); - outer_window->pending_window->base.outer_window = NULL; + list_add_tail(&outer_window->detached_inner_windows, &outer_window->pending_window->outer_window_entry); IHTMLWindow2_Release(&outer_window->pending_window->base.IHTMLWindow2_iface); }
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 95f7a5f4941..53e6bbe08a8 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -754,6 +754,7 @@ struct HTMLOuterWindow {
struct list sibling_entry; struct wine_rb_entry entry; + struct list detached_inner_windows; };
struct HTMLInnerWindow { @@ -818,6 +819,8 @@ struct HTMLInnerWindow { ULONGLONG load_event_start_time; ULONGLONG load_event_end_time; ULONGLONG first_paint_time; + + struct list outer_window_entry; };
typedef enum { @@ -1312,6 +1315,11 @@ static inline BOOL is_main_content_window(HTMLOuterWindow *window) return window->browser && window == window->browser->content_window; }
+static inline BOOL is_detached_window(HTMLInnerWindow *window) +{ + return !list_empty(&window->outer_window_entry) || !window->base.outer_window; +} + struct HTMLAttributeCollection { DispatchEx dispex; IHTMLAttributeCollection IHTMLAttributeCollection_iface; diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index 6cc969cf634..a203c03e2dc 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -446,7 +446,7 @@ static void set_document_mode(HTMLDocumentNode *doc, compat_mode_t document_mode
TRACE("%p: %d\n", doc, document_mode);
- max_compat_mode = doc->window && doc->window->base.outer_window + max_compat_mode = doc->window && !is_detached_window(doc->window) ? get_max_compat_mode(doc->window->base.outer_window->uri) : COMPAT_MODE_IE11; if(max_compat_mode < document_mode) { diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index 90ca22ea8b1..f05bf0be9c6 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -578,7 +578,7 @@ static HRESULT WINAPI BindCallbackRedirect_Redirect(IBindCallbackRedirect *iface
TRACE("(%p)->(%s %p)\n", This, debugstr_w(url), vbCancel);
- if(This->window && This->window->base.outer_window && (browser = This->window->base.outer_window->browser) + if(This->window && !is_detached_window(This->window) && (browser = This->window->base.outer_window->browser) && browser->doc->doc_object_service) { if(is_main_content_window(This->window->base.outer_window)) { hres = IHTMLWindow2_get_name(&This->window->base.IHTMLWindow2_iface, &frame_name); @@ -1269,7 +1269,7 @@ static nsresult NSAPI nsAsyncVerifyRedirectCallback_OnRedirectVerifyCallback(nsI ERR("AddRequest failed: %08lx\n", nsres); }
- if(This->bsc->is_doc_channel && This->bsc->bsc.window && This->bsc->bsc.window->base.outer_window) { + if(This->bsc->is_doc_channel && This->bsc->bsc.window && !is_detached_window(This->bsc->bsc.window)) { IUri *uri = nsuri_get_uri(This->nschannel->uri);
if(uri) { @@ -1445,7 +1445,7 @@ static void handle_navigation_error(nsChannelBSC *This, DWORD result) BSTR unk; HRESULT hres;
- if(!This->is_doc_channel || !This->bsc.window || !This->bsc.window->base.outer_window + if(!This->is_doc_channel || !This->bsc.window || is_detached_window(This->bsc.window) || !This->bsc.window->base.outer_window->browser) return;
@@ -1644,7 +1644,7 @@ static void handle_extern_mime_navigation(nsChannelBSC *This) VARIANT flags; HRESULT hres;
- if(!This->bsc.window || !This->bsc.window->base.outer_window || !This->bsc.window->base.outer_window->browser) + if(!This->bsc.window || is_detached_window(This->bsc.window) || !This->bsc.window->base.outer_window->browser) return;
doc_obj = This->bsc.window->base.outer_window->browser->doc; diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index 5d52cf4f17a..ee0e04f1aa9 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -316,7 +316,7 @@ static nsresult handle_load(HTMLDocumentNode *doc, nsIDOMEvent *event)
TRACE("(%p)\n", doc);
- if(!doc->window || !doc->window->base.outer_window) + if(!doc->window || is_detached_window(doc->window)) return NS_ERROR_FAILURE; if(doc->doc_obj && doc->doc_obj->doc_node == doc) { doc_obj = doc->doc_obj; @@ -328,7 +328,7 @@ static nsresult handle_load(HTMLDocumentNode *doc, nsIDOMEvent *event) handle_docobj_load(doc_obj);
doc->window->dom_complete_time = get_time_stamp(); - if(doc->window->base.outer_window) + if(!is_detached_window(doc->window)) set_ready_state(doc->window->base.outer_window, READYSTATE_COMPLETE);
if(doc_obj) { @@ -339,7 +339,7 @@ static nsresult handle_load(HTMLDocumentNode *doc, nsIDOMEvent *event)
update_title(doc_obj);
- if(doc_obj->doc_object_service && doc->window->base.outer_window && !(doc->window->base.outer_window->load_flags & BINDING_REFRESH)) + if(doc_obj->doc_object_service && !is_detached_window(doc->window) && !(doc->window->base.outer_window->load_flags & BINDING_REFRESH)) IDocObjectService_FireDocumentComplete(doc_obj->doc_object_service, &doc->window->base.outer_window->base.IHTMLWindow2_iface, 0);
diff --git a/dlls/mshtml/olecmd.c b/dlls/mshtml/olecmd.c index 650c44c9d2b..8d0eafee812 100644 --- a/dlls/mshtml/olecmd.c +++ b/dlls/mshtml/olecmd.c @@ -490,7 +490,7 @@ static HRESULT exec_refresh(HTMLDocumentNode *doc, DWORD nCmdexecopt, VARIANT *p } }
- if(!doc->window || !doc->window->base.outer_window) + if(!doc->window || is_detached_window(doc->window)) return E_UNEXPECTED;
return reload_page(doc->window->base.outer_window); diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c index 3ad1da8cf3c..a6ebb4a266d 100644 --- a/dlls/mshtml/script.c +++ b/dlls/mshtml/script.c @@ -419,7 +419,7 @@ static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPC if(wcscmp(pstrName, L"window")) return DISP_E_MEMBERNOTFOUND;
- if(!This->window || !This->window->base.outer_window) + if(!This->window || is_detached_window(This->window)) return E_FAIL;
if(dispex_compat_mode(&This->window->event_target.dispex) >= COMPAT_MODE_IE9) @@ -565,7 +565,7 @@ static HRESULT WINAPI ActiveScriptSiteWindow_GetWindow(IActiveScriptSiteWindow *
TRACE("(%p)->(%p)\n", This, phwnd);
- if(!This->window || !This->window->base.outer_window) + if(!This->window || is_detached_window(This->window)) return E_UNEXPECTED;
*phwnd = This->window->base.outer_window->browser->doc->hwnd; @@ -1433,7 +1433,7 @@ static ScriptHost *get_script_host(HTMLInnerWindow *window, const GUID *guid)
void initialize_script_global(HTMLInnerWindow *script_global) { - if(!script_global->base.outer_window) + if(is_detached_window(script_global)) return; get_script_host(script_global, &CLSID_JScript); } diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 135b5ab4060..bdfbb6c6b78 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -4138,7 +4138,6 @@ static void test_window_refs(IHTMLDocument2 *doc)
hres = IOmHistory_get_length(history, &length); ok(hres == S_OK, "get_length failed: %08lx\n", hres); - todo_wine ok(length == 42, "length = %d\n", length); IOmHistory_Release(history); } @@ -4403,9 +4402,7 @@ static void test_doc_obj(IHTMLDocument2 *doc) ok(doc_node != doc_node2, "doc_node == doc_node2\n");
hres = IHTMLDocument2_get_parentWindow(doc_node, &window2); - todo_wine ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres); - todo_wine ok(window == window2, "window != window2\n"); if(hres == S_OK) IHTMLWindow2_Release(window2);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/jsutils.c | 9 ++------- dlls/mshtml/tests/documentmode.js | 1 - dlls/mshtml/tests/es5.js | 10 ++++++++++ 3 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c index 2c6516e06bb..1d6fa06a993 100644 --- a/dlls/jscript/jsutils.c +++ b/dlls/jscript/jsutils.c @@ -293,13 +293,8 @@ HRESULT variant_to_jsval(script_ctx_t *ctx, VARIANT *var, jsval_t *r) hres = IWineJSDispatchHost_GetJSDispatch(disp_host, &jsdisp_iface); IWineJSDispatchHost_Release(disp_host); if(SUCCEEDED(hres)) { - jsdisp_t *jsdisp = as_jsdisp((IDispatch *)jsdisp_iface); - if(jsdisp->ctx == ctx) { - *r = jsval_obj(jsdisp); - return S_OK; - }else { - jsdisp_release(jsdisp); - } + *r = jsval_obj(as_jsdisp((IDispatch *)jsdisp_iface)); + return S_OK; } } } diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 164f5e2bce4..5bbd8b098f6 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -2300,7 +2300,6 @@ async_test("storage events", function() { return; } var s = Object.prototype.toString.call(e); - todo_wine_if(e.target != window && e.target != document). ok(s === "[object StorageEvent]", "Object.toString = " + s); ok(e.key === key, "key = " + e.key + ", expected " + key); ok(e.oldValue === oldValue, "oldValue = " + e.oldValue + ", expected " + oldValue); diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 40458c103c9..02d83b607ca 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -2848,6 +2848,7 @@ async_test("script_global", function() { todo_wine. ok(doc instanceof Object, "created doc is not an instance of Object"); ok(doc.implementation instanceof Object, "created doc.implementation is not an instance of Object"); + ok(doc.implementation instanceof DOMImplementation, "created doc.implementation is not an instance of DOMImplementation");
document.body.innerHTML = ""; var iframe = document.createElement("iframe"); @@ -2858,10 +2859,19 @@ async_test("script_global", function() { var doc = iframe.contentWindow.document; ok(!(doc instanceof Object), "doc is an instance of Object"); ok(!(doc.implementation instanceof Object), "doc.implementation is an instance of Object"); + ok(!(doc.implementation instanceof DOMImplementation), "doc.implementation is an instance of DOMImplementation"); + ok(doc.implementation instanceof iframe.contentWindow.DOMImplementation, "doc.implementation is not an instance of iframe's DOMImplementation");
doc = doc.implementation.createHTMLDocument("test"); ok(!(doc instanceof Object), "created iframe doc is an instance of Object"); ok(!(doc.implementation instanceof Object), "created iframe doc.implementation is an instance of Object"); + ok(!(doc.implementation instanceof DOMImplementation), "created iframe doc.implementation is an instance of DOMImplementation"); + ok(doc.implementation instanceof iframe.contentWindow.DOMImplementation, "created iframe doc.implementation is not an instance of iframe's DOMImplementation"); + + var r = Object.prototype.toString.call(iframe.contentWindow); + ok(r === "[object Window]", "iframe's Window toString = " + r); + r = Object.prototype.toString.call(iframe.contentWindow.DOMImplementation); + ok(r === "[object DOMImplementation]", "iframe's DOMImplementation toString = " + r);
next_test(); });
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/nsevents.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index ee0e04f1aa9..342615a9e67 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -441,8 +441,12 @@ static nsresult handle_htmlevent(HTMLDocumentNode *doc, nsIDOMEvent *nsevent) }else { hres = get_node(nsnode, TRUE, &node); nsIDOMNode_Release(nsnode); - if(FAILED(hres) || !node->doc->script_global) + if(FAILED(hres)) + return NS_OK; + if(!node->doc->script_global) { + IHTMLDOMNode_Release(&node->IHTMLDOMNode_iface); return NS_OK; + } target = &node->event_target; }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/function.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 5330bbae21f..848ee657dc2 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -709,7 +709,7 @@ static const builtin_info_t FunctionInst_info = { };
static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_info, const function_vtbl_t *vtbl, size_t size, - DWORD flags, BOOL funcprot, jsdisp_t *prototype, void **ret) + DWORD flags, jsdisp_t *prototype, void **ret) { FunctionInstance *function; HRESULT hres; @@ -718,7 +718,7 @@ static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_ if(!function) return E_OUTOFMEMORY;
- if(funcprot) + if(prototype) hres = init_dispex(&function->dispex, ctx, builtin_info, prototype); else if(builtin_info) hres = init_dispex_from_constr(&function->dispex, ctx, builtin_info, ctx->function_constr); @@ -779,7 +779,7 @@ HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc, if(!ctx->function_constr) return E_UNEXPECTED;
- hres = create_function(ctx, builtin_info, &NativeFunctionVtbl, sizeof(NativeFunction), flags, FALSE, NULL, (void**)&function); + hres = create_function(ctx, builtin_info, &NativeFunctionVtbl, sizeof(NativeFunction), flags, NULL, (void**)&function); if(FAILED(hres)) return hres;
@@ -957,7 +957,7 @@ HRESULT create_source_function(script_ctx_t *ctx, bytecode_t *code, function_cod HRESULT hres;
hres = create_function(ctx, &InterpretedFunction_info, &InterpretedFunctionVtbl, sizeof(InterpretedFunction), - PROPF_CONSTR, FALSE, NULL, (void**)&function); + PROPF_CONSTR, NULL, (void**)&function); if(FAILED(hres)) return hres;
@@ -1078,7 +1078,7 @@ HRESULT create_host_function(script_ctx_t *ctx, const struct property_info *desc return E_UNEXPECTED;
hres = create_function(ctx, &HostFunction_info, &HostFunctionVtbl, sizeof(HostFunction), PROPF_METHOD, - FALSE, NULL, (void**)&function); + NULL, (void**)&function); if(FAILED(hres)) return hres;
@@ -1194,7 +1194,7 @@ HRESULT init_host_constructor(script_ctx_t *ctx, IWineJSDispatchHost *host_const HRESULT hres;
hres = create_function(ctx, &HostConstructor_info, &HostConstructorVtbl, sizeof(*function), PROPF_METHOD, - FALSE, NULL, (void**)&function); + NULL, (void**)&function); if(FAILED(hres)) return hres; function->host_iface = host_constr; @@ -1322,7 +1322,7 @@ static HRESULT create_bind_function(script_ctx_t *ctx, FunctionInstance *target, HRESULT hres;
hres = create_function(ctx, &BindFunction_info, &BindFunctionVtbl, FIELD_OFFSET(BindFunction, args[argc]), PROPF_METHOD, - FALSE, NULL, (void**)&function); + NULL, (void**)&function); if(FAILED(hres)) return hres;
@@ -1479,7 +1479,7 @@ HRESULT init_function_constr(script_ctx_t *ctx, jsdisp_t *object_prototype) HRESULT hres;
hres = create_function(ctx, &Function_info, &NativeFunctionVtbl, sizeof(NativeFunction), PROPF_CONSTR, - TRUE, object_prototype, (void**)&prot); + object_prototype, (void**)&prot); if(FAILED(hres)) return hres;
@@ -1487,7 +1487,7 @@ HRESULT init_function_constr(script_ctx_t *ctx, jsdisp_t *object_prototype) prot->name = L"prototype";
hres = create_function(ctx, &FunctionInst_info, &NativeFunctionVtbl, sizeof(NativeFunction), PROPF_CONSTR|1, - TRUE, &prot->function.dispex, (void**)&constr); + &prot->function.dispex, (void**)&constr); if(SUCCEEDED(hres)) { constr->proc = FunctionConstr_value; constr->name = L"Function";
On Thu Feb 27 20:36:00 2025 +0000, Gabriel Ivăncescu wrote:
Sorry for the delay, I had an emergency to take care of today. `IObjectIdentity` isn't going to work, the problem itself isn't that we get a different jsdisp by itself. `disp_cmp` already checks for the host object, in this particular case GetOuterDispatch results in the outer window. The problem is that the old iframe's inner window is detached on navigation. Thus, GetOuterDispatch will return the inner window's disp instead of the outer window, so it will mismatch. This isn't a problem if we "migrate" the jsdisp though, but that's not pretty as you said. I remember I had a patch awhile ago to deal with this issue (and add tests to confirm it) by storing strong (cyclic) ref between inner and outer windows, maybe I need to revive it. But that one was also "not very pretty" and I had to drop it. At this point I don't know what to do anymore with this particular problem, it keeps popping up and I can't find a "clean" solution. Maybe I'm missing something, but should I revive the outer window<->inner window cyclic ref patch again? Anyway I think that patch is better (in functionality/correctness) than the jsdisp migration, and since both aren't pretty I guess it's a better contender.
I went with a weak ref and unlink like it's done for script_global and documents. If we don't have any refs to the outer window it doesn't really matter anymore, anyway, so it's fine.
This also fixes those todo_wines I added back then when it was initially rejected, and needed for second patch to not break tests, hopefully it's better now?
Jacek Caban (@jacek) commented about dlls/mshtml/mshtml_private.h:
struct list sibling_entry; struct wine_rb_entry entry;
- struct list detached_inner_windows;
Instead of special-casing detached windows, I think it would be cleaner to have a list of all inner windows (including the one that's currently active). To check if a window is detached, you may simply compare the current active window pointer to the one you're testing.
Jacek Caban (@jacek) commented about dlls/mshtml/tests/es5.js:
var doc = iframe.contentWindow.document; ok(!(doc instanceof Object), "doc is an instance of Object"); ok(!(doc.implementation instanceof Object), "doc.implementation is an instance of Object");
ok(!(doc.implementation instanceof DOMImplementation), "doc.implementation is an instance of DOMImplementation");
ok(doc.implementation instanceof iframe.contentWindow.DOMImplementation, "doc.implementation is not an instance of iframe's DOMImplementation");
It would be nice to add a few more simple tests dealing with different contexts. `getPrototypeOf` seems interesting, but some random simple functions like `isFrozen` or `defineProperty` would be nice to have too.
On Mon Mar 31 18:57:34 2025 +0000, Jacek Caban wrote:
Instead of special-casing detached windows, I think it would be cleaner to have a list of all inner windows (including the one that's currently active). To check if a window is detached, you may simply compare the current active window pointer to the one you're testing.
I also had to add check for `pending_window` but other than that it's fine.
On Mon Mar 31 18:57:34 2025 +0000, Jacek Caban wrote:
It would be nice to add a few more simple tests dealing with different contexts. `getPrototypeOf` seems interesting, but some random simple functions like `isFrozen` or `defineProperty` would be nice to have too.
Interesting, those tests needed another fix, added on 3rd patch.