script/dom/
documentfragment.rs1use dom_struct::dom_struct;
6use js::rust::HandleObject;
7use stylo_atoms::Atom;
8
9use super::bindings::trace::HashMapTracedValues;
10use crate::dom::bindings::cell::DomRefCell;
11use crate::dom::bindings::codegen::Bindings::DocumentFragmentBinding::DocumentFragmentMethods;
12use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
13use crate::dom::bindings::codegen::UnionTypes::NodeOrString;
14use crate::dom::bindings::error::{ErrorResult, Fallible};
15use crate::dom::bindings::inheritance::Castable;
16use crate::dom::bindings::root::{Dom, DomRoot};
17use crate::dom::bindings::str::DOMString;
18use crate::dom::document::Document;
19use crate::dom::element::Element;
20use crate::dom::html::htmlcollection::HTMLCollection;
21use crate::dom::node::{Node, NodeTraits};
22use crate::dom::nodelist::NodeList;
23use crate::dom::virtualmethods::VirtualMethods;
24use crate::dom::window::Window;
25use crate::script_runtime::CanGc;
26
27#[dom_struct]
29pub(crate) struct DocumentFragment {
30 node: Node,
31 id_map: DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>>,
33}
34
35impl DocumentFragment {
36 pub(crate) fn new_inherited(document: &Document) -> DocumentFragment {
38 DocumentFragment {
39 node: Node::new_inherited(document),
40 id_map: DomRefCell::new(HashMapTracedValues::new()),
41 }
42 }
43
44 pub(crate) fn new(document: &Document, can_gc: CanGc) -> DomRoot<DocumentFragment> {
45 Self::new_with_proto(document, None, can_gc)
46 }
47
48 fn new_with_proto(
49 document: &Document,
50 proto: Option<HandleObject>,
51 can_gc: CanGc,
52 ) -> DomRoot<DocumentFragment> {
53 Node::reflect_node_with_proto(
54 Box::new(DocumentFragment::new_inherited(document)),
55 document,
56 proto,
57 can_gc,
58 )
59 }
60
61 pub(crate) fn id_map(&self) -> &DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>> {
62 &self.id_map
63 }
64}
65
66impl DocumentFragmentMethods<crate::DomTypeHolder> for DocumentFragment {
67 fn Constructor(
69 window: &Window,
70 proto: Option<HandleObject>,
71 can_gc: CanGc,
72 ) -> Fallible<DomRoot<DocumentFragment>> {
73 let document = window.Document();
74
75 Ok(DocumentFragment::new_with_proto(&document, proto, can_gc))
76 }
77
78 fn Children(&self, can_gc: CanGc) -> DomRoot<HTMLCollection> {
80 let window = self.owner_window();
81 HTMLCollection::children(&window, self.upcast(), can_gc)
82 }
83
84 fn GetElementById(&self, id: DOMString) -> Option<DomRoot<Element>> {
86 let id = Atom::from(id);
87 self.id_map
88 .borrow()
89 .get(&id)
90 .map(|elements| DomRoot::from_ref(&*elements[0]))
91 }
92
93 fn GetFirstElementChild(&self) -> Option<DomRoot<Element>> {
95 self.upcast::<Node>().child_elements().next()
96 }
97
98 fn GetLastElementChild(&self) -> Option<DomRoot<Element>> {
100 self.upcast::<Node>()
101 .rev_children()
102 .filter_map(DomRoot::downcast::<Element>)
103 .next()
104 }
105
106 fn ChildElementCount(&self) -> u32 {
108 self.upcast::<Node>().child_elements().count() as u32
109 }
110
111 fn Prepend(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
113 self.upcast::<Node>().prepend(nodes, can_gc)
114 }
115
116 fn Append(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
118 self.upcast::<Node>().append(nodes, can_gc)
119 }
120
121 fn ReplaceChildren(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
123 self.upcast::<Node>().replace_children(nodes, can_gc)
124 }
125
126 fn QuerySelector(&self, selectors: DOMString) -> Fallible<Option<DomRoot<Element>>> {
128 self.upcast::<Node>().query_selector(selectors)
129 }
130
131 fn QuerySelectorAll(&self, selectors: DOMString) -> Fallible<DomRoot<NodeList>> {
133 self.upcast::<Node>().query_selector_all(selectors)
134 }
135}
136
137impl VirtualMethods for DocumentFragment {
138 fn super_type(&self) -> Option<&dyn VirtualMethods> {
139 Some(self.upcast::<Node>() as &dyn VirtualMethods)
140 }
141}