diff options
author | Rizky Luthfianto <mrluthfianto@gmail.com> | 2016-04-03 21:44:01 +0700 |
---|---|---|
committer | Rizky Luthfianto <mrluthfianto@gmail.com> | 2016-04-03 21:44:01 +0700 |
commit | 07584b9f29bf99362b74c75ea4291e3438768291 (patch) | |
tree | d1939f9ab7e6766249e76e8df9b6690206cc11dc /components/script | |
parent | 88d29e537cb3e92cc39804eabca7cb347c1417e9 (diff) | |
download | servo-07584b9f29bf99362b74c75ea4291e3438768291.tar.gz servo-07584b9f29bf99362b74c75ea4291e3438768291.zip |
Implement Document#elementsFromPoint
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/document.rs | 42 | ||||
-rw-r--r-- | components/script/dom/webidls/Document.webidl | 1 | ||||
-rw-r--r-- | components/script/layout_interface.rs | 2 |
3 files changed, 45 insertions, 0 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index eb7e0da8a1b..a708e9b6cc6 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -94,6 +94,7 @@ use net_traits::response::HttpsState; use net_traits::{AsyncResponseTarget, PendingAsyncLoad}; use num::ToPrimitive; use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable, ScriptChan}; +use script_traits::UntrustedNodeAddress; use script_traits::{AnimationState, MouseButton, MouseEventType, MozBrowserEvent}; use script_traits::{ScriptMsg as ConstellationMsg, ScriptToCompositorMsg}; use script_traits::{TouchEventType, TouchId}; @@ -1480,6 +1481,12 @@ impl Document { self.browsing_context.is_none() || !url_has_network_scheme(&self.url) } + + pub fn nodes_from_point(&self, page_point: &Point2D<f32>) -> Vec<UntrustedNodeAddress> { + assert!(self.GetDocumentElement().is_some()); + + self.window.layout().nodes_from_point(*page_point) + } } #[derive(PartialEq, HeapSizeOf)] @@ -2601,6 +2608,40 @@ impl DocumentMethods for Document { None => self.GetDocumentElement() } } + + #[allow(unsafe_code)] + // https://drafts.csswg.org/cssom-view/#dom-document-elementsfrompoint + fn ElementsFromPoint(&self, x: Finite<f64>, y: Finite<f64>) -> Vec<Root<Element>> { + let x = *x as f32; + let y = *y as f32; + let point = &Point2D { x: x, y: y }; + let window = window_from_node(self); + let viewport = window.window_size().unwrap().visible_viewport; + + // Step 2 + if x < 0.0 || y < 0.0 || x > viewport.width.get() || y > viewport.height.get() { + return vec!(); + } + + let js_runtime = unsafe { JS_GetRuntime(window.get_cx()) }; + + // Step 1 and Step 3 + let mut elements: Vec<Root<Element>> = self.nodes_from_point(point).iter() + .flat_map(|&untrusted_node_address| { + let node = node::from_untrusted_node_address(js_runtime, untrusted_node_address); + Root::downcast::<Element>(node) + }).collect(); + + // Step 4 + if let Some(root_element) = self.GetDocumentElement() { + if elements.last() != Some(&root_element) { + elements.push(root_element); + } + } + + // Step 5 + elements + } } fn is_scheme_host_port_tuple(url: &Url) -> bool { @@ -2672,3 +2713,4 @@ pub enum FocusEventType { Focus, // Element gained focus. Doesn't bubble. Blur, // Element lost focus. Doesn't bubble. } + diff --git a/components/script/dom/webidls/Document.webidl b/components/script/dom/webidls/Document.webidl index 845037e430c..7ca1dec527f 100644 --- a/components/script/dom/webidls/Document.webidl +++ b/components/script/dom/webidls/Document.webidl @@ -184,6 +184,7 @@ partial interface Document { // https://drafts.csswg.org/cssom-view/#dom-document-elementfrompoint partial interface Document { Element? elementFromPoint(double x, double y); + sequence<Element> elementsFromPoint(double x, double y); }; // https://drafts.csswg.org/cssom/#extensions-to-the-document-interface diff --git a/components/script/layout_interface.rs b/components/script/layout_interface.rs index 0d063f47bc1..07d8ac47edc 100644 --- a/components/script/layout_interface.rs +++ b/components/script/layout_interface.rs @@ -113,6 +113,8 @@ pub trait LayoutRPC { fn offset_parent(&self) -> OffsetParentResponse; /// Query layout for the resolve values of the margin properties for an element. fn margin_style(&self) -> MarginStyleResponse; + + fn nodes_from_point(&self, point: Point2D<f32>) -> Vec<UntrustedNodeAddress>; } #[derive(Clone)] |