Allow 'keypress' event to emerge from input and textarea elements

This commit is contained in:
Ravi Shankar 2016-12-27 13:01:45 +05:30
parent b10bfeaeb6
commit 08662cc64e
3 changed files with 33 additions and 34 deletions

View file

@ -13,7 +13,6 @@ use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods;
use dom::bindings::codegen::Bindings::DocumentBinding; use dom::bindings::codegen::Bindings::DocumentBinding;
use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState}; use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState};
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventHandlerBinding::OnErrorEventHandlerNonNull; use dom::bindings::codegen::Bindings::EventHandlerBinding::OnErrorEventHandlerNonNull;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
@ -41,7 +40,7 @@ use dom::documenttype::DocumentType;
use dom::domimplementation::DOMImplementation; use dom::domimplementation::DOMImplementation;
use dom::element::{Element, ElementCreator, ElementPerformFullscreenEnter, ElementPerformFullscreenExit}; use dom::element::{Element, ElementCreator, ElementPerformFullscreenEnter, ElementPerformFullscreenExit};
use dom::errorevent::ErrorEvent; use dom::errorevent::ErrorEvent;
use dom::event::{Event, EventBubbles, EventCancelable}; use dom::event::{Event, EventBubbles, EventCancelable, EventDefault};
use dom::eventdispatcher::EventStatus; use dom::eventdispatcher::EventStatus;
use dom::eventtarget::EventTarget; use dom::eventtarget::EventTarget;
use dom::focusevent::FocusEvent; use dom::focusevent::FocusEvent;
@ -1308,10 +1307,10 @@ impl Document {
props.key_code); props.key_code);
let event = keyevent.upcast::<Event>(); let event = keyevent.upcast::<Event>();
event.fire(target); event.fire(target);
let mut prevented = event.DefaultPrevented(); let mut cancel_state = event.get_cancel_state();
// https://w3c.github.io/uievents/#keys-cancelable-keys // https://w3c.github.io/uievents/#keys-cancelable-keys
if state != KeyState::Released && props.is_printable() && !prevented { if state != KeyState::Released && props.is_printable() && cancel_state != EventDefault::Prevented {
// https://w3c.github.io/uievents/#keypress-event-order // https://w3c.github.io/uievents/#keypress-event-order
let event = KeyboardEvent::new(&self.window, let event = KeyboardEvent::new(&self.window,
DOMString::from("keypress"), DOMString::from("keypress"),
@ -1334,21 +1333,20 @@ impl Document {
0); 0);
let ev = event.upcast::<Event>(); let ev = event.upcast::<Event>();
ev.fire(target); ev.fire(target);
prevented = ev.DefaultPrevented(); cancel_state = ev.get_cancel_state();
// TODO: if keypress event is canceled, prevent firing input events // TODO: if keypress event is canceled, prevent firing input events
} }
if !prevented { if cancel_state == EventDefault::Allowed {
constellation.send(ConstellationMsg::SendKeyEvent(ch, key, state, modifiers)).unwrap(); constellation.send(ConstellationMsg::SendKeyEvent(ch, key, state, modifiers)).unwrap();
}
// This behavior is unspecced // This behavior is unspecced
// We are supposed to dispatch synthetic click activation for Space and/or Return, // We are supposed to dispatch synthetic click activation for Space and/or Return,
// however *when* we do it is up to us // however *when* we do it is up to us.
// I'm dispatching it after the key event so the script has a chance to cancel it // 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 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=27337
match key { match key {
Key::Space if !prevented && state == KeyState::Released => { Key::Space if state == KeyState::Released => {
let maybe_elem = target.downcast::<Element>(); let maybe_elem = target.downcast::<Element>();
if let Some(el) = maybe_elem { if let Some(el) = maybe_elem {
synthetic_click_activation(el, synthetic_click_activation(el,
@ -1359,7 +1357,7 @@ impl Document {
ActivationSource::NotFromClick) ActivationSource::NotFromClick)
} }
} }
Key::Enter if !prevented && state == KeyState::Released => { Key::Enter if state == KeyState::Released => {
let maybe_elem = target.downcast::<Element>(); let maybe_elem = target.downcast::<Element>();
if let Some(el) = maybe_elem { if let Some(el) = maybe_elem {
if let Some(a) = el.as_maybe_activatable() { if let Some(a) = el.as_maybe_activatable() {
@ -1369,6 +1367,7 @@ impl Document {
} }
_ => (), _ => (),
} }
}
self.window.reflow(ReflowGoal::ForDisplay, self.window.reflow(ReflowGoal::ForDisplay,
ReflowQueryType::NoQuery, ReflowQueryType::NoQuery,

View file

@ -1117,11 +1117,11 @@ impl VirtualMethods for HTMLInputElement {
} }
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
event.PreventDefault(); event.mark_as_handled();
} }
RedrawSelection => { RedrawSelection => {
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
event.PreventDefault(); event.mark_as_handled();
} }
Nothing => (), Nothing => (),
} }

View file

@ -415,11 +415,11 @@ impl VirtualMethods for HTMLTextAreaElement {
} }
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
event.PreventDefault(); event.mark_as_handled();
} }
KeyReaction::RedrawSelection => { KeyReaction::RedrawSelection => {
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
event.PreventDefault(); event.mark_as_handled();
} }
KeyReaction::Nothing => (), KeyReaction::Nothing => (),
} }