Skip to content

Commit 87654f5

Browse files
committed
LibWeb: Start fleshing out the ReadableStream interface
This is so we can just assume it exists in Fetch APIs (while still skipping functionality that relies on a full implementation, of course).
1 parent 1ace802 commit 87654f5

File tree

9 files changed

+199
-4
lines changed

9 files changed

+199
-4
lines changed

Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,8 @@
301301
#include <LibWeb/Bindings/PromiseRejectionEventPrototype.h>
302302
#include <LibWeb/Bindings/RangeConstructor.h>
303303
#include <LibWeb/Bindings/RangePrototype.h>
304+
#include <LibWeb/Bindings/ReadableStreamConstructor.h>
305+
#include <LibWeb/Bindings/ReadableStreamPrototype.h>
304306
#include <LibWeb/Bindings/ResizeObserverConstructor.h>
305307
#include <LibWeb/Bindings/ResizeObserverPrototype.h>
306308
#include <LibWeb/Bindings/SVGAnimatedLengthConstructor.h>
@@ -543,6 +545,7 @@
543545
ADD_WINDOW_OBJECT_INTERFACE(ProgressEvent) \
544546
ADD_WINDOW_OBJECT_INTERFACE(PromiseRejectionEvent) \
545547
ADD_WINDOW_OBJECT_INTERFACE(Range) \
548+
ADD_WINDOW_OBJECT_INTERFACE(ReadableStream) \
546549
ADD_WINDOW_OBJECT_INTERFACE(ResizeObserver) \
547550
ADD_WINDOW_OBJECT_INTERFACE(Screen) \
548551
ADD_WINDOW_OBJECT_INTERFACE(Selection) \

Userland/Libraries/LibWeb/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ set(SOURCES
364364
Platform/TimerSerenity.cpp
365365
RequestIdleCallback/IdleDeadline.cpp
366366
ResizeObserver/ResizeObserver.cpp
367+
Streams/AbstractOperations.cpp
368+
Streams/ReadableStream.cpp
367369
SVG/AttributeNames.cpp
368370
SVG/AttributeParser.cpp
369371
SVG/SVGAnimatedLength.cpp

Userland/Libraries/LibWeb/Forward.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,14 @@ namespace Web::ResizeObserver {
366366
class ResizeObserver;
367367
}
368368

369+
namespace Web::Selection {
370+
class Selection;
371+
}
372+
373+
namespace Web::Streams {
374+
class ReadableStream;
375+
}
376+
369377
namespace Web::SVG {
370378
class SVGAnimatedLength;
371379
class SVGCircleElement;
@@ -384,10 +392,6 @@ class SVGRectElement;
384392
class SVGSVGElement;
385393
}
386394

387-
namespace Web::Selection {
388-
class Selection;
389-
}
390-
391395
namespace Web::WebSockets {
392396
class WebSocket;
393397
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#include <LibWeb/Streams/AbstractOperations.h>
8+
#include <LibWeb/Streams/ReadableStream.h>
9+
10+
namespace Web::Streams {
11+
12+
// https://streams.spec.whatwg.org/#is-readable-stream-locked
13+
bool is_readable_stream_locked(ReadableStream const& stream)
14+
{
15+
// 1. If stream.[[reader]] is undefined, return false.
16+
if (stream.reader() == nullptr)
17+
return false;
18+
19+
// 2. Return true.
20+
return true;
21+
}
22+
23+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#pragma once
8+
9+
#include <LibWeb/Forward.h>
10+
11+
namespace Web::Streams {
12+
13+
bool is_readable_stream_locked(ReadableStream const&);
14+
15+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#include <LibWeb/HTML/Window.h>
8+
#include <LibWeb/Streams/AbstractOperations.h>
9+
#include <LibWeb/Streams/ReadableStream.h>
10+
11+
namespace Web::Streams {
12+
13+
// https://streams.spec.whatwg.org/#rs-constructor
14+
DOM::ExceptionOr<JS::NonnullGCPtr<ReadableStream>> ReadableStream::create_with_global_object(HTML::Window& window)
15+
{
16+
auto* readable_stream = window.heap().allocate<ReadableStream>(window.realm(), window);
17+
18+
return JS::NonnullGCPtr { *readable_stream };
19+
}
20+
21+
ReadableStream::ReadableStream(HTML::Window& window)
22+
: PlatformObject(window.realm())
23+
{
24+
set_prototype(&window.cached_web_prototype("ReadableStream"));
25+
}
26+
27+
ReadableStream::~ReadableStream() = default;
28+
29+
void ReadableStream::visit_edges(Cell::Visitor& visitor)
30+
{
31+
Base::visit_edges(visitor);
32+
visitor.visit(m_controller);
33+
visitor.visit(m_reader);
34+
visitor.visit(m_stored_error);
35+
}
36+
37+
// https://streams.spec.whatwg.org/#readablestream-locked
38+
bool ReadableStream::is_readable() const
39+
{
40+
// A ReadableStream stream is readable if stream.[[state]] is "readable".
41+
return m_state == State::Readable;
42+
}
43+
44+
// https://streams.spec.whatwg.org/#readablestream-closed
45+
bool ReadableStream::is_closed() const
46+
{
47+
// A ReadableStream stream is closed if stream.[[state]] is "closed".
48+
return m_state == State::Closed;
49+
}
50+
51+
// https://streams.spec.whatwg.org/#readablestream-errored
52+
bool ReadableStream::is_errored() const
53+
{
54+
// A ReadableStream stream is errored if stream.[[state]] is "errored".
55+
return m_state == State::Errored;
56+
}
57+
// https://streams.spec.whatwg.org/#readablestream-locked
58+
bool ReadableStream::is_locked() const
59+
{
60+
// A ReadableStream stream is locked if ! IsReadableStreamLocked(stream) returns true.
61+
return is_readable_stream_locked(*this);
62+
}
63+
64+
// https://streams.spec.whatwg.org/#is-readable-stream-disturbed
65+
bool ReadableStream::is_disturbed() const
66+
{
67+
// A ReadableStream stream is disturbed if stream.[[disturbed]] is true.
68+
return m_disturbed;
69+
}
70+
71+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#pragma once
8+
9+
#include <AK/Forward.h>
10+
#include <LibJS/Forward.h>
11+
#include <LibWeb/Bindings/PlatformObject.h>
12+
#include <LibWeb/Forward.h>
13+
14+
namespace Web::Streams {
15+
16+
// https://streams.spec.whatwg.org/#readablestream
17+
class ReadableStream final : public Bindings::PlatformObject {
18+
WEB_PLATFORM_OBJECT(Request, Bindings::PlatformObject);
19+
20+
public:
21+
enum class State {
22+
Readable,
23+
Closed,
24+
Errored,
25+
};
26+
27+
static DOM::ExceptionOr<JS::NonnullGCPtr<ReadableStream>> create_with_global_object(HTML::Window&);
28+
29+
virtual ~ReadableStream() override;
30+
31+
JS::GCPtr<JS::Object> controller() const { return m_controller; }
32+
JS::GCPtr<JS::Object> reader() const { return m_reader; }
33+
JS::Value stored_error() const { return m_stored_error; }
34+
35+
bool is_readable() const;
36+
bool is_closed() const;
37+
bool is_errored() const;
38+
bool is_locked() const;
39+
bool is_disturbed() const;
40+
41+
private:
42+
explicit ReadableStream(HTML::Window&);
43+
44+
virtual void visit_edges(Cell::Visitor&) override;
45+
46+
// https://streams.spec.whatwg.org/#readablestream-controller
47+
// A ReadableStreamDefaultController or ReadableByteStreamController created with the ability to control the state and queue of this stream
48+
JS::GCPtr<JS::Object> m_controller;
49+
50+
// https://streams.spec.whatwg.org/#readablestream-detached
51+
// A boolean flag set to true when the stream is transferred
52+
bool m_detached { false };
53+
54+
// https://streams.spec.whatwg.org/#readablestream-disturbed
55+
// A boolean flag set to true when the stream has been read from or canceled
56+
bool m_disturbed { false };
57+
58+
// https://streams.spec.whatwg.org/#readablestream-reader
59+
// A ReadableStreamDefaultReader or ReadableStreamBYOBReader instance, if the stream is locked to a reader, or undefined if it is not
60+
JS::GCPtr<JS::Object> m_reader;
61+
62+
// https://streams.spec.whatwg.org/#readablestream-state
63+
// A string containing the stream’s current state, used internally; one of "readable", "closed", or "errored"
64+
State m_state { State::Readable };
65+
66+
// https://streams.spec.whatwg.org/#readablestream-storederror
67+
// A value indicating how the stream failed, to be given as a failure reason or exception when trying to operate on an errored stream
68+
JS::Value m_stored_error { JS::js_undefined() };
69+
};
70+
71+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Dummy definition so we can use ReadableStream as a type in Fetch.
2+
3+
// https://streams.spec.whatwg.org/#readablestream
4+
interface ReadableStream {
5+
};

Userland/Libraries/LibWeb/idl_files.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ libweb_js_bindings(IntersectionObserver/IntersectionObserver)
159159
libweb_js_bindings(NavigationTiming/PerformanceTiming)
160160
libweb_js_bindings(RequestIdleCallback/IdleDeadline)
161161
libweb_js_bindings(ResizeObserver/ResizeObserver)
162+
libweb_js_bindings(Streams/ReadableStream)
162163
libweb_js_bindings(SVG/SVGAnimatedLength)
163164
libweb_js_bindings(SVG/SVGClipPathElement)
164165
libweb_js_bindings(SVG/SVGDefsElement)

0 commit comments

Comments
 (0)