LibWeb/FileAPI: Update Blob.slice for spec changes
This commit is contained in:
parent
181ece4d9c
commit
9650a5ff33
Notes:
github-actions[bot]
2024-08-23 11:09:18 +00:00
Author: https://github.com/jamierocks Commit: https://github.com/LadybirdBrowser/ladybird/commit/9650a5ff33a Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1164 Reviewed-by: https://github.com/tcl3 ✅
2 changed files with 47 additions and 26 deletions
|
@ -221,66 +221,85 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Blob>> Blob::construct_impl(JS::Realm& real
|
|||
|
||||
// https://w3c.github.io/FileAPI/#dfn-slice
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Blob>> Blob::slice(Optional<i64> start, Optional<i64> end, Optional<String> const& content_type)
|
||||
{
|
||||
// 1. Let sliceStart, sliceEnd, and sliceContentType be null.
|
||||
// 2. If start is given, set sliceStart to start.
|
||||
// 3. If end is given, set sliceEnd to end.
|
||||
// 3. If contentType is given, set sliceContentType to contentType.
|
||||
// 4. Return the result of slice blob given this, sliceStart, sliceEnd, and sliceContentType.
|
||||
return slice_blob(start, end, content_type);
|
||||
}
|
||||
|
||||
// https://w3c.github.io/FileAPI/#slice-blob
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Blob>> Blob::slice_blob(Optional<i64> start, Optional<i64> end, Optional<String> const& content_type)
|
||||
{
|
||||
auto& vm = realm().vm();
|
||||
|
||||
// 1. The optional start parameter is a value for the start point of a slice() call, and must be treated as a byte-order position, with the zeroth position representing the first byte.
|
||||
// User agents must process slice() with start normalized according to the following:
|
||||
// 1. Let originalSize be blob’s size.
|
||||
auto original_size = size();
|
||||
|
||||
// 2. The start parameter, if non-null, is a value for the start point of a slice blob call, and must be treated as a byte-order position,
|
||||
// with the zeroth position representing the first byte. User agents must normalize start according to the following:
|
||||
i64 relative_start;
|
||||
if (!start.has_value()) {
|
||||
// a. If the optional start parameter is not used as a parameter when making this call, let relativeStart be 0.
|
||||
// a. If start is null, let relativeStart be 0.
|
||||
relative_start = 0;
|
||||
} else {
|
||||
auto start_value = start.value();
|
||||
// b. If start is negative, let relativeStart be max((size + start), 0).
|
||||
|
||||
// b. If start is negative, let relativeStart be max((originalSize + start), 0).
|
||||
if (start_value < 0) {
|
||||
relative_start = max((size() + start_value), 0);
|
||||
relative_start = max((static_cast<i64>(original_size) + start_value), 0);
|
||||
}
|
||||
// c. Else, let relativeStart be min(start, size).
|
||||
// c. Otherwise, let relativeStart be min(start, originalSize).
|
||||
else {
|
||||
relative_start = min(start_value, size());
|
||||
relative_start = min(start_value, original_size);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. The optional end parameter is a value for the end point of a slice() call. User agents must process slice() with end normalized according to the following:
|
||||
// 3. The end parameter, if non-null. is a value for the end point of a slice blob call. User agents must normalize end according to the following:
|
||||
i64 relative_end;
|
||||
if (!end.has_value()) {
|
||||
// a. If the optional end parameter is not used as a parameter when making this call, let relativeEnd be size.
|
||||
relative_end = size();
|
||||
// a. If end is null, let relativeEnd be originalSize.
|
||||
relative_end = original_size;
|
||||
} else {
|
||||
auto end_value = end.value();
|
||||
// b. If end is negative, let relativeEnd be max((size + end), 0).
|
||||
|
||||
// b. If end is negative, let relativeEnd be max((originalSize + end), 0).
|
||||
if (end_value < 0) {
|
||||
relative_end = max((size() + end_value), 0);
|
||||
relative_end = max((static_cast<i64>(original_size) + end_value), 0);
|
||||
}
|
||||
// c Else, let relativeEnd be min(end, size).
|
||||
// c. Otherwise, let relativeEnd be min(end, originalSize).
|
||||
else {
|
||||
relative_end = min(end_value, size());
|
||||
relative_end = min(end_value, original_size);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. The optional contentType parameter is used to set the ASCII-encoded string in lower case representing the media type of the Blob.
|
||||
// User agents must process the slice() with contentType normalized according to the following:
|
||||
// 4. The contentType parameter, if non-null, is used to set the ASCII-encoded string in lower case representing the media type of the Blob.
|
||||
// User agents must normalize contentType according to the following:
|
||||
String relative_content_type;
|
||||
if (!content_type.has_value()) {
|
||||
// a. If the contentType parameter is not provided, let relativeContentType be set to the empty string.
|
||||
relative_content_type = String {};
|
||||
// a. If contentType is null, let relativeContentType be set to the empty string.
|
||||
relative_content_type = {};
|
||||
} else {
|
||||
// b. Else let relativeContentType be set to contentType and run the substeps below:
|
||||
// b. Otherwise, let relativeContentType be set to contentType and run the substeps below:
|
||||
|
||||
// 1. If relativeContentType contains any characters outside the range of U+0020 to U+007E, then set relativeContentType to the empty string and return from these substeps.
|
||||
// NOTE: contentType is set to empty string at declaration.
|
||||
if (is_basic_latin(content_type.value())) {
|
||||
// 2. Convert every character in relativeContentType to ASCII lowercase.
|
||||
// 1. If relativeContentType contains any characters outside the range of U+0020 to U+007E, then set relativeContentType to the empty string
|
||||
// and return from these substeps:
|
||||
if (!is_basic_latin(content_type.value())) {
|
||||
relative_content_type = {};
|
||||
}
|
||||
// 2. Convert every character in relativeContentType to ASCII lowercase.
|
||||
else {
|
||||
relative_content_type = TRY_OR_THROW_OOM(vm, Infra::to_ascii_lowercase(content_type.value()));
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Let span be max((relativeEnd - relativeStart), 0).
|
||||
// 5. Let span be max((relativeEnd - relativeStart), 0).
|
||||
auto span = max((relative_end - relative_start), 0);
|
||||
|
||||
// 5. Return a new Blob object S with the following characteristics:
|
||||
// a. S refers to span consecutive bytes from this, beginning with the byte at byte-order position relativeStart.
|
||||
// 6. Return a new Blob object S with the following characteristics:
|
||||
// a. S refers to span consecutive bytes from blob’s associated byte sequence, beginning with the byte at byte-order position relativeStart.
|
||||
// b. S.size = span.
|
||||
// c. S.type = relativeContentType.
|
||||
auto byte_buffer = TRY_OR_THROW_OOM(vm, m_byte_buffer.slice(relative_start, span));
|
||||
|
|
|
@ -67,6 +67,8 @@ protected:
|
|||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Blob>> slice_blob(Optional<i64> start = {}, Optional<i64> end = {}, Optional<String> const& content_type = {});
|
||||
|
||||
ByteBuffer m_byte_buffer {};
|
||||
String m_type {};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue