script/dom/file/
filelist.rs1use std::slice::Iter;
6
7use dom_struct::dom_struct;
8use servo_base::id::{FileListId, FileListIndex};
9use servo_constellation_traits::SerializableFileList;
10
11use crate::dom::bindings::codegen::Bindings::FileListBinding::FileListMethods;
12use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
13use crate::dom::bindings::root::{Dom, DomRoot};
14use crate::dom::bindings::serializable::Serializable;
15use crate::dom::bindings::structuredclone::StructuredData;
16use crate::dom::file::File;
17use crate::dom::globalscope::GlobalScope;
18use crate::dom::window::Window;
19use crate::script_runtime::CanGc;
20
21#[dom_struct]
23pub(crate) struct FileList {
24 reflector_: Reflector,
25 list: Vec<Dom<File>>,
26}
27
28impl FileList {
29 #[cfg_attr(crown, expect(crown::unrooted_must_root))]
30 fn new_inherited(files: Vec<Dom<File>>) -> FileList {
31 FileList {
32 reflector_: Reflector::new(),
33 list: files,
34 }
35 }
36
37 pub(crate) fn new(
38 window: &Window,
39 files: Vec<DomRoot<File>>,
40 can_gc: CanGc,
41 ) -> DomRoot<FileList> {
42 reflect_dom_object(
43 Box::new(FileList::new_inherited(
44 files.iter().map(|r| Dom::from_ref(&**r)).collect(),
45 )),
46 window,
47 can_gc,
48 )
49 }
50
51 pub(crate) fn new_in_global(
52 global: &GlobalScope,
53 files: Vec<DomRoot<File>>,
54 can_gc: CanGc,
55 ) -> DomRoot<FileList> {
56 reflect_dom_object(
57 Box::new(FileList::new_inherited(
58 files.iter().map(|r| Dom::from_ref(&**r)).collect(),
59 )),
60 global,
61 can_gc,
62 )
63 }
64
65 pub(crate) fn iter_files(&self) -> Iter<'_, Dom<File>> {
66 self.list.iter()
67 }
68}
69
70impl Serializable for FileList {
71 type Index = FileListIndex;
72 type Data = SerializableFileList;
73
74 fn serialize(&self) -> Result<(FileListId, SerializableFileList), ()> {
76 let files = self
77 .list
78 .iter()
79 .map(|file| file.serialized_data())
80 .collect::<Result<Vec<_>, _>>()?;
81 Ok((FileListId::new(), SerializableFileList { files }))
82 }
83
84 fn deserialize(
86 owner: &GlobalScope,
87 serialized: SerializableFileList,
88 can_gc: CanGc,
89 ) -> Result<DomRoot<Self>, ()> {
90 let files = serialized
91 .files
92 .into_iter()
93 .map(|file| File::deserialize(owner, file, can_gc))
94 .collect::<Result<Vec<_>, _>>()?;
95 Ok(FileList::new_in_global(owner, files, can_gc))
96 }
97
98 fn serialized_storage<'a>(
99 reader: StructuredData<'a, '_>,
100 ) -> &'a mut Option<rustc_hash::FxHashMap<FileListId, Self::Data>> {
101 match reader {
102 StructuredData::Reader(r) => &mut r.file_lists,
103 StructuredData::Writer(w) => &mut w.file_lists,
104 }
105 }
106}
107
108impl FileListMethods<crate::DomTypeHolder> for FileList {
109 fn Length(&self) -> u32 {
111 self.list.len() as u32
112 }
113
114 fn Item(&self, index: u32) -> Option<DomRoot<File>> {
116 if (index as usize) < self.list.len() {
117 Some(DomRoot::from_ref(&*(self.list[index as usize])))
118 } else {
119 None
120 }
121 }
122
123 fn IndexedGetter(&self, index: u32) -> Option<DomRoot<File>> {
125 self.Item(index)
126 }
127}