diff --git a/index.bs b/index.bs
index 16e2d30..98187dd 100644
--- a/index.bs
+++ b/index.bs
@@ -283,7 +283,7 @@ It can have the following values:
close code=] and |reason| as [=the WebSocket connection close reason=].
: |socket|.url
- :: Returns the URL that was used to establish the WebSocket connection.
+ :: Returns the URL that was used to establish the WebSocket connection.
: |socket|.readyState
:: Returns the state of the WebSocket connection. It can have the values described above.
@@ -323,14 +323,8 @@ It can have the following values:
constructor steps are:
1. Let |baseURL| be [=this=]'s [=relevant settings object=]'s [=API base URL=].
- 1. Let |urlRecord| be the result of applying the [=URL parser=] to |url| with |baseURL|.
- 1. If |urlRecord| is failure, then throw a "{{SyntaxError}}" {{DOMException}}.
- 1. If |urlRecord|'s [=url/scheme=] is "`http`", then set |urlRecord|'s [=url/scheme=] to "`ws`".
- 1. Otherwise, if |urlRecord|'s [=url/scheme=] is "`https`", set |urlRecord|'s [=url/scheme=] to
- "`wss`".
- 1. If |urlRecord|'s [=scheme=] is not "[=ws=]
" or "[=wss=]
", then throw a
- "{{SyntaxError}}" {{DOMException}}.
- 1. If |urlRecord|'s [=fragment=] is non-null, then throw a "{{SyntaxError}}" {{DOMException}}.
+ 1. Let |urlRecord| be the result of [=get a url record|getting a url record=] given |url| and
+ |baseURL|.
1. If |protocols| is a string, set |protocols| to a sequence consisting of just that string.
1. If any of the values in |protocols| occur more than once or otherwise fail to match the
requirements for elements that comprise the value of
@@ -366,58 +360,8 @@ string. After [=the WebSocket connection is established=], its value might chang
The connection is already closing or is already closed. If it has not already, a - {{WebSocket/close}} event will eventually fire as described below. - - : If the WebSocket connection is not yet [=established=] [[!WSP]] - :: [=Fail the WebSocket connection=] and set [=this=]'s [=WebSocket/ready state=] to - {{WebSocket/CLOSING}} (2). [[!WSP]] + 1. [=Close the WebSocket=] with this, |code|, and |reason|. -
The [=fail the WebSocket connection=] algorithm invokes the [=close the - WebSocket connection=] algorithm, which then establishes that [=the WebSocket connection is - closed=], which fires the {{WebSocket/close}} event as described - below. - - : If the WebSocket closing handshake has not yet been started [[!WSP]] - :: [=Start the WebSocket closing handshake=] and set [=this=]'s [=WebSocket/ready state=] to - {{WebSocket/CLOSING}} (2). [[!WSP]] - - If neither |code| nor |reason| is present, the WebSocket Close message must not have a body. - -
The WebSocket Protocol erroneously states that the status code is required for the [=start the WebSocket closing handshake=] algorithm.
-
-
- If |code| is present, then the status code to use in the WebSocket Close
- message must be the integer given by |code|. [[!WSP]]
-
- If |reason| is also present, then |reasonBytes| must be provided in the Close message after the
- status code. [[!WSP]]
-
- The [=start the WebSocket closing handshake=] algorithm eventually invokes the
- [=close the WebSocket connection=] algorithm, which then establishes that [=the WebSocket
- connection is closed=], which fires the {{WebSocket/close}} event as
- described below.
-
- : Otherwise
- :: Set [=this=]'s [=WebSocket/ready state=] to {{WebSocket/CLOSING}} (2).
-
- [=The WebSocket closing handshake is started=], and will eventually invoke the
- [=close the WebSocket connection=] algorithm, which will establish that [=the WebSocket
- connection is closed=], and thus the {{WebSocket/close}} event will fire, as described below.
-
The {{WebSocket/close()}} method does not discard previously sent messages before @@ -597,8 +541,8 @@ When [=a WebSocket message has been received=] with type |type| and data |data|, 1. [=Fire an event=] named message at the {{WebSocket}} object, using {{MessageEvent}}, with the {{MessageEvent/origin}} attribute initialized to the serialization of the {{WebSocket}} object's [=url=]'s [=origin=], and the - {{MessageEvent/data}} attribute initialized to |dataForEvent|. + serializer">serialization of the {{WebSocket}} object's [=internal-url|url=]'s [=origin=], + and the {{MessageEvent/data}} attribute initialized to |dataForEvent|.
User agents are encouraged to check if they can perform the above steps efficiently before they run the task, picking tasks from other [=task queues=] while they prepare the buffers @@ -832,14 +776,27 @@ dictionary WebSocketStreamOptions { }; -A {{WebSocketStream}} object has an associated url (a [=URL record=]). +A {{WebSocketStream}} object has an associated url (a [=URL +record=]). + +A {{WebSocketStream}} object has an associated opened promise. -A {{WebSocketStream}} object has an associated opened promise. +A {{WebSocketStream}} object has an associated closed promise. -A {{WebSocketStream}} object has an associated closed promise. +A {{WebSocketStream}} object has an associated readable stream, +which is initially unset. + +A {{WebSocketStream}} object has an associated writable stream, +which is initially unset. + +A {{WebSocketStream}} object has an associated was ever connected +flag, which is initially unset. + +A {{WebSocketStream}} object has an associated ready state, which +is a number representing the state of the connection. Initially it must be {{WebSocket/CONNECTING}} +(0). It has the same semantics as {{WebSocket}}'s [=WebSocket/ready state=], but is not exposed to +JavaScript. -A {{WebSocketStream}} object has an associated was ever connected flag, which is -initially unset.
|socket| = new {{WebSocketStream/constructor(url, options)|WebSocketStream}}(|url| [, |options| ]
@@ -864,7 +821,7 @@ initially unset.
signal does nothing.
: |socket| . {{WebSocketStream/url}}
- :: Returns the URL that was used to establish the WebSocket connection.
+ :: Returns the [=WebSocketStream/url|URL=] that was used to establish the WebSocket connection.
: |socket| . {{WebSocketStream/opened}}
:: Returns a {{promise}} which resolves when the handshake successfully completes, or rejects if
@@ -921,6 +878,235 @@ initially unset.
{{WebSocketCloseInfo/reason}} will be ignored.
new
+ WebSocketStream(|url|, |options|)
constructor steps are:
+
+ 1. Let |baseURL| be [=this=]'s [=relevant settings object=]'s [=API base URL=].
+ 1. Let |urlRecord| be the result of [=get a url record|getting a url record=] given |url| and
+ |baseURL|.
+ 1. Let |protocols| be |options|["{{WebSocketStreamOptions/protocols}}"] if it exists, otherwise an
+ empty sequence.
+ 1. If any of the values in |protocols| occur more than once or otherwise fail to match the
+ requirements for elements that comprise the value of
+ \``Sec-WebSocket-Protocol`\` fields as defined by The WebSocket protocol,
+ then throw a "{{SyntaxError}}" {{DOMException}}. [[!WSP]]
+ 1. Set [=this=]'s [=WebSocketStream/url=] to |urlRecord|.
+ 1. Set [=this=]'s [=WebSocketStream/opened promise=] and [=WebSocketStream/closed promise=] to new
+ promises.
+ 1. Let |client| be [=this=]'s [=relevant settings object=].
+ 1. Run this step [=in parallel=]:
+ 1. [=Establish a WebSocket connection=] given |urlRecord|, |protocols|, and |client|. [[!FETCH]]
+
+ If the [=establish a WebSocket connection=] algorithm fails, it triggers the + [=fail the WebSocket connection=] algorithm, which then invokes the [=close the WebSocket + connection=] algorithm, which then establishes that [=the WebSocket connection is closed=], + which rejects the {{WebSocketStream/opened}} and {{WebSocketStream/closed}} promises. +
|error| = new {{WebSocketError/constructor(message, init)|WebSocketError}}([|message| [,
@@ -968,6 +1154,115 @@ A {{WebSocketError}} object has an associated reason.
:: Returns the [=the WebSocket connection close reason=].
new
+WebSocketError(|message|, |init|)
constructor steps are:
+
+ 1. Set |this|'s [=DOMException/name=] to "WebSocketError
".
+ 1. Set |this|'s [=DOMException/message=] to |message|.
+ 1. Let |code| be |init|["{{WebSocketCloseInfo/closeCode}}"] if it exists, or unset otherwise.
+ 1. Let |reason| be |init|["{{WebSocketCloseInfo/reason}}"] if it exists, or unset otherwise.
+ 1. [=Validate close code and reason=] with |code| and |reason|.
+ 1. If |reason| is non-empty, but |code| is not set, then set |code| to 1000 ("Normal Closure").
+ 1. Set |this|'s [=WebSocketError/closeCode=] to |code|.
+ 1. Set |this|'s [=WebSocketError/reason=] to |reason|.
+[=ws=]
" or "[=wss=]
", then throw a
+ "{{SyntaxError}}" {{DOMException}}.
+ 1. If |urlRecord|'s [=fragment=] is non-null, then throw a "{{SyntaxError}}" {{DOMException}}.
+ 1. Return |urlRecord|.
+The connection is already closing or is already closed. If it has not already, a + {{WebSocket/close}} event will eventually fire if |this| is a {{WebSocket}}, or the + {{WebSocketStream/closed}} promise will become settled if |this| is a {{WebSocketStream}}. + + : If the WebSocket connection is not yet [=established=] [[!WSP]] + :: [=Fail the WebSocket connection=] and set [=this=]'s [=WebSocket/ready state=] to + {{WebSocket/CLOSING}} (2). [[!WSP]] + +
The [=fail the WebSocket connection=] algorithm invokes the [=close the + WebSocket connection=] algorithm, which then establishes that [=the WebSocket connection is + closed=], which fires the {{WebSocket/close}} event if |this| is a {{WebSocket}}, or settles + the {{WebSocketStream/closed}} promise if |this| is a {{WebSocketStream}}. + + : If the WebSocket closing handshake has not yet been started [[!WSP]] + :: [=Start the WebSocket closing handshake=] and set [=this=]'s [=WebSocket/ready state=] to + {{WebSocket/CLOSING}} (2). [[!WSP]] + + If neither |code| nor |reason| is set, the WebSocket Close message must not have a body. + +
The WebSocket Protocol erroneously states that the status code is required for the [=start the WebSocket closing handshake=] algorithm.
+
+
+ if |reason| is non-empty but |code| is not set, then set |code| to 1000 ("Normal Closure").
+
+ If |code| is set, then the status code to use in the WebSocket Close
+ message must be the integer given by |code|. [[!WSP]]
+
+ If |reason| is non-empty, then |reason|, encoded as UTF-8, must be
+ provided in the Close message after the status code. [[!WSP]]
+
+ The [=start the WebSocket closing handshake=] algorithm eventually invokes the
+ [=close the WebSocket connection=] algorithm, which then establishes that [=the WebSocket
+ connection is closed=], which fires the {{WebSocket/close}} event if |this| is a {{WebSocket}},
+ or settles the {{WebSocketStream/closed}} promise if |this| is a {{WebSocketStream}}.
+
+ : Otherwise
+ :: Set [=this=]'s [=WebSocket/ready state=] to {{WebSocket/CLOSING}} (2).
+
+ [=The WebSocket closing handshake is started=], and will eventually invoke the
+ [=close the WebSocket connection=] algorithm, which will establish that [=the WebSocket
+ connection is closed=], and thus the {{WebSocket/close}} event will fire or the
+ {{WebSocketStream/closed}} promise will resolve, depending on the type of |this|.
+