1. Introduction
This section is informative.
Web applications should have the ability to manipulate as wide as possible a range of user input, including files that a user may wish to upload to a remote server or manipulate inside a rich web application. This specification defines the basic representations for files, lists of files, errors raised by access to files, and programmatic ways to read files. Additionally, this specification also defines an interface that represents "raw data" which can be asynchronously processed on the main thread of conforming user agents. The interfaces and API defined in this specification can be used with other interfaces and APIs exposed to the web platform.
The File
interface represents file data typically obtained from the underlying file system,
and the Blob
interface
("Binary Large Object" - a name originally introduced to web APIs in Google Gears)
represents immutable raw data. File
or Blob
reads should happen asynchronously on the main thread,
with an optional synchronous API used within threaded web applications.
An asynchronous API for reading files prevents blocking and UI "freezing" on a user agent’s main thread.
This specification defines an asynchronous API based on an event model to read and access a File
or Blob
’s data.
A FileReader
object provides asynchronous read methods to access that file’s data
through event handler content attributes and the firing of events.
The use of events and event handlers allows separate code blocks the ability
to monitor the progress of the read (which is particularly useful for remote drives or mounted drives,
where file access performance may vary from local drives)
and error conditions that may arise during reading of a file.
An example will be illustrative.
function startRead() { // obtain input element through DOM var file= document. getElementById( 'file' ). files[ 0 ]; if ( file){ getAsText( file); } } function getAsText( readFile) { var reader= new FileReader(); // Read file into memory as UTF-16 reader. readAsText( readFile, "UTF-16" ); // Handle progress, success, and errors reader. onprogress= updateProgress; reader. onload= loaded; reader. onerror= errorHandler; } function updateProgress( evt) { if ( evt. lengthComputable) { // evt.loaded and evt.total are ProgressEvent properties var loaded= ( evt. loaded/ evt. total); if ( loaded< 1 ) { // Increase the prog bar length // style.width = (loaded * 200) + "px"; } } } function loaded( evt) { // Obtain the read file data var fileString= evt. target. result; // Handle UTF-16 file dump if ( utils. regexp. isChinese( fileString)) { //Chinese Characters + Name validation } else { // run other charset test } // xhr.send(fileString) } function errorHandler( evt) { if ( evt. target. error. name== "NotReadableError" ) { // The file could not be read } }
2. Terminology and Algorithms
When this specification says to terminate an algorithm the user agent must terminate the algorithm after finishing the step it is on.
Asynchronous read methods defined in this specification may return before the algorithm in question is terminated,
and can be terminated by an abort()
call.
The algorithms and steps in this specification use the following mathematical operations:
-
max(a,b) returns the maximum of a and b, and is always performed on integers as they are defined in WebIDL [WebIDL]; in the case of max(6,4) the result is 6. This operation is also defined in ECMAScript [ECMA-262].
-
min(a,b) returns the minimum of a and b, and is always performed on integers as they are defined in WebIDL [WebIDL]; in the case of min(6,4) the result is 4. This operation is also defined in ECMAScript [ECMA-262].
-
Mathematical comparisons such as < (less than), ≤ (less than or equal to), and > (greater than) are as in ECMAScript [ECMA-262].
The term Unix Epoch is used in this specification to refer to the time 00:00:00 UTC on January 1 1970
(or 1970-01-01T00:00:00Z ISO 8601);
this is the same time that is conceptually "0
" in ECMA-262 [ECMA-262].
Blob
blob, start, end, and contentType is used to refer to the following
steps and returns a new Blob
containing the bytes ranging from the start parameter
up to but not including the end parameter. It must act as follows:
-
Let originalSize be blob’s
size
. -
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:
- If start is null, let relativeStart be 0.
- If start is negative, let relativeStart be
max((originalSize + start), 0)
. - Otherwise, let relativeStart be
min(start, originalSize)
.
-
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:
- If end is null, let relativeEnd be originalSize.
- If end is negative, let relativeEnd be
max((originalSize + end), 0)
. - Otherwise, let relativeEnd be
min(end, originalSize)
.
-
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:- If contentType is null, let relativeContentType be set to the empty string.
-
Otherwise, let relativeContentType be set to contentType and run the
substeps below:
-
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.
-
Convert every character in relativeContentType to ASCII lowercase.
-
-
Let span be
max((relativeEnd - relativeStart), 0)
. -
Return a new
Blob
object S with the following characteristics:
3. The Blob Interface and Binary Data
A Blob
object refers to a byte sequence,
and has a size
attribute which is the total number of bytes in the byte sequence,
and a type
attribute,
which is an ASCII-encoded string in lower case representing the media type of the byte sequence.
Each Blob
must have an internal snapshot state,
which must be initially set to the state of the underlying storage,
if any such underlying storage exists.
Further normative definition of snapshot state can be found for File
s.
[Exposed =(Window ,Worker ),Serializable ]interface {
Blob (
constructor optional sequence <BlobPart >blobParts ,optional BlobPropertyBag = {});
options readonly attribute unsigned long long size ;readonly attribute DOMString type ; // slice Blob into byte-ranged chunksBlob slice (optional [Clamp ]long long ,
start optional [Clamp ]long long ,
end optional DOMString ); // read from the Blob. [
contentType NewObject ]ReadableStream stream (); [NewObject ]Promise <USVString >text (); [NewObject ]Promise <ArrayBuffer >arrayBuffer (); [NewObject ]Promise <Uint8Array >bytes (); };enum {
EndingType ,
"transparent" };
"native" dictionary {
BlobPropertyBag DOMString type = "";EndingType endings = "transparent"; };typedef (BufferSource or Blob or USVString );
BlobPart
Blob
objects are serializable objects. Their serialization steps,
given value and serialized, are:
-
Set serialized.[[SnapshotState]] to value’s snapshot state.
-
Set serialized.[[ByteSequence]] to value’s underlying byte sequence.
Their deserialization step, given serialized and value, are:
-
Set value’s snapshot state to serialized.[[SnapshotState]].
-
Set value’s underlying byte sequence to serialized.[[ByteSequence]].
Blob
blob has an associated get stream algorithm,
which runs these steps:
-
Let stream be a new
ReadableStream
created in blob’s relevant Realm. -
Set up stream with byte reading support.
-
Run the following steps in parallel:
-
While not all bytes of blob have been read:
-
Let bytes be the byte sequence that results from reading a chunk from blob, or failure if a chunk cannot be read.
-
Queue a global task on the file reading task source given blob’s relevant global object to perform the following steps:
-
If bytes is failure, then error stream with a failure reason and abort these steps.
-
Let chunk be a new
Uint8Array
wrapping anArrayBuffer
containing bytes. If creating theArrayBuffer
throws an exception, then error stream with that exception and abort these steps. -
Enqueue chunk in stream.
-
We need to specify more concretely what reading from a Blob actually does, what possible errors can happen, perhaps something about chunk sizes, etc.
-
-
-
Return stream.
3.1. Constructors
Blob()
constructor can be invoked with zero or more parameters.
When the Blob()
constructor is invoked,
user agents must run the following steps:
-
If invoked with zero parameters, return a new
Blob
object consisting of 0 bytes, withsize
set to 0, and withtype
set to the empty string. -
Let bytes be the result of processing blob parts given
blobParts
andoptions
. -
If the
type
member of theoptions
argument is not the empty string, run the following sub-steps:-
Let t be 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. -
Convert every character in t to ASCII lowercase.
-
-
Return a
Blob
object referring to bytes as its associated byte sequence, with itssize
set to the length of bytes, and itstype
set to the value of t from the substeps above.
3.1.1. Constructor Parameters
The Blob()
constructor can be invoked with the parameters below:
- A
blobParts
sequence
-
which takes any number of the following types of elements, and in any order:
-
BufferSource
elements. -
Blob
elements. -
USVString
elements.
-
- An optional
BlobPropertyBag
-
which takes these optional members:
-
type
, the ASCII-encoded string in lower case representing the media type of theBlob
. Normative conditions for this member are provided in the § 3.1 Constructors. -
endings
, an enum which can take the values"transparent"
or"native"
. By default this is set to"transparent"
. If set to"native"
, line endings will be converted to native in anyUSVString
elements inblobParts
.
-
BlobPart
's parts and BlobPropertyBag
options,
run the following steps:
-
Let bytes be an empty sequence of bytes.
-
For each element in parts:
-
If element is a
USVString
, run the following substeps:-
Let s be element.
-
If the
endings
member of options is"native"
, set s to the result of converting line endings to native of element. -
Append the result of UTF-8 encoding s to bytes.
Note: The algorithm from WebIDL [WebIDL] replaces unmatched surrogates in an invalid utf-16 string with U+FFFD replacement characters. Scenarios exist when the
Blob
constructor may result in some data loss due to lost or scrambled character sequences.
-
-
If element is a
BufferSource
, get a copy of the bytes held by the buffer source, and append those bytes to bytes. -
If element is a
Blob
, append the bytes it represents to bytes.Note: The
type
of theBlob
array element is ignored and will not affecttype
of returnedBlob
object.
-
-
Return bytes.
-
Let native line ending be the code point U+000A LF.
-
If the underlying platform’s conventions are to represent newlines as a carriage return and line feed sequence, set native line ending to the code point U+000D CR followed by the code point U+000A LF.
-
Set result to the empty string.
-
Let position be a position variable for s, initially pointing at the start of s.
-
Let token be the result of collecting a sequence of code points that are not equal to U+000A LF or U+000D CR from s given position.
-
Append token to result.
-
While position is not past the end of s:
-
If the code point at position within s equals U+000D CR:
-
Append native line ending to result.
-
Advance position by 1.
-
If position is not past the end of s and the code point at position within s equals U+000A LF advance position by 1.
-
-
Otherwise if the code point at position within s equals U+000A LF, advance position by 1 and append native line ending to result.
-
Let token be the result of collecting a sequence of code points that are not equal to U+000A LF or U+000D CR from s given position.
-
Append token to result.
-
-
Return result.
// Create a new Blob object var a= new Blob(); // Create a 1024-byte ArrayBuffer // buffer could also come from reading a File var buffer= new ArrayBuffer( 1024 ); // Create ArrayBufferView objects based on buffer var shorts= new Uint16Array( buffer, 512 , 128 ); var bytes= new Uint8Array( buffer, shorts. byteOffset+ shorts. byteLength); var b= new Blob([ "foobarbazetcetc" + "birdiebirdieboo" ], { type: "text/plain;charset=utf-8" }); var c= new Blob([ b, shorts]); var a= new Blob([ b, c, bytes]); var d= new Blob([ buffer, b, c, bytes]);
3.2. Attributes
size
, of type unsigned long long, readonly- Returns the size of the byte sequence in number of bytes.
On getting, conforming user agents must return the total number of bytes that can be read by a
FileReader
orFileReaderSync
object, or 0 if theBlob
has no bytes to be read. type
, of type DOMString, readonly-
The ASCII-encoded string in lower case representing the media type of the
Blob
. On getting, user agents must return the type of aBlob
as an ASCII-encoded string in lower case, such that when it is converted to a byte sequence, it is a parsable MIME type, or the empty string – 0 bytes – if the type cannot be determined.The
type
attribute can be set by the web application itself through constructor invocation and through theslice()
call; in these cases, further normative conditions for this attribute are in § 3.1 Constructors, § 4.1 Constructor, and § 3.3.1 The slice() method respectively. User agents can also determine thetype
of aBlob
, especially if the byte sequence is from an on-disk file; in this case, further normative conditions are in the file type guidelines.Note: The type t of a
Blob
is considered a parsable MIME type, if performing the parse a MIME type algorithm to a byte sequence converted from the ASCII-encoded string representing the Blob object’s type does not return failure.Note: Use of the
type
attribute informs the package data algorithm and determines theContent-Type
header when fetching blob URLs.
3.3. Methods and Parameters
3.3.1. The slice()
method
slice()
method
returns a new Blob
object with bytes ranging from the optional start parameter
up to but not including the optional end parameter, and with a type
attribute
that is the value of the optional contentType parameter. It must act as follows:
-
Let sliceStart, sliceEnd, and sliceContentType be null.
-
If start is given, set sliceStart to start.
-
If end is given, set sliceEnd to end.
-
If contentType is given, set sliceContentType to contentType.
-
Return the result of slice blob given this, sliceStart, sliceEnd, and sliceContentType.
slice()
calls possible. Since the File
interface inherits from the Blob
interface, examples are based on the use of the File
interface.
// obtain input element through DOM var file= document. getElementById( 'file' ). files[ 0 ]; if ( file) { // create an identical copy of file // the two calls below are equivalent var fileClone= file. slice(); var fileClone2= file. slice( 0 , file. size); // slice file into 1/2 chunk starting at middle of file // Note the use of negative number var fileChunkFromEnd= file. slice( - ( Math. round( file. size/ 2 ))); // slice file into 1/2 chunk starting at beginning of file var fileChunkFromStart= file. slice( 0 , Math. round( file. size/ 2 )); // slice file from beginning till 150 bytes before end var fileNoMetadata= file. slice( 0 , - 150 , "application/experimental" ); }
3.3.2. The stream()
method
The stream()
method, when invoked, must return
the result of calling get stream on this.
3.3.3. The text()
method
The text()
method, when invoked, must run these steps:
-
Let stream be the result of calling get stream on this.
-
Let reader be the result of getting a reader from stream. If that threw an exception, return a new promise rejected with that exception.
-
Let promise be the result of reading all bytes from stream with reader.
-
Return the result of transforming promise by a fulfillment handler that returns the result of running UTF-8 decode on its first argument.
Note: This is different from the behavior of readAsText()
to align better
with the behavior of Fetch’s text()
. Specifically this method will always
use UTF-8 as encoding, while FileReader
can use a different encoding depending on
the blob’s type and passed in encoding name.
3.3.4. The arrayBuffer()
method
The arrayBuffer()
method, when invoked, must run these steps:
-
Let stream be the result of calling get stream on this.
-
Let reader be the result of getting a reader from stream. If that threw an exception, return a new promise rejected with that exception.
-
Let promise be the result of reading all bytes from stream with reader.
-
Return the result of transforming promise by a fulfillment handler that returns a new
ArrayBuffer
whose contents are its first argument.
3.3.5. The bytes()
method
The bytes()
method, when invoked, must run these steps:
-
Let stream be the result of calling get stream on this.
-
Let reader be the result of getting a reader from stream. If that threw an exception, return a new promise rejected with that exception.
-
Let promise be the result of reading all bytes from stream with reader.
-
Return the result of transforming promise by a fulfillment handler that returns a new
Uint8Array
wrapping anArrayBuffer
containing its first argument.
4. The File Interface
A File
object is a Blob
object with a name
attribute, which is a string;
it can be created within the web application via a constructor,
or is a reference to a byte sequence from a file from the underlying (OS) file system.
If a File
object is a reference to a byte sequence originating from a file on disk,
then its snapshot state should be set to the state of the file on disk at the time the File
object is created.
Note: This is a non-trivial requirement to implement for user agents,
and is thus not a must but a should [RFC2119].
User agents should endeavor to have a File
object’s snapshot state set to the state of the underlying storage on disk at the time the reference is taken.
If the file is modified on disk following the time a reference has been taken,
the File
's snapshot state will differ from the state of the underlying storage.
User agents may use modification time stamps and other mechanisms to maintain snapshot state,
but this is left as an implementation detail.
When a File
object refers to a file on disk,
user agents must return the type
of that file,
and must follow the file type guidelines below:
-
User agents must return the
type
as an ASCII-encoded string in lower case, such that when it is converted to a corresponding byte sequence, it is a parsable MIME type, or the empty string – 0 bytes – if the type cannot be determined. -
When the file is of type
text/plain
user agents must NOT append a charset parameter to the dictionary of parameters portion of the media type [MIMESNIFF]. -
User agents must not attempt heuristic determination of encoding, including statistical methods.
[Exposed =(Window ,Worker ),Serializable ]interface :
File Blob {(
constructor sequence <BlobPart >fileBits ,USVString fileName ,optional FilePropertyBag = {});
options readonly attribute DOMString name ;readonly attribute long long lastModified ; };dictionary :
FilePropertyBag BlobPropertyBag {long long lastModified ; };
File
objects are serializable objects. Their serialization steps,
given value and serialized, are:
-
Set serialized.[[SnapshotState]] to value’s snapshot state.
-
Set serialized.[[ByteSequence]] to value’s underlying byte sequence.
-
Set serialized.[[Name]] to the value of value’s
name
attribute. -
Set serialized.[[LastModified]] to the value of value’s
lastModified
attribute.
Their deserialization steps, given value and serialized, are:
-
Set value’s snapshot state to serialized.[[SnapshotState]].
-
Set value’s underlying byte sequence to serialized.[[ByteSequence]].
-
Initialize the value of value’s
name
attribute to serialized.[[Name]]. -
Initialize the value of value’s
lastModified
attribute to serialized.[[LastModified]].
4.1. Constructor
File
constructor is invoked with two or three parameters,
depending on whether the optional dictionary parameter is used.
When the File()
constructor is invoked,
user agents must run the following steps:
-
Let bytes be the result of processing blob parts given
fileBits
andoptions
. -
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.
-
Process
FilePropertyBag
dictionary argument by running the following substeps:-
If the
type
member is provided and is not the empty string, let t be set to thetype
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. -
Convert every character in t to ASCII lowercase.
-
If the
lastModified
member is provided, let d be set to thelastModified
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 ofDate.now()
[ECMA-262]).Note: Since ECMA-262
Date
objects convert tolong long
values representing the number of milliseconds since the Unix Epoch, thelastModified
member could be aDate
object [ECMA-262].
-
-
Return a new
File
object F such that:-
F refers to the bytes byte sequence.
-
F.
size
is set to the number of total bytes in bytes. -
F.
name
is set to n. -
F.
type
is set to t. -
F.
lastModified
is set to d.
-
4.1.1. Constructor Parameters
The File()
constructor can be invoked with the parameters below:
- A
fileBits
sequence
-
which takes any number of the following elements, and in any order:
-
BufferSource
elements. -
USVString
elements.
-
- A
fileName
parameter - A
USVString
parameter representing the name of the file; normative conditions for this constructor parameter can be found in § 4.1 Constructor. - An optional
FilePropertyBag
dictionary -
which in addition to the members of
BlobPropertyBag
takes one member:-
An optional
lastModified
member, which must be along long
; normative conditions for this member are provided in § 4.1 Constructor.
-
4.2. Attributes
name
, of type DOMString, readonly- The name of the file.
On getting, this must return the name of the file as a string.
There are numerous file name variations and conventions used by different underlying OS file systems;
this is merely the name of the file, without path information.
On getting, if user agents cannot make this information available,
they must return the empty string.
If a
File
object is created using a constructor, further normative conditions for this attribute are found in § 4.1 Constructor. lastModified
, of type long long, readonly- The last modified date of the file.
On getting, if user agents can make this information available,
this must return a
long long
set to the time the file was last modified as the number of milliseconds since the Unix Epoch. If the last modification date and time are not known, the attribute must return the current date and time as along long
representing the number of milliseconds since the Unix Epoch; this is equivalent toDate
[ECMA-262]. If a. now() File
object is created using a constructor, further normative conditions for this attribute are found in § 4.1 Constructor.
The File
interface is available on objects that expose an attribute of type FileList
;
these objects are defined in HTML [HTML].
The File
interface, which inherits from Blob
, is immutable,
and thus represents file data that can be read into memory at the time a read operation is initiated.
User agents must process reads on files that no longer exist at the time of read as errors,
throwing a NotFoundError
exception
if using a FileReaderSync
on a Web Worker [Workers] or firing an error
event
with the error
attribute returning a NotFoundError
.
var file= document. getElementById( "filePicker" ). files[ 0 ]; var date= new Date( file. lastModified); println( "You selected the file " + file. name+ " which was modified on " + date. toDateString() + "." ); ... // Generate a file with a specific last modified date var d= new Date( 2013 , 12 , 5 , 16 , 23 , 45 , 600 ); var generatedFile= new File([ "Rough Draft ...." ], "Draft1.txt" , { type: "text/plain" , lastModified: d}) ...
5. The FileList Interface
Note: The FileList
interface should be considered "at risk"
since the general trend on the Web Platform is to replace such interfaces
with the Array
platform object in ECMAScript [ECMA-262].
In particular, this means syntax of the sort filelist
is at risk;
most other programmatic use of FileList
is unlikely to be affected by the eventual migration to an Array
type.
This interface is a list of File
objects.
[Exposed =(Window ,Worker ),Serializable ]interface {
FileList getter File ?item (unsigned long index );readonly attribute unsigned long length ; };
FileList
objects are serializable objects. Their serialization steps,
given value and serialized, are:
-
Set serialized.[[Files]] to an empty list.
-
For each file in value, append the sub-serialization of file to serialized.[[Files]].
Their deserialization step, given serialized and value, are:
-
For each file of serialized.[[Files]], add the sub-deserialization of file to value.
<input type="file">
element within a form,
and then accessing selected files.
// uploadData is a form element // fileChooser is input element of type 'file' var file= document. forms[ 'uploadData' ][ 'fileChooser' ]. files[ 0 ]; // alternative syntax can be // var file = document.forms['uploadData']['fileChooser'].files.item(0); if ( file) { // Perform file ops }
5.1. Attributes
length
, of type unsigned long, readonly- must return the number of files in the
FileList
object. If there are no files, this attribute must return 0.
5.2. Methods and Parameters
item(index)
-
must return the indexth
File
object in theFileList
. If there is no indexthFile
object in theFileList
, then this method must returnnull
.index
must be treated by user agents as value for the position of aFile
object in theFileList
, with 0 representing the first file. Supported property indices are the numbers in the range zero to one less than the number ofFile
objects represented by theFileList
object. If there are no suchFile
objects, then there are no supported property indices.
Note: The HTMLInputElement
interface has a readonly attribute of type FileList
,
which is what is being accessed in the above example.
Other interfaces with a readonly attribute of type FileList
include the DataTransfer
interface.
6. Reading Data
6.1. The File Reading Task Source
This specification defines a new generic task source called the file reading task source,
which is used for all tasks that are queued in this specification
to read byte sequences associated with Blob
and File
objects.
It is to be used for features that trigger in response to asynchronously reading binary data.
6.2. The FileReader
API
[Exposed =(Window ,Worker )]interface :
FileReader EventTarget {constructor (); // async read methodsundefined readAsArrayBuffer (Blob );
blob undefined readAsBinaryString (Blob );
blob undefined readAsText (Blob ,
blob optional DOMString );
encoding undefined readAsDataURL (Blob );
blob undefined abort (); // statesconst unsigned short = 0;
EMPTY const unsigned short = 1;
LOADING const unsigned short = 2;
DONE readonly attribute unsigned short readyState ; // File or Blob datareadonly attribute (DOMString or ArrayBuffer )?result ;readonly attribute DOMException ?error ; // event handler content attributesattribute EventHandler onloadstart ;attribute EventHandler onprogress ;attribute EventHandler onload ;attribute EventHandler onabort ;attribute EventHandler onerror ;attribute EventHandler onloadend ; };
A FileReader
has an associated state,
that is "empty"
, "loading"
, or "done"
. It is initially "empty"
.
A FileReader
has an associated result (null
, a DOMString
or an ArrayBuffer
). It is initially null
.
A FileReader
has an associated error (null
or a DOMException
). It is initially null
.
The FileReader()
constructor,
when invoked, must return a new FileReader
object.
The readyState
attribute’s getter,
when invoked, switches on this's state and runs the associated step:
The result
attribute’s getter,
when invoked, must return this's result.
The error
attribute’s getter,
when invoked, must return this's error.
FileReader
fr has an associated read operation algorithm,
which given blob, a type and an optional encodingName,
runs the following steps:
-
If fr’s state is
"loading"
, throw anInvalidStateError
DOMException
. -
Set fr’s state to
"loading"
. -
Set fr’s result to
null
. -
Set fr’s error to
null
. -
Let stream be the result of calling get stream on blob.
-
Let reader be the result of getting a reader from stream.
-
Let bytes be an empty byte sequence.
-
Let chunkPromise be the result of reading a chunk from stream with reader.
-
Let isFirstChunk be true.
-
In parallel, while true:
-
Wait for chunkPromise to be fulfilled or rejected.
-
If chunkPromise is fulfilled, and isFirstChunk is true, queue a task to fire a progress event called
loadstart
at fr.We might change
loadstart
to be dispatched synchronously, to align with XMLHttpRequest behavior. [Issue #119] -
Set isFirstChunk to false.
-
If chunkPromise is fulfilled with an object whose
done
property is false and whosevalue
property is aUint8Array
object, run these steps:-
Let bs be the byte sequence represented by the
Uint8Array
object. -
Append bs to bytes.
-
If roughly 50ms have passed since these steps were last invoked, queue a task to fire a progress event called
progress
at fr. -
Set chunkPromise to the result of reading a chunk from stream with reader.
-
-
Otherwise, if chunkPromise is fulfilled with an object whose
done
property is true, queue a task to run the following steps and abort this algorithm:-
Set fr’s state to
"done"
. -
Let result be the result of package data given bytes, type, blob’s
type
, and encodingName. -
If package data threw an exception error:
-
Set fr’s error to error.
-
Fire a progress event called
error
at fr.
-
-
Else:
-
Set fr’s
-
-
-