diff --git a/Tests/LibWeb/Text/expected/HTML/data-transfer.txt b/Tests/LibWeb/Text/expected/HTML/data-transfer.txt
index 96592024645..a41e32bd4b6 100644
--- a/Tests/LibWeb/Text/expected/HTML/data-transfer.txt
+++ b/Tests/LibWeb/Text/expected/HTML/data-transfer.txt
@@ -5,3 +5,4 @@ stringItem: kind=string, type=custom-type
length=1, types=custom-type
fileItem: kind=file, type=text/plain
length=2, types=custom-type,Files
+fileItemAsFile: name=file.txt, type=text/plain
diff --git a/Tests/LibWeb/Text/input/HTML/data-transfer.html b/Tests/LibWeb/Text/input/HTML/data-transfer.html
index 0d092360fa6..76038e2e862 100644
--- a/Tests/LibWeb/Text/input/HTML/data-transfer.html
+++ b/Tests/LibWeb/Text/input/HTML/data-transfer.html
@@ -29,6 +29,9 @@
println(`fileItem: kind=${fileItem.kind}, type=${fileItem.type}`);
println(`length=${dataTransferItemList.length}, types=${dataTransfer.types}`);
+ let fileItemAsFile = fileItem.getAsFile();
+ println(`fileItemAsFile: name=${fileItemAsFile.name}, type=${fileItemAsFile.type}`);
+
if (dataTransferItemList[1] !== fileItem) {
println("FAILED");
}
diff --git a/Userland/Libraries/LibWeb/HTML/DataTransferItem.cpp b/Userland/Libraries/LibWeb/HTML/DataTransferItem.cpp
index fdf2ea8b004..27c8d2f7ec8 100644
--- a/Userland/Libraries/LibWeb/HTML/DataTransferItem.cpp
+++ b/Userland/Libraries/LibWeb/HTML/DataTransferItem.cpp
@@ -7,6 +7,7 @@
#include
#include
#include
+#include
#include
#include
@@ -85,4 +86,32 @@ Optional DataTransferItem::mode() const
return m_data_transfer->mode();
}
+// https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransferitem-getasfile
+JS::GCPtr DataTransferItem::get_as_file() const
+{
+ auto& realm = this->realm();
+
+ // 1. If the DataTransferItem object is not in the read/write mode or the read-only mode, then return null
+ if (mode() != DragDataStore::Mode::ReadWrite && mode() != DragDataStore::Mode::ReadOnly)
+ return nullptr;
+
+ auto const& item = m_data_transfer->drag_data(*m_item_index);
+
+ // 2. If the drag data item kind is not File, then return null.
+ if (item.kind != DragDataStoreItem::Kind::File)
+ return nullptr;
+
+ // 3. Return a new File object representing the actual data of the item represented by the DataTransferItem object.
+ 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;
+
+ return MUST(FileAPI::File::create(realm, { JS::make_handle(blob) }, file_name, move(options)));
+}
+
}
diff --git a/Userland/Libraries/LibWeb/HTML/DataTransferItem.h b/Userland/Libraries/LibWeb/HTML/DataTransferItem.h
index 5659286497f..adbce270a1d 100644
--- a/Userland/Libraries/LibWeb/HTML/DataTransferItem.h
+++ b/Userland/Libraries/LibWeb/HTML/DataTransferItem.h
@@ -25,6 +25,8 @@ public:
String kind() const;
String type() const;
+ JS::GCPtr get_as_file() const;
+
private:
DataTransferItem(JS::Realm&, JS::NonnullGCPtr, size_t item_index);
diff --git a/Userland/Libraries/LibWeb/HTML/DataTransferItem.idl b/Userland/Libraries/LibWeb/HTML/DataTransferItem.idl
index 157e87b2894..4eb4a760ffc 100644
--- a/Userland/Libraries/LibWeb/HTML/DataTransferItem.idl
+++ b/Userland/Libraries/LibWeb/HTML/DataTransferItem.idl
@@ -8,5 +8,5 @@ interface DataTransferItem {
readonly attribute DOMString kind;
readonly attribute DOMString type;
[FIXME] undefined getAsString(FunctionStringCallback? _callback);
- [FIXME] File? getAsFile();
+ File? getAsFile();
};