diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index a636a31ecb..a507dea841 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -30,6 +30,7 @@ #include "nsContentUtils.h" #include "nsUnicharUtils.h" #include "mozilla/Preferences.h" +#include "mozilla/dom/Clipboard.h" #ifdef MOZ_GAMEPAD #include "mozilla/dom/GamepadServiceTest.h" #endif @@ -1510,6 +1511,15 @@ Navigator::GetUserAgent(nsPIDOMWindowInner* aWindow, nsIURI* aURI, return siteSpecificUA->GetUserAgentForURIAndWindow(aURI, aWindow, aUserAgent); } +Clipboard* +Navigator::Clipboard() +{ + if (!mClipboard) { + mClipboard = new dom::Clipboard(GetWindow()); + } + return mClipboard; +} + #ifdef MOZ_EME static nsCString ToCString(const nsString& aString) diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h index 3a0c9cc45f..69626d1a7c 100644 --- a/dom/base/Navigator.h +++ b/dom/base/Navigator.h @@ -40,6 +40,7 @@ class WakeLock; class ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams; class ServiceWorkerContainer; class DOMRequest; +class Clipboard; } // namespace dom } // namespace mozilla @@ -213,6 +214,8 @@ public: ErrorResult& aRv); already_AddRefed ServiceWorker(); + + dom::Clipboard* Clipboard(); void GetLanguages(nsTArray& aLanguages); @@ -277,6 +280,7 @@ private: RefPtr mNotification; RefPtr mPowerManager; RefPtr mConnection; + RefPtr mClipboard; #ifdef MOZ_AUDIO_CHANNEL_MANAGER RefPtr mAudioChannelManager; #endif diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index fcd84e28b6..26751ac8c6 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -169,6 +169,10 @@ DOMInterfaces = { 'headerFile': 'mozilla/dom/workers/bindings/ServiceWorkerClients.h', }, +'Clipboard' : { + 'implicitJSContext' : ['write', 'writeText', 'read', 'readText'], +}, + 'console': { 'nativeType': 'mozilla::dom::Console', }, diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp index 6ed49c969d..6c4051e508 100644 --- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -676,9 +676,11 @@ WebGLContext::CreateAndInitGL(bool forceEnabled, std::vector* const out_failReasons) { const gl::SurfaceCaps baseCaps = BaseCaps(mOptions, this); - gl::CreateContextFlags flags = gl::CreateContextFlags::NO_VALIDATION; - bool tryNativeGL = true; - bool tryANGLE = false; + gl::CreateContextFlags flags = gl::CreateContextFlags::NONE; + + if (Preferences::GetBool("webgl.gl_khr_no_validation", false)) { + flags |= gl::CreateContextFlags::NO_VALIDATION; + } if (forceEnabled) { flags |= gl::CreateContextFlags::FORCE_ENABLE_HARDWARE; @@ -694,6 +696,9 @@ WebGLContext::CreateAndInitGL(bool forceEnabled, const bool useEGL = PR_GetEnv("MOZ_WEBGL_FORCE_EGL"); + bool tryNativeGL = true; + bool tryANGLE = false; + #ifdef XP_WIN tryNativeGL = false; tryANGLE = true; diff --git a/dom/canvas/WebGLTextureUpload.cpp b/dom/canvas/WebGLTextureUpload.cpp index 661fb91ce2..6b864f2ff5 100644 --- a/dom/canvas/WebGLTextureUpload.cpp +++ b/dom/canvas/WebGLTextureUpload.cpp @@ -2188,6 +2188,7 @@ WebGLTexture::CopyTexImage2D(TexImageTarget target, GLint level, GLenum internal srcTotalWidth, srcTotalHeight, srcUsage, 0, 0, 0, width, height, dstUsage)) { + Truncate(); return; } diff --git a/dom/events/Clipboard.cpp b/dom/events/Clipboard.cpp new file mode 100644 index 0000000000..4bfa15b725 --- /dev/null +++ b/dom/events/Clipboard.cpp @@ -0,0 +1,166 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "mozilla/AbstractThread.h" +#include "mozilla/dom/Clipboard.h" +#include "mozilla/dom/ClipboardBinding.h" +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/DataTransfer.h" +#include "mozilla/dom/DataTransferItemList.h" +#include "mozilla/dom/DataTransferItem.h" +#include "mozilla/dom/ContentChild.h" +#include "nsIClipboard.h" +#include "nsISupportsPrimitives.h" +#include "nsComponentManagerUtils.h" +#include "nsITransferable.h" +#include "nsArrayUtils.h" + + +static mozilla::LazyLogModule gClipboardLog("Clipboard"); + +namespace mozilla { +namespace dom { + +Clipboard::Clipboard(nsPIDOMWindowInner* aWindow) +: DOMEventTargetHelper(aWindow) +{ +} + +Clipboard::~Clipboard() +{ +} + +already_AddRefed +Clipboard::ReadHelper(JSContext* aCx, nsIPrincipal& aSubjectPrincipal, + ClipboardReadType aClipboardReadType, ErrorResult& aRv) +{ + // Create a new promise + RefPtr p = dom::Promise::Create(GetOwnerGlobal(), aRv); + if (aRv.Failed()) { + return nullptr; + } + + // We always reject reading from clipboard for sec reasons. + MOZ_LOG(GetClipboardLog(), LogLevel::Debug, ("Clipboard, ReadHelper, " + "Don't have permissions for reading\n")); + p->MaybeRejectWithUndefined(); + return p.forget(); +} + +already_AddRefed +Clipboard::Read(JSContext* aCx, nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) +{ + return ReadHelper(aCx, aSubjectPrincipal, eRead, aRv); +} + +already_AddRefed +Clipboard::ReadText(JSContext* aCx, nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) +{ + return ReadHelper(aCx, aSubjectPrincipal, eReadText, aRv); +} + +already_AddRefed +Clipboard::Write(JSContext* aCx, DataTransfer& aData, nsIPrincipal& aSubjectPrincipal, + ErrorResult& aRv) +{ + // Create a promise + RefPtr p = dom::Promise::Create(GetOwnerGlobal(), aRv); + if (aRv.Failed()) { + return nullptr; + } + + // We want to disable this if dom.allow_cut_copy is false, or + // it doesn't meet the other requirements for copying to clipboard + if (!nsContentUtils::IsCutCopyAllowed()) { + MOZ_LOG(GetClipboardLog(), LogLevel::Debug, + ("Clipboard, Write, Not allowed to write to clipboard\n")); + p->MaybeRejectWithUndefined(); + return p.forget(); + } + + // Get the clipboard service + nsCOMPtr clipboard(do_GetService("@mozilla.org/widget/clipboard;1")); + if (!clipboard) { + p->MaybeRejectWithUndefined(); + return p.forget(); + } + + nsPIDOMWindowInner* owner = GetOwner(); + nsIDocument* doc = owner ? owner->GetDoc() : nullptr; + nsILoadContext* context = doc ? doc->GetLoadContext() : nullptr; + if (!context) { + p->MaybeRejectWithUndefined(); + return p.forget(); + } + + // Get the transferable + RefPtr transferable = aData.GetTransferable(0, context); + if (!transferable) { + p->MaybeRejectWithUndefined(); + return p.forget(); + } + + // Create a runnable + RefPtr r = NS_NewRunnableFunction( + [transferable, p, clipboard]() { + nsresult rv = clipboard->SetData(transferable, + /* owner of the transferable */ nullptr, + nsIClipboard::kGlobalClipboard); + if (NS_FAILED(rv)) { + p->MaybeRejectWithUndefined(); + return; + } + p->MaybeResolveWithUndefined(); + return; + }); + // Dispatch the runnable + NS_DispatchToCurrentThread(r.forget()); + return p.forget(); +} + +already_AddRefed +Clipboard::WriteText(JSContext* aCx, const nsAString& aData, + nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) +{ + // We create a data transfer with text/plain format so that + // we can reuse the Clipboard::Write(...) member function + // We want isExternal = true in order to use the data transfer object to perform a write + RefPtr dataTransfer = new DataTransfer(this, eCopy, + /* is external */ true, + /* clipboard type */ -1); + dataTransfer->SetData(NS_LITERAL_STRING(kTextMime), aData, aSubjectPrincipal, aRv); + return Write(aCx, *dataTransfer, aSubjectPrincipal, aRv); +} + +JSObject* +Clipboard::WrapObject(JSContext* aCx, JS::Handle aGivenProto) +{ + return ClipboardBinding::Wrap(aCx, this, aGivenProto); +} + +/* static */ LogModule* +Clipboard::GetClipboardLog() +{ + return gClipboardLog; +} + +NS_IMPL_CYCLE_COLLECTION_CLASS(Clipboard) + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(Clipboard, + DOMEventTargetHelper) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(Clipboard, + DOMEventTargetHelper) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Clipboard) +NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) + +NS_IMPL_ADDREF_INHERITED(Clipboard, DOMEventTargetHelper) +NS_IMPL_RELEASE_INHERITED(Clipboard, DOMEventTargetHelper) + +} // namespace dom +} // namespace mozilla diff --git a/dom/events/Clipboard.h b/dom/events/Clipboard.h new file mode 100644 index 0000000000..9960de652b --- /dev/null +++ b/dom/events/Clipboard.h @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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_Clipboard_h_ +#define mozilla_dom_Clipboard_h_ + +#include "nsString.h" +#include "mozilla/DOMEventTargetHelper.h" +#include "mozilla/Logging.h" +#include "mozilla/dom/DataTransfer.h" + +namespace mozilla { +namespace dom { + +enum ClipboardReadType { + eRead, + eReadText, +}; + +class Promise; + +// https://www.w3.org/TR/clipboard-apis/#clipboard-interface +class Clipboard : public DOMEventTargetHelper +{ +public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(Clipboard, + DOMEventTargetHelper) + + IMPL_EVENT_HANDLER(message) + //IMPL_EVENT_HANDLER(messageerror) + + explicit Clipboard(nsPIDOMWindowInner* aWindow); + already_AddRefed Read(JSContext* aCx, nsIPrincipal& aSubjectPrincipal, + ErrorResult& aRv); + already_AddRefed ReadText(JSContext* aCx, nsIPrincipal& aSubjectPrincipal, + ErrorResult& aRv); + already_AddRefed Write(JSContext* aCx, DataTransfer& aData, + nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv); + already_AddRefed WriteText(JSContext* aCx, const nsAString& aData, + nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv); + + static LogModule* GetClipboardLog(); + + + virtual JSObject* + WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; + +private: + already_AddRefed ReadHelper(JSContext* aCx, nsIPrincipal& aSubjectPrincipal, + ClipboardReadType aClipboardReadType, ErrorResult& aRv); + + ~Clipboard(); +}; + +} // namespace dom +} // namespace mozilla +#endif // mozilla_dom_Clipboard_h_ diff --git a/dom/events/DataTransfer.cpp b/dom/events/DataTransfer.cpp index 3a3f5464d2..7ac154ea4b 100644 --- a/dom/events/DataTransfer.cpp +++ b/dom/events/DataTransfer.cpp @@ -1204,16 +1204,12 @@ DataTransfer::ConvertFromVariant(nsIVariant* aVariant, return true; } - char16_t* chrs; - uint32_t len = 0; - nsresult rv = aVariant->GetAsWStringWithSize(&len, &chrs); + nsAutoString str; + nsresult rv = aVariant->GetAsAString(str); if (NS_FAILED(rv)) { return false; } - nsAutoString str; - str.Adopt(chrs, len); - nsCOMPtr strSupports(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); if (!strSupports) { @@ -1225,7 +1221,7 @@ DataTransfer::ConvertFromVariant(nsIVariant* aVariant, strSupports.forget(aSupports); // each character is two bytes - *aLength = str.Length() << 1; + *aLength = str.Length() * 2; return true; } @@ -1410,9 +1406,7 @@ DataTransfer::CacheExternalClipboardFormats() return; } - nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); - nsCOMPtr sysPrincipal; - ssm->GetSystemPrincipal(getter_AddRefs(sysPrincipal)); + nsCOMPtr sysPrincipal = nsContentUtils::GetSystemPrincipal(); // Check if the clipboard has any files bool hasFileData = false; diff --git a/dom/events/DataTransfer.h b/dom/events/DataTransfer.h index dbb4ec9bf8..f35020e111 100644 --- a/dom/events/DataTransfer.h +++ b/dom/events/DataTransfer.h @@ -315,6 +315,7 @@ protected: uint32_t aIndex, nsIPrincipal* aSubjectPrincipal); friend class ContentParent; + friend class Clipboard; void FillAllExternalData(); diff --git a/dom/events/DataTransferItemList.cpp b/dom/events/DataTransferItemList.cpp index ecea4968ce..630ae8a957 100644 --- a/dom/events/DataTransferItemList.cpp +++ b/dom/events/DataTransferItemList.cpp @@ -152,7 +152,8 @@ DataTransferItemList::Add(const nsAString& aData, return nullptr; } - nsCOMPtr data(new storage::TextVariant(aData)); + RefPtr data(new nsVariantCC()); + data->SetAsAString(aData); nsAutoString format; mDataTransfer->GetRealFormat(aType, format); diff --git a/dom/events/moz.build b/dom/events/moz.build index fcb59a2975..ae57e91fe3 100644 --- a/dom/events/moz.build +++ b/dom/events/moz.build @@ -37,6 +37,7 @@ EXPORTS.mozilla.dom += [ 'AnimationEvent.h', 'BeforeAfterKeyboardEvent.h', 'BeforeUnloadEvent.h', + 'Clipboard.h', 'ClipboardEvent.h', 'CommandEvent.h', 'CompositionEvent.h', @@ -78,6 +79,7 @@ UNIFIED_SOURCES += [ 'AsyncEventDispatcher.cpp', 'BeforeAfterKeyboardEvent.cpp', 'BeforeUnloadEvent.cpp', + 'Clipboard.cpp', 'ClipboardEvent.cpp', 'CommandEvent.cpp', 'CompositionEvent.cpp', diff --git a/dom/messagechannel/MessagePort.cpp b/dom/messagechannel/MessagePort.cpp index 5fbd1e9bb9..ee537607bf 100644 --- a/dom/messagechannel/MessagePort.cpp +++ b/dom/messagechannel/MessagePort.cpp @@ -296,6 +296,11 @@ MessagePort::MessagePort(nsIGlobalObject* aGlobal) MessagePort::~MessagePort() { CloseForced(); + MOZ_ASSERT(!mActor); + if (mActor) { + mActor->SetPort(nullptr); + mActor = nullptr; + } MOZ_ASSERT(!mWorkerHolder); } @@ -370,6 +375,7 @@ MessagePort::Initialize(const nsID& aUUID, nsAutoPtr workerHolder(new MessagePortWorkerHolder(this)); if (NS_WARN_IF(!workerHolder->HoldWorker(workerPrivate, Closing))) { + CloseForced(); aRv.Throw(NS_ERROR_FAILURE); return; } diff --git a/dom/security/nsMixedContentBlocker.cpp b/dom/security/nsMixedContentBlocker.cpp index 031bc27db7..f980acf018 100644 --- a/dom/security/nsMixedContentBlocker.cpp +++ b/dom/security/nsMixedContentBlocker.cpp @@ -729,10 +729,10 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect, docShell->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot)); NS_ASSERTION(sameTypeRoot, "No root tree item from docshell!"); - // When navigating an iframe, the iframe may be https - // but its parents may not be. Check the parents to see if any of them are https. - // If none of the parents are https, allow the load. - if (aContentType == TYPE_SUBDOCUMENT && !rootHasSecureConnection) { + // When navigating an iframe, the iframe may be https but its parents may not + // be. Check the parents to see if any of them are https. If none of the + // parents are https, allow the load. + if (aContentType == TYPE_SUBDOCUMENT && !rootHasSecureConnection && !parentIsHttps) { bool httpsParentExists = false; diff --git a/dom/webidl/Clipboard.webidl b/dom/webidl/Clipboard.webidl new file mode 100644 index 0000000000..65fa976af6 --- /dev/null +++ b/dom/webidl/Clipboard.webidl @@ -0,0 +1,25 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. + * + * The origin of this IDL file is + * http://www.w3.org/TR/geolocation-API + * + * Copyright © 2018 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ + + +[SecureContext, Exposed=Window, Pref="dom.events.asyncClipboard"] +interface Clipboard : EventTarget { + [Pref="dom.events.asyncClipboard.dataTransfer", Throws, NeedsSubjectPrincipal] + Promise read(); + [Throws, NeedsSubjectPrincipal] + Promise readText(); + [Pref="dom.events.asyncClipboard.dataTransfer", Throws, NeedsSubjectPrincipal] + Promise write(DataTransfer data); + [Throws, NeedsSubjectPrincipal] + Promise writeText(DOMString data); +}; + diff --git a/dom/webidl/Navigator.webidl b/dom/webidl/Navigator.webidl index eacb6c9443..60ed84d535 100644 --- a/dom/webidl/Navigator.webidl +++ b/dom/webidl/Navigator.webidl @@ -324,3 +324,9 @@ partial interface Navigator { interface NavigatorConcurrentHardware { readonly attribute unsigned long long hardwareConcurrency; }; + +// https://www.w3.org/TR/clipboard-apis/#navigator-interface +partial interface Navigator { + [Pref="dom.events.asyncClipboard", SecureContext, SameObject] + readonly attribute Clipboard clipboard; +}; diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index cc1f16c81f..6e7871efa0 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -74,6 +74,7 @@ WEBIDL_FILES = [ 'ChromeUtils.webidl', 'Client.webidl', 'Clients.webidl', + 'Clipboard.webidl', 'ClipboardEvent.webidl', 'CommandEvent.webidl', 'Comment.webidl', diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index f3a156c7cb..457eb24539 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -4345,6 +4345,13 @@ pref("webgl.dxgl.enabled", true); pref("webgl.dxgl.needs-finish", false); #endif +// Disable ANGLE's validation layer? +#ifdef XP_WIN +pref("webgl.gl_khr_no_validation", false); +#else +pref("webgl.gl_khr_no_validation", true); +#endif + pref("gfx.offscreencanvas.enabled", false); // Stagefright prefs @@ -5284,3 +5291,8 @@ pref("media.sourceErrorDetails.enabled", true); #else pref("media.sourceErrorDetails.enabled", false); #endif + +// Whether Navigator.Clipboard methods are a thing. +pref("dom.events.asyncClipboard", true); +// Whether arbitrary data transfer methods (not plaintext) are allowed. +pref("dom.events.asyncClipboard.dataTransfer", true); diff --git a/netwerk/base/nsStandardURL.cpp b/netwerk/base/nsStandardURL.cpp index aa60b52cd5..9334def6c7 100644 --- a/netwerk/base/nsStandardURL.cpp +++ b/netwerk/base/nsStandardURL.cpp @@ -2541,7 +2541,15 @@ nsStandardURL::Resolve(const nsACString &in, nsACString &out) // locate result path resultPath = PL_strstr(result, "://"); if (resultPath) { - resultPath = PL_strchr(resultPath + 3, '/'); + // If there are multiple slashes after :// we must ignore them + // otherwise net_CoalesceDirs may think the host is a part of the path. + resultPath += 3; + if (protocol.IsEmpty() && !SegmentIs(mScheme,"file")) { + while (*resultPath == '/') { + resultPath++; + } + } + resultPath = PL_strchr(resultPath, '/'); if (resultPath) net_CoalesceDirs(coalesceFlag,resultPath); } diff --git a/xpcom/threads/MozPromise.h b/xpcom/threads/MozPromise.h index 8cc3d51ba0..f97f55bb8d 100644 --- a/xpcom/threads/MozPromise.h +++ b/xpcom/threads/MozPromise.h @@ -229,35 +229,35 @@ private: mResolveValues.SetLength(aDependentPromises); } - void Resolve(size_t aIndex, const ResolveValueType& aResolveValue) + void Resolve(size_t aIndex, ResolveValueType&& aResolveValue) { if (!mPromise) { // Already rejected. return; } - mResolveValues[aIndex].emplace(aResolveValue); + mResolveValues[aIndex].emplace(Move(aResolveValue)); if (--mOutstandingPromises == 0) { nsTArray resolveValues; resolveValues.SetCapacity(mResolveValues.Length()); for (size_t i = 0; i < mResolveValues.Length(); ++i) { - resolveValues.AppendElement(mResolveValues[i].ref()); + resolveValues.AppendElement(Move(mResolveValues[i].ref())); } - mPromise->Resolve(resolveValues, __func__); + mPromise->Resolve(Move(resolveValues), __func__); mPromise = nullptr; mResolveValues.Clear(); } } - void Reject(const RejectValueType& aRejectValue) + void Reject(RejectValueType&& aRejectValue) { if (!mPromise) { // Already rejected. return; } - mPromise->Reject(aRejectValue, __func__); + mPromise->Reject(Move(aRejectValue), __func__); mPromise = nullptr; mResolveValues.Clear(); } @@ -276,8 +276,8 @@ public: RefPtr holder = new AllPromiseHolder(aPromises.Length()); for (size_t i = 0; i < aPromises.Length(); ++i) { aPromises[i]->Then(aProcessingThread, __func__, - [holder, i] (ResolveValueType aResolveValue) -> void { holder->Resolve(i, aResolveValue); }, - [holder] (RejectValueType aRejectValue) -> void { holder->Reject(aRejectValue); } + [holder, i] (ResolveValueType aResolveValue) -> void { holder->Resolve(i, Move(aResolveValue)); }, + [holder] (RejectValueType aRejectValue) -> void { holder->Reject(Move(aRejectValue)); } ); } return holder->Promise();