2022-07-24 21:32:18 +02:00
/*
2023-02-25 10:27:38 +01:00
* Copyright ( c ) 2022 - 2023 , Kenneth Myhra < kennethmyhra @ serenityos . org >
2022-07-24 21:32:18 +02:00
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
2022-09-25 18:08:29 -06:00
# include <AK/Time.h>
2023-01-07 12:14:54 -05:00
# include <LibJS/Runtime/Completion.h>
2022-09-25 18:08:29 -06:00
# include <LibWeb/Bindings/Intrinsics.h>
2022-07-24 21:32:18 +02:00
# include <LibWeb/FileAPI/File.h>
2023-02-25 10:27:38 +01:00
# include <LibWeb/Infra/Strings.h>
2022-07-24 21:32:18 +02:00
namespace Web : : FileAPI {
2023-11-19 19:47:52 +01:00
JS_DEFINE_ALLOCATOR ( File ) ;
2023-02-25 10:27:38 +01:00
File : : File ( JS : : Realm & realm , ByteBuffer byte_buffer , String file_name , String type , i64 last_modified )
2022-09-25 18:08:29 -06:00
: Blob ( realm , move ( byte_buffer ) , move ( type ) )
2022-07-24 21:32:18 +02:00
, m_name ( move ( file_name ) )
, m_last_modified ( last_modified )
{
2023-01-10 06:28:20 -05:00
}
2023-08-07 08:41:28 +02:00
void File : : initialize ( JS : : Realm & realm )
2023-01-10 06:28:20 -05:00
{
2023-08-07 08:41:28 +02:00
Base : : initialize ( realm ) ;
2023-01-10 06:28:20 -05:00
set_prototype ( & Bindings : : ensure_web_prototype < Bindings : : FilePrototype > ( realm , " File " ) ) ;
2022-07-24 21:32:18 +02:00
}
2022-09-04 11:44:38 +02:00
File : : ~ File ( ) = default ;
2022-07-24 21:32:18 +02:00
// https://w3c.github.io/FileAPI/#ref-for-dom-file-file
2023-02-25 10:27:38 +01:00
WebIDL : : ExceptionOr < JS : : NonnullGCPtr < File > > File : : create ( JS : : Realm & realm , Vector < BlobPart > const & file_bits , String const & file_name , Optional < FilePropertyBag > const & options )
2022-07-24 21:32:18 +02:00
{
2023-02-25 10:27:38 +01:00
auto & vm = realm . vm ( ) ;
2022-07-24 21:32:18 +02:00
// 1. Let bytes be the result of processing blob parts given fileBits and options.
2023-01-07 12:14:54 -05:00
auto bytes = TRY_OR_THROW_OOM ( realm . vm ( ) , process_blob_parts ( file_bits , options . has_value ( ) ? static_cast < BlobPropertyBag const & > ( * options ) : Optional < BlobPropertyBag > { } ) ) ;
2022-07-24 21:32:18 +02:00
// 2. Let n be the fileName argument to the constructor.
// NOTE: Underlying OS filesystems use differing conventions for file name; with constructed files, mandating UTF-16 lessens ambiquity when file names are converted to byte sequences.
auto name = file_name ;
2023-02-25 10:27:38 +01:00
auto type = String { } ;
2022-07-24 21:32:18 +02:00
i64 last_modified = 0 ;
// 3. Process FilePropertyBag dictionary argument by running the following substeps:
if ( options . has_value ( ) ) {
// 1. If the type member is provided and is not the empty string, let t be set to the type dictionary member.
// If t contains any characters outside the range U+0020 to U+007E, then set t to the empty string and return from these substeps.
// NOTE: t is set to empty string at declaration.
if ( ! options - > type . is_empty ( ) ) {
if ( is_basic_latin ( options - > type ) )
type = options - > type ;
}
// 2. Convert every character in t to ASCII lowercase.
if ( ! type . is_empty ( ) )
2023-03-04 22:41:57 +00:00
type = TRY_OR_THROW_OOM ( vm , Infra : : to_ascii_lowercase ( type ) ) ;
2022-07-24 21:32:18 +02:00
// 3. If the lastModified member is provided, let d be set to the lastModified dictionary member. If it is not provided, set d to the current date and time represented as the number of milliseconds since the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]).
// Note: Since ECMA-262 Date objects convert to long long values representing the number of milliseconds since the Unix Epoch, the lastModified member could be a Date object [ECMA-262].
2023-03-13 22:35:22 +01:00
last_modified = options - > last_modified . has_value ( ) ? options - > last_modified . value ( ) : UnixDateTime : : now ( ) . milliseconds_since_epoch ( ) ;
2022-07-24 21:32:18 +02:00
}
// 4. Return a new File object F such that:
// 2. F refers to the bytes byte sequence.
// NOTE: Spec started at 2 therefore keeping the same number sequence here.
// 3. F.size is set to the number of total bytes in bytes.
// 4. F.name is set to n.
// 5. F.type is set to t.
// 6. F.lastModified is set to d.
2023-08-13 13:05:26 +02:00
return realm . heap ( ) . allocate < File > ( realm , realm , move ( bytes ) , move ( name ) , move ( type ) , last_modified ) ;
2022-07-24 21:32:18 +02:00
}
2023-02-25 10:27:38 +01:00
WebIDL : : ExceptionOr < JS : : NonnullGCPtr < File > > File : : construct_impl ( JS : : Realm & realm , Vector < BlobPart > const & file_bits , String const & file_name , Optional < FilePropertyBag > const & options )
2022-07-24 21:32:18 +02:00
{
2022-09-25 18:08:29 -06:00
return create ( realm , file_bits , file_name , options ) ;
2022-07-24 21:32:18 +02:00
}
}