diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2020-01-31 06:14:47 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-31 06:14:47 -0500 |
commit | 393b6768f05741717cfbaf4d077f91a73a6e3c05 (patch) | |
tree | e21f3440ea6318787109e94e73aac1f257401d38 | |
parent | 7ac4f9eec6c5208865c435505437df0f569a278a (diff) | |
parent | 9cc218d0b064cb517d6963bcd3ffa746ba447976 (diff) | |
download | servo-393b6768f05741717cfbaf4d077f91a73a6e3c05.tar.gz servo-393b6768f05741717cfbaf4d077f91a73a6e3c05.zip |
Auto merge of #25636 - pshaughn:submitevent, r=jdm
Implement SubmitEvent
<!-- Please describe your changes on the following line: -->
FormSubmitter was already being passed into submit, so there wasn't much work to do here other than making the new event interface itself.
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #24617
<!-- Either: -->
- [X] There are tests for these changes
<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
18 files changed, 131 insertions, 58 deletions
diff --git a/components/script/dom/htmlbuttonelement.rs b/components/script/dom/htmlbuttonelement.rs index b7c7da1e9bf..49541a2d4a0 100755 --- a/components/script/dom/htmlbuttonelement.rs +++ b/components/script/dom/htmlbuttonelement.rs @@ -307,7 +307,7 @@ impl Activatable for HTMLButtonElement { if let Some(owner) = self.form_owner() { owner.submit( SubmittedFrom::NotFromForm, - FormSubmitter::ButtonElement(self.clone()), + FormSubmitter::ButtonElement(self), ); } }, diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index ebbe1d49615..bf59dc0280b 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -48,6 +48,7 @@ use crate::dom::node::{Node, NodeFlags, ShadowIncluding}; use crate::dom::node::{UnbindContext, VecPreOrderInsertionHelper}; use crate::dom::nodelist::{NodeList, RadioListMode}; use crate::dom::radionodelist::RadioNodeList; +use crate::dom::submitevent::SubmitEvent; use crate::dom::validitystate::ValidationFlags; use crate::dom::virtualmethods::VirtualMethods; use crate::dom::window::Window; @@ -604,10 +605,29 @@ impl HTMLFormElement { } } // Step 7 + // spec calls this "submitterButton" but it doesn't have to be a button, + // just not be the form itself + let submitter_button = match submitter { + FormSubmitter::FormElement(f) => { + if f == self { + None + } else { + Some(f.upcast::<HTMLElement>()) + } + }, + FormSubmitter::InputElement(i) => Some(i.upcast::<HTMLElement>()), + FormSubmitter::ButtonElement(b) => Some(b.upcast::<HTMLElement>()), + }; if submit_method_flag == SubmittedFrom::NotFromForm { - let event = self - .upcast::<EventTarget>() - .fire_bubbling_cancelable_event(atom!("submit")); + let event = SubmitEvent::new( + &self.global(), + atom!("submit"), + true, + true, + submitter_button.map(|s| DomRoot::from_ref(s)), + ); + let event = event.upcast::<Event>(); + event.fire(self.upcast::<EventTarget>()); if event.DefaultPrevented() { return; } diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index a8587b58ed0..88b2e688d65 100755 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -2470,7 +2470,7 @@ impl Activatable for HTMLInputElement { self.form_owner().map(|o| { o.submit( SubmittedFrom::NotFromForm, - FormSubmitter::InputElement(self.clone()), + FormSubmitter::InputElement(self), ) }); }, diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 282d3b66d60..c1a1ab72354 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -484,6 +484,7 @@ pub mod storageevent; pub mod stylepropertymapreadonly; pub mod stylesheet; pub mod stylesheetlist; +pub mod submitevent; pub mod svgelement; pub mod svggraphicselement; pub mod svgsvgelement; diff --git a/components/script/dom/submitevent.rs b/components/script/dom/submitevent.rs new file mode 100644 index 00000000000..17f8e7fd003 --- /dev/null +++ b/components/script/dom/submitevent.rs @@ -0,0 +1,79 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods; +use crate::dom::bindings::codegen::Bindings::SubmitEventBinding; +use crate::dom::bindings::codegen::Bindings::SubmitEventBinding::SubmitEventMethods; +use crate::dom::bindings::inheritance::Castable; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::str::DOMString; +use crate::dom::event::Event; +use crate::dom::globalscope::GlobalScope; +use crate::dom::htmlelement::HTMLElement; +use crate::dom::window::Window; +use dom_struct::dom_struct; +use servo_atoms::Atom; + +#[dom_struct] +#[allow(non_snake_case)] +pub struct SubmitEvent { + event: Event, + submitter: Option<DomRoot<HTMLElement>>, +} + +impl SubmitEvent { + fn new_inherited(submitter: Option<DomRoot<HTMLElement>>) -> SubmitEvent { + SubmitEvent { + event: Event::new_inherited(), + submitter: submitter, + } + } + + pub fn new( + global: &GlobalScope, + type_: Atom, + bubbles: bool, + cancelable: bool, + submitter: Option<DomRoot<HTMLElement>>, + ) -> DomRoot<SubmitEvent> { + let ev = reflect_dom_object( + Box::new(SubmitEvent::new_inherited(submitter)), + global, + SubmitEventBinding::Wrap, + ); + { + let event = ev.upcast::<Event>(); + event.init_event(type_, bubbles, cancelable); + } + ev + } + + #[allow(non_snake_case)] + pub fn Constructor( + window: &Window, + type_: DOMString, + init: &SubmitEventBinding::SubmitEventInit, + ) -> DomRoot<SubmitEvent> { + SubmitEvent::new( + &window.global(), + Atom::from(type_), + init.parent.bubbles, + init.parent.cancelable, + init.submitter.as_ref().map(|s| DomRoot::from_ref(&**s)), + ) + } +} + +impl SubmitEventMethods for SubmitEvent { + /// <https://dom.spec.whatwg.org/#dom-event-istrusted> + fn IsTrusted(&self) -> bool { + self.event.IsTrusted() + } + + /// https://html.spec.whatwg.org/multipage/#dom-submitevent-submitter + fn GetSubmitter(&self) -> Option<DomRoot<HTMLElement>> { + self.submitter.as_ref().map(|s| DomRoot::from_ref(&**s)) + } +} diff --git a/components/script/dom/webidls/SubmitEvent.webidl b/components/script/dom/webidls/SubmitEvent.webidl new file mode 100644 index 00000000000..f5b2c49257d --- /dev/null +++ b/components/script/dom/webidls/SubmitEvent.webidl @@ -0,0 +1,15 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +// https://html.spec.whatwg.org/multipage/#submitevent +[Exposed=Window] +interface SubmitEvent : Event { + constructor(DOMString typeArg, optional SubmitEventInit eventInitDict = {}); + + readonly attribute HTMLElement? submitter; +}; + +dictionary SubmitEventInit : EventInit { + HTMLElement? submitter = null; +}; diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 0556b1d2367..7e27c9e6b25 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -692159,15 +692159,15 @@ "testharness" ], "html/semantics/forms/form-submission-0/form-double-submit-2.html": [ - "f0c9471a704d4c0c0742d7ed8e8f13a789514d69", + "4c715de250e22bf48c225f5337ff38736f3fa80b", "testharness" ], "html/semantics/forms/form-submission-0/form-double-submit-3.html": [ - "1bad23260d054b8f60e255de4d1a074803db4b2f", + "cdb50d226a893de2250a19a93c0b5a0f72bbcfee", "testharness" ], "html/semantics/forms/form-submission-0/form-double-submit.html": [ - "1102e304174eeec18b65b54deec74a328d998be0", + "005f393bfd42fb850a81eb1d87bae048b7cad30b", "testharness" ], "html/semantics/forms/form-submission-0/form-echo.py": [ diff --git a/tests/wpt/metadata/html/dom/idlharness.https.html.ini b/tests/wpt/metadata/html/dom/idlharness.https.html.ini index 2ed0991f98c..7d0fadaea7d 100644 --- a/tests/wpt/metadata/html/dom/idlharness.https.html.ini +++ b/tests/wpt/metadata/html/dom/idlharness.https.html.ini @@ -1376,27 +1376,6 @@ [SVGAElement includes HTMLHyperlinkElementUtils: member names are unique] expected: FAIL - [SubmitEvent interface object name] - expected: FAIL - - [SubmitEvent interface object length] - expected: FAIL - - [SubmitEvent interface: existence and properties of interface prototype object] - expected: FAIL - - [SubmitEvent interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [SubmitEvent interface: attribute submitter] - expected: FAIL - - [SubmitEvent interface: existence and properties of interface object] - expected: FAIL - - [SubmitEvent interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - [SVGElement interface: attribute onwebkitanimationend] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/forms/form-submission-0/SubmitEvent.window.js.ini b/tests/wpt/metadata/html/semantics/forms/form-submission-0/SubmitEvent.window.js.ini deleted file mode 100644 index 74cd4de030f..00000000000 --- a/tests/wpt/metadata/html/semantics/forms/form-submission-0/SubmitEvent.window.js.ini +++ /dev/null @@ -1,22 +0,0 @@ -[SubmitEvent.window.html] - [Successful SubmitEvent constructor] - expected: FAIL - - [Failing SubmitEvent constructor] - expected: FAIL - - [Successful SubmitEvent constructor; empty dictionary] - expected: FAIL - - [Successful SubmitEvent constructor; null submitter] - expected: FAIL - - [Successful SubmitEvent constructor; missing dictionary] - expected: FAIL - - [Successful SubmitEvent constructor; null/undefined submitter] - expected: FAIL - - [Successful SubmitEvent constructor; null/undefined dictionary] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-double-submit-2.html.ini b/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-double-submit-2.html.ini index 61799e4c935..633a99517d3 100644 --- a/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-double-submit-2.html.ini +++ b/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-double-submit-2.html.ini @@ -1,5 +1,4 @@ [form-double-submit-2.html] - expected: ERROR [preventDefault should allow onclick submit() to succeed] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-double-submit-3.html.ini b/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-double-submit-3.html.ini index df89cd21511..9f416703229 100644 --- a/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-double-submit-3.html.ini +++ b/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-double-submit-3.html.ini @@ -1,5 +1,4 @@ [form-double-submit-3.html] - expected: ERROR [<button> should have the same double-submit protection as <input type=submit>] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-double-submit.html.ini b/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-double-submit.html.ini index dce74c6dd71..b193c33c2b6 100644 --- a/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-double-submit.html.ini +++ b/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-double-submit.html.ini @@ -1,5 +1,4 @@ [form-double-submit.html] - expected: ERROR [default submit action should supersede onclick submit()] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-submission-algorithm.html.ini b/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-submission-algorithm.html.ini index 52cb32ee092..f2a5ec38b79 100644 --- a/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-submission-algorithm.html.ini +++ b/tests/wpt/metadata/html/semantics/forms/form-submission-0/form-submission-algorithm.html.ini @@ -5,9 +5,6 @@ [firing an event named submit; form.requestSubmit(submitter)] expected: FAIL - [firing an event named submit; clicking a submit button] - expected: FAIL - [firing an event named submit; form.requestSubmit(null)] expected: FAIL diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index fb721fd2900..145f8189f02 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -19032,7 +19032,7 @@ "testharness" ], "mozilla/interfaces.html": [ - "114ec29df620cc0526d39a41928f72d9359890a9", + "fc82a7e82e936811024cbefadaa9cc396511942b", "testharness" ], "mozilla/interfaces.js": [ diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.html b/tests/wpt/mozilla/tests/mozilla/interfaces.html index 114ec29df62..fc82a7e82e9 100644 --- a/tests/wpt/mozilla/tests/mozilla/interfaces.html +++ b/tests/wpt/mozilla/tests/mozilla/interfaces.html @@ -218,6 +218,7 @@ test_interfaces([ "StorageEvent", "StyleSheet", "StyleSheetList", + "SubmitEvent", "Text", "TextTrack", "TextTrackCue", diff --git a/tests/wpt/web-platform-tests/html/semantics/forms/form-submission-0/form-double-submit-2.html b/tests/wpt/web-platform-tests/html/semantics/forms/form-submission-0/form-double-submit-2.html index f0c9471a704..4c715de250e 100644 --- a/tests/wpt/web-platform-tests/html/semantics/forms/form-submission-0/form-double-submit-2.html +++ b/tests/wpt/web-platform-tests/html/semantics/forms/form-submission-0/form-double-submit-2.html @@ -25,6 +25,8 @@ <script> let frame1 = document.getElementById('frame1'); let frame2 = document.getElementById('frame2'); +let form1 = document.getElementById('form1'); +let submitbutton = document.getElementById('submitbutton'); async_test(t => { window.addEventListener('load', () => { diff --git a/tests/wpt/web-platform-tests/html/semantics/forms/form-submission-0/form-double-submit-3.html b/tests/wpt/web-platform-tests/html/semantics/forms/form-submission-0/form-double-submit-3.html index 1bad23260d0..cdb50d226a8 100644 --- a/tests/wpt/web-platform-tests/html/semantics/forms/form-submission-0/form-double-submit-3.html +++ b/tests/wpt/web-platform-tests/html/semantics/forms/form-submission-0/form-double-submit-3.html @@ -25,6 +25,8 @@ <script> let frame1 = document.getElementById('frame1'); let frame2 = document.getElementById('frame2'); +let form1 = document.getElementById('form1'); +let submitbutton = document.getElementById('submitbutton'); async_test(t => { window.addEventListener('load', () => { diff --git a/tests/wpt/web-platform-tests/html/semantics/forms/form-submission-0/form-double-submit.html b/tests/wpt/web-platform-tests/html/semantics/forms/form-submission-0/form-double-submit.html index 1102e304174..005f393bfd4 100644 --- a/tests/wpt/web-platform-tests/html/semantics/forms/form-submission-0/form-double-submit.html +++ b/tests/wpt/web-platform-tests/html/semantics/forms/form-submission-0/form-double-submit.html @@ -25,6 +25,8 @@ <script> let frame1 = document.getElementById('frame1'); let frame2 = document.getElementById('frame2'); +let form1 = document.getElementById('form1'); +let submitbutton = document.getElementById('submitbutton'); async_test(t => { window.addEventListener('load', () => { |