mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-16 13:56:29 +00:00
Bug 1486949 - Part 4: Implement TransformStream construction for GenericTransformStream r=smaug
Per the Streams spec, other specs that want to implement custom TransformStream should use [GenericTransformStream](https://streams.spec.whatwg.org/#other-specs-ts-wrapping) mixin and store a [new TransformStream](https://streams.spec.whatwg.org/#transformstream-set-up) in a slot. This implements the latter part. Differential Revision: https://phabricator.services.mozilla.com/D153975
This commit is contained in:
parent
bb449a5649
commit
237dffb194
@ -40,6 +40,63 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TransformStream)
|
|||||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#transformstream-set-up
|
||||||
|
// (except this instead creates a new TransformStream rather than accepting an
|
||||||
|
// existing instance)
|
||||||
|
already_AddRefed<TransformStream> TransformStream::CreateGeneric(
|
||||||
|
const GlobalObject& aGlobal, TransformerAlgorithmsWrapper& aAlgorithms,
|
||||||
|
ErrorResult& aRv) {
|
||||||
|
// Step 1. Let writableHighWaterMark be 1.
|
||||||
|
double writableHighWaterMark = 1;
|
||||||
|
|
||||||
|
// Step 2. Let writableSizeAlgorithm be an algorithm that returns 1.
|
||||||
|
// Note: Callers should recognize nullptr as a callback that returns 1. See
|
||||||
|
// also WritableStream::Constructor for this design decision.
|
||||||
|
RefPtr<QueuingStrategySize> writableSizeAlgorithm;
|
||||||
|
|
||||||
|
// Step 3. Let readableHighWaterMark be 0.
|
||||||
|
double readableHighWaterMark = 0;
|
||||||
|
|
||||||
|
// Step 4. Let readableSizeAlgorithm be an algorithm that returns 1.
|
||||||
|
// Note: Callers should recognize nullptr as a callback that returns 1. See
|
||||||
|
// also ReadableStream::Constructor for this design decision.
|
||||||
|
RefPtr<QueuingStrategySize> readableSizeAlgorithm;
|
||||||
|
|
||||||
|
// Step 5. Let transformAlgorithmWrapper be an algorithm that runs these steps
|
||||||
|
// given a value chunk:
|
||||||
|
// Step 6. Let flushAlgorithmWrapper be an algorithm that runs these steps:
|
||||||
|
// (Done by TransformerAlgorithmsWrapper)
|
||||||
|
|
||||||
|
// Step 7. Let startPromise be a promise resolved with undefined.
|
||||||
|
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
|
||||||
|
RefPtr<Promise> startPromise =
|
||||||
|
Promise::CreateResolvedWithUndefined(global, aRv);
|
||||||
|
if (!startPromise) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 8. Perform ! InitializeTransformStream(stream, startPromise,
|
||||||
|
// writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark,
|
||||||
|
// readableSizeAlgorithm).
|
||||||
|
auto stream = MakeRefPtr<TransformStream>(global, nullptr, nullptr);
|
||||||
|
stream->Initialize(aGlobal.Context(), startPromise, writableHighWaterMark,
|
||||||
|
writableSizeAlgorithm, readableHighWaterMark,
|
||||||
|
readableSizeAlgorithm, aRv);
|
||||||
|
if (aRv.Failed()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 9. Let controller be a new TransformStreamDefaultController.
|
||||||
|
auto controller = MakeRefPtr<TransformStreamDefaultController>(global);
|
||||||
|
|
||||||
|
// Step 10. Perform ! SetUpTransformStreamDefaultController(stream,
|
||||||
|
// controller, transformAlgorithmWrapper, flushAlgorithmWrapper).
|
||||||
|
SetUpTransformStreamDefaultController(aGlobal.Context(), *stream, *controller,
|
||||||
|
aAlgorithms);
|
||||||
|
|
||||||
|
return stream.forget();
|
||||||
|
}
|
||||||
|
|
||||||
TransformStream::TransformStream(nsIGlobalObject* aGlobal) : mGlobal(aGlobal) {
|
TransformStream::TransformStream(nsIGlobalObject* aGlobal) : mGlobal(aGlobal) {
|
||||||
mozilla::HoldJSObjects(this);
|
mozilla::HoldJSObjects(this);
|
||||||
}
|
}
|
||||||
|
@ -21,12 +21,19 @@ class WritableStream;
|
|||||||
class ReadableStream;
|
class ReadableStream;
|
||||||
class UniqueMessagePortId;
|
class UniqueMessagePortId;
|
||||||
class MessagePort;
|
class MessagePort;
|
||||||
|
class TransformerAlgorithmsWrapper;
|
||||||
|
|
||||||
class TransformStream final : public nsISupports, public nsWrapperCache {
|
class TransformStream final : public nsISupports, public nsWrapperCache {
|
||||||
public:
|
public:
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TransformStream)
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TransformStream)
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#transformstream-set-up
|
||||||
|
// Intended to be used by interfaces using GenericTransformStream mixin.
|
||||||
|
MOZ_CAN_RUN_SCRIPT static already_AddRefed<TransformStream> CreateGeneric(
|
||||||
|
const GlobalObject& aGlobal, TransformerAlgorithmsWrapper& aAlgorithms,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
TransformStream(nsIGlobalObject* aGlobal, ReadableStream* aReadable,
|
TransformStream(nsIGlobalObject* aGlobal, ReadableStream* aReadable,
|
||||||
WritableStream* aWritable);
|
WritableStream* aWritable);
|
||||||
|
|
||||||
|
@ -58,6 +58,11 @@ class TransformStreamDefaultController final : public nsISupports,
|
|||||||
RefPtr<TransformerAlgorithmsBase> mTransformerAlgorithms;
|
RefPtr<TransformerAlgorithmsBase> mTransformerAlgorithms;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void SetUpTransformStreamDefaultController(
|
||||||
|
JSContext* aCx, TransformStream& aStream,
|
||||||
|
TransformStreamDefaultController& aController,
|
||||||
|
TransformerAlgorithmsBase& aTransformerAlgorithms);
|
||||||
|
|
||||||
void SetUpTransformStreamDefaultControllerFromTransformer(
|
void SetUpTransformStreamDefaultControllerFromTransformer(
|
||||||
JSContext* aCx, TransformStream& aStream,
|
JSContext* aCx, TransformStream& aStream,
|
||||||
JS::Handle<JSObject*> aTransformer, Transformer& aTransformerDict);
|
JS::Handle<JSObject*> aTransformer, Transformer& aTransformerDict);
|
||||||
|
@ -83,3 +83,47 @@ already_AddRefed<Promise> TransformerAlgorithms::FlushCallback(
|
|||||||
"TransformStreamDefaultController.[[flushAlgorithm]]",
|
"TransformStreamDefaultController.[[flushAlgorithm]]",
|
||||||
CallbackObject::eRethrowExceptions);
|
CallbackObject::eRethrowExceptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#transformstream-set-up
|
||||||
|
// Step 5 and 6.
|
||||||
|
template <typename T>
|
||||||
|
MOZ_CAN_RUN_SCRIPT static already_AddRefed<Promise> Promisify(
|
||||||
|
nsIGlobalObject* aGlobal, T aFunc, mozilla::ErrorResult& aRv) {
|
||||||
|
// Step 1. Let result be the result of running (algorithm). If this throws an
|
||||||
|
// exception e, return a promise rejected with e.
|
||||||
|
aFunc(aRv);
|
||||||
|
if (aRv.Failed()) {
|
||||||
|
return Promise::CreateRejectedWithErrorResult(aGlobal, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2. If result is a Promise, then return result.
|
||||||
|
// (This supports no return value since currently no subclass needs one)
|
||||||
|
|
||||||
|
// Step 3. Return a promise resolved with undefined.
|
||||||
|
return Promise::CreateResolvedWithUndefined(aGlobal, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise> TransformerAlgorithmsWrapper::TransformCallback(
|
||||||
|
JSContext*, JS::Handle<JS::Value> aChunk,
|
||||||
|
TransformStreamDefaultController& aController, ErrorResult& aRv) {
|
||||||
|
nsCOMPtr<nsIGlobalObject> global = aController.GetParentObject();
|
||||||
|
return Promisify(
|
||||||
|
global,
|
||||||
|
[this, &aChunk, &aController](ErrorResult& aRv)
|
||||||
|
MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
|
||||||
|
return TransformCallbackImpl(aChunk, aController, aRv);
|
||||||
|
},
|
||||||
|
aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise> TransformerAlgorithmsWrapper::FlushCallback(
|
||||||
|
JSContext*, TransformStreamDefaultController& aController,
|
||||||
|
ErrorResult& aRv) {
|
||||||
|
nsCOMPtr<nsIGlobalObject> global = aController.GetParentObject();
|
||||||
|
return Promisify(
|
||||||
|
global,
|
||||||
|
[this, &aController](ErrorResult& aRv) MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
|
||||||
|
return FlushCallbackImpl(aController, aRv);
|
||||||
|
},
|
||||||
|
aRv);
|
||||||
|
}
|
||||||
|
@ -77,6 +77,24 @@ class TransformerAlgorithms final : public TransformerAlgorithmsBase {
|
|||||||
MOZ_KNOWN_LIVE RefPtr<TransformerFlushCallback> mFlushCallback;
|
MOZ_KNOWN_LIVE RefPtr<TransformerFlushCallback> mFlushCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#transformstream-set-up
|
||||||
|
class TransformerAlgorithmsWrapper : public TransformerAlgorithmsBase {
|
||||||
|
MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> TransformCallback(
|
||||||
|
JSContext*, JS::Handle<JS::Value> aChunk,
|
||||||
|
TransformStreamDefaultController& aController, ErrorResult& aRv) final;
|
||||||
|
|
||||||
|
MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> FlushCallback(
|
||||||
|
JSContext*, TransformStreamDefaultController& aController,
|
||||||
|
ErrorResult& aRv) final;
|
||||||
|
|
||||||
|
MOZ_CAN_RUN_SCRIPT virtual void TransformCallbackImpl(
|
||||||
|
JS::Handle<JS::Value> aChunk,
|
||||||
|
TransformStreamDefaultController& aController, ErrorResult& aRv) = 0;
|
||||||
|
|
||||||
|
MOZ_CAN_RUN_SCRIPT virtual void FlushCallbackImpl(
|
||||||
|
TransformStreamDefaultController& aController, ErrorResult& aRv) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace mozilla::dom
|
} // namespace mozilla::dom
|
||||||
|
|
||||||
#endif // DOM_STREAMS_TRANSFORMERCALLBACKHELPERS_H_
|
#endif // DOM_STREAMS_TRANSFORMERCALLBACKHELPERS_H_
|
||||||
|
@ -27,6 +27,7 @@ EXPORTS.mozilla.dom += [
|
|||||||
"ReadRequest.h",
|
"ReadRequest.h",
|
||||||
"StreamUtils.h",
|
"StreamUtils.h",
|
||||||
"TeeState.h",
|
"TeeState.h",
|
||||||
|
"TransformerCallbackHelpers.h",
|
||||||
"TransformStream.h",
|
"TransformStream.h",
|
||||||
"TransformStreamDefaultController.h",
|
"TransformStreamDefaultController.h",
|
||||||
"UnderlyingSinkCallbackHelpers.h",
|
"UnderlyingSinkCallbackHelpers.h",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user