From 1c64dabb150da4152957b2c6e16f30d5201328e1 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 2 Oct 2014 03:11:50 -0400 Subject: Pass all key events to the current constellation frame. --- components/script/script_task.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'components/script/script_task.rs') diff --git a/components/script/script_task.rs b/components/script/script_task.rs index c6f4b636d50..31f3abb289c 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -42,7 +42,7 @@ use script_traits::{CompositorEvent, ResizeEvent, ReflowEvent, ClickEvent, Mouse use script_traits::{MouseMoveEvent, MouseUpEvent, ConstellationControlMsg, ScriptTaskFactory}; use script_traits::{ResizeMsg, AttachLayoutMsg, LoadMsg, ViewportMsg, SendEventMsg}; use script_traits::{ResizeInactiveMsg, ExitPipelineMsg, NewLayoutInfo, OpaqueScriptLayoutChannel}; -use script_traits::{ScriptControlChan, ReflowCompleteMsg, UntrustedNodeAddress}; +use script_traits::{ScriptControlChan, ReflowCompleteMsg, UntrustedNodeAddress, KeyEvent}; use servo_msg::compositor_msg::{FinishedLoading, LayerId, Loading}; use servo_msg::compositor_msg::{ScriptListener}; use servo_msg::constellation_msg::{ConstellationChan, LoadCompleteMsg, LoadUrlMsg, NavigationDirection}; @@ -907,6 +907,10 @@ impl ScriptTask { MouseMoveEvent(point) => { self.handle_mouse_move_event(pipeline_id, point); } + + KeyEvent(key, state) => { + println!("key {} is {}", key as int, state as int); + } } } @@ -1093,7 +1097,7 @@ impl ScriptTask { } None => {} - } + } } } -- cgit v1.2.3 From 329ba56fca3bd3808a37aae6bc3ed3c5a5d23524 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sat, 4 Oct 2014 09:46:50 -0400 Subject: Dispatch keydown, keyup, and keypress events at appropriate times. --- components/script/script_task.rs | 56 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) (limited to 'components/script/script_task.rs') diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 31f3abb289c..ff499fb474b 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -10,6 +10,7 @@ use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, Documen use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods; use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods; +use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, EventCast, ElementCast}; use dom::bindings::conversions; use dom::bindings::conversions::{FromJSValConvertible, Empty}; @@ -23,6 +24,7 @@ use dom::element::{HTMLSelectElementTypeId, HTMLTextAreaElementTypeId, HTMLOptio use dom::event::{Event, Bubbles, DoesNotBubble, Cancelable, NotCancelable}; use dom::uievent::UIEvent; use dom::eventtarget::{EventTarget, EventTargetHelpers}; +use dom::keyboardevent::KeyboardEvent; use dom::node; use dom::node::{ElementNodeTypeId, Node, NodeHelpers}; use dom::window::{Window, WindowHelpers}; @@ -46,7 +48,9 @@ use script_traits::{ScriptControlChan, ReflowCompleteMsg, UntrustedNodeAddress, use servo_msg::compositor_msg::{FinishedLoading, LayerId, Loading}; use servo_msg::compositor_msg::{ScriptListener}; use servo_msg::constellation_msg::{ConstellationChan, LoadCompleteMsg, LoadUrlMsg, NavigationDirection}; -use servo_msg::constellation_msg::{LoadData, PipelineId, Failure, FailureMsg, WindowSizeData}; +use servo_msg::constellation_msg::{LoadData, PipelineId, Failure, FailureMsg, WindowSizeData, Key, KeyState}; +use servo_msg::constellation_msg::{KeyModifiers, Super, Shift, Control, Alt, Repeated, Pressed}; +use servo_msg::constellation_msg::{Released}; use servo_msg::constellation_msg; use servo_net::image_cache_task::ImageCacheTask; use servo_net::resource_task::ResourceTask; @@ -908,12 +912,58 @@ impl ScriptTask { self.handle_mouse_move_event(pipeline_id, point); } - KeyEvent(key, state) => { - println!("key {} is {}", key as int, state as int); + KeyEvent(key, state, modifiers) => { + self.dispatch_key_event(key, state, modifiers, pipeline_id); } } } + /// The entry point for all key processing for web content + fn dispatch_key_event(&self, key: Key, + state: KeyState, + modifiers: KeyModifiers, + pipeline_id: PipelineId) { + println!("key {} is {}", key as int, state as int); + let page = get_page(&*self.page.borrow(), pipeline_id); + let frame = page.frame(); + let window = frame.as_ref().unwrap().window.root(); + let doc = window.Document().root(); + let body = doc.GetBody().root(); + + let target: JSRef = match body { + Some(body) => EventTargetCast::from_ref(*body), + None => EventTargetCast::from_ref(*window), + }; + + let ctrl = modifiers.contains(Control); + let alt = modifiers.contains(Alt); + let shift = modifiers.contains(Shift); + let meta = modifiers.contains(Super); + + let is_composing = false; + let is_repeating = state == Repeated; + let ev_type = match state { + Pressed | Repeated => "keydown", + Released => "keyup", + }.to_string(); + + let props = KeyboardEvent::key_properties(key); + + let event = KeyboardEvent::new(*window, ev_type, true, true, Some(*window), 0, + props.key.clone(), props.code.clone(), props.location, + is_repeating, is_composing, ctrl, alt, shift, meta, + props.char_code, props.key_code).root(); + let _ = target.DispatchEvent(EventCast::from_ref(*event)); + + if state != Released && props.is_printable() { + let event = KeyboardEvent::new(*window, "keypress".to_string(), true, true, Some(*window), + 0, props.key.clone(), props.code.clone(), props.location, + is_repeating, is_composing, ctrl, alt, shift, meta, + props.char_code, props.key_code).root(); + let _ = target.DispatchEvent(EventCast::from_ref(*event)); + } + } + /// The entry point for content to notify that a new load has been requested /// for the given pipeline. fn trigger_load(&self, pipeline_id: PipelineId, load_data: LoadData) { -- cgit v1.2.3 From 84bc17e7ad99d11ff416f2126acb2031b680dc19 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sat, 4 Oct 2014 10:31:47 -0400 Subject: Implement document focus context and hook it up to click events. --- components/script/script_task.rs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'components/script/script_task.rs') diff --git a/components/script/script_task.rs b/components/script/script_task.rs index ff499fb474b..684ae327ad2 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -928,11 +928,13 @@ impl ScriptTask { let frame = page.frame(); let window = frame.as_ref().unwrap().window.root(); let doc = window.Document().root(); + let focused = doc.get_focused_element().root(); let body = doc.GetBody().root(); - let target: JSRef = match body { - Some(body) => EventTargetCast::from_ref(*body), - None => EventTargetCast::from_ref(*window), + let target: JSRef = match (&focused, &body) { + (&Some(ref focused), _) => EventTargetCast::from_ref(**focused), + (&None, &Some(ref body)) => EventTargetCast::from_ref(**body), + (&None, &None) => EventTargetCast::from_ref(*window), }; let ctrl = modifiers.contains(Control); @@ -956,10 +958,10 @@ impl ScriptTask { let _ = target.DispatchEvent(EventCast::from_ref(*event)); if state != Released && props.is_printable() { - let event = KeyboardEvent::new(*window, "keypress".to_string(), true, true, Some(*window), - 0, props.key.clone(), props.code.clone(), props.location, - is_repeating, is_composing, ctrl, alt, shift, meta, - props.char_code, props.key_code).root(); + let event = KeyboardEvent::new(*window, "keypress".to_string(), true, true, Some(*window), + 0, props.key.clone(), props.code.clone(), props.location, + is_repeating, is_composing, ctrl, alt, shift, meta, + props.char_code, props.key_code).root(); let _ = target.DispatchEvent(EventCast::from_ref(*event)); } } @@ -1065,6 +1067,9 @@ impl ScriptTask { match *page.frame() { Some(ref frame) => { let window = frame.window.root(); + let doc = window.Document().root(); + doc.begin_focus_transaction(); + let event = Event::new(&global::Window(*window), "click".to_string(), @@ -1072,6 +1077,7 @@ impl ScriptTask { let eventtarget: JSRef = EventTargetCast::from_ref(node); let _ = eventtarget.dispatch_event_with_target(None, *event); + doc.commit_focus_transaction(); window.flush_layout(); } None => {} -- cgit v1.2.3 From 80764f65e3e4895d3a012d6bc1d3bb8183ae15da Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Mon, 6 Oct 2014 11:51:44 -0400 Subject: Add single-line text input with no visible cursor. --- components/script/script_task.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'components/script/script_task.rs') diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 684ae327ad2..5ed9023b5e5 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -49,7 +49,7 @@ use servo_msg::compositor_msg::{FinishedLoading, LayerId, Loading}; use servo_msg::compositor_msg::{ScriptListener}; use servo_msg::constellation_msg::{ConstellationChan, LoadCompleteMsg, LoadUrlMsg, NavigationDirection}; use servo_msg::constellation_msg::{LoadData, PipelineId, Failure, FailureMsg, WindowSizeData, Key, KeyState}; -use servo_msg::constellation_msg::{KeyModifiers, Super, Shift, Control, Alt, Repeated, Pressed}; +use servo_msg::constellation_msg::{KeyModifiers, SUPER, SHIFT, CONTROL, ALT, Repeated, Pressed}; use servo_msg::constellation_msg::{Released}; use servo_msg::constellation_msg; use servo_net::image_cache_task::ImageCacheTask; @@ -923,7 +923,6 @@ impl ScriptTask { state: KeyState, modifiers: KeyModifiers, pipeline_id: PipelineId) { - println!("key {} is {}", key as int, state as int); let page = get_page(&*self.page.borrow(), pipeline_id); let frame = page.frame(); let window = frame.as_ref().unwrap().window.root(); @@ -937,10 +936,10 @@ impl ScriptTask { (&None, &None) => EventTargetCast::from_ref(*window), }; - let ctrl = modifiers.contains(Control); - let alt = modifiers.contains(Alt); - let shift = modifiers.contains(Shift); - let meta = modifiers.contains(Super); + let ctrl = modifiers.contains(CONTROL); + let alt = modifiers.contains(ALT); + let shift = modifiers.contains(SHIFT); + let meta = modifiers.contains(SUPER); let is_composing = false; let is_repeating = state == Repeated; @@ -949,21 +948,24 @@ impl ScriptTask { Released => "keyup", }.to_string(); - let props = KeyboardEvent::key_properties(key); + let props = KeyboardEvent::key_properties(key, modifiers); let event = KeyboardEvent::new(*window, ev_type, true, true, Some(*window), 0, - props.key.clone(), props.code.clone(), props.location, + props.key.to_string(), props.code.to_string(), props.location, is_repeating, is_composing, ctrl, alt, shift, meta, - props.char_code, props.key_code).root(); + None, props.key_code).root(); let _ = target.DispatchEvent(EventCast::from_ref(*event)); if state != Released && props.is_printable() { let event = KeyboardEvent::new(*window, "keypress".to_string(), true, true, Some(*window), - 0, props.key.clone(), props.code.clone(), props.location, - is_repeating, is_composing, ctrl, alt, shift, meta, - props.char_code, props.key_code).root(); + 0, props.key.to_string(), props.code.to_string(), + props.location, is_repeating, is_composing, + ctrl, alt, shift, meta, + props.char_code, 0).root(); let _ = target.DispatchEvent(EventCast::from_ref(*event)); } + + window.flush_layout(); } /// The entry point for content to notify that a new load has been requested -- cgit v1.2.3 From 642a3592c7ea1b82e3a3a660370b9871aa5b5e96 Mon Sep 17 00:00:00 2001 From: Keegan McAllister Date: Mon, 3 Nov 2014 17:21:18 -0800 Subject: Fix interfaces test --- components/script/script_task.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'components/script/script_task.rs') diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 5ed9023b5e5..087e3fdf043 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -9,6 +9,7 @@ use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyStateValues}; use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods; use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; +use dom::bindings::codegen::Bindings::EventBinding::EventMethods; use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods; use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, EventCast, ElementCast}; @@ -950,19 +951,25 @@ impl ScriptTask { let props = KeyboardEvent::key_properties(key, modifiers); - let event = KeyboardEvent::new(*window, ev_type, true, true, Some(*window), 0, - props.key.to_string(), props.code.to_string(), props.location, - is_repeating, is_composing, ctrl, alt, shift, meta, - None, props.key_code).root(); - let _ = target.DispatchEvent(EventCast::from_ref(*event)); - - if state != Released && props.is_printable() { + let keyevent = KeyboardEvent::new(*window, ev_type, true, true, Some(*window), 0, + props.key.to_string(), props.code.to_string(), + props.location, is_repeating, is_composing, + ctrl, alt, shift, meta, + None, props.key_code).root(); + let event = EventCast::from_ref(*keyevent); + let _ = target.DispatchEvent(event); + + // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#keys-cancelable-keys + if state != Released && props.is_printable() && !event.DefaultPrevented() { + // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#keypress-event-order let event = KeyboardEvent::new(*window, "keypress".to_string(), true, true, Some(*window), 0, props.key.to_string(), props.code.to_string(), props.location, is_repeating, is_composing, ctrl, alt, shift, meta, props.char_code, 0).root(); let _ = target.DispatchEvent(EventCast::from_ref(*event)); + + // TODO: if keypress event is canceled, prevent firing input events } window.flush_layout(); -- cgit v1.2.3