script/dom/document/
documentfragment.rs1use dom_struct::dom_struct;
6use js::context::JSContext;
7use js::rust::HandleObject;
8use stylo_atoms::Atom;
9
10use crate::dom::bindings::codegen::Bindings::DocumentFragmentBinding::DocumentFragmentMethods;
11use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
12use crate::dom::bindings::codegen::UnionTypes::NodeOrString;
13use crate::dom::bindings::error::{ErrorResult, Fallible};
14use crate::dom::bindings::inheritance::Castable;
15use crate::dom::bindings::root::{DomRoot, LayoutDom, MutNullableDom};
16use crate::dom::bindings::str::DOMString;
17use crate::dom::document::Document;
18use crate::dom::element::Element;
19use crate::dom::html::htmlcollection::HTMLCollection;
20use crate::dom::node::{Node, NodeTraits};
21use crate::dom::nodelist::NodeList;
22use crate::dom::tree_ordered_index_map::TreeOrderedIndexMap;
23use crate::dom::virtualmethods::VirtualMethods;
24use crate::dom::window::Window;
25
26#[dom_struct]
28pub(crate) struct DocumentFragment {
29 node: Node,
31 id_map: TreeOrderedIndexMap,
33 host: MutNullableDom<Element>,
35}
36
37impl DocumentFragment {
38 pub(crate) fn new_inherited(document: &Document, host: Option<&Element>) -> DocumentFragment {
40 DocumentFragment {
41 node: Node::new_inherited(document),
42 id_map: TreeOrderedIndexMap::id(),
43 host: MutNullableDom::new(host),
44 }
45 }
46
47 pub(crate) fn new(
48 cx: &mut js::context::JSContext,
49 document: &Document,
50 ) -> DomRoot<DocumentFragment> {
51 Self::new_with_proto(cx, document, None)
52 }
53
54 fn new_with_proto(
55 cx: &mut js::context::JSContext,
56 document: &Document,
57 proto: Option<HandleObject>,
58 ) -> DomRoot<DocumentFragment> {
59 Node::reflect_node_with_proto(
60 cx,
61 Box::new(DocumentFragment::new_inherited(document, None)),
62 document,
63 proto,
64 )
65 }
66
67 pub(crate) fn id_map(&self) -> &TreeOrderedIndexMap {
68 &self.id_map
69 }
70
71 pub(crate) fn host(&self) -> Option<DomRoot<Element>> {
72 self.host.get()
73 }
74
75 pub(crate) fn set_host(&self, host: &Element) {
76 self.host.set(Some(host));
77 }
78}
79
80impl<'dom> LayoutDom<'dom, DocumentFragment> {
81 #[inline]
82 pub(crate) fn shadowroot_host_for_layout(self) -> LayoutDom<'dom, Element> {
83 #[expect(unsafe_code)]
84 unsafe {
85 self.unsafe_get()
88 .host
89 .get_inner_as_layout()
90 .expect("Shadow roots's associated host is never null")
91 }
92 }
93}
94
95impl DocumentFragmentMethods<crate::DomTypeHolder> for DocumentFragment {
96 fn Constructor(
98 cx: &mut js::context::JSContext,
99 window: &Window,
100 proto: Option<HandleObject>,
101 ) -> Fallible<DomRoot<DocumentFragment>> {
102 let document = window.Document();
103
104 Ok(DocumentFragment::new_with_proto(cx, &document, proto))
105 }
106
107 fn Children(&self, cx: &mut js::context::JSContext) -> DomRoot<HTMLCollection> {
109 let window = self.owner_window();
110 HTMLCollection::children(cx, &window, self.upcast())
111 }
112
113 fn GetElementById(&self, cx: &JSContext, id: DOMString) -> Option<DomRoot<Element>> {
115 self.id_map.get(cx, self.upcast(), &Atom::from(id))
116 }
117
118 fn GetFirstElementChild(&self) -> Option<DomRoot<Element>> {
120 self.upcast::<Node>().child_elements().next()
121 }
122
123 fn GetLastElementChild(&self) -> Option<DomRoot<Element>> {
125 self.upcast::<Node>()
126 .rev_children()
127 .find_map(DomRoot::downcast::<Element>)
128 }
129
130 fn ChildElementCount(&self) -> u32 {
132 self.upcast::<Node>().child_elements().count() as u32
133 }
134
135 fn Prepend(&self, cx: &mut JSContext, nodes: Vec<NodeOrString>) -> ErrorResult {
137 self.upcast::<Node>().prepend(cx, nodes)
138 }
139
140 fn Append(&self, cx: &mut JSContext, nodes: Vec<NodeOrString>) -> ErrorResult {
142 self.upcast::<Node>().append(cx, nodes)
143 }
144
145 fn ReplaceChildren(&self, cx: &mut JSContext, nodes: Vec<NodeOrString>) -> ErrorResult {
147 self.upcast::<Node>().replace_children(cx, nodes)
148 }
149
150 fn MoveBefore(&self, cx: &mut JSContext, node: &Node, child: Option<&Node>) -> ErrorResult {
152 self.upcast::<Node>().move_before(cx, node, child)
153 }
154
155 fn QuerySelector(
157 &self,
158 cx: &mut JSContext,
159 selectors: DOMString,
160 ) -> Fallible<Option<DomRoot<Element>>> {
161 self.upcast::<Node>().query_selector(cx.no_gc(), selectors)
162 }
163
164 fn QuerySelectorAll(
166 &self,
167 cx: &mut JSContext,
168 selectors: DOMString,
169 ) -> Fallible<DomRoot<NodeList>> {
170 self.upcast::<Node>()
171 .query_selector_all(cx.no_gc(), selectors)
172 }
173}
174
175impl VirtualMethods for DocumentFragment {
176 fn super_type(&self) -> Option<&dyn VirtualMethods> {
177 Some(self.upcast::<Node>() as &dyn VirtualMethods)
178 }
179}