Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor submission #24489

Merged
merged 1 commit into from Oct 23, 2019
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

[WIP] solve #22782

TODO: write tests for my change
  • Loading branch information
garasubo committed Oct 18, 2019
commit 7ce40080bf8a956a60a0a2a6d4258ed959ebceab
@@ -30,9 +30,6 @@ pub trait Activatable {
// https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps
fn activation_behavior(&self, event: &Event, target: &EventTarget);

// https://html.spec.whatwg.org/multipage/#implicit-submission
fn implicit_submission(&self, ctrl_key: bool, shift_key: bool, alt_key: bool, meta_key: bool);

// https://html.spec.whatwg.org/multipage/#concept-selector-active
fn enter_formal_activation_state(&self) {
self.as_element().set_active_state(true);
@@ -121,7 +121,7 @@ use html5ever::{LocalName, Namespace, QualName};
use hyper_serde::Serde;
use ipc_channel::ipc::{self, IpcSender};
use js::jsapi::{JSObject, JSRuntime};
use keyboard_types::{Key, KeyState, Modifiers};
use keyboard_types::{Code, Key, KeyState};
use metrics::{
InteractiveFlag, InteractiveMetrics, InteractiveWindow, ProfilerMetadataFactory,
ProgressiveWebMetric,
@@ -1469,35 +1469,20 @@ impl Document {
// however *when* we do it is up to us.
// Here, we're dispatching it after the key event so the script has a chance to cancel it
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=27337
match keyboard_event.key {
Key::Character(ref letter)
if letter == " " && keyboard_event.state == KeyState::Up =>
{
let maybe_elem = target.downcast::<Element>();
if let Some(el) = maybe_elem {
synthetic_click_activation(
el,
false,
false,
false,
false,
ActivationSource::NotFromClick,
)
}
if (keyboard_event.key == Key::Enter && keyboard_event.state == KeyState::Up) ||
(keyboard_event.code == Code::Space && keyboard_event.state == KeyState::Down)

This comment has been minimized.

@nox

nox Oct 21, 2019

Member

In the code before your change, it was KeyState::Up for both spaces and enters, is it intended that you now check for KeyState::Down for spaces?

This comment has been minimized.

@garasubo

garasubo Oct 22, 2019

Author Contributor

Oh, no. It's not intended. Fixed.

{
let maybe_elem = target.downcast::<Element>();
if let Some(el) = maybe_elem {
synthetic_click_activation(
el,
false,
false,
false,
false,
ActivationSource::NotFromClick,
)
}
Key::Enter if keyboard_event.state == KeyState::Up => {
let maybe_elem = target.downcast::<Element>();
if let Some(el) = maybe_elem {
if let Some(a) = el.as_maybe_activatable() {
let ctrl = keyboard_event.modifiers.contains(Modifiers::CONTROL);
let alt = keyboard_event.modifiers.contains(Modifiers::ALT);
let shift = keyboard_event.modifiers.contains(Modifiers::SHIFT);
let meta = keyboard_event.modifiers.contains(Modifiers::META);
a.implicit_submission(ctrl, alt, shift, meta);
}
}
},
_ => (),
}
}

@@ -578,16 +578,6 @@ impl Activatable for HTMLAnchorElement {
//TODO: Download the link is `download` attribute is set.
follow_hyperlink(element, ismap_suffix);
}

//TODO:https://html.spec.whatwg.org/multipage/#the-a-element
fn implicit_submission(
&self,
_ctrl_key: bool,
_shift_key: bool,
_alt_key: bool,
_meta_key: bool,
) {
}
}

/// <https://html.spec.whatwg.org/multipage/#following-hyperlinks-2>
@@ -326,15 +326,6 @@ impl Activatable for HTMLAreaElement {

fn canceled_activation(&self) {}

fn implicit_submission(
&self,
_ctrl_key: bool,
_shift_key: bool,
_alt_key: bool,
_meta_key: bool,
) {
}

fn activation_behavior(&self, _event: &Event, _target: &EventTarget) {
follow_hyperlink(self.as_element(), None);
}
@@ -2,7 +2,7 @@
* 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::activation::{synthetic_click_activation, Activatable, ActivationSource};
use crate::dom::activation::Activatable;
use crate::dom::attr::Attr;
use crate::dom::bindings::codegen::Bindings::HTMLButtonElementBinding;
use crate::dom::bindings::codegen::Bindings::HTMLButtonElementBinding::HTMLButtonElementMethods;
@@ -18,7 +18,7 @@ use crate::dom::htmlfieldsetelement::HTMLFieldSetElement;
use crate::dom::htmlformelement::HTMLFormElement;
use crate::dom::htmlformelement::{FormControl, FormDatum, FormDatumValue};
use crate::dom::htmlformelement::{FormSubmitter, ResetFrom, SubmittedFrom};
use crate::dom::node::{document_from_node, window_from_node, BindContext, Node, UnbindContext};
use crate::dom::node::{window_from_node, BindContext, Node, UnbindContext};
use crate::dom::nodelist::NodeList;
use crate::dom::validation::Validatable;
use crate::dom::validitystate::{ValidationFlags, ValidityState};
@@ -322,29 +322,4 @@ impl Activatable for HTMLButtonElement {
_ => (),
}
}

// https://html.spec.whatwg.org/multipage/#implicit-submission
#[allow(unsafe_code)]
fn implicit_submission(&self, ctrl_key: bool, shift_key: bool, alt_key: bool, meta_key: bool) {
let doc = document_from_node(self);
let node = doc.upcast::<Node>();
let owner = self.form_owner();
if owner.is_none() || self.upcast::<Element>().click_in_progress() {
return;
}
node.query_selector_iter(DOMString::from("button[type=submit]"))
.unwrap()
.filter_map(DomRoot::downcast::<HTMLButtonElement>)
.find(|r| r.form_owner() == owner)
.map(|s| {
synthetic_click_activation(
s.as_element(),
ctrl_key,
shift_key,
alt_key,
meta_key,
ActivationSource::NotFromClick,
)
});
}
}
@@ -1221,6 +1221,75 @@ impl HTMLInputElement {
fn selection(&self) -> TextControlSelection<Self> {
TextControlSelection::new(&self, &self.textinput)
}

// https://html.spec.whatwg.org/multipage/#implicit-submission
#[allow(unsafe_code)]
fn implicit_submission(&self, ctrl_key: bool, shift_key: bool, alt_key: bool, meta_key: bool) {
let doc = document_from_node(self);
let node = doc.upcast::<Node>();
let owner = self.form_owner();
let form = match owner {
None => return,
Some(ref f) => f,
};

if self.upcast::<Element>().click_in_progress() {
return;
}
let submit_button;
submit_button = node
.query_selector_iter(DOMString::from("input[type=submit]"))
.unwrap()
.filter_map(DomRoot::downcast::<HTMLInputElement>)
.find(|r| r.form_owner() == owner);
match submit_button {
Some(ref button) => {
if button.is_instance_activatable() {
synthetic_click_activation(
button.as_element(),
ctrl_key,
shift_key,
alt_key,
meta_key,
ActivationSource::NotFromClick,
)
}
},
None => {
let inputs = node
.query_selector_iter(DOMString::from("input"))
.unwrap()
.filter_map(DomRoot::downcast::<HTMLInputElement>)
.filter(|input| {
input.form_owner() == owner &&
match input.input_type() {
InputType::Text |
InputType::Search |
InputType::Url |
InputType::Tel |
InputType::Email |
InputType::Password |
InputType::Date |
InputType::Month |
InputType::Week |
InputType::Time |
InputType::DatetimeLocal |
InputType::Number => true,
_ => false,
}
});

if inputs.skip(1).next().is_some() {
// lazily test for > 1 submission-blocking inputs
return;
}
form.submit(
SubmittedFrom::NotFromForm,
FormSubmitter::FormElement(&form),
);
},
}
}
}

impl VirtualMethods for HTMLInputElement {
@@ -1746,75 +1815,6 @@ impl Activatable for HTMLInputElement {
_ => (),
}
}

// https://html.spec.whatwg.org/multipage/#implicit-submission
#[allow(unsafe_code)]
fn implicit_submission(&self, ctrl_key: bool, shift_key: bool, alt_key: bool, meta_key: bool) {
let doc = document_from_node(self);
let node = doc.upcast::<Node>();
let owner = self.form_owner();
let form = match owner {
None => return,
Some(ref f) => f,
};

if self.upcast::<Element>().click_in_progress() {
return;
}
let submit_button;
submit_button = node
.query_selector_iter(DOMString::from("input[type=submit]"))
.unwrap()
.filter_map(DomRoot::downcast::<HTMLInputElement>)
.find(|r| r.form_owner() == owner);
match submit_button {
Some(ref button) => {
if button.is_instance_activatable() {
synthetic_click_activation(
button.as_element(),
ctrl_key,
shift_key,
alt_key,
meta_key,
ActivationSource::NotFromClick,
)
}
},
None => {
let inputs = node
.query_selector_iter(DOMString::from("input"))
.unwrap()
.filter_map(DomRoot::downcast::<HTMLInputElement>)
.filter(|input| {
input.form_owner() == owner &&
match input.input_type() {
InputType::Text |
InputType::Search |
InputType::Url |
InputType::Tel |
InputType::Email |
InputType::Password |
InputType::Date |
InputType::Month |
InputType::Week |
InputType::Time |
InputType::DatetimeLocal |
InputType::Number => true,
_ => false,
}
});

if inputs.skip(1).next().is_some() {
// lazily test for > 1 submission-blocking inputs
return;
}
form.submit(
SubmittedFrom::NotFromForm,
FormSubmitter::FormElement(&form),
);
},
}
}
}

// https://html.spec.whatwg.org/multipage/#attr-input-accept
@@ -83,18 +83,6 @@ impl Activatable for HTMLLabelElement {
);
}
}

// https://html.spec.whatwg.org/multipage/#implicit-submission
fn implicit_submission(
&self,
_ctrl_key: bool,
_shift_key: bool,
_alt_key: bool,
_meta_key: bool,
) {
//FIXME: Investigate and implement implicit submission for label elements
// Issue filed at https://github.com/servo/servo/issues/8263
}
}

impl HTMLLabelElementMethods for HTMLLabelElement {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.