diff options
author | Fernando Jiménez Moreno <ferjmoreno@gmail.com> | 2019-01-18 18:22:09 +0100 |
---|---|---|
committer | Fernando Jiménez Moreno <ferjmoreno@gmail.com> | 2019-04-26 10:17:44 +0200 |
commit | cbcf21c2489521fbed29681ee59fbcdd90db2d80 (patch) | |
tree | dd1b74cf4191fff0810c872c2f6a852a4d7a93a9 /components/script/dom/macros.rs | |
parent | 9b2018779347dcd404b955e3773dfed3c3b45c92 (diff) | |
download | servo-cbcf21c2489521fbed29681ee59fbcdd90db2d80.tar.gz servo-cbcf21c2489521fbed29681ee59fbcdd90db2d80.zip |
DocumentOrShadowRoot mixin
Diffstat (limited to 'components/script/dom/macros.rs')
-rw-r--r-- | components/script/dom/macros.rs | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs index a566fee4fb6..94a0779732c 100644 --- a/components/script/dom/macros.rs +++ b/components/script/dom/macros.rs @@ -632,3 +632,105 @@ macro_rules! handle_potential_webgl_error { handle_potential_webgl_error!($context, $call, ()); }; } + +macro_rules! impl_document_or_shadow_root { + () => ( + #[allow(unsafe_code)] + // https://drafts.csswg.org/cssom-view/#dom-document-elementfrompoint + fn ElementFromPoint(&self, x: Finite<f64>, y: Finite<f64>) -> Option<DomRoot<Element>> { + let x = *x as f32; + let y = *y as f32; + let point = &Point2D::new(x, y); + let window = window_from_node(self); + let viewport = window.window_size().initial_viewport; + + if self.browsing_context().is_none() { + return None; + } + + if x < 0.0 || y < 0.0 || x > viewport.width || y > viewport.height { + return None; + } + + match self + .nodes_from_point(point, NodesFromPointQueryType::Topmost) + .first() + { + Some(address) => { + let js_runtime = unsafe { JS_GetRuntime(window.get_cx()) }; + let node = unsafe { node::from_untrusted_node_address(js_runtime, *address) }; + let parent_node = node.GetParentNode().unwrap(); + let element_ref = node + .downcast::<Element>() + .unwrap_or_else(|| parent_node.downcast::<Element>().unwrap()); + + Some(DomRoot::from_ref(element_ref)) + }, + 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<DomRoot<Element>> { + let x = *x as f32; + let y = *y as f32; + let point = &Point2D::new(x, y); + let window = window_from_node(self); + let viewport = window.window_size().initial_viewport; + + if self.browsing_context().is_none() { + return vec![]; + } + + // Step 2 + if x < 0.0 || y < 0.0 || x > viewport.width || y > viewport.height { + return vec![]; + } + + let js_runtime = unsafe { JS_GetRuntime(window.get_cx()) }; + + // Step 1 and Step 3 + let nodes = self.nodes_from_point(point, NodesFromPointQueryType::All); + let mut elements: Vec<DomRoot<Element>> = nodes + .iter() + .flat_map(|&untrusted_node_address| { + let node = unsafe { + node::from_untrusted_node_address(js_runtime, untrusted_node_address) + }; + DomRoot::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 + } + + // https://html.spec.whatwg.org/multipage/#dom-document-activeelement + fn GetActiveElement(&self) -> Option<DomRoot<Element>> { + // TODO: Step 2. + + match self.get_focused_element() { + Some(element) => Some(element), // Step 3. and 4. + None => match self.GetBody() { + // Step 5. + Some(body) => Some(DomRoot::upcast(body)), + None => self.GetDocumentElement(), + }, + } + } + + // https://drafts.csswg.org/cssom/#dom-document-stylesheets + fn StyleSheets(&self) -> DomRoot<StyleSheetList> { + self.stylesheet_list + .or_init(|| StyleSheetList::new(&self.window, Dom::from_ref(&self))) + } + ) +} |