diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-03-01 03:01:50 +0530 |
---|---|---|
committer | bors-servo <lbergstrom+bors@mozilla.com> | 2016-03-01 03:01:50 +0530 |
commit | 4bcdbe6d56d4d4e2a679ad7e0e27f2caf71f4d22 (patch) | |
tree | 99c2419f3242f8a921ee1bf216c02bfb78628235 /components/script/dom/document.rs | |
parent | 2ba170918109723b45ad3c6671b3028d7bc47048 (diff) | |
parent | 76678bbdae34c13373dc6c104c4f78bfb6000fea (diff) | |
download | servo-4bcdbe6d56d4d4e2a679ad7e0e27f2caf71f4d22.tar.gz servo-4bcdbe6d56d4d4e2a679ad7e0e27f2caf71f4d22.zip |
Auto merge of #8932 - rilut:add-elementfrompoint, r=nox
Implement Document#elementFromPoint
Related to #8666. I haven't implemented elementsFromPoint, because from my past discussion with jdm, [it's not good yet](https://github.com/rilut/servo/commit/dbfa25214b2888dda7527d62b5df1bb61f1ab047#commitcomment-14668959) to implement elementsFromPoint because it may cause GC hazards.
By the way, I also have to include the test for this, right? I've found this [1]. So, is all I have to do is just to put this into `tests/wpt/web-platform-tests/cssom-view/elementFromPoint.html`?
[1] http://test.csswg.org/suites/cssom-view-1_dev/nightly-unstable/html/elementFromPosition.htm
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8932)
<!-- Reviewable:end -->
Diffstat (limited to 'components/script/dom/document.rs')
-rw-r--r-- | components/script/dom/document.rs | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index fb996f7596d..a1e256dede1 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -62,7 +62,7 @@ use dom::keyboardevent::KeyboardEvent; use dom::location::Location; use dom::messageevent::MessageEvent; use dom::mouseevent::MouseEvent; -use dom::node::{self, CloneChildrenFlag, Node, NodeDamage}; +use dom::node::{self, CloneChildrenFlag, Node, NodeDamage, window_from_node}; use dom::nodeiterator::NodeIterator; use dom::nodelist::NodeList; use dom::processinginstruction::ProcessingInstruction; @@ -78,6 +78,7 @@ use dom::window::{ReflowReason, Window}; use euclid::point::Point2D; use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks, QuirksMode}; use ipc_channel::ipc::{self, IpcSender}; +use js::jsapi::JS_GetRuntime; use js::jsapi::{JSContext, JSObject, JSRuntime}; use layout_interface::{HitTestResponse, MouseOverResponse}; use layout_interface::{LayoutChan, Msg, ReflowQueryType}; @@ -2553,6 +2554,35 @@ impl DocumentMethods for Document { // https://html.spec.whatwg.org/multipage/#handler-onreadystatechange event_handler!(readystatechange, GetOnreadystatechange, SetOnreadystatechange); + + #[allow(unsafe_code)] + // https://drafts.csswg.org/cssom-view/#dom-document-elementfrompoint + fn ElementFromPoint(&self, x: Finite<f64>, y: Finite<f64>) -> Option<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; + + if x < 0.0 || y < 0.0 || x > viewport.width.get() || y > viewport.height.get() { + return None; + } + + let js_runtime = unsafe { JS_GetRuntime(window.get_cx()) }; + + match self.hit_test(point) { + Some(untrusted_node_address) => { + let node = node::from_untrusted_node_address(js_runtime, untrusted_node_address); + let parent_node = node.GetParentNode().unwrap(); + let element_ref = node.downcast::<Element>().unwrap_or_else(|| { + parent_node.downcast::<Element>().unwrap() + }); + + Some(Root::from_ref(element_ref)) + }, + None => self.GetDocumentElement() + } + } } fn is_scheme_host_port_tuple(url: &Url) -> bool { |