From 313597f325a48243300c73bf786d1c2421825ca4 Mon Sep 17 00:00:00 2001 From: shanehandley <1322294+shanehandley@users.noreply.github.com> Date: Fri, 15 Nov 2024 01:28:48 +1100 Subject: [PATCH] fix: allow form submission for input [type=image] (#34203) * fix: allow form submission for input [type=image] Signed-off-by: Shane Handley * Fix comments and use existing can_gc where available Signed-off-by: Shane Handley --------- Signed-off-by: Shane Handley --- components/script/dom/htmlinputelement.rs | 74 ++++++++++++------ ...spatch-single-activation-behavior.html.ini | 27 ------- .../constructing-form-data-set.html.ini | 3 - .../form-submission-algorithm.html.ini | 19 ----- ...spatch-single-activation-behavior.html.ini | 75 ++++++------------- .../constructing-form-data-set.html.ini | 3 - .../form-submission-algorithm.html.ini | 19 ----- 7 files changed, 75 insertions(+), 145 deletions(-) delete mode 100644 tests/wpt/meta-legacy-layout/html/semantics/forms/form-submission-0/form-submission-algorithm.html.ini delete mode 100644 tests/wpt/meta/html/semantics/forms/form-submission-0/form-submission-algorithm.html.ini diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 16537b2478e..08aacca46e1 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -538,7 +538,7 @@ impl HTMLInputElement { 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 fn stepped_minimum(&self) -> Option { match (self.minimum(), self.allowed_value_step()) { @@ -1130,6 +1130,7 @@ impl TextControlElement for HTMLInputElement { } } +#[allow(non_snake_case)] impl HTMLInputElementMethods for HTMLInputElement { // https://html.spec.whatwg.org/multipage/#dom-input-accept make_getter!(Accept, "accept"); @@ -2719,11 +2720,15 @@ impl Activatable for HTMLInputElement { fn is_instance_activatable(&self) -> bool { 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/#reset-button-state-%28type=reset%29:activation-behaviour-2 - // https://html.spec.whatwg.org/multipage/#checkbox-state-%28type=checkbox%29:activation-behaviour-2 - // https://html.spec.whatwg.org/multipage/#radio-button-state-%28type=radio%29:activation-behaviour-2 - InputType::Submit | InputType::Reset | InputType::File => self.is_mutable(), + // https://html.spec.whatwg.org/multipage/#submit-button-state-(type=submit):input-activation-behavior + // https://html.spec.whatwg.org/multipage/#reset-button-state-(type=reset):input-activation-behavior + // https://html.spec.whatwg.org/multipage/#file-upload-state-(type=file):input-activation-behavior + // https://html.spec.whatwg.org/multipage/#image-button-state-(type=image):input-activation-behavior + 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, _ => false, } @@ -2812,16 +2817,24 @@ impl Activatable for HTMLInputElement { } } - // https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps + /// fn activation_behavior(&self, _event: &Event, _target: &EventTarget, can_gc: CanGc) { - let ty = self.input_type(); - match ty { - InputType::Submit => { - // 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) - // Check if document owner is fully active - if let Some(o) = self.form_owner() { - o.submit( + match self.input_type() { + // https://html.spec.whatwg.org/multipage/#submit-button-state-(type=submit):activation-behavior + // https://html.spec.whatwg.org/multipage/#submit-button-state-(type=image):activation-behavior + InputType::Submit | InputType::Image => { + // Step 1: If the element does not have a form owner, then return. + 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, FormSubmitterElement::Input(self), CanGc::note(), @@ -2830,24 +2843,39 @@ impl Activatable for HTMLInputElement { }, InputType::Reset => { // 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) - // Check if document owner is fully active - if let Some(o) = self.form_owner() { - o.reset(ResetFrom::NotFromForm, CanGc::note()) + // Step 1: If the element does not have a form owner, then return. + if let Some(form_owner) = self.form_owner() { + let document = document_from_node(self); + + // 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); } }, + // 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 InputType::Checkbox | InputType::Radio => { - // 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 - // Check if document owner is fully active + // Step 1: If the element is not connected, then return. if !self.upcast::().is_connected() { return; } + let target = self.upcast::(); + + // 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); + + // 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); }, - 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), _ => (), } } diff --git a/tests/wpt/meta-legacy-layout/dom/events/Event-dispatch-single-activation-behavior.html.ini b/tests/wpt/meta-legacy-layout/dom/events/Event-dispatch-single-activation-behavior.html.ini index a464f5a1f72..034464f9fb8 100644 --- a/tests/wpt/meta-legacy-layout/dom/events/Event-dispatch-single-activation-behavior.html.ini +++ b/tests/wpt/meta-legacy-layout/dom/events/Event-dispatch-single-activation-behavior.html.ini @@ -5,39 +5,12 @@ [When clicking child
of parent
, only child should be activated.] expected: FAIL - [When clicking child
of parent , only child should be activated.] - expected: FAIL - - [When clicking child
of parent , only child should be activated.] - expected: FAIL - [When clicking child
of parent
, only child should be activated.] expected: FAIL - [When clicking child
of parent
, only child should be activated.] - expected: FAIL - [When clicking child
of parent
, only child should be activated.] expected: FAIL - [When clicking child
of parent
, only child should be activated.] - expected: FAIL - - [When clicking child
of parent , only child should be activated.] - expected: FAIL - - [When clicking child
of parent , only child should be activated.] - expected: FAIL - - [When clicking child
of parent
, only child should be activated.] - expected: FAIL - - [When clicking child
of parent , only child should be activated.] - expected: FAIL - - [When clicking child
of parent , only child should be activated.] - expected: FAIL - [When clicking child
of parent
, only child should be activated.] expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/semantics/forms/form-submission-0/constructing-form-data-set.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/forms/form-submission-0/constructing-form-data-set.html.ini index 25a183e59ca..678efa224a3 100644 --- a/tests/wpt/meta-legacy-layout/html/semantics/forms/form-submission-0/constructing-form-data-set.html.ini +++ b/tests/wpt/meta-legacy-layout/html/semantics/forms/form-submission-0/constructing-form-data-set.html.ini @@ -10,6 +10,3 @@ [Files in a text/plain form show up as File objects in the "formData" IDL attribute] 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 diff --git a/tests/wpt/meta-legacy-layout/html/semantics/forms/form-submission-0/form-submission-algorithm.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/forms/form-submission-0/form-submission-algorithm.html.ini deleted file mode 100644 index 93cbeba5a54..00000000000 --- a/tests/wpt/meta-legacy-layout/html/semantics/forms/form-submission-0/form-submission-algorithm.html.ini +++ /dev/null @@ -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 diff --git a/tests/wpt/meta/dom/events/Event-dispatch-single-activation-behavior.html.ini b/tests/wpt/meta/dom/events/Event-dispatch-single-activation-behavior.html.ini index a464f5a1f72..1bce1dc04b7 100644 --- a/tests/wpt/meta/dom/events/Event-dispatch-single-activation-behavior.html.ini +++ b/tests/wpt/meta/dom/events/Event-dispatch-single-activation-behavior.html.ini @@ -5,39 +5,12 @@ [When clicking child
of parent
, only child should be activated.] expected: FAIL - [When clicking child
of parent , only child should be activated.] - expected: FAIL - - [When clicking child
of parent , only child should be activated.] - expected: FAIL - [When clicking child
of parent
, only child should be activated.] expected: FAIL - [When clicking child
of parent
, only child should be activated.] - expected: FAIL - [When clicking child
of parent
, only child should be activated.] expected: FAIL - [When clicking child
of parent
, only child should be activated.] - expected: FAIL - - [When clicking child
of parent , only child should be activated.] - expected: FAIL - - [When clicking child
of parent , only child should be activated.] - expected: FAIL - - [When clicking child
of parent
, only child should be activated.] - expected: FAIL - - [When clicking child
of parent , only child should be activated.] - expected: FAIL - - [When clicking child
of parent , only child should be activated.] - expected: FAIL - [When clicking child
of parent
, only child should be activated.] expected: FAIL @@ -50,30 +23,6 @@ [When clicking child
of parent
, only child should be activated.] expected: FAIL - [When clicking child of parent , only child should be activated.] - expected: FAIL - - [When clicking child of parent , only child should be activated.] - expected: FAIL - - [When clicking child of parent
, only child should be activated.] - expected: FAIL - - [When clicking child of parent
, only child should be activated.] - expected: FAIL - - [When clicking child of parent
, only child should be activated.] - expected: FAIL - - [When clicking child of parent
, only child should be activated.] - expected: FAIL - - [When clicking child of parent
, only child should be activated.] - expected: FAIL - - [When clicking child of parent , only child should be activated.] - expected: FAIL - [When clicking child of parent
, only child should be activated.] expected: FAIL @@ -115,3 +64,27 @@ [When clicking child of parent , only child should be activated.] expected: FAIL + + [When clicking child of parent , only child should be activated.] + expected: FAIL + + [When clicking child of parent , only child should be activated.] + expected: FAIL + + [When clicking child of parent
, only child should be activated.] + expected: FAIL + + [When clicking child of parent
, only child should be activated.] + expected: FAIL + + [When clicking child of parent
, only child should be activated.] + expected: FAIL + + [When clicking child of parent
, only child should be activated.] + expected: FAIL + + [When clicking child of parent
, only child should be activated.] + expected: FAIL + + [When clicking child of parent , only child should be activated.] + expected: FAIL diff --git a/tests/wpt/meta/html/semantics/forms/form-submission-0/constructing-form-data-set.html.ini b/tests/wpt/meta/html/semantics/forms/form-submission-0/constructing-form-data-set.html.ini index 25a183e59ca..678efa224a3 100644 --- a/tests/wpt/meta/html/semantics/forms/form-submission-0/constructing-form-data-set.html.ini +++ b/tests/wpt/meta/html/semantics/forms/form-submission-0/constructing-form-data-set.html.ini @@ -10,6 +10,3 @@ [Files in a text/plain form show up as File objects in the "formData" IDL attribute] 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 diff --git a/tests/wpt/meta/html/semantics/forms/form-submission-0/form-submission-algorithm.html.ini b/tests/wpt/meta/html/semantics/forms/form-submission-0/form-submission-algorithm.html.ini deleted file mode 100644 index 93cbeba5a54..00000000000 --- a/tests/wpt/meta/html/semantics/forms/form-submission-0/form-submission-algorithm.html.ini +++ /dev/null @@ -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