Commit c54edb2b authored by Gabriel Ivăncescu's avatar Gabriel Ivăncescu Committed by Alexandre Julliard

mshtml: Implement setAttributeNS for Elements.

parent 821b1090
...@@ -4845,8 +4845,42 @@ static HRESULT WINAPI HTMLElement6_getAttributeNS(IHTMLElement6 *iface, VARIANT ...@@ -4845,8 +4845,42 @@ static HRESULT WINAPI HTMLElement6_getAttributeNS(IHTMLElement6 *iface, VARIANT
static HRESULT WINAPI HTMLElement6_setAttributeNS(IHTMLElement6 *iface, VARIANT *pvarNS, BSTR strAttributeName, VARIANT *pvarAttributeValue) static HRESULT WINAPI HTMLElement6_setAttributeNS(IHTMLElement6 *iface, VARIANT *pvarNS, BSTR strAttributeName, VARIANT *pvarAttributeValue)
{ {
HTMLElement *This = impl_from_IHTMLElement6(iface); HTMLElement *This = impl_from_IHTMLElement6(iface);
FIXME("(%p)->(%s %s %s)\n", This, debugstr_variant(pvarNS), debugstr_w(strAttributeName), debugstr_variant(pvarAttributeValue)); nsAString ns_str, name_str, value_str;
return E_NOTIMPL; const PRUnichar *ns;
nsresult nsres;
HRESULT hres;
TRACE("(%p)->(%s %s %s)\n", This, debugstr_variant(pvarNS), debugstr_w(strAttributeName), debugstr_variant(pvarAttributeValue));
hres = variant_to_nsstr(pvarNS, FALSE, &ns_str);
if(FAILED(hres))
return hres;
nsAString_GetData(&ns_str, &ns);
if((!ns || !ns[0]) && wcschr(strAttributeName, ':')) {
/* FIXME: Return NamespaceError */
return E_FAIL;
}
if(!This->dom_element) {
FIXME("No dom_element\n");
nsAString_Finish(&ns_str);
return E_NOTIMPL;
}
hres = variant_to_nsstr(pvarAttributeValue, FALSE, &value_str);
if(FAILED(hres)) {
nsAString_Finish(&ns_str);
return hres;
}
nsAString_InitDepend(&name_str, strAttributeName);
nsres = nsIDOMElement_SetAttributeNS(This->dom_element, &ns_str, &name_str, &value_str);
nsAString_Finish(&ns_str);
nsAString_Finish(&name_str);
nsAString_Finish(&value_str);
if(NS_FAILED(nsres))
WARN("SetAttributeNS failed: %08lx\n", nsres);
return map_nsresult(nsres);
} }
static HRESULT WINAPI HTMLElement6_removeAttributeNS(IHTMLElement6 *iface, VARIANT *pvarNS, BSTR strAttributeName) static HRESULT WINAPI HTMLElement6_removeAttributeNS(IHTMLElement6 *iface, VARIANT *pvarNS, BSTR strAttributeName)
...@@ -6845,6 +6879,61 @@ static HRESULT IHTMLElement6_getAttributeNS_hook(DispatchEx *dispex, WORD flags, ...@@ -6845,6 +6879,61 @@ static HRESULT IHTMLElement6_getAttributeNS_hook(DispatchEx *dispex, WORD flags,
return hres; return hres;
} }
static HRESULT IHTMLElement6_setAttributeNS_hook(DispatchEx *dispex, WORD flags, DISPPARAMS *dp,
VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
{
BOOL ns_conv = FALSE, val_conv = FALSE;
VARIANT args[3];
HRESULT hres;
DISPPARAMS new_dp = { args, NULL, 3, 0 };
if(!(flags & DISPATCH_METHOD) || dp->cArgs < 3 || dp->cNamedArgs)
return S_FALSE;
if(dispex_compat_mode(dispex) < COMPAT_MODE_IE10)
args[2] = dp->rgvarg[dp->cArgs - 1];
else {
switch(V_VT(&dp->rgvarg[dp->cArgs - 1])) {
case VT_EMPTY:
case VT_BSTR:
case VT_NULL:
args[2] = dp->rgvarg[dp->cArgs - 1];
break;
default:
hres = change_type(&args[2], &dp->rgvarg[dp->cArgs - 1], VT_BSTR, caller);
if(FAILED(hres))
return hres;
ns_conv = TRUE;
break;
}
}
switch(V_VT(&dp->rgvarg[dp->cArgs - 3])) {
case VT_EMPTY:
case VT_BSTR:
case VT_NULL:
if(!ns_conv)
return S_FALSE;
args[0] = dp->rgvarg[dp->cArgs - 3];
break;
default:
hres = change_type(&args[0], &dp->rgvarg[dp->cArgs - 3], VT_BSTR, caller);
if(FAILED(hres)) {
if(ns_conv)
VariantClear(&args[2]);
return hres;
}
val_conv = TRUE;
break;
}
args[1] = dp->rgvarg[dp->cArgs - 2];
hres = dispex_call_builtin(dispex, DISPID_IHTMLELEMENT6_SETATTRIBUTENS, &new_dp, res, ei, caller);
if(ns_conv) VariantClear(&args[2]);
if(val_conv) VariantClear(&args[0]);
return hres;
}
static HRESULT IHTMLElement6_setAttribute_hook(DispatchEx *dispex, WORD flags, DISPPARAMS *dp, static HRESULT IHTMLElement6_setAttribute_hook(DispatchEx *dispex, WORD flags, DISPPARAMS *dp,
VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
{ {
...@@ -6876,8 +6965,13 @@ static HRESULT IHTMLElement6_setAttribute_hook(DispatchEx *dispex, WORD flags, D ...@@ -6876,8 +6965,13 @@ static HRESULT IHTMLElement6_setAttribute_hook(DispatchEx *dispex, WORD flags, D
void HTMLElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) void HTMLElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode)
{ {
static const dispex_hook_t elem6_ie9_hooks[] = {
{DISPID_IHTMLELEMENT6_SETATTRIBUTENS, IHTMLElement6_setAttributeNS_hook},
{DISPID_UNKNOWN}
};
static const dispex_hook_t elem6_ie10_hooks[] = { static const dispex_hook_t elem6_ie10_hooks[] = {
{DISPID_IHTMLELEMENT6_GETATTRIBUTENS, IHTMLElement6_getAttributeNS_hook}, {DISPID_IHTMLELEMENT6_GETATTRIBUTENS, IHTMLElement6_getAttributeNS_hook},
{DISPID_IHTMLELEMENT6_SETATTRIBUTENS, IHTMLElement6_setAttributeNS_hook},
{DISPID_IHTMLELEMENT6_IE9_SETATTRIBUTE, IHTMLElement6_setAttribute_hook}, {DISPID_IHTMLELEMENT6_IE9_SETATTRIBUTE, IHTMLElement6_setAttribute_hook},
{DISPID_UNKNOWN} {DISPID_UNKNOWN}
}; };
...@@ -6895,7 +6989,7 @@ void HTMLElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) ...@@ -6895,7 +6989,7 @@ void HTMLElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode)
dispex_info_add_interface(info, IElementSelector_tid, NULL); dispex_info_add_interface(info, IElementSelector_tid, NULL);
if(mode >= COMPAT_MODE_IE9) { if(mode >= COMPAT_MODE_IE9) {
dispex_info_add_interface(info, IHTMLElement6_tid, mode >= COMPAT_MODE_IE10 ? elem6_ie10_hooks : NULL); 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, NULL);
} }
......
...@@ -1408,6 +1408,134 @@ sync_test("elem_attr", function() { ...@@ -1408,6 +1408,134 @@ sync_test("elem_attr", function() {
} }
}); });
sync_test("elem_attrNS", function() {
var v = document.documentMode;
if(v < 9) return; /* not available */
var specialspace_ns = "http://www.mozilla.org/ns/specialspace";
var svg_ns = "http://www.w3.org/2000/svg";
var elem = document.createElement("div"), r;
elem.setAttributeNS(specialspace_ns, "spec:align", "left");
r = elem.getAttribute("spec:align");
ok(r === "left", "spec:align = " + r);
r = elem.getAttribute("align");
ok(r === null, "align = " + r);
r = elem.getAttributeNS(null, "spec:align");
ok(r === "", "null spec:align = " + r);
r = elem.getAttributeNS(null, "align");
ok(r === "", "null align = " + r);
r = elem.getAttributeNS(svg_ns, "spec:align");
ok(r === "", "svg spec:align = " + r);
r = elem.getAttributeNS(svg_ns, "align");
ok(r === "", "svg align = " + r);
r = elem.getAttributeNS(specialspace_ns, "spec:align");
ok(r === "", "specialspace spec:align = " + r);
r = elem.getAttributeNS(specialspace_ns, "align");
ok(r === "left", "specialspace align = " + r);
try {
elem.setAttributeNS(null, "spec:align", "right");
ok(false, "expected exception setting qualified attr with null ns");
}catch(ex) {
todo_wine.
ok(ex.message === "NamespaceError", "setAttributeNS(null, 'spec:align', 'right') threw " + ex.message);
}
try {
elem.setAttributeNS("", "spec:align", "right");
ok(false, "expected exception setting qualified attr with empty ns");
}catch(ex) {
todo_wine.
ok(ex.message === "NamespaceError", "setAttributeNS('', 'spec:align', 'right') threw " + ex.message);
}
elem.setAttributeNS(null, "align", "right");
r = elem.getAttribute("spec:align");
ok(r === "left", "spec:align (null) = " + r);
r = elem.getAttribute("align");
ok(r === "right", "align (null) = " + r);
r = elem.getAttributeNS(null, "spec:align");
ok(r === "", "null spec:align (null) = " + r);
r = elem.getAttributeNS(null, "align");
ok(r === "right", "null align (null) = " + r);
r = elem.getAttributeNS(svg_ns, "spec:align");
ok(r === "", "svg spec:align (null) = " + r);
r = elem.getAttributeNS(svg_ns, "align");
ok(r === "", "svg align (null) = " + r);
r = elem.getAttributeNS(specialspace_ns, "spec:align");
ok(r === "", "specialspace spec:align (null) = " + r);
r = elem.getAttributeNS(specialspace_ns, "align");
ok(r === "left", "specialspace align (null) = " + r);
elem.setAttribute("align", "center");
r = elem.getAttributeNS(null, "spec:align");
ok(r === "", "null spec:align (non-NS) = " + r);
r = elem.getAttributeNS(null, "align");
ok(r === "center", "null align (non-NS) = " + r);
r = elem.getAttributeNS(svg_ns, "spec:align");
ok(r === "", "svg spec:align (non-NS) = " + r);
r = elem.getAttributeNS(svg_ns, "align");
ok(r === "", "svg align (non-NS) = " + r);
r = elem.getAttributeNS(specialspace_ns, "spec:align");
ok(r === "", "specialspace spec:align (non-NS) = " + r);
r = elem.getAttributeNS(specialspace_ns, "align");
ok(r === "left", "specialspace align (non-NS) = " + r);
elem.setAttribute("emptynsattr", "none");
elem.setAttributeNS("", "emptynsattr", "test");
r = elem.getAttribute("emptynsattr");
ok(r === "test", "emptynsattr without NS = " + r);
elem.setAttributeNS(null, "emptynsattr", "wine");
r = elem.getAttribute("emptynsattr");
ok(r === "wine", "emptynsattr without NS = " + r);
elem.setAttributeNS(specialspace_ns, "emptynsattr", "ns");
r = elem.getAttribute("emptynsattr");
ok(r === "wine", "emptynsattr without NS = " + r);
r = elem.getAttributeNS("", "emptynsattr");
ok(r === "wine", "emptynsattr empty ns = " + r);
r = elem.getAttributeNS(null, "emptynsattr");
ok(r === "wine", "emptynsattr null ns = " + r);
r = elem.getAttributeNS(specialspace_ns, "emptynsattr");
ok(r === "ns", "emptynsattr specialspace ns = " + r);
var ns = {};
ns.toString = function() { return "toString namespace"; }
ns.valueOf = function() { return "valueOf namespace"; }
elem.setAttributeNS(ns, "foobar", "test");
r = elem.getAttribute("foobar");
ok(r === "test", "foobar without NS = " + r);
r = elem.getAttributeNS(ns, "foobar");
ok(r === "test", "foobar = " + r);
r = elem.getAttributeNS("toString namespace", "foobar");
ok(r === (v < 10 ? "" : "test"), "foobar (toString namespace) = " + r);
r = elem.getAttributeNS("valueOf namespace", "foobar");
ok(r === (v < 10 ? "test" : ""), "foobar (valueOf namespace) = " + r);
var arr = [3];
elem.setAttributeNS(svg_ns, "testattr", arr);
r = elem.getAttributeNS(svg_ns, "testattr");
ok(r === "3", "testattr = " + r);
ok(elem.testattr === undefined, "elem.testattr = " + elem.testattr);
arr.toString = function() { return 42; }
elem.setAttributeNS(svg_ns, "testattr", arr);
r = elem.getAttributeNS(svg_ns, "testattr");
ok(r === "42", "testattr with custom toString = " + r);
arr.valueOf = function() { return "arrval"; }
elem.setAttributeNS(svg_ns, "testattr", arr);
r = elem.getAttributeNS(svg_ns, "testattr");
ok(r === "42", "testattr with custom valueOf = " + r);
elem.setAttributeNS(svg_ns, "boolattr", true);
r = elem.getAttributeNS(svg_ns, "boolattr");
ok(r === "true", "boolattr = " + r);
elem.setAttributeNS(svg_ns, "numattr", 13);
r = elem.getAttributeNS(svg_ns, "numattr");
ok(r === "13", "numattr = " + r);
});
sync_test("builtins_diffs", function() { sync_test("builtins_diffs", function() {
var v = document.documentMode; var v = document.documentMode;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment