script/dom/
selection_range.rs1use crate::dom::abstractrange::BoundaryPoint;
6use crate::dom::bindings::root::Dom;
7use crate::dom::node::Node;
8use crate::dom::range::Range;
9
10#[derive(Clone, JSTraceable, PartialEq, MallocSizeOf)]
13#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
14pub(crate) struct SelectionBoundary {
15 pub container: Dom<Node>,
16 pub offset: u32,
17}
18
19impl SelectionBoundary {
20 pub(crate) fn new(container: &Node, offset: u32) -> Self {
21 Self {
22 container: Dom::from_ref(container),
23 offset,
24 }
25 }
26}
27
28impl PartialEq<BoundaryPoint> for SelectionBoundary {
29 fn eq(&self, boundary_point: &BoundaryPoint) -> bool {
30 *self.container == *boundary_point.node().get() &&
31 self.offset as usize == boundary_point.offset().0
32 }
33}
34
35#[derive(JSTraceable, PartialEq, MallocSizeOf)]
36#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
37pub(crate) struct SelectionRange {
38 pub start: SelectionBoundary,
39 pub end: SelectionBoundary,
40}
41
42impl SelectionRange {
43 #[cfg_attr(crown, expect(crown::unrooted_must_root))]
44 pub(crate) fn new(start: SelectionBoundary, end: SelectionBoundary) -> Self {
45 Self { start, end }
46 }
47
48 #[cfg_attr(crown, expect(crown::unrooted_must_root))]
49 pub(crate) fn collapsed_at(at: SelectionBoundary) -> Self {
50 Self {
51 start: at.clone(),
52 end: at,
53 }
54 }
55
56 pub(crate) fn collapsed(&self) -> bool {
57 self.start == self.end
58 }
59
60 pub(crate) fn start_and_end_are_in_document_tree(&self) -> bool {
61 self.start.container.is_in_a_document_tree() && self.end.container.is_in_a_document_tree()
62 }
63}
64
65impl From<&Range> for SelectionRange {
66 fn from(range: &Range) -> Self {
67 Self::new(
68 SelectionBoundary::new(&range.start_container(), range.start_offset()),
69 SelectionBoundary::new(&range.end_container(), range.end_offset()),
70 )
71 }
72}