aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorRizky Luthfianto <mrluthfianto@gmail.com>2016-04-03 21:44:01 +0700
committerRizky Luthfianto <mrluthfianto@gmail.com>2016-04-03 21:44:01 +0700
commit07584b9f29bf99362b74c75ea4291e3438768291 (patch)
treed1939f9ab7e6766249e76e8df9b6690206cc11dc /components/script
parent88d29e537cb3e92cc39804eabca7cb347c1417e9 (diff)
downloadservo-07584b9f29bf99362b74c75ea4291e3438768291.tar.gz
servo-07584b9f29bf99362b74c75ea4291e3438768291.zip
Implement Document#elementsFromPoint
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/document.rs42
-rw-r--r--components/script/dom/webidls/Document.webidl1
-rw-r--r--components/script/layout_interface.rs2
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)]