mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Bug #3811 - Extracted the script task handlers into methods
This commit is contained in:
parent
ffae110498
commit
783c6703ca
1 changed files with 178 additions and 158 deletions
|
@ -42,7 +42,7 @@ use script_traits::{CompositorEvent, ResizeEvent, ReflowEvent, ClickEvent, Mouse
|
||||||
use script_traits::{MouseMoveEvent, MouseUpEvent, ConstellationControlMsg, ScriptTaskFactory};
|
use script_traits::{MouseMoveEvent, MouseUpEvent, ConstellationControlMsg, ScriptTaskFactory};
|
||||||
use script_traits::{ResizeMsg, AttachLayoutMsg, LoadMsg, SendEventMsg, ResizeInactiveMsg};
|
use script_traits::{ResizeMsg, AttachLayoutMsg, LoadMsg, SendEventMsg, ResizeInactiveMsg};
|
||||||
use script_traits::{ExitPipelineMsg, NewLayoutInfo, OpaqueScriptLayoutChannel, ScriptControlChan};
|
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::{FinishedLoading, LayerId, Loading};
|
||||||
use servo_msg::compositor_msg::{ScriptListener};
|
use servo_msg::compositor_msg::{ScriptListener};
|
||||||
use servo_msg::constellation_msg::{ConstellationChan, LoadCompleteMsg, LoadUrlMsg, NavigationDirection};
|
use servo_msg::constellation_msg::{ConstellationChan, LoadCompleteMsg, LoadUrlMsg, NavigationDirection};
|
||||||
|
@ -885,172 +885,22 @@ impl ScriptTask {
|
||||||
fn handle_event(&self, pipeline_id: PipelineId, event: CompositorEvent) {
|
fn handle_event(&self, pipeline_id: PipelineId, event: CompositorEvent) {
|
||||||
match event {
|
match event {
|
||||||
ResizeEvent(new_size) => {
|
ResizeEvent(new_size) => {
|
||||||
debug!("script got resize event: {:?}", new_size);
|
self.handle_resize_event(pipeline_id, 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 => ()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(pcwalton): This reflows the entire document and is not incremental-y.
|
// FIXME(pcwalton): This reflows the entire document and is not incremental-y.
|
||||||
ReflowEvent(to_dirty) => {
|
ReflowEvent(to_dirty) => {
|
||||||
debug!("script got reflow event");
|
self.handle_reflow_event(pipeline_id, to_dirty);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClickEvent(_button, point) => {
|
ClickEvent(_button, point) => {
|
||||||
debug!("ClickEvent: clicked at {:?}", point);
|
self.handle_click_event(pipeline_id, _button, 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 => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseDownEvent(..) => {}
|
MouseDownEvent(..) => {}
|
||||||
MouseUpEvent(..) => {}
|
MouseUpEvent(..) => {}
|
||||||
MouseMoveEvent(point) => {
|
MouseMoveEvent(point) => {
|
||||||
let page = get_page(&*self.page.borrow(), pipeline_id);
|
self.handle_mouse_move_event(pipeline_id, point);
|
||||||
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 => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1071,8 +921,177 @@ impl ScriptTask {
|
||||||
self.scroll_fragment_point(pipeline_id, *node);
|
self.scroll_fragment_point(pipeline_id, *node);
|
||||||
}
|
}
|
||||||
None => {}
|
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.
|
/// 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.\
|
message for a layout channel that is not associated with this script task.\
|
||||||
This is a bug.")
|
This is a bug.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue