mirror of
https://github.com/servo/servo
synced 2026-04-30 11:27:28 +02:00
script: Reset form controls immediately after parsing them (#41962)
This change brings Servo closer to the specification by removing the unspecified sanitization flags used during parsing of input elements. Instead we implement the lines of the specification that say to reset resettable elements after parsing them. This forces a re-sanitization of the default value (from the `value` attribute), clearing up the confusion in parser comments. In addition, specification text is added in the element creation code. Testing: This just brings our code closer to the specification, so it is covered by existing tests. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
@@ -1355,44 +1355,7 @@ impl HTMLFormElement {
|
||||
.collect();
|
||||
|
||||
for child in controls {
|
||||
let child = child.upcast::<Node>();
|
||||
|
||||
match child.type_id() {
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(
|
||||
HTMLElementTypeId::HTMLInputElement,
|
||||
)) => {
|
||||
child.downcast::<HTMLInputElement>().unwrap().reset(can_gc);
|
||||
},
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(
|
||||
HTMLElementTypeId::HTMLSelectElement,
|
||||
)) => {
|
||||
child.downcast::<HTMLSelectElement>().unwrap().reset();
|
||||
},
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(
|
||||
HTMLElementTypeId::HTMLTextAreaElement,
|
||||
)) => {
|
||||
child
|
||||
.downcast::<HTMLTextAreaElement>()
|
||||
.unwrap()
|
||||
.reset(can_gc);
|
||||
},
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(
|
||||
HTMLElementTypeId::HTMLOutputElement,
|
||||
)) => {
|
||||
child.downcast::<HTMLOutputElement>().unwrap().reset(can_gc);
|
||||
},
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLElement)) => {
|
||||
let html_element = child.downcast::<HTMLElement>().unwrap();
|
||||
if html_element.is_form_associated_custom_element() {
|
||||
ScriptThread::enqueue_callback_reaction(
|
||||
html_element.upcast::<Element>(),
|
||||
CallbackReaction::FormReset,
|
||||
None,
|
||||
)
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
child.reset(can_gc);
|
||||
}
|
||||
self.marked_for_reset.set(false);
|
||||
}
|
||||
@@ -1427,6 +1390,48 @@ impl HTMLFormElement {
|
||||
}
|
||||
}
|
||||
|
||||
impl Element {
|
||||
pub(crate) fn is_resettable(&self) -> bool {
|
||||
let NodeTypeId::Element(ElementTypeId::HTMLElement(element_type)) =
|
||||
self.upcast::<Node>().type_id()
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
matches!(
|
||||
element_type,
|
||||
HTMLElementTypeId::HTMLInputElement |
|
||||
HTMLElementTypeId::HTMLSelectElement |
|
||||
HTMLElementTypeId::HTMLTextAreaElement |
|
||||
HTMLElementTypeId::HTMLOutputElement |
|
||||
HTMLElementTypeId::HTMLElement
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn reset(&self, can_gc: CanGc) {
|
||||
if !self.is_resettable() {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(input_element) = self.downcast::<HTMLInputElement>() {
|
||||
input_element.reset(can_gc);
|
||||
} else if let Some(select_element) = self.downcast::<HTMLSelectElement>() {
|
||||
select_element.reset();
|
||||
} else if let Some(textarea_element) = self.downcast::<HTMLTextAreaElement>() {
|
||||
textarea_element.reset(can_gc);
|
||||
} else if let Some(output_element) = self.downcast::<HTMLOutputElement>() {
|
||||
output_element.reset(can_gc);
|
||||
} else if let Some(html_element) = self.downcast::<HTMLElement>() {
|
||||
if html_element.is_form_associated_custom_element() {
|
||||
ScriptThread::enqueue_callback_reaction(
|
||||
html_element.upcast::<Element>(),
|
||||
CallbackReaction::FormReset,
|
||||
None,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, JSTraceable, MallocSizeOf)]
|
||||
pub(crate) enum FormDatumValue {
|
||||
File(DomRoot<File>),
|
||||
|
||||
Reference in New Issue
Block a user