/
githubmirror
/
servo
Обзор
Документация
Войти
/
githubmirror
/
servo
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
components/script/dom/filesystem/filesystemfileentry.rs
115 строк
4 KB
Euclid Ye
script: Implement async FileSystemFileEntry.file() success callback (#46832)
29 июл 2026, 06:49
Не верифицирован
29 июл 2026, 06:49
15905ac
Код
Авторство
О чём код?
/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::cell::Cell; use std::rc::Rc; use dom_struct::dom_struct; use js::context::JSContext; use script_bindings::cell::DomRefCell; use script_bindings::reflector::reflect_dom_object_with_cx; use crate::dom::bindings::callback::ExceptionHandling; use crate::dom::bindings::codegen::Bindings::FileSystemEntryBinding::ErrorCallback; use crate::dom::bindings::codegen::Bindings::FileSystemFileEntryBinding::{ FileCallback, FileSystemFileEntryMethods, }; use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::reflector::DomGlobal; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::USVString; use crate::dom::file::File; use crate::dom::filesystem::FileSystem; use crate::dom::filesystementry::FileSystemEntry; use crate::dom::globalscope::GlobalScope; #[dom_struct] pub(crate) struct FileSystemFileEntry { filesystementry: FileSystemEntry, file: Dom<File>, pending_callbacks: DomRefCell<Vec<PendingFileCallback>>, next_callback: Cell<usize>, } #[derive(JSTraceable, MallocSizeOf)] struct PendingFileCallback { id: usize, #[conditional_malloc_size_of] callback: Rc<FileCallback>, } impl FileSystemFileEntry { fn new_inherited(name: USVString, full_path: USVString, file: &File) -> FileSystemFileEntry { FileSystemFileEntry { filesystementry: FileSystemEntry::new_inherited(name, full_path, true), file: Dom::from_ref(file), pending_callbacks: Default::default(), next_callback: Cell::new(0), } } pub(crate) fn new( cx: &mut JSContext, global: &GlobalScope, name: USVString, full_path: USVString, file: &File, ) -> DomRoot<FileSystemFileEntry> { reflect_dom_object_with_cx( Box::new(FileSystemFileEntry::new_inherited(name, full_path, file)), global, cx, ) } pub(crate) fn set_filesystem(&self, fs: &FileSystem) { self.filesystementry.set_filesystem(fs); } } impl FileSystemFileEntryMethods<crate::DomTypeHolder> for FileSystemFileEntry { /// <https://wicg.github.io/entries-api/#dom-filesystemfileentry-file> fn File(&self, success_callback: Rc<FileCallback>, _error_callback: Option<Rc<ErrorCallback>>) { // Per spec 7.4: in parallel, // 1. (TODO) Evaluate path // 2-3. (TODO) errorCallback // Note: Step 1 - 3 is meant to re-check if file exists on OS filesystem. // It is unreachable for now, as the file data is already // stored in-memory on this entry as `File` (set by webkitGetAsEntry). // 4. on success, queue a task to invoke successCallback // with a new `File` object representing item and "report". let id = self.next_callback.get(); let pending_callback = PendingFileCallback { id, callback: success_callback, }; self.pending_callbacks.borrow_mut().push(pending_callback); self.next_callback.set(id + 1); let this = Trusted::new(self); self.global() .task_manager() .dom_manipulation_task_source() .queue(task!(invoke_file_callback: move |cx| { let this = this.root(); let maybe_index = this .pending_callbacks .borrow() .iter() .position(|val| val.id == id); if let Some(index) = maybe_index { let callback = this .pending_callbacks .safe_borrow_mut(cx.no_gc()) .swap_remove(index) .callback; let file = DomRoot::from_ref(&*this.file); let _ = callback.Call__(cx, &file, ExceptionHandling::Report); } })); } }