aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/event.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/event.rs')
-rw-r--r--components/script/dom/event.rs42
1 files changed, 37 insertions, 5 deletions
diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs
index d471c25d873..fa3b9bfae6b 100644
--- a/components/script/dom/event.rs
+++ b/components/script/dom/event.rs
@@ -77,6 +77,28 @@ impl From<bool> for EventCancelable {
}
}
+/// An enum to indicate whether the default action of an event is allowed.
+///
+/// This should've been a bool. Instead, it's an enum, because, aside from the allowed/canceled
+/// states, we also need something to stop the event from being handled again (without cancelling
+/// the event entirely). For example, an Up/Down `KeyEvent` inside a `textarea` element will
+/// trigger the cursor to go up/down if the text inside the element spans multiple lines. This enum
+/// helps us to prevent such events from being [sent to the constellation][msg] where it will be
+/// handled once again for page scrolling (which is definitely not what we'd want).
+///
+/// [msg]: https://doc.servo.org/script_traits/enum.ConstellationMsg.html#variant.KeyEvent
+///
+#[derive(JSTraceable, HeapSizeOf, Copy, Clone, PartialEq)]
+pub enum EventDefault {
+ /// The default action of the event is allowed (constructor's default)
+ Allowed,
+ /// The default action has been prevented by calling `PreventDefault`
+ Prevented,
+ /// The event has been handled somewhere in the DOM, and it should be prevented from being
+ /// re-handled elsewhere. This doesn't affect the judgement of `DefaultPrevented`
+ Handled,
+}
+
#[dom_struct]
pub struct Event {
reflector_: Reflector,
@@ -84,7 +106,7 @@ pub struct Event {
target: MutNullableJS<EventTarget>,
type_: DOMRefCell<Atom>,
phase: Cell<EventPhase>,
- canceled: Cell<bool>,
+ canceled: Cell<EventDefault>,
stop_propagation: Cell<bool>,
stop_immediate: Cell<bool>,
cancelable: Cell<bool>,
@@ -103,7 +125,7 @@ impl Event {
target: Default::default(),
type_: DOMRefCell::new(atom!("")),
phase: Cell::new(EventPhase::None),
- canceled: Cell::new(false),
+ canceled: Cell::new(EventDefault::Allowed),
stop_propagation: Cell::new(false),
stop_immediate: Cell::new(false),
cancelable: Cell::new(false),
@@ -146,7 +168,7 @@ impl Event {
self.initialized.set(true);
self.stop_propagation.set(false);
self.stop_immediate.set(false);
- self.canceled.set(false);
+ self.canceled.set(EventDefault::Allowed);
self.trusted.set(false);
self.target.set(None);
*self.type_.borrow_mut() = type_;
@@ -229,6 +251,16 @@ impl Event {
pub fn type_(&self) -> Atom {
self.type_.borrow().clone()
}
+
+ #[inline]
+ pub fn mark_as_handled(&self) {
+ self.canceled.set(EventDefault::Handled);
+ }
+
+ #[inline]
+ pub fn get_cancel_state(&self) -> EventDefault {
+ self.canceled.get()
+ }
}
impl EventMethods for Event {
@@ -254,13 +286,13 @@ impl EventMethods for Event {
// https://dom.spec.whatwg.org/#dom-event-defaultprevented
fn DefaultPrevented(&self) -> bool {
- self.canceled.get()
+ self.canceled.get() == EventDefault::Prevented
}
// https://dom.spec.whatwg.org/#dom-event-preventdefault
fn PreventDefault(&self) {
if self.cancelable.get() {
- self.canceled.set(true)
+ self.canceled.set(EventDefault::Prevented)
}
}