script/dom/filesystem/
filesystemfileentry.rs1use std::cell::Cell;
6use std::rc::Rc;
7
8use dom_struct::dom_struct;
9use js::context::JSContext;
10use script_bindings::cell::DomRefCell;
11use script_bindings::reflector::reflect_dom_object_with_cx;
12
13use crate::dom::bindings::callback::ExceptionHandling;
14use crate::dom::bindings::codegen::Bindings::FileSystemEntryBinding::ErrorCallback;
15use crate::dom::bindings::codegen::Bindings::FileSystemFileEntryBinding::{
16 FileCallback, FileSystemFileEntryMethods,
17};
18use crate::dom::bindings::refcounted::Trusted;
19use crate::dom::bindings::reflector::DomGlobal;
20use crate::dom::bindings::root::{Dom, DomRoot};
21use crate::dom::bindings::str::USVString;
22use crate::dom::file::File;
23use crate::dom::filesystem::FileSystem;
24use crate::dom::filesystementry::FileSystemEntry;
25use crate::dom::globalscope::GlobalScope;
26
27#[dom_struct]
28pub(crate) struct FileSystemFileEntry {
29 filesystementry: FileSystemEntry,
30 file: Dom<File>,
31 pending_callbacks: DomRefCell<Vec<PendingFileCallback>>,
32 next_callback: Cell<usize>,
33}
34
35#[derive(JSTraceable, MallocSizeOf)]
36struct PendingFileCallback {
37 id: usize,
38 #[conditional_malloc_size_of]
39 callback: Rc<FileCallback>,
40}
41
42impl FileSystemFileEntry {
43 fn new_inherited(name: USVString, full_path: USVString, file: &File) -> FileSystemFileEntry {
44 FileSystemFileEntry {
45 filesystementry: FileSystemEntry::new_inherited(name, full_path, true),
46 file: Dom::from_ref(file),
47 pending_callbacks: Default::default(),
48 next_callback: Cell::new(0),
49 }
50 }
51
52 pub(crate) fn new(
53 cx: &mut JSContext,
54 global: &GlobalScope,
55 name: USVString,
56 full_path: USVString,
57 file: &File,
58 ) -> DomRoot<FileSystemFileEntry> {
59 reflect_dom_object_with_cx(
60 Box::new(FileSystemFileEntry::new_inherited(name, full_path, file)),
61 global,
62 cx,
63 )
64 }
65
66 pub(crate) fn set_filesystem(&self, fs: &FileSystem) {
67 self.filesystementry.set_filesystem(fs);
68 }
69}
70
71impl FileSystemFileEntryMethods<crate::DomTypeHolder> for FileSystemFileEntry {
72 fn File(&self, success_callback: Rc<FileCallback>, _error_callback: Option<Rc<ErrorCallback>>) {
74 let id = self.next_callback.get();
86 let pending_callback = PendingFileCallback {
87 id,
88 callback: success_callback,
89 };
90 self.pending_callbacks.borrow_mut().push(pending_callback);
91 self.next_callback.set(id + 1);
92
93 let this = Trusted::new(self);
94 self.global()
95 .task_manager()
96 .dom_manipulation_task_source()
97 .queue(task!(invoke_file_callback: move |cx| {
98 let this = this.root();
99 let maybe_index = this
100 .pending_callbacks
101 .borrow()
102 .iter()
103 .position(|val| val.id == id);
104 if let Some(index) = maybe_index {
105 let callback = this
106 .pending_callbacks
107 .safe_borrow_mut(cx.no_gc())
108 .swap_remove(index)
109 .callback;
110 let file = DomRoot::from_ref(&*this.file);
111 let _ = callback.Call__(cx, &file, ExceptionHandling::Report);
112 }
113 }));
114 }
115}