mirror of
https://github.com/lexmount/moli.git
synced 2026-10-05 16:00:54 +00:00
fix(inert): blur focus after dynamic activation
This commit is contained in:
@@ -240,6 +240,21 @@ impl DocumentRuntime {
|
||||
crate::native_bridge::element::handle_popover_attribute_change(
|
||||
scope, host_ptr, handle, namespace, local_name, old_value, new_value,
|
||||
);
|
||||
if namespace.is_none()
|
||||
&& local_name.eq_ignore_ascii_case("inert")
|
||||
&& old_value.is_none()
|
||||
&& new_value.is_some()
|
||||
&& self
|
||||
.dom_host
|
||||
.node(handle)
|
||||
.and_then(Node::as_element)
|
||||
.is_some_and(|element| {
|
||||
element.namespace() == crate::native_bridge::document::XHTML_NS
|
||||
})
|
||||
&& let Some(active) = self.active_element_handle()
|
||||
{
|
||||
crate::native_bridge::element::schedule_focus_blur_if_needed(scope, host_ptr, active);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_text_content(
|
||||
|
||||
@@ -2535,6 +2535,78 @@ async fn focused_display_none_blur_listener_sees_updated_focus_state() {
|
||||
assert_eq!(sync_state, "none|true|true");
|
||||
assert_eq!(blur_state, "block,true,true|block");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn focused_element_blurs_after_it_becomes_inert() {
|
||||
let loader = ResourceRequestClient::new(&moli_fetch::FetchConfig::default()).expect("loader");
|
||||
let mut vm =
|
||||
new_storage_test_vm_with_loader("https://dynamic-inert-focus-fixup.test/", &loader);
|
||||
|
||||
let direct_sync_state = vm
|
||||
.eval(
|
||||
r#"
|
||||
(() => {
|
||||
const html = document.documentElement || document.appendChild(document.createElement('html'));
|
||||
const body = document.body || html.appendChild(document.createElement('body'));
|
||||
const wrapper = document.createElement('div');
|
||||
const input = document.createElement('input');
|
||||
wrapper.appendChild(input);
|
||||
body.appendChild(wrapper);
|
||||
globalThis.__dynamicInertFocus = { wrapper, input, blurCount: 0 };
|
||||
input.addEventListener('blur', () => globalThis.__dynamicInertFocus.blurCount++);
|
||||
input.focus();
|
||||
input.inert = true;
|
||||
return [document.activeElement === input, globalThis.__dynamicInertFocus.blurCount].join('|');
|
||||
})()
|
||||
"#,
|
||||
)
|
||||
.expect("direct inert focus setup should evaluate");
|
||||
|
||||
assert!(
|
||||
vm.run_next_due_timer_callback_for_test(&loader)
|
||||
.await
|
||||
.expect("direct inert focus-fixup timer should run")
|
||||
);
|
||||
let direct_async_state = vm
|
||||
.eval(
|
||||
r#"
|
||||
[document.activeElement === document.body, globalThis.__dynamicInertFocus.blurCount].join('|')
|
||||
"#,
|
||||
)
|
||||
.expect("direct inert focus-fixup result should evaluate");
|
||||
|
||||
let ancestor_sync_state = vm
|
||||
.eval(
|
||||
r#"
|
||||
(() => {
|
||||
const { wrapper, input } = globalThis.__dynamicInertFocus;
|
||||
input.inert = false;
|
||||
input.focus();
|
||||
wrapper.setAttribute('inert', '');
|
||||
return [document.activeElement === input, globalThis.__dynamicInertFocus.blurCount].join('|');
|
||||
})()
|
||||
"#,
|
||||
)
|
||||
.expect("ancestor inert focus setup should evaluate");
|
||||
|
||||
assert!(
|
||||
vm.run_next_due_timer_callback_for_test(&loader)
|
||||
.await
|
||||
.expect("ancestor inert focus-fixup timer should run")
|
||||
);
|
||||
let ancestor_async_state = vm
|
||||
.eval(
|
||||
r#"
|
||||
[document.activeElement === document.body, globalThis.__dynamicInertFocus.blurCount].join('|')
|
||||
"#,
|
||||
)
|
||||
.expect("ancestor inert focus-fixup result should evaluate");
|
||||
|
||||
assert_eq!(direct_sync_state, "true|0");
|
||||
assert_eq!(direct_async_state, "true|1");
|
||||
assert_eq!(ancestor_sync_state, "true|1");
|
||||
assert_eq!(ancestor_async_state, "true|2");
|
||||
}
|
||||
#[test]
|
||||
fn scroll_container_focusability_tracks_current_layout() {
|
||||
let mut vm = new_storage_test_vm("https://scroll-focusability.test/");
|
||||
|
||||
Reference in New Issue
Block a user