fix(dom): preserve namespaced attribute qualified names

This commit is contained in:
SGavrl committed 2026-08-01 16:00:52 +00:00
1 parent 1e305135e3
commit 76e5280c32
5 files changed
+96 -27

No files matched your search

+2 -2
View File
@@ -321,7 +321,7 @@ fn op_dom_inner(state: &OpState, cmd: String, arg1: String, arg2: String) -> Str
let names: Vec<String> = dom
.with_node(NodeId::new(nid), |n| {
n.attrs()
.map(|a| a.iter().map(|x| x.name.local.as_ref().to_string()).collect())
.map(|a| a.iter().map(|x| x.qualified_name()).collect())
.unwrap_or_default()
})
.unwrap_or_default();
@@ -373,7 +373,7 @@ fn op_dom_inner(state: &OpState, cmd: String, arg1: String, arg2: String) -> Str
let nid = arg1.parse::<u32>().unwrap_or(0);
dom.with_node_mut(NodeId::new(nid), |n| {
if let NodeData::Element { attrs, .. } = &mut n.data {
attrs.retain(|a| a.name.local.as_ref() != arg2.as_str());
attrs.retain(|a| !a.qualified_name_eq(&arg2));
}
});
"true".into()
+34
View File
@@ -1345,6 +1345,40 @@ mod tests {
assert_eq!(v, serde_json::json!("hi"));
}
#[test]
fn namespaced_attribute_keeps_its_qualified_name() {
let mut rt = setup_runtime("<html><body></body></html>");
let v = rt
.evaluate("(function(){var s=document.createElementNS('http://www.w3.org/2000/svg','svg');s.setAttributeNS('http://www.w3.org/1999/xlink','xlink:href','#g');return s.getAttribute('xlink:href')+'|'+s.getAttributeNames()[0]+'|'+s.outerHTML;})()")
.unwrap();
assert_eq!(v, serde_json::json!("#g|xlink:href|<svg xlink:href=\"#g\"></svg>"));
}
#[test]
fn parsed_xlink_attribute_is_available_through_both_apis() {
let mut rt = setup_runtime(
r##"<html><body><svg><use id="u" xlink:href="#icon"></use></svg></body></html>"##,
);
let v = rt
.evaluate("(function(){var u=document.getElementById('u');return u.getAttribute('xlink:href')+'|'+u.getAttributeNS('http://www.w3.org/1999/xlink','href')+'|'+u.getAttributeNames().join(',');})()")
.unwrap();
assert_eq!(v, serde_json::json!("#icon|#icon|id,xlink:href"));
}
#[test]
fn set_attribute_ns_validates_namespace_constraints() {
let mut rt = setup_runtime("<html><body></body></html>");
let v = rt
.evaluate("(function(){var e=document.createElement('div'),out=[];for(const args of [[null,'x:y'],['urn:test','a:b:c'],['urn:test','xml:lang'],['urn:test','xmlns:x']]){try{e.setAttributeNS(args[0],args[1],'v');out.push('none')}catch(err){out.push(err.name)}}return out.join('|');})()")
.unwrap();
assert_eq!(
v,
serde_json::json!(
"NamespaceError|InvalidCharacterError|NamespaceError|NamespaceError"
)
);
}
#[test]
fn test_document_title() {
let mut rt = setup_runtime("<html><head><title>Test</title></head><body></body></html>");