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