[PATCH v3 0/5] MR7425: jscript: Obtain the jsdisp for host objects in other contexts.
-- v3: jscript: Get rid of the funcprot argument. mshtml: Release the node if there's no script global when handling events. mshtml: Make sure manually created document dispex info is initialized in jscript: Obtain the jsdisp for host objects in other contexts. mshtml: Keep the link from the inner window to the outer window even when https://gitlab.winehq.org/wine/wine/-/merge_requests/7425
From: Gabriel Ivăncescu <gabrielopcode(a)gmail.com> Until the outer window is actually unlinked. Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)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 | 12 +++++++++--- 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, 43 insertions(+), 33 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..e685da74c03 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -138,7 +138,6 @@ 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; @@ -3779,6 +3778,8 @@ static void HTMLWindow_destructor(DispatchEx *dispex) HTMLInnerWindow *This = impl_from_DispatchEx(dispex); unsigned i; + if(This->base.outer_window) + list_remove(&This->outer_window_entry); VariantClear(&This->performance); for(i = 0; i < This->global_prop_cnt; i++) @@ -4295,7 +4296,6 @@ static nsresult NSAPI outer_window_unlink(void *p) 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); } @@ -4318,6 +4318,11 @@ static nsresult NSAPI outer_window_unlink(void *p) unlink_ref(&window->window_proxy); wine_rb_remove(&window_map, &window->entry); } + while(!list_empty(&window->inner_windows)) { + HTMLInnerWindow *inner_window = LIST_ENTRY(list_head(&window->inner_windows), HTMLInnerWindow, outer_window_entry); + list_remove(&inner_window->outer_window_entry); + inner_window->base.outer_window = NULL; + } return NS_OK; } @@ -4399,6 +4404,7 @@ static HRESULT create_inner_window(HTMLOuterWindow *outer_window, IMoniker *mon, window->base.outer_window = outer_window; window->base.inner_window = window; + list_add_tail(&outer_window->inner_windows, &window->outer_window_entry); init_event_target(&window->event_target, &Window_dispex, NULL); @@ -4431,6 +4437,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->inner_windows); ccref_init(&window->ccref, 1); mozIDOMWindowProxy_AddRef(mozwindow); @@ -4483,7 +4490,6 @@ 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; 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..f306cff68c6 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -752,6 +752,7 @@ struct HTMLOuterWindow { BSTR url; DWORD load_flags; + struct list inner_windows; struct list sibling_entry; struct wine_rb_entry entry; }; @@ -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 !window->base.outer_window || (window->base.outer_window->base.inner_window != window && window->base.outer_window->pending_window != 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); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7425
From: Gabriel Ivăncescu <gabrielopcode(a)gmail.com> Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com> --- dlls/jscript/jsutils.c | 9 ++------- dlls/mshtml/tests/documentmode.js | 1 - dlls/mshtml/tests/es5.js | 15 +++++++++++++++ 3 files changed, 17 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..fe4c8ac7a7e 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,24 @@ 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"); + ok(Object.getPrototypeOf(doc) !== Object.getPrototypeOf(document), "doc's prototype same as doc prototype"); + ok(Object.getPrototypeOf(doc) === iframe.contentWindow.HTMLDocument.prototype, "doc's prototype not iframe's HTMLDocument.prototype"); 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"); + ok(Object.getPrototypeOf(doc) !== Object.getPrototypeOf(document), "created iframe doc's prototype same as doc prototype"); + todo_wine. + ok(Object.getPrototypeOf(doc) === iframe.contentWindow.HTMLDocument.prototype, "created iframe doc's prototype not iframe's HTMLDocument.prototype"); + + 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(); }); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7425
From: Gabriel Ivăncescu <gabrielopcode(a)gmail.com> Otherwise, the prototype and all the related info may never be initialized, as the script can simply access properties of the object without interacting with the object's methods and so ensure_real_info never ends up called. Note that we can't do this from within create_document_node, as that will break if it's a document created from update_window_doc (the window's doc is not set at that point, since it's being created, and ensure_real_info needs it). Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com> --- dlls/mshtml/omnavigator.c | 8 +++++++- dlls/mshtml/tests/es5.js | 11 +++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 6b255d4cd54..8dd785e72ba 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -113,6 +113,7 @@ static HRESULT WINAPI HTMLDOMImplementation2_createHTMLDocument(IHTMLDOMImplemen { HTMLDOMImplementation *This = impl_from_IHTMLDOMImplementation2(iface); HTMLDocumentNode *new_document_node; + compat_mode_t compat_mode; nsIDOMDocument *doc; nsAString title_str; nsresult nsres; @@ -131,12 +132,17 @@ static HRESULT WINAPI HTMLDOMImplementation2_createHTMLDocument(IHTMLDOMImplemen return E_FAIL; } + compat_mode = dispex_compat_mode(&This->dispex); hres = create_document_node(doc, This->doc->browser, NULL, This->doc->script_global, - dispex_compat_mode(&This->dispex), &new_document_node); + compat_mode, &new_document_node); nsIDOMDocument_Release(doc); if(FAILED(hres)) return hres; + /* make sure dispex info is initialized for the prototype */ + if(compat_mode >= COMPAT_MODE_IE9) + dispex_compat_mode(&new_document_node->node.event_target.dispex); + *new_document = &new_document_node->IHTMLDocument7_iface; return S_OK; } diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index fe4c8ac7a7e..2f62f051d33 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -2845,7 +2845,6 @@ async_test("script_global", function() { // Created documents share script global, so their objects are instances of Object from // the current script context. var doc = document.implementation.createHTMLDocument("test"); - 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"); @@ -2870,9 +2869,17 @@ async_test("script_global", function() { 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"); ok(Object.getPrototypeOf(doc) !== Object.getPrototypeOf(document), "created iframe doc's prototype same as doc prototype"); - todo_wine. ok(Object.getPrototypeOf(doc) === iframe.contentWindow.HTMLDocument.prototype, "created iframe doc's prototype not iframe's HTMLDocument.prototype"); + Object.defineProperty(doc, "winetest", { writable: true, enumerable: true, configurable: true, value: 42 }); + test_own_data_prop_desc(doc, "winetest", true, true, true); + + ok(Object.isFrozen(doc) === false, "created iframe doc isFrozen is not false"); + ok(Object.isSealed(doc) === false, "created iframe doc isSealed is not false"); + Object.freeze(doc); + ok(Object.isFrozen(doc) === true, "created iframe doc isFrozen is not true after freezing it"); + ok(Object.isSealed(doc) === true, "created iframe doc isSealed is not true after freezing it"); + 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); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7425
From: Gabriel Ivăncescu <gabrielopcode(a)gmail.com> Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)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; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7425
From: Gabriel Ivăncescu <gabrielopcode(a)gmail.com> Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)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"; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7425
This merge request was approved by Jacek Caban. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/7425
participants (2)
-
Gabriel Ivăncescu -
Jacek Caban (@jacek)