aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/script_task.rs
diff options
context:
space:
mode:
authorHyunJune Kim <hyunjune.kim@samsung.com>2014-02-05 18:01:13 +0900
committerHyunJune Kim <hyunjune.kim@samsung.com>2014-02-10 11:16:07 +0900
commitc8d503898a6f53126c6ead740fcfa880b9059273 (patch)
treef48a177a76edc65d89d7fdaafbaa6da1401336fe /src/components/script/script_task.rs
parentd2f8b593a9a61e0bd4984f4c1dabad4239657d11 (diff)
downloadservo-c8d503898a6f53126c6ead740fcfa880b9059273.tar.gz
servo-c8d503898a6f53126c6ead740fcfa880b9059273.zip
This is implement Hover Event. If over element, currently full reflow. after PR, will make partial reflow.
Diffstat (limited to 'src/components/script/script_task.rs')
-rw-r--r--src/components/script/script_task.rs77
1 files changed, 74 insertions, 3 deletions
diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs
index e7f00045582..17c60cd45bf 100644
--- a/src/components/script/script_task.rs
+++ b/src/components/script/script_task.rs
@@ -9,7 +9,7 @@ use dom::bindings::codegen::RegisterBindings;
use dom::bindings::utils::{Reflectable, GlobalStaticData};
use dom::document::AbstractDocument;
use dom::element::Element;
-use dom::event::{Event_, ResizeEvent, ReflowEvent, ClickEvent, MouseDownEvent, MouseUpEvent, MouseMoveEvent};
+use dom::event::{Event_, ResizeEvent, ReflowEvent, ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent};
use dom::event::Event;
use dom::eventtarget::AbstractEventTarget;
use dom::htmldocument::HTMLDocument;
@@ -20,7 +20,7 @@ use html::hubbub_html_parser::{HtmlDiscoveredStyle, HtmlDiscoveredIFrame, HtmlDi
use html::hubbub_html_parser;
use layout_interface::{AddStylesheetMsg, DocumentDamage};
use layout_interface::{ContentBoxQuery, ContentBoxResponse};
-use layout_interface::{DocumentDamageLevel, HitTestQuery, HitTestResponse, LayoutQuery};
+use layout_interface::{DocumentDamageLevel, HitTestQuery, HitTestResponse, LayoutQuery, MouseOverQuery, MouseOverResponse};
use layout_interface::{LayoutChan, MatchSelectorsDocumentDamage, QueryMsg};
use layout_interface::{Reflow, ReflowDocumentDamage, ReflowForDisplay, ReflowGoal, ReflowMsg};
use layout_interface::ContentChangedDocumentDamage;
@@ -405,6 +405,8 @@ pub struct ScriptTask {
/// The JavaScript runtime.
js_runtime: js::rust::rt,
+
+ mouse_over_targets:Option<~[AbstractNode]>
}
/// Returns the relevant page from the associated JS Context.
@@ -440,6 +442,7 @@ impl ScriptTask {
compositor: compositor,
js_runtime: js_runtime,
+ mouse_over_targets:None
};
script_task
@@ -882,7 +885,75 @@ impl ScriptTask {
}
MouseDownEvent(..) => {}
MouseUpEvent(..) => {}
- MouseMoveEvent(point) => {}
+ MouseMoveEvent(point) => {
+ let document = page.frame.expect("root frame is None").document;
+ let root = document.document().GetDocumentElement();
+ if root.is_none() {
+ return;
+ }
+ let (port, chan) = Chan::new();
+ match page.query_layout(MouseOverQuery(root.unwrap(), point, chan), port) {
+ Ok(MouseOverResponse(node_address)) => {
+
+ let mut target_list:~[AbstractNode] = ~[];
+ let mut target_compare = false;
+
+ match self.mouse_over_targets {
+ Some(ref mut mouse_over_targets) => {
+ for node in mouse_over_targets.iter() {
+ node.set_hover_state(false);
+ }
+ }
+ None => {}
+ }
+
+ for node_address in node_address.iter() {
+ let mut node = AbstractNode::from_untrusted_node_address(self.js_runtime
+ .ptr,
+ *node_address);
+ // Traverse node generations until a node that is an element is
+ // found.
+ while !node.is_element() {
+ match node.parent_node() {
+ Some(parent) => node = parent,
+ None => break,
+ }
+ }
+
+ if node.is_element() {
+ node.set_hover_state(true);
+
+ match self.mouse_over_targets {
+ Some(ref mouse_over_targets) => {
+ if !target_compare {
+ target_compare = !mouse_over_targets.contains(&node);
+ }
+ }
+ None => {}
+ }
+ target_list.push(node);
+ }
+ }
+ match self.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 self.mouse_over_targets.is_some() {
+ page.damage(MatchSelectorsDocumentDamage);
+ page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor);
+ }
+ self.mouse_over_targets = Some(target_list);
+ }
+ },
+ Err(()) => {},
+ }
+ }
}
}