1 use webcore::value::{Value, Reference};
2 use webcore::try_from::TryInto;
3 use webcore::reference_type::ReferenceType;
4 use webapi::file::File;
5 
6 /// An object of this type is returned by the files property of the HTML `<input>` element;
7 /// this lets you access the list of files selected with the `<input type="file">` element.
8 /// It's also used for a list of files dropped into web content when using the drag and drop API.
9 ///
10 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/FileList)
11 // https://w3c.github.io/FileAPI/#dfn-filelist
12 #[derive(Clone, Debug, PartialEq, Eq, ReferenceType)]
13 #[reference(instance_of = "FileList")]
14 pub struct FileList( Reference );
15 
16 impl FileList {
17     /// Returns the number of [File](struct.File.html)s contained in this list.
18     ///
19     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/FileList/length)
20     // https://w3c.github.io/FileAPI/#ref-for-dfn-length
len( &self ) -> u3221     pub fn len( &self ) -> u32 {
22         js!( return @{self}.length; ).try_into().unwrap()
23     }
24 
25     /// Returns an iterator over the list.
iter( &self ) -> FileIter26     pub fn iter( &self ) -> FileIter {
27         FileIter {
28             list: self.clone(),
29             index: 0
30         }
31     }
32 }
33 
34 impl IntoIterator for FileList {
35     type Item = File;
36     type IntoIter = FileIter;
37 
38     #[inline]
into_iter( self ) -> Self::IntoIter39     fn into_iter( self ) -> Self::IntoIter {
40         FileIter {
41             list: self,
42             index: 0
43         }
44     }
45 }
46 
47 impl< 'a > IntoIterator for &'a FileList {
48     type Item = File;
49     type IntoIter = FileIter;
50 
51     #[inline]
into_iter( self ) -> Self::IntoIter52     fn into_iter( self ) -> Self::IntoIter {
53         FileIter {
54             list: self.clone(),
55             index: 0
56         }
57     }
58 }
59 
60 #[derive(Debug)]
61 pub struct FileIter {
62     list: FileList,
63     index: i32
64 }
65 
66 impl Iterator for FileIter {
67     type Item = File;
next( &mut self ) -> Option< Self::Item >68     fn next( &mut self ) -> Option< Self::Item > {
69         let value = js!(
70             return @{&self.list}[ @{self.index} ];
71         );
72 
73         let file = match value {
74             Value::Undefined => return None,
75             Value::Reference( reference ) => unsafe { File::from_reference_unchecked( reference ) },
76             _ => unreachable!()
77         };
78 
79         self.index += 1;
80         Some( file )
81     }
82 }
83