mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
fix: allow form submission for input [type=image] (#34203)
* fix: allow form submission for input [type=image] Signed-off-by: Shane Handley <shanehandley@fastmail.com> * Fix comments and use existing can_gc where available Signed-off-by: Shane Handley <shanehandley@fastmail.com> --------- Signed-off-by: Shane Handley <shanehandley@fastmail.com>
This commit is contained in:
parent
3fd1a229df
commit
313597f325
7 changed files with 75 additions and 145 deletions
|
@ -538,7 +538,7 @@ impl HTMLInputElement {
|
||||||
self.default_maximum()
|
self.default_maximum()
|
||||||
}
|
}
|
||||||
|
|
||||||
// when allowed_value_step and minumum both exist, this is the smallest
|
// when allowed_value_step and minimum both exist, this is the smallest
|
||||||
// value >= minimum that lies on an integer step
|
// value >= minimum that lies on an integer step
|
||||||
fn stepped_minimum(&self) -> Option<f64> {
|
fn stepped_minimum(&self) -> Option<f64> {
|
||||||
match (self.minimum(), self.allowed_value_step()) {
|
match (self.minimum(), self.allowed_value_step()) {
|
||||||
|
@ -1130,6 +1130,7 @@ impl TextControlElement for HTMLInputElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
impl HTMLInputElementMethods for HTMLInputElement {
|
impl HTMLInputElementMethods for HTMLInputElement {
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-input-accept
|
// https://html.spec.whatwg.org/multipage/#dom-input-accept
|
||||||
make_getter!(Accept, "accept");
|
make_getter!(Accept, "accept");
|
||||||
|
@ -2719,11 +2720,15 @@ impl Activatable for HTMLInputElement {
|
||||||
|
|
||||||
fn is_instance_activatable(&self) -> bool {
|
fn is_instance_activatable(&self) -> bool {
|
||||||
match self.input_type() {
|
match self.input_type() {
|
||||||
// https://html.spec.whatwg.org/multipage/#submit-button-state-%28type=submit%29:activation-behaviour-2
|
// https://html.spec.whatwg.org/multipage/#submit-button-state-(type=submit):input-activation-behavior
|
||||||
// https://html.spec.whatwg.org/multipage/#reset-button-state-%28type=reset%29:activation-behaviour-2
|
// https://html.spec.whatwg.org/multipage/#reset-button-state-(type=reset):input-activation-behavior
|
||||||
// https://html.spec.whatwg.org/multipage/#checkbox-state-%28type=checkbox%29:activation-behaviour-2
|
// https://html.spec.whatwg.org/multipage/#file-upload-state-(type=file):input-activation-behavior
|
||||||
// https://html.spec.whatwg.org/multipage/#radio-button-state-%28type=radio%29:activation-behaviour-2
|
// https://html.spec.whatwg.org/multipage/#image-button-state-(type=image):input-activation-behavior
|
||||||
InputType::Submit | InputType::Reset | InputType::File => self.is_mutable(),
|
InputType::Submit | InputType::Reset | InputType::File | InputType::Image => {
|
||||||
|
self.is_mutable()
|
||||||
|
},
|
||||||
|
// https://html.spec.whatwg.org/multipage/#checkbox-state-(type=checkbox):input-activation-behavior
|
||||||
|
// https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio):input-activation-behavior
|
||||||
InputType::Checkbox | InputType::Radio => true,
|
InputType::Checkbox | InputType::Radio => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -2812,16 +2817,24 @@ impl Activatable for HTMLInputElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps
|
/// <https://html.spec.whatwg.org/multipage/#input-activation-behavior>
|
||||||
fn activation_behavior(&self, _event: &Event, _target: &EventTarget, can_gc: CanGc) {
|
fn activation_behavior(&self, _event: &Event, _target: &EventTarget, can_gc: CanGc) {
|
||||||
let ty = self.input_type();
|
match self.input_type() {
|
||||||
match ty {
|
|
||||||
InputType::Submit => {
|
|
||||||
// https://html.spec.whatwg.org/multipage/#submit-button-state-(type=submit):activation-behavior
|
// https://html.spec.whatwg.org/multipage/#submit-button-state-(type=submit):activation-behavior
|
||||||
// FIXME (Manishearth): support document owners (needs ability to get parent browsing context)
|
// https://html.spec.whatwg.org/multipage/#submit-button-state-(type=image):activation-behavior
|
||||||
// Check if document owner is fully active
|
InputType::Submit | InputType::Image => {
|
||||||
if let Some(o) = self.form_owner() {
|
// Step 1: If the element does not have a form owner, then return.
|
||||||
o.submit(
|
if let Some(form_owner) = self.form_owner() {
|
||||||
|
// Step 2: If the element's node document is not fully active, then return.
|
||||||
|
let document = document_from_node(self);
|
||||||
|
|
||||||
|
if !document.is_fully_active() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3: Submit the element's form owner from the element with userInvolvement
|
||||||
|
// set to event's user navigation involvement.
|
||||||
|
form_owner.submit(
|
||||||
SubmittedFrom::NotFromForm,
|
SubmittedFrom::NotFromForm,
|
||||||
FormSubmitterElement::Input(self),
|
FormSubmitterElement::Input(self),
|
||||||
CanGc::note(),
|
CanGc::note(),
|
||||||
|
@ -2830,24 +2843,39 @@ impl Activatable for HTMLInputElement {
|
||||||
},
|
},
|
||||||
InputType::Reset => {
|
InputType::Reset => {
|
||||||
// https://html.spec.whatwg.org/multipage/#reset-button-state-(type=reset):activation-behavior
|
// https://html.spec.whatwg.org/multipage/#reset-button-state-(type=reset):activation-behavior
|
||||||
// FIXME (Manishearth): support document owners (needs ability to get parent browsing context)
|
// Step 1: If the element does not have a form owner, then return.
|
||||||
// Check if document owner is fully active
|
if let Some(form_owner) = self.form_owner() {
|
||||||
if let Some(o) = self.form_owner() {
|
let document = document_from_node(self);
|
||||||
o.reset(ResetFrom::NotFromForm, CanGc::note())
|
|
||||||
|
// Step 2: If the element's node document is not fully active, then return.
|
||||||
|
if !document.is_fully_active() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3: Reset the form owner from the element.
|
||||||
|
form_owner.reset(ResetFrom::NotFromForm, can_gc);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InputType::Checkbox | InputType::Radio => {
|
|
||||||
// https://html.spec.whatwg.org/multipage/#checkbox-state-(type=checkbox):activation-behavior
|
// https://html.spec.whatwg.org/multipage/#checkbox-state-(type=checkbox):activation-behavior
|
||||||
// https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio):activation-behavior
|
// https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio):activation-behavior
|
||||||
// Check if document owner is fully active
|
InputType::Checkbox | InputType::Radio => {
|
||||||
|
// Step 1: If the element is not connected, then return.
|
||||||
if !self.upcast::<Node>().is_connected() {
|
if !self.upcast::<Node>().is_connected() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let target = self.upcast::<EventTarget>();
|
let target = self.upcast::<EventTarget>();
|
||||||
|
|
||||||
|
// Step 2: Fire an event named input at the element with the bubbles and composed
|
||||||
|
// attributes initialized to true.
|
||||||
target.fire_bubbling_event(atom!("input"), can_gc);
|
target.fire_bubbling_event(atom!("input"), can_gc);
|
||||||
|
|
||||||
|
// Step 3: Fire an event named change at the element with the bubbles attribute
|
||||||
|
// initialized to true.
|
||||||
target.fire_bubbling_event(atom!("change"), can_gc);
|
target.fire_bubbling_event(atom!("change"), can_gc);
|
||||||
},
|
},
|
||||||
InputType::File => self.select_files(None, CanGc::note()),
|
// https://html.spec.whatwg.org/multipage/#file-upload-state-(type=file):input-activation-behavior
|
||||||
|
InputType::File => self.select_files(None, can_gc),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,39 +5,12 @@
|
||||||
[When clicking child <FORM><INPUT type=submit></INPUT></FORM> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.]
|
[When clicking child <FORM><INPUT type=submit></INPUT></FORM> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <INPUT type=checkbox></INPUT>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <INPUT type=radio></INPUT>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.]
|
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.]
|
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <A></A>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <AREA></AREA>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <DETAILS><SUMMARY></SUMMARY></DETAILS>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <LABEL><BUTTON type=button></BUTTON></LABEL>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=reset></INPUT></FORM> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.]
|
[When clicking child <FORM><INPUT type=reset></INPUT></FORM> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,3 @@
|
||||||
|
|
||||||
[Files in a text/plain form show up as File objects in the "formData" IDL attribute]
|
[Files in a text/plain form show up as File objects in the "formData" IDL attribute]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[The constructed FormData object should not contain an entry for the image submit button that was used to submit the form.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
[form-submission-algorithm.html]
|
|
||||||
expected: TIMEOUT
|
|
||||||
[Submission URL should always have a non-null query part]
|
|
||||||
expected: NOTRUN
|
|
||||||
|
|
||||||
[firing an event named submit; clicking an image button]
|
|
||||||
expected: TIMEOUT
|
|
||||||
|
|
||||||
[firing an event named submit; form.requestSubmit()]
|
|
||||||
expected: NOTRUN
|
|
||||||
|
|
||||||
[firing an event named submit; form.requestSubmit(null)]
|
|
||||||
expected: NOTRUN
|
|
||||||
|
|
||||||
[firing an event named submit; form.requestSubmit(submitter)]
|
|
||||||
expected: NOTRUN
|
|
||||||
|
|
||||||
[Cannot navigate (after constructing the entry list)]
|
|
||||||
expected: NOTRUN
|
|
|
@ -5,39 +5,12 @@
|
||||||
[When clicking child <FORM><INPUT type=submit></INPUT></FORM> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.]
|
[When clicking child <FORM><INPUT type=submit></INPUT></FORM> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <INPUT type=checkbox></INPUT>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <INPUT type=radio></INPUT>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.]
|
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.]
|
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <A></A>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <AREA></AREA>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <DETAILS><SUMMARY></SUMMARY></DETAILS>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <LABEL><BUTTON type=button></BUTTON></LABEL>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <FORM><INPUT type=reset></INPUT></FORM> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.]
|
[When clicking child <FORM><INPUT type=reset></INPUT></FORM> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -50,30 +23,6 @@
|
||||||
[When clicking child <FORM><BUTTON type=reset></BUTTON></FORM> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.]
|
[When clicking child <FORM><BUTTON type=reset></BUTTON></FORM> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[When clicking child <A></A> of parent <INPUT type=checkbox></INPUT>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <A></A> of parent <INPUT type=radio></INPUT>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <A></A> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <A></A> of parent <FORM><INPUT type=image></INPUT></FORM>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <A></A> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <A></A> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <A></A> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <A></A> of parent <AREA></AREA>, only child should be activated.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[When clicking child <A></A> of parent <DETAILS><SUMMARY></SUMMARY></DETAILS>, only child should be activated.]
|
[When clicking child <A></A> of parent <DETAILS><SUMMARY></SUMMARY></DETAILS>, only child should be activated.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -115,3 +64,27 @@
|
||||||
|
|
||||||
[When clicking child <AREA></AREA> of parent <LABEL><BUTTON type=button></BUTTON></LABEL>, only child should be activated.]
|
[When clicking child <AREA></AREA> of parent <LABEL><BUTTON type=button></BUTTON></LABEL>, only child should be activated.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[When clicking child <A></A> of parent <INPUT type=checkbox></INPUT>, only child should be activated.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[When clicking child <A></A> of parent <INPUT type=radio></INPUT>, only child should be activated.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[When clicking child <A></A> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[When clicking child <A></A> of parent <FORM><INPUT type=image></INPUT></FORM>, only child should be activated.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[When clicking child <A></A> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[When clicking child <A></A> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[When clicking child <A></A> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[When clicking child <A></A> of parent <AREA></AREA>, only child should be activated.]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -10,6 +10,3 @@
|
||||||
|
|
||||||
[Files in a text/plain form show up as File objects in the "formData" IDL attribute]
|
[Files in a text/plain form show up as File objects in the "formData" IDL attribute]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[The constructed FormData object should not contain an entry for the image submit button that was used to submit the form.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
[form-submission-algorithm.html]
|
|
||||||
expected: TIMEOUT
|
|
||||||
[Submission URL should always have a non-null query part]
|
|
||||||
expected: NOTRUN
|
|
||||||
|
|
||||||
[firing an event named submit; clicking an image button]
|
|
||||||
expected: TIMEOUT
|
|
||||||
|
|
||||||
[firing an event named submit; form.requestSubmit()]
|
|
||||||
expected: NOTRUN
|
|
||||||
|
|
||||||
[firing an event named submit; form.requestSubmit(null)]
|
|
||||||
expected: NOTRUN
|
|
||||||
|
|
||||||
[firing an event named submit; form.requestSubmit(submitter)]
|
|
||||||
expected: NOTRUN
|
|
||||||
|
|
||||||
[Cannot navigate (after constructing the entry list)]
|
|
||||||
expected: NOTRUN
|
|
Loading…
Add table
Add a link
Reference in a new issue