fix(dom): synchronize element reflection targets

This commit is contained in:
ldm0
2026-10-02 03:27:48 +08:00
parent 938bcddd17
commit 63c49d320c
3 changed files with 43 additions and 15 deletions
+3
View File
@@ -73,6 +73,9 @@ fn is_element_reference_attribute(name: &str) -> bool {
| "aria-flowto"
| "aria-labelledby"
| "aria-owns"
| "commandfor"
| "interestfor"
| "popovertarget"
)
}
+2 -8
View File
@@ -211,10 +211,7 @@ fn aria_element_reference_state_is_owned_by_the_content_attribute() {
None,
String::new(),
));
assert_eq!(
element.explicit_element_references("aria-controls"),
None
);
assert_eq!(element.explicit_element_references("aria-controls"), None);
element.set_explicit_element_references("aria-controls", vec![NativeNodeId::new(8)]);
assert!(element.set_attribute_ns(
@@ -229,10 +226,7 @@ fn aria_element_reference_state_is_owned_by_the_content_attribute() {
);
assert!(element.remove_attribute("aria-controls"));
assert_eq!(
element.explicit_element_references("aria-controls"),
None
);
assert_eq!(element.explicit_element_references("aria-controls"), None);
}
#[test]
+38 -7
View File
@@ -1851,7 +1851,7 @@ fn aria_element_reference_handle_for_owner(
.or_else(|| (reference.runtime_ptr == owner_runtime_ptr).then_some(reference.handle))
}
fn aria_element_reference_is_in_valid_scope(
fn element_reference_is_in_valid_scope(
runtime: &JsContextHost,
owner: DomHandle,
candidate: DomHandle,
@@ -1882,7 +1882,7 @@ fn aria_element_reference_is_in_valid_scope(
}
}
fn aria_element_by_id_including_disconnected(
fn element_by_id_including_disconnected(
runtime: &JsContextHost,
owner: DomHandle,
id: &str,
@@ -1906,6 +1906,39 @@ fn aria_element_by_id_including_disconnected(
None
}
pub(in crate::native_bridge::element) fn reflected_element_attribute_handle(
runtime: &JsContextHost,
owner: DomHandle,
attribute: &str,
) -> Option<DomHandle> {
let candidate = match runtime
.dom_host()
.explicit_element_references(owner, attribute)
{
Some(references) => references.into_iter().next()?,
None => {
let id = runtime.dom_host().get_attribute(owner, attribute)?;
element_by_id_including_disconnected(runtime, owner, &id)?
}
};
if !element_reference_is_in_valid_scope(runtime, owner, candidate) {
return None;
}
runtime
.dom_host()
.resolve_reference_target_chain(candidate)
.map(|_| candidate)
}
pub(in crate::native_bridge::element) fn resolved_reflected_element_attribute_handle(
runtime: &JsContextHost,
owner: DomHandle,
attribute: &str,
) -> Option<DomHandle> {
reflected_element_attribute_handle(runtime, owner, attribute)
.and_then(|candidate| runtime.dom_host().resolve_reference_target_chain(candidate))
}
fn aria_element_reference_content_handles(
runtime: &JsContextHost,
owner: DomHandle,
@@ -1914,7 +1947,7 @@ fn aria_element_reference_content_handles(
let value = runtime.dom_host().get_attribute(owner, attribute)?;
if aria_element_reference_is_singular(attribute) {
return Some(
aria_element_by_id_including_disconnected(runtime, owner, &value)
element_by_id_including_disconnected(runtime, owner, &value)
.into_iter()
.collect(),
);
@@ -1923,7 +1956,7 @@ fn aria_element_reference_content_handles(
value
.split([' ', '\t', '\n', '\r', '\u{000c}'])
.filter(|token| !token.is_empty())
.filter_map(|token| aria_element_by_id_including_disconnected(runtime, owner, token))
.filter_map(|token| element_by_id_including_disconnected(runtime, owner, token))
.collect(),
)
}
@@ -1940,9 +1973,7 @@ fn aria_element_reference_handles(
Some(references) => Some(
references
.into_iter()
.filter(|candidate| {
aria_element_reference_is_in_valid_scope(runtime, owner, *candidate)
})
.filter(|candidate| element_reference_is_in_valid_scope(runtime, owner, *candidate))
.collect(),
),
None => aria_element_reference_content_handles(runtime, owner, attribute),