mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
script/layout: Refactor mouse_over since it now basically uses hit_test
This commit is contained in:
parent
c3786437a3
commit
48dee6413d
3 changed files with 17 additions and 47 deletions
|
@ -16,7 +16,7 @@ use layout_thread::LayoutThreadData;
|
||||||
use msg::constellation_msg::ConstellationChan;
|
use msg::constellation_msg::ConstellationChan;
|
||||||
use opaque_node::OpaqueNodeMethods;
|
use opaque_node::OpaqueNodeMethods;
|
||||||
use script::layout_interface::{ContentBoxResponse, ContentBoxesResponse, NodeGeometryResponse};
|
use script::layout_interface::{ContentBoxResponse, ContentBoxesResponse, NodeGeometryResponse};
|
||||||
use script::layout_interface::{HitTestResponse, LayoutRPC, MouseOverResponse, OffsetParentResponse};
|
use script::layout_interface::{HitTestResponse, LayoutRPC, OffsetParentResponse};
|
||||||
use script::layout_interface::{ResolvedStyleResponse, ScriptLayoutChan, MarginStyleResponse};
|
use script::layout_interface::{ResolvedStyleResponse, ScriptLayoutChan, MarginStyleResponse};
|
||||||
use script_traits::LayoutMsg as ConstellationMsg;
|
use script_traits::LayoutMsg as ConstellationMsg;
|
||||||
use sequential;
|
use sequential;
|
||||||
|
@ -67,48 +67,29 @@ impl LayoutRPC for LayoutRPCImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Requests the node containing the point of interest.
|
/// Requests the node containing the point of interest.
|
||||||
fn hit_test(&self, point: Point2D<f32>) -> Result<HitTestResponse, ()> {
|
fn hit_test(&self, point: Point2D<f32>, update_cursor: bool) -> Result<HitTestResponse, ()> {
|
||||||
let point = Point2D::new(Au::from_f32_px(point.x), Au::from_f32_px(point.y));
|
let point = Point2D::new(Au::from_f32_px(point.x), Au::from_f32_px(point.y));
|
||||||
let &LayoutRPCImpl(ref rw_data) = self;
|
let &LayoutRPCImpl(ref rw_data) = self;
|
||||||
let rw_data = rw_data.lock().unwrap();
|
let rw_data = rw_data.lock().unwrap();
|
||||||
let result = match rw_data.display_list {
|
let display_list = rw_data.display_list.as_ref().expect("Tried to hit test without a DisplayList!");
|
||||||
None => panic!("Tried to hit test without a DisplayList"),
|
|
||||||
Some(ref display_list) => display_list.hit_test(point),
|
|
||||||
};
|
|
||||||
|
|
||||||
if result.is_empty() {
|
let result = display_list.hit_test(point);
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(HitTestResponse(result[0].node.to_untrusted_node_address()))
|
if update_cursor {
|
||||||
}
|
|
||||||
|
|
||||||
fn mouse_over(&self, point: Point2D<f32>) -> Result<MouseOverResponse, ()> {
|
|
||||||
let point = Point2D::new(Au::from_f32_px(point.x), Au::from_f32_px(point.y));
|
|
||||||
let mouse_over_list = {
|
|
||||||
let &LayoutRPCImpl(ref rw_data) = self;
|
|
||||||
let rw_data = rw_data.lock().unwrap();
|
|
||||||
let result = match rw_data.display_list {
|
|
||||||
None => panic!("Tried to hit test without a DisplayList"),
|
|
||||||
Some(ref display_list) => display_list.hit_test(point),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Compute the new cursor.
|
|
||||||
let cursor = if !result.is_empty() {
|
let cursor = if !result.is_empty() {
|
||||||
result[0].pointing.unwrap()
|
result[0].pointing.unwrap()
|
||||||
} else {
|
} else {
|
||||||
Cursor::DefaultCursor
|
Cursor::DefaultCursor
|
||||||
};
|
};
|
||||||
|
|
||||||
let ConstellationChan(ref constellation_chan) = rw_data.constellation_chan;
|
let ConstellationChan(ref constellation_chan) = rw_data.constellation_chan;
|
||||||
constellation_chan.send(ConstellationMsg::SetCursor(cursor)).unwrap();
|
constellation_chan.send(ConstellationMsg::SetCursor(cursor)).unwrap();
|
||||||
result
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if mouse_over_list.is_empty() {
|
if !result.is_empty() {
|
||||||
Err(())
|
Ok(HitTestResponse(result[0].node.to_untrusted_node_address()))
|
||||||
} else {
|
} else {
|
||||||
let response = mouse_over_list[0].node.to_untrusted_node_address();
|
Err(())
|
||||||
Ok(MouseOverResponse(response))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks, QuirksMode};
|
||||||
use ipc_channel::ipc::{self, IpcSender};
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
use js::jsapi::JS_GetRuntime;
|
use js::jsapi::JS_GetRuntime;
|
||||||
use js::jsapi::{JSContext, JSObject, JSRuntime};
|
use js::jsapi::{JSContext, JSObject, JSRuntime};
|
||||||
use layout_interface::{HitTestResponse, MouseOverResponse};
|
use layout_interface::HitTestResponse;
|
||||||
use layout_interface::{LayoutChan, Msg, ReflowQueryType};
|
use layout_interface::{LayoutChan, Msg, ReflowQueryType};
|
||||||
use msg::constellation_msg::{ALT, CONTROL, SHIFT, SUPER};
|
use msg::constellation_msg::{ALT, CONTROL, SHIFT, SUPER};
|
||||||
use msg::constellation_msg::{ConstellationChan, Key, KeyModifiers, KeyState};
|
use msg::constellation_msg::{ConstellationChan, Key, KeyModifiers, KeyState};
|
||||||
|
@ -563,9 +563,9 @@ impl Document {
|
||||||
.map(Root::upcast)
|
.map(Root::upcast)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hit_test(&self, page_point: &Point2D<f32>) -> Option<UntrustedNodeAddress> {
|
pub fn hit_test(&self, page_point: &Point2D<f32>, update_cursor: bool) -> Option<UntrustedNodeAddress> {
|
||||||
assert!(self.GetDocumentElement().is_some());
|
assert!(self.GetDocumentElement().is_some());
|
||||||
match self.window.layout().hit_test(*page_point) {
|
match self.window.layout().hit_test(*page_point, update_cursor) {
|
||||||
Ok(HitTestResponse(node_address)) => Some(node_address),
|
Ok(HitTestResponse(node_address)) => Some(node_address),
|
||||||
Err(()) => {
|
Err(()) => {
|
||||||
debug!("layout query error");
|
debug!("layout query error");
|
||||||
|
@ -574,14 +574,6 @@ impl Document {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_node_under_mouse(&self, page_point: &Point2D<f32>) -> Option<UntrustedNodeAddress> {
|
|
||||||
assert!(self.GetDocumentElement().is_some());
|
|
||||||
match self.window.layout().mouse_over(*page_point) {
|
|
||||||
Ok(MouseOverResponse(node_address)) => Some(node_address),
|
|
||||||
Err(()) => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#current-document-readiness
|
// https://html.spec.whatwg.org/multipage/#current-document-readiness
|
||||||
pub fn set_ready_state(&self, state: DocumentReadyState) {
|
pub fn set_ready_state(&self, state: DocumentReadyState) {
|
||||||
match state {
|
match state {
|
||||||
|
@ -693,7 +685,7 @@ impl Document {
|
||||||
|
|
||||||
let page_point = Point2D::new(client_point.x + self.window.PageXOffset() as f32,
|
let page_point = Point2D::new(client_point.x + self.window.PageXOffset() as f32,
|
||||||
client_point.y + self.window.PageYOffset() as f32);
|
client_point.y + self.window.PageYOffset() as f32);
|
||||||
let node = match self.hit_test(&page_point) {
|
let node = match self.hit_test(&page_point, false) {
|
||||||
Some(node_address) => {
|
Some(node_address) => {
|
||||||
debug!("node address is {:?}", node_address);
|
debug!("node address is {:?}", node_address);
|
||||||
node::from_untrusted_node_address(js_runtime, node_address)
|
node::from_untrusted_node_address(js_runtime, node_address)
|
||||||
|
@ -811,7 +803,7 @@ impl Document {
|
||||||
let mouse_over_address = client_point.as_ref().map(|client_point| {
|
let mouse_over_address = client_point.as_ref().map(|client_point| {
|
||||||
let page_point = Point2D::new(client_point.x + self.window.PageXOffset() as f32,
|
let page_point = Point2D::new(client_point.x + self.window.PageXOffset() as f32,
|
||||||
client_point.y + self.window.PageYOffset() as f32);
|
client_point.y + self.window.PageYOffset() as f32);
|
||||||
self.get_node_under_mouse(&page_point)
|
self.hit_test(&page_point, true)
|
||||||
}).unwrap_or(None);
|
}).unwrap_or(None);
|
||||||
|
|
||||||
let mut mouse_over_targets = RootedVec::<JS<Element>>::new();
|
let mut mouse_over_targets = RootedVec::<JS<Element>>::new();
|
||||||
|
@ -918,7 +910,7 @@ impl Document {
|
||||||
TouchEventType::Cancel => "touchcancel",
|
TouchEventType::Cancel => "touchcancel",
|
||||||
};
|
};
|
||||||
|
|
||||||
let node = match self.hit_test(&point) {
|
let node = match self.hit_test(&point, false) {
|
||||||
Some(node_address) => node::from_untrusted_node_address(js_runtime, node_address),
|
Some(node_address) => node::from_untrusted_node_address(js_runtime, node_address),
|
||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
|
@ -2585,7 +2577,7 @@ impl DocumentMethods for Document {
|
||||||
|
|
||||||
let js_runtime = unsafe { JS_GetRuntime(window.get_cx()) };
|
let js_runtime = unsafe { JS_GetRuntime(window.get_cx()) };
|
||||||
|
|
||||||
match self.hit_test(point) {
|
match self.hit_test(point, false) {
|
||||||
Some(untrusted_node_address) => {
|
Some(untrusted_node_address) => {
|
||||||
let node = node::from_untrusted_node_address(js_runtime, untrusted_node_address);
|
let node = node::from_untrusted_node_address(js_runtime, untrusted_node_address);
|
||||||
let parent_node = node.GetParentNode().unwrap();
|
let parent_node = node.GetParentNode().unwrap();
|
||||||
|
|
|
@ -105,9 +105,7 @@ pub trait LayoutRPC {
|
||||||
/// Requests the geometry of this node. Used by APIs such as `clientTop`.
|
/// Requests the geometry of this node. Used by APIs such as `clientTop`.
|
||||||
fn node_geometry(&self) -> NodeGeometryResponse;
|
fn node_geometry(&self) -> NodeGeometryResponse;
|
||||||
/// Requests the node containing the point of interest
|
/// Requests the node containing the point of interest
|
||||||
fn hit_test(&self, point: Point2D<f32>) -> Result<HitTestResponse, ()>;
|
fn hit_test(&self, point: Point2D<f32>, update_cursor: bool) -> Result<HitTestResponse, ()>;
|
||||||
/// Query layout for the topmost node under the mouse.
|
|
||||||
fn mouse_over(&self, point: Point2D<f32>) -> Result<MouseOverResponse, ()>;
|
|
||||||
/// Query layout for the resolved value of a given CSS property
|
/// Query layout for the resolved value of a given CSS property
|
||||||
fn resolved_style(&self) -> ResolvedStyleResponse;
|
fn resolved_style(&self) -> ResolvedStyleResponse;
|
||||||
fn offset_parent(&self) -> OffsetParentResponse;
|
fn offset_parent(&self) -> OffsetParentResponse;
|
||||||
|
@ -140,7 +138,6 @@ pub struct NodeGeometryResponse {
|
||||||
pub client_rect: Rect<i32>,
|
pub client_rect: Rect<i32>,
|
||||||
}
|
}
|
||||||
pub struct HitTestResponse(pub UntrustedNodeAddress);
|
pub struct HitTestResponse(pub UntrustedNodeAddress);
|
||||||
pub struct MouseOverResponse(pub UntrustedNodeAddress);
|
|
||||||
pub struct ResolvedStyleResponse(pub Option<String>);
|
pub struct ResolvedStyleResponse(pub Option<String>);
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue