mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-28 12:45:27 +00:00
servo: Merge #3915 - Extract the script task handlers code into separate methods (from shinglyu:bug3811); r=jdm
This is a fix for bug #3811 , thank you. Source-Repo: https://github.com/servo/servo Source-Revision: fc62243f81ba4c5a3585b2a80c859fad16083557
This commit is contained in:
parent
e3578e3f69
commit
e9f57feaf4
@ -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, SendEventMsg, ResizeInactiveMsg};
|
||||
use script_traits::{ExitPipelineMsg, NewLayoutInfo, OpaqueScriptLayoutChannel, ScriptControlChan};
|
||||
use script_traits::ReflowCompleteMsg;
|
||||
use script_traits::{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};
|
||||
@ -885,172 +885,22 @@ impl ScriptTask {
|
||||
fn handle_event(&self, pipeline_id: PipelineId, event: CompositorEvent) {
|
||||
match event {
|
||||
ResizeEvent(new_size) => {
|
||||
debug!("script got resize event: {:?}", new_size);
|
||||
|
||||
let window = {
|
||||
let page = get_page(&*self.page.borrow(), pipeline_id);
|
||||
page.window_size.set(new_size);
|
||||
|
||||
let frame = page.frame();
|
||||
if frame.is_some() {
|
||||
self.force_reflow(&*page);
|
||||
}
|
||||
|
||||
let fragment_node =
|
||||
page.fragment_name
|
||||
.borrow_mut()
|
||||
.take()
|
||||
.and_then(|name| page.find_fragment_node(name))
|
||||
.root();
|
||||
match fragment_node {
|
||||
Some(node) => self.scroll_fragment_point(pipeline_id, *node),
|
||||
None => {}
|
||||
}
|
||||
|
||||
frame.as_ref().map(|frame| Temporary::new(frame.window.clone()))
|
||||
};
|
||||
|
||||
match window.root() {
|
||||
Some(window) => {
|
||||
// http://dev.w3.org/csswg/cssom-view/#resizing-viewports
|
||||
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#event-type-resize
|
||||
let uievent = UIEvent::new(window.clone(),
|
||||
"resize".to_string(), false,
|
||||
false, Some(window.clone()),
|
||||
0i32).root();
|
||||
let event: JSRef<Event> = EventCast::from_ref(*uievent);
|
||||
|
||||
let wintarget: JSRef<EventTarget> = EventTargetCast::from_ref(*window);
|
||||
let _ = wintarget.dispatch_event_with_target(None, event);
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
self.handle_resize_event(pipeline_id, new_size);
|
||||
}
|
||||
|
||||
// FIXME(pcwalton): This reflows the entire document and is not incremental-y.
|
||||
ReflowEvent(to_dirty) => {
|
||||
debug!("script got reflow event");
|
||||
assert_eq!(to_dirty.len(), 0);
|
||||
let page = get_page(&*self.page.borrow(), pipeline_id);
|
||||
let frame = page.frame();
|
||||
if frame.is_some() {
|
||||
let in_layout = page.layout_join_port.borrow().is_some();
|
||||
if in_layout {
|
||||
page.pending_reflows.set(page.pending_reflows.get() + 1);
|
||||
} else {
|
||||
self.force_reflow(&*page);
|
||||
}
|
||||
}
|
||||
self.handle_reflow_event(pipeline_id, to_dirty);
|
||||
}
|
||||
|
||||
ClickEvent(_button, point) => {
|
||||
debug!("ClickEvent: clicked at {:?}", point);
|
||||
let page = get_page(&*self.page.borrow(), pipeline_id);
|
||||
match page.hit_test(&point) {
|
||||
Some(node_address) => {
|
||||
debug!("node address is {:?}", node_address);
|
||||
|
||||
let temp_node =
|
||||
node::from_untrusted_node_address(
|
||||
self.js_runtime.ptr, node_address).root();
|
||||
|
||||
let maybe_node = if !temp_node.is_element() {
|
||||
temp_node.ancestors().find(|node| node.is_element())
|
||||
} else {
|
||||
Some(*temp_node)
|
||||
};
|
||||
|
||||
match maybe_node {
|
||||
Some(node) => {
|
||||
debug!("clicked on {:s}", node.debug_str());
|
||||
// Prevent click event if form control element is disabled.
|
||||
if node.click_event_filter_by_disabled_state() { return; }
|
||||
match *page.frame() {
|
||||
Some(ref frame) => {
|
||||
let window = frame.window.root();
|
||||
let event =
|
||||
Event::new(&global::Window(*window),
|
||||
"click".to_string(),
|
||||
Bubbles, Cancelable).root();
|
||||
let eventtarget: JSRef<EventTarget> = EventTargetCast::from_ref(node);
|
||||
let _ = eventtarget.dispatch_event_with_target(None, *event);
|
||||
|
||||
window.flush_layout();
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
None => {}
|
||||
}
|
||||
self.handle_click_event(pipeline_id, _button, point);
|
||||
}
|
||||
|
||||
MouseDownEvent(..) => {}
|
||||
MouseUpEvent(..) => {}
|
||||
MouseMoveEvent(point) => {
|
||||
let page = get_page(&*self.page.borrow(), pipeline_id);
|
||||
match page.get_nodes_under_mouse(&point) {
|
||||
Some(node_address) => {
|
||||
|
||||
let mut target_list = vec!();
|
||||
let mut target_compare = false;
|
||||
|
||||
let mouse_over_targets = &mut *self.mouse_over_targets.borrow_mut();
|
||||
match *mouse_over_targets {
|
||||
Some(ref mut mouse_over_targets) => {
|
||||
for node in mouse_over_targets.iter_mut() {
|
||||
let node = node.root();
|
||||
node.set_hover_state(false);
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
for node_address in node_address.iter() {
|
||||
|
||||
let temp_node =
|
||||
node::from_untrusted_node_address(
|
||||
self.js_runtime.ptr, *node_address);
|
||||
|
||||
let maybe_node = temp_node.root().ancestors().find(|node| node.is_element());
|
||||
match maybe_node {
|
||||
Some(node) => {
|
||||
node.set_hover_state(true);
|
||||
|
||||
match *mouse_over_targets {
|
||||
Some(ref mouse_over_targets) => {
|
||||
if !target_compare {
|
||||
target_compare = !mouse_over_targets.contains(&JS::from_rooted(node));
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
target_list.push(JS::from_rooted(node));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
match *mouse_over_targets {
|
||||
Some(ref mouse_over_targets) => {
|
||||
if mouse_over_targets.len() != target_list.len() {
|
||||
target_compare = true;
|
||||
}
|
||||
}
|
||||
None => { target_compare = true; }
|
||||
}
|
||||
|
||||
if target_compare {
|
||||
if mouse_over_targets.is_some() {
|
||||
self.force_reflow(&*page);
|
||||
}
|
||||
*mouse_over_targets = Some(target_list);
|
||||
}
|
||||
}
|
||||
|
||||
None => {}
|
||||
}
|
||||
self.handle_mouse_move_event(pipeline_id, point);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1071,8 +921,177 @@ impl ScriptTask {
|
||||
self.scroll_fragment_point(pipeline_id, *node);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn handle_resize_event(&self, pipeline_id: PipelineId, new_size: WindowSizeData) {
|
||||
debug!("script got resize event: {:?}", new_size);
|
||||
|
||||
let window = {
|
||||
let page = get_page(&*self.page.borrow(), pipeline_id);
|
||||
page.window_size.set(new_size);
|
||||
|
||||
let frame = page.frame();
|
||||
if frame.is_some() {
|
||||
self.force_reflow(&*page);
|
||||
}
|
||||
|
||||
let fragment_node =
|
||||
page.fragment_name
|
||||
.borrow_mut()
|
||||
.take()
|
||||
.and_then(|name| page.find_fragment_node(name))
|
||||
.root();
|
||||
match fragment_node {
|
||||
Some(node) => self.scroll_fragment_point(pipeline_id, *node),
|
||||
None => {}
|
||||
}
|
||||
|
||||
frame.as_ref().map(|frame| Temporary::new(frame.window.clone()))
|
||||
};
|
||||
|
||||
match window.root() {
|
||||
Some(window) => {
|
||||
// http://dev.w3.org/csswg/cssom-view/#resizing-viewports
|
||||
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#event-type-resize
|
||||
let uievent = UIEvent::new(window.clone(),
|
||||
"resize".to_string(), false,
|
||||
false, Some(window.clone()),
|
||||
0i32).root();
|
||||
let event: JSRef<Event> = EventCast::from_ref(*uievent);
|
||||
|
||||
let wintarget: JSRef<EventTarget> = EventTargetCast::from_ref(*window);
|
||||
let _ = wintarget.dispatch_event_with_target(None, event);
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_reflow_event(&self, pipeline_id: PipelineId, to_dirty: SmallVec1<UntrustedNodeAddress>) {
|
||||
debug!("script got reflow event");
|
||||
assert_eq!(to_dirty.len(), 0);
|
||||
let page = get_page(&*self.page.borrow(), pipeline_id);
|
||||
let frame = page.frame();
|
||||
if frame.is_some() {
|
||||
let in_layout = page.layout_join_port.borrow().is_some();
|
||||
if in_layout {
|
||||
page.pending_reflows.set(page.pending_reflows.get() + 1);
|
||||
} else {
|
||||
self.force_reflow(&*page);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_click_event(&self, pipeline_id: PipelineId, _button: uint, point: Point2D<f32>) {
|
||||
debug!("ClickEvent: clicked at {:?}", point);
|
||||
let page = get_page(&*self.page.borrow(), pipeline_id);
|
||||
match page.hit_test(&point) {
|
||||
Some(node_address) => {
|
||||
debug!("node address is {:?}", node_address);
|
||||
|
||||
let temp_node =
|
||||
node::from_untrusted_node_address(
|
||||
self.js_runtime.ptr, node_address).root();
|
||||
|
||||
let maybe_node = if !temp_node.is_element() {
|
||||
temp_node.ancestors().find(|node| node.is_element())
|
||||
} else {
|
||||
Some(*temp_node)
|
||||
};
|
||||
|
||||
match maybe_node {
|
||||
Some(node) => {
|
||||
debug!("clicked on {:s}", node.debug_str());
|
||||
// Prevent click event if form control element is disabled.
|
||||
if node.click_event_filter_by_disabled_state() { return; }
|
||||
match *page.frame() {
|
||||
Some(ref frame) => {
|
||||
let window = frame.window.root();
|
||||
let event =
|
||||
Event::new(&global::Window(*window),
|
||||
"click".to_string(),
|
||||
Bubbles, Cancelable).root();
|
||||
let eventtarget: JSRef<EventTarget> = EventTargetCast::from_ref(node);
|
||||
let _ = eventtarget.dispatch_event_with_target(None, *event);
|
||||
|
||||
window.flush_layout();
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn handle_mouse_move_event(&self, pipeline_id: PipelineId, point: Point2D<f32>) {
|
||||
let page = get_page(&*self.page.borrow(), pipeline_id);
|
||||
match page.get_nodes_under_mouse(&point) {
|
||||
Some(node_address) => {
|
||||
|
||||
let mut target_list = vec!();
|
||||
let mut target_compare = false;
|
||||
|
||||
let mouse_over_targets = &mut *self.mouse_over_targets.borrow_mut();
|
||||
match *mouse_over_targets {
|
||||
Some(ref mut mouse_over_targets) => {
|
||||
for node in mouse_over_targets.iter_mut() {
|
||||
let node = node.root();
|
||||
node.set_hover_state(false);
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
for node_address in node_address.iter() {
|
||||
|
||||
let temp_node =
|
||||
node::from_untrusted_node_address(
|
||||
self.js_runtime.ptr, *node_address);
|
||||
|
||||
let maybe_node = temp_node.root().ancestors().find(|node| node.is_element());
|
||||
match maybe_node {
|
||||
Some(node) => {
|
||||
node.set_hover_state(true);
|
||||
|
||||
match *mouse_over_targets {
|
||||
Some(ref mouse_over_targets) => {
|
||||
if !target_compare {
|
||||
target_compare = !mouse_over_targets.contains(&JS::from_rooted(node));
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
target_list.push(JS::from_rooted(node));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
match *mouse_over_targets {
|
||||
Some(ref mouse_over_targets) => {
|
||||
if mouse_over_targets.len() != target_list.len() {
|
||||
target_compare = true;
|
||||
}
|
||||
}
|
||||
None => { target_compare = true; }
|
||||
}
|
||||
|
||||
if target_compare {
|
||||
if mouse_over_targets.is_some() {
|
||||
self.force_reflow(&*page);
|
||||
}
|
||||
*mouse_over_targets = Some(target_list);
|
||||
}
|
||||
}
|
||||
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Shuts down layout for the given page tree.
|
||||
@ -1117,3 +1136,4 @@ fn get_page(page: &Rc<Page>, pipeline_id: PipelineId) -> Rc<Page> {
|
||||
message for a layout channel that is not associated with this script task.\
|
||||
This is a bug.")
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user