From: Gabriel Ivăncescu gabrielopcode@gmail.com
Surprisingly, this applies even in IE9+ modes when using IHTMLElement4's methods, but we can't test that yet because it's too broken in wine.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 20 ++- dlls/mshtml/htmlelem.c | 89 ++++++++- dlls/mshtml/htmlform.c | 23 ++- dlls/mshtml/htmlframe.c | 54 ++++-- dlls/mshtml/htmlhead.c | 19 +- dlls/mshtml/htmlimg.c | 17 +- dlls/mshtml/htmlinput.c | 70 +++++--- dlls/mshtml/htmllink.c | 20 ++- dlls/mshtml/htmlnode.c | 36 +++- dlls/mshtml/htmlobject.c | 23 ++- dlls/mshtml/htmlscript.c | 22 ++- dlls/mshtml/htmlselect.c | 46 +++-- dlls/mshtml/htmlstyleelem.c | 6 +- dlls/mshtml/htmltable.c | 67 +++++-- dlls/mshtml/htmltextarea.c | 23 ++- dlls/mshtml/mshtml_private.h | 2 + dlls/mshtml/tests/dom.c | 338 ++++++++++++++++++++++++++++++++++- 17 files changed, 746 insertions(+), 129 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 695cdaad0e2..60138ea511a 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -62,6 +62,7 @@ typedef struct { SHORT func_disp_idx; USHORT argc; USHORT default_value_cnt; + BOOLEAN noattr; VARTYPE prop_vt; VARTYPE *arg_types; func_arg_info_t *arg_info; @@ -282,7 +283,7 @@ static BOOL is_arg_type_supported(VARTYPE vt) }
static void add_func_info(dispex_data_t *data, tid_t tid, const FUNCDESC *desc, ITypeInfo *dti, - dispex_hook_invoke_t hook, const WCHAR *name_override) + dispex_hook_invoke_t hook, const WCHAR *name_override, BOOL noattr) { func_info_t *info; BSTR name; @@ -333,6 +334,7 @@ static void add_func_info(dispex_data_t *data, tid_t tid, const FUNCDESC *desc, info->func_disp_idx = -1; info->prop_vt = VT_EMPTY; info->hook = hook; + info->noattr = noattr; }else { SysFreeString(name); } @@ -342,6 +344,7 @@ static void add_func_info(dispex_data_t *data, tid_t tid, const FUNCDESC *desc,
info->func_disp_idx = data->func_disp_cnt++; info->argc = desc->cParams; + info->noattr = TRUE;
assert(info->argc < MAX_ARGS); assert(desc->funckind == FUNC_DISPATCH); @@ -480,9 +483,9 @@ static HRESULT process_interface(dispex_data_t *data, tid_t tid, ITypeInfo *disp } }
- if(!hook || hook->invoke || hook->name) { + if(!hook || hook->invoke || hook->name || hook->noattr) { add_func_info(data, tid, funcdesc, disp_typeinfo ? disp_typeinfo : typeinfo, - hook ? hook->invoke : NULL, hook ? hook->name : NULL); + hook ? hook->invoke : NULL, hook ? hook->name : NULL, hook ? hook->noattr : FALSE); }
ITypeInfo_ReleaseFuncDesc(typeinfo, funcdesc); @@ -1996,6 +1999,17 @@ HRESULT dispex_to_string(DispatchEx *dispex, BSTR *ret) return *ret ? S_OK : E_OUTOFMEMORY; }
+BOOL dispex_builtin_is_noattr(DispatchEx *dispex, DISPID id) +{ + func_info_t *func; + HRESULT hres; + + hres = get_builtin_func(dispex->info, id, &func); + assert(SUCCEEDED(hres)); + + return func->noattr; +} + static inline DispatchEx *impl_from_IWineJSDispatchHost(IWineJSDispatchHost *iface) { return CONTAINING_RECORD(iface, DispatchEx, IWineJSDispatchHost_iface); diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index fcc6394c0d2..0e78347881a 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -6667,6 +6667,14 @@ static HRESULT IHTMLElement6_setAttribute_hook(DispatchEx *dispex, WORD flags, D return hres; }
+static const dispex_hook_t elem_traversal_noattr_hooks[] = { + {DISPID_IELEMENTTRAVERSAL_FIRSTELEMENTCHILD, .noattr = TRUE}, + {DISPID_IELEMENTTRAVERSAL_LASTELEMENTCHILD, .noattr = TRUE}, + {DISPID_IELEMENTTRAVERSAL_PREVIOUSELEMENTSIBLING, .noattr = TRUE}, + {DISPID_IELEMENTTRAVERSAL_NEXTELEMENTSIBLING, .noattr = TRUE}, + {DISPID_IELEMENTTRAVERSAL_CHILDELEMENTCOUNT, .noattr = TRUE} +}; + void HTMLElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) { static const dispex_hook_t elem6_ie9_hooks[] = { @@ -6699,10 +6707,33 @@ void HTMLElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode)
/* IE9+ */ {DISPID_IHTMLELEMENT_TOSTRING, NULL}, + + /* Common for all modes */ + {DISPID_IHTMLELEMENT_PARENTELEMENT, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_CLASSNAME, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_TAGNAME, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_OFFSETLEFT, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_OFFSETTOP, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_OFFSETWIDTH, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_OFFSETHEIGHT, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_OFFSETPARENT, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_DOCUMENT, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_SOURCEINDEX, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_RECORDNUMBER, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_INNERHTML, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_INNERTEXT, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_OUTERHTML, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_OUTERTEXT, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_PARENTTEXTEDIT, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_ISTEXTEDIT, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_FILTERS, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_CHILDREN, .noattr = TRUE}, + {DISPID_IHTMLELEMENT_ALL, .noattr = TRUE}, {DISPID_UNKNOWN} }; const dispex_hook_t *const elem_ie10_hooks = elem_ie11_hooks + 10; const dispex_hook_t *const elem_ie9_hooks = elem_ie10_hooks + 2; + const dispex_hook_t *const elem_hooks = elem_ie9_hooks + 1; static const dispex_hook_t elem2_ie11_hooks[] = { {DISPID_IHTMLELEMENT2_ONLOSECAPTURE}, {DISPID_IHTMLELEMENT2_ONPROPERTYCHANGE}, @@ -6730,10 +6761,28 @@ void HTMLElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) {DISPID_IHTMLELEMENT2_SETEXPRESSION, NULL}, {DISPID_IHTMLELEMENT2_GETEXPRESSION, NULL}, {DISPID_IHTMLELEMENT2_REMOVEEXPRESSION, NULL}, + + /* Common for all modes */ + {DISPID_IHTMLELEMENT2_CURRENTSTYLE, .noattr = TRUE}, + {DISPID_IHTMLELEMENT2_SCOPENAME, .noattr = TRUE}, + {DISPID_IHTMLELEMENT2_SCROLLHEIGHT, .noattr = TRUE}, + {DISPID_IHTMLELEMENT2_SCROLLWIDTH, .noattr = TRUE}, + {DISPID_IHTMLELEMENT2_SCROLLTOP, .noattr = TRUE}, + {DISPID_IHTMLELEMENT2_SCROLLLEFT, .noattr = TRUE}, + {DISPID_IHTMLELEMENT2_RUNTIMESTYLE, .noattr = TRUE}, + {DISPID_IHTMLELEMENT2_CANHAVECHILDREN, .noattr = TRUE}, + {DISPID_IHTMLELEMENT2_BEHAVIORURNS, .noattr = TRUE}, + {DISPID_IHTMLELEMENT2_TAGURN, .noattr = TRUE}, + {DISPID_IHTMLELEMENT2_CLIENTHEIGHT, .noattr = TRUE}, + {DISPID_IHTMLELEMENT2_CLIENTWIDTH, .noattr = TRUE}, + {DISPID_IHTMLELEMENT2_CLIENTTOP, .noattr = TRUE}, + {DISPID_IHTMLELEMENT2_CLIENTLEFT, .noattr = TRUE}, + {DISPID_IHTMLELEMENT2_READYSTATE, .noattr = TRUE}, {DISPID_UNKNOWN} }; const dispex_hook_t *const elem2_ie10_hooks = elem2_ie11_hooks + 15; const dispex_hook_t *const elem2_ie9_hooks = elem2_ie10_hooks + 4; + const dispex_hook_t *const elem2_hooks = elem2_ie9_hooks + 3; static const dispex_hook_t elem3_ie11_hooks[] = { {DISPID_IHTMLELEMENT3_ONLAYOUTCOMPLETE}, {DISPID_IHTMLELEMENT3_ONMOVE}, @@ -6746,9 +6795,17 @@ void HTMLElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode)
/* IE9+ */ {DISPID_IHTMLELEMENT3_ONPAGE}, + + /* Common for all modes */ + {DISPID_IHTMLELEMENT3_ISMULTILINE, .noattr = TRUE}, + {DISPID_IHTMLELEMENT3_CANHAVEHTML, .noattr = TRUE}, + {DISPID_IHTMLELEMENT3_ISCONTENTEDITABLE, .noattr = TRUE}, + {DISPID_IHTMLELEMENT3_ISDISABLED, .noattr = TRUE}, + {DISPID_UNKNOWN} }; const dispex_hook_t *const elem3_ie9_hooks = elem3_ie11_hooks + 8; + const dispex_hook_t *const elem3_hooks = elem3_ie9_hooks + 1; static const dispex_hook_t elem7_ie11_hooks[] = { {DISPID_IHTMLELEMENT7_ONMSPOINTERHOVER},
@@ -6763,18 +6820,22 @@ void HTMLElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) {DISPID_UNKNOWN} }; const dispex_hook_t *const elem7_ie10_hooks = elem7_ie11_hooks + 1; + static const dispex_hook_t unique_name_noattr_hooks[] = { + {DISPID_IHTMLUNIQUENAME_UNIQUENUMBER, .noattr = TRUE}, + {DISPID_IHTMLUNIQUENAME_UNIQUEID, .noattr = TRUE} + };
HTMLDOMNode_init_dispex_info(info, mode);
dispex_info_add_interface(info, IHTMLElement2_tid, mode >= COMPAT_MODE_IE11 ? elem2_ie11_hooks : mode >= COMPAT_MODE_IE10 ? elem2_ie10_hooks : - mode >= COMPAT_MODE_IE9 ? elem2_ie9_hooks : NULL); + mode >= COMPAT_MODE_IE9 ? elem2_ie9_hooks : elem2_hooks); if(mode >= COMPAT_MODE_IE8) dispex_info_add_interface(info, IElementSelector_tid, NULL);
if(mode >= COMPAT_MODE_IE9) { dispex_info_add_interface(info, IHTMLElement6_tid, mode >= COMPAT_MODE_IE10 ? elem6_ie10_hooks : elem6_ie9_hooks); - dispex_info_add_interface(info, IElementTraversal_tid, NULL); + dispex_info_add_interface(info, IElementTraversal_tid, elem_traversal_noattr_hooks); }
if(mode >= COMPAT_MODE_IE10) @@ -6785,13 +6846,13 @@ void HTMLElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) }
dispex_info_add_interface(info, IHTMLElement3_tid, mode >= COMPAT_MODE_IE11 ? elem3_ie11_hooks : - mode >= COMPAT_MODE_IE9 ? elem3_ie9_hooks : NULL); + mode >= COMPAT_MODE_IE9 ? elem3_ie9_hooks : elem3_hooks); dispex_info_add_interface(info, IHTMLElement_tid, mode >= COMPAT_MODE_IE11 ? elem_ie11_hooks : mode >= COMPAT_MODE_IE10 ? elem_ie10_hooks : - mode >= COMPAT_MODE_IE9 ? elem_ie9_hooks : NULL); + mode >= COMPAT_MODE_IE9 ? elem_ie9_hooks : elem_hooks); dispex_info_add_interface(info, IHTMLElement4_tid, NULL); dispex_info_add_interface(info, IHTMLDOMNode_tid, NULL); - dispex_info_add_interface(info, IHTMLUniqueName_tid, NULL); + dispex_info_add_interface(info, IHTMLUniqueName_tid, unique_name_noattr_hooks); }
static const event_target_vtbl_t HTMLElement_event_target_vtbl = { @@ -7407,7 +7468,7 @@ static void Element_init_dispex_info(dispex_data_t *info, compat_mode_t mode) dispex_info_add_dispids(info, IHTMLElement_tid, elem_dispids); dispex_info_add_dispids(info, IHTMLElement4_tid, elem4_dispids); dispex_info_add_interface(info, IElementSelector_tid, NULL); - dispex_info_add_interface(info, IElementTraversal_tid, NULL); + dispex_info_add_interface(info, IElementTraversal_tid, elem_traversal_noattr_hooks); }
dispex_static_data_t Element_dispex = { @@ -7677,6 +7738,17 @@ static HRESULT create_filters_collection(compat_mode_t compat_mode, IHTMLFilters return S_OK; }
+static inline BOOL is_valid_attr_dispid(HTMLAttributeCollection *col, DISPID id) +{ + if(get_dispid_type(id) != DISPEXPROP_BUILTIN) + return TRUE; + + if(dispex_builtin_is_noattr(&col->elem->node.event_target.dispex, id)) + return FALSE; + + return TRUE; +} + static HRESULT get_attr_dispid_by_relative_idx(HTMLAttributeCollection *This, LONG *idx, DISPID start, DISPID *dispid) { DISPID id = start; @@ -7691,6 +7763,8 @@ static HRESULT get_attr_dispid_by_relative_idx(HTMLAttributeCollection *This, LO return hres; else if(hres == S_FALSE) break; + else if(!is_valid_attr_dispid(This, id)) + continue;
len++; if(len == *idx) @@ -7727,7 +7801,8 @@ static inline HRESULT get_attr_dispid_by_name(HTMLAttributeCollection *This, con } }
- return dispex_get_id(&This->elem->node.event_target.dispex, name, fdexNameCaseInsensitive, id); + hres = dispex_get_id(&This->elem->node.event_target.dispex, name, fdexNameCaseInsensitive, id); + return (FAILED(hres) || is_valid_attr_dispid(This, *id)) ? hres : DISP_E_UNKNOWNNAME; }
static inline HRESULT get_domattr(HTMLAttributeCollection *This, DISPID id, LONG *list_pos, HTMLDOMAttribute **attr) diff --git a/dlls/mshtml/htmlform.c b/dlls/mshtml/htmlform.c index 49c8b72e883..1af2e942c81 100644 --- a/dlls/mshtml/htmlform.c +++ b/dlls/mshtml/htmlform.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "winuser.h" #include "ole2.h" +#include "mshtmdid.h"
#include "wine/debug.h"
@@ -887,6 +888,20 @@ static const NodeImplVtbl HTMLFormElementImplVtbl = { .get_attr_col = HTMLElement_get_attr_col, };
+static void HTMLFormElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t hooks[] = { + {DISPID_IHTMLFORMELEMENT_ENCODING, .noattr = TRUE}, + {DISPID_IHTMLFORMELEMENT_ELEMENTS, .noattr = TRUE}, + {DISPID_NEWENUM, .noattr = TRUE}, + {DISPID_COLLECTION, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLFormElement_tid, hooks); + + HTMLElement_init_dispex_info(info, mode); +} + static const event_target_vtbl_t HTMLFormElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, @@ -902,18 +917,12 @@ static const event_target_vtbl_t HTMLFormElement_event_target_vtbl = { .handle_event = HTMLFormElement_handle_event };
-static const tid_t HTMLFormElement_iface_tids[] = { - IHTMLFormElement_tid, - 0 -}; - dispex_static_data_t HTMLFormElement_dispex = { .id = OBJID_HTMLFormElement, .prototype_id = OBJID_HTMLElement, .vtbl = &HTMLFormElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLFormElement_tid, - .iface_tids = HTMLFormElement_iface_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLFormElement_init_dispex_info, };
HRESULT HTMLFormElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) diff --git a/dlls/mshtml/htmlframe.c b/dlls/mshtml/htmlframe.c index 48312b59a21..d5aab3c7fcf 100644 --- a/dlls/mshtml/htmlframe.c +++ b/dlls/mshtml/htmlframe.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "winuser.h" #include "ole2.h" +#include "mshtmdid.h"
#include "mshtml_private.h" #include "binding.h" @@ -905,6 +906,25 @@ static const NodeImplVtbl HTMLFrameElementImplVtbl = { .bind_to_tree = HTMLFrameElement_bind_to_tree, };
+static void HTMLFrameElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t base2_hooks[] = { + {DISPID_IHTMLFRAMEBASE2_CONTENTWINDOW, .noattr = TRUE}, + {DISPID_IHTMLFRAMEBASE2_READYSTATE, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + static const dispex_hook_t hooks[] = { + {DISPID_IHTMLFRAMEELEMENT3_CONTENTDOCUMENT, .noattr = TRUE}, + {DISPID_IHTMLFRAMEELEMENT3_IE8_LONGDESC, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLFrameBase_tid, NULL); + dispex_info_add_interface(info, IHTMLFrameBase2_tid, base2_hooks); + dispex_info_add_interface(info, IHTMLFrameElement3_tid, hooks); + + HTMLElement_init_dispex_info(info, mode); +} + static const event_target_vtbl_t HTMLFrameElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, @@ -920,20 +940,12 @@ static const event_target_vtbl_t HTMLFrameElement_event_target_vtbl = { .handle_event = HTMLElement_handle_event };
-static const tid_t HTMLFrameElement_iface_tids[] = { - IHTMLFrameBase_tid, - IHTMLFrameBase2_tid, - IHTMLFrameElement3_tid, - 0 -}; - dispex_static_data_t HTMLFrameElement_dispex = { .id = OBJID_HTMLFrameElement, .prototype_id = OBJID_HTMLElement, .vtbl = &HTMLFrameElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLFrameElement_tid, - .iface_tids = HTMLFrameElement_iface_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLFrameElement_init_dispex_info, };
HRESULT HTMLFrameElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) @@ -1340,6 +1352,25 @@ static const NodeImplVtbl HTMLIFrameImplVtbl = { .bind_to_tree = HTMLIFrame_bind_to_tree, };
+static void HTMLIFrameElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t base2_hooks[] = { + {DISPID_IHTMLFRAMEBASE2_CONTENTWINDOW, .noattr = TRUE}, + {DISPID_IHTMLFRAMEBASE2_READYSTATE, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + static const dispex_hook_t hooks[] = { + {DISPID_IHTMLIFRAMEELEMENT3_CONTENTDOCUMENT, .noattr = TRUE}, + {DISPID_IHTMLIFRAMEELEMENT3_IE8_LONGDESC, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLFrameBase_tid, NULL); + dispex_info_add_interface(info, IHTMLFrameBase2_tid, base2_hooks); + dispex_info_add_interface(info, IHTMLIFrameElement3_tid, hooks); + + HTMLElement_init_dispex_info(info, mode); +} + static const event_target_vtbl_t HTMLIFrameElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, @@ -1356,11 +1387,8 @@ static const event_target_vtbl_t HTMLIFrameElement_event_target_vtbl = { };
static const tid_t HTMLIFrameElement_iface_tids[] = { - IHTMLFrameBase_tid, - IHTMLFrameBase2_tid, IHTMLIFrameElement_tid, IHTMLIFrameElement2_tid, - IHTMLIFrameElement3_tid, 0 };
@@ -1370,7 +1398,7 @@ dispex_static_data_t HTMLIFrameElement_dispex = { .vtbl = &HTMLIFrameElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLIFrame_tid, .iface_tids = HTMLIFrameElement_iface_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLIFrameElement_init_dispex_info, };
HRESULT HTMLIFrame_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) diff --git a/dlls/mshtml/htmlhead.c b/dlls/mshtml/htmlhead.c index 2386f243599..79ba13b5e83 100644 --- a/dlls/mshtml/htmlhead.c +++ b/dlls/mshtml/htmlhead.c @@ -402,6 +402,17 @@ static const NodeImplVtbl HTMLMetaElementImplVtbl = { .get_attr_col = HTMLElement_get_attr_col };
+static void HTMLMetaElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t hooks[] = { + {DISPID_IHTMLMETAELEMENT_HTTPEQUIV, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLMetaElement_tid, hooks); + + HTMLElement_init_dispex_info(info, mode); +} + static const event_target_vtbl_t HTMLMetaElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, @@ -414,18 +425,12 @@ static const event_target_vtbl_t HTMLMetaElement_event_target_vtbl = { .handle_event = HTMLElement_handle_event };
-static const tid_t HTMLMetaElement_iface_tids[] = { - IHTMLMetaElement_tid, - 0 -}; - dispex_static_data_t HTMLMetaElement_dispex = { .id = OBJID_HTMLMetaElement, .prototype_id = OBJID_HTMLElement, .vtbl = &HTMLMetaElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLMetaElement_tid, - .iface_tids = HTMLMetaElement_iface_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLMetaElement_init_dispex_info, };
HRESULT HTMLMetaElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) diff --git a/dlls/mshtml/htmlimg.c b/dlls/mshtml/htmlimg.c index 40c2c2dd09b..21f6d5138ff 100644 --- a/dlls/mshtml/htmlimg.c +++ b/dlls/mshtml/htmlimg.c @@ -670,12 +670,25 @@ static void HTMLImgElement_init_dispex_info(dispex_data_t *info, compat_mode_t m { static const dispex_hook_t img_ie11_hooks[] = { {DISPID_IHTMLIMGELEMENT_FILESIZE, NULL}, + + /* Common for all modes */ + {DISPID_IHTMLIMGELEMENT_READYSTATE, .noattr = TRUE}, + {DISPID_IHTMLIMGELEMENT_COMPLETE, .noattr = TRUE}, + {DISPID_IHTMLIMGELEMENT_MIMETYPE, .noattr = TRUE}, + {DISPID_IHTMLIMGELEMENT_FILESIZE, .noattr = TRUE}, + {DISPID_IHTMLIMGELEMENT_FILECREATEDDATE, .noattr = TRUE}, + {DISPID_IHTMLIMGELEMENT_FILEMODIFIEDDATE, .noattr = TRUE}, + {DISPID_IHTMLIMGELEMENT_FILEUPDATEDDATE, .noattr = TRUE}, + {DISPID_IHTMLIMGELEMENT_PROTOCOL, .noattr = TRUE}, + {DISPID_IHTMLIMGELEMENT_HREF, .noattr = TRUE}, + {DISPID_IHTMLIMGELEMENT_NAMEPROP, .noattr = TRUE}, {DISPID_UNKNOWN} }; + const dispex_hook_t *const img_hooks = img_ie11_hooks + 1;
- HTMLElement_init_dispex_info(info, mode); + dispex_info_add_interface(info, IHTMLImgElement_tid, mode >= COMPAT_MODE_IE11 ? img_ie11_hooks : img_hooks);
- dispex_info_add_interface(info, IHTMLImgElement_tid, mode >= COMPAT_MODE_IE11 ? img_ie11_hooks : NULL); + HTMLElement_init_dispex_info(info, mode); }
dispex_static_data_t HTMLImageElement_dispex = { diff --git a/dlls/mshtml/htmlinput.c b/dlls/mshtml/htmlinput.c index ca0de3131e3..779085e4107 100644 --- a/dlls/mshtml/htmlinput.c +++ b/dlls/mshtml/htmlinput.c @@ -25,6 +25,7 @@ #include "winbase.h" #include "winuser.h" #include "ole2.h" +#include "mshtmdid.h"
#include "wine/debug.h"
@@ -1270,6 +1271,27 @@ static const NodeImplVtbl HTMLInputElementImplVtbl = { .is_text_edit = HTMLInputElement_is_text_edit };
+static void HTMLInputElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t input_hooks[] = { + {DISPID_IHTMLINPUTELEMENT_READYSTATE, .noattr = TRUE}, + {DISPID_IHTMLINPUTELEMENT_FORM, .noattr = TRUE}, + {DISPID_IHTMLINPUTELEMENT_STATUS, .noattr = TRUE}, + {DISPID_IHTMLINPUTELEMENT_DEFAULTCHECKED, .noattr = TRUE}, + {DISPID_IHTMLINPUTELEMENT_COMPLETE, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + static const dispex_hook_t inputtext_hooks[] = { + {DISPID_IHTMLINPUTTEXTELEMENT2_SELECTIONSTART, .noattr = TRUE}, + {DISPID_IHTMLINPUTTEXTELEMENT2_SELECTIONEND, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLInputElement_tid, input_hooks); + dispex_info_add_interface(info, IHTMLInputTextElement2_tid, inputtext_hooks); + + HTMLElement_init_dispex_info(info, mode); +} + static const event_target_vtbl_t HTMLInputElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, @@ -1282,18 +1304,12 @@ static const event_target_vtbl_t HTMLInputElement_event_target_vtbl = { .handle_event = HTMLElement_handle_event };
-static const tid_t HTMLInputElement_iface_tids[] = { - IHTMLInputElement_tid, - IHTMLInputTextElement2_tid, - 0 -}; dispex_static_data_t HTMLInputElement_dispex = { .id = OBJID_HTMLInputElement, .prototype_id = OBJID_HTMLElement, .vtbl = &HTMLInputElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLInputElement_tid, - .iface_tids = HTMLInputElement_iface_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLInputElement_init_dispex_info, };
HRESULT HTMLInputElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) @@ -1413,6 +1429,17 @@ static const NodeImplVtbl HTMLLabelElementImplVtbl = { .get_attr_col = HTMLElement_get_attr_col, };
+static void HTMLLabelElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t label_hooks[] = { + {DISPID_IHTMLLABELELEMENT_HTMLFOR, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLLabelElement_tid, label_hooks); + + HTMLElement_init_dispex_info(info, mode); +} + static const event_target_vtbl_t HTMLLabelElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, @@ -1425,18 +1452,12 @@ static const event_target_vtbl_t HTMLLabelElement_event_target_vtbl = { .handle_event = HTMLElement_handle_event };
-static const tid_t HTMLLabelElement_iface_tids[] = { - IHTMLLabelElement_tid, - 0 -}; - dispex_static_data_t HTMLLabelElement_dispex = { .id = OBJID_HTMLLabelElement, .prototype_id = OBJID_HTMLElement, .vtbl = &HTMLLabelElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLLabelElement_tid, - .iface_tids = HTMLLabelElement_iface_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLLabelElement_init_dispex_info, };
HRESULT HTMLLabelElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) @@ -1699,6 +1720,19 @@ static const NodeImplVtbl HTMLButtonElementImplVtbl = { .is_text_edit = HTMLButtonElement_is_text_edit };
+static void HTMLButtonElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t button_hooks[] = { + {DISPID_IHTMLBUTTONELEMENT_FORM, .noattr = TRUE}, + {DISPID_IHTMLBUTTONELEMENT_VALUE, .noattr = TRUE}, + {DISPID_IHTMLBUTTONELEMENT_STATUS, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLButtonElement_tid, button_hooks); + + HTMLElement_init_dispex_info(info, mode); +} + static const event_target_vtbl_t HTMLButtonElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, @@ -1711,18 +1745,12 @@ static const event_target_vtbl_t HTMLButtonElement_event_target_vtbl = { .handle_event = HTMLElement_handle_event };
-static const tid_t HTMLButtonElement_iface_tids[] = { - IHTMLButtonElement_tid, - 0 -}; - dispex_static_data_t HTMLButtonElement_dispex = { .id = OBJID_HTMLButtonElement, .prototype_id = OBJID_HTMLElement, .vtbl = &HTMLButtonElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLButtonElement_tid, - .iface_tids = HTMLButtonElement_iface_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLButtonElement_init_dispex_info, };
HRESULT HTMLButtonElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) diff --git a/dlls/mshtml/htmllink.c b/dlls/mshtml/htmllink.c index 9ad66eef52e..f7e1ae4c42b 100644 --- a/dlls/mshtml/htmllink.c +++ b/dlls/mshtml/htmllink.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "winuser.h" #include "ole2.h" +#include "mshtmdid.h"
#include "wine/debug.h"
@@ -370,6 +371,18 @@ static const NodeImplVtbl HTMLLinkElementImplVtbl = { .get_disabled = HTMLLinkElementImpl_get_disabled, };
+static void HTMLLinkElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t link_hooks[] = { + {DISPID_IHTMLLINKELEMENT_STYLESHEET, .noattr = TRUE}, + {DISPID_IHTMLLINKELEMENT_READYSTATE, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLLinkElement_tid, link_hooks); + + HTMLElement_init_dispex_info(info, mode); +} + static const event_target_vtbl_t HTMLLinkElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, @@ -382,17 +395,12 @@ static const event_target_vtbl_t HTMLLinkElement_event_target_vtbl = { .handle_event = HTMLElement_handle_event };
-static const tid_t HTMLLinkElement_iface_tids[] = { - IHTMLLinkElement_tid, - 0 -}; dispex_static_data_t HTMLLinkElement_dispex = { .id = OBJID_HTMLLinkElement, .prototype_id = OBJID_HTMLElement, .vtbl = &HTMLLinkElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLLinkElement_tid, - .iface_tids = HTMLLinkElement_iface_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLLinkElement_init_dispex_info, };
HRESULT HTMLLinkElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c index 84c3e669109..3ace6fcdf7c 100644 --- a/dlls/mshtml/htmlnode.c +++ b/dlls/mshtml/htmlnode.c @@ -1296,15 +1296,43 @@ void HTMLDOMNode_init_dispex_info(dispex_data_t *info, compat_mode_t mode) {DISPID_IHTMLDOMNODE_REMOVENODE, NULL}, {DISPID_IHTMLDOMNODE_REPLACENODE, NULL}, {DISPID_IHTMLDOMNODE_SWAPNODE, NULL}, + + /* Common for all modes */ + {DISPID_IHTMLDOMNODE_NODETYPE, .noattr = TRUE}, + {DISPID_IHTMLDOMNODE_PARENTNODE, .noattr = TRUE}, + {DISPID_IHTMLDOMNODE_CHILDNODES, .noattr = TRUE}, + {DISPID_IHTMLDOMNODE_ATTRIBUTES, .noattr = TRUE}, + {DISPID_IHTMLDOMNODE_NODENAME, .noattr = TRUE}, + {DISPID_IHTMLDOMNODE_NODEVALUE, .noattr = TRUE}, + {DISPID_IHTMLDOMNODE_FIRSTCHILD, .noattr = TRUE}, + {DISPID_IHTMLDOMNODE_LASTCHILD, .noattr = TRUE}, + {DISPID_IHTMLDOMNODE_PREVIOUSSIBLING, .noattr = TRUE}, + {DISPID_IHTMLDOMNODE_NEXTSIBLING, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + const dispex_hook_t *const hooks = ie9_hooks + 3; + static const dispex_hook_t node2_hooks[] = { + {DISPID_IHTMLDOMNODE2_OWNERDOCUMENT, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + static const dispex_hook_t node3_hooks[] = { + {DISPID_IHTMLDOMNODE3_LOCALNAME, .noattr = TRUE}, + {DISPID_IHTMLDOMNODE3_NAMESPACEURI, .noattr = TRUE}, + {DISPID_IHTMLDOMNODE3_PREFIX, .noattr = TRUE}, + {DISPID_IHTMLDOMNODE3_TEXTCONTENT, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + static const dispex_hook_t priv_hooks[] = { + {DISPID_IHTMLELEMENT6_IE9_HASATTRIBUTES, .noattr = TRUE}, {DISPID_UNKNOWN} };
- dispex_info_add_interface(info, IHTMLDOMNode_tid, mode >= COMPAT_MODE_IE9 ? ie9_hooks : NULL); - dispex_info_add_interface(info, IHTMLDOMNode2_tid, NULL); + dispex_info_add_interface(info, IHTMLDOMNode_tid, mode >= COMPAT_MODE_IE9 ? ie9_hooks : hooks); + dispex_info_add_interface(info, IHTMLDOMNode2_tid, node2_hooks);
if(mode >= COMPAT_MODE_IE9) { - dispex_info_add_interface(info, IHTMLDOMNode3_tid, NULL); - dispex_info_add_interface(info, IWineHTMLDOMNodePrivate_tid, NULL); + dispex_info_add_interface(info, IHTMLDOMNode3_tid, node3_hooks); + dispex_info_add_interface(info, IWineHTMLDOMNodePrivate_tid, priv_hooks); }
EventTarget_init_dispex_info(info, mode); diff --git a/dlls/mshtml/htmlobject.c b/dlls/mshtml/htmlobject.c index ca49708d54e..f24f39deb74 100644 --- a/dlls/mshtml/htmlobject.c +++ b/dlls/mshtml/htmlobject.c @@ -25,6 +25,7 @@ #include "winuser.h" #include "winreg.h" #include "ole2.h" +#include "mshtmdid.h"
#include "wine/debug.h"
@@ -661,6 +662,20 @@ static const NodeImplVtbl HTMLObjectElementImplVtbl = { .get_readystate = HTMLObjectElement_get_readystate, };
+static void HTMLObjectElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t hooks[] = { + {DISPID_IHTMLOBJECTELEMENT_BASEHREF, .noattr = TRUE}, + {DISPID_IHTMLOBJECTELEMENT_FORM, .noattr = TRUE}, + {DISPID_IHTMLOBJECTELEMENT_ALTHTML, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLObjectElement2_tid, hooks); + dispex_info_add_interface(info, IHTMLObjectElement_tid, hooks); + + HTMLElement_init_dispex_info(info, mode); +} + static const event_target_vtbl_t HTMLObjectElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, @@ -676,18 +691,12 @@ static const event_target_vtbl_t HTMLObjectElement_event_target_vtbl = { .handle_event = HTMLElement_handle_event };
-static const tid_t HTMLObjectElement_iface_tids[] = { - IHTMLObjectElement2_tid, - IHTMLObjectElement_tid, - 0 -}; dispex_static_data_t HTMLObjectElement_dispex = { .id = OBJID_HTMLObjectElement, .prototype_id = OBJID_HTMLElement, .vtbl = &HTMLObjectElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLObjectElement_tid, - .iface_tids = HTMLObjectElement_iface_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLObjectElement_init_dispex_info, };
HRESULT HTMLObjectElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) diff --git a/dlls/mshtml/htmlscript.c b/dlls/mshtml/htmlscript.c index 9e21d15ce26..45f0808975a 100644 --- a/dlls/mshtml/htmlscript.c +++ b/dlls/mshtml/htmlscript.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "winuser.h" #include "ole2.h" +#include "mshtmdid.h"
#include "wine/debug.h"
@@ -376,6 +377,19 @@ static const NodeImplVtbl HTMLScriptElementImplVtbl = { .bind_to_tree = HTMLScriptElement_bind_to_tree, };
+static void HTMLScriptElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t hooks[] = { + {DISPID_IHTMLSCRIPTELEMENT_HTMLFOR, .noattr = TRUE}, + {DISPID_IHTMLSCRIPTELEMENT_TEXT, .noattr = TRUE}, + {DISPID_IHTMLSCRIPTELEMENT_READYSTATE, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLScriptElement_tid, hooks); + + HTMLElement_init_dispex_info(info, mode); +} + static const event_target_vtbl_t HTMLScriptElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, @@ -408,18 +422,12 @@ HRESULT script_elem_from_nsscript(nsIDOMHTMLScriptElement *nsscript, HTMLScriptE return S_OK; }
-static const tid_t HTMLScriptElement_iface_tids[] = { - IHTMLScriptElement_tid, - 0 -}; - dispex_static_data_t HTMLScriptElement_dispex = { .id = OBJID_HTMLScriptElement, .prototype_id = OBJID_HTMLElement, .vtbl = &HTMLScriptElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLScriptElement_tid, - .iface_tids = HTMLScriptElement_iface_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLScriptElement_init_dispex_info, };
HRESULT HTMLScriptElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) diff --git a/dlls/mshtml/htmlselect.c b/dlls/mshtml/htmlselect.c index a126f977697..97a47e38762 100644 --- a/dlls/mshtml/htmlselect.c +++ b/dlls/mshtml/htmlselect.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "winuser.h" #include "ole2.h" +#include "mshtmdid.h"
#include "wine/debug.h"
@@ -328,6 +329,20 @@ static const NodeImplVtbl HTMLOptionElementImplVtbl = { .get_attr_col = HTMLElement_get_attr_col, };
+static void HTMLOptionElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t option_hooks[] = { + {DISPID_IHTMLOPTIONELEMENT_DEFAULTSELECTED, .noattr = TRUE}, + {DISPID_IHTMLOPTIONELEMENT_TEXT, .noattr = TRUE}, + {DISPID_IHTMLOPTIONELEMENT_INDEX, .noattr = TRUE}, + {DISPID_IHTMLOPTIONELEMENT_FORM, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLOptionElement_tid, option_hooks); + + HTMLElement_init_dispex_info(info, mode); +} + static const event_target_vtbl_t HTMLOptionElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, @@ -340,17 +355,12 @@ static const event_target_vtbl_t HTMLOptionElement_event_target_vtbl = { .handle_event = HTMLElement_handle_event };
-static const tid_t HTMLOptionElement_iface_tids[] = { - IHTMLOptionElement_tid, - 0 -}; dispex_static_data_t HTMLOptionElement_dispex = { .id = OBJID_HTMLOptionElement, .prototype_id = OBJID_HTMLElement, .vtbl = &HTMLOptionElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLOptionElement_tid, - .iface_tids = HTMLOptionElement_iface_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLOptionElement_init_dispex_info, };
HRESULT HTMLOptionElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) @@ -1238,6 +1248,22 @@ static const NodeImplVtbl HTMLSelectElementImplVtbl = { .get_disabled = HTMLSelectElementImpl_get_disabled, };
+static void HTMLSelectElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t select_hooks[] = { + {DISPID_IHTMLSELECTELEMENT_FORM, .noattr = TRUE}, + {DISPID_IHTMLSELECTELEMENT_OPTIONS, .noattr = TRUE}, + {DISPID_IHTMLSELECTELEMENT_SELECTEDINDEX, .noattr = TRUE}, + {DISPID_IHTMLSELECTELEMENT_VALUE, .noattr = TRUE}, + {DISPID_IHTMLSELECTELEMENT_TYPE, .noattr = TRUE}, + {DISPID_COLLECTION, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLSelectElement_tid, select_hooks); + + HTMLElement_init_dispex_info(info, mode); +} + static const event_target_vtbl_t HTMLSelectElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, @@ -1253,18 +1279,12 @@ static const event_target_vtbl_t HTMLSelectElement_event_target_vtbl = { .handle_event = HTMLElement_handle_event };
-static const tid_t HTMLSelectElement_tids[] = { - IHTMLSelectElement_tid, - 0 -}; - dispex_static_data_t HTMLSelectElement_dispex = { .id = OBJID_HTMLSelectElement, .prototype_id = OBJID_HTMLElement, .vtbl = &HTMLSelectElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLSelectElement_tid, - .iface_tids = HTMLSelectElement_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLSelectElement_init_dispex_info, };
HRESULT HTMLSelectElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) diff --git a/dlls/mshtml/htmlstyleelem.c b/dlls/mshtml/htmlstyleelem.c index d400f4980cb..4c3a222471e 100644 --- a/dlls/mshtml/htmlstyleelem.c +++ b/dlls/mshtml/htmlstyleelem.c @@ -302,11 +302,15 @@ static void HTMLStyleElement_init_dispex_info(dispex_data_t *info, compat_mode_t {DISPID_IHTMLSTYLEELEMENT_STYLESHEET, NULL}, {DISPID_UNKNOWN} }; + static const dispex_hook_t hooks[] = { + {DISPID_IHTMLSTYLEELEMENT_STYLESHEET, .noattr = TRUE}, + {DISPID_UNKNOWN} + };
HTMLElement_init_dispex_info(info, mode);
dispex_info_add_interface(info, IHTMLStyleElement_tid, - mode >= COMPAT_MODE_IE11 ? ie11_hooks : NULL); + mode >= COMPAT_MODE_IE11 ? ie11_hooks : hooks);
if(mode >= COMPAT_MODE_IE9) dispex_info_add_interface(info, IHTMLStyleElement2_tid, NULL); diff --git a/dlls/mshtml/htmltable.c b/dlls/mshtml/htmltable.c index 27e1d258b22..26b14c72cfa 100644 --- a/dlls/mshtml/htmltable.c +++ b/dlls/mshtml/htmltable.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "winuser.h" #include "ole2.h" +#include "mshtmdid.h"
#include "wine/debug.h"
@@ -430,17 +431,22 @@ static const NodeImplVtbl HTMLTableCellImplVtbl = { .get_attr_col = HTMLElement_get_attr_col, };
-static const tid_t HTMLTableDataCellElement_iface_tids[] = { - IHTMLTableCell_tid, - 0 -}; +static void HTMLTableCellElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t hooks[] = { + {DISPID_IHTMLTABLECELL_CELLINDEX, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLTableCell_tid, hooks); + + HTMLElement_init_dispex_info(info, mode); +}
dispex_static_data_t HTMLTableCellElement_dispex = { .id = OBJID_HTMLTableCellElement, .prototype_id = OBJID_HTMLElement, .disp_tid = DispHTMLTableCell_tid, - .iface_tids = HTMLTableDataCellElement_iface_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLTableCellElement_init_dispex_info, };
static const event_target_vtbl_t HTMLTableDataCellElement_event_target_vtbl = { @@ -460,8 +466,7 @@ dispex_static_data_t HTMLTableDataCellElement_dispex = { .prototype_id = OBJID_HTMLTableCellElement, .vtbl = &HTMLTableDataCellElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLTableCell_tid, - .iface_tids = HTMLTableDataCellElement_iface_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLTableCellElement_init_dispex_info, };
HRESULT HTMLTableCell_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) @@ -812,6 +817,19 @@ static const NodeImplVtbl HTMLTableRowImplVtbl = { .get_attr_col = HTMLElement_get_attr_col, };
+static void HTMLTableRowElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t hooks[] = { + {DISPID_IHTMLTABLEROW_ROWINDEX, .noattr = TRUE}, + {DISPID_IHTMLTABLEROW_SECTIONROWINDEX, .noattr = TRUE}, + {DISPID_IHTMLTABLEROW_CELLS, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLTableRow_tid, hooks); + + HTMLElement_init_dispex_info(info, mode); +} + static const event_target_vtbl_t HTMLTableRowElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, @@ -824,18 +842,12 @@ static const event_target_vtbl_t HTMLTableRowElement_event_target_vtbl = { .handle_event = HTMLElement_handle_event };
-static const tid_t HTMLTableRowElement_iface_tids[] = { - IHTMLTableRow_tid, - 0 -}; - dispex_static_data_t HTMLTableRowElement_dispex = { .id = OBJID_HTMLTableRowElement, .prototype_id = OBJID_HTMLElement, .vtbl = &HTMLTableRowElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLTableRow_tid, - .iface_tids = HTMLTableRowElement_iface_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLTableRowElement_init_dispex_info, };
HRESULT HTMLTableRow_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) @@ -1663,6 +1675,27 @@ static const NodeImplVtbl HTMLTableImplVtbl = { .get_attr_col = HTMLElement_get_attr_col, };
+static void HTMLTableElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t table_hooks[] = { + {DISPID_IHTMLTABLE_ROWS, .noattr = TRUE}, + {DISPID_IHTMLTABLE_THEAD, .noattr = TRUE}, + {DISPID_IHTMLTABLE_TFOOT, .noattr = TRUE}, + {DISPID_IHTMLTABLE_TBODIES, .noattr = TRUE}, + {DISPID_IHTMLTABLE_CAPTION, .noattr = TRUE}, + {DISPID_IHTMLTABLE_READYSTATE, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + static const dispex_hook_t table2_hooks[] = { + {DISPID_IHTMLTABLE2_CELLS, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLTable_tid, table_hooks); + dispex_info_add_interface(info, IHTMLTable2_tid, table2_hooks); + + HTMLElement_init_dispex_info(info, mode); +} + static const event_target_vtbl_t HTMLTableElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, @@ -1676,8 +1709,6 @@ static const event_target_vtbl_t HTMLTableElement_event_target_vtbl = { };
static const tid_t HTMLTableElement_iface_tids[] = { - IHTMLTable_tid, - IHTMLTable2_tid, IHTMLTable3_tid, 0 }; @@ -1688,7 +1719,7 @@ dispex_static_data_t HTMLTableElement_dispex = { .vtbl = &HTMLTableElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLTable_tid, .iface_tids = HTMLTableElement_iface_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLTableElement_init_dispex_info, };
HRESULT HTMLTable_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) diff --git a/dlls/mshtml/htmltextarea.c b/dlls/mshtml/htmltextarea.c index e8a846047e8..3eb714b7b08 100644 --- a/dlls/mshtml/htmltextarea.c +++ b/dlls/mshtml/htmltextarea.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "winuser.h" #include "ole2.h" +#include "mshtmdid.h"
#include "wine/debug.h"
@@ -397,6 +398,20 @@ static const NodeImplVtbl HTMLTextAreaElementImplVtbl = { .is_text_edit = HTMLTextAreaElement_is_text_edit };
+static void HTMLTextAreaElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t hooks[] = { + {DISPID_IHTMLTEXTAREAELEMENT_FORM, .noattr = TRUE}, + {DISPID_IHTMLTEXTAREAELEMENT_VALUE, .noattr = TRUE}, + {DISPID_IHTMLTEXTAREAELEMENT_TYPE, .noattr = TRUE}, + {DISPID_IHTMLTEXTAREAELEMENT_STATUS, .noattr = TRUE}, + {DISPID_UNKNOWN} + }; + dispex_info_add_interface(info, IHTMLTextAreaElement_tid, hooks); + + HTMLElement_init_dispex_info(info, mode); +} + static const event_target_vtbl_t HTMLTextAreaElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, @@ -409,18 +424,12 @@ static const event_target_vtbl_t HTMLTextAreaElement_event_target_vtbl = { .handle_event = HTMLElement_handle_event };
-static const tid_t HTMLTextAreaElement_iface_tids[] = { - IHTMLTextAreaElement_tid, - 0 -}; - dispex_static_data_t HTMLTextAreaElement_dispex = { .id = OBJID_HTMLTextAreaElement, .prototype_id = OBJID_HTMLElement, .vtbl = &HTMLTextAreaElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLTextAreaElement_tid, - .iface_tids = HTMLTextAreaElement_iface_tids, - .init_info = HTMLElement_init_dispex_info, + .init_info = HTMLTextAreaElement_init_dispex_info, };
HRESULT HTMLTextAreaElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 4319c8b4725..4eac921223f 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -548,6 +548,7 @@ typedef struct { DISPID dispid; dispex_hook_invoke_t invoke; const WCHAR *name; + BOOL noattr; } dispex_hook_t;
struct DispatchEx { @@ -649,6 +650,7 @@ HRESULT dispex_prop_name(DispatchEx *dispex, DISPID id, BSTR *ret); HRESULT dispex_define_property(DispatchEx *dispex, const WCHAR *name, DWORD flags, VARIANT *v, DISPID *id); HRESULT dispex_index_prop_desc(DispatchEx*,DISPID,struct property_info*); const WCHAR *dispex_builtin_prop_name(DispatchEx *dispex, DISPID id); +BOOL dispex_builtin_is_noattr(DispatchEx *dispex, DISPID id); IWineJSDispatchHost *dispex_outer_iface(DispatchEx *dispex); HRESULT get_constructor(HTMLInnerWindow *script_global, object_id_t id, DispatchEx **ret); HRESULT get_prototype(HTMLInnerWindow *script_global, object_id_t id, DispatchEx **ret); diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 9eb7bac9a11..1a0a8295fd1 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -3794,18 +3794,20 @@ static void test_attr_collection_disp(IDispatch *disp)
static void test_attr_collection(IHTMLElement *elem) { - static const WCHAR testW[] = {'t','e','s','t',0}; - - IHTMLDOMNode *node; - IDispatch *disp, *attr; IHTMLAttributeCollection *attr_col; - BSTR name = SysAllocString(testW); + IDispatch *disp, *attr; IEnumVARIANT *enum_var; + DISPPARAMS dp = { 0 }; + LONG i, len, checked; + IDispatchEx *dispex; + IHTMLDOMNode *node; IUnknown *enum_unk; VARIANT id, val; - LONG i, len, checked; + DISPID dispid; ULONG fetched; + EXCEPINFO ei; HRESULT hres; + BSTR name;
hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLDOMNode, (void**)&node); ok(hres == S_OK, "QueryInterface failed: %08lx\n", hres); @@ -3822,11 +3824,31 @@ static void test_attr_collection(IHTMLElement *elem) hres = IDispatch_QueryInterface(disp, &IID_IHTMLAttributeCollection, (void**)&attr_col); ok(hres == S_OK, "QueryInterface failed: %08lx\n", hres);
+ hres = IUnknown_QueryInterface(elem, &IID_IDispatchEx, (void**)&dispex); + ok(hres == S_OK, "QueryInterface failed: %08lx\n", hres); + + name = SysAllocString(L"attributes"); + hres = IDispatchEx_GetDispID(dispex, name, fdexNameCaseSensitive, &dispid); + ok(hres == S_OK, "GetDispID failed: %08lx\n", hres); + SysFreeString(name); + + VariantInit(&val); + hres = IDispatchEx_InvokeEx(dispex, dispid, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dp, &val, &ei, NULL); + ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres); + ok(V_VT(&val) == VT_DISPATCH, "V_VT(attributes) = %d\n", V_VT(&val)); + ok(V_DISPATCH(&val) != NULL, "V_DISPATCH(attributes) == NULL\n"); + + ok(iface_cmp((IUnknown*)attr_col, (IUnknown*)V_DISPATCH(&val)), "attr_col != attr_col from disp\n"); + IDispatchEx_Release(dispex); + VariantClear(&val); + hres = IHTMLAttributeCollection_get_length(attr_col, &i); ok(hres == S_OK, "get_length failed: %08lx\n", hres); + ok(i > 3, "length = %ld\n", i);
V_VT(&val) = VT_I4; V_I4(&val) = 1; + name = SysAllocString(L"test"); hres = IHTMLElement_setAttribute(elem, name, val, 0); ok(hres == S_OK, "setAttribute failed: %08lx\n", hres); SysFreeString(name); @@ -3892,6 +3914,250 @@ static void test_attr_collection(IHTMLElement *elem) IHTMLAttributeCollection_Release(attr_col); }
+static void test_attr_collection_builtins(IHTMLDocument2 *doc) +{ + static const WCHAR *generic_builtins[] = { + L"accessKey", L"aria-activedescendant", L"aria-atomic", L"aria-autocomplete", L"aria-busy", L"aria-checked", L"aria-controls", L"aria-describedby", + L"aria-disabled", L"aria-dropeffect", L"aria-expanded", L"aria-flowto", L"aria-grabbed", L"aria-haspopup", L"aria-hidden", L"aria-invalid", L"aria-label", + L"aria-labelledby", L"aria-level", L"aria-live", L"aria-multiline", L"aria-multiselectable", L"aria-orientation", L"aria-owns", L"aria-posinset", + L"aria-pressed", L"aria-readonly", L"aria-relevant", L"aria-required", L"aria-secret", L"aria-selected", L"aria-setsize", L"aria-sort", L"aria-valuemax", + L"aria-valuemin", L"aria-valuenow", L"aria-valuetext", L"class", L"contentEditable", L"dataFld", L"dataFormatAs", L"dataSrc", L"dir", L"disabled", + L"hideFocus", L"id", L"implementation", L"lang", L"language", L"onactivate", L"onafterupdate", L"onbeforeactivate", L"onbeforecopy", L"onbeforecut", + L"onbeforedeactivate", L"onbeforeeditfocus", L"onbeforepaste", L"onbeforeupdate", L"onblur", L"oncellchange", L"onclick", L"oncontextmenu", L"oncontrolselect", + L"oncopy", L"oncuechange", L"oncut", L"ondataavailable", L"ondatasetchanged", L"ondatasetcomplete", L"ondblclick", L"ondeactivate", L"ondrag", L"ondragend", + L"ondragenter", L"ondragleave", L"ondragover", L"ondragstart", L"ondrop", L"onerrorupdate", L"onfilterchange", L"onfocus", L"onfocusin", L"onfocusout", + L"onhelp", L"oninvalid", L"onkeydown", L"onkeypress", L"onkeyup", L"onlayoutcomplete", L"onlosecapture", L"onmousedown", L"onmouseenter", L"onmouseleave", + L"onmousemove", L"onmouseout", L"onmouseover", L"onmouseup", L"onmousewheel", L"onmove", L"onmoveend", L"onmovestart", L"onmsanimationend", + L"onmsanimationiteration", L"onmsanimationstart", L"onmsmanipulationstatechanged", L"onmstransitionend", L"onmstransitionstart", L"onpage", L"onpaste", + L"onpropertychange", L"onreadystatechange", L"onresize", L"onresizeend", L"onresizestart", L"onrowenter", L"onrowexit", L"onrowsdelete", L"onrowsinserted", + L"onscroll", L"onselectstart", L"role", L"spellcheck", L"style", L"tabIndex", L"title", L"x-ms-acceleratorkey", L"x-ms-aria-flowfrom" + }; + static const WCHAR *generic_builtins_todo[] = { + L"aria-activedescendant", L"aria-atomic", L"aria-autocomplete", L"aria-busy", L"aria-checked", L"aria-controls", L"aria-describedby", L"aria-disabled", + L"aria-dropeffect", L"aria-expanded", L"aria-flowto", L"aria-grabbed", L"aria-haspopup", L"aria-hidden", L"aria-invalid", L"aria-label", L"aria-labelledby", + L"aria-level", L"aria-live", L"aria-multiline", L"aria-multiselectable", L"aria-orientation", L"aria-owns", L"aria-posinset", L"aria-pressed", L"aria-readonly", + L"aria-relevant", L"aria-required", L"aria-secret", L"aria-selected", L"aria-setsize", L"aria-sort", L"aria-valuemax", L"aria-valuemin", L"aria-valuenow", + L"aria-valuetext", L"class", L"dataFld", L"dataFormatAs", L"dataSrc", L"implementation", L"oncuechange", L"oninvalid", L"onmouseenter", L"onmsanimationend", + L"onmsanimationiteration", L"onmsanimationstart", L"onmsmanipulationstatechanged", L"onmstransitionend", L"onmstransitionstart", L"role", L"spellcheck", + L"x-ms-acceleratorkey", L"x-ms-aria-flowfrom" + }; + static const WCHAR *tags[] = { + L"audio", NULL, + L"b", L"cite", L"dateTime", NULL, + L"base", L"href", L"target", NULL, + L"basefont", L"color", L"face", L"size", NULL, + L"body", L"aLink", L"background", L"bgColor", L"bgProperties", L"bottomMargin", L"leftMargin", L"link", L"noWrap", L"onafterprint", L"onbeforeprint", L"onbeforeunload", + L"onhashchange", L"onload", L"onoffline", L"ononline", L"onselect", L"onunload", L"rightMargin", L"scroll", L"text", L"topMargin", L"vLink", NULL, + L"br", L"clear", NULL, + L"button", L"formaction", L"formenctype", L"formmethod", L"formnovalidate", L"formtarget", L"name", L"type", NULL, + L"caption", L"align", L"vAlign", NULL, + L"center", L"cite", L"clear", L"width", NULL, + L"code", L"cite", L"dateTime", NULL, + L"col", L"align", L"bgColor", L"ch", L"chOff", L"span", L"vAlign", L"width", NULL, + L"dd", L"noWrap", NULL, + L"dir", L"compact", L"type", NULL, + L"div", L"align", L"nofocusrect", L"noWrap", NULL, + L"dl", L"compact", NULL, + L"dt", L"noWrap", NULL, + L"embed", L"align", L"codeBase", L"height", L"hidden", L"name", L"palette", L"pluginspage", L"src", L"type", L"units", L"width", NULL, + L"fieldset", L"align", NULL, + L"font", L"color", L"face", L"size", NULL, + L"form", L"accept-charset", L"action", L"encType", L"method", L"name", L"onreset", L"onsubmit", L"target", NULL, + L"frame", L"allowTransparency", L"border", L"borderColor", L"frameBorder", L"frameSpacing", L"longDesc", L"marginHeight", L"marginWidth", L"name", L"noResize", L"onload", L"scrolling", L"src", NULL, + L"frameset", L"border", L"borderColor", L"cols", L"frameBorder", L"frameSpacing", L"name", L"onafterprint", L"onbeforeprint", L"onbeforeunload", L"onload", L"onunload", L"rows", NULL, + L"h1", L"align", L"cite", L"clear", L"width", NULL, + L"head", L"profile", NULL, + L"hr", L"align", L"color", L"noShade", L"SIZE", L"width", NULL, + L"html", L"version", NULL, + L"i", L"cite", L"dateTime", NULL, + L"iframe", L"align", L"allowTransparency", L"border", L"frameBorder", L"frameSpacing", L"height", L"hspace", L"longDesc", L"marginHeight", L"marginWidth", + L"name", L"noResize", L"onload", L"scrolling", L"src", L"vspace", L"width", NULL, + L"img", L"align", L"alt", L"border", L"dynsrc", L"height", L"hspace", L"isMap", L"longDesc", L"loop", L"lowsrc", L"name", + L"onabort", L"onerror", L"onload", L"src", L"start", L"useMap", L"vrml", L"vspace", L"width", NULL, + L"input", L"accept", L"align", L"alt", L"border", L"cache", L"checked", L"dynsrc", L"formaction", L"formenctype", L"formmethod", L"formnovalidate", L"formtarget", + L"height", L"hspace", L"indeterminate", L"loop", L"lowsrc", L"maxLength", L"name", L"onabort", L"onchange", L"onerror", L"onload", L"onselect", L"readOnly", + L"size", L"src", L"start", L"type", L"useMap", L"value", L"vrml", L"vspace", L"width", NULL, + L"label", L"for", NULL, + L"legend", L"align", NULL, + L"li", L"type", L"value", NULL, + L"link", L"charset", L"href", L"hreflang", L"media", L"onerror", L"onload", L"rel", L"rev", L"target", L"type", NULL, + L"map", L"name", NULL, + L"meta", L"charset", L"content", L"http-equiv", L"name", L"scheme", L"url", NULL, + L"noscript", NULL, + L"object", L"align", L"alt", L"archive", L"border", L"classid", L"code", L"codeBase", L"codeType", L"data", L"declare", L"height", + L"hspace", L"name", L"object", L"onerror", L"standby", L"type", L"useMap", L"vspace", L"width", NULL, + L"ol", L"compact", L"start", L"type", NULL, + L"option", L"label", L"selected", L"value", NULL, + L"p", L"align", L"cite", L"clear", L"width", NULL, + L"param", L"name", L"type", L"value", L"valueType", NULL, + L"pre", L"cite", L"clear", L"width", NULL, + L"q", L"cite", L"dateTime", NULL, + L"script", L"charset", L"defer", L"event", L"for", L"onerror", L"src", L"type", NULL, + L"select", L"align", L"multiple", L"name", L"onchange", L"size", NULL, + L"span", L"cite", L"dateTime", L"nofocusrect", NULL, + L"style", L"media", L"onerror", L"onload", L"type", NULL, + L"table", L"align", L"background", L"bgColor", L"border", L"borderColor", L"borderColorDark", L"borderColorLight", L"cellPadding", L"cellSpacing", + L"cols", L"dataPageSize", L"frame", L"height", L"rules", L"summary", L"width", NULL, + L"tbody", L"align", L"bgColor", L"ch", L"chOff", L"vAlign", NULL, + L"td", L"abbr", L"align", L"axis", L"background", L"bgColor", L"borderColor", L"borderColorDark", L"borderColorLight", L"ch", L"chOff", + L"colSpan", L"headers", L"height", L"noWrap", L"rowSpan", L"scope", L"vAlign", L"width", NULL, + L"textarea", L"cols", L"name", L"onchange", L"onselect", L"readOnly", L"rows", L"wrap", NULL, + L"tr", L"align", L"bgColor", L"borderColor", L"borderColorDark", L"borderColorLight", L"ch", L"chOff", L"height", L"vAlign", NULL, + L"ul", L"compact", L"type", NULL, + L"video", NULL, + L"winetest", NULL, + NULL + }; + static const WCHAR *tags_todo[] = { + L"b", L"cite", L"dateTime", NULL, + L"base", L"href", L"target", NULL, + L"basefont", L"color", L"face", L"size", NULL, + L"body", L"onhashchange", L"onoffline", L"ononline", NULL, + L"br", L"clear", NULL, + L"button", L"formaction", L"formenctype", L"formmethod", L"formnovalidate", L"formtarget", NULL, + L"caption", L"align", L"vAlign", NULL, + L"center", L"cite", L"clear", L"width", NULL, + L"code", L"cite", L"dateTime", NULL, + L"col", L"align", L"bgColor", L"ch", L"chOff", L"span", L"vAlign", L"width", NULL, + L"dd", L"noWrap", NULL, + L"dir", L"compact", L"type", NULL, + L"div", L"align", L"nofocusrect", L"noWrap", NULL, + L"dl", L"compact", NULL, + L"dt", L"noWrap", NULL, + L"embed", L"align", L"codeBase", L"type", NULL, + L"fieldset", L"align", NULL, + L"font", L"color", L"face", L"size", NULL, + L"form", L"accept-charset", L"encType", NULL, + L"frame", L"borderColor", L"longDesc", NULL, + L"frameset", L"border", L"borderColor", L"cols", L"frameBorder", L"frameSpacing", L"name", L"onafterprint", L"onbeforeprint", L"onbeforeunload", L"onload", L"onunload", L"rows", NULL, + L"h1", L"align", L"cite", L"clear", L"width", NULL, + L"hr", L"align", L"color", L"noShade", L"SIZE", L"width", NULL, + L"i", L"cite", L"dateTime", NULL, + L"iframe", L"longDesc", NULL, + L"img", L"longDesc", NULL, + L"input", L"accept", L"cache", L"dynsrc", L"formaction", L"formenctype", L"formmethod", L"formnovalidate", L"formtarget", L"useMap", NULL, + L"label", L"for", NULL, + L"legend", L"align", NULL, + L"li", L"type", L"value", NULL, + L"link", L"charset", L"hreflang", L"target", NULL, + L"map", L"name", NULL, + L"meta", L"http-equiv", L"scheme", NULL, + L"object", L"alt", L"archive", L"border", L"classid", L"data", L"declare", L"object", L"standby", L"useMap", NULL, + L"ol", L"compact", L"start", L"type", NULL, + L"option", L"label", NULL, + L"p", L"align", L"cite", L"clear", L"width", NULL, + L"param", L"name", L"type", L"value", L"valueType", NULL, + L"pre", L"cite", L"clear", L"width", NULL, + L"q", L"cite", L"dateTime", NULL, + L"script", L"charset", L"for", NULL, + L"select", L"align", NULL, + L"span", L"cite", L"dateTime", L"nofocusrect", NULL, + L"tbody", L"align", L"bgColor", L"ch", L"chOff", L"vAlign", NULL, + L"td", L"abbr", L"axis", L"ch", L"chOff", L"headers", L"scope", NULL, + L"tr", L"ch", L"chOff", L"height", NULL, + L"ul", L"compact", L"type", NULL, + NULL + }; + BOOLEAN found[ARRAY_SIZE(generic_builtins)]; + BOOLEAN found_tag_specific[36]; + + const WCHAR **iter = tags, **iter_todo = tags_todo; + IHTMLAttributeCollection *attr_col; + IHTMLDOMAttribute *attr; + IHTMLElement *elem; + IHTMLDOMNode *node; + IDispatch *disp; + LONG i, j, len; + HRESULT hres; + VARIANT id; + BSTR bstr; + + while(*iter) { + const WCHAR *tag = *iter++, **todos = NULL; + + if(*iter_todo && !wcscmp(tag, *iter_todo)) { + todos = ++iter_todo; + while(*iter_todo++) {} + } + + bstr = SysAllocString(tag); + hres = IHTMLDocument2_createElement(doc, bstr, &elem); + ok(hres == S_OK, "[%s] createElement failed: %08lx\n", wine_dbgstr_w(tag), hres); + SysFreeString(bstr); + + hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLDOMNode, (void**)&node); + ok(hres == S_OK, "[%s] Could not get IHTMLDOMNode iface: %08lx\n", wine_dbgstr_w(tag), hres); + IHTMLElement_Release(elem); + + hres = IHTMLDOMNode_get_attributes(node, &disp); + ok(hres == S_OK, "[%s] get_attributes failed: %08lx\n", wine_dbgstr_w(tag), hres); + IHTMLDOMNode_Release(node); + + hres = IDispatch_QueryInterface(disp, &IID_IHTMLAttributeCollection, (void**)&attr_col); + ok(hres == S_OK, "[%s] Could not get IHTMLAttributeCollection iface: %08lx\n", wine_dbgstr_w(tag), hres); + IDispatch_Release(disp); + + hres = IHTMLAttributeCollection_get_length(attr_col, &len); + ok(hres == S_OK, "[%s] get_length failed: %08lx\n", wine_dbgstr_w(tag), hres); + + memset(found, 0, sizeof(found)); + memset(found_tag_specific, 0, sizeof(found_tag_specific)); + for(i = 0; i < len; i++) { + BOOL expected = FALSE; + + V_VT(&id) = VT_I4; + V_I4(&id) = i; + hres = IHTMLAttributeCollection_item(attr_col, &id, &disp); + ok(hres == S_OK, "[%s:%ld] item failed: %08lx\n", wine_dbgstr_w(tag), i, hres); + + hres = IDispatch_QueryInterface(disp, &IID_IHTMLDOMAttribute, (void**)&attr); + ok(hres == S_OK, "[%s:%ld] Could not get IHTMLDOMAttribute iface: %08lx\n", wine_dbgstr_w(tag), i, hres); + IDispatch_Release(disp); + + hres = IHTMLDOMAttribute_get_nodeName(attr, &bstr); + ok(hres == S_OK, "[%s:%ld] get_nodeName failed: %08lx\n", wine_dbgstr_w(tag), i, hres); + IHTMLDOMAttribute_Release(attr); + + for(j = 0; j < ARRAY_SIZE(generic_builtins); j++) { + if(!wcscmp(bstr, generic_builtins[j])) { + found[j] = TRUE; + expected = TRUE; + break; + } + } + if(!expected) { + for(j = 0; iter[j]; j++) { + if(!wcsicmp(bstr, iter[j])) { + found_tag_specific[j] = TRUE; + expected = TRUE; + break; + } + } + } + ok(expected, "[%s] %s is in collection but not in expected list\n", wine_dbgstr_w(tag), wine_dbgstr_w(bstr)); + SysFreeString(bstr); + } + IHTMLAttributeCollection_Release(attr_col); + + for(i = 0; i < ARRAY_SIZE(generic_builtins); i++) { + for(j = 0; !found[i] && j < ARRAY_SIZE(generic_builtins_todo); j++) + if(!wcscmp(generic_builtins[i], generic_builtins_todo[j])) + break; + todo_wine_if(!found[i] && j < ARRAY_SIZE(generic_builtins_todo)) + ok(found[i], "[%s] %s not in collection\n", wine_dbgstr_w(tag), wine_dbgstr_w(generic_builtins[i])); + } + + for(i = 0; iter[i]; i++) { + for(j = 0; !found_tag_specific[i] && todos && todos[j]; j++) + if(!wcscmp(iter[i], todos[j])) + break; + todo_wine_if(!found_tag_specific[i] && todos && todos[j]) + ok(found_tag_specific[i], "[%s] %s not in collection\n", wine_dbgstr_w(tag), wine_dbgstr_w(iter[i])); + } + iter += i + 1; + } +} + #define test_elem_id(e,i) _test_elem_id(__LINE__,e,i) static void _test_elem_id(unsigned line, IUnknown *unk, const WCHAR *exid) { @@ -5116,6 +5382,24 @@ static void _link_put_href(unsigned line, IHTMLElement *elem, const WCHAR *v) _test_link_href(line, elem, v); }
+#define elem_has_attr(a,b) _elem_has_attr(__LINE__,a,b) +static BOOL _elem_has_attr(unsigned line, IUnknown *unk, const WCHAR *attr_name) +{ + BSTR str = SysAllocString(attr_name); + IHTMLElement6 *elem; + VARIANT_BOOL b; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement6, (void**)&elem); + ok_(__FILE__,line)(hres == S_OK, "Could not get IHTMLElement6: %08lx\n", hres); + hres = IHTMLElement6_hasAttribute(elem, str, &b); + ok_(__FILE__,line)(hres == S_OK, "hasAttribute failed: %08lx\n", hres); + IHTMLElement6_Release(elem); + SysFreeString(str); + + return b != VARIANT_FALSE; +} + #define get_elem_doc(e) _get_elem_doc(__LINE__,e) static IHTMLDocument2 *_get_elem_doc(unsigned line, IUnknown *unk) { @@ -10076,8 +10360,31 @@ static void test_attr_node(IHTMLDOMAttribute *test_attr, IHTMLDocument2 *doc)
static void test_attr(IHTMLDocument2 *doc, IHTMLElement *elem) { + static const WCHAR *elem_attr_props[] = { + L"accessKey", L"contentEditable", L"dir", L"disabled", L"hideFocus", L"id", L"lang", L"language", L"onactivate", L"onafterupdate", L"onbeforeactivate", + L"onbeforecopy", L"onbeforecut", L"onbeforedeactivate", L"onbeforeeditfocus", L"onbeforepaste", L"onbeforeupdate", L"onblur", L"oncellchange", L"onclick", + L"oncontextmenu", L"oncontrolselect", L"oncopy", L"oncut", L"ondataavailable", L"ondatasetchanged", L"ondatasetcomplete", L"ondblclick", L"ondeactivate", + L"ondrag", L"ondragend", L"ondragenter", L"ondragleave", L"ondragover", L"ondragstart", L"ondrop", L"onerrorupdate", L"onfilterchange", L"onfocus", + L"onfocusin", L"onfocusout", L"onhelp", L"onkeydown", L"onkeypress", L"onkeyup", L"onlayoutcomplete", L"onlosecapture", L"onmousedown", L"onmouseleave", + L"onmousemove", L"onmouseout", L"onmouseover", L"onmouseup", L"onmousewheel", L"onmove", L"onmoveend", L"onmovestart", L"onpage", L"onpaste", + L"onpropertychange", L"onreadystatechange", L"onresize", L"onresizeend", L"onresizestart", L"onrowenter", L"onrowexit", L"onrowsdelete", + L"onrowsinserted", L"onscroll", L"onselectstart", L"style", L"tabIndex", L"title" + }; + static const WCHAR *elem_noattr_props[] = { + L"addBehavior", L"all", L"applyElement", L"attachEvent", L"attributes", L"behaviorUrns", L"blur", L"canHaveHTML", L"childNodes", L"children", L"className", + L"clearAttributes", L"click", L"clientHeight", L"clientLeft", L"clientTop", L"clientWidth", L"componentFromPoint", L"contains", L"createControlRange", + L"currentStyle", L"detachEvent", L"document", L"doScroll", L"dragDrop", L"filters", L"fireEvent", L"firstChild", L"focus", L"getAdjacentText", L"getAttribute", + L"getAttributeNode", L"getBoundingClientRect", L"getClientRects", L"getElementsByTagName", L"getExpression", L"innerHTML", L"innerText", L"insertAdjacentElement", + L"insertAdjacentHTML", L"insertAdjacentText", L"isContentEditable", L"isDisabled", L"isMultiLine", L"isTextEdit", L"lastChild", L"mergeAttributes", L"nextSibling", + L"nodeName", L"nodeName", L"nodeType", L"nodeValue", L"normalize", L"offsetHeight", L"offsetLeft", L"offsetParent", L"offsetTop", L"offsetWidth", L"outerHTML", + L"outerText", L"ownerDocument", L"parentElement", L"parentNode", L"parentTextEdit", L"previousSibling", L"readyState", L"recordNumber", L"removeAttribute", + L"removeAttributeNode", L"removeBehavior", L"removeExpression", L"replaceAdjacentText", L"runtimeStyle", L"scopeName", L"scrollHeight", L"scrollIntoView", + L"scrollLeft", L"scrollTop", L"scrollWidth", L"setActive", L"setAttribute", L"setAttributeNode", L"setExpression", L"sourceIndex", L"tagName", L"tagUrn", + L"toString", L"uniqueID", L"uniqueNumber" + }; IHTMLDOMAttribute *attr, *attr2, *attr3; IHTMLElement4 *elem4; + unsigned i; VARIANT v; HRESULT hres;
@@ -10165,6 +10472,24 @@ static void test_attr(IHTMLDocument2 *doc, IHTMLElement *elem) test_attr_specified(attr, VARIANT_FALSE); test_attr_expando(attr, VARIANT_FALSE); test_attr_node(attr, doc); + + for(i = 0; i < ARRAY_SIZE(elem_attr_props); i++) { + BOOL has_attr = elem_has_attr((IUnknown*)elem, elem_attr_props[i]); + + attr = get_elem_attr_node((IUnknown*)elem, elem_attr_props[i], TRUE); + test_attr_specified(attr, has_attr ? VARIANT_TRUE : VARIANT_FALSE); + test_attr_expando(attr, VARIANT_FALSE); + IHTMLDOMAttribute_Release(attr); + } + for(i = 0; i < ARRAY_SIZE(elem_noattr_props); i++) { + get_elem_attr_node((IUnknown*)elem, elem_noattr_props[i], FALSE); + } + + ok(elem_has_attr((IUnknown*)elem, L"emptyattr"), "elem does not have emptyattr"); + attr = get_elem_attr_node((IUnknown*)elem, L"emptyattr", TRUE); + test_attr_specified(attr, VARIANT_TRUE); + test_attr_expando(attr, VARIANT_TRUE); + test_attr_node(attr, doc); IHTMLDOMAttribute_Release(attr);
/* Test created, detached attribute. */ @@ -12532,6 +12857,7 @@ START_TEST(dom) run_domtest(elem_test2_str, test_elems2); run_domtest(doc_blank, test_dom_elements); run_domtest(doc_blank, test_about_blank_storage); + run_domtest(doc_blank, test_attr_collection_builtins); if(is_ie9plus) { compat_mode = COMPAT_IE9; run_domtest(doc_blank_ie9, test_dom_elements);