Skip to main content

script/dom/range/
staticrange.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::rc::Rc;
6
7use dom_struct::dom_struct;
8use js::context::JSContext;
9use js::rust::HandleObject;
10use script_bindings::reflector::reflect_weak_referenceable_dom_object_with_proto;
11
12use crate::dom::abstractrange::AbstractRange;
13use crate::dom::bindings::codegen::Bindings::StaticRangeBinding::{
14    StaticRangeInit, StaticRangeMethods,
15};
16use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
17use crate::dom::bindings::error::{Error, Fallible};
18use crate::dom::bindings::inheritance::NodeTypeId;
19use crate::dom::bindings::root::DomRoot;
20use crate::dom::document::Document;
21use crate::dom::node::Node;
22use crate::dom::window::Window;
23
24#[dom_struct]
25pub(crate) struct StaticRange {
26    abstract_range: AbstractRange,
27}
28
29impl StaticRange {
30    pub(crate) fn new(
31        cx: &mut JSContext,
32        document: &Document,
33        start_container: &Node,
34        start_offset: u32,
35        end_container: &Node,
36        end_offset: u32,
37    ) -> DomRoot<StaticRange> {
38        Self::new_with_proto(
39            cx,
40            document,
41            start_container,
42            start_offset,
43            end_container,
44            end_offset,
45            None, /* proto */
46        )
47    }
48
49    fn new_inherited(
50        start_container: &Node,
51        start_offset: u32,
52        end_container: &Node,
53        end_offset: u32,
54    ) -> StaticRange {
55        StaticRange {
56            abstract_range: AbstractRange::new_inherited(
57                start_container,
58                start_offset,
59                end_container,
60                end_offset,
61            ),
62        }
63    }
64
65    pub(crate) fn new_with_proto(
66        cx: &mut JSContext,
67        document: &Document,
68        start_container: &Node,
69        start_offset: u32,
70        end_container: &Node,
71        end_offset: u32,
72        proto: Option<HandleObject>,
73    ) -> DomRoot<StaticRange> {
74        reflect_weak_referenceable_dom_object_with_proto(
75            cx,
76            Rc::new(StaticRange::new_inherited(
77                start_container,
78                start_offset,
79                end_container,
80                end_offset,
81            )),
82            document.window(),
83            proto,
84        )
85    }
86}
87
88impl StaticRangeMethods<crate::DomTypeHolder> for StaticRange {
89    /// <https://dom.spec.whatwg.org/#dom-staticrange-staticrange>
90    fn Constructor(
91        cx: &mut JSContext,
92        window: &Window,
93        proto: Option<HandleObject>,
94        init: &StaticRangeInit,
95    ) -> Fallible<DomRoot<StaticRange>> {
96        match init.startContainer.type_id() {
97            NodeTypeId::DocumentType | NodeTypeId::Attr => {
98                return Err(Error::InvalidNodeType(Some(
99                    "Invalid node type: startContainer cannot be DocumentType or Attr node".into(),
100                )));
101            },
102            _ => (),
103        }
104        match init.endContainer.type_id() {
105            NodeTypeId::DocumentType | NodeTypeId::Attr => {
106                return Err(Error::InvalidNodeType(Some(
107                    "Invalid node type: endContainer cannot be DocumentType or Attr node".into(),
108                )));
109            },
110            _ => (),
111        }
112        let document = window.Document();
113        Ok(StaticRange::new_with_proto(
114            cx,
115            &document,
116            &init.startContainer,
117            init.startOffset,
118            &init.endContainer,
119            init.endOffset,
120            proto,
121        ))
122    }
123}