This get us pass the "Update your browser" blocker in adobe's sign-in page. The page itself doesn't make use of `window.MutationObserver`.
However the sign-in page is still broken.
-- v14: mshtml: add stubs for MutationObserver methods mshtml: implement window.MutationObserver with MutationObserver stub
From: Yuxuan Shui yshui@codeweavers.com
--- dlls/mshtml/htmlwindow.c | 33 +++- dlls/mshtml/mshtml_private.h | 6 +- dlls/mshtml/mshtml_private_iface.idl | 14 ++ dlls/mshtml/mutation.c | 282 +++++++++++++++++++++++++++ dlls/mshtml/tests/documentmode.js | 50 +++++ 5 files changed, 383 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index c6072c7e9fa..b1d423e8e34 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -309,6 +309,9 @@ static void release_inner_window(HTMLInnerWindow *This) if(This->mon) IMoniker_Release(This->mon);
+ if(This->mutation_observer_ctor) + IDispatch_Release(This->mutation_observer_ctor); + free(This); }
@@ -3330,6 +3333,26 @@ static HRESULT WINAPI window_private_get_console(IWineHTMLWindowPrivate *iface, return S_OK; }
+static HRESULT WINAPI window_private_get_MutationObserver(IWineHTMLWindowPrivate *iface, + IDispatch **mutation_observer) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowPrivateVtbl(iface); + HRESULT hres; + + FIXME("iface %p, mutation_observer %p, stub.\n", iface, mutation_observer); + + if (!This->inner_window->mutation_observer_ctor) { + hres = create_mutation_observer_ctor(dispex_compat_mode(&This->inner_window->event_target.dispex), + &This->inner_window->mutation_observer_ctor); + if (FAILED(hres)) + return hres; + } + + IDispatch_AddRef(This->inner_window->mutation_observer_ctor); + *mutation_observer = This->inner_window->mutation_observer_ctor; + return S_OK; +} + static const IWineHTMLWindowPrivateVtbl WineHTMLWindowPrivateVtbl = { window_private_QueryInterface, window_private_AddRef, @@ -3343,6 +3366,7 @@ static const IWineHTMLWindowPrivateVtbl WineHTMLWindowPrivateVtbl = { window_private_get_console, window_private_matchMedia, window_private_postMessage, + window_private_get_MutationObserver };
static inline HTMLWindow *impl_from_IWineHTMLWindowCompatPrivateVtbl(IWineHTMLWindowCompatPrivate *iface) @@ -3975,12 +3999,19 @@ static void HTMLWindow_init_dispex_info(dispex_data_t *info, compat_mode_t compa {DISPID_UNKNOWN} };
+ /* Hide props not available in IE10 */ + static const dispex_hook_t private_ie10_hooks[] = { + {DISPID_IWINEHTMLWINDOWPRIVATE_MUTATIONOBSERVER}, + {DISPID_UNKNOWN} + }; + if(compat_mode >= COMPAT_MODE_IE9) dispex_info_add_interface(info, IHTMLWindow7_tid, NULL); else dispex_info_add_interface(info, IWineHTMLWindowCompatPrivate_tid, NULL); if(compat_mode >= COMPAT_MODE_IE10) - dispex_info_add_interface(info, IWineHTMLWindowPrivate_tid, NULL); + dispex_info_add_interface(info, IWineHTMLWindowPrivate_tid, + compat_mode >= COMPAT_MODE_IE11 ? NULL : private_ie10_hooks);
dispex_info_add_interface(info, IHTMLWindow5_tid, NULL); dispex_info_add_interface(info, IHTMLWindow4_tid, compat_mode >= COMPAT_MODE_IE11 ? window4_ie11_hooks : NULL); diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 59d652a828b..ffd179f1124 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -294,7 +294,8 @@ typedef struct EventTarget EventTarget; XIID(IWinePageTransitionEvent) \ XIID(IWineXMLHttpRequestPrivate) \ XIID(IWineMSHTMLConsole) \ - XIID(IWineMSHTMLMediaQueryList) + XIID(IWineMSHTMLMediaQueryList) \ + XIID(IWineMSHTMLMutationObserver)
typedef enum { #define XIID(iface) iface ## _tid, @@ -619,6 +620,7 @@ struct HTMLInnerWindow { LONG task_magic;
IMoniker *mon; + IDispatch *mutation_observer_ctor; nsChannelBSC *bscallback; struct list bindings; }; @@ -1479,3 +1481,5 @@ IInternetSecurityManager *get_security_manager(void); extern HINSTANCE hInst; void create_console(compat_mode_t compat_mode, IWineMSHTMLConsole **ret); HRESULT create_media_query_list(HTMLWindow *window, BSTR media_query, IDispatch **ret); + +HRESULT create_mutation_observer_ctor(compat_mode_t compat_mode, IDispatch **ret); diff --git a/dlls/mshtml/mshtml_private_iface.idl b/dlls/mshtml/mshtml_private_iface.idl index c0bb30fbbc8..46bae638fa5 100644 --- a/dlls/mshtml/mshtml_private_iface.idl +++ b/dlls/mshtml/mshtml_private_iface.idl @@ -76,6 +76,17 @@ interface IWineMSHTMLConsole : IDispatch HRESULT warn([in, optional] VARIANT *varargStart); }
+[ + odl, + oleautomation, + dual, + hidden, + uuid(6ac5491e-1758-4b82-98a2-83e31a7c8871) +] +interface IWineMSHTMLMutationObserver : IDispatch +{ +} + [ odl, oleautomation, @@ -95,6 +106,7 @@ interface IWineMSHTMLMediaQueryList : IDispatch HRESULT removeListener([in] VARIANT *listener); }
+const long DISPID_IWINEHTMLWINDOWPRIVATE_MUTATIONOBSERVER = 55; [ odl, oleautomation, @@ -114,6 +126,8 @@ interface IWineHTMLWindowPrivate : IDispatch HRESULT matchMedia([in] BSTR media_query, [retval, out] IDispatch **media_query_list); [id(54)] HRESULT postMessage([in] VARIANT msg, [in] BSTR targetOrigin, [in, optional] VARIANT transfer); + [propget, id(DISPID_IWINEHTMLWINDOWPRIVATE_MUTATIONOBSERVER)] + HRESULT MutationObserver([retval, out] IDispatch **observer_ctor); }
[ diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index 83ab623aea8..c895b7f5469 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -1076,3 +1076,285 @@ void init_mutation(nsIComponentManager *component_manager) if(NS_FAILED(nsres)) ERR("Could not create nsIContentUtils instance: %08lx\n", nsres); } + +struct mutation_observer { + IWineMSHTMLMutationObserver IWineMSHTMLMutationObserver_iface; + + LONG ref; + DispatchEx dispex; + IDispatch *callback; +}; + +static inline struct mutation_observer *impl_from_IWineMSHTMLMutationObserver(IWineMSHTMLMutationObserver *iface) +{ + return CONTAINING_RECORD(iface, struct mutation_observer, IWineMSHTMLMutationObserver_iface); +} + +static HRESULT WINAPI MutationObserver_QueryInterface(IWineMSHTMLMutationObserver *iface, REFIID riid, void **ppv) +{ + struct mutation_observer *This = impl_from_IWineMSHTMLMutationObserver(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); + + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IWineMSHTMLMutationObserver, riid)) { + *ppv = &This->IWineMSHTMLMutationObserver_iface; + }else { + WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI MutationObserver_AddRef(IWineMSHTMLMutationObserver *iface) +{ + struct mutation_observer *This = impl_from_IWineMSHTMLMutationObserver(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%ld\n", This, ref); + + return ref; +} + +static ULONG WINAPI MutationObserver_Release(IWineMSHTMLMutationObserver *iface) +{ + struct mutation_observer *This = impl_from_IWineMSHTMLMutationObserver(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%ld\n", This, ref); + + if(!ref) { + release_dispex(&This->dispex); + IDispatch_Release(This->callback); + This->callback = NULL; + free(This); + } + + return ref; +} + +static HRESULT WINAPI MutationObserver_GetTypeInfoCount(IWineMSHTMLMutationObserver *iface, UINT *pctinfo) +{ + struct mutation_observer *This = impl_from_IWineMSHTMLMutationObserver(iface); + FIXME("(%p)->(%p)\n", This, pctinfo); + + return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI MutationObserver_GetTypeInfo(IWineMSHTMLMutationObserver *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + struct mutation_observer *This = impl_from_IWineMSHTMLMutationObserver(iface); + + return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI MutationObserver_GetIDsOfNames(IWineMSHTMLMutationObserver *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, + DISPID *rgDispId) +{ + struct mutation_observer *This = impl_from_IWineMSHTMLMutationObserver(iface); + + return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, lcid, + rgDispId); +} + +static HRESULT WINAPI MutationObserver_Invoke(IWineMSHTMLMutationObserver *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + struct mutation_observer *This = impl_from_IWineMSHTMLMutationObserver(iface); + + return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static const IWineMSHTMLMutationObserverVtbl WineMSHTMLMutationObserverVtbl = { + MutationObserver_QueryInterface, + MutationObserver_AddRef, + MutationObserver_Release, + MutationObserver_GetTypeInfoCount, + MutationObserver_GetTypeInfo, + MutationObserver_GetIDsOfNames, + MutationObserver_Invoke, +}; + +static const tid_t mutation_observer_iface_tids[] = { + IWineMSHTMLMutationObserver_tid, + 0 +}; +static dispex_static_data_t mutation_observer_dispex = { + L"MutationObserver", + NULL, + IWineMSHTMLMutationObserver_tid, + mutation_observer_iface_tids +}; + +static HRESULT create_mutation_observer(compat_mode_t compat_mode, IDispatch *callback, + IWineMSHTMLMutationObserver **ret) { + struct mutation_observer *obj; + + TRACE("(compat_mode = %d, callback = %p, ret = %p)\n", compat_mode, callback, ret); + + obj = calloc(1, sizeof(*obj)); + if(!obj) + { + ERR("No memory.\n"); + return E_OUTOFMEMORY; + } + + obj->IWineMSHTMLMutationObserver_iface.lpVtbl = &WineMSHTMLMutationObserverVtbl; + obj->ref = 1; + init_dispatch(&obj->dispex, (IUnknown*)&obj->IWineMSHTMLMutationObserver_iface.lpVtbl, + &mutation_observer_dispex, compat_mode); + + IDispatch_AddRef(callback); + obj->callback = callback; + *ret = &obj->IWineMSHTMLMutationObserver_iface; + return S_OK; +} + +struct mutation_observer_ctor { + IUnknown IUnknown_iface; + DispatchEx dispex; + + LONG ref; +}; + +static inline struct mutation_observer_ctor *mutation_observer_ctor_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, struct mutation_observer_ctor, IUnknown_iface); +} + +static inline struct mutation_observer_ctor *mutation_observer_ctor_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, struct mutation_observer_ctor, dispex); +} + +static HRESULT WINAPI mutation_observer_ctor_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) +{ + struct mutation_observer_ctor *This = mutation_observer_ctor_from_IUnknown(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); + + if(IsEqualGUID(&IID_IUnknown, riid)) { + *ppv = &This->IUnknown_iface; + }else if(dispex_query_interface(&This->dispex, riid, ppv)) { + return *ppv ? S_OK : E_NOINTERFACE; + }else { + WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI mutation_observer_ctor_AddRef(IUnknown *iface) +{ + struct mutation_observer_ctor *This = mutation_observer_ctor_from_IUnknown(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%ld\n", This, ref); + + return ref; +} + +static ULONG WINAPI mutation_observer_ctor_Release(IUnknown *iface) +{ + struct mutation_observer_ctor *This = mutation_observer_ctor_from_IUnknown(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%ld\n", This, ref); + + if(!ref) { + release_dispex(&This->dispex); + free(This); + } + + return ref; +} + +static const IUnknownVtbl mutation_observer_ctor_vtbl = { + mutation_observer_ctor_QueryInterface, + mutation_observer_ctor_AddRef, + mutation_observer_ctor_Release, +}; + +HRESULT mutation_observer_ctor_value(DispatchEx *dispex, LCID lcid, + WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, + IServiceProvider *caller) +{ + struct mutation_observer_ctor *This = mutation_observer_ctor_from_DispatchEx(dispex); + VARIANT *callback; + IWineMSHTMLMutationObserver *mutation_observer; + HRESULT hres; + int argc = params->cArgs - params->cNamedArgs; + + TRACE("(%p)->(%lx %x %p %p %p %p)\n", This, lcid, flags, params, res, ei, caller); + + if (argc < 1) + return E_UNEXPECTED; + + if (!res) { + /* This function has no side effects if the return value is dropped. */ + return S_OK; + } + + V_VT(res) = VT_NULL; + + callback = params->rgvarg + (params->cArgs - 1); + if (V_VT(callback) != VT_DISPATCH) { + FIXME("Should return TypeMismatchError\n"); + return E_FAIL; + } + + hres = create_mutation_observer(dispex_compat_mode(&This->dispex), V_DISPATCH(callback), + &mutation_observer); + if (FAILED(hres)) + return hres; + + V_VT(res) = VT_DISPATCH; + V_DISPATCH(res) = (IDispatch*)mutation_observer; + + return S_OK; +} + +static dispex_static_data_vtbl_t mutation_observer_ctor_dispex_vtbl = { + .value = mutation_observer_ctor_value +}; + +static const tid_t mutation_observer_ctor_iface_tids[] = { + 0 +}; + +static dispex_static_data_t mutation_observer_ctor_dispex = { + L"Function", + &mutation_observer_ctor_dispex_vtbl, + NULL_tid, + mutation_observer_ctor_iface_tids +}; + +HRESULT create_mutation_observer_ctor(compat_mode_t compat_mode, IDispatch **ret) { + struct mutation_observer_ctor *obj; + + TRACE("(compat_mode = %d, ret = %p)\n", compat_mode, ret); + + obj = calloc(1, sizeof(*obj)); + if(!obj) + { + ERR("No memory.\n"); + return E_OUTOFMEMORY; + } + + obj->IUnknown_iface.lpVtbl = &mutation_observer_ctor_vtbl; + obj->ref = 1; + init_dispatch(&obj->dispex, (IUnknown*)&obj->IUnknown_iface.lpVtbl, + &mutation_observer_ctor_dispex, compat_mode); + + *ret = (IDispatch *)&obj->dispex.IDispatchEx_iface; + return S_OK; +} diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 00a6eded3fe..917c36b812e 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -343,6 +343,9 @@ sync_test("builtin_toString", function() { test("console", window.console, "Console"); test("mediaQueryList", window.matchMedia("(hover:hover)"), "MediaQueryList"); } + if(v >= 11) { + test("MutationObserver", new window.MutationObserver(function() {}), "MutationObserver"); + } if(v >= 9) { document.body.innerHTML = "<!--...-->"; test("comment", document.body.firstChild, "Comment"); @@ -475,6 +478,7 @@ sync_test("window_props", function() { test_exposed("performance", true); test_exposed("console", v >= 10); test_exposed("matchMedia", v >= 10); + test_exposed("MutationObserver", v >= 11); });
sync_test("domimpl_props", function() { @@ -2853,6 +2857,52 @@ sync_test("__defineSetter__", function() { ok(x.setterVal === 9, "x.setterVal after setting bar = " + x.setterVal); });
+sync_test("MutationObserver", function() { + if (!window.MutationObserver) { + return; + } + + try { + window.MutationObserver(); + ok(false, "MutationObserver without args should fail"); + } catch(e) { + ok(e.number == 0xffff - 0x80000000, "MutationObserver without new threw exception " + e.number); + } + + try { + window.MutationObserver(function() {}); + } catch(e) { + ok(false, "MutationObserver without new threw exception " + e.number); + } + + try { + new window.MutationObserver(); + ok(false, "MutationObserver with no args should fail"); + } catch(e) { + ok(e.number == 0xffff - 0x80000000, "MutationObserver with no args threw exception " + e.number); + } + + try { + new window.MutationObserver(1); + ok(false, "MutationObserver with non-function arg should fail"); + } catch(e) { + todo_wine. + ok(e.name == "TypeMismatchError", "MutationObserver with non-function arg threw exception " + e.name); + } + + try { + new window.MutationObserver(function() {}); + } catch(e) { + ok(false, "MutationObserver threw exception " + e.number); + } + + try { + new window.MutationObserver(function() {}, 1); + } catch(e) { + ok(false, "MutationObserver with extra args threw exception " + e.number); + } +}) + async_test("postMessage", function() { var v = document.documentMode; var onmessage_called = false;
From: Yuxuan Shui yshui@codeweavers.com
--- dlls/mshtml/mshtml_private_iface.idl | 7 +++++++ dlls/mshtml/mutation.c | 31 ++++++++++++++++++++++++++++ dlls/mshtml/tests/documentmode.js | 16 +++++++++++++- 3 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/mshtml_private_iface.idl b/dlls/mshtml/mshtml_private_iface.idl index 46bae638fa5..e4d97361ce1 100644 --- a/dlls/mshtml/mshtml_private_iface.idl +++ b/dlls/mshtml/mshtml_private_iface.idl @@ -21,6 +21,7 @@ #include <mshtmdid.h>
import "ocidl.idl"; +import "mshtml.idl";
[ version(1.0), @@ -85,6 +86,12 @@ interface IWineMSHTMLConsole : IDispatch ] interface IWineMSHTMLMutationObserver : IDispatch { + [id(1)] + HRESULT disconnect(); + [id(2)] + HRESULT observe([in] IHTMLDOMNode *target, [in] IDispatch *options); + [id(3)] + HRESULT takeRecords([retval, out] IDispatch **records); }
[ diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index c895b7f5469..c5059f292ac 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -1171,6 +1171,34 @@ static HRESULT WINAPI MutationObserver_Invoke(IWineMSHTMLMutationObserver *iface pDispParams, pVarResult, pExcepInfo, puArgErr); }
+static HRESULT WINAPI MutationObserver_disconnect(IWineMSHTMLMutationObserver *iface) +{ + struct mutation_observer *This = impl_from_IWineMSHTMLMutationObserver(iface); + + FIXME("(%p), stub\n", This); + + return S_OK; +} + +static HRESULT WINAPI MutationObserver_observe(IWineMSHTMLMutationObserver *iface, IHTMLDOMNode *target, + IDispatch *options) +{ + struct mutation_observer *This = impl_from_IWineMSHTMLMutationObserver(iface); + + FIXME("(%p)->(%p %p), stub\n", This, target, options); + + return S_OK; +} + +static HRESULT WINAPI MutationObserver_takeRecords(IWineMSHTMLMutationObserver *iface, IDispatch **ret) +{ + struct mutation_observer *This = impl_from_IWineMSHTMLMutationObserver(iface); + + FIXME("(%p)->(%p), stub\n", This, ret); + + return E_NOTIMPL; +} + static const IWineMSHTMLMutationObserverVtbl WineMSHTMLMutationObserverVtbl = { MutationObserver_QueryInterface, MutationObserver_AddRef, @@ -1179,6 +1207,9 @@ static const IWineMSHTMLMutationObserverVtbl WineMSHTMLMutationObserverVtbl = { MutationObserver_GetTypeInfo, MutationObserver_GetIDsOfNames, MutationObserver_Invoke, + MutationObserver_disconnect, + MutationObserver_observe, + MutationObserver_takeRecords };
static const tid_t mutation_observer_iface_tids[] = { diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 917c36b812e..f40262a7c54 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -2901,7 +2901,21 @@ sync_test("MutationObserver", function() { } catch(e) { ok(false, "MutationObserver with extra args threw exception " + e.number); } -}) +}); + +sync_test("MutationObserver_props", function() { + if (!window.MutationObserver) { + return; + } + + var mutation_observer = new MutationObserver(function() {}); + function test_exposed(prop) { + ok(prop in mutation_observer, prop + " not found in MutationObserver."); + } + test_exposed("observe"); + test_exposed("disconnect"); + test_exposed("takeRecords"); +});
async_test("postMessage", function() { var v = document.documentMode;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=135260
Your paranoid android.
=== debian11b (64 bit WoW report) ===
win32u: win32u.c:1060: Test failed: res = win32u:win32u:09bc done (0) in 0s 1411B
On Tue Jul 25 19:04:54 2023 +0000, Yuxuan Shui wrote:
how do i create a js array from mshtml? do i call `create_array`?
I think I will just return E_NOTIMPL
Gabriel Ivăncescu (@insn) commented about dlls/mshtml/tests/documentmode.js:
ok(e.name == "TypeMismatchError", "MutationObserver with non-function arg threw exception " + e.name);
- }
- try {
new window.MutationObserver(function() {});
- } catch(e) {
ok(false, "MutationObserver threw exception " + e.number);
- }
- try {
new window.MutationObserver(function() {}, 1);
- } catch(e) {
ok(false, "MutationObserver with extra args threw exception " + e.number);
- }
+})
Small nitpick, but you don't need try {} catch {} blocks for *successful* tests, just put the succesful test without any try/catch. If it fails it will generate an exception and the test will fail (but obviously, it shouldn't, so that's fine).
Gabriel Ivăncescu (@insn) commented about dlls/mshtml/mutation.c:
+{
- struct mutation_observer_ctor *This = mutation_observer_ctor_from_DispatchEx(dispex);
- VARIANT *callback;
- IWineMSHTMLMutationObserver *mutation_observer;
- HRESULT hres;
- int argc = params->cArgs - params->cNamedArgs;
- TRACE("(%p)->(%lx %x %p %p %p %p)\n", This, lcid, flags, params, res, ei, caller);
- if (argc < 1)
return E_UNEXPECTED;
- if (!res) {
/* This function has no side effects if the return value is dropped. */
return S_OK;
- }
Are you sure this should be checked *before* validating `callback`? What happens if you write (in tests):
```jscript MutationObserver(42); ```
Gabriel Ivăncescu (@insn) commented about dlls/mshtml/tests/documentmode.js:
-}) +});
+sync_test("MutationObserver_props", function() {
- if (!window.MutationObserver) {
return;
- }
- var mutation_observer = new MutationObserver(function() {});
- function test_exposed(prop) {
ok(prop in mutation_observer, prop + " not found in MutationObserver.");
- }
- test_exposed("observe");
- test_exposed("disconnect");
- test_exposed("takeRecords");
+});
Small nitpick, but I'd honestly just merge this test with "MutationObserver" (just add it to the end of it), no need to make another separate test.
On Wed Jul 26 00:17:08 2023 +0000, Yuxuan Shui wrote:
I think I will just return E_NOTIMPL
Yeah, that's what I meant, to make them stubs (so it's totally fine now).
As for your question about the array, you can't right now, it will need private interface and I have a lot of patches for that and to integrate jscript objects with mshtml ones (which is in Proton for example), but I need some revamps first upstream to get rid of some hacks as preparatory work before I try to upstream it.
Anyway it's nothing related to this MR so don't worry about it.
Anyway, other than those small nitpicks and (probably) moving the NULL result check (depending on the test you add), it looks good to me, now it depends on @jacek
On Wed Jul 26 10:56:22 2023 +0000, Gabriel Ivăncescu wrote:
Small nitpick, but you don't need try {} catch {} blocks for *successful* tests, just put the succesful test without any try/catch. If it fails it will generate an exception and the test will fail (but obviously, it shouldn't, so that's fine).
but we would miss the helpful error message
On Wed Jul 26 10:56:23 2023 +0000, Gabriel Ivăncescu wrote:
Are you sure this should be checked *before* validating `callback`? What happens if you write (in tests):
MutationObserver(42);
good catch, thanks