mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 04:09:13 +00:00
LibWeb: Implement DataTransferItemList.prototype.add()
This commit is contained in:
parent
b3bfd02e64
commit
74d9cfbf2a
Notes:
github-actions[bot]
2024-08-22 12:22:38 +00:00
Author: https://github.com/trflynn89
Commit: 74d9cfbf2a
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1158
Reviewed-by: https://github.com/shannonbooth
8 changed files with 126 additions and 3 deletions
|
@ -53,6 +53,7 @@ static bool is_platform_object(Type const& type)
|
||||||
"DynamicsCompressorNode"sv,
|
"DynamicsCompressorNode"sv,
|
||||||
"ElementInternals"sv,
|
"ElementInternals"sv,
|
||||||
"EventTarget"sv,
|
"EventTarget"sv,
|
||||||
|
"File"sv,
|
||||||
"FileList"sv,
|
"FileList"sv,
|
||||||
"FontFace"sv,
|
"FontFace"sv,
|
||||||
"FormData"sv,
|
"FormData"sv,
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
dropEffect: none
|
dropEffect: none
|
||||||
effectAllowed: none
|
effectAllowed: none
|
||||||
|
stringItem: [object DataTransferItem], types=custom-type
|
||||||
|
fileItem: [object DataTransferItem], types=custom-type,Files
|
||||||
|
|
|
@ -4,5 +4,22 @@
|
||||||
let dataTransfer = new DataTransfer();
|
let dataTransfer = new DataTransfer();
|
||||||
println(`dropEffect: ${dataTransfer.dropEffect}`);
|
println(`dropEffect: ${dataTransfer.dropEffect}`);
|
||||||
println(`effectAllowed: ${dataTransfer.effectAllowed}`);
|
println(`effectAllowed: ${dataTransfer.effectAllowed}`);
|
||||||
|
|
||||||
|
let dataTransferItemList = dataTransfer.items;
|
||||||
|
|
||||||
|
let stringItem = dataTransferItemList.add("well hello friends", "custom-type");
|
||||||
|
println(`stringItem: ${stringItem}, types=${dataTransfer.types}`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
dataTransferItemList.add("well hello friends", "custom-type");
|
||||||
|
println("FAILED");
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
let file = new File(["well hello friends"], "file.txt", {
|
||||||
|
type: "text/plain",
|
||||||
|
});
|
||||||
|
|
||||||
|
let fileItem = dataTransferItemList.add(file);
|
||||||
|
println(`fileItem: ${fileItem}, types=${dataTransfer.types}`);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -220,12 +220,46 @@ JS::NonnullGCPtr<FileAPI::FileList> DataTransfer::files() const
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Optional<DragDataStore::Mode> DataTransfer::mode() const
|
||||||
|
{
|
||||||
|
if (m_associated_drag_data_store)
|
||||||
|
return m_associated_drag_data_store->mode();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void DataTransfer::disassociate_with_drag_data_store()
|
void DataTransfer::disassociate_with_drag_data_store()
|
||||||
{
|
{
|
||||||
m_associated_drag_data_store.clear();
|
m_associated_drag_data_store.clear();
|
||||||
update_data_transfer_types_list();
|
update_data_transfer_types_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JS::NonnullGCPtr<DataTransferItem> DataTransfer::add_item(DragDataStoreItem item)
|
||||||
|
{
|
||||||
|
auto& realm = this->realm();
|
||||||
|
|
||||||
|
VERIFY(m_associated_drag_data_store);
|
||||||
|
m_associated_drag_data_store->add_item(move(item));
|
||||||
|
|
||||||
|
auto data_transfer_item = DataTransferItem::create(realm, *this, m_associated_drag_data_store->size() - 1);
|
||||||
|
m_item_list.append(data_transfer_item);
|
||||||
|
|
||||||
|
update_data_transfer_types_list();
|
||||||
|
|
||||||
|
return data_transfer_item;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DataTransfer::contains_item_with_type(DragDataStoreItem::Kind kind, String const& type) const
|
||||||
|
{
|
||||||
|
VERIFY(m_associated_drag_data_store);
|
||||||
|
|
||||||
|
for (auto const& item : m_associated_drag_data_store->item_list()) {
|
||||||
|
if (item.kind == kind && item.type_string.equals_ignoring_ascii_case(type))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/dnd.html#concept-datatransfer-types
|
// https://html.spec.whatwg.org/multipage/dnd.html#concept-datatransfer-types
|
||||||
void DataTransfer::update_data_transfer_types_list()
|
void DataTransfer::update_data_transfer_types_list()
|
||||||
{
|
{
|
||||||
|
@ -259,5 +293,4 @@ void DataTransfer::update_data_transfer_types_list()
|
||||||
// 3. Set the DataTransfer object's types array to the result of creating a frozen array from L.
|
// 3. Set the DataTransfer object's types array to the result of creating a frozen array from L.
|
||||||
m_types = move(types);
|
m_types = move(types);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,8 +56,12 @@ public:
|
||||||
String get_data(String const& format) const;
|
String get_data(String const& format) const;
|
||||||
JS::NonnullGCPtr<FileAPI::FileList> files() const;
|
JS::NonnullGCPtr<FileAPI::FileList> files() const;
|
||||||
|
|
||||||
|
Optional<DragDataStore::Mode> mode() const;
|
||||||
void disassociate_with_drag_data_store();
|
void disassociate_with_drag_data_store();
|
||||||
|
|
||||||
|
JS::NonnullGCPtr<DataTransferItem> add_item(DragDataStoreItem item);
|
||||||
|
bool contains_item_with_type(DragDataStoreItem::Kind, String const& type) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DataTransfer(JS::Realm&, NonnullRefPtr<DragDataStore>);
|
DataTransfer(JS::Realm&, NonnullRefPtr<DragDataStore>);
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,10 @@
|
||||||
#include <LibJS/Runtime/Realm.h>
|
#include <LibJS/Runtime/Realm.h>
|
||||||
#include <LibWeb/Bindings/DataTransferItemListPrototype.h>
|
#include <LibWeb/Bindings/DataTransferItemListPrototype.h>
|
||||||
#include <LibWeb/Bindings/Intrinsics.h>
|
#include <LibWeb/Bindings/Intrinsics.h>
|
||||||
|
#include <LibWeb/FileAPI/File.h>
|
||||||
#include <LibWeb/HTML/DataTransfer.h>
|
#include <LibWeb/HTML/DataTransfer.h>
|
||||||
#include <LibWeb/HTML/DataTransferItemList.h>
|
#include <LibWeb/HTML/DataTransferItemList.h>
|
||||||
|
#include <LibWeb/Infra/Strings.h>
|
||||||
|
|
||||||
namespace Web::HTML {
|
namespace Web::HTML {
|
||||||
|
|
||||||
|
@ -39,4 +41,63 @@ void DataTransferItemList::visit_edges(JS::Cell::Visitor& visitor)
|
||||||
visitor.visit(m_data_transfer);
|
visitor.visit(m_data_transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransferitemlist-add
|
||||||
|
WebIDL::ExceptionOr<JS::GCPtr<DataTransferItem>> DataTransferItemList::add(String const& data, String const& type)
|
||||||
|
{
|
||||||
|
auto& realm = this->realm();
|
||||||
|
|
||||||
|
// 1. If the DataTransferItemList object is not in the read/write mode, return null.
|
||||||
|
if (m_data_transfer->mode() != DragDataStore::Mode::ReadWrite)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// 2. Jump to the appropriate set of steps from the following list:
|
||||||
|
// -> If the first argument to the method is a string
|
||||||
|
|
||||||
|
// If there is already an item in the drag data store item list whose kind is text and whose type string is equal
|
||||||
|
// to the value of the method's second argument, converted to ASCII lowercase, then throw a "NotSupportedError"
|
||||||
|
// DOMException.
|
||||||
|
if (m_data_transfer->contains_item_with_type(DragDataStoreItem::Kind::Text, type)) {
|
||||||
|
auto error = MUST(String::formatted("There is already a DataTransferItem with type {}", type));
|
||||||
|
return WebIDL::NotSupportedError::create(realm, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, add an item to the drag data store item list whose kind is text, whose type string is equal to the
|
||||||
|
// value of the method's second argument, converted to ASCII lowercase, and whose data is the string given by the
|
||||||
|
// method's first argument.
|
||||||
|
auto item = m_data_transfer->add_item({
|
||||||
|
.kind = HTML::DragDataStoreItem::Kind::Text,
|
||||||
|
.type_string = MUST(Infra::to_ascii_lowercase(type)),
|
||||||
|
.data = MUST(ByteBuffer::copy(data.bytes())),
|
||||||
|
.file_name = {},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. Determine the value of the indexed property corresponding to the newly added item, and return that value (a
|
||||||
|
// newly created DataTransferItem object).
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransferitemlist-add
|
||||||
|
JS::GCPtr<DataTransferItem> DataTransferItemList::add(JS::NonnullGCPtr<FileAPI::File> file)
|
||||||
|
{
|
||||||
|
// 1. If the DataTransferItemList object is not in the read/write mode, return null.
|
||||||
|
if (m_data_transfer->mode() != DragDataStore::Mode::ReadWrite)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// 2. Jump to the appropriate set of steps from the following list:
|
||||||
|
// -> If the first argument to the method is a File
|
||||||
|
|
||||||
|
// Add an item to the drag data store item list whose kind is File, whose type string is the type of the File,
|
||||||
|
// converted to ASCII lowercase, and whose data is the same as the File's data.
|
||||||
|
auto item = m_data_transfer->add_item({
|
||||||
|
.kind = HTML::DragDataStoreItem::Kind::File,
|
||||||
|
.type_string = MUST(Infra::to_ascii_lowercase(file->type())),
|
||||||
|
.data = MUST(ByteBuffer::copy(file->raw_bytes())),
|
||||||
|
.file_name = file->name().to_byte_string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. Determine the value of the indexed property corresponding to the newly added item, and return that value (a
|
||||||
|
// newly created DataTransferItem object).
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <LibJS/Forward.h>
|
#include <LibJS/Forward.h>
|
||||||
#include <LibWeb/Bindings/PlatformObject.h>
|
#include <LibWeb/Bindings/PlatformObject.h>
|
||||||
|
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||||
|
|
||||||
namespace Web::HTML {
|
namespace Web::HTML {
|
||||||
|
|
||||||
|
@ -20,6 +21,9 @@ public:
|
||||||
static JS::NonnullGCPtr<DataTransferItemList> create(JS::Realm&, JS::NonnullGCPtr<DataTransfer>);
|
static JS::NonnullGCPtr<DataTransferItemList> create(JS::Realm&, JS::NonnullGCPtr<DataTransfer>);
|
||||||
virtual ~DataTransferItemList() override;
|
virtual ~DataTransferItemList() override;
|
||||||
|
|
||||||
|
WebIDL::ExceptionOr<JS::GCPtr<DataTransferItem>> add(String const& data, String const& type);
|
||||||
|
JS::GCPtr<DataTransferItem> add(JS::NonnullGCPtr<FileAPI::File>);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DataTransferItemList(JS::Realm&, JS::NonnullGCPtr<DataTransfer>);
|
DataTransferItemList(JS::Realm&, JS::NonnullGCPtr<DataTransfer>);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#import <FileAPI/File.idl>
|
||||||
#import <HTML/DataTransferItem.idl>
|
#import <HTML/DataTransferItem.idl>
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/dnd.html#datatransferitemlist
|
// https://html.spec.whatwg.org/multipage/dnd.html#datatransferitemlist
|
||||||
|
@ -5,8 +6,8 @@
|
||||||
interface DataTransferItemList {
|
interface DataTransferItemList {
|
||||||
[FIXME] readonly attribute unsigned long length;
|
[FIXME] readonly attribute unsigned long length;
|
||||||
[FIXME] getter DataTransferItem (unsigned long index);
|
[FIXME] getter DataTransferItem (unsigned long index);
|
||||||
[FIXME] DataTransferItem? add(DOMString data, DOMString type);
|
DataTransferItem? add(DOMString data, DOMString type);
|
||||||
[FIXME] DataTransferItem? add(File data);
|
DataTransferItem? add(File data);
|
||||||
[FIXME] undefined remove(unsigned long index);
|
[FIXME] undefined remove(unsigned long index);
|
||||||
[FIXME] undefined clear();
|
[FIXME] undefined clear();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue