use crate::browser_data_transfer_helper::IReadableDataItems;
use crate::browser_drag_data_transfer_item::BrowserDragDataTransferItem;
use ferroui_base::input::platform::{
ClipboardError, PlatformDataTransfer, PlatformDataTransferImpl, PlatformDataTransferItem,
};
use ferroui_base::input::DataFormat;
use std::cell::RefCell;
use std::rc::Rc;
pub(crate) struct BrowserDragDataTransfer {
js_items: RefCell<Option<Rc<dyn IReadableDataItems>>>,
items: RefCell<Option<Vec<Rc<PlatformDataTransferItem>>>>,
}
impl BrowserDragDataTransfer {
pub(crate) fn new(js_items: Rc<dyn IReadableDataItems>) -> Rc<PlatformDataTransfer> {
PlatformDataTransfer::new(Self { js_items: RefCell::new(Some(js_items)), items: RefCell::new(None) })
}
fn items(&self) -> Vec<Rc<PlatformDataTransferItem>> {
if let Some(items) = self.items.borrow().as_ref() {
return items.clone();
}
let items: Vec<Rc<PlatformDataTransferItem>> = match self.js_items.borrow().as_ref() {
Some(js_items) => (0..js_items.len()).map(|i| BrowserDragDataTransferItem::new(js_items.get(i))).collect(),
None => panic!("Cannot access a disposed object: BrowserDragDataTransfer"),
};
*self.items.borrow_mut() = Some(items.clone());
items
}
}
impl PlatformDataTransferImpl for BrowserDragDataTransfer {
fn provide_formats(&self) -> Result<Vec<DataFormat>, ClipboardError> {
let mut formats: Vec<DataFormat> = Vec::new();
for item in self.items() {
for format in item.try_formats()?.iter() {
if !formats.contains(format) {
formats.push(format.clone());
}
}
}
Ok(formats)
}
fn provide_items(&self) -> Result<Vec<Rc<PlatformDataTransferItem>>, ClipboardError> {
Ok(self.items())
}
fn dispose(&self, _owner: &PlatformDataTransfer) {
let js_items = self.js_items.borrow_mut().take();
drop(js_items);
let items = self.items.borrow_mut().take();
drop(items);
}
}