mirror of
https://github.com/servo/servo.git
synced 2025-06-15 20:04:28 +00:00
Dispatch touch events and perform default touch actions.
This is currently limited to simple single-touch actions. It does not include momentum scrolling or pinch zooming.
This commit is contained in:
parent
4ed15a8853
commit
fe7460f34d
9 changed files with 276 additions and 15 deletions
|
@ -21,6 +21,7 @@ use dom::bindings::error::{Error, ErrorResult, Fallible};
|
|||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::RootedReference;
|
||||
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root};
|
||||
use dom::bindings::num::Finite;
|
||||
use dom::bindings::refcounted::Trusted;
|
||||
use dom::bindings::trace::RootedVec;
|
||||
use dom::bindings::utils::XMLName::InvalidXMLName;
|
||||
|
@ -60,6 +61,9 @@ use dom::processinginstruction::ProcessingInstruction;
|
|||
use dom::range::Range;
|
||||
use dom::servohtmlparser::ServoHTMLParser;
|
||||
use dom::text::Text;
|
||||
use dom::touch::Touch;
|
||||
use dom::touchevent::TouchEvent;
|
||||
use dom::touchlist::TouchList;
|
||||
use dom::treewalker::TreeWalker;
|
||||
use dom::uievent::UIEvent;
|
||||
use dom::window::{ReflowReason, Window};
|
||||
|
@ -699,6 +703,55 @@ impl Document {
|
|||
ReflowReason::MouseEvent);
|
||||
}
|
||||
|
||||
pub fn handle_touch_event(&self,
|
||||
js_runtime: *mut JSRuntime,
|
||||
identifier: i32,
|
||||
point: Point2D<f32>,
|
||||
event_name: String) -> bool {
|
||||
let node = match self.hit_test(&point) {
|
||||
Some(node_address) => node::from_untrusted_node_address(js_runtime, node_address),
|
||||
None => return false
|
||||
};
|
||||
let el = match node.downcast::<Element>() {
|
||||
Some(el) => Root::from_ref(el),
|
||||
None => {
|
||||
let parent = node.r().GetParentNode();
|
||||
match parent.and_then(Root::downcast::<Element>) {
|
||||
Some(parent) => parent,
|
||||
None => return false
|
||||
}
|
||||
},
|
||||
};
|
||||
let target = el.upcast::<EventTarget>();
|
||||
|
||||
let x = Finite::wrap(point.x as f64);
|
||||
let y = Finite::wrap(point.y as f64);
|
||||
|
||||
let window = self.window.root();
|
||||
|
||||
let touch = Touch::new(window.r(), identifier, target, x, y, x, y);
|
||||
let mut touches = RootedVec::new();
|
||||
touches.push(JS::from_rooted(&touch));
|
||||
let touches = TouchList::new(window.r(), touches.r());
|
||||
|
||||
let event = TouchEvent::new(window.r(),
|
||||
event_name,
|
||||
EventBubbles::Bubbles,
|
||||
EventCancelable::Cancelable,
|
||||
Some(window.r()),
|
||||
0i32,
|
||||
&touches, &touches, &touches,
|
||||
// FIXME: modifier keys
|
||||
false, false, false, false);
|
||||
let event = event.upcast::<Event>();
|
||||
let result = event.fire(target);
|
||||
|
||||
window.r().reflow(ReflowGoal::ForDisplay,
|
||||
ReflowQueryType::NoQuery,
|
||||
ReflowReason::MouseEvent);
|
||||
result
|
||||
}
|
||||
|
||||
/// The entry point for all key processing for web content
|
||||
pub fn dispatch_key_event(&self,
|
||||
key: Key,
|
||||
|
|
|
@ -9,7 +9,7 @@ use dom::bindings::conversions::Castable;
|
|||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{JS, MutHeap, Root};
|
||||
use dom::bindings::utils::reflect_dom_object;
|
||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||
use dom::event::{EventBubbles, EventCancelable};
|
||||
use dom::touchlist::TouchList;
|
||||
use dom::uievent::UIEvent;
|
||||
use dom::window::Window;
|
||||
|
|
|
@ -60,7 +60,7 @@ use layout_interface::{ReflowQueryType};
|
|||
use layout_interface::{self, LayoutChan, NewLayoutTaskInfo, ReflowGoal, ScriptLayoutChan};
|
||||
use libc;
|
||||
use mem::heap_size_of_self_and_children;
|
||||
use msg::compositor_msg::{LayerId, ScriptToCompositorMsg};
|
||||
use msg::compositor_msg::{EventResult, LayerId, ScriptToCompositorMsg};
|
||||
use msg::constellation_msg::Msg as ConstellationMsg;
|
||||
use msg::constellation_msg::{ConstellationChan, FocusType, LoadData};
|
||||
use msg::constellation_msg::{MozBrowserEvent, PipelineExitType, PipelineId};
|
||||
|
@ -79,6 +79,7 @@ use profile_traits::time::{self, ProfilerCategory, profile};
|
|||
use script_traits::CompositorEvent::{ClickEvent, ResizeEvent};
|
||||
use script_traits::CompositorEvent::{KeyEvent, MouseMoveEvent};
|
||||
use script_traits::CompositorEvent::{MouseDownEvent, MouseUpEvent};
|
||||
use script_traits::CompositorEvent::{TouchDownEvent, TouchMoveEvent, TouchUpEvent};
|
||||
use script_traits::{CompositorEvent, ConstellationControlMsg};
|
||||
use script_traits::{InitialScriptState, MouseButton, NewLayoutInfo};
|
||||
use script_traits::{OpaqueScriptLayoutChannel, ScriptState, ScriptTaskFactory};
|
||||
|
@ -1784,6 +1785,27 @@ impl ScriptTask {
|
|||
std_mem::swap(&mut *self.mouse_over_targets.borrow_mut(), &mut *mouse_over_targets);
|
||||
}
|
||||
|
||||
TouchDownEvent(identifier, point) => {
|
||||
let default_action_allowed =
|
||||
self.handle_touch_event(pipeline_id, identifier, point, "touchstart");
|
||||
if default_action_allowed {
|
||||
// TODO: Wait to see if preventDefault is called on the first touchmove event.
|
||||
self.compositor.borrow_mut().send(ScriptToCompositorMsg::TouchEventProcessed(
|
||||
EventResult::DefaultAllowed)).unwrap();
|
||||
} else {
|
||||
self.compositor.borrow_mut().send(ScriptToCompositorMsg::TouchEventProcessed(
|
||||
EventResult::DefaultPrevented)).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
TouchMoveEvent(identifier, point) => {
|
||||
self.handle_touch_event(pipeline_id, identifier, point, "touchmove");
|
||||
}
|
||||
|
||||
TouchUpEvent(identifier, point) => {
|
||||
self.handle_touch_event(pipeline_id, identifier, point, "touchend");
|
||||
}
|
||||
|
||||
KeyEvent(key, state, modifiers) => {
|
||||
let page = get_page(&self.root_page(), pipeline_id);
|
||||
let document = page.document();
|
||||
|
@ -1803,6 +1825,17 @@ impl ScriptTask {
|
|||
document.r().handle_mouse_event(self.js_runtime.rt(), button, point, mouse_event_type);
|
||||
}
|
||||
|
||||
fn handle_touch_event(&self,
|
||||
pipeline_id: PipelineId,
|
||||
identifier: i32,
|
||||
point: Point2D<f32>,
|
||||
event_name: &str) -> bool {
|
||||
let page = get_page(&self.root_page(), pipeline_id);
|
||||
let document = page.document();
|
||||
document.r().handle_touch_event(self.js_runtime.rt(), identifier, point,
|
||||
event_name.to_owned())
|
||||
}
|
||||
|
||||
/// https://html.spec.whatwg.org/multipage/#navigating-across-documents
|
||||
/// The entry point for content to notify that a new load has been requested
|
||||
/// for the given pipeline (specifically the "navigate" algorithm).
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue