2018-08-18 19:43:22 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#ifndef mozilla_dom_Promise_inl_h
|
|
|
|
#define mozilla_dom_Promise_inl_h
|
|
|
|
|
2020-03-28 16:57:15 +03:00
|
|
|
#include <type_traits>
|
2020-03-28 16:57:18 +03:00
|
|
|
#include <utility>
|
2020-03-28 16:57:15 +03:00
|
|
|
|
2022-03-21 19:45:35 +03:00
|
|
|
#include "mozilla/AlreadyAddRefed.h"
|
2018-08-18 19:43:22 +03:00
|
|
|
#include "mozilla/ResultExtensions.h"
|
2022-03-21 19:45:35 +03:00
|
|
|
#include "mozilla/dom/BindingUtils.h"
|
|
|
|
#include "mozilla/dom/Promise.h"
|
2018-08-18 19:43:22 +03:00
|
|
|
#include "mozilla/dom/PromiseNativeHandler.h"
|
2022-03-21 19:45:35 +03:00
|
|
|
#include "nsCycleCollectionParticipant.h"
|
2018-08-18 19:43:22 +03:00
|
|
|
|
2022-03-22 19:44:58 +03:00
|
|
|
namespace mozilla::dom {
|
2018-08-18 19:43:22 +03:00
|
|
|
|
|
|
|
class PromiseNativeThenHandlerBase : public PromiseNativeHandler {
|
|
|
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
2022-04-06 01:19:47 +03:00
|
|
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PromiseNativeThenHandlerBase)
|
2018-08-18 19:43:22 +03:00
|
|
|
|
2022-03-21 19:45:36 +03:00
|
|
|
PromiseNativeThenHandlerBase(Promise* aPromise) : mPromise(aPromise) {}
|
2018-08-18 19:43:22 +03:00
|
|
|
|
2022-03-22 19:44:58 +03:00
|
|
|
virtual bool HasResolvedCallback() = 0;
|
|
|
|
virtual bool HasRejectedCallback() = 0;
|
|
|
|
|
2022-10-22 12:42:27 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT void ResolvedCallback(JSContext* aCx,
|
|
|
|
JS::Handle<JS::Value> aValue,
|
|
|
|
ErrorResult& aRv) override;
|
2018-08-18 19:43:22 +03:00
|
|
|
|
2022-10-22 12:42:27 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT void RejectedCallback(JSContext* aCx,
|
|
|
|
JS::Handle<JS::Value> aValue,
|
|
|
|
ErrorResult& aRv) override;
|
2018-08-18 19:43:22 +03:00
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual ~PromiseNativeThenHandlerBase() = default;
|
|
|
|
|
2022-10-22 12:42:27 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT virtual already_AddRefed<Promise> CallResolveCallback(
|
2022-03-21 19:45:35 +03:00
|
|
|
JSContext* aCx, JS::Handle<JS::Value> aValue, ErrorResult& aRv) = 0;
|
2022-10-22 12:42:27 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT virtual already_AddRefed<Promise> CallRejectCallback(
|
2022-03-21 19:45:36 +03:00
|
|
|
JSContext* aCx, JS::Handle<JS::Value> aValue, ErrorResult& aRv) = 0;
|
2018-08-18 19:43:22 +03:00
|
|
|
|
|
|
|
virtual void Traverse(nsCycleCollectionTraversalCallback&) = 0;
|
|
|
|
virtual void Unlink() = 0;
|
2022-04-06 01:19:47 +03:00
|
|
|
virtual void Trace(const TraceCallbacks& aCallbacks, void* aClosure) = 0;
|
2018-08-18 19:43:22 +03:00
|
|
|
|
|
|
|
RefPtr<Promise> mPromise;
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2020-03-28 16:57:17 +03:00
|
|
|
template <typename T, bool = IsRefcounted<std::remove_pointer_t<T>>::value,
|
2020-03-28 16:57:17 +03:00
|
|
|
bool = (std::is_convertible_v<T, nsISupports*> ||
|
|
|
|
std::is_convertible_v<T*, nsISupports*>)>
|
2018-08-18 19:43:22 +03:00
|
|
|
struct StorageTypeHelper {
|
|
|
|
using Type = T;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
struct StorageTypeHelper<T, true, true> {
|
|
|
|
using Type = nsCOMPtr<T>;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
struct StorageTypeHelper<nsCOMPtr<T>, true, true> {
|
|
|
|
using Type = nsCOMPtr<T>;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
struct StorageTypeHelper<T*, true, false> {
|
|
|
|
using Type = RefPtr<T>;
|
|
|
|
};
|
|
|
|
|
2022-04-06 01:19:47 +03:00
|
|
|
template <typename T>
|
|
|
|
struct StorageTypeHelper<JS::Handle<T>, false, false> {
|
|
|
|
using Type = JS::Heap<T>;
|
|
|
|
};
|
|
|
|
|
2018-08-18 19:43:22 +03:00
|
|
|
template <template <typename> class SmartPtr, typename T>
|
|
|
|
struct StorageTypeHelper<SmartPtr<T>, true, false>
|
2020-03-28 16:35:31 +03:00
|
|
|
: std::enable_if<std::is_convertible_v<SmartPtr<T>, T*>, RefPtr<T>> {
|
|
|
|
using Type = typename StorageTypeHelper::enable_if::type;
|
|
|
|
};
|
2018-08-18 19:43:22 +03:00
|
|
|
|
|
|
|
template <typename T>
|
2020-03-28 16:57:15 +03:00
|
|
|
using StorageType = typename StorageTypeHelper<std::decay_t<T>>::Type;
|
2018-08-18 19:43:22 +03:00
|
|
|
|
2018-08-27 23:10:23 +03:00
|
|
|
// Helpers to choose the correct argument type based on the storage type. Smart
|
|
|
|
// pointers are converted to the corresponding raw pointer type. Everything else
|
|
|
|
// is passed by move reference.
|
|
|
|
//
|
|
|
|
// Note: We can't just use std::forward for this because the input type may be a
|
|
|
|
// raw pointer which does not match the argument type, and while the
|
|
|
|
// spec-compliant behavior there should still give us the expected results, MSVC
|
|
|
|
// considers it an illegal use of std::forward.
|
|
|
|
template <template <typename> class SmartPtr, typename T>
|
2020-03-28 16:57:18 +03:00
|
|
|
decltype(std::declval<SmartPtr<T>>().get()) ArgType(SmartPtr<T>& aVal) {
|
2018-08-27 23:10:23 +03:00
|
|
|
return aVal.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T&& ArgType(T& aVal) {
|
|
|
|
return std::move(aVal);
|
|
|
|
}
|
|
|
|
|
2018-08-18 19:43:22 +03:00
|
|
|
using ::ImplCycleCollectionUnlink;
|
|
|
|
|
2022-04-06 01:19:47 +03:00
|
|
|
template <typename ResolveCallback, typename RejectCallback, typename ArgsTuple,
|
|
|
|
typename JSArgsTuple>
|
|
|
|
class NativeThenHandler;
|
|
|
|
|
|
|
|
template <typename ResolveCallback, typename RejectCallback, typename... Args,
|
|
|
|
typename... JSArgs>
|
|
|
|
class NativeThenHandler<ResolveCallback, RejectCallback, std::tuple<Args...>,
|
|
|
|
std::tuple<JSArgs...>>
|
|
|
|
final : public PromiseNativeThenHandlerBase {
|
2018-08-18 19:43:22 +03:00
|
|
|
public:
|
2022-03-21 19:45:35 +03:00
|
|
|
/**
|
|
|
|
* @param aPromise A promise that will be settled by the result of the
|
2022-03-21 19:45:36 +03:00
|
|
|
* callbacks. Any thrown value to ErrorResult passed to those callbacks will
|
2022-03-21 19:45:35 +03:00
|
|
|
* be used to reject the promise, otherwise the promise will be resolved with
|
|
|
|
* the return value.
|
|
|
|
* @param aOnResolve A resolve callback
|
2022-03-21 19:45:36 +03:00
|
|
|
* @param aOnReject A reject callback
|
2022-03-21 19:45:35 +03:00
|
|
|
* @param aArgs The custom arguments to be passed to the both callbacks. The
|
|
|
|
* handler class will grab them to make them live long enough and to allow
|
|
|
|
* cycle collection.
|
2022-04-06 01:19:47 +03:00
|
|
|
* @param aJSArgs The JS arguments to be passed to the both callbacks, after
|
|
|
|
* native arguments. The handler will also grab them and allow garbage
|
|
|
|
* collection.
|
2022-03-21 19:45:36 +03:00
|
|
|
*
|
|
|
|
* XXX(krosylight): ideally there should be two signatures, with or without a
|
|
|
|
* promise parameter. Unfortunately doing so confuses the compiler and errors
|
|
|
|
* out, because nothing prevents promise from being ResolveCallback.
|
2022-03-21 19:45:35 +03:00
|
|
|
*/
|
2022-03-22 19:44:58 +03:00
|
|
|
NativeThenHandler(Promise* aPromise, Maybe<ResolveCallback>&& aOnResolve,
|
2022-04-06 01:19:47 +03:00
|
|
|
Maybe<RejectCallback>&& aOnReject,
|
|
|
|
std::tuple<std::remove_reference_t<Args>...>&& aArgs,
|
|
|
|
std::tuple<std::remove_reference_t<JSArgs>...>&& aJSArgs)
|
2018-08-18 19:43:22 +03:00
|
|
|
: PromiseNativeThenHandlerBase(aPromise),
|
2022-03-22 19:44:58 +03:00
|
|
|
mOnResolve(std::forward<Maybe<ResolveCallback>>(aOnResolve)),
|
|
|
|
mOnReject(std::forward<Maybe<RejectCallback>>(aOnReject)),
|
2022-04-06 01:19:47 +03:00
|
|
|
mArgs(std::forward<decltype(aArgs)>(aArgs)),
|
|
|
|
mJSArgs(std::forward<decltype(aJSArgs)>(aJSArgs)) {
|
|
|
|
if constexpr (std::tuple_size<decltype(mJSArgs)>::value > 0) {
|
|
|
|
mozilla::HoldJSObjects(this);
|
|
|
|
}
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-08-18 19:43:22 +03:00
|
|
|
protected:
|
2022-04-06 01:19:47 +03:00
|
|
|
~NativeThenHandler() override {
|
|
|
|
if constexpr (std::tuple_size<decltype(mJSArgs)>::value > 0) {
|
|
|
|
mozilla::DropJSObjects(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-18 19:43:22 +03:00
|
|
|
void Traverse(nsCycleCollectionTraversalCallback& cb) override {
|
|
|
|
auto* tmp = this;
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mArgs)
|
|
|
|
}
|
|
|
|
|
|
|
|
void Unlink() override {
|
|
|
|
auto* tmp = this;
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mArgs)
|
2022-04-06 01:19:47 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mJSArgs)
|
|
|
|
}
|
|
|
|
|
|
|
|
void Trace(const TraceCallbacks& aCallbacks, void* aClosure) override {
|
|
|
|
std::apply(
|
|
|
|
[&aCallbacks, aClosure](auto&&... aArgs) {
|
|
|
|
(aCallbacks.Trace(&aArgs, "mJSArgs[]", aClosure), ...);
|
|
|
|
},
|
|
|
|
mJSArgs);
|
2018-08-18 19:43:22 +03:00
|
|
|
}
|
|
|
|
|
2022-03-22 19:44:58 +03:00
|
|
|
bool HasResolvedCallback() override { return mOnResolve.isSome(); }
|
|
|
|
bool HasRejectedCallback() override { return mOnReject.isSome(); }
|
|
|
|
|
2022-10-22 12:42:27 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> CallResolveCallback(
|
|
|
|
JSContext* aCx, JS::Handle<JS::Value> aValue, ErrorResult& aRv) override {
|
2022-03-22 19:44:58 +03:00
|
|
|
return CallCallback(aCx, *mOnResolve, aValue, aRv);
|
2018-08-18 19:43:22 +03:00
|
|
|
}
|
2022-10-22 12:42:27 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> CallRejectCallback(
|
|
|
|
JSContext* aCx, JS::Handle<JS::Value> aValue, ErrorResult& aRv) override {
|
2022-03-22 19:44:58 +03:00
|
|
|
return CallCallback(aCx, *mOnReject, aValue, aRv);
|
2022-03-21 19:45:36 +03:00
|
|
|
}
|
2018-08-18 19:43:22 +03:00
|
|
|
|
2022-04-06 01:19:47 +03:00
|
|
|
// mJSArgs are marked with Trace() above, so they can be safely converted to
|
2023-03-01 18:20:26 +03:00
|
|
|
// Handles. But we should not circumvent the read barrier, so call
|
|
|
|
// exposeToActiveJS explicitly.
|
2022-04-06 01:19:47 +03:00
|
|
|
template <typename T>
|
2023-03-01 18:20:26 +03:00
|
|
|
static JS::Handle<T> GetJSArgHandleForCall(JS::Heap<T>& aArg) {
|
|
|
|
aArg.exposeToActiveJS();
|
2024-06-13 10:33:54 +03:00
|
|
|
return JS::Handle<T>::fromMarkedLocation(aArg.unsafeAddress());
|
2022-04-06 01:19:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename TCallback, size_t... Indices, size_t... JSIndices>
|
2022-10-22 12:42:27 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> CallCallback(
|
|
|
|
JSContext* aCx, const TCallback& aHandler, JS::Handle<JS::Value> aValue,
|
|
|
|
ErrorResult& aRv, std::index_sequence<Indices...>,
|
|
|
|
std::index_sequence<JSIndices...>) {
|
2022-04-06 01:19:47 +03:00
|
|
|
return aHandler(aCx, aValue, aRv, ArgType(std::get<Indices>(mArgs))...,
|
2023-03-01 18:20:26 +03:00
|
|
|
GetJSArgHandleForCall(std::get<JSIndices>(mJSArgs))...);
|
2018-08-18 19:43:22 +03:00
|
|
|
}
|
|
|
|
|
2022-03-21 19:45:36 +03:00
|
|
|
template <typename TCallback>
|
2022-10-22 12:42:27 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> CallCallback(
|
|
|
|
JSContext* aCx, const TCallback& aHandler, JS::Handle<JS::Value> aValue,
|
|
|
|
ErrorResult& aRv) {
|
2022-03-21 19:45:35 +03:00
|
|
|
return CallCallback(aCx, aHandler, aValue, aRv,
|
2022-04-06 01:19:47 +03:00
|
|
|
std::index_sequence_for<Args...>{},
|
|
|
|
std::index_sequence_for<JSArgs...>{});
|
2018-08-18 19:43:22 +03:00
|
|
|
}
|
|
|
|
|
2022-03-22 19:44:58 +03:00
|
|
|
Maybe<ResolveCallback> mOnResolve;
|
|
|
|
Maybe<RejectCallback> mOnReject;
|
2018-08-18 19:43:22 +03:00
|
|
|
|
2022-03-22 19:44:58 +03:00
|
|
|
std::tuple<StorageType<Args>...> mArgs;
|
2022-04-06 01:19:47 +03:00
|
|
|
std::tuple<StorageType<JSArgs>...> mJSArgs;
|
2018-08-18 19:43:22 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
2022-09-22 21:28:18 +03:00
|
|
|
template <typename ResolveCallback, typename RejectCallback, typename... Args,
|
|
|
|
typename... JSArgs>
|
|
|
|
Result<RefPtr<Promise>, nsresult>
|
|
|
|
Promise::ThenCatchWithCycleCollectedArgsJSImpl(
|
2022-03-22 19:44:58 +03:00
|
|
|
Maybe<ResolveCallback>&& aOnResolve, Maybe<RejectCallback>&& aOnReject,
|
2022-09-22 21:28:18 +03:00
|
|
|
std::tuple<Args...>&& aArgs, std::tuple<JSArgs...>&& aJSArgs) {
|
|
|
|
using HandlerType =
|
|
|
|
NativeThenHandler<ResolveCallback, RejectCallback, std::tuple<Args...>,
|
|
|
|
std::tuple<JSArgs...>>;
|
2018-08-18 19:43:22 +03:00
|
|
|
|
|
|
|
ErrorResult rv;
|
|
|
|
RefPtr<Promise> promise = Promise::Create(GetParentObject(), rv);
|
|
|
|
if (rv.Failed()) {
|
|
|
|
return Err(rv.StealNSResult());
|
|
|
|
}
|
|
|
|
|
2022-09-22 21:28:18 +03:00
|
|
|
auto* handler = new (fallible)
|
|
|
|
HandlerType(promise, std::forward<Maybe<ResolveCallback>>(aOnResolve),
|
|
|
|
std::forward<Maybe<RejectCallback>>(aOnReject),
|
|
|
|
std::forward<std::tuple<Args...>>(aArgs),
|
|
|
|
std::forward<std::tuple<JSArgs...>>(aJSArgs));
|
2018-08-18 19:43:22 +03:00
|
|
|
|
|
|
|
if (!handler) {
|
|
|
|
return Err(NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
}
|
|
|
|
|
|
|
|
AppendNativeHandler(handler);
|
|
|
|
return std::move(promise);
|
|
|
|
}
|
|
|
|
|
2022-09-22 21:28:18 +03:00
|
|
|
template <typename ResolveCallback, typename RejectCallback, typename... Args>
|
|
|
|
Promise::ThenResult<ResolveCallback, Args...>
|
|
|
|
Promise::ThenCatchWithCycleCollectedArgsImpl(
|
|
|
|
Maybe<ResolveCallback>&& aOnResolve, Maybe<RejectCallback>&& aOnReject,
|
|
|
|
Args&&... aArgs) {
|
|
|
|
return ThenCatchWithCycleCollectedArgsJSImpl(
|
|
|
|
std::forward<Maybe<ResolveCallback>>(aOnResolve),
|
|
|
|
std::forward<Maybe<RejectCallback>>(aOnReject),
|
|
|
|
std::make_tuple(std::forward<Args>(aArgs)...), std::make_tuple());
|
|
|
|
}
|
|
|
|
|
2022-03-22 19:44:58 +03:00
|
|
|
template <typename ResolveCallback, typename RejectCallback, typename... Args>
|
|
|
|
Promise::ThenResult<ResolveCallback, Args...>
|
|
|
|
Promise::ThenCatchWithCycleCollectedArgs(ResolveCallback&& aOnResolve,
|
|
|
|
RejectCallback&& aOnReject,
|
|
|
|
Args&&... aArgs) {
|
|
|
|
return ThenCatchWithCycleCollectedArgsImpl(Some(aOnResolve), Some(aOnReject),
|
|
|
|
std::forward<Args>(aArgs)...);
|
|
|
|
}
|
|
|
|
|
2022-03-21 19:45:36 +03:00
|
|
|
template <typename Callback, typename... Args>
|
|
|
|
Promise::ThenResult<Callback, Args...> Promise::ThenWithCycleCollectedArgs(
|
|
|
|
Callback&& aOnResolve, Args&&... aArgs) {
|
2022-03-22 19:44:58 +03:00
|
|
|
return ThenCatchWithCycleCollectedArgsImpl(Some(aOnResolve),
|
|
|
|
Maybe<Callback>(Nothing()),
|
|
|
|
std::forward<Args>(aArgs)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Callback, typename... Args>
|
|
|
|
Promise::ThenResult<Callback, Args...> Promise::CatchWithCycleCollectedArgs(
|
|
|
|
Callback&& aOnReject, Args&&... aArgs) {
|
|
|
|
return ThenCatchWithCycleCollectedArgsImpl(Maybe<Callback>(Nothing()),
|
|
|
|
Some(aOnReject),
|
|
|
|
std::forward<Args>(aArgs)...);
|
2022-03-21 19:45:36 +03:00
|
|
|
}
|
|
|
|
|
2022-09-22 21:28:18 +03:00
|
|
|
template <typename ResolveCallback, typename RejectCallback, typename ArgsTuple,
|
|
|
|
typename JSArgsTuple>
|
|
|
|
Result<RefPtr<Promise>, nsresult> Promise::ThenCatchWithCycleCollectedArgsJS(
|
|
|
|
ResolveCallback&& aOnResolve, RejectCallback&& aOnReject, ArgsTuple&& aArgs,
|
|
|
|
JSArgsTuple&& aJSArgs) {
|
|
|
|
return ThenCatchWithCycleCollectedArgsJSImpl(
|
|
|
|
Some(aOnResolve), Some(aOnReject), std::forward<ArgsTuple>(aArgs),
|
|
|
|
std::forward<JSArgsTuple>(aJSArgs));
|
|
|
|
}
|
|
|
|
|
2022-04-06 01:19:47 +03:00
|
|
|
template <typename Callback, typename ArgsTuple, typename JSArgsTuple>
|
|
|
|
Result<RefPtr<Promise>, nsresult> Promise::ThenWithCycleCollectedArgsJS(
|
|
|
|
Callback&& aOnResolve, ArgsTuple&& aArgs, JSArgsTuple&& aJSArgs) {
|
2022-09-22 21:28:18 +03:00
|
|
|
return ThenCatchWithCycleCollectedArgsJSImpl(
|
|
|
|
Some(aOnResolve), Maybe<Callback>(Nothing()),
|
2022-04-06 01:19:47 +03:00
|
|
|
std::forward<ArgsTuple>(aArgs), std::forward<JSArgsTuple>(aJSArgs));
|
|
|
|
}
|
|
|
|
|
2022-03-21 19:45:37 +03:00
|
|
|
template <typename ResolveCallback, typename RejectCallback, typename... Args>
|
|
|
|
void Promise::AddCallbacksWithCycleCollectedArgs(ResolveCallback&& aOnResolve,
|
|
|
|
RejectCallback&& aOnReject,
|
|
|
|
Args&&... aArgs) {
|
|
|
|
auto onResolve =
|
2022-05-18 11:43:08 +03:00
|
|
|
[aOnResolve](JSContext* aCx, JS::Handle<JS::Value> value,
|
|
|
|
ErrorResult& aRv,
|
2022-03-21 19:45:37 +03:00
|
|
|
StorageType<Args>&&... aArgs) -> already_AddRefed<Promise> {
|
|
|
|
aOnResolve(aCx, value, aRv, aArgs...);
|
|
|
|
return nullptr;
|
|
|
|
};
|
|
|
|
auto onReject =
|
2022-05-18 11:43:08 +03:00
|
|
|
[aOnReject](JSContext* aCx, JS::Handle<JS::Value> value, ErrorResult& aRv,
|
2022-03-21 19:45:37 +03:00
|
|
|
StorageType<Args>&&... aArgs) -> already_AddRefed<Promise> {
|
|
|
|
aOnReject(aCx, value, aRv, aArgs...);
|
|
|
|
return nullptr;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Note: explicit template parameters for clang<7/gcc<8 without "Template
|
|
|
|
// argument deduction for class templates" support
|
|
|
|
AppendNativeHandler(
|
2022-04-06 01:19:47 +03:00
|
|
|
new NativeThenHandler<decltype(onResolve), decltype(onReject),
|
|
|
|
std::tuple<Args...>, std::tuple<>>(
|
2022-03-22 19:44:58 +03:00
|
|
|
nullptr, Some(onResolve), Some(onReject),
|
2022-04-06 01:19:47 +03:00
|
|
|
std::make_tuple(std::forward<Args>(aArgs)...), std::make_tuple()));
|
2022-03-21 19:45:37 +03:00
|
|
|
}
|
|
|
|
|
2022-03-22 19:44:58 +03:00
|
|
|
} // namespace mozilla::dom
|
2018-08-18 19:43:22 +03:00
|
|
|
|
|
|
|
#endif // mozilla_dom_Promise_inl_h
|