mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-01 12:03:39 +00:00
mshtml: Implement window.MutationObserver with MutationObserver stub.
This commit is contained in:
parent
17841cd529
commit
02994bdd10
|
@ -309,6 +309,9 @@ static void release_inner_window(HTMLInnerWindow *This)
|
||||||
if(This->mon)
|
if(This->mon)
|
||||||
IMoniker_Release(This->mon);
|
IMoniker_Release(This->mon);
|
||||||
|
|
||||||
|
if(This->mutation_observer_ctor)
|
||||||
|
IDispatch_Release(This->mutation_observer_ctor);
|
||||||
|
|
||||||
free(This);
|
free(This);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3330,6 +3333,26 @@ static HRESULT WINAPI window_private_get_console(IWineHTMLWindowPrivate *iface,
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI window_private_get_MutationObserver(IWineHTMLWindowPrivate *iface,
|
||||||
|
IDispatch **mutation_observer)
|
||||||
|
{
|
||||||
|
HTMLWindow *This = impl_from_IWineHTMLWindowPrivateVtbl(iface);
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
TRACE("iface %p, mutation_observer %p.\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 = {
|
static const IWineHTMLWindowPrivateVtbl WineHTMLWindowPrivateVtbl = {
|
||||||
window_private_QueryInterface,
|
window_private_QueryInterface,
|
||||||
window_private_AddRef,
|
window_private_AddRef,
|
||||||
|
@ -3343,6 +3366,7 @@ static const IWineHTMLWindowPrivateVtbl WineHTMLWindowPrivateVtbl = {
|
||||||
window_private_get_console,
|
window_private_get_console,
|
||||||
window_private_matchMedia,
|
window_private_matchMedia,
|
||||||
window_private_postMessage,
|
window_private_postMessage,
|
||||||
|
window_private_get_MutationObserver
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline HTMLWindow *impl_from_IWineHTMLWindowCompatPrivateVtbl(IWineHTMLWindowCompatPrivate *iface)
|
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}
|
{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)
|
if(compat_mode >= COMPAT_MODE_IE9)
|
||||||
dispex_info_add_interface(info, IHTMLWindow7_tid, NULL);
|
dispex_info_add_interface(info, IHTMLWindow7_tid, NULL);
|
||||||
else
|
else
|
||||||
dispex_info_add_interface(info, IWineHTMLWindowCompatPrivate_tid, NULL);
|
dispex_info_add_interface(info, IWineHTMLWindowCompatPrivate_tid, NULL);
|
||||||
if(compat_mode >= COMPAT_MODE_IE10)
|
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, IHTMLWindow5_tid, NULL);
|
||||||
dispex_info_add_interface(info, IHTMLWindow4_tid, compat_mode >= COMPAT_MODE_IE11 ? window4_ie11_hooks : NULL);
|
dispex_info_add_interface(info, IHTMLWindow4_tid, compat_mode >= COMPAT_MODE_IE11 ? window4_ie11_hooks : NULL);
|
||||||
|
|
|
@ -294,7 +294,8 @@ typedef struct EventTarget EventTarget;
|
||||||
XIID(IWinePageTransitionEvent) \
|
XIID(IWinePageTransitionEvent) \
|
||||||
XIID(IWineXMLHttpRequestPrivate) \
|
XIID(IWineXMLHttpRequestPrivate) \
|
||||||
XIID(IWineMSHTMLConsole) \
|
XIID(IWineMSHTMLConsole) \
|
||||||
XIID(IWineMSHTMLMediaQueryList)
|
XIID(IWineMSHTMLMediaQueryList) \
|
||||||
|
XIID(IWineMSHTMLMutationObserver)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
#define XIID(iface) iface ## _tid,
|
#define XIID(iface) iface ## _tid,
|
||||||
|
@ -636,6 +637,7 @@ struct HTMLInnerWindow {
|
||||||
LONG task_magic;
|
LONG task_magic;
|
||||||
|
|
||||||
IMoniker *mon;
|
IMoniker *mon;
|
||||||
|
IDispatch *mutation_observer_ctor;
|
||||||
nsChannelBSC *bscallback;
|
nsChannelBSC *bscallback;
|
||||||
struct list bindings;
|
struct list bindings;
|
||||||
};
|
};
|
||||||
|
@ -1496,3 +1498,5 @@ IInternetSecurityManager *get_security_manager(void);
|
||||||
extern HINSTANCE hInst;
|
extern HINSTANCE hInst;
|
||||||
void create_console(compat_mode_t compat_mode, IWineMSHTMLConsole **ret);
|
void create_console(compat_mode_t compat_mode, IWineMSHTMLConsole **ret);
|
||||||
HRESULT create_media_query_list(HTMLWindow *window, BSTR media_query, IDispatch **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);
|
||||||
|
|
|
@ -76,6 +76,17 @@ interface IWineMSHTMLConsole : IDispatch
|
||||||
HRESULT warn([in, optional] VARIANT *varargStart);
|
HRESULT warn([in, optional] VARIANT *varargStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[
|
||||||
|
odl,
|
||||||
|
oleautomation,
|
||||||
|
dual,
|
||||||
|
hidden,
|
||||||
|
uuid(6ac5491e-1758-4b82-98a2-83e31a7c8871)
|
||||||
|
]
|
||||||
|
interface IWineMSHTMLMutationObserver : IDispatch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
[
|
[
|
||||||
odl,
|
odl,
|
||||||
oleautomation,
|
oleautomation,
|
||||||
|
@ -95,6 +106,7 @@ interface IWineMSHTMLMediaQueryList : IDispatch
|
||||||
HRESULT removeListener([in] VARIANT *listener);
|
HRESULT removeListener([in] VARIANT *listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const long DISPID_IWINEHTMLWINDOWPRIVATE_MUTATIONOBSERVER = 55;
|
||||||
[
|
[
|
||||||
odl,
|
odl,
|
||||||
oleautomation,
|
oleautomation,
|
||||||
|
@ -114,6 +126,8 @@ interface IWineHTMLWindowPrivate : IDispatch
|
||||||
HRESULT matchMedia([in] BSTR media_query, [retval, out] IDispatch **media_query_list);
|
HRESULT matchMedia([in] BSTR media_query, [retval, out] IDispatch **media_query_list);
|
||||||
[id(54)]
|
[id(54)]
|
||||||
HRESULT postMessage([in] VARIANT msg, [in] BSTR targetOrigin, [in, optional] VARIANT transfer);
|
HRESULT postMessage([in] VARIANT msg, [in] BSTR targetOrigin, [in, optional] VARIANT transfer);
|
||||||
|
[propget, id(DISPID_IWINEHTMLWINDOWPRIVATE_MUTATIONOBSERVER)]
|
||||||
|
HRESULT MutationObserver([retval, out] IDispatch **observer_ctor);
|
||||||
}
|
}
|
||||||
|
|
||||||
[
|
[
|
||||||
|
|
|
@ -1076,3 +1076,296 @@ void init_mutation(nsIComponentManager *component_manager)
|
||||||
if(NS_FAILED(nsres))
|
if(NS_FAILED(nsres))
|
||||||
ERR("Could not create nsIContentUtils instance: %08lx\n", 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 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 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);
|
||||||
|
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,
|
||||||
|
&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,
|
||||||
|
};
|
||||||
|
|
||||||
|
static 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);
|
||||||
|
|
||||||
|
switch (flags) {
|
||||||
|
case DISPATCH_METHOD | DISPATCH_PROPERTYGET:
|
||||||
|
if (!res)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
case DISPATCH_CONSTRUCT:
|
||||||
|
case DISPATCH_METHOD:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FIXME("flags %x is not supported\n", flags);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc < 1)
|
||||||
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
|
callback = params->rgvarg + (params->cArgs - 1);
|
||||||
|
if (V_VT(callback) != VT_DISPATCH) {
|
||||||
|
FIXME("Should return TypeMismatchError\n");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
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,
|
||||||
|
&mutation_observer_ctor_dispex, compat_mode);
|
||||||
|
|
||||||
|
*ret = (IDispatch *)&obj->dispex.IDispatchEx_iface;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -343,6 +343,9 @@ sync_test("builtin_toString", function() {
|
||||||
test("console", window.console, "Console");
|
test("console", window.console, "Console");
|
||||||
test("mediaQueryList", window.matchMedia("(hover:hover)"), "MediaQueryList");
|
test("mediaQueryList", window.matchMedia("(hover:hover)"), "MediaQueryList");
|
||||||
}
|
}
|
||||||
|
if(v >= 11) {
|
||||||
|
test("MutationObserver", new window.MutationObserver(function() {}), "MutationObserver");
|
||||||
|
}
|
||||||
if(v >= 9) {
|
if(v >= 9) {
|
||||||
document.body.innerHTML = "<!--...-->";
|
document.body.innerHTML = "<!--...-->";
|
||||||
test("comment", document.body.firstChild, "Comment");
|
test("comment", document.body.firstChild, "Comment");
|
||||||
|
@ -475,6 +478,7 @@ sync_test("window_props", function() {
|
||||||
test_exposed("performance", true);
|
test_exposed("performance", true);
|
||||||
test_exposed("console", v >= 10);
|
test_exposed("console", v >= 10);
|
||||||
test_exposed("matchMedia", v >= 10);
|
test_exposed("matchMedia", v >= 10);
|
||||||
|
test_exposed("MutationObserver", v >= 11);
|
||||||
});
|
});
|
||||||
|
|
||||||
sync_test("domimpl_props", function() {
|
sync_test("domimpl_props", function() {
|
||||||
|
@ -2853,6 +2857,60 @@ sync_test("__defineSetter__", function() {
|
||||||
ok(x.setterVal === 9, "x.setterVal after setting bar = " + x.setterVal);
|
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(42);
|
||||||
|
ok(false, "MutationObserver with non-function should fail");
|
||||||
|
} catch(e) {
|
||||||
|
todo_wine.
|
||||||
|
ok(e.name == "TypeMismatchError", "MutationObserver with non-function arg threw exception " + e.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
async_test("postMessage", function() {
|
||||||
var v = document.documentMode;
|
var v = document.documentMode;
|
||||||
var onmessage_called = false;
|
var onmessage_called = false;
|
||||||
|
|
Loading…
Reference in a new issue