From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlattr.c | 87 +++++++++++++++++++++++++++++++ dlls/mshtml/mshtml_private.h | 2 + dlls/mshtml/tests/documentmode.js | 53 +++++++++++++++++++ dlls/mshtml/tests/dom.c | 1 + 4 files changed, 143 insertions(+)
diff --git a/dlls/mshtml/htmlattr.c b/dlls/mshtml/htmlattr.c index d1e8a8e71bb..77d90837ef9 100644 --- a/dlls/mshtml/htmlattr.c +++ b/dlls/mshtml/htmlattr.c @@ -409,6 +409,83 @@ static const IHTMLDOMAttribute2Vtbl HTMLDOMAttribute2Vtbl = { HTMLDOMAttribute2_cloneNode };
+static inline HTMLDOMAttribute *impl_from_IHTMLDOMAttribute3(IHTMLDOMAttribute3 *iface) +{ + return CONTAINING_RECORD(iface, HTMLDOMAttribute, IHTMLDOMAttribute3_iface); +} + +DISPEX_IDISPATCH_IMPL(HTMLDOMAttribute3, IHTMLDOMAttribute3, impl_from_IHTMLDOMAttribute3(iface)->dispex) + +static HRESULT WINAPI HTMLDOMAttribute3_put_nodeValue(IHTMLDOMAttribute3 *iface, VARIANT v) +{ + HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute3(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + + return HTMLDOMAttribute_put_nodeValue(&This->IHTMLDOMAttribute_iface, v); +} + +static HRESULT WINAPI HTMLDOMAttribute3_get_nodeValue(IHTMLDOMAttribute3 *iface, VARIANT *p) +{ + HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute3(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return HTMLDOMAttribute_get_nodeValue(&This->IHTMLDOMAttribute_iface, p); +} + +static HRESULT WINAPI HTMLDOMAttribute3_put_value(IHTMLDOMAttribute3 *iface, BSTR v) +{ + HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute3(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + return HTMLDOMAttribute2_put_value(&This->IHTMLDOMAttribute2_iface, v); +} + +static HRESULT WINAPI HTMLDOMAttribute3_get_value(IHTMLDOMAttribute3 *iface, BSTR *p) +{ + HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute3(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return HTMLDOMAttribute2_get_value(&This->IHTMLDOMAttribute2_iface, p); +} + +static HRESULT WINAPI HTMLDOMAttribute3_get_specified(IHTMLDOMAttribute3 *iface, VARIANT_BOOL *p) +{ + HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute3(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return HTMLDOMAttribute_get_specified(&This->IHTMLDOMAttribute_iface, p); +} + +static HRESULT WINAPI HTMLDOMAttribute3_get_ownerElement(IHTMLDOMAttribute3 *iface, IHTMLElement2 **p) +{ + HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute3(iface); + + FIXME("(%p)->(%p)\n", This, p); + + return E_NOTIMPL; +} + +static const IHTMLDOMAttribute3Vtbl HTMLDOMAttribute3Vtbl = { + HTMLDOMAttribute3_QueryInterface, + HTMLDOMAttribute3_AddRef, + HTMLDOMAttribute3_Release, + HTMLDOMAttribute3_GetTypeInfoCount, + HTMLDOMAttribute3_GetTypeInfo, + HTMLDOMAttribute3_GetIDsOfNames, + HTMLDOMAttribute3_Invoke, + HTMLDOMAttribute3_put_nodeValue, + HTMLDOMAttribute3_get_nodeValue, + HTMLDOMAttribute3_put_value, + HTMLDOMAttribute3_get_value, + HTMLDOMAttribute3_get_specified, + HTMLDOMAttribute3_get_ownerElement +}; + static inline HTMLDOMAttribute *impl_from_DispatchEx(DispatchEx *iface) { return CONTAINING_RECORD(iface, HTMLDOMAttribute, dispex); @@ -422,6 +499,8 @@ static void *HTMLDOMAttribute_query_interface(DispatchEx *dispex, REFIID riid) return &This->IHTMLDOMAttribute_iface; if(IsEqualGUID(&IID_IHTMLDOMAttribute2, riid)) return &This->IHTMLDOMAttribute2_iface; + if(IsEqualGUID(&IID_IHTMLDOMAttribute3, riid)) + return &This->IHTMLDOMAttribute3_iface;
return NULL; } @@ -469,6 +548,12 @@ static const dispex_static_data_vtbl_t HTMLDOMAttribute_dispex_vtbl = { .unlink = HTMLDOMAttribute_unlink };
+static void HTMLDOMAttribute_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + if(mode >= COMPAT_MODE_IE8) + dispex_info_add_interface(info, IHTMLDOMAttribute3_tid, NULL); +} + static const tid_t HTMLDOMAttribute_iface_tids[] = { IHTMLDOMAttribute_tid, IHTMLDOMAttribute2_tid, @@ -480,6 +565,7 @@ dispex_static_data_t Attr_dispex = { .vtbl = &HTMLDOMAttribute_dispex_vtbl, .disp_tid = DispHTMLDOMAttribute_tid, .iface_tids = HTMLDOMAttribute_iface_tids, + .init_info = HTMLDOMAttribute_init_dispex_info, };
HTMLDOMAttribute *unsafe_impl_from_IHTMLDOMAttribute(IHTMLDOMAttribute *iface) @@ -500,6 +586,7 @@ HRESULT HTMLDOMAttribute_Create(const WCHAR *name, HTMLElement *elem, DISPID dis
ret->IHTMLDOMAttribute_iface.lpVtbl = &HTMLDOMAttributeVtbl; ret->IHTMLDOMAttribute2_iface.lpVtbl = &HTMLDOMAttribute2Vtbl; + ret->IHTMLDOMAttribute3_iface.lpVtbl = &HTMLDOMAttribute3Vtbl; ret->dispid = dispid; ret->elem = elem;
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 4bee0a26607..4c055325575 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -201,6 +201,7 @@ struct constructor; XIID(IHTMLDocument7) \ XIID(IHTMLDOMAttribute) \ XIID(IHTMLDOMAttribute2) \ + XIID(IHTMLDOMAttribute3) \ XIID(IHTMLDOMChildrenCollection) \ XIID(IHTMLDOMImplementation) \ XIID(IHTMLDOMImplementation2) \ @@ -1334,6 +1335,7 @@ typedef struct { DispatchEx dispex; IHTMLDOMAttribute IHTMLDOMAttribute_iface; IHTMLDOMAttribute2 IHTMLDOMAttribute2_iface; + IHTMLDOMAttribute3 IHTMLDOMAttribute3_iface;
/* value is valid only for detached attributes (when elem == NULL). */ VARIANT value; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index d41f82647f0..c2847ce7643 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -575,6 +575,59 @@ sync_test("elem_props", function() { test_exposed("fileSize", v < 11); });
+sync_test("attr_props", function() { + var v = document.documentMode, elem = document.createElement("div"), attr; + + /* FIXME: Wine's IE9+ attributes don't sync with our attribute node implementation which is based on legacy attrs */ + if(!broken(true)) + attr = elem.attributes[0]; + else { + elem.setAttribute("id", "test"); + attr = elem.getAttributeNode("id"); + } + + function test_exposed(prop, expect) { + if(expect) + ok(prop in attr, prop + " not found in attribute."); + else + ok(!(prop in attr), prop + " found in attribute."); + } + + test_exposed("appendChild", true); + test_exposed("attributes", true); + test_exposed("childNodes", true); + test_exposed("cloneNode", true); + test_exposed("compareDocumentPosition", v >= 9); + test_exposed("expando", true); + test_exposed("firstChild", true); + test_exposed("hasChildNodes", true); + test_exposed("insertBefore", true); + test_exposed("isDefaultNamespace", v >= 9); + test_exposed("isEqualNode", v >= 9); + test_exposed("isSameNode", v >= 9); + test_exposed("isSupported", v >= 9); + test_exposed("lastChild", true); + test_exposed("localName", v >= 9); + test_exposed("lookupNamespaceURI", v >= 9); + test_exposed("lookupPrefix", v >= 9); + test_exposed("name", true); + test_exposed("namespaceURI", v >= 9); + test_exposed("nextSibling", true); + test_exposed("nodeName", true); + test_exposed("nodeType", true); + test_exposed("nodeValue", true); + test_exposed("ownerDocument", true); + test_exposed("ownerElement", v >= 8); + test_exposed("parentNode", true); + test_exposed("prefix", v >= 9); + test_exposed("previousSibling", true); + test_exposed("removeChild", true); + test_exposed("replaceChild", true); + test_exposed("specified", true); + test_exposed("textContent", v >= 9); + test_exposed("value", true); +}); + sync_test("doc_props", function() { function test_exposed(prop, expect, is_todo) { var ok_ = is_todo ? todo_wine.ok : ok; diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index dd987350e72..b1625b619ca 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -319,6 +319,7 @@ static const IID * const text_iids[] = { static const IID * const attr_iids[] = { &IID_IHTMLDOMAttribute, &IID_IHTMLDOMAttribute2, + &IID_IHTMLDOMAttribute3, &IID_IDispatchEx, NULL };