mshtml: Added delayed DispatchEx init support and use it to expose IHTMLDOMNode3 from document node.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
53253aa6a4
commit
856dc7eda4
|
@ -62,7 +62,7 @@ typedef struct {
|
||||||
} func_info_t;
|
} func_info_t;
|
||||||
|
|
||||||
struct dispex_data_t {
|
struct dispex_data_t {
|
||||||
const dispex_static_data_t *desc;
|
dispex_static_data_t *desc;
|
||||||
|
|
||||||
DWORD func_cnt;
|
DWORD func_cnt;
|
||||||
DWORD func_size;
|
DWORD func_size;
|
||||||
|
@ -379,7 +379,7 @@ static int func_name_cmp(const void *p1, const void *p2)
|
||||||
return strcmpiW((*(func_info_t* const*)p1)->name, (*(func_info_t* const*)p2)->name);
|
return strcmpiW((*(func_info_t* const*)p1)->name, (*(func_info_t* const*)p2)->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static dispex_data_t *preprocess_dispex_data(const dispex_static_data_t *desc, compat_mode_t compat_mode)
|
static dispex_data_t *preprocess_dispex_data(dispex_static_data_t *desc, compat_mode_t compat_mode)
|
||||||
{
|
{
|
||||||
const tid_t *tid;
|
const tid_t *tid;
|
||||||
dispex_data_t *data;
|
dispex_data_t *data;
|
||||||
|
@ -1346,6 +1346,27 @@ HRESULT remove_attribute(DispatchEx *This, DISPID id, VARIANT_BOOL *success)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static dispex_data_t *ensure_dispex_info(dispex_static_data_t *desc, compat_mode_t compat_mode)
|
||||||
|
{
|
||||||
|
if(!desc->info_cache[compat_mode]) {
|
||||||
|
EnterCriticalSection(&cs_dispex_static_data);
|
||||||
|
if(!desc->info_cache[compat_mode])
|
||||||
|
desc->info_cache[compat_mode] = preprocess_dispex_data(desc, compat_mode);
|
||||||
|
LeaveCriticalSection(&cs_dispex_static_data);
|
||||||
|
}
|
||||||
|
return desc->info_cache[compat_mode];
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL ensure_real_info(DispatchEx *dispex)
|
||||||
|
{
|
||||||
|
if(dispex->info != dispex->info->desc->delayed_init_info)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
dispex->info = ensure_dispex_info(dispex->info->desc,
|
||||||
|
dispex->info->desc->vtbl->get_compat_mode(dispex));
|
||||||
|
return dispex->info != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static inline DispatchEx *impl_from_IDispatchEx(IDispatchEx *iface)
|
static inline DispatchEx *impl_from_IDispatchEx(IDispatchEx *iface)
|
||||||
{
|
{
|
||||||
return CONTAINING_RECORD(iface, DispatchEx, IDispatchEx_iface);
|
return CONTAINING_RECORD(iface, DispatchEx, IDispatchEx_iface);
|
||||||
|
@ -1442,6 +1463,9 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
|
||||||
if(grfdex & ~(fdexNameCaseSensitive|fdexNameCaseInsensitive|fdexNameEnsure|fdexNameImplicit|FDEX_VERSION_MASK))
|
if(grfdex & ~(fdexNameCaseSensitive|fdexNameCaseInsensitive|fdexNameEnsure|fdexNameImplicit|FDEX_VERSION_MASK))
|
||||||
FIXME("Unsupported grfdex %x\n", grfdex);
|
FIXME("Unsupported grfdex %x\n", grfdex);
|
||||||
|
|
||||||
|
if(!ensure_real_info(This))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
hres = get_builtin_id(This, bstrName, grfdex, pid);
|
hres = get_builtin_id(This, bstrName, grfdex, pid);
|
||||||
if(hres != DISP_E_UNKNOWNNAME)
|
if(hres != DISP_E_UNKNOWNNAME)
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -1462,6 +1486,9 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
|
||||||
|
|
||||||
TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
|
TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
|
||||||
|
|
||||||
|
if(!ensure_real_info(This))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if(wFlags == (DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF))
|
if(wFlags == (DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF))
|
||||||
wFlags = DISPATCH_PROPERTYPUT;
|
wFlags = DISPATCH_PROPERTYPUT;
|
||||||
|
|
||||||
|
@ -1572,6 +1599,9 @@ static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BS
|
||||||
|
|
||||||
TRACE("(%p)->(%x %p)\n", This, id, pbstrName);
|
TRACE("(%p)->(%x %p)\n", This, id, pbstrName);
|
||||||
|
|
||||||
|
if(!ensure_real_info(This))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if(is_dynamic_dispid(id)) {
|
if(is_dynamic_dispid(id)) {
|
||||||
DWORD idx = id - DISPID_DYNPROP_0;
|
DWORD idx = id - DISPID_DYNPROP_0;
|
||||||
|
|
||||||
|
@ -1617,6 +1647,9 @@ static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex,
|
||||||
|
|
||||||
TRACE("(%p)->(%x %x %p)\n", This, grfdex, id, pid);
|
TRACE("(%p)->(%x %x %p)\n", This, grfdex, id, pid);
|
||||||
|
|
||||||
|
if(!ensure_real_info(This))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if(is_dynamic_dispid(id)) {
|
if(is_dynamic_dispid(id)) {
|
||||||
DWORD idx = id - DISPID_DYNPROP_0;
|
DWORD idx = id - DISPID_DYNPROP_0;
|
||||||
|
|
||||||
|
@ -1770,15 +1803,25 @@ void init_dispex_with_compat_mode(DispatchEx *dispex, IUnknown *outer, dispex_st
|
||||||
{
|
{
|
||||||
assert(compat_mode < COMPAT_MODE_CNT);
|
assert(compat_mode < COMPAT_MODE_CNT);
|
||||||
|
|
||||||
if(!data->info_cache[compat_mode]) {
|
|
||||||
EnterCriticalSection(&cs_dispex_static_data);
|
|
||||||
if(!data->info_cache[compat_mode])
|
|
||||||
data->info_cache[compat_mode] = preprocess_dispex_data(data, compat_mode);
|
|
||||||
LeaveCriticalSection(&cs_dispex_static_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
dispex->IDispatchEx_iface.lpVtbl = &DispatchExVtbl;
|
dispex->IDispatchEx_iface.lpVtbl = &DispatchExVtbl;
|
||||||
dispex->outer = outer;
|
dispex->outer = outer;
|
||||||
dispex->info = data->info_cache[compat_mode];
|
|
||||||
dispex->dynamic_data = NULL;
|
dispex->dynamic_data = NULL;
|
||||||
|
|
||||||
|
if(data->vtbl && data->vtbl->get_compat_mode) {
|
||||||
|
/* delayed init */
|
||||||
|
if(!data->delayed_init_info) {
|
||||||
|
EnterCriticalSection(&cs_dispex_static_data);
|
||||||
|
if(!data->delayed_init_info) {
|
||||||
|
dispex_data_t *info = heap_alloc_zero(sizeof(*data->delayed_init_info));
|
||||||
|
if(info) {
|
||||||
|
info->desc = data;
|
||||||
|
data->delayed_init_info = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LeaveCriticalSection(&cs_dispex_static_data);
|
||||||
|
}
|
||||||
|
dispex->info = data->delayed_init_info;
|
||||||
|
}else {
|
||||||
|
dispex->info = ensure_dispex_info(data, compat_mode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4813,6 +4813,16 @@ static HRESULT HTMLDocumentNode_invoke(DispatchEx *dispex, DISPID id, LCID lcid,
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static compat_mode_t HTMLDocumentNode_get_compat_mode(DispatchEx *dispex)
|
||||||
|
{
|
||||||
|
HTMLDocumentNode *This = impl_from_DispatchEx(dispex);
|
||||||
|
|
||||||
|
TRACE("(%p) returning %u\n", This, This->document_mode);
|
||||||
|
|
||||||
|
This->document_mode_locked = TRUE;
|
||||||
|
return This->document_mode;
|
||||||
|
}
|
||||||
|
|
||||||
static void HTMLDocumentNode_bind_event(DispatchEx *dispex, int eid)
|
static void HTMLDocumentNode_bind_event(DispatchEx *dispex, int eid)
|
||||||
{
|
{
|
||||||
HTMLDocumentNode *This = impl_from_DispatchEx(dispex);
|
HTMLDocumentNode *This = impl_from_DispatchEx(dispex);
|
||||||
|
@ -4823,6 +4833,7 @@ static const dispex_static_data_vtbl_t HTMLDocumentNode_dispex_vtbl = {
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
HTMLDocumentNode_invoke,
|
HTMLDocumentNode_invoke,
|
||||||
|
HTMLDocumentNode_get_compat_mode,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
HTMLDocumentNode_bind_event
|
HTMLDocumentNode_bind_event
|
||||||
|
@ -4851,7 +4862,8 @@ static const tid_t HTMLDocumentNode_iface_tids[] = {
|
||||||
static dispex_static_data_t HTMLDocumentNode_dispex = {
|
static dispex_static_data_t HTMLDocumentNode_dispex = {
|
||||||
&HTMLDocumentNode_dispex_vtbl,
|
&HTMLDocumentNode_dispex_vtbl,
|
||||||
DispHTMLDocument_tid,
|
DispHTMLDocument_tid,
|
||||||
HTMLDocumentNode_iface_tids
|
HTMLDocumentNode_iface_tids,
|
||||||
|
HTMLDOMNode_init_dispex_info
|
||||||
};
|
};
|
||||||
|
|
||||||
static HTMLDocumentNode *alloc_doc_node(HTMLDocumentObj *doc_obj, HTMLInnerWindow *window)
|
static HTMLDocumentNode *alloc_doc_node(HTMLDocumentObj *doc_obj, HTMLInnerWindow *window)
|
||||||
|
|
|
@ -5319,6 +5319,7 @@ static dispex_static_data_vtbl_t HTMLElement_dispex_vtbl = {
|
||||||
NULL,
|
NULL,
|
||||||
HTMLElement_get_dispid,
|
HTMLElement_get_dispid,
|
||||||
HTMLElement_invoke,
|
HTMLElement_invoke,
|
||||||
|
NULL,
|
||||||
HTMLElement_populate_props,
|
HTMLElement_populate_props,
|
||||||
HTMLElement_get_event_target,
|
HTMLElement_get_event_target,
|
||||||
HTMLElement_bind_event
|
HTMLElement_bind_event
|
||||||
|
|
|
@ -3019,6 +3019,7 @@ static const dispex_static_data_vtbl_t HTMLWindow_dispex_vtbl = {
|
||||||
NULL,
|
NULL,
|
||||||
HTMLWindow_invoke,
|
HTMLWindow_invoke,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
HTMLWindow_get_event_target,
|
HTMLWindow_get_event_target,
|
||||||
HTMLWindow_bind_event
|
HTMLWindow_bind_event
|
||||||
};
|
};
|
||||||
|
|
|
@ -267,6 +267,7 @@ typedef struct {
|
||||||
HRESULT (*value)(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*);
|
HRESULT (*value)(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*);
|
||||||
HRESULT (*get_dispid)(DispatchEx*,BSTR,DWORD,DISPID*);
|
HRESULT (*get_dispid)(DispatchEx*,BSTR,DWORD,DISPID*);
|
||||||
HRESULT (*invoke)(DispatchEx*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*);
|
HRESULT (*invoke)(DispatchEx*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*);
|
||||||
|
compat_mode_t (*get_compat_mode)(DispatchEx*);
|
||||||
HRESULT (*populate_props)(DispatchEx*);
|
HRESULT (*populate_props)(DispatchEx*);
|
||||||
/* We abuse this vtbl for EventTarget functions to avoid separated vtbl. */
|
/* We abuse this vtbl for EventTarget functions to avoid separated vtbl. */
|
||||||
EventTarget *(*get_event_target)(DispatchEx*);
|
EventTarget *(*get_event_target)(DispatchEx*);
|
||||||
|
@ -279,6 +280,7 @@ typedef struct {
|
||||||
const tid_t* const iface_tids;
|
const tid_t* const iface_tids;
|
||||||
void (*init_info)(dispex_data_t*,compat_mode_t);
|
void (*init_info)(dispex_data_t*,compat_mode_t);
|
||||||
dispex_data_t *info_cache[COMPAT_MODE_CNT];
|
dispex_data_t *info_cache[COMPAT_MODE_CNT];
|
||||||
|
dispex_data_t *delayed_init_info;
|
||||||
} dispex_static_data_t;
|
} dispex_static_data_t;
|
||||||
|
|
||||||
struct DispatchEx {
|
struct DispatchEx {
|
||||||
|
|
|
@ -39,6 +39,22 @@ function test_elem_props() {
|
||||||
next_test();
|
next_test();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function test_doc_props() {
|
||||||
|
function test_exposed(prop, expect) {
|
||||||
|
if(expect)
|
||||||
|
ok(prop in document, prop + " not found in document.");
|
||||||
|
else
|
||||||
|
ok(!(prop in document), prop + " found in document.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var v = document.documentMode;
|
||||||
|
|
||||||
|
test_exposed("textContent", v >= 9);
|
||||||
|
test_exposed("prefix", v >= 9);
|
||||||
|
|
||||||
|
next_test();
|
||||||
|
}
|
||||||
|
|
||||||
function test_doc_mode() {
|
function test_doc_mode() {
|
||||||
compat_version = parseInt(document.location.search.substring(1));
|
compat_version = parseInt(document.location.search.substring(1));
|
||||||
|
|
||||||
|
@ -99,5 +115,6 @@ function test_conditional_comments() {
|
||||||
var tests = [
|
var tests = [
|
||||||
test_doc_mode,
|
test_doc_mode,
|
||||||
test_elem_props,
|
test_elem_props,
|
||||||
|
test_doc_props,
|
||||||
test_conditional_comments
|
test_conditional_comments
|
||||||
];
|
];
|
||||||
|
|
|
@ -77,6 +77,8 @@ function test_textContent() {
|
||||||
ok(div.textContent === "", "div.textContent = " + div.textContent);
|
ok(div.textContent === "", "div.textContent = " + div.textContent);
|
||||||
ok(div.childNodes.length === 0, "div.childNodes.length = " + div.childNodes.length);
|
ok(div.childNodes.length === 0, "div.childNodes.length = " + div.childNodes.length);
|
||||||
|
|
||||||
|
ok(document.textContent === null, "document.textContent = " + document.textContent);
|
||||||
|
|
||||||
next_test();
|
next_test();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -778,6 +778,7 @@ static dispex_static_data_vtbl_t HTMLXMLHttpRequest_dispex_vtbl = {
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
HTMLXMLHttpRequest_bind_event
|
HTMLXMLHttpRequest_bind_event
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue