Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 18 additions & 14 deletions lib/internal/blob.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';

const {
ArrayFrom,
MathMax,
MathMin,
ObjectDefineProperties,
Expand All @@ -15,7 +14,6 @@ const {
StringPrototypeSplit,
StringPrototypeToLowerCase,
Symbol,
SymbolIterator,
SymbolToStringTag,
Uint8Array,
} = primordials;
Expand Down Expand Up @@ -54,12 +52,15 @@ const {
lazyDOMException,
} = require('internal/util');
const { inspect } = require('internal/util/inspect');
const { convertToInt } = require('internal/webidl');
const {
converters,
convertToInt,
createSequenceConverter,
} = require('internal/webidl');

const {
codes: {
ERR_BUFFER_TOO_LARGE,
ERR_INVALID_ARG_TYPE,
ERR_INVALID_ARG_VALUE,
ERR_INVALID_STATE,
ERR_INVALID_THIS,
Expand Down Expand Up @@ -112,7 +113,6 @@ function getSource(source, endings) {
if (isAnyArrayBuffer(source)) {
source = new Uint8Array(source);
} else if (!isArrayBufferView(source)) {
source = `${source}`;
if (endings === 'native')
source = RegExpPrototypeSymbolReplace(/\n|\r\n/g, source, EOL);
source = enc.encode(source);
Expand All @@ -126,6 +126,13 @@ function getSource(source, endings) {
return [byteLength, new Uint8Array(slice)];
}

const sourcesConverter = createSequenceConverter((source, opts = kEmptyObject) => {
if (isBlob(source) || isAnyArrayBuffer(source) || isArrayBufferView(source)) {
return source;
}
return converters.DOMString(source, opts);
});

class Blob {
/**
* @typedef {string|ArrayBuffer|ArrayBufferView|Blob} SourcePart
Expand All @@ -142,11 +149,8 @@ class Blob {
constructor(sources = [], options) {
markTransferMode(this, true, false);

if (sources === null ||
typeof sources[SymbolIterator] !== 'function' ||
typeof sources === 'string') {
throw new ERR_INVALID_ARG_TYPE('sources', 'a sequence', sources);
}
const sources_ = sourcesConverter(sources);

validateDictionary(options, 'options');
let {
endings = 'transparent',
Expand All @@ -158,11 +162,11 @@ class Blob {
throw new ERR_INVALID_ARG_VALUE('options.endings', endings);

let length = 0;
const sources_ = ArrayFrom(sources, (source) => {
const { 0: len, 1: src } = getSource(source, endings);
for (let i = 0; i < sources_.length; ++i) {
const { 0: len, 1: src } = getSource(sources_[i], endings);
length += len;
return src;
});
sources_[i] = src;
}

if (length > kMaxLength)
throw new ERR_BUFFER_TOO_LARGE(kMaxLength);
Expand Down
8 changes: 0 additions & 8 deletions test/wpt/status/FileAPI/blob.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@
},
"Blob-constructor.any.js": {
"fail": {
"expected": [
"blobParts not an object: boolean with Boolean.prototype[Symbol.iterator]",
"blobParts not an object: number with Number.prototype[Symbol.iterator]",
"blobParts not an object: BigInt with BigInt.prototype[Symbol.iterator]",
"blobParts not an object: Symbol with Symbol.prototype[Symbol.iterator]",
"Getters and value conversions should happen in order until an exception is thrown.",
"Arguments should be evaluated from left to right."
],
"flaky": [
"Passing typed arrays as elements of the blobParts array should work.",
"Passing a Float16Array as element of the blobParts array should work.",
Expand Down
Loading