소스 검색

LibWeb: Implement DataTransferItem.prototype.getAsString()

Timothy Flynn 10 달 전
부모
커밋
181ece4d9c

+ 1 - 0
Tests/LibWeb/Text/expected/HTML/data-transfer.txt

@@ -3,6 +3,7 @@ effectAllowed: none
 length=0, types=
 stringItem: kind=string, type=custom-type
 length=1, types=custom-type
+stringItemAsString: data=well hello friends
 fileItem: kind=file, type=text/plain
 length=2, types=custom-type,Files
 fileItemAsFile: name=file.txt, type=text/plain

+ 9 - 1
Tests/LibWeb/Text/input/HTML/data-transfer.html

@@ -1,6 +1,6 @@
 <script src="../include.js"></script>
 <script>
-    test(() => {
+    test(async () => {
         let dataTransfer = new DataTransfer();
         println(`dropEffect: ${dataTransfer.dropEffect}`);
         println(`effectAllowed: ${dataTransfer.effectAllowed}`);
@@ -16,6 +16,14 @@
             println("FAILED");
         }
 
+        let promise = new Promise((resolve, reject) => {
+            stringItem.getAsString(data => {
+                println(`stringItemAsString: data=${data}`);
+                resolve();
+            });
+        });
+        await promise;
+
         try {
             dataTransferItemList.add("well hello friends", "custom-type");
             println("FAILED");

+ 34 - 0
Userland/Libraries/LibWeb/HTML/DataTransferItem.cpp

@@ -4,12 +4,15 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
+#include <LibJS/Heap/HeapFunction.h>
 #include <LibJS/Runtime/Realm.h>
 #include <LibWeb/Bindings/DataTransferItemPrototype.h>
 #include <LibWeb/Bindings/Intrinsics.h>
 #include <LibWeb/FileAPI/File.h>
 #include <LibWeb/HTML/DataTransfer.h>
 #include <LibWeb/HTML/DataTransferItem.h>
+#include <LibWeb/WebIDL/AbstractOperations.h>
+#include <LibWeb/WebIDL/CallbackType.h>
 
 namespace Web::HTML {
 
@@ -86,6 +89,37 @@ Optional<DragDataStore::Mode> DataTransferItem::mode() const
     return m_data_transfer->mode();
 }
 
+// https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransferitem-getasstring
+void DataTransferItem::get_as_string(JS::GCPtr<WebIDL::CallbackType> callback) const
+{
+    auto& realm = this->realm();
+    auto& vm = realm.vm();
+
+    // 1. If the callback is null, return.
+    if (!callback)
+        return;
+
+    // 2. If the DataTransferItem object is not in the read/write mode or the read-only mode, return. The callback is
+    //    never invoked.
+    if (mode() != DragDataStore::Mode::ReadWrite && mode() != DragDataStore::Mode::ReadOnly)
+        return;
+
+    auto const& item = m_data_transfer->drag_data(*m_item_index);
+
+    // 3. If the drag data item kind is not text, then return. The callback is never invoked.
+    if (item.kind != DragDataStoreItem::Kind::Text)
+        return;
+
+    // 4. Otherwise, queue a task to invoke callback, passing the actual data of the item represented by the
+    //    DataTransferItem object as the argument.
+    auto data = JS::PrimitiveString::create(vm, MUST(String::from_utf8({ item.data })));
+
+    HTML::queue_a_task(HTML::Task::Source::Unspecified, nullptr, nullptr,
+        JS::HeapFunction<void()>::create(realm.heap(), [callback, data]() {
+            (void)WebIDL::invoke_callback(*callback, {}, data);
+        }));
+}
+
 // https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransferitem-getasfile
 JS::GCPtr<FileAPI::File> DataTransferItem::get_as_file() const
 {

+ 1 - 0
Userland/Libraries/LibWeb/HTML/DataTransferItem.h

@@ -25,6 +25,7 @@ public:
     String kind() const;
     String type() const;
 
+    void get_as_string(JS::GCPtr<WebIDL::CallbackType>) const;
     JS::GCPtr<FileAPI::File> get_as_file() const;
 
 private:

+ 1 - 1
Userland/Libraries/LibWeb/HTML/DataTransferItem.idl

@@ -7,6 +7,6 @@ callback FunctionStringCallback = undefined (DOMString data);
 interface DataTransferItem {
     readonly attribute DOMString kind;
     readonly attribute DOMString type;
-    [FIXME] undefined getAsString(FunctionStringCallback? _callback);
+    undefined getAsString(FunctionStringCallback? _callback);
     File? getAsFile();
 };