aboutsummaryrefslogtreecommitdiffstats
path: root/components/shared/compositing/tests
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2025-04-06 19:34:18 +0200
committerGitHub <noreply@github.com>2025-04-06 17:34:18 +0000
commit0caa271176d4670eb06bedd05cdffb24df08fc4f (patch)
tree9a0c3431dcf7ac31cfbdc1f801c9f4ef3dda6ae7 /components/shared/compositing/tests
parente74a042efdf01ab2ff32e82e203bd1d954b599bd (diff)
downloadservo-0caa271176d4670eb06bedd05cdffb24df08fc4f.tar.gz
servo-0caa271176d4670eb06bedd05cdffb24df08fc4f.zip
`compositing`: Combine `webrender_traits` and `compositing_traits` (#36372)
These two traits both exposed different parts of the compositing API, but now that the compositor doesn't depend directly on `script` any longer and the `script_traits` crate has been split into the `constellation_traits` crate, this can be finally be cleaned up without causing circular dependencies. In addition, some unit tests for the `IOPCompositor`'s scroll node tree are also moved into `compositing_traits` as well. Testing: This just combines two crates, so no new tests are necessary. Fixes: #35984. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Diffstat (limited to 'components/shared/compositing/tests')
-rw-r--r--components/shared/compositing/tests/compositor.rs188
1 files changed, 188 insertions, 0 deletions
diff --git a/components/shared/compositing/tests/compositor.rs b/components/shared/compositing/tests/compositor.rs
new file mode 100644
index 00000000000..4d2ecfd99c9
--- /dev/null
+++ b/components/shared/compositing/tests/compositor.rs
@@ -0,0 +1,188 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+use base::id::ScrollTreeNodeId;
+use compositing_traits::display_list::{
+ AxesScrollSensitivity, ScrollSensitivity, ScrollTree, ScrollableNodeInfo,
+};
+use euclid::Size2D;
+use webrender_api::units::LayoutVector2D;
+use webrender_api::{ExternalScrollId, PipelineId, ScrollLocation, SpatialId};
+
+fn add_mock_scroll_node(tree: &mut ScrollTree) -> ScrollTreeNodeId {
+ let pipeline_id = PipelineId(0, 0);
+ let num_nodes = tree.nodes.len();
+ let parent = if num_nodes > 0 {
+ Some(ScrollTreeNodeId {
+ index: num_nodes - 1,
+ spatial_id: SpatialId::new(num_nodes - 1, pipeline_id),
+ })
+ } else {
+ None
+ };
+
+ tree.add_scroll_tree_node(
+ parent.as_ref(),
+ SpatialId::new(num_nodes, pipeline_id),
+ Some(ScrollableNodeInfo {
+ external_id: ExternalScrollId(num_nodes as u64, pipeline_id),
+ scrollable_size: Size2D::new(100.0, 100.0),
+ scroll_sensitivity: AxesScrollSensitivity {
+ x: ScrollSensitivity::ScriptAndInputEvents,
+ y: ScrollSensitivity::ScriptAndInputEvents,
+ },
+ offset: LayoutVector2D::zero(),
+ }),
+ )
+}
+
+#[test]
+fn test_scroll_tree_simple_scroll() {
+ let mut scroll_tree = ScrollTree::default();
+ let pipeline_id = PipelineId(0, 0);
+ let id = add_mock_scroll_node(&mut scroll_tree);
+
+ let (scrolled_id, offset) = scroll_tree
+ .scroll_node_or_ancestor(
+ &id,
+ ScrollLocation::Delta(LayoutVector2D::new(-20.0, -40.0)),
+ )
+ .unwrap();
+ let expected_offset = LayoutVector2D::new(-20.0, -40.0);
+ assert_eq!(scrolled_id, ExternalScrollId(0, pipeline_id));
+ assert_eq!(offset, expected_offset);
+ assert_eq!(scroll_tree.get_node(&id).offset(), Some(expected_offset));
+
+ let (scrolled_id, offset) = scroll_tree
+ .scroll_node_or_ancestor(&id, ScrollLocation::Delta(LayoutVector2D::new(20.0, 40.0)))
+ .unwrap();
+ let expected_offset = LayoutVector2D::new(0.0, 0.0);
+ assert_eq!(scrolled_id, ExternalScrollId(0, pipeline_id));
+ assert_eq!(offset, expected_offset);
+ assert_eq!(scroll_tree.get_node(&id).offset(), Some(expected_offset));
+
+ // Scroll offsets must be negative.
+ let result = scroll_tree
+ .scroll_node_or_ancestor(&id, ScrollLocation::Delta(LayoutVector2D::new(20.0, 40.0)));
+ assert!(result.is_none());
+ assert_eq!(
+ scroll_tree.get_node(&id).offset(),
+ Some(LayoutVector2D::new(0.0, 0.0))
+ );
+}
+
+#[test]
+fn test_scroll_tree_simple_scroll_chaining() {
+ let mut scroll_tree = ScrollTree::default();
+
+ let pipeline_id = PipelineId(0, 0);
+ let parent_id = add_mock_scroll_node(&mut scroll_tree);
+ let unscrollable_child_id =
+ scroll_tree.add_scroll_tree_node(Some(&parent_id), SpatialId::new(1, pipeline_id), None);
+
+ let (scrolled_id, offset) = scroll_tree
+ .scroll_node_or_ancestor(
+ &unscrollable_child_id,
+ ScrollLocation::Delta(LayoutVector2D::new(-20.0, -40.0)),
+ )
+ .unwrap();
+ let expected_offset = LayoutVector2D::new(-20.0, -40.0);
+ assert_eq!(scrolled_id, ExternalScrollId(0, pipeline_id));
+ assert_eq!(offset, expected_offset);
+ assert_eq!(
+ scroll_tree.get_node(&parent_id).offset(),
+ Some(expected_offset)
+ );
+
+ let (scrolled_id, offset) = scroll_tree
+ .scroll_node_or_ancestor(
+ &unscrollable_child_id,
+ ScrollLocation::Delta(LayoutVector2D::new(-10.0, -15.0)),
+ )
+ .unwrap();
+ let expected_offset = LayoutVector2D::new(-30.0, -55.0);
+ assert_eq!(scrolled_id, ExternalScrollId(0, pipeline_id));
+ assert_eq!(offset, expected_offset);
+ assert_eq!(
+ scroll_tree.get_node(&parent_id).offset(),
+ Some(expected_offset)
+ );
+ assert_eq!(scroll_tree.get_node(&unscrollable_child_id).offset(), None);
+}
+
+#[test]
+fn test_scroll_tree_chain_when_at_extent() {
+ let mut scroll_tree = ScrollTree::default();
+
+ let pipeline_id = PipelineId(0, 0);
+ let parent_id = add_mock_scroll_node(&mut scroll_tree);
+ let child_id = add_mock_scroll_node(&mut scroll_tree);
+
+ let (scrolled_id, offset) = scroll_tree
+ .scroll_node_or_ancestor(&child_id, ScrollLocation::End)
+ .unwrap();
+
+ let expected_offset = LayoutVector2D::new(0.0, -100.0);
+ assert_eq!(scrolled_id, ExternalScrollId(1, pipeline_id));
+ assert_eq!(offset, expected_offset);
+ assert_eq!(
+ scroll_tree.get_node(&child_id).offset(),
+ Some(expected_offset)
+ );
+
+ // The parent will have scrolled because the child is already at the extent
+ // of its scroll area in the y axis.
+ let (scrolled_id, offset) = scroll_tree
+ .scroll_node_or_ancestor(
+ &child_id,
+ ScrollLocation::Delta(LayoutVector2D::new(0.0, -10.0)),
+ )
+ .unwrap();
+ let expected_offset = LayoutVector2D::new(0.0, -10.0);
+ assert_eq!(scrolled_id, ExternalScrollId(0, pipeline_id));
+ assert_eq!(offset, expected_offset);
+ assert_eq!(
+ scroll_tree.get_node(&parent_id).offset(),
+ Some(expected_offset)
+ );
+}
+
+#[test]
+fn test_scroll_tree_chain_through_overflow_hidden() {
+ let mut scroll_tree = ScrollTree::default();
+
+ // Create a tree with a scrollable leaf, but make its `scroll_sensitivity`
+ // reflect `overflow: hidden` ie not responsive to non-script scroll events.
+ let pipeline_id = PipelineId(0, 0);
+ let parent_id = add_mock_scroll_node(&mut scroll_tree);
+ let overflow_hidden_id = add_mock_scroll_node(&mut scroll_tree);
+ scroll_tree
+ .get_node_mut(&overflow_hidden_id)
+ .scroll_info
+ .as_mut()
+ .map(|info| {
+ info.scroll_sensitivity = AxesScrollSensitivity {
+ x: ScrollSensitivity::Script,
+ y: ScrollSensitivity::Script,
+ };
+ });
+
+ let (scrolled_id, offset) = scroll_tree
+ .scroll_node_or_ancestor(
+ &overflow_hidden_id,
+ ScrollLocation::Delta(LayoutVector2D::new(-20.0, -40.0)),
+ )
+ .unwrap();
+ let expected_offset = LayoutVector2D::new(-20.0, -40.0);
+ assert_eq!(scrolled_id, ExternalScrollId(0, pipeline_id));
+ assert_eq!(offset, expected_offset);
+ assert_eq!(
+ scroll_tree.get_node(&parent_id).offset(),
+ Some(expected_offset)
+ );
+ assert_eq!(
+ scroll_tree.get_node(&overflow_hidden_id).offset(),
+ Some(LayoutVector2D::new(0.0, 0.0))
+ );
+}