From ffab9fb44ed0cff0d895d0e21e52e53d85f742e5 Mon Sep 17 00:00:00 2001 From: Andrew Kaster Date: Mon, 3 Oct 2022 21:10:39 -0600 Subject: [PATCH] LibWeb: Add FileList from the FileAPI spec --- .../LibWeb/Bindings/WindowObjectHelper.h | 3 ++ Userland/Libraries/LibWeb/CMakeLists.txt | 1 + .../Libraries/LibWeb/FileAPI/FileList.cpp | 53 +++++++++++++++++++ Userland/Libraries/LibWeb/FileAPI/FileList.h | 43 +++++++++++++++ .../Libraries/LibWeb/FileAPI/FileList.idl | 5 ++ Userland/Libraries/LibWeb/idl_files.cmake | 1 + 6 files changed, 106 insertions(+) create mode 100644 Userland/Libraries/LibWeb/FileAPI/FileList.cpp create mode 100644 Userland/Libraries/LibWeb/FileAPI/FileList.h create mode 100644 Userland/Libraries/LibWeb/FileAPI/FileList.idl diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h b/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h index 50fcfda5c0..e9b65acfd3 100644 --- a/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h +++ b/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h @@ -92,6 +92,8 @@ #include #include #include +#include +#include #include #include #include @@ -449,6 +451,7 @@ ADD_WINDOW_OBJECT_INTERFACE(Event) \ ADD_WINDOW_OBJECT_INTERFACE(EventTarget) \ ADD_WINDOW_OBJECT_INTERFACE(File) \ + ADD_WINDOW_OBJECT_INTERFACE(FileList) \ ADD_WINDOW_OBJECT_INTERFACE(Headers) \ ADD_WINDOW_OBJECT_INTERFACE(History) \ ADD_WINDOW_OBJECT_INTERFACE(HTMLAnchorElement) \ diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 8d5ae47578..d0bf1faeda 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -137,6 +137,7 @@ set(SOURCES Fetch/Response.cpp FileAPI/Blob.cpp FileAPI/File.cpp + FileAPI/FileList.cpp FontCache.cpp Geometry/DOMPoint.cpp Geometry/DOMPointReadOnly.cpp diff --git a/Userland/Libraries/LibWeb/FileAPI/FileList.cpp b/Userland/Libraries/LibWeb/FileAPI/FileList.cpp new file mode 100644 index 0000000000..988b1e030e --- /dev/null +++ b/Userland/Libraries/LibWeb/FileAPI/FileList.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022, Andrew Kaster + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Web::FileAPI { + +JS::NonnullGCPtr FileList::create(JS::Realm& realm, Vector>&& files) +{ + return *realm.heap().allocate(realm, realm, move(files)); +} + +FileList::FileList(JS::Realm& realm, Vector>&& files) + : Bindings::LegacyPlatformObject(Bindings::cached_web_prototype(realm, "FileList")) + , m_files(move(files)) +{ +} + +FileList::~FileList() = default; + +// https://w3c.github.io/FileAPI/#dfn-item +bool FileList::is_supported_property_index(u32 index) const +{ + // Supported property indices are the numbers in the range zero to one less than the number of File objects represented by the FileList object. + // If there are no such File objects, then there are no supported property indices. + if (m_files.is_empty()) + return false; + + return m_files.size() < index; +} + +JS::Value FileList::item_value(size_t index) const +{ + if (index >= m_files.size()) + return JS::js_undefined(); + + return m_files[index].ptr(); +} + +void FileList::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + for (auto file : m_files) + visitor.visit(file); +} + +} diff --git a/Userland/Libraries/LibWeb/FileAPI/FileList.h b/Userland/Libraries/LibWeb/FileAPI/FileList.h new file mode 100644 index 0000000000..82f4a989cf --- /dev/null +++ b/Userland/Libraries/LibWeb/FileAPI/FileList.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022, Andrew Kaster + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include + +namespace Web::FileAPI { + +class FileList : public Bindings::LegacyPlatformObject { + WEB_PLATFORM_OBJECT(FileList, Bindings::LegacyPlatformObject); + +public: + static JS::NonnullGCPtr create(JS::Realm&, Vector>&&); + virtual ~FileList() override; + + // https://w3c.github.io/FileAPI/#dfn-length + unsigned long length() const { return m_files.size(); } + + // https://w3c.github.io/FileAPI/#dfn-item + File const* item(size_t index) const + { + return index < m_files.size() ? m_files[index].ptr() : nullptr; + } + + virtual bool is_supported_property_index(u32 index) const override; + virtual JS::Value item_value(size_t index) const override; + +private: + FileList(JS::Realm&, Vector>&&); + + virtual void visit_edges(Cell::Visitor&) override; + + Vector> m_files; +}; + +} diff --git a/Userland/Libraries/LibWeb/FileAPI/FileList.idl b/Userland/Libraries/LibWeb/FileAPI/FileList.idl new file mode 100644 index 0000000000..3e13c79479 --- /dev/null +++ b/Userland/Libraries/LibWeb/FileAPI/FileList.idl @@ -0,0 +1,5 @@ +[Exposed=(Window,Worker), Serializable] +interface FileList { + getter File? item(unsigned long index); + readonly attribute unsigned long length; +}; diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index 5f293b7a30..9427d3d1c7 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -57,6 +57,7 @@ libweb_js_bindings(Fetch/Request) libweb_js_bindings(Fetch/Response) libweb_js_bindings(FileAPI/Blob) libweb_js_bindings(FileAPI/File) +libweb_js_bindings(FileAPI/FileList) libweb_js_bindings(Geometry/DOMPoint) libweb_js_bindings(Geometry/DOMPointReadOnly) libweb_js_bindings(Geometry/DOMRect)