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