Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move body of ScriptTask::handle_mouse_move_event into a method on Document (fixes #5032). #5073

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -83,6 +83,7 @@ use std::ascii::AsciiExt;
use std::cell::{Cell, Ref};
use std::default::Default;
use std::sync::mpsc::channel;
use std::num::ToPrimitive;
use time;

#[derive(PartialEq)]
@@ -209,6 +210,9 @@ pub trait DocumentHelpers<'a> {
fn handle_click_event(self, js_runtime: *mut JSRuntime, _button: uint, point: Point2D<f32>);
fn dispatch_key_event(self, key: Key, state: KeyState,
modifiers: KeyModifiers, compositor: &mut Box<ScriptListener+'static>);
/// Return need force reflow or not
fn handle_mouse_move_event(self, js_runtime: *mut JSRuntime, point: Point2D<f32>,
prev_mouse_over_targets: &mut Vec<JS<Node>>) -> bool;
fn set_current_script(self, script: Option<JSRef<HTMLScriptElement>>);
}

@@ -462,6 +466,75 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
}
}

/// Return need force reflow or not
fn handle_mouse_move_event(self, js_runtime: *mut JSRuntime, point: Point2D<f32>,
prev_mouse_over_targets: &mut Vec<JS<Node>>) -> bool {
let window = self.window.root();
let window = window.r();
let page = window.page();
let mut needs_reflow = false;
// Build a list of elements that are currently under the mouse.
let mouse_over_addresses = page.get_nodes_under_mouse(&point);
let mouse_over_targets: Vec<JS<Node>> = mouse_over_addresses.iter()
.filter_map(|node_address| {
let node = node::from_untrusted_node_address(js_runtime, *node_address);
node.root().r().inclusive_ancestors().find(|node| node.is_element()).map(JS::from_rooted)
}).collect();

// Remove hover from any elements in the previous list that are no longer
// under the mouse.
for target in prev_mouse_over_targets.iter() {
if !mouse_over_targets.contains(target) {
target.root().r().set_hover_state(false);
needs_reflow = true;
}
}

// Set hover state for any elements in the current mouse over list.
// Check if any of them changed state to determine whether to
// force a reflow below.
for target in mouse_over_targets.iter() {
let target = target.root();
let target_ref = target.r();
if !target_ref.get_hover_state() {
target_ref.set_hover_state(true);
needs_reflow = true;
}
}

// Send mousemove event to topmost target
if mouse_over_addresses.len() > 0 {
let top_most_node =
node::from_untrusted_node_address(js_runtime, mouse_over_addresses[0]).root();

if let Some(ref frame) = *page.frame() {
let window = frame.window.root();

let x = point.x.to_i32().unwrap_or(0);
let y = point.y.to_i32().unwrap_or(0);

let mouse_event = MouseEvent::new(window.r(),
"mousemove".to_owned(),
true,
true,
Some(window.r()),
0i32,
x, y, x, y,
false, false, false, false,
0i16,
None).root();

let event: JSRef<Event> = EventCast::from_ref(mouse_event.r());
let target: JSRef<EventTarget> = EventTargetCast::from_ref(top_most_node.r());
event.fire(target);
}
}

// Store the current mouse over targets for next frame
*prev_mouse_over_targets = mouse_over_targets;
needs_reflow
}

/// The entry point for all key processing for web content
fn dispatch_key_event(self, key: Key,
state: KeyState,
@@ -999,7 +999,14 @@ impl ScriptTask {
MouseDownEvent(..) => {}
MouseUpEvent(..) => {}
MouseMoveEvent(point) => {
self.handle_mouse_move_event(pipeline_id, point);
let page = get_page(&*self.page.borrow(), pipeline_id);
let frame = page.frame();
let document = frame.as_ref().unwrap().document.root();
let mouse_over_targets = &mut *self.mouse_over_targets.borrow_mut();

if document.r().handle_mouse_move_event(self.js_runtime.ptr, point, mouse_over_targets) {
self.force_reflow(&page)
}
}

KeyEvent(key, state, modifiers) => {
@@ -1081,78 +1088,6 @@ impl ScriptTask {
self.force_reflow(&*page);
}
}


fn handle_mouse_move_event(&self, pipeline_id: PipelineId, point: Point2D<f32>) {
let page = get_page(&*self.page.borrow(), pipeline_id);
let mut needs_reflow = false;

// Build a list of elements that are currently under the mouse.
let mouse_over_addresses = page.get_nodes_under_mouse(&point);
let mouse_over_targets: Vec<JS<Node>> = mouse_over_addresses.iter()
.filter_map(|node_address| {
let node = node::from_untrusted_node_address(self.js_runtime.ptr, *node_address);
node.root().r().inclusive_ancestors().find(|node| node.is_element()).map(JS::from_rooted)
}).collect();

// Remove hover from any elements in the previous list that are no longer
// under the mouse.
let prev_mouse_over_targets = &mut *self.mouse_over_targets.borrow_mut();
for target in prev_mouse_over_targets.iter() {
if !mouse_over_targets.contains(target) {
target.root().r().set_hover_state(false);
needs_reflow = true;
}
}

// Set hover state for any elements in the current mouse over list.
// Check if any of them changed state to determine whether to
// force a reflow below.
for target in mouse_over_targets.iter() {
let target = target.root();
let target_ref = target.r();
if !target_ref.get_hover_state() {
target_ref.set_hover_state(true);
needs_reflow = true;
}
}

// Send mousemove event to topmost target
if mouse_over_addresses.len() > 0 {
let top_most_node =
node::from_untrusted_node_address(self.js_runtime.ptr, mouse_over_addresses[0]).root();

if let Some(ref frame) = *page.frame() {
let window = frame.window.root();

let x = point.x.to_i32().unwrap_or(0);
let y = point.y.to_i32().unwrap_or(0);

let mouse_event = MouseEvent::new(window.r(),
"mousemove".to_owned(),
true,
true,
Some(window.r()),
0i32,
x, y, x, y,
false, false, false, false,
0i16,
None).root();

let event: JSRef<Event> = EventCast::from_ref(mouse_event.r());
let target: JSRef<EventTarget> = EventTargetCast::from_ref(top_most_node.r());
event.fire(target);
}
}

// Store the current mouse over targets for next frame
*prev_mouse_over_targets = mouse_over_targets;

// Reflow if hover state changed
if needs_reflow {
self.force_reflow(&*page);
}
}
}

/// Shuts down layout for the given page tree.
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.