LibWeb: Implement the DataTransfer files attribute

This commit is contained in:
Timothy Flynn 2024-08-17 14:44:26 -04:00 committed by Andreas Kling
parent 8b4d28b5fd
commit 4bb9168712
Notes: github-actions[bot] 2024-08-19 11:30:24 +00:00
5 changed files with 64 additions and 1 deletions

View file

@ -5,6 +5,8 @@ dragover
types: Files types: Files
drop drop
types: Files types: Files
files: 1
test1
Drag enter and leave: Drag enter and leave:
dragenter dragenter
@ -19,6 +21,8 @@ dragover
types: Files types: Files
drop drop
types: Files types: Files
files: 1
test2
Drag enter not accepted: Drag enter not accepted:
dragenter dragenter
@ -41,3 +45,5 @@ dragover
types: Files types: Files
drop drop
types: Files types: Files
files: 1
test5

View file

@ -8,6 +8,16 @@
const printEvent = (name, e) => { const printEvent = (name, e) => {
println(name); println(name);
println(` types: ${e.dataTransfer.types}`); println(` types: ${e.dataTransfer.types}`);
const files = e.dataTransfer.files;
if (files.length !== 0) {
println(` files: ${files.length}`);
for (const file of files) {
println(` ${file.name}`);
}
}
}; };
target.addEventListener("dragenter", e => { target.addEventListener("dragenter", e => {

View file

@ -7,6 +7,9 @@
#include <LibJS/Runtime/Realm.h> #include <LibJS/Runtime/Realm.h>
#include <LibWeb/Bindings/DataTransferPrototype.h> #include <LibWeb/Bindings/DataTransferPrototype.h>
#include <LibWeb/Bindings/Intrinsics.h> #include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/FileAPI/Blob.h>
#include <LibWeb/FileAPI/File.h>
#include <LibWeb/FileAPI/FileList.h>
#include <LibWeb/HTML/DataTransfer.h> #include <LibWeb/HTML/DataTransfer.h>
namespace Web::HTML { namespace Web::HTML {
@ -84,6 +87,46 @@ ReadonlySpan<String> DataTransfer::types() const
return m_types; return m_types;
} }
// https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-files
JS::NonnullGCPtr<FileAPI::FileList> DataTransfer::files() const
{
auto& realm = this->realm();
// 1. Start with an empty list L.
auto files = FileAPI::FileList::create(realm);
// 2. If the DataTransfer object is no longer associated with a drag data store, the FileList is empty. Return
// the empty list L.
if (!m_associated_drag_data_store.has_value())
return files;
// 3. If the drag data store's mode is the protected mode, return the empty list L.
if (m_associated_drag_data_store->mode() == DragDataStore::Mode::Protected)
return files;
// 4. For each item in the drag data store item list whose kind is File, add the item's data (the file, in
// particular its name and contents, as well as its type) to the list L.
for (auto const& item : m_associated_drag_data_store->item_list()) {
if (item.kind != DragDataStoreItem::Kind::File)
continue;
auto blob = FileAPI::Blob::create(realm, item.data, item.type_string);
// FIXME: The FileAPI should use ByteString for file names.
auto file_name = MUST(String::from_byte_string(item.file_name));
// FIXME: Fill in other fields (e.g. last_modified).
FileAPI::FilePropertyBag options {};
options.type = item.type_string;
auto file = MUST(FileAPI::File::create(realm, { JS::make_handle(blob) }, file_name, move(options)));
files->add_file(file);
}
// 5. The files found by these steps are those in the list L.
return files;
}
void DataTransfer::associate_with_drag_data_store(DragDataStore& drag_data_store) void DataTransfer::associate_with_drag_data_store(DragDataStore& drag_data_store)
{ {
m_associated_drag_data_store = drag_data_store; m_associated_drag_data_store = drag_data_store;

View file

@ -51,6 +51,8 @@ public:
ReadonlySpan<String> types() const; ReadonlySpan<String> types() const;
JS::NonnullGCPtr<FileAPI::FileList> files() const;
void associate_with_drag_data_store(DragDataStore& drag_data_store); void associate_with_drag_data_store(DragDataStore& drag_data_store);
void disassociate_with_drag_data_store(); void disassociate_with_drag_data_store();

View file

@ -1,3 +1,5 @@
#import <FileAPI/FileList.idl>
// https://html.spec.whatwg.org/multipage/dnd.html#datatransfer // https://html.spec.whatwg.org/multipage/dnd.html#datatransfer
[Exposed=Window] [Exposed=Window]
interface DataTransfer { interface DataTransfer {
@ -15,5 +17,5 @@ interface DataTransfer {
[FIXME] DOMString getData(DOMString format); [FIXME] DOMString getData(DOMString format);
[FIXME] undefined setData(DOMString format, DOMString data); [FIXME] undefined setData(DOMString format, DOMString data);
[FIXME] undefined clearData(optional DOMString format); [FIXME] undefined clearData(optional DOMString format);
[FIXME, SameObject] readonly attribute FileList files; [SameObject] readonly attribute FileList files;
}; };