diff --git a/components/layout/query.rs b/components/layout/query.rs index 60d1719e13a..7a795e387fe 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -364,24 +364,24 @@ impl FragmentBorderBoxIterator for MarginRetrievingFragmentBorderBoxIterator { } } -pub fn process_content_box_request( - requested_node: N, +pub fn process_content_box_request( + requested_node: OpaqueNode, layout_root: &mut dyn Flow, ) -> Option> { // FIXME(pcwalton): This has not been updated to handle the stacking context relative // stuff. So the position is wrong in most cases. - let mut iterator = UnioningFragmentBorderBoxIterator::new(requested_node.opaque()); + let mut iterator = UnioningFragmentBorderBoxIterator::new(requested_node); sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator); iterator.rect } -pub fn process_content_boxes_request( - requested_node: N, +pub fn process_content_boxes_request( + requested_node: OpaqueNode, layout_root: &mut dyn Flow, ) -> Vec> { // FIXME(pcwalton): This has not been updated to handle the stacking context relative // stuff. So the position is wrong in most cases. - let mut iterator = CollectingFragmentBorderBoxIterator::new(requested_node.opaque()); + let mut iterator = CollectingFragmentBorderBoxIterator::new(requested_node); sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator); iterator.rects } @@ -669,11 +669,11 @@ impl FragmentBorderBoxIterator for ParentOffsetBorderBoxIterator { } } -pub fn process_node_geometry_request( - requested_node: N, +pub fn process_node_geometry_request( + requested_node: OpaqueNode, layout_root: &mut dyn Flow, ) -> Rect { - let mut iterator = FragmentLocatingFragmentIterator::new(requested_node.opaque()); + let mut iterator = FragmentLocatingFragmentIterator::new(requested_node); sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator); iterator.client_rect } @@ -687,11 +687,11 @@ pub fn process_node_scroll_id_request( } /// https://drafts.csswg.org/cssom-view/#scrolling-area -pub fn process_node_scroll_area_request( - requested_node: N, +pub fn process_node_scroll_area_request( + requested_node: OpaqueNode, layout_root: &mut dyn Flow, ) -> Rect { - let mut iterator = UnioningFragmentScrollAreaIterator::new(requested_node.opaque()); + let mut iterator = UnioningFragmentScrollAreaIterator::new(requested_node); sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator); match iterator.overflow_direction { OverflowDirection::RightAndDown => { @@ -932,11 +932,11 @@ where } } -pub fn process_offset_parent_query( - requested_node: N, +pub fn process_offset_parent_query( + requested_node: OpaqueNode, layout_root: &mut dyn Flow, ) -> OffsetParentResponse { - let mut iterator = ParentOffsetBorderBoxIterator::new(requested_node.opaque()); + let mut iterator = ParentOffsetBorderBoxIterator::new(requested_node); sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator); let node_offset_box = iterator.node_offset_box; diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 190f79d8d05..b60838365de 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -1471,32 +1471,23 @@ impl LayoutThread { match *reflow_goal { ReflowGoal::LayoutQuery(ref querymsg, _) => match querymsg { &QueryMsg::ContentBoxQuery(node) => { - let node = unsafe { ServoLayoutNode::new(&node) }; rw_data.content_box_response = process_content_box_request(node, root_flow); }, &QueryMsg::ContentBoxesQuery(node) => { - let node = unsafe { ServoLayoutNode::new(&node) }; rw_data.content_boxes_response = process_content_boxes_request(node, root_flow); }, &QueryMsg::TextIndexQuery(node, point_in_node) => { - let node = unsafe { ServoLayoutNode::new(&node) }; - let opaque_node = node.opaque(); let point_in_node = Point2D::new( Au::from_f32_px(point_in_node.x), Au::from_f32_px(point_in_node.y), ); - rw_data.text_index_response = TextIndexResponse( - rw_data - .indexable_text - .text_index(opaque_node, point_in_node), - ); + rw_data.text_index_response = + TextIndexResponse(rw_data.indexable_text.text_index(node, point_in_node)); }, &QueryMsg::NodeGeometryQuery(node) => { - let node = unsafe { ServoLayoutNode::new(&node) }; rw_data.client_rect_response = process_node_geometry_request(node, root_flow); }, &QueryMsg::NodeScrollGeometryQuery(node) => { - let node = unsafe { ServoLayoutNode::new(&node) }; rw_data.scroll_area_response = process_node_scroll_area_request(node, root_flow); }, @@ -1511,7 +1502,6 @@ impl LayoutThread { process_resolved_style_request(context, node, pseudo, property, root_flow); }, &QueryMsg::OffsetParentQuery(node) => { - let node = unsafe { ServoLayoutNode::new(&node) }; rw_data.offset_parent_response = process_offset_parent_query(node, root_flow); }, &QueryMsg::StyleQuery(node) => { diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index 50786f8aac9..2712580ea7f 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -403,7 +403,7 @@ impl HTMLElementMethods for HTMLElement { let node = self.upcast::(); let window = window_from_node(self); - let (element, _) = window.offset_parent_query(node.to_trusted_node_address()); + let (element, _) = window.offset_parent_query(node); element } @@ -416,7 +416,7 @@ impl HTMLElementMethods for HTMLElement { let node = self.upcast::(); let window = window_from_node(self); - let (_, rect) = window.offset_parent_query(node.to_trusted_node_address()); + let (_, rect) = window.offset_parent_query(node); rect.origin.y.to_nearest_px() } @@ -429,7 +429,7 @@ impl HTMLElementMethods for HTMLElement { let node = self.upcast::(); let window = window_from_node(self); - let (_, rect) = window.offset_parent_query(node.to_trusted_node_address()); + let (_, rect) = window.offset_parent_query(node); rect.origin.x.to_nearest_px() } @@ -438,7 +438,7 @@ impl HTMLElementMethods for HTMLElement { fn OffsetWidth(&self) -> i32 { let node = self.upcast::(); let window = window_from_node(self); - let (_, rect) = window.offset_parent_query(node.to_trusted_node_address()); + let (_, rect) = window.offset_parent_query(node); rect.size.width.to_nearest_px() } @@ -447,7 +447,7 @@ impl HTMLElementMethods for HTMLElement { fn OffsetHeight(&self) -> i32 { let node = self.upcast::(); let window = window_from_node(self); - let (_, rect) = window.offset_parent_query(node.to_trusted_node_address()); + let (_, rect) = window.offset_parent_query(node); rect.size.height.to_nearest_px() } diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 4541c38038e..c43ea02828b 100755 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -1467,10 +1467,8 @@ impl VirtualMethods for HTMLInputElement { // now. if let Some(point_in_target) = mouse_event.point_in_target() { let window = window_from_node(self); - let TextIndexResponse(index) = window.text_index_query( - self.upcast::().to_trusted_node_address(), - point_in_target, - ); + let TextIndexResponse(index) = + window.text_index_query(self.upcast::(), point_in_target); if let Some(i) = index { self.textinput.borrow_mut().set_edit_point_index(i as usize); // trigger redraw diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 77b7d66cf2d..6d3c7e5381f 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -334,6 +334,10 @@ impl Node { UntrustedNodeAddress(self.reflector().get_jsobject().get() as *const c_void) } + pub fn to_opaque(&self) -> OpaqueNode { + OpaqueNode(self.reflector().get_jsobject().get() as usize) + } + pub fn as_custom_element(&self) -> Option> { self.downcast::().and_then(|element| { if element.get_custom_element_definition().is_some() { @@ -639,7 +643,7 @@ impl Node { /// Returns the rendered bounding content box if the element is rendered, /// and none otherwise. pub fn bounding_content_box(&self) -> Option> { - window_from_node(self).content_box_query(self.to_trusted_node_address()) + window_from_node(self).content_box_query(self) } pub fn bounding_content_box_or_zero(&self) -> Rect { @@ -647,11 +651,11 @@ impl Node { } pub fn content_boxes(&self) -> Vec> { - window_from_node(self).content_boxes_query(self.to_trusted_node_address()) + window_from_node(self).content_boxes_query(self) } pub fn client_rect(&self) -> Rect { - window_from_node(self).client_rect_query(self.to_trusted_node_address()) + window_from_node(self).client_rect_query(self) } // https://drafts.csswg.org/cssom-view/#dom-element-scrollwidth @@ -668,7 +672,7 @@ impl Node { .downcast::() .map_or(false, |e| e.is_the_html_body_element()); - let scroll_area = window.scroll_area_query(self.to_trusted_node_address()); + let scroll_area = window.scroll_area_query(self); match ( document != window.Document(), diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index bcda545a8cb..3f702cbeabd 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -1571,31 +1571,31 @@ impl Window { &*self.layout_rpc } - pub fn content_box_query(&self, content_box_request: TrustedNodeAddress) -> Option> { - if !self.layout_reflow(QueryMsg::ContentBoxQuery(content_box_request)) { + pub fn content_box_query(&self, node: &Node) -> Option> { + if !self.layout_reflow(QueryMsg::ContentBoxQuery(node.to_opaque())) { return None; } let ContentBoxResponse(rect) = self.layout_rpc.content_box(); rect } - pub fn content_boxes_query(&self, content_boxes_request: TrustedNodeAddress) -> Vec> { - if !self.layout_reflow(QueryMsg::ContentBoxesQuery(content_boxes_request)) { + pub fn content_boxes_query(&self, node: &Node) -> Vec> { + if !self.layout_reflow(QueryMsg::ContentBoxesQuery(node.to_opaque())) { return vec![]; } let ContentBoxesResponse(rects) = self.layout_rpc.content_boxes(); rects } - pub fn client_rect_query(&self, node_geometry_request: TrustedNodeAddress) -> Rect { - if !self.layout_reflow(QueryMsg::NodeGeometryQuery(node_geometry_request)) { + pub fn client_rect_query(&self, node: &Node) -> Rect { + if !self.layout_reflow(QueryMsg::NodeGeometryQuery(node.to_opaque())) { return Rect::zero(); } self.layout_rpc.node_geometry().client_rect } - pub fn scroll_area_query(&self, node: TrustedNodeAddress) -> Rect { - if !self.layout_reflow(QueryMsg::NodeScrollGeometryQuery(node)) { + pub fn scroll_area_query(&self, node: &Node) -> Rect { + if !self.layout_reflow(QueryMsg::NodeScrollGeometryQuery(node.to_opaque())) { return Rect::zero(); } self.layout_rpc.node_scroll_area().client_rect @@ -1652,14 +1652,13 @@ impl Window { } #[allow(unsafe_code)] - pub fn offset_parent_query( - &self, - node: TrustedNodeAddress, - ) -> (Option>, Rect) { - if !self.layout_reflow(QueryMsg::OffsetParentQuery(node)) { + pub fn offset_parent_query(&self, node: &Node) -> (Option>, Rect) { + if !self.layout_reflow(QueryMsg::OffsetParentQuery(node.to_opaque())) { return (None, Rect::zero()); } + // FIXME(nox): Layout can reply with a garbage value which doesn't + // actually correspond to an element, that's unsound. let response = self.layout_rpc.offset_parent(); let js_runtime = self.js_runtime.borrow(); let js_runtime = js_runtime.as_ref().unwrap(); @@ -1677,12 +1676,8 @@ impl Window { self.layout_rpc.style().0 } - pub fn text_index_query( - &self, - node: TrustedNodeAddress, - point_in_node: Point2D, - ) -> TextIndexResponse { - if !self.layout_reflow(QueryMsg::TextIndexQuery(node, point_in_node)) { + pub fn text_index_query(&self, node: &Node, point_in_node: Point2D) -> TextIndexResponse { + if !self.layout_reflow(QueryMsg::TextIndexQuery(node.to_opaque(), point_in_node)) { return TextIndexResponse(None); } self.layout_rpc.text_index() diff --git a/components/script_layout_interface/message.rs b/components/script_layout_interface/message.rs index 7600ebe372a..144961cb8f5 100644 --- a/components/script_layout_interface/message.rs +++ b/components/script_layout_interface/message.rs @@ -21,6 +21,7 @@ use servo_atoms::Atom; use servo_url::ServoUrl; use std::sync::Arc; use style::context::QuirksMode; +use style::dom::OpaqueNode; use style::properties::PropertyId; use style::selector_parser::PseudoElement; use style::stylesheets::Stylesheet; @@ -111,16 +112,20 @@ pub enum NodesFromPointQueryType { #[derive(Debug, PartialEq)] pub enum QueryMsg { - ContentBoxQuery(TrustedNodeAddress), - ContentBoxesQuery(TrustedNodeAddress), - NodeScrollIdQuery(TrustedNodeAddress), - NodeGeometryQuery(TrustedNodeAddress), - NodeScrollGeometryQuery(TrustedNodeAddress), - ResolvedStyleQuery(TrustedNodeAddress, Option, PropertyId), - OffsetParentQuery(TrustedNodeAddress), - StyleQuery(TrustedNodeAddress), - TextIndexQuery(TrustedNodeAddress, Point2D), + ContentBoxQuery(OpaqueNode), + ContentBoxesQuery(OpaqueNode), + NodeGeometryQuery(OpaqueNode), + NodeScrollGeometryQuery(OpaqueNode), + OffsetParentQuery(OpaqueNode), + TextIndexQuery(OpaqueNode, Point2D), NodesFromPointQuery(Point2D, NodesFromPointQueryType), + + // FIXME(nox): The following queries use the TrustedNodeAddress to + // access actual DOM nodes, but those values can be constructed from + // garbage values such as `0xdeadbeef as *const _`, this is unsound. + NodeScrollIdQuery(TrustedNodeAddress), + ResolvedStyleQuery(TrustedNodeAddress, Option, PropertyId), + StyleQuery(TrustedNodeAddress), ElementInnerTextQuery(TrustedNodeAddress), }