diff --git a/index.bs b/index.bs
index 69bb661..0f28ebd 100644
--- a/index.bs
+++ b/index.bs
@@ -56,6 +56,8 @@ spec: infra
text: list
text: string
spec: streams
+ type:interface
+ text:ReadableStream
type: dfn
text: chunk
spec: url
@@ -251,6 +253,28 @@ Their [=deserialization step=], given |serialized| and |value|, are:
2. Set |value|'s underlying byte sequence to |serialized|.\[[ByteSequence]].
+
@@ -444,7 +468,7 @@ run the following steps:
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 {{Blob/type}} attribute informs the
encoding determination
+ Note: Use of the {{Blob/type}} attribute informs the [=package data=] algorithm
and determines the `Content-Type` header when [=/fetching=] [=blob URLs=].
@@ -821,106 +845,15 @@ Other interfaces with a readonly attribute of type {{FileList}} include the {{Da
# Reading Data # {#reading-data-section}
-## The Read Operation ## {#readOperationSection}
-
-The algorithm below defines a
read operation,
-which takes a {{Blob}} and a
synchronous flag as input,
-and reads
bytes into a byte stream
-which is returned as the |result| of the
read operation,
-or else fails along with a
failure reason.
-Methods in this specification invoke the
read operation
-with the
synchronous flag either set or unset.
-
-The
synchronous flag determines if a read operation is synchronous or asynchronous,
-and is *unset* by default.
-Methods may set it.
-If it is set,
-the
read operation takes place synchronously.
-Otherwise, it takes place asynchronously.
-
-To perform a
read operation on a {{Blob}} and the
synchronous flag,
-run the following steps:
-
-1. Let |s| be a a new [=/body=],
- |b| be the {{Blob}} to be read from,
- and |bytes| initially set to an empty byte sequence.
- Set the [=body/total bytes=] on |s| to the {{Blob/size}} of |b|.
- While there are still bytes to be read in |b|,
- perform the following substeps:
-
- 1. If the
synchronous flag is set, follow the steps below:
- 1. Let |bytes| be the byte sequence that results from reading a
chunk from |b|.
- If a
file read error occurs reading a
chunk from |b|,
- return |s| with the error flag set,
- along with a
failure reason,
- and
terminate this algorithm.
-
- Note: Along with returning failure,
- the synchronous part of this algorithm must return the
failure reason that occurred
- for
throwing an exception by synchronous methods
- that invoke this algorithm with the
synchronous flag set.
-
- 2. If there are no errors,
- push |bytes| to |s|,
- and increment |s|'s |transmitted| [[Fetch]]
- by the number of bytes in |bytes|.
- Reset |bytes| to the empty byte sequence
- and continue reading
chunks as above.
-
- 3. When all the bytes of |b| have been read into |s|,
- return |s|
- and
terminate this algorithm.
-
- 2. Otherwise, the
synchronous flag is unset.
- Return |s| and process the rest of this algorithm asynchronously.
-
- 3. Let |bytes| be the byte sequence that results from reading a
chunk from |b|.
- If a
file read error occurs reading a
chunk from |b|,
- set the error flag on |s|,
- and
terminate this algorithm with a
failure reason.
-
- Note: The asynchronous part of this algorithm must signal the
failure reason that occurred
- for asynchronous error reporting by methods expecting |s|
- and which invoke this algorithm with the
synchronous flag unset.
-
- 4. If no
file read error occurs,
- push |bytes| to |s|,
- and increment |s|'s |transmitted| [[Fetch]]
- by the number of bytes in |bytes|.
- Reset |bytes| to the empty byte sequence
- and continue reading
chunks as above.
-
-To perform an
annotated task read operation
-on a {{Blob}} |b|,
-perform the steps below:
-
-1. Perform a
read operation on |b| with the
synchronous flag unset,
- along with the additional steps below.
-2. If the
read operation terminates with a
failure reason,
-
queue a task to
process read error with the
failure reason
- and terminate this algorithm.
-3. When the first
chunk is being pushed to the [=/body=] |s| during the
read operation,
-
queue a task to
process read.
-4. Once the [=/body=] |s| from the
read operation has at least one
chunk read into it,
- or there are no
chunks left to read from |b|,
-
queue a task to
process read data.
- Keep
queuing tasks to
process read data
- for every
chunk read or every 50ms,
- whichever is *least frequent*.
-5. When all of the
chunks from |b| are read into the [=/body=] |s| from the
read operation,
-
queue a task to
process read EOF.
-
-Use the
file reading task source for all these tasks.
-
-
## The File Reading Task Source ## {#blobreader-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
+This specification defines a new generic [=task source=] called the
+
file reading task source,
+which is used for all [=queue a task|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.
-## The FileReader API ## {#APIASynch}
+## The {{FileReader}} API ## {#APIASynch}
[Constructor, Exposed=(Window,Worker)]
@@ -939,7 +872,6 @@ interface FileReader: EventTarget {
const unsigned short LOADING = 1;
const unsigned short DONE = 2;
-
readonly attribute unsigned short readyState;
// File or Blob data
@@ -954,17 +886,101 @@ interface FileReader: EventTarget {
attribute EventHandler onabort;
attribute EventHandler onerror;
attribute EventHandler onloadend;
-
};
-### Constructor ### {#filereaderConstrctr}
-
-When the {{FileReader()}} constructor is invoked,
-the user agent must return a new {{FileReader}} object.
-
-In environments where the global object is represented by a {{Window}} or a {{WorkerGlobalScope}} object,
-the {{FileReader}} constructor must be available.
+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 the [=context object=]'s [=FileReader/state=]
+and runs the associated step:
+
+: `"empty"`
+:: Return {{EMPTY}}
+: `"loading"`
+:: Return {{LOADING}}
+: `"done"`
+:: Return {{DONE}}
+
+The
result attribute's getter,
+when invoked, must return the [=context object=]'s [=FileReader/result=].
+
+The
error attribute's getter,
+when invoked, must return the [=context object=]'s [=FileReader/error=].
+
+
+A {{FileReader}} |fr| has an associated read operation algorithm,
+which given |blob|, a |type| and an optional |encodingName|,
+runs the following steps:
+
+1. If |fr|'s [=FileReader/state=] is `"loading"`,
+ throw an {{InvalidStateError}} {{DOMException}}.
+1. Set |fr|'s [=FileReader/state=] to `"loading"`.
+1. Set |fr|'s [=FileReader/result=] to `null`.
+1. Set |fr|'s [=FileReader/error=] to `null`.
+1. Let |stream| be the result of calling [=get stream=] on |blob|.
+1. Let |reader| be the result of [=get a reader|getting a reader=] from |stream|.
+1. Let |bytes| by an empty [=byte sequence=].
+1. Let |chunkPromise| be the result of [=read a chunk|reading a chunk=] from |stream| with |reader|.
+1. Let |isFirstChunk| be true.
+1. [=In parallel=], while true:
+ 1. Wait for |chunkPromise| to be fulfilled or rejected.
+ 1. If |chunkPromise| is fulfilled, and |isFirstChunk| is true,
+ [=queue a task=] to [=fire a progress event=] called {{loadstart}} at |fr|.
+
+ Issue(119): We might change {{loadstart}} to be dispatched synchronously,
+ to align with XMLHttpRequest behavior.
+
+ 1. Set |isFirstChunk| to false.
+
+ 1. If |chunkPromise| is fulfilled with an object whose `done` property is false and whose `value`
+ property is a `Uint8Array` object, run these steps:
+ 1. Let |bs| be the [=byte sequence=] represented by the `Uint8Array` object.
+ 1. Append |bs| to |bytes|.
+ 1. If roughly 50ms have passed since these steps were last invoked,
+ [=queue a task=] to [=fire a progress event=] called {{progress}} at |fr|.
+ 1. Set |chunkPromise| to the result of [=read a chunk|reading a chunk=] from |stream| with |reader|.
+
+ 1. 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:
+ 1. Set |fr|'s [=FileReader/state=] to `"done"`.
+ 1. Let |result| be the result of
+ [=package data=] given |bytes|, |type|, |blob|'s {{Blob/type}}, and |encodingName|.
+ 1. If [=package data=] threw an exception |error|:
+ 1. Set |fr|'s [=FileReader/error=] to |error|.
+ 1. [=Fire a progress event=] called {{error!!event}} at |fr|.
+ 1. Else:
+ 1. Set |fr|'s [=FileReader/result=] to |result|.
+ 1. [=Fire a progress event=] called {{load}} at the |fr|.
+ 1. If |fr|'s [=FileReader/state=] is not `"loading"`,
+ [=fire a progress event=] called {{loadend}} at the |fr|.
+
+ Note: Event handler for the {{load}} or {{error!!event}} events could have started another load,
+ if that happens the {{loadend}} event for this load is not fired.
+
+ 1. Otherwise, if |chunkPromise| is rejected with an error |error|,
+ [=queue a task=] to run the following steps and abort this algorithm:
+ 1. Set |fr|'s [=FileReader/state=] to `"done"`.
+ 1. Set |fr|'s [=FileReader/error=] to |error|.
+ 1. [=Fire a progress event=] called {{error!!event}} at |fr|.
+ 1. If |fr|'s [=FileReader/state=] is not `"loading"`,
+ [=fire a progress event=] called {{loadend}} at |fr|.
+
+ Note: Event handler for the {{error!!event}} event could have started another load,
+ if that happens the {{loadend}} event for this load is not fired.
+
+Use the [=file reading task source=] for all these tasks.
+
### Event Handler Content Attributes ### {#event-handler-attributes-section}
@@ -1000,272 +1016,131 @@ that user agents must support on {{FileReader}} as DOM attributes:
### FileReader States ### {#blobreader-state}
+
The {{FileReader}} object can be in one of 3 states.
-The
readyState attribute,
-on getting,
-must return the current state,
-which must be one of the following values:
-
-
- - EMPTY (numeric value 0)
-
- The {{FileReader}} object has been constructed,
- and there are no pending reads.
- None of the read methods have been called.
- This is the default state of a newly minted {{FileReader}} object,
- until one of the read methods have been called on it.
-
- LOADING (numeric value 1)
-
- A {{File}} or {{Blob}} is being read.
- One of the read methods is being processed,
- and no error has occurred during the read.
-
- DONE (numeric value 2)
-
- The entire {{File}} or {{Blob}} has been read into memory,
- OR a file read error occurred,
- OR the read was aborted using {{FileReader/abort()}}.
- The {{FileReader}} is no longer reading a {{File}} or {{Blob}}.
- If {{FileReader/readyState}} is set to {{FileReader/DONE}}
- it means at least one of the read methods have been called on this {{FileReader}}.
-
+The {{FileReader/readyState}} attribute tells you in which state the object is:
+
+: {{EMPTY}} (numeric value 0)
+:: The {{FileReader}} object has been constructed,
+ and there are no pending reads.
+ None of the [=read methods=] have been called.
+ This is the default state of a newly minted {{FileReader}} object,
+ until one of the [=read methods=] have been called on it.
+: {{LOADING}} (numeric value 1)
+:: A {{File}} or {{Blob}} is being read.
+ One of the [=read methods=] is being processed,
+ and no error has occurred during the read.
+: {{DONE}} (numeric value 2)
+:: The entire {{File}} or {{Blob}} has been read into memory,
+ OR a [=file read error=] occurred,
+ OR the read was aborted using {{FileReader/abort()}}.
+ The {{FileReader}} is no longer reading a {{File}} or {{Blob}}.
+ If {{FileReader/readyState}} is set to {{FileReader/DONE}}
+ it means at least one of the [=read methods=] have been called on this {{FileReader}}.
+
+
### Reading a File or Blob ### {#reading-a-file}
The {{FileReader}} interface makes available several
asynchronous read methods--
{{FileReader/readAsArrayBuffer()}}, {{FileReader/readAsBinaryString()}}, {{FileReader/readAsText()}} and {{FileReader/readAsDataURL()}},
which read files into memory.
-If multiple concurrent read methods are called on the same {{FileReader}} object,
-user agents must throw an {{InvalidStateError}} on any of the read methods that occur
+
+Note: If multiple concurrent read methods are called on the same {{FileReader}} object,
+user agents throw an {{InvalidStateError}} on any of the read methods that occur
when {{FileReader/readyState}} = {{FileReader/LOADING}}.
-({{FileReaderSync}} makes available several
synchronous read methods.
+({{FileReaderSync}} makes available several [=synchronous read methods=].
Collectively, the sync and async read methods of {{FileReader}} and {{FileReaderSync}}
are referred to as just
read methods.)
-#### The {{FileReader/result}} attribute #### {#filedata-attr}
-
-On getting, the
result attribute returns a {{Blob}}'s data
-as a {{DOMString}}, or as an {{ArrayBuffer}}, or
null
,
-depending on the
read method that has been called on the {{FileReader}},
-and any errors that may have occurred.
-
-The list below is normative for the {{FileReader/result}} attribute
-and is the conformance criteria for this attribute:
-
-* On getting,
- if the {{FileReader/readyState}} is {{FileReader/EMPTY}}
- (no read method has been called)
- then the {{FileReader/result}} attribute must return
null
.
-* On getting,
- if an error in reading the {{File}} or {{Blob}} has occurred
- (using *any*
read method)
- then the {{FileReader/result}} attribute must return
null
.
-* On getting, if the {{FileReader/readAsDataURL()}}
read method is used,
- the {{FileReader/result}} attribute must return a {{DOMString}}
- that is a Data URL [[!RFC2397]] encoding of the {{File}} or {{Blob}}'s data.
-* On getting, if the {{FileReader/readAsBinaryString()}}
read method is called
- and no error in reading the {{File}} or {{Blob}} has occurred,
- then the {{FileReader/result}} attribute must return a {{DOMString}}
- representing the {{File}} or {{Blob}}'s data as a
binary string,
- in which every byte is represented by a code unit of equal value [0...255].
-* On getting, if the {{FileReader/readAsText()}}
read method is called
- and no error in reading the {{File}} or {{Blob}} has occurred,
- then the {{FileReader/result}} attribute must return a string
- representing the {{File}} or {{Blob}}'s data as a text string,
- and should decode the string into memory in the format specified by the
encoding determination as a {{DOMString}}.
-* On getting, if the {{FileReader/readAsArrayBuffer()}}
read method is called
- and no error in reading the {{File}} or {{Blob}} has occurred,
- then the {{FileReader/result}} attribute must return an {{ArrayBuffer}} object.
-
#### The {{FileReader/readAsDataURL()}} method #### {#readAsDataURL}
-When the
readAsDataURL(blob) method is called,
-the user agent must run the steps below.
-
-1. If {{FileReader/readyState}} = {{FileReader/LOADING}}
- throw an {{InvalidStateError}} exception and
terminate this algorithm.
-3. Otherwise set {{FileReader/readyState}} to {{FileReader/LOADING}}.
-4. Initiate an
annotated task read operation using the
blob
argument as |input|
- and handle
tasks queued on the
file reading task source per below.
-5. To
process read error with a
failure reason,
- proceed to [[#dfn-error-steps]].
-6. To
process read fire a progress event called {{loadstart}} at the
context object.
-7. To
process read data fire a progress event called {{progress}} at the
context object.
-8. To
process read EOF run these substeps:
- 1. Set {{FileReader/readyState}} to {{FileReader/DONE}}.
- 2. Set the {{FileReader/result}} attribute to the [=/body=] returned by the
read operation as a DataURL [[!RFC2397]];
- on getting, the {{FileReader/result}} attribute returns the
blob
as a Data URL [[!RFC2397]].
-
- * Use the
blob
's {{Blob/type}} attribute as part of the Data URL if it is available
- in keeping with the Data URL specification [[!RFC2397]].
- * If the {{Blob/type}} attribute is not available on the
blob
return a Data URL without a media-type. [[!RFC2397]].
- Data URLs that do not have media-types [[RFC2046]] must be treated as plain text by conforming user agents. [[!RFC2397]].
- 3.
Fire a progress event called {{load}} at the
context object.
- 4. Unless {{FileReader/readyState}} is {{FileReader/LOADING}}
-
fire a progress event called {{loadend}} at the
context object.
- If {{FileReader/readyState}} is {{FileReader/LOADING}} do NOT fire {{loadend}} at the
context object.
-9.
Terminate this algorithm.
+The
readAsDataURL(|blob|) method,
+when invoked, must initiate a [=read operation=] for |blob| with *DataURL*.
#### The {{FileReader/readAsText()}} method #### {#readAsDataText}
-The {{FileReader/readAsText()}} method can be called with an optional parameter,
-
encoding,
-which is a {{DOMString}} argument that represents the label of an encoding [[!Encoding]];
-if provided, it must be used as part of the
encoding determination used when processing this method call.
-
-When the
readAsText(blob, encoding) method is called,
-the user agent must run the steps below.
-
-1. If {{FileReader/readyState}} = {{FileReader/LOADING}} throw an {{InvalidStateError}} and
terminate this algorithm.
-3. Otherwise set {{FileReader/readyState}} to {{FileReader/LOADING}}.
-4. Initiate an
annotated task read operation using the
blob
argument as |input|
- and handle
tasks queued on the
file reading task source per below.
-5. To
process read error with a
failure reason,
- proceed to the [[#dfn-error-steps]].
-6. To
process read fire a progress event called {{loadstart}} at the
context object.
-7. To
process read data fire a progress event called {{progress}} at the
context object.
-8. To
process read EOF run these substeps:
- 1. Set {{FileReader/readyState}} to {{FileReader/DONE}}
- 2. Set the {{FileReader/result}} attribute to the [=/body=] returned by the
read operation,
- represented as a string in a format determined by the
encoding determination.
- 3.
Fire a progress event called {{load}} at the
context object.
- 4. Unless {{FileReader/readyState}} is {{FileReader/LOADING}}
-
fire a progress event called {{loadend}} at the
context object.
- If {{FileReader/readyState}} is {{FileReader/LOADING}}
- do NOT fire {{loadend}} at the
context object.
-9.
Terminate this algorithm.
+The
readAsText(|blob|, |encoding|) method,
+when invoked, must initiate a [=read operation=] for |blob| with *Text* and |encoding|.
#### The {{FileReader/readAsArrayBuffer()}} #### {#readAsArrayBuffer}
-When the
readAsArrayBuffer(blob) method is called,
-the user agent must run the steps below.
-
-1. If {{FileReader/readyState}} = {{FileReader/LOADING}} throw an {{InvalidStateError}} exception and
terminate this algorithm.
-3. Otherwise set {{FileReader/readyState}} to {{FileReader/LOADING}}.
-4. Initiate an
annotated task read operation using the
blob
argument as |input|
- and handle
tasks queued on the
file reading task source per below.
-5. To
process read error with a
failure reason,
- proceed to the [[#dfn-error-steps]].
-6. To
process read fire a progress event called {{loadstart}} at the
context object.
-7. To
process read data fire a progress event called {{progress}} at the
context object.
-8. To
process read EOF run these substeps:
- 1. Set {{FileReader/readyState}} to {{FileReader/DONE}}
- 2. Set the {{FileReader/result}} attribute to the [=/body=] returned by the
read operation as an {{ArrayBuffer}} object.
- 3.
Fire a progress event called {{load}} at the
context object.
- 4. Unless {{FileReader/readyState}} is {{FileReader/LOADING}}
-
fire a progress event called {{loadend}} at the
context object.
- If {{FileReader/readyState}} is {{FileReader/LOADING}}
- do NOT fire {{loadend}} at the
context object.
-9.
Terminate this algorithm.
+The
readAsArrayBuffer(|blob|) method,
+when invoked, must initiate a [=read operation=] for |blob| with *ArrayBuffer*.
#### The {{FileReader/readAsBinaryString()}} method #### {#readAsBinaryString}
-When the
readAsBinaryString(blob) method is called,
-the user agent must run the steps below.
-
-1. If {{FileReader/readyState}} = {{FileReader/LOADING}} throw an {{InvalidStateError}} exception and
terminate this algorithm.
-3. Otherwise set {{FileReader/readyState}} to {{FileReader/LOADING}}.
-4. Initiate an
annotated task read operation using the
blob
argument as |input|
- and handle
tasks queued on the
file reading task source per below.
-5. To
process read error with a
failure reason,
- proceed to the [[#dfn-error-steps]].
-6. To
process read fire a progress event called {{loadstart}} at the
context object.
-7. To
process read data fire a progress event called {{progress}} at the
context object.
-8. To
process read EOF run these substeps:
- 1. Set {{FileReader/readyState}} to {{FileReader/DONE}}
- 2. Set the {{FileReader/result}} attribute to the [=/body=] returned by the
read operation as a
binary string.
- 3.
Fire a progress event called {{load}} at the
context object.
- 4. Unless {{FileReader/readyState}} is {{FileReader/LOADING}}
-
fire a progress event called {{loadend}} at the
context object.
- If {{FileReader/readyState}} is {{FileReader/LOADING}}
- do NOT fire {{loadend}} at the
context object.
-9.
Terminate this algorithm.
-
-
- The use of {{FileReader/readAsArrayBuffer()}} is preferred over
- {{FileReader/readAsBinaryString()}}, which is provided for backwards
- compatibility.
-
-
-#### Error Steps #### {#dfn-error-steps}
-
-These error steps are to
process read error with a
failure reason.
+The
readAsBinaryString(|blob|) method,
+when invoked, must initiate a [=read operation=] for |blob| with *BinaryString*.
-1. Set the
context object's {{FileReader/readyState}} to {{FileReader/DONE}}
- and {{FileReader/result}} to null if it is not already set to null.
-2. Set the {{error!!attribute}} attribute on the
context object;
- on getting, the {{error!!attribute}} attribute must be a a {{DOMException}} object
- that corresponds to the
failure reason.
-
Fire a progress event called {{error!!event}} at the
context object.
-3. Unless {{FileReader/readyState}} is {{FileReader/LOADING}},
-
fire a progress event called {{loadend}} at the
context object.
- If {{FileReader/readyState}} is {{FileReader/LOADING}}
- do NOT fire {{loadend}} at the
context object.
-4.
Terminate the algorithm for any
read method.
+Note: The use of {{FileReader/readAsArrayBuffer()}} is preferred over
+{{FileReader/readAsBinaryString()}}, which is provided for backwards
+compatibility.
#### The {{FileReader/abort()}} method #### {#abort}
When the
abort() method is called,
the user agent must run the steps below:
-1. If {{FileReader/readyState}} = {{FileReader/EMPTY}}
- or if {{FileReader/readyState}} = {{FileReader/DONE}}
- set {{FileReader/result}} to
null
- and
terminate this algorithm.
-2. If {{FileReader/readyState}} = {{FileReader/LOADING}}
- set {{FileReader/readyState}} to {{FileReader/DONE}}
- and {{FileReader/result}} to
null
.
-3. If there are any
tasks from the
context object
- on the
file reading task source in an affiliated
task queue,
- then remove those
tasks from that task queue.
-4.
Terminate the algorithm for the
read method being processed.
-5.
Fire a progress event called {{abort}}.
-6.
Fire a progress event called {{loadend}}.
-
-#### Blob Parameters #### {#blobAndFileParams}
-
-The
asynchronous read methods,
-the
synchronous read methods, and
-
URL.{{URL/createObjectURL()}}
-take a {{Blob}} parameter.
-This section defines this parameter.
-
-
- - blob
-
- This is a {{Blob}} argument
- and must be a reference to a single {{File}} in a {{FileList}}
- or a {{Blob}} argument not obtained from the underlying OS file system.
-
-
-
-## Determining Encoding ## {#enctype}
-
-When reading {{Blob}} objects using the {{FileReader/readAsText()}}
read method,
-the following
encoding determination steps must be followed:
-
-1. Let |encoding| be null.
-2. If the {{FileReader/readAsText()/encoding}} argument is present when calling the method,
- set |encoding| to the result of the
getting an encoding from {{FileReader/readAsText()/encoding}}.
-3. If the
getting an encoding steps above return failure,
- then set |encoding| to null.
-4. If |encoding| is null,
- and the {{FileReader/readAsText()/blob}} argument's {{Blob/type}} attribute is present,
- and it uses a Charset Parameter [[RFC2046]],
- set |encoding| to the result of
getting an encoding
- for the portion of the Charset Parameter that is a
label of an encoding.
+1. If [=context object=]'s [=FileReader/state=] is `"empty"`
+ or if [=context object=]'s [=FileReader/state=] is `"done"`
+ set [=context object=]'s [=FileReader/result=] to `null`
+ and [=terminate this algorithm=].
+1. If [=context object=]'s [=FileReader/state=] is `"loading"`
+ set [=context object=]'s [=FileReader/state=] to `"done"`
+ and set [=context object=]'s [=FileReader/result=] to `null`.
+1. If there are any [=tasks=] from the [=context object=]
+ on the [=file reading task source=] in an affiliated [=queue a task|task queue=],
+ then remove those [=tasks=] from that task queue.
+1. [=terminate an algorithm|Terminate the algorithm=] for the [=read method=] being processed.
+1. [=Fire a progress event=] called {{abort}} at the [=context object=].
+1. If [=context object=]'s [=FileReader/state=] is not `"loading"`,
+ [=fire a progress event=] called {{loadend}} at the [=context object=].
+
+## Packaging data ## {#packaging-data}
+
+
+A {{Blob}} has an associated
package data algorithm,
+given |bytes|, a |type|, a optional |mimeType|, and a optional |encodingName|,
+which switches on |type| and runs the associated steps:
+
+: DataURL
+:: Return |bytes| as a DataURL [[!RFC2397]] subject to the considerations below:
+
+ * Use |mimeType| as part of the Data URL if it is available
+ in keeping with the Data URL specification [[!RFC2397]].
+ * If |mimeType| is not available return a Data URL without a media-type. [[!RFC2397]].
+
+ Issue(104): Better specify how the DataURL is generated.
+
+: Text
+:: 1. Let |encoding| be failure.
+ 1. If the |encodingName| is present, set |encoding| to the result of
+ [=getting an encoding=] from |encodingName|.
+ 1. If |encoding| is failure, and |mimeType| is present:
+ 1. Let |type| be the result of [=parse a MIME type=] given |mimeType|.
+ 1. If |type| is not failure,
+ set |encoding| to the result of [=getting an encoding=]
+ from |type|'s [=MIME type/parameters=][`"charset"`].
+
+
+ If `blob` has a {{Blob/type}} attribute of `text/plain;charset=utf-8`
+ then
getting an encoding is run using `"utf-8"` as the label.
+ Note that user agents must parse and extract the portion of the Charset Parameter
+ that constitutes a *label* of an encoding.
+
+ 1. If |encoding| is failure, then set |encoding| to [=UTF-8=].
+ 1. [=Decode=] |bytes| using fallback encoding |encoding|, and return the result.
+
+: ArrayBuffer
+:: Return a new `ArrayBuffer` whose contents are |bytes|.
+
+: BinaryString
+:: Return |bytes| as a binary string,
+ in which every byte is represented by a code unit of equal value [0..255].
-
- If
blob
has a {{Blob/type}} attribute of
text/plain;charset=utf-8
- then
getting an encoding is run using
"utf-8"
as the label.
- Note that user agents must parse and extract the portion of the Charset Parameter that constitutes a
label of an encoding.
-
-5. If the
getting an encoding steps above return failure,
- then set |encoding| to null.
-6. If |encoding| is null,
- then set encoding to utf-8.
-7.
Decode this
blob
using fallback encoding |encoding|,
- and return the result.
- On getting, the {{FileReader/result}} attribute of the {{FileReader}} object
- returns a string in |encoding| format.
- The synchronous {{FileReaderSync/readAsText()}} method of the {{FileReaderSync}} object
- returns a string in |encoding| format.
+
## Events ## {#events}
@@ -1391,71 +1266,61 @@ interface FileReaderSync {
When the {{FileReaderSync()}} constructor is invoked,
the user agent must return a new {{FileReaderSync}} object.
-In environments where the global object is represented by a {{WorkerGlobalScope}} object,
-the {{FileReaderSync}} constructor must be available.
-
#### The {{FileReaderSync/readAsText()}} #### {#readAsTextSync}
-When the
readAsText(blob, encoding) method is called,
-the following steps must be followed:
+The
readAsText(|blob|, |encoding|) method,
+when invoked, must run these steps:
-1. Initiate a
read operation using the
blob
argument,
- and with the
synchronous flag *set*.
- If the read operation returns failure,
- throw the appropriate exception as defined in [[#dfn-error-codes]].
-
Terminate this algorithm.
-1. If no error has occurred,
- return the |result| of the
read operation represented as a string
- in a format determined through the
encoding determination algorithm.
+1. Let |stream| be the result of calling [=get stream=] on |blob|.
+1. Let |reader| be the result of [=get a reader|getting a reader=] from |stream|.
+1. Let |promise| be the result of [=read all bytes|reading all bytes=] from |stream| with |reader|.
+1. Wait for |promise| to be fulfilled or rejected.
+1. If |promise| fulfilled with a [=byte sequence=] |bytes|:
+ 1. Return the result of [=package data=] given |bytes|, *Text*, |blob|'s {{Blob/type}}, and |encoding|.
+1. Throw |promise|'s rejection reason.
#### The {{FileReaderSync/readAsDataURL()}} method #### {#readAsDataURLSync-section}
-When the
readAsDataURL(blob) method is called,
-the following steps must be followed:
+The
readAsDataURL(|blob|) method,
+when invoked, must run these steps:
-1. Initiate a
read operation using the
blob
argument,
- and with the
synchronous flag *set*.
- If the
read operation returns failure,
- throw the appropriate exception as defined in [[#dfn-error-codes]].
-
Terminate this algorithm.
-1. If no error has occurred, return the |result| of the
read operation
- as a Data URL [[!RFC2397]] subject to the considerations below:
-
- * Use the
blob
's {{Blob/type}} attribute as part of the Data URL if it is available
- in keeping with the Data URL specification [[!RFC2397]].
- * If the {{Blob/type}} attribute is not available on the
blob
return a Data URL without a media-type. [[!RFC2397]].
- Data URLs that do not have media-types [[RFC2046]] must be treated as plain text by conforming user agents. [[!RFC2397]].
+1. Let |stream| be the result of calling [=get stream=] on |blob|.
+1. Let |reader| be the result of [=get a reader|getting a reader=] from |stream|.
+1. Let |promise| be the result of [=read all bytes|reading all bytes=] from |stream| with |reader|.
+1. Wait for |promise| to be fulfilled or rejected.
+1. If |promise| fulfilled with a [=byte sequence=] |bytes|:
+ 1. Return the result of [=package data=] given |bytes|, *DataURL*, and |blob|'s {{Blob/type}}.
+1. Throw |promise|'s rejection reason.
#### The {{FileReaderSync/readAsArrayBuffer()}} method #### {#readAsArrayBufferSyncSection}
-When the
readAsArrayBuffer(blob) method is called,
-the following steps must be followed:
+The
readAsArrayBuffer(|blob|) method,
+when invoked, must run these steps:
-1. Initiate a
read operation using the
blob
argument,
- and with the
synchronous flag *set*.
- If the
read operation returns failure,
- throw the appropriate exception as defined in [[#dfn-error-codes]].
-
Terminate this algorithm.
-1. If no error has occurred, return the |result| of the
read operation as an {{ArrayBuffer}}.
+1. Let |stream| be the result of calling [=get stream=] on |blob|.
+1. Let |reader| be the result of [=get a reader|getting a reader=] from |stream|.
+1. Let |promise| be the result of [=read all bytes|reading all bytes=] from |stream| with |reader|.
+1. Wait for |promise| to be fulfilled or rejected.
+1. If |promise| fulfilled with a [=byte sequence=] |bytes|:
+ 1. Return the result of [=package data=] given |bytes|, *ArrayBuffer*, and |blob|'s {{Blob/type}}.
+1. Throw |promise|'s rejection reason.
#### The {{FileReaderSync/readAsBinaryString()}} method #### {#readAsBinaryStringSyncSection}
-When the
readAsBinaryString(blob) method is called,
-the following steps must be followed:
-
-1. Initiate a
read operation using the
blob
argument,
- and with the
synchronous flag *set*.
- If the
read operation returns failure,
- throw the appropriate exception as defined in [[#dfn-error-codes]].
-
Terminate this algorithm.
-1. If no error has occurred, return the |result| of the
-
read operation as an
binary string.
-
-
- The use of {{FileReaderSync/readAsArrayBuffer()}} is preferred over
- {{FileReaderSync/readAsBinaryString()}}, which is provided for
- backwards compatibility.
-
+The
readAsBinaryString(|blob|) method,
+when invoked, must run these steps:
+
+1. Let |stream| be the result of calling [=get stream=] on |blob|.
+1. Let |reader| be the result of [=get a reader|getting a reader=] from |stream|.
+1. Let |promise| be the result of [=read all bytes|reading all bytes=] from |stream| with |reader|.
+1. Wait for |promise| to be fulfilled or rejected.
+1. If |promise| fulfilled with a [=byte sequence=] |bytes|:
+ 1. Return the result of [=package data=] given |bytes|, *BinaryString*, and |blob|'s {{Blob/type}}.
+1. Throw |promise|'s rejection reason.
+
+Note: The use of {{FileReaderSync/readAsArrayBuffer()}} is preferred over
+{{FileReaderSync/readAsBinaryString()}}, which is provided for
+backwards compatibility.
# Errors and Exceptions # {#ErrorAndException}
@@ -1486,15 +1351,14 @@ The list below of potential error conditions is *informative*.
Error conditions can arise when reading a {{File}} or a {{Blob}}.
The
read operation can terminate due to error conditions when reading a {{File}} or a {{Blob}};
-the particular error condition that causes a read operation to return failure
-or
queue a task to
process read error
+the particular error condition that causes the [=get stream=] algorithm to fail
is called a
failure reason. A
failure reason is one of
[=NotFound=], [=UnsafeFile=], [=TooManyReads=], [=SnapshotState=], or [=FileLock=].
Synchronous read methods
throw exceptions of the type in the table below
if there has been an error owing to a particular
failure reason.
-Asynchronous read methods use the
error attribute of the {{FileReader}} object,
+Asynchronous read methods use the {{FileReader/error!!attribute}} attribute of the {{FileReader}} object,
which must return a {{DOMException}} object of the most appropriate type from the table below
if there has been an error owing to a particular
failure reason,
or otherwise return null.