[Streams API] Implement ReadableStreamController
authoryouenn.fablet@crf.canon.fr <youenn.fablet@crf.canon.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Apr 2015 15:55:20 +0000 (15:55 +0000)
committeryouenn.fablet@crf.canon.fr <youenn.fablet@crf.canon.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Apr 2015 15:55:20 +0000 (15:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=143608

Reviewed by Benjamin Poulain.

Source/WebCore:

Introducing ReadableStreamController, an abstraction to manage JS source stream queues.
This new interface is not exposed to JS scripts as specified, using NoInterfaceObject.

A controller is created at the time a ReadableJSStream is started and it is owned by it.
The controller may outlive the stream but as its reference will be reset, the calls to
its methods would result in exceptions.

The constructor is not implemented yet.

Change covered by existing tests and rebased expectations.

* CMakeLists.txt:
* DerivedSources.cpp:
* DerivedSources.make: Added ReadableStreamController.idl related files.
* Modules/streams/ReadableStreamController.h: Added.
* Modules/streams/ReadableStreamController.idl: Added.
* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.vcxproj/WebCore.vcxproj.filters:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSBindingsAllInOne.cpp: Added ReadableStreamController.idl related files.
* bindings/js/JSReadableStreamControllerCustom.cpp: Added.
* bindings/js/ReadableStreamJSSource.cpp:
* bindings/js/ReadableStreamJSSource.h: Removed custom controller implementation.

LayoutTests:

Updated expectations as more tests are passed.
ReadableStreamController constructor tests fail due to the custom constructor being not implemented yet.
Added a test to ensure that calling a controller method when its stream is collected is throwing an error.

* streams/readable-stream.html:
* streams/readable-stream-expected.txt:
* streams/reference-implementation/bad-underlying-sources-expected.txt:
* streams/reference-implementation/brand-checks-expected.txt:
* streams/reference-implementation/count-queuing-strategy-expected.txt:
* streams/reference-implementation/readable-stream-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@183107 268f45cc-cd09-0410-ab3c-d52691b4dbfc

20 files changed:
LayoutTests/ChangeLog
LayoutTests/streams/readable-stream-expected.txt
LayoutTests/streams/readable-stream.html
LayoutTests/streams/reference-implementation/bad-underlying-sources-expected.txt
LayoutTests/streams/reference-implementation/brand-checks-expected.txt
LayoutTests/streams/reference-implementation/count-queuing-strategy-expected.txt
LayoutTests/streams/reference-implementation/readable-stream-expected.txt
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/DerivedSources.cpp
Source/WebCore/DerivedSources.make
Source/WebCore/Modules/streams/ReadableStreamController.h [new file with mode: 0644]
Source/WebCore/Modules/streams/ReadableStreamController.idl [new file with mode: 0644]
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/JSBindingsAllInOne.cpp
Source/WebCore/bindings/js/JSReadableStreamControllerCustom.cpp [new file with mode: 0644]
Source/WebCore/bindings/js/ReadableStreamJSSource.cpp
Source/WebCore/bindings/js/ReadableStreamJSSource.h

index d886ce5..33d0287 100644 (file)
@@ -1,3 +1,21 @@
+2015-04-22  Xabier Rodriguez Calvar  <calvaris@igalia.com> and Youenn Fablet  <youenn.fablet@crf.canon.fr>
+
+        [Streams API] Implement ReadableStreamController
+        https://bugs.webkit.org/show_bug.cgi?id=143608
+
+        Reviewed by Benjamin Poulain.
+
+        Updated expectations as more tests are passed.
+        ReadableStreamController constructor tests fail due to the custom constructor being not implemented yet.
+        Added a test to ensure that calling a controller method when its stream is collected is throwing an error.
+
+        * streams/readable-stream.html:
+        * streams/readable-stream-expected.txt:
+        * streams/reference-implementation/bad-underlying-sources-expected.txt:
+        * streams/reference-implementation/brand-checks-expected.txt:
+        * streams/reference-implementation/count-queuing-strategy-expected.txt:
+        * streams/reference-implementation/readable-stream-expected.txt:
+
 2015-04-22  Marcos Chavarría Teijeiro  <chavarria1991@gmail.com>
 
         [GTK] Gardening 21st April.
index 2d5229b..a791305 100644 (file)
@@ -1,6 +1,6 @@
 
 PASS ReadableStream can't be constructed with garbage 
-FAIL ReadableStream start should be called with the proper parameters null is not an object (evaluating 'Object.getOwnPropertyNames(Object.getPrototypeOf(controller))')
-FAIL ReadableStream start controller parameter should be updatable null is not an object (evaluating 'Object.getOwnPropertyNames(Object.getPrototypeOf(controller))')
+PASS ReadableStream start should be called with the proper parameters 
 PASS ReadableStream should be able to call start method within prototype chain of its source 
+PASS A readable stream controller methods should throw if its readablestream is collected 
 
index 3f4053b..e5aeff7 100644 (file)
@@ -1,6 +1,7 @@
 <!DOCTYPE html>
 <script src='../resources/testharness.js'></script>
 <script src='../resources/testharnessreport.js'></script>
+<script src='../resources/gc.js'></script>
 <script>
 test(function() {
     assert_throws(new TypeError(), function() {
@@ -15,21 +16,17 @@ test(function()
         start: function(controller) {
             assert_equals(this, source, 'source is this during start');
 
-            var unnamedMethods = [ 'close', 'enqueue', 'error' ];
-            var methods = unnamedMethods.concat(['constructor']).sort();
+            // FIXME: We should add constructor at some point.
+            var methods = [ 'close', 'enqueue', 'error' ];
             var proto = Object.getPrototypeOf(controller);
 
             assert_array_equals(Object.getOwnPropertyNames(Object.getPrototypeOf(controller)).sort(), methods,
                         'the controller should have the right methods');
 
-            for (var m of unnamedMethods) {
-                assert_equals(controller[m].name, '', 'method should have no name');
-            }
-
             for (var m of methods) {
-                var methodProperties = [ 'arguments', 'caller', 'length', 'name', 'prototype' ];
+                var methodProperties = [ 'length', 'name' ];
                 var propDesc = Object.getOwnPropertyDescriptor(proto, m);
-                assert_equals(propDesc.enumerable, false, 'method should be non-enumerable');
+                assert_equals(propDesc.enumerable, true, 'method should be enumerable');
                 assert_equals(propDesc.configurable, true, 'method should be configurable');
                 assert_equals(propDesc.writable, true, 'method should be writable');
                 assert_equals(typeof controller[m], 'function', 'should have be a method');
@@ -37,9 +34,9 @@ test(function()
             }
 
             assert_equals(controller.close.length, 0, 'close should have no parameters');
-            assert_equals(controller.constructor.length, 1, 'constructor should have 1 parameters');
             assert_equals(controller.enqueue.length, 1, 'enqueue should have 1 parameter');
             assert_equals(controller.error.length, 1, 'error should have 1 parameter');
+            //assert_equals(controller.constructor.length, 1, 'constructor should have 1 parameters');
 
             isStartCalled = true;
         }
@@ -52,25 +49,6 @@ test(function()
 test(function()
 {
     var isStartCalled = false;
-    var source = {
-        start: function(controller) {
-      const methods = [ 'close', 'constructor', 'enqueue', 'error' ];
-            assert_array_equals(Object.getOwnPropertyNames(Object.getPrototypeOf(controller)).sort(), methods, 'prototype should have the right methods');
-            controller.test = "";
-            assert_array_equals(Object.getOwnPropertyNames(Object.getPrototypeOf(controller)).sort(), methods, 'prototype should still have the right methods');
-            assert_not_equals(Object.getOwnPropertyNames(controller).indexOf('test'), '\'test\' is a property of the controller');
-
-            isStartCalled = true;
-        }
-    };
-
-    var rs = new ReadableStream(source);
-    assert_true(isStartCalled);
-}, 'ReadableStream start controller parameter should be updatable');
-
-test(function()
-{
-    var isStartCalled = false;
 
     var SimpleStreamSource = function() { };
     SimpleStreamSource.prototype.start = function() { isStartCalled = true; };
@@ -79,4 +57,21 @@ test(function()
     var rs = new ReadableStream(new SimpleStreamSource());
     assert_true(isStartCalled);
 }, 'ReadableStream should be able to call start method within prototype chain of its source');
+
+t1 = async_test('A readable stream controller methods should throw if its readablestream is collected');
+t1.step(function() {
+    var controller;
+    new ReadableStream({
+        start: function(c) {
+            controller = c;
+        }
+    });
+    setTimeout(t1.step_func(function() {
+        window.gc();
+        assert_throws(new TypeError(), function() { controller.close(); });
+        assert_throws(new TypeError(), function() { controller.error(); });
+        assert_throws(new TypeError(), function() { controller.enqueue(); });
+        t1.done();
+    }), 10);
+});
 </script>
index 5c0023b..e32a734 100644 (file)
@@ -17,21 +17,11 @@ FAIL Underlying source: throwing strategy.shouldApplyBackpressure method assert_
 FAIL Underlying source: strategy.size returning NaN assert_unreached: enqueue didn't throw Reached unreachable code
 FAIL Underlying source: strategy.size returning -Infinity assert_unreached: enqueue didn't throw Reached unreachable code
 FAIL Underlying source: strategy.size returning +Infinity assert_unreached: enqueue didn't throw Reached unreachable code
-FAIL Underlying source: calling close twice on an empty stream should throw the second time assert_throws: second call to close should throw a TypeError function "function () {
-    [native code]
-}" did not throw
-FAIL Underlying source: calling close twice on a non-empty stream should throw the second time assert_throws: second call to close should throw a TypeError function "function () {
-    [native code]
-}" did not throw
+TIMEOUT Underlying source: calling close twice on an empty stream should throw the second time Test timed out
+FAIL Underlying source: calling close twice on a non-empty stream should throw the second time read is not implemented
 FAIL Underlying source: calling close on an empty canceled stream should not throw cancel is not implemented
 FAIL Underlying source: calling close on a non-empty canceled stream should not throw cancel is not implemented
-FAIL Underlying source: calling close after error should throw assert_throws: call to close should throw a TypeError function "function () {
-    [native code]
-}" did not throw
-FAIL Underlying source: calling error twice should throw the second time assert_throws: second call to error should throw a TypeError function "function () {
-    [native code]
-}" did not throw
-FAIL Underlying source: calling error after close should throw assert_throws: call to error should throw a TypeError function "function () {
-    [native code]
-}" did not throw
+TIMEOUT Underlying source: calling close after error should throw Test timed out
+TIMEOUT Underlying source: calling error twice should throw the second time Test timed out
+TIMEOUT Underlying source: calling error after close should throw Test timed out
 
index 449a0d5..33fa14b 100644 (file)
@@ -6,11 +6,11 @@ FAIL ReadableStreamReader.prototype.closed enforces a brand check undefined is n
 FAIL ReadableStreamReader.prototype.cancel enforces a brand check Can only call ReadableStreamReader.cancel on instances of ReadableStreamReader
 FAIL ReadableStreamReader.prototype.read enforces a brand check Can only call ReadableStreamReader.read on instances of ReadableStreamReader
 PASS ReadableStreamReader.prototype.releaseLock enforces a brand check 
-PASS ReadableStreamController enforces a brand check on its argument 
-PASS ReadableStreamController can't be given a fully-constructed ReadableStream 
-FAIL ReadableStreamController.prototype.close enforces a brand check undefined is not an object (evaluating 'ReadableStreamController.prototype')
-FAIL ReadableStreamController.prototype.enqueue enforces a brand check undefined is not an object (evaluating 'ReadableStreamController.prototype')
-FAIL ReadableStreamController.prototype.error enforces a brand check undefined is not an object (evaluating 'ReadableStreamController.prototype')
+FAIL ReadableStreamController enforces a brand check on its argument assert_throws: Constructing a ReadableStreamController should throw function "function () { new ReadableStreamController(fakeReadableSt..." did not throw
+FAIL ReadableStreamController can't be given a fully-constructed ReadableStream assert_throws: Constructing a ReadableStreamController should throw function "function () { new ReadableStreamController(realReadableSt..." did not throw
+PASS ReadableStreamController.prototype.close enforces a brand check 
+PASS ReadableStreamController.prototype.enqueue enforces a brand check 
+PASS ReadableStreamController.prototype.error enforces a brand check 
 PASS ByteLengthQueuingStrategy.prototype.shouldApplyBackpressure enforces a brand check 
 PASS ByteLengthQueuingStrategy.prototype.size should work generically on its this and its arguments 
 PASS CountQueuingStrategy.prototype.shouldApplyBackpressure enforces a brand check 
index b9bb735..7bdf3de 100644 (file)
@@ -2,7 +2,7 @@
 PASS Can construct a CountQueuingStrategy with a valid high water mark 
 PASS Gives a RangeError when the number is negative 
 PASS Can construct a readable stream with a valid CountQueuingStrategy 
-FAIL Correctly governs the return value of a ReadableStream's enqueue function (HWM = 0) assert_equals: After 0 reads, 1st enqueue should return false (queue now contains 1 chunk) expected (boolean) false but got (undefined) undefined
-FAIL Correctly governs the return value of a ReadableStream's enqueue function (HWM = 1) assert_equals: After 0 reads, 1st enqueue should return true (queue now contains 1 chunk) expected (boolean) true but got (undefined) undefined
-FAIL Correctly governs the return value of a ReadableStream's enqueue function (HWM = 4) assert_equals: After 0 reads, 1st enqueue should return true (queue now contains 1 chunk) expected (boolean) true but got (undefined) undefined
+FAIL Correctly governs the return value of a ReadableStream's enqueue function (HWM = 0) read is not implemented
+FAIL Correctly governs the return value of a ReadableStream's enqueue function (HWM = 1) assert_equals: After 0 reads, 1st enqueue should return true (queue now contains 1 chunk) expected true but got false
+FAIL Correctly governs the return value of a ReadableStream's enqueue function (HWM = 4) assert_equals: After 0 reads, 1st enqueue should return true (queue now contains 1 chunk) expected true but got false
 
index bbf4862..e9d8495 100644 (file)
@@ -14,12 +14,12 @@ FAIL ReadableStream: should not call pull until the previous pull call's promise
 FAIL ReadableStream: should not call pull after start if the stream is now closed read is not implemented
 FAIL ReadableStream: should call pull after enqueueing from inside pull (with no read requests), if strategy allows assert_equals: pull() should have been called four times expected 4 but got 0
 TIMEOUT ReadableStream pull should be able to close a stream. Test timed out
-FAIL ReadableStream: enqueue should throw when the stream is readable but draining assert_equals: the first enqueue should return true expected (boolean) true but got (undefined) undefined
+FAIL ReadableStream: enqueue should throw when the stream is readable but draining assert_equals: the first enqueue should return true expected true but got false
 FAIL ReadableStream: enqueue should throw when the stream is closed assert_throws: enqueue after close should throw a TypeError function "function () { c.enqueue('a'); }" did not throw
 FAIL ReadableStream: enqueue should throw the stored error when the stream is errored assert_throws: enqueue after error should throw that error function "function () { c.enqueue('a'); }" did not throw
 FAIL ReadableStream: should call underlying source methods as methods read is not implemented
-FAIL ReadableStream strategies: the default strategy should return false for all but the first enqueue call assert_equals: first enqueue should return true expected (boolean) true but got (undefined) undefined
-FAIL ReadableStream strategies: the default strategy should continue returning true from enqueue if the chunks are read immediately assert_equals: first enqueue should return true expected (boolean) true but got (undefined) undefined
+FAIL ReadableStream strategies: the default strategy should return false for all but the first enqueue call assert_equals: first enqueue should return true expected true but got false
+FAIL ReadableStream strategies: the default strategy should continue returning true from enqueue if the chunks are read immediately assert_equals: first enqueue should return true expected true but got false
 FAIL ReadableStream integration test: adapting a random push source read is not implemented
 FAIL ReadableStream integration test: adapting a sync pull source read is not implemented
 FAIL ReadableStream integration test: adapting an async pull source read is not implemented
index 3df94ef..2d56daf 100644 (file)
@@ -275,6 +275,7 @@ set(WebCore_NON_SVG_IDL_FILES
     Modules/speech/SpeechSynthesisVoice.idl
 
     Modules/streams/ReadableStream.idl
+    Modules/streams/ReadableStreamController.idl
     Modules/streams/ReadableStreamReader.idl
 
     Modules/vibration/NavigatorVibration.idl
@@ -1155,6 +1156,7 @@ set(WebCore_SOURCES
     bindings/js/JSRTCSessionDescriptionCustom.cpp
     bindings/js/JSRTCStatsResponseCustom.cpp
     bindings/js/JSReadableStreamCustom.cpp
+    bindings/js/JSReadableStreamControllerCustom.cpp
     bindings/js/JSReadableStreamReaderCustom.cpp
     bindings/js/ReadableStreamJSSource.cpp
     bindings/js/JSRequestAnimationFrameCallbackCustom.cpp
index c96fb43..c5cc792 100644 (file)
@@ -1,3 +1,34 @@
+2015-04-22  Xabier Rodriguez Calvar  <calvaris@igalia.com> and Youenn Fablet  <youenn.fablet@crf.canon.fr>
+
+        [Streams API] Implement ReadableStreamController
+        https://bugs.webkit.org/show_bug.cgi?id=143608
+
+        Reviewed by Benjamin Poulain.
+
+        Introducing ReadableStreamController, an abstraction to manage JS source stream queues.
+        This new interface is not exposed to JS scripts as specified, using NoInterfaceObject.
+
+        A controller is created at the time a ReadableJSStream is started and it is owned by it.
+        The controller may outlive the stream but as its reference will be reset, the calls to
+        its methods would result in exceptions.
+
+        The constructor is not implemented yet.
+
+        Change covered by existing tests and rebased expectations.
+
+        * CMakeLists.txt:
+        * DerivedSources.cpp:
+        * DerivedSources.make: Added ReadableStreamController.idl related files.
+        * Modules/streams/ReadableStreamController.h: Added.
+        * Modules/streams/ReadableStreamController.idl: Added.
+        * WebCore.vcxproj/WebCore.vcxproj:
+        * WebCore.vcxproj/WebCore.vcxproj.filters:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/JSBindingsAllInOne.cpp: Added ReadableStreamController.idl related files.
+        * bindings/js/JSReadableStreamControllerCustom.cpp: Added.
+        * bindings/js/ReadableStreamJSSource.cpp:
+        * bindings/js/ReadableStreamJSSource.h: Removed custom controller implementation.
+
 2015-04-22  Manuel Rego Casasnovas  <rego@igalia.com>
 
         Rename hasOverride{Height,Width}() to hasOverrideLogicalContent{Height,Width}()
index be6c757..72b41a3 100644 (file)
 #include "JSRangeException.cpp"
 #if ENABLE(STREAMS_API)
 #include "JSReadableStream.cpp"
+#include "JSReadableStreamController.cpp"
 #include "JSReadableStreamReader.cpp"
 #endif
 #include "JSRect.cpp"
index 28adcca..22eaa4f 100644 (file)
@@ -169,6 +169,7 @@ NON_SVG_BINDING_IDLS = \
     $(WebCore)/Modules/speech/SpeechSynthesisUtterance.idl \
     $(WebCore)/Modules/speech/SpeechSynthesisVoice.idl \
     $(WebCore)/Modules/streams/ReadableStream.idl \
+    $(WebCore)/Modules/streams/ReadableStreamController.idl \
     $(WebCore)/Modules/streams/ReadableStreamReader.idl \
     $(WebCore)/Modules/webaudio/AudioBuffer.idl \
     $(WebCore)/Modules/webaudio/AudioBufferCallback.idl \
diff --git a/Source/WebCore/Modules/streams/ReadableStreamController.h b/Source/WebCore/Modules/streams/ReadableStreamController.h
new file mode 100644 (file)
index 0000000..6fd9d21
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015 Canon Inc.
+ * Copyright (C) 2015 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted, provided that the following conditions
+ * are required to be met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Canon Inc. nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CANON INC. AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CANON INC. AND ITS CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ReadableStreamController_h
+#define ReadableStreamController_h
+
+#if ENABLE(STREAMS_API)
+
+#include <wtf/Ref.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class ReadableJSStream;
+
+// This class is only used for JS source readable streams to allow enqueuing, closing or erroring a readable stream.
+// Its definition is at https://streams.spec.whatwg.org/#rs-controller-class.
+// Note that its constructor is taking a ReadableJSStream as it should only be used for JS sources.
+class ReadableStreamController : public RefCounted<ReadableStreamController> {
+public:
+    static Ref<ReadableStreamController> create(ReadableJSStream& stream)
+    {
+        auto controller = adoptRef(*new ReadableStreamController(stream));
+        return controller;
+    }
+    ~ReadableStreamController() { }
+
+    void resetStream() { m_stream = nullptr; }
+    ReadableJSStream* stream() { return m_stream; }
+
+private:
+    ReadableStreamController(ReadableJSStream& stream) { m_stream = &stream; }
+
+    ReadableJSStream* m_stream;
+};
+
+}
+
+#endif
+
+#endif // ReadableStream_h
diff --git a/Source/WebCore/Modules/streams/ReadableStreamController.idl b/Source/WebCore/Modules/streams/ReadableStreamController.idl
new file mode 100644 (file)
index 0000000..5767c4b
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 Canon Inc.
+ * Copyright (C) 2015 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted, provided that the following conditions
+ * are required to be met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Canon Inc. nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CANON INC. AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CANON INC. AND ITS CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+    Conditional=STREAMS_API,
+    ImplementationLacksVTable,
+    NoInterfaceObject
+] interface ReadableStreamController {
+    [Custom, RaisesException] boolean enqueue(any chunk);
+    [Custom, RaisesException] void close();
+    [Custom, RaisesException] void error(any error);
+};
index 3ebe6b9..4f9fd96 100644 (file)
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSReadableStreamController.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSReadableStreamReader.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="..\bindings\js\JSReadableStreamControllerCustom.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\bindings\js\JSReadableStreamReaderCustom.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSRange.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSRangeException.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSReadableStream.h" />
+    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSReadableStreamController.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSReadableStreamReader.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSRect.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSRequestAnimationFrameCallback.h" />
     <ClInclude Include="..\Modules\notifications\WorkerGlobalScopeNotifications.h" />
     <ClInclude Include="..\Modules\plugins\PluginReplacement.h" />
     <ClInclude Include="..\Modules\streams\ReadableStream.h" />
+    <ClInclude Include="..\Modules\streams\ReadableStreamController.h" />
     <ClInclude Include="..\Modules\streams\ReadableStreamReader.h" />
     <ClInclude Include="..\Modules\streams\ReadableStreamSource.h" />
     <ClInclude Include="..\Modules\webdatabase\AbstractDatabaseServer.h" />
index e2ba2e6..9147401 100644 (file)
     <ClCompile Include="..\bindings\js\JSReadableStreamCustom.cpp">
       <Filter>bindings\js</Filter>
     </ClCompile>
+    <ClCompile Include="..\bindings\js\JSReadableStreamControllerCustom.cpp">
+      <Filter>bindings\js</Filter>
+    </ClCompile>
     <ClCompile Include="..\bindings\js\JSReadableStreamReaderCustom.cpp">
       <Filter>bindings\js</Filter>
     </ClCompile>
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSReadableStream.cpp">
       <Filter>DerivedSources</Filter>
     </ClCompile>
+    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSReadableStreamController.cpp">
+      <Filter>DerivedSources</Filter>
+    </ClCompile>
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSReadableStreamReader.cpp">
       <Filter>DerivedSources</Filter>
     </ClCompile>
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSReadableStream.h">
       <Filter>DerivedSources</Filter>
     </ClInclude>
+    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSReadableStreamController.h">
+      <Filter>DerivedSources</Filter>
+    </ClInclude>
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSReadableStreamReader.h">
       <Filter>DerivedSources</Filter>
     </ClInclude>
     <ClInclude Include="..\Modules\streams\ReadableStream.h">
       <Filter>Modules\streams</Filter>
     </ClInclude>
+    <ClInclude Include="..\Modules\streams\ReadableStreamController.h">
+      <Filter>Modules\streams</Filter>
+    </ClInclude>
     <ClInclude Include="..\Modules\streams\ReadableStreamReader.h">
       <Filter>Modules\streams</Filter>
     </ClInclude>
index 7639d7f..14dbd70 100644 (file)
                40ECAE7E16B8B67200C36103 /* JSDOMError.h in Headers */ = {isa = PBXBuildFile; fileRef = 40ECAE7D16B8B67200C36103 /* JSDOMError.h */; };
                40ECAE8116B8B68A00C36103 /* JSDOMError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 40ECAE8016B8B68A00C36103 /* JSDOMError.cpp */; };
                410B7E721045FAB000D8224F /* JSMessageEventCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 410B7E711045FAB000D8224F /* JSMessageEventCustom.cpp */; };
+               41189EF91AD8273700B90A0D /* JSReadableStreamControllerCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41189EF81AD8233C00B90A0D /* JSReadableStreamControllerCustom.cpp */; };
                4123081B138C429700BCCFCA /* WebCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93F19B1A08245E5A001E9ABC /* WebCore.framework */; };
                41230913138C42FF00BCCFCA /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8216299029F4FB501000131 /* JavaScriptCore.framework */; };
                4127D5370F8AAB1D00E424F5 /* ScriptState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4127D5360F8AAB1D00E424F5 /* ScriptState.cpp */; };
                65FD466619B596F6001E2B4D /* WebVideoFullscreenModelVideoElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6586FE3D19B548BD005C3C82 /* WebVideoFullscreenModelVideoElement.mm */; };
                65FEA86909833ADE00BED4AB /* Page.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65FEA86809833ADE00BED4AB /* Page.cpp */; };
                6B3480940EEF50D400AC1B41 /* NativeImagePtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B3480920EEF50D400AC1B41 /* NativeImagePtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               6C4C96DE1AD4483500365A50 /* JSReadableStreamController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6C4C96DA1AD4483500365A50 /* JSReadableStreamController.cpp */; };
+               6C4C96DF1AD4483500365A50 /* JSReadableStreamController.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C4C96DB1AD4483500365A50 /* JSReadableStreamController.h */; };
                6C568CB019DAFEA000430CA2 /* MaskImageOperation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6C568CAE19DAFEA000430CA2 /* MaskImageOperation.cpp */; };
                6C568CB119DAFEA000430CA2 /* MaskImageOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C568CAF19DAFEA000430CA2 /* MaskImageOperation.h */; settings = {ATTRIBUTES = (Private, ); }; };
                6C638895A96CCEE50C8C946C /* CachedResourceRequestInitiators.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C638893A96CCEE50C8C946C /* CachedResourceRequestInitiators.h */; settings = {ATTRIBUTES = (Private, ); }; };
                40ECAE7D16B8B67200C36103 /* JSDOMError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMError.h; sourceTree = "<group>"; };
                40ECAE8016B8B68A00C36103 /* JSDOMError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMError.cpp; sourceTree = "<group>"; };
                410B7E711045FAB000D8224F /* JSMessageEventCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMessageEventCustom.cpp; sourceTree = "<group>"; };
+               41189EF61AD8232800B90A0D /* ReadableStreamController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReadableStreamController.h; sourceTree = "<group>"; };
+               41189EF71AD8232800B90A0D /* ReadableStreamController.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadableStreamController.idl; sourceTree = "<group>"; };
+               41189EF81AD8233C00B90A0D /* JSReadableStreamControllerCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSReadableStreamControllerCustom.cpp; sourceTree = "<group>"; };
                4127D5360F8AAB1D00E424F5 /* ScriptState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptState.cpp; sourceTree = "<group>"; };
                4138D3331244054800323D33 /* EventContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventContext.h; sourceTree = "<group>"; };
                4138D3341244054800323D33 /* EventContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventContext.cpp; sourceTree = "<group>"; };
                65F80697054D9F86008BF776 /* BlockExceptions.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BlockExceptions.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                65FEA86809833ADE00BED4AB /* Page.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Page.cpp; sourceTree = "<group>"; };
                6B3480920EEF50D400AC1B41 /* NativeImagePtr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = NativeImagePtr.h; sourceTree = "<group>"; };
+               6C4C96DA1AD4483500365A50 /* JSReadableStreamController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSReadableStreamController.cpp; sourceTree = "<group>"; };
+               6C4C96DB1AD4483500365A50 /* JSReadableStreamController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSReadableStreamController.h; sourceTree = "<group>"; };
                6C568CAE19DAFEA000430CA2 /* MaskImageOperation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MaskImageOperation.cpp; sourceTree = "<group>"; };
                6C568CAF19DAFEA000430CA2 /* MaskImageOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MaskImageOperation.h; sourceTree = "<group>"; };
                6C638893A96CCEE50C8C946C /* CachedResourceRequestInitiators.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CachedResourceRequestInitiators.h; sourceTree = "<group>"; };
                41A023EA1A39DB7900F722CF /* streams */ = {
                        isa = PBXGroup;
                        children = (
+                               41189EF61AD8232800B90A0D /* ReadableStreamController.h */,
+                               41189EF71AD8232800B90A0D /* ReadableStreamController.idl */,
                                41A023EB1A39DB7900F722CF /* ReadableStream.cpp */,
                                41A023EC1A39DB7900F722CF /* ReadableStream.h */,
                                41A023ED1A39DB7900F722CF /* ReadableStream.idl */,
                        children = (
                                7C4C96D81AD4483500365A50 /* JSReadableStream.cpp */,
                                7C4C96D91AD4483500365A50 /* JSReadableStream.h */,
+                               6C4C96DA1AD4483500365A50 /* JSReadableStreamController.cpp */,
+                               6C4C96DB1AD4483500365A50 /* JSReadableStreamController.h */,
                                7C4C96DA1AD4483500365A50 /* JSReadableStreamReader.cpp */,
                                7C4C96DB1AD4483500365A50 /* JSReadableStreamReader.h */,
                        );
                                93B70D5009EB0C7C009D8468 /* JSPluginElementFunctions.h */,
                                E1C36D320EB0A094007410BC /* JSWorkerGlobalScopeBase.cpp */,
                                E1C36D330EB0A094007410BC /* JSWorkerGlobalScopeBase.h */,
+                               41189EF81AD8233C00B90A0D /* JSReadableStreamControllerCustom.cpp */,
                                4198BDEE1A81123600B22FB5 /* ReadableStreamJSSource.cpp */,
                                4198BDEF1A81123600B22FB5 /* ReadableStreamJSSource.h */,
                                BCA378BA0D15F64200B793D6 /* ScheduledAction.cpp */,
                                859A9C490AA5E3BD00B694B2 /* DOMHTMLBodyElement.h in Headers */,
                                85E7119F0AC5D5350053270F /* DOMHTMLBodyElementInternal.h in Headers */,
                                85183B420AA6926100F19FA3 /* DOMHTMLBRElement.h in Headers */,
+                               6C4C96DF1AD4483500365A50 /* JSReadableStreamController.h in Headers */,
                                7C4C96DF1AD4483500365A50 /* JSReadableStreamReader.h in Headers */,
                                85E711A00AC5D5350053270F /* DOMHTMLBRElementInternal.h in Headers */,
                                85BA4CDD0AA6861B0088052D /* DOMHTMLButtonElement.h in Headers */,
                                85031B470A44EFC700F992E0 /* MouseRelatedEvent.cpp in Sources */,
                                93309DFB099E64920056E581 /* MoveSelectionCommand.cpp in Sources */,
                                FDB1700514A2BAB200A2B5D9 /* MultiChannelResampler.cpp in Sources */,
+                               41189EF91AD8273700B90A0D /* JSReadableStreamControllerCustom.cpp in Sources */,
                                46C83EFD1A9BBE2900A79A41 /* GeoNotifier.cpp in Sources */,
                                85031B490A44EFC700F992E0 /* MutationEvent.cpp in Sources */,
                                C6F0900E14327B6100685849 /* MutationObserver.cpp in Sources */,
                                43B85ED418CBEC5200E31AF4 /* SelectorPseudoClassAndCompatibilityElementMap.cpp in Sources */,
                                26AA0F9E18D2A18B00419381 /* SelectorPseudoElementTypeMap.cpp in Sources */,
                                E45322AB140CE267005A0F92 /* SelectorQuery.cpp in Sources */,
+                               6C4C96DE1AD4483500365A50 /* JSReadableStreamController.cpp in Sources */,
                                7C4C96DE1AD4483500365A50 /* JSReadableStreamReader.cpp in Sources */,
                                99CC0B5F18BE984A006CEBCC /* SerializationMethods.cpp in Sources */,
                                E18DF33818AAF14D00773E59 /* SerializedCryptoKeyWrapMac.mm in Sources */,
index 1665288..9a62dd6 100644 (file)
 #include "JSPluginElementFunctions.cpp"
 #include "JSPopStateEventCustom.cpp"
 #if ENABLE(STREAMS_API)
+#include "JSReadableStreamControllerCustom.cpp"
 #include "JSReadableStreamCustom.cpp"
 #include "JSReadableStreamReaderCustom.cpp"
 #include "ReadableStreamJSSource.cpp"
diff --git a/Source/WebCore/bindings/js/JSReadableStreamControllerCustom.cpp b/Source/WebCore/bindings/js/JSReadableStreamControllerCustom.cpp
new file mode 100644 (file)
index 0000000..15f7a4a
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 Canon Inc.
+ * Copyright (C) 2015 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted, provided that the following conditions
+ * are required to be met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Canon Inc. nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CANON INC. AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CANON INC. AND ITS CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSReadableStreamController.h"
+
+#if ENABLE(STREAMS_API)
+
+#include "JSDOMBinding.h"
+#include "NotImplemented.h"
+#include "ReadableStreamJSSource.h"
+#include <runtime/Error.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+JSValue JSReadableStreamController::close(ExecState* exec)
+{
+    ReadableJSStream* stream = impl().stream();
+    if (!stream)
+        return exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Controller has no readablestream")));
+    // FIXME: Handle the case of draining.
+    if (stream->internalState() != ReadableStream::State::Readable)
+        return exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Calling close on a stream which is not readable")));
+    notImplemented();
+    return jsUndefined();
+}
+
+JSValue JSReadableStreamController::enqueue(ExecState* exec)
+{
+    ReadableJSStream* stream = impl().stream();
+    if (!stream)
+        return exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Controller has no readablestream")));
+    notImplemented();
+    return jsBoolean(false);
+}
+
+JSValue JSReadableStreamController::error(ExecState* exec)
+{
+    ReadableJSStream* stream = impl().stream();
+    if (!stream)
+        return exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Controller has no readablestream")));
+    if (stream->internalState() != ReadableStream::State::Readable)
+        return exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Calling error on a stream which is not readable")));
+    notImplemented();
+    return jsUndefined();
+}
+
+} // namespace WebCore
+
+#endif
index 6f9d7ba..05228f7 100644 (file)
@@ -69,13 +69,6 @@ static inline JSValue getPropertyFromObject(ExecState* exec, JSObject* object, c
     return object->get(exec, Identifier::fromString(exec, identifier));
 }
 
-static inline void setPropertyToObject(ExecState* exec, JSValue objectValue, const char* name, JSValue value)
-{
-    JSObject* object = objectValue.toObject(exec);
-    PutPropertySlot propertySlot(objectValue);
-    object->put(object, exec, Identifier::fromString(exec, name), value, propertySlot);
-}
-
 static inline JSValue callFunction(ExecState* exec, JSValue jsFunction, JSValue thisValue, const ArgList& arguments, JSValue* exception)
 {
     CallData callData;
@@ -95,25 +88,10 @@ ReadableStreamJSSource::ReadableStreamJSSource(JSC::ExecState* exec)
     m_source.set(exec->vm(), source);
 }
 
-static EncodedJSValue JSC_HOST_CALL notImplementedFunction(ExecState*)
+ReadableStreamJSSource::~ReadableStreamJSSource()
 {
-    notImplemented();
-    return JSValue::encode(jsUndefined());
-}
-
-static inline JSFunction* createReadableStreamEnqueueFunction(ExecState* exec)
-{
-    return JSFunction::create(exec->vm(), exec->callee()->globalObject(), 1, String(), notImplementedFunction);
-}
-
-static inline JSFunction* createReadableStreamCloseFunction(ExecState* exec)
-{
-    return JSFunction::create(exec->vm(), exec->callee()->globalObject(), 0, String(), notImplementedFunction);
-}
-
-static inline JSFunction* createReadableStreamErrorFunction(ExecState* exec)
-{
-    return JSFunction::create(exec->vm(), exec->callee()->globalObject(), 1, String(), notImplementedFunction);
+    if (m_controller)
+        m_controller.get()->impl().resetStream();
 }
 
 static void startReadableStreamAsync(ReadableStream& readableStream)
@@ -124,24 +102,12 @@ static void startReadableStreamAsync(ReadableStream& readableStream)
     });
 }
 
-static inline JSObject* createReadableStreamController(JSC::ExecState* exec)
-{
-    JSFunction* enqueueFunction = createReadableStreamEnqueueFunction(exec);
-    JSFunction* closeFunction = createReadableStreamCloseFunction(exec);
-    JSFunction* errorFunction = createReadableStreamErrorFunction(exec);
-
-    JSObject* controller =  JSFinalObject::create(exec->vm(), JSFinalObject::createStructure(exec->vm(), exec->callee()->globalObject(), jsNull(), 3));
-    setPropertyToObject(exec, controller, "enqueue", enqueueFunction);
-    setPropertyToObject(exec, controller, "close", closeFunction);
-    setPropertyToObject(exec, controller, "error", errorFunction);
-    return controller;
-}
-
 void ReadableStreamJSSource::start(JSC::ExecState* exec, JSReadableStream* readableStream)
 {
     JSLockHolder lock(exec);
 
-    m_controller.set(exec->vm(), createReadableStreamController(exec));
+    Ref<ReadableStreamController> controller = ReadableStreamController::create(static_cast<ReadableJSStream&>(readableStream->impl()));
+    m_controller.set(exec->vm(), jsDynamicCast<JSReadableStreamController*>(toJS(exec, readableStream->globalObject(), controller)));
 
     JSValue startFunction = getPropertyFromObject(exec, m_source.get(), "start");
     if (!startFunction.isFunction()) {
index 478510b..223b277 100644 (file)
@@ -32,6 +32,7 @@
 
 #if ENABLE(STREAMS_API)
 
+#include "JSReadableStreamController.h"
 #include "ReadableStream.h"
 #include "ReadableStreamReader.h"
 #include "ReadableStreamSource.h"
@@ -48,7 +49,7 @@ class JSReadableStream;
 class ReadableStreamJSSource: public ReadableStreamSource {
 public:
     static Ref<ReadableStreamJSSource> create(JSC::ExecState*);
-    ~ReadableStreamJSSource() { }
+    ~ReadableStreamJSSource();
 
     void start(JSC::ExecState*, JSReadableStream*);
 
@@ -58,7 +59,7 @@ private:
     // Object passed to constructor.
     JSC::Strong<JSC::JSObject> m_source;
 
-    JSC::Strong<JSC::JSObject> m_controller;
+    JSC::Strong<JSReadableStreamController> m_controller;
 };
 
 class ReadableJSStream: public ReadableStream {