mirror of
https://github.com/lexmount/moli.git
synced 2026-10-03 00:00:44 +00:00
fix(forms): avoid quadratic selectedcontent synchronization
This commit is contained in:
@@ -189,7 +189,20 @@ impl DomHost {
|
||||
}
|
||||
|
||||
pub fn select_selectedcontent_elements(&self, handle: DomHandle) -> Vec<DomHandle> {
|
||||
self.dom.select_selectedcontent_elements(handle)
|
||||
if !self.is_html_element_named(handle, "select") {
|
||||
return Vec::new();
|
||||
}
|
||||
self.elements_by_tag_name_ns(
|
||||
handle,
|
||||
Some("http://www.w3.org/1999/xhtml"),
|
||||
"selectedcontent",
|
||||
false,
|
||||
)
|
||||
.into_iter()
|
||||
.filter(|selectedcontent| {
|
||||
self.selectedcontent_nearest_ancestor_select(*selectedcontent) == Some(handle)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn option_is_disabled(&self, handle: DomHandle) -> bool {
|
||||
|
||||
@@ -1742,9 +1742,11 @@ mod tests {
|
||||
let body = host.document_body_handle().unwrap();
|
||||
|
||||
let select = host.create_element("select");
|
||||
assert!(host.append_child(body, select));
|
||||
assert!(host.select_selectedcontent_elements(select).is_empty());
|
||||
|
||||
let button = host.create_element("button");
|
||||
let selectedcontent = host.create_element("selectedcontent");
|
||||
assert!(host.append_child(body, select));
|
||||
assert!(host.append_child(select, button));
|
||||
assert!(host.append_child(button, selectedcontent));
|
||||
assert_eq!(
|
||||
@@ -1776,6 +1778,44 @@ mod tests {
|
||||
host.select_selectedcontent_elements(select),
|
||||
vec![selectedcontent]
|
||||
);
|
||||
|
||||
assert!(host.remove_child(button, selectedcontent));
|
||||
assert!(host.select_selectedcontent_elements(select).is_empty());
|
||||
assert!(host.append_child(button, selectedcontent));
|
||||
assert_eq!(
|
||||
host.select_selectedcontent_elements(select),
|
||||
vec![selectedcontent]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn selectedcontent_query_index_preserves_detached_subtree_order_and_namespace() {
|
||||
let mut host = DomHost::from_dom(NativeDom::new_html(test_url()));
|
||||
let select = host.create_element("select");
|
||||
assert!(host.select_selectedcontent_elements(select).is_empty());
|
||||
|
||||
let first_button = host.create_element("button");
|
||||
let first = host.create_element("selectedcontent");
|
||||
let second_button = host.create_element("button");
|
||||
let second = host.create_element("selectedcontent");
|
||||
let foreign = host
|
||||
.create_element_ns(Some("urn:selectedcontent-test"), "selectedcontent")
|
||||
.expect("foreign selectedcontent element");
|
||||
assert!(host.append_child(select, first_button));
|
||||
assert!(host.append_child(first_button, first));
|
||||
assert!(host.append_child(select, second_button));
|
||||
assert!(host.append_child(second_button, second));
|
||||
assert!(host.append_child(select, foreign));
|
||||
|
||||
assert_eq!(
|
||||
host.select_selectedcontent_elements(select),
|
||||
vec![first, second]
|
||||
);
|
||||
assert!(host.insert_before(select, second_button, Some(first_button)));
|
||||
assert_eq!(
|
||||
host.select_selectedcontent_elements(select),
|
||||
vec![second, first]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -260,6 +260,13 @@ impl DocumentRuntime {
|
||||
let Some(select) = self.dom_host.option_nearest_ancestor_select(option) else {
|
||||
return false;
|
||||
};
|
||||
if self
|
||||
.dom_host
|
||||
.select_selectedcontent_elements(select)
|
||||
.is_empty()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if self
|
||||
.dom_host
|
||||
.select_selected_option_elements(select)
|
||||
@@ -406,12 +413,15 @@ impl DocumentRuntime {
|
||||
return false;
|
||||
}
|
||||
|
||||
let targets = self.dom_host.select_selectedcontent_elements(select);
|
||||
if targets.is_empty() {
|
||||
return false;
|
||||
}
|
||||
let selected_option = self
|
||||
.dom_host
|
||||
.select_selected_option_elements(select)
|
||||
.first()
|
||||
.copied();
|
||||
let targets = self.dom_host.select_selectedcontent_elements(select);
|
||||
let mut changed = false;
|
||||
for target in targets {
|
||||
changed |= self.clone_selected_option_contents_into_selectedcontent(
|
||||
|
||||
Reference in New Issue
Block a user