mirror of
https://github.com/servo/servo
synced 2026-04-25 17:15:48 +02:00
script: Add an initial implementation of the "focus update steps" (#44360)
This moves Servo closer to the focus parts of the HTML specification. The behavior should be the same as before, but now the code in `script` matches the structure of the specification. The main goal is to set us up for: - Firing focus events in the right order on nested documents - A proper implementation of the unfocusing steps. Testing: This should not change behavior so is covered by existing tests. Signed-off-by: Martin Robinson <mrobinson@fastmail.fm> Co-authored-by: Martin Robinson <mrobinson@fastmail.fm>
This commit is contained in:
@@ -128,7 +128,7 @@ use crate::dom::csp::{CspReporting, GlobalCspReporting, Violation};
|
||||
use crate::dom::customelementregistry::{
|
||||
CallbackReaction, CustomElementDefinition, CustomElementReactionStack,
|
||||
};
|
||||
use crate::dom::document::focus::{FocusInitiator, FocusOperation, FocusableArea};
|
||||
use crate::dom::document::focus::FocusableArea;
|
||||
use crate::dom::document::{
|
||||
Document, DocumentSource, HasBrowsingContext, IsHTMLDocument, RenderingUpdateReason,
|
||||
};
|
||||
@@ -2867,21 +2867,28 @@ impl ScriptThread {
|
||||
return;
|
||||
}
|
||||
|
||||
let focusable_area = browsing_context_id
|
||||
.and_then(|browsing_context_id| {
|
||||
document
|
||||
.iframes()
|
||||
.get(browsing_context_id)
|
||||
.map(|iframe| FocusableArea::Node {
|
||||
node: DomRoot::from_ref(iframe.element.upcast()),
|
||||
kind: Default::default(),
|
||||
})
|
||||
// This is separate from the next few lines in order to drop the borrow
|
||||
// on `document.iframes()`.
|
||||
let iframe_element = browsing_context_id.and_then(|browsing_context_id| {
|
||||
document
|
||||
.iframes()
|
||||
.get(browsing_context_id)
|
||||
.map(|iframe| iframe.element.as_rooted())
|
||||
});
|
||||
let focusable_area = iframe_element
|
||||
.map(|iframe_element| {
|
||||
let kind = iframe_element.upcast::<Element>().focusable_area_kind();
|
||||
FocusableArea::IFrameViewport {
|
||||
iframe_element,
|
||||
kind,
|
||||
}
|
||||
})
|
||||
.unwrap_or(FocusableArea::Viewport);
|
||||
|
||||
focus_handler.focus(
|
||||
FocusOperation::Focus(focusable_area),
|
||||
FocusInitiator::Remote,
|
||||
focus_handler.focus_update_steps(
|
||||
focusable_area.focus_chain(),
|
||||
focus_handler.current_focus_chain(),
|
||||
&focusable_area,
|
||||
CanGc::from_cx(cx),
|
||||
);
|
||||
}
|
||||
@@ -2907,7 +2914,8 @@ impl ScriptThread {
|
||||
|
||||
// We ignore unfocus requests for top-level `Document`s as they *always* have focus.
|
||||
// Note that this does not take into account system focus.
|
||||
if document.window().is_top_level() {
|
||||
let window = document.window();
|
||||
if window.is_top_level() {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2921,9 +2929,11 @@ impl ScriptThread {
|
||||
);
|
||||
return;
|
||||
}
|
||||
focus_handler.focus(
|
||||
FocusOperation::Unfocus,
|
||||
FocusInitiator::Remote,
|
||||
|
||||
focus_handler.focus_update_steps(
|
||||
vec![],
|
||||
focus_handler.current_focus_chain(),
|
||||
&FocusableArea::Viewport,
|
||||
CanGc::from_cx(cx),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user