mshtml: Added IHTMLElement4::setAttributeNode implementation.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
423b7ba1d1
commit
17fcc112ad
|
@ -491,6 +491,11 @@ static dispex_static_data_t HTMLDOMAttribute_dispex = {
|
|||
HTMLDOMAttribute_iface_tids
|
||||
};
|
||||
|
||||
HTMLDOMAttribute *unsafe_impl_from_IHTMLDOMAttribute(IHTMLDOMAttribute *iface)
|
||||
{
|
||||
return iface->lpVtbl == &HTMLDOMAttributeVtbl ? impl_from_IHTMLDOMAttribute(iface) : NULL;
|
||||
}
|
||||
|
||||
HRESULT HTMLDOMAttribute_Create(const WCHAR *name, HTMLElement *elem, DISPID dispid, HTMLDOMAttribute **attr)
|
||||
{
|
||||
HTMLAttributeCollection *col;
|
||||
|
|
|
@ -612,14 +612,27 @@ static HRESULT WINAPI HTMLElement_Invoke(IHTMLElement *iface, DISPID dispIdMembe
|
|||
wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
||||
}
|
||||
|
||||
static HRESULT set_elem_attr_value_by_dispid(HTMLElement *elem, DISPID dispid, VARIANT *v)
|
||||
{
|
||||
DISPID propput_dispid = DISPID_PROPERTYPUT;
|
||||
DISPPARAMS dp = {v, &propput_dispid, 1, 1};
|
||||
EXCEPINFO ei;
|
||||
|
||||
if(dispid == DISPID_IHTMLELEMENT_STYLE) {
|
||||
TRACE("Ignoring call on style attribute\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return IDispatchEx_InvokeEx(&elem->node.event_target.dispex.IDispatchEx_iface, dispid,
|
||||
LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HTMLElement_setAttribute(IHTMLElement *iface, BSTR strAttributeName,
|
||||
VARIANT AttributeValue, LONG lFlags)
|
||||
{
|
||||
HTMLElement *This = impl_from_IHTMLElement(iface);
|
||||
DISPID dispid;
|
||||
HRESULT hres;
|
||||
DISPID dispid, dispidNamed = DISPID_PROPERTYPUT;
|
||||
DISPPARAMS dispParams;
|
||||
EXCEPINFO excep;
|
||||
|
||||
TRACE("(%p)->(%s %s %08x)\n", This, debugstr_w(strAttributeName), debugstr_variant(&AttributeValue), lFlags);
|
||||
|
||||
|
@ -628,18 +641,7 @@ static HRESULT WINAPI HTMLElement_setAttribute(IHTMLElement *iface, BSTR strAttr
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(dispid == DISPID_IHTMLELEMENT_STYLE) {
|
||||
TRACE("Ignoring call on style attribute\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
dispParams.cArgs = 1;
|
||||
dispParams.cNamedArgs = 1;
|
||||
dispParams.rgdispidNamedArgs = &dispidNamed;
|
||||
dispParams.rgvarg = &AttributeValue;
|
||||
|
||||
return IDispatchEx_InvokeEx(&This->node.event_target.dispex.IDispatchEx_iface, dispid,
|
||||
LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &dispParams, NULL, &excep, NULL);
|
||||
return set_elem_attr_value_by_dispid(This, dispid, &AttributeValue);
|
||||
}
|
||||
|
||||
HRESULT get_elem_attr_value_by_dispid(HTMLElement *elem, DISPID dispid, VARIANT *ret)
|
||||
|
@ -3718,8 +3720,68 @@ static HRESULT WINAPI HTMLElement4_setAttributeNode(IHTMLElement4 *iface, IHTMLD
|
|||
IHTMLDOMAttribute **ppretAttribute)
|
||||
{
|
||||
HTMLElement *This = impl_from_IHTMLElement4(iface);
|
||||
FIXME("(%p)->(%p %p)\n", This, pattr, ppretAttribute);
|
||||
return E_NOTIMPL;
|
||||
HTMLDOMAttribute *attr, *iter, *replace = NULL;
|
||||
HTMLAttributeCollection *attrs;
|
||||
DISPID dispid;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%p %p)\n", This, pattr, ppretAttribute);
|
||||
|
||||
attr = unsafe_impl_from_IHTMLDOMAttribute(pattr);
|
||||
if(!attr)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if(attr->elem) {
|
||||
WARN("Tried to set already attached attribute.\n");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
hres = IDispatchEx_GetDispID(&This->node.event_target.dispex.IDispatchEx_iface,
|
||||
attr->name, fdexNameCaseInsensitive|fdexNameEnsure, &dispid);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = HTMLElement_get_attr_col(&This->node, &attrs);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(iter, &attrs->attrs, HTMLDOMAttribute, entry) {
|
||||
if(iter->dispid == dispid) {
|
||||
replace = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(replace) {
|
||||
hres = get_elem_attr_value_by_dispid(This, dispid, &replace->value);
|
||||
if(FAILED(hres)) {
|
||||
WARN("could not get attr value: %08x\n", hres);
|
||||
V_VT(&replace->value) = VT_EMPTY;
|
||||
}
|
||||
if(!replace->name) {
|
||||
replace->name = attr->name;
|
||||
attr->name = NULL;
|
||||
}
|
||||
list_add_head(&replace->entry, &attr->entry);
|
||||
list_remove(&replace->entry);
|
||||
replace->elem = NULL;
|
||||
}else {
|
||||
list_add_tail(&attrs->attrs, &attr->entry);
|
||||
}
|
||||
|
||||
IHTMLDOMAttribute_AddRef(&attr->IHTMLDOMAttribute_iface);
|
||||
attr->elem = This;
|
||||
attr->dispid = dispid;
|
||||
|
||||
IHTMLAttributeCollection_Release(&attrs->IHTMLAttributeCollection_iface);
|
||||
|
||||
hres = set_elem_attr_value_by_dispid(This, dispid, &attr->value);
|
||||
if(FAILED(hres))
|
||||
WARN("Could not set attribute value: %08x\n", hres);
|
||||
VariantClear(&attr->value);
|
||||
|
||||
*ppretAttribute = replace ? &replace->IHTMLDOMAttribute_iface : NULL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HTMLElement4_removeAttributeNode(IHTMLElement4 *iface, IHTMLDOMAttribute *pattr,
|
||||
|
|
|
@ -943,15 +943,18 @@ typedef struct {
|
|||
|
||||
LONG ref;
|
||||
|
||||
/* name and value are valid only for detached attributes (when elem == NULL). */
|
||||
WCHAR *name;
|
||||
/* value is valid only for detached attributes (when elem == NULL). */
|
||||
VARIANT value;
|
||||
/* name must be valid for detached attributes */
|
||||
WCHAR *name;
|
||||
|
||||
HTMLElement *elem;
|
||||
DISPID dispid;
|
||||
struct list entry;
|
||||
} HTMLDOMAttribute;
|
||||
|
||||
HTMLDOMAttribute *unsafe_impl_from_IHTMLDOMAttribute(IHTMLDOMAttribute*) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT HTMLDOMAttribute_Create(const WCHAR*,HTMLElement*,DISPID,HTMLDOMAttribute**) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT HTMLElement_Create(HTMLDocumentNode*,nsIDOMNode*,BOOL,HTMLElement**) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -8524,8 +8524,10 @@ static void test_elems(IHTMLDocument2 *doc)
|
|||
|
||||
static void test_attr(IHTMLDocument2 *doc, IHTMLElement *elem)
|
||||
{
|
||||
IHTMLDOMAttribute *attr, *attr2;
|
||||
IHTMLDOMAttribute *attr, *attr2, *attr3;
|
||||
IHTMLElement4 *elem4;
|
||||
VARIANT v;
|
||||
HRESULT hres;
|
||||
|
||||
get_elem_attr_node((IUnknown*)elem, "noattr", FALSE);
|
||||
|
||||
|
@ -8636,6 +8638,57 @@ static void test_attr(IHTMLDocument2 *doc, IHTMLElement *elem)
|
|||
SysFreeString(V_BSTR(&v));
|
||||
test_attr_value(attr, "testing");
|
||||
|
||||
elem4 = get_elem4_iface((IUnknown*)elem);
|
||||
|
||||
hres = IHTMLElement4_setAttributeNode(elem4, attr, &attr2);
|
||||
ok(hres == S_OK, "setAttributeNode failed: %08x\n", hres);
|
||||
ok(!attr2, "attr2 != NULL\n");
|
||||
|
||||
test_elem_attr(elem, "Test", "testing");
|
||||
put_attr_value(attr, "new value");
|
||||
test_elem_attr(elem, "Test", "new value");
|
||||
|
||||
attr2 = get_elem_attr_node((IUnknown*)elem, "Test", TRUE);
|
||||
ok(iface_cmp((IUnknown*)attr2, (IUnknown*)attr), "attr2 != attr\n");
|
||||
IHTMLDOMAttribute_Release(attr2);
|
||||
|
||||
attr3 = create_attr((IUnknown*)doc, "Test");
|
||||
put_attr_value(attr3, "replace test");
|
||||
|
||||
hres = IHTMLElement4_setAttributeNode(elem4, attr3, &attr2);
|
||||
ok(hres == S_OK, "setAttributeNode failed: %08x\n", hres);
|
||||
ok(iface_cmp((IUnknown*)attr2, (IUnknown*)attr), "attr2 != attr\n");
|
||||
IHTMLDOMAttribute_Release(attr2);
|
||||
|
||||
test_elem_attr(elem, "Test", "replace test");
|
||||
test_attr_value(attr, "new value");
|
||||
test_attr_value(attr3, "replace test");
|
||||
|
||||
attr2 = get_elem_attr_node((IUnknown*)elem, "Test", TRUE);
|
||||
ok(iface_cmp((IUnknown*)attr2, (IUnknown*)attr3), "attr2 != attr3\n");
|
||||
IHTMLDOMAttribute_Release(attr2);
|
||||
|
||||
put_attr_value(attr, "new value2");
|
||||
test_elem_attr(elem, "Test", "replace test");
|
||||
test_attr_value(attr, "new value2");
|
||||
test_attr_value(attr3, "replace test");
|
||||
|
||||
put_attr_value(attr3, "new replace value");
|
||||
test_elem_attr(elem, "Test", "new replace value");
|
||||
test_attr_value(attr, "new value2");
|
||||
test_attr_value(attr3, "new replace value");
|
||||
|
||||
/* Attached attributes cause errors. */
|
||||
hres = IHTMLElement4_setAttributeNode(elem4, attr3, &attr2);
|
||||
ok(hres == E_INVALIDARG, "setAttributeNode failed: %08x, expected E_INVALIDARG\n", hres);
|
||||
IHTMLDOMAttribute_Release(attr3);
|
||||
|
||||
attr2 = get_elem_attr_node((IUnknown*)elem, "id", TRUE);
|
||||
hres = IHTMLElement4_setAttributeNode(elem4, attr2, &attr3);
|
||||
ok(hres == E_INVALIDARG, "setAttributeNode failed: %08x, expected E_INVALIDARG\n", hres);
|
||||
IHTMLDOMAttribute_Release(attr2);
|
||||
|
||||
IHTMLElement4_Release(elem4);
|
||||
IHTMLDOMAttribute_Release(attr);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue