mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Refactor retrieving element container in webdriver into function (#36467)
Refactor getting an element's container. Previously this is inlined and
only done for `HTMLOptionElement`.
[Try](1439948227
)
Fixes: #24106
Signed-off-by: Kenzie Raditya Tirtarahardja <kenzieradityatirtarahardja.18@gmail.com>
Co-authored-by: Kenzie Raditya Tirtarahardja <kenzieradityatirtarahardja.18@gmail.com>
This commit is contained in:
parent
da4ea0f096
commit
cef7aa58ec
1 changed files with 37 additions and 21 deletions
|
@ -60,6 +60,7 @@ use crate::dom::htmldatalistelement::HTMLDataListElement;
|
|||
use crate::dom::htmlelement::HTMLElement;
|
||||
use crate::dom::htmliframeelement::HTMLIFrameElement;
|
||||
use crate::dom::htmlinputelement::{HTMLInputElement, InputType};
|
||||
use crate::dom::htmloptgroupelement::HTMLOptGroupElement;
|
||||
use crate::dom::htmloptionelement::HTMLOptionElement;
|
||||
use crate::dom::htmlselectelement::HTMLSelectElement;
|
||||
use crate::dom::node::{Node, NodeTraits, ShadowIncluding};
|
||||
|
@ -1191,6 +1192,35 @@ pub(crate) fn handle_get_url(
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
fn get_option_parent(node: &Node) -> Option<DomRoot<Node>> {
|
||||
// Get parent for `<option>` or `<optiongrp>` based on container spec:
|
||||
// > 1. Let datalist parent be the first datalist element reached by traversing the tree
|
||||
// > in reverse order from element, or undefined if the root of the tree is reached.
|
||||
// > 2. Let select parent be the first select element reached by traversing the tree in
|
||||
// > reverse order from element, or undefined if the root of the tree is reached.
|
||||
// > 3. If datalist parent is undefined, the element context is select parent.
|
||||
// > Otherwise, the element context is datalist parent.
|
||||
let root_node = node.GetRootNode(&GetRootNodeOptions::empty());
|
||||
node.preceding_nodes(&root_node)
|
||||
.find(|preceding| preceding.is::<HTMLDataListElement>())
|
||||
.or_else(|| {
|
||||
node.preceding_nodes(&root_node)
|
||||
.find(|preceding| preceding.is::<HTMLSelectElement>())
|
||||
})
|
||||
}
|
||||
|
||||
// https://w3c.github.io/webdriver/#dfn-container
|
||||
fn get_container(node: &Node) -> Option<DomRoot<Node>> {
|
||||
if node.is::<HTMLOptionElement>() {
|
||||
return get_option_parent(node);
|
||||
}
|
||||
if node.is::<HTMLOptGroupElement>() {
|
||||
let option_parent = get_option_parent(node);
|
||||
return option_parent.or_else(|| Some(DomRoot::from_ref(node)));
|
||||
}
|
||||
Some(DomRoot::from_ref(node))
|
||||
}
|
||||
|
||||
// https://w3c.github.io/webdriver/#element-click
|
||||
pub(crate) fn handle_element_click(
|
||||
documents: &DocumentCollection,
|
||||
|
@ -1210,6 +1240,10 @@ pub(crate) fn handle_element_click(
|
|||
}
|
||||
}
|
||||
|
||||
let Some(container) = get_container(&node) else {
|
||||
return Err(ErrorStatus::UnknownError);
|
||||
};
|
||||
|
||||
// Step 5
|
||||
// TODO: scroll into view
|
||||
|
||||
|
@ -1222,32 +1256,14 @@ pub(crate) fn handle_element_click(
|
|||
// Step 8
|
||||
match node.downcast::<HTMLOptionElement>() {
|
||||
Some(option_element) => {
|
||||
// https://w3c.github.io/webdriver/#dfn-container
|
||||
let root_node = node.GetRootNode(&GetRootNodeOptions::empty());
|
||||
let datalist_parent = node
|
||||
.preceding_nodes(&root_node)
|
||||
.find(|preceding| preceding.is::<HTMLDataListElement>());
|
||||
let select_parent = node
|
||||
.preceding_nodes(&root_node)
|
||||
.find(|preceding| preceding.is::<HTMLSelectElement>());
|
||||
|
||||
// Step 8.1
|
||||
let parent_node = match datalist_parent {
|
||||
Some(datalist_parent) => datalist_parent,
|
||||
None => match select_parent {
|
||||
Some(select_parent) => select_parent,
|
||||
None => return Err(ErrorStatus::UnknownError),
|
||||
},
|
||||
};
|
||||
|
||||
// Steps 8.2 - 8.4
|
||||
let event_target = parent_node.upcast::<EventTarget>();
|
||||
let event_target = container.upcast::<EventTarget>();
|
||||
event_target.fire_event(atom!("mouseover"), can_gc);
|
||||
event_target.fire_event(atom!("mousemove"), can_gc);
|
||||
event_target.fire_event(atom!("mousedown"), can_gc);
|
||||
|
||||
// Step 8.5
|
||||
match parent_node.downcast::<HTMLElement>() {
|
||||
match container.downcast::<HTMLElement>() {
|
||||
Some(html_element) => html_element.Focus(can_gc),
|
||||
None => return Err(ErrorStatus::UnknownError),
|
||||
}
|
||||
|
@ -1261,7 +1277,7 @@ pub(crate) fn handle_element_click(
|
|||
let previous_selectedness = option_element.Selected();
|
||||
|
||||
// Step 8.6.3
|
||||
match parent_node.downcast::<HTMLSelectElement>() {
|
||||
match container.downcast::<HTMLSelectElement>() {
|
||||
Some(select_element) => {
|
||||
if select_element.Multiple() {
|
||||
option_element.SetSelected(!option_element.Selected());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue