Bug 1040263. Eagerly create and preserve Promise reflectors so we always have them available during unlink. r=nsm,bholley.

This commit is contained in:
Boris Zbarsky 2014-07-18 21:31:11 -04:00
parent e8ce41b015
commit 92fb7dde3a
45 changed files with 379 additions and 194 deletions

View File

@ -3967,7 +3967,10 @@ HTMLMediaElement::SetMediaKeys(mozilla::dom::MediaKeys* aMediaKeys,
return nullptr;
}
// TODO: Need to shutdown existing MediaKeys instance? bug 1016709.
nsRefPtr<Promise> promise = new Promise(global);
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
}
if (mMediaKeys != aMediaKeys) {
mMediaKeys = aMediaKeys;
}

View File

@ -31,7 +31,8 @@ NS_IMPL_RELEASE_INHERITED(MediaKeySession, DOMEventTargetHelper)
MediaKeySession::MediaKeySession(nsPIDOMWindow* aParent,
MediaKeys* aKeys,
const nsAString& aKeySystem,
SessionType aSessionType)
SessionType aSessionType,
ErrorResult& aRv)
: DOMEventTargetHelper(aParent)
, mKeys(aKeys)
, mKeySystem(aKeySystem)
@ -39,7 +40,7 @@ MediaKeySession::MediaKeySession(nsPIDOMWindow* aParent,
, mIsClosed(false)
{
MOZ_ASSERT(aParent);
mClosed = mKeys->MakePromise();
mClosed = mKeys->MakePromise(aRv);
}
void MediaKeySession::Init(const nsAString& aSessionId)
@ -88,9 +89,12 @@ MediaKeySession::Closed() const
}
already_AddRefed<Promise>
MediaKeySession::Update(const Uint8Array& aResponse)
MediaKeySession::Update(const Uint8Array& aResponse, ErrorResult& aRv)
{
nsRefPtr<Promise> promise(mKeys->MakePromise());
nsRefPtr<Promise> promise(mKeys->MakePromise(aRv));
if (aRv.Failed()) {
return nullptr;
}
aResponse.ComputeLengthAndData();
if (IsClosed() ||
!mKeys->GetCDMProxy() ||
@ -105,9 +109,12 @@ MediaKeySession::Update(const Uint8Array& aResponse)
}
already_AddRefed<Promise>
MediaKeySession::Close()
MediaKeySession::Close(ErrorResult& aRv)
{
nsRefPtr<Promise> promise(mKeys->MakePromise());
nsRefPtr<Promise> promise(mKeys->MakePromise(aRv));
if (aRv.Failed()) {
return nullptr;
}
if (IsClosed() || !mKeys->GetCDMProxy()) {
promise->MaybeResolve(JS::UndefinedHandleValue);
return promise.forget();
@ -137,9 +144,12 @@ MediaKeySession::IsClosed() const
}
already_AddRefed<Promise>
MediaKeySession::Remove()
MediaKeySession::Remove(ErrorResult& aRv)
{
nsRefPtr<Promise> promise(mKeys->MakePromise());
nsRefPtr<Promise> promise(mKeys->MakePromise(aRv));
if (aRv.Failed()) {
return nullptr;
}
if (mSessionType != SessionType::Persistent) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
// "The operation is not supported on session type sessions."

View File

@ -39,7 +39,8 @@ public:
MediaKeySession(nsPIDOMWindow* aParent,
MediaKeys* aKeys,
const nsAString& aKeySystem,
SessionType aSessionType);
SessionType aSessionType,
ErrorResult& aRv);
void Init(const nsAString& aSessionId);
@ -59,11 +60,12 @@ public:
Promise* Closed() const;
already_AddRefed<Promise> Update(const Uint8Array& response);
already_AddRefed<Promise> Update(const Uint8Array& response,
ErrorResult& aRv);
already_AddRefed<Promise> Close();
already_AddRefed<Promise> Close(ErrorResult& aRv);
already_AddRefed<Promise> Remove();
already_AddRefed<Promise> Remove(ErrorResult& aRv);
void DispatchKeyMessage(const nsTArray<uint8_t>& aMessage,
const nsString& aURL);

View File

@ -65,10 +65,13 @@ MediaKeys::GetKeySystem(nsString& retval) const
}
already_AddRefed<Promise>
MediaKeys::SetServerCertificate(const Uint8Array& aCert)
MediaKeys::SetServerCertificate(const Uint8Array& aCert, ErrorResult& aRv)
{
aCert.ComputeLengthAndData();
nsRefPtr<Promise> promise(MakePromise());
nsRefPtr<Promise> promise(MakePromise(aRv));
if (aRv.Failed()) {
return nullptr;
}
mProxy->SetServerCertificate(StorePromise(promise), aCert);
return promise.forget();
}
@ -88,15 +91,15 @@ MediaKeys::IsTypeSupported(const GlobalObject& aGlobal,
}
already_AddRefed<Promise>
MediaKeys::MakePromise()
MediaKeys::MakePromise(ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
if (!global) {
NS_WARNING("Passed non-global to MediaKeys ctor!");
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsRefPtr<Promise> promise = new Promise(global);
return promise.forget();
return Promise::Create(global, aRv);
}
PromiseId
@ -166,9 +169,8 @@ MediaKeys::Create(const GlobalObject& aGlobal,
}
nsRefPtr<MediaKeys> keys = new MediaKeys(window, aKeySystem);
nsRefPtr<Promise> promise(keys->MakePromise());
if (!promise) {
aRv.Throw(NS_ERROR_UNEXPECTED);
nsRefPtr<Promise> promise(keys->MakePromise(aRv));
if (aRv.Failed()) {
return nullptr;
}
@ -196,9 +198,12 @@ MediaKeys::OnCDMCreated(PromiseId aId)
}
already_AddRefed<Promise>
MediaKeys::LoadSession(const nsAString& aSessionId)
MediaKeys::LoadSession(const nsAString& aSessionId, ErrorResult& aRv)
{
nsRefPtr<Promise> promise(MakePromise());
nsRefPtr<Promise> promise(MakePromise(aRv));
if (aRv.Failed()) {
return nullptr;
}
if (aSessionId.IsEmpty()) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
@ -214,7 +219,10 @@ MediaKeys::LoadSession(const nsAString& aSessionId)
// Create session.
nsRefPtr<MediaKeySession> session(
new MediaKeySession(GetParentObject(), this, mKeySystem, SessionType::Persistent));
new MediaKeySession(GetParentObject(), this, mKeySystem, SessionType::Persistent, aRv));
if (aRv.Failed()) {
return nullptr;
}
// Proxy owns session object until resolving promise.
mProxy->LoadSession(StorePromise(promise),
@ -226,14 +234,22 @@ MediaKeys::LoadSession(const nsAString& aSessionId)
already_AddRefed<Promise>
MediaKeys::CreateSession(const nsAString& initDataType,
const Uint8Array& aInitData,
SessionType aSessionType)
SessionType aSessionType,
ErrorResult& aRv)
{
aInitData.ComputeLengthAndData();
nsRefPtr<Promise> promise(MakePromise());
nsRefPtr<Promise> promise(MakePromise(aRv));
if (aRv.Failed()) {
return nullptr;
}
nsRefPtr<MediaKeySession> session = new MediaKeySession(GetParentObject(),
this,
mKeySystem,
aSessionType);
aSessionType, aRv);
if (aRv.Failed()) {
return nullptr;
}
auto pid = StorePromise(promise);
// Hang onto session until the CDM has finished setting it up.
mPendingSessions.Put(pid, session);

View File

@ -54,13 +54,16 @@ public:
// JavaScript: MediaKeys.createSession()
already_AddRefed<Promise> CreateSession(const nsAString& aInitDataType,
const Uint8Array& aInitData,
SessionType aSessionType);
SessionType aSessionType,
ErrorResult& aRv);
// JavaScript: MediaKeys.loadSession()
already_AddRefed<Promise> LoadSession(const nsAString& aSessionId);
already_AddRefed<Promise> LoadSession(const nsAString& aSessionId,
ErrorResult& aRv);
// JavaScript: MediaKeys.SetServerCertificate()
already_AddRefed<Promise> SetServerCertificate(const Uint8Array& aServerCertificate);
already_AddRefed<Promise> SetServerCertificate(const Uint8Array& aServerCertificate,
ErrorResult& aRv);
// JavaScript: MediaKeys.create()
static
@ -87,7 +90,7 @@ public:
CDMProxy* GetCDMProxy() { return mProxy; }
// Makes a new promise, or nullptr on failure.
already_AddRefed<Promise> MakePromise();
already_AddRefed<Promise> MakePromise(ErrorResult& aRv);
// Stores promise in mPromises, returning an ID that can be used to retrieve
// it later. The ID is passed to the CDM, so that it can signal specific
// promises to be resolved.

View File

@ -1493,10 +1493,13 @@ Navigator::GetDataStores(const nsAString& aName, ErrorResult& aRv)
}
already_AddRefed<Promise>
Navigator::GetFeature(const nsAString& aName)
Navigator::GetFeature(const nsAString& aName, ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
nsRefPtr<Promise> p = new Promise(go);
nsRefPtr<Promise> p = Promise::Create(go, aRv);
if (aRv.Failed()) {
return nullptr;
}
#if defined(XP_LINUX)
if (aName.EqualsLiteral("hardware.memory")) {

View File

@ -167,7 +167,8 @@ public:
ErrorResult& aRv);
// Feature Detection API
already_AddRefed<Promise> GetFeature(const nsAString &aName);
already_AddRefed<Promise> GetFeature(const nsAString &aName,
ErrorResult& aRv);
bool Vibrate(uint32_t aDuration);
bool Vibrate(const nsTArray<uint32_t>& aDuration);

View File

@ -35,10 +35,13 @@ SubtleCrypto::WrapObject(JSContext* aCx)
return SubtleCryptoBinding::Wrap(aCx, this);
}
#define SUBTLECRYPTO_METHOD_BODY(Operation, ...) \
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow); \
MOZ_ASSERT(global); \
nsRefPtr<Promise> p = new Promise(global); \
#define SUBTLECRYPTO_METHOD_BODY(Operation, aRv, ...) \
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow); \
MOZ_ASSERT(global); \
nsRefPtr<Promise> p = Promise::Create(global, aRv); \
if (aRv.Failed()) { \
return nullptr; \
} \
nsRefPtr<WebCryptoTask> task = WebCryptoTask::Operation ## Task(__VA_ARGS__); \
task->DispatchWithPromise(p); \
return p.forget();
@ -47,27 +50,30 @@ already_AddRefed<Promise>
SubtleCrypto::Encrypt(JSContext* cx,
const ObjectOrString& algorithm,
CryptoKey& key,
const CryptoOperationData& data)
const CryptoOperationData& data,
ErrorResult& aRv)
{
SUBTLECRYPTO_METHOD_BODY(Encrypt, cx, algorithm, key, data)
SUBTLECRYPTO_METHOD_BODY(Encrypt, aRv, cx, algorithm, key, data)
}
already_AddRefed<Promise>
SubtleCrypto::Decrypt(JSContext* cx,
const ObjectOrString& algorithm,
CryptoKey& key,
const CryptoOperationData& data)
const CryptoOperationData& data,
ErrorResult& aRv)
{
SUBTLECRYPTO_METHOD_BODY(Decrypt, cx, algorithm, key, data)
SUBTLECRYPTO_METHOD_BODY(Decrypt, aRv, cx, algorithm, key, data)
}
already_AddRefed<Promise>
SubtleCrypto::Sign(JSContext* cx,
const ObjectOrString& algorithm,
CryptoKey& key,
const CryptoOperationData& data)
const CryptoOperationData& data,
ErrorResult& aRv)
{
SUBTLECRYPTO_METHOD_BODY(Sign, cx, algorithm, key, data)
SUBTLECRYPTO_METHOD_BODY(Sign, aRv, cx, algorithm, key, data)
}
already_AddRefed<Promise>
@ -75,17 +81,19 @@ SubtleCrypto::Verify(JSContext* cx,
const ObjectOrString& algorithm,
CryptoKey& key,
const CryptoOperationData& signature,
const CryptoOperationData& data)
const CryptoOperationData& data,
ErrorResult& aRv)
{
SUBTLECRYPTO_METHOD_BODY(Verify, cx, algorithm, key, signature, data)
SUBTLECRYPTO_METHOD_BODY(Verify, aRv, cx, algorithm, key, signature, data)
}
already_AddRefed<Promise>
SubtleCrypto::Digest(JSContext* cx,
const ObjectOrString& algorithm,
const CryptoOperationData& data)
const CryptoOperationData& data,
ErrorResult& aRv)
{
SUBTLECRYPTO_METHOD_BODY(Digest, cx, algorithm, data)
SUBTLECRYPTO_METHOD_BODY(Digest, aRv, cx, algorithm, data)
}
@ -95,24 +103,27 @@ SubtleCrypto::ImportKey(JSContext* cx,
const KeyData& keyData,
const ObjectOrString& algorithm,
bool extractable,
const Sequence<nsString>& keyUsages)
const Sequence<nsString>& keyUsages,
ErrorResult& aRv)
{
SUBTLECRYPTO_METHOD_BODY(ImportKey, cx, format, keyData, algorithm,
extractable, keyUsages)
SUBTLECRYPTO_METHOD_BODY(ImportKey, aRv, cx, format, keyData, algorithm,
extractable, keyUsages)
}
already_AddRefed<Promise>
SubtleCrypto::ExportKey(const nsAString& format,
CryptoKey& key)
CryptoKey& key,
ErrorResult& aRv)
{
SUBTLECRYPTO_METHOD_BODY(ExportKey, format, key)
SUBTLECRYPTO_METHOD_BODY(ExportKey, aRv, format, key)
}
already_AddRefed<Promise>
SubtleCrypto::GenerateKey(JSContext* cx, const ObjectOrString& algorithm,
bool extractable, const Sequence<nsString>& keyUsages)
bool extractable, const Sequence<nsString>& keyUsages,
ErrorResult& aRv)
{
SUBTLECRYPTO_METHOD_BODY(GenerateKey, cx, algorithm, extractable, keyUsages)
SUBTLECRYPTO_METHOD_BODY(GenerateKey, aRv, cx, algorithm, extractable, keyUsages)
}
already_AddRefed<Promise>
@ -120,19 +131,21 @@ SubtleCrypto::DeriveKey(JSContext* cx,
const ObjectOrString& algorithm,
CryptoKey& baseKey,
const ObjectOrString& derivedKeyType,
bool extractable, const Sequence<nsString>& keyUsages)
bool extractable, const Sequence<nsString>& keyUsages,
ErrorResult& aRv)
{
SUBTLECRYPTO_METHOD_BODY(DeriveKey, cx, algorithm, baseKey, derivedKeyType,
extractable, keyUsages)
SUBTLECRYPTO_METHOD_BODY(DeriveKey, aRv, cx, algorithm, baseKey,
derivedKeyType, extractable, keyUsages)
}
already_AddRefed<Promise>
SubtleCrypto::DeriveBits(JSContext* cx,
const ObjectOrString& algorithm,
CryptoKey& baseKey,
uint32_t length)
uint32_t length,
ErrorResult& aRv)
{
SUBTLECRYPTO_METHOD_BODY(DeriveBits, cx, algorithm, baseKey, length)
SUBTLECRYPTO_METHOD_BODY(DeriveBits, aRv, cx, algorithm, baseKey, length)
}
} // namespace dom

View File

@ -44,53 +44,63 @@ public:
already_AddRefed<Promise> Encrypt(JSContext* cx,
const ObjectOrString& algorithm,
CryptoKey& key,
const CryptoOperationData& data);
const CryptoOperationData& data,
ErrorResult& aRv);
already_AddRefed<Promise> Decrypt(JSContext* cx,
const ObjectOrString& algorithm,
CryptoKey& key,
const CryptoOperationData& data);
const CryptoOperationData& data,
ErrorResult& aRv);
already_AddRefed<Promise> Sign(JSContext* cx,
const ObjectOrString& algorithm,
CryptoKey& key,
const CryptoOperationData& data);
const CryptoOperationData& data,
ErrorResult& aRv);
already_AddRefed<Promise> Verify(JSContext* cx,
const ObjectOrString& algorithm,
CryptoKey& key,
const CryptoOperationData& signature,
const CryptoOperationData& data);
const CryptoOperationData& data,
ErrorResult& aRv);
already_AddRefed<Promise> Digest(JSContext* cx,
const ObjectOrString& aAlgorithm,
const CryptoOperationData& aData);
const CryptoOperationData& aData,
ErrorResult& aRv);
already_AddRefed<Promise> ImportKey(JSContext* cx,
const nsAString& format,
const KeyData& keyData,
const ObjectOrString& algorithm,
bool extractable,
const Sequence<nsString>& keyUsages);
const Sequence<nsString>& keyUsages,
ErrorResult& aRv);
already_AddRefed<Promise> ExportKey(const nsAString& format, CryptoKey& key);
already_AddRefed<Promise> ExportKey(const nsAString& format, CryptoKey& key,
ErrorResult& aRv);
already_AddRefed<Promise> GenerateKey(JSContext* cx,
const ObjectOrString& algorithm,
bool extractable,
const Sequence<nsString>& keyUsages);
const Sequence<nsString>& keyUsages,
ErrorResult& aRv);
already_AddRefed<Promise> DeriveKey(JSContext* cx,
const ObjectOrString& algorithm,
CryptoKey& baseKey,
const ObjectOrString& derivedKeyType,
bool extractable,
const Sequence<nsString>& keyUsages);
const Sequence<nsString>& keyUsages,
ErrorResult& aRv);
already_AddRefed<Promise> DeriveBits(JSContext* cx,
const ObjectOrString& algorithm,
CryptoKey& baseKey,
uint32_t length);
uint32_t length,
ErrorResult& aRv);
private:
nsCOMPtr<nsPIDOMWindow> mWindow;

View File

@ -420,7 +420,10 @@ BluetoothAdapter::StartDiscovery(ErrorResult& aRv)
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<Promise> promise = new Promise(global);
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
}
/**
* Ensure
@ -518,7 +521,10 @@ BluetoothAdapter::SetName(const nsAString& aName, ErrorResult& aRv)
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<Promise> promise = new Promise(global);
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
}
/**
* Ensure
@ -556,7 +562,10 @@ BluetoothAdapter::SetDiscoverable(bool aDiscoverable, ErrorResult& aRv)
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<Promise> promise = new Promise(global);
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
}
/**
* Ensure
@ -784,7 +793,10 @@ BluetoothAdapter::EnableDisable(bool aEnable, ErrorResult& aRv)
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<Promise> promise = new Promise(global);
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
}
// Ensure BluetoothService is available before modifying adapter state
BluetoothService* bs = BluetoothService::Get();

View File

@ -143,7 +143,10 @@ BluetoothDevice::FetchUuids(ErrorResult& aRv)
return nullptr;
}
nsRefPtr<Promise> promise = new Promise(global);
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
}
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, NS_ERROR_NOT_AVAILABLE);

View File

@ -884,7 +884,11 @@ DataStoreService::GetDataStores(nsIDOMWindow* aWindow,
}
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
nsRefPtr<Promise> promise = new Promise(global);
ErrorResult rv;
nsRefPtr<Promise> promise = Promise::Create(global, rv);
if (rv.Failed()) {
return rv.ErrorCode();
}
nsCOMPtr<nsIDocument> document = window->GetDoc();
MOZ_ASSERT(document);

View File

@ -284,7 +284,7 @@ public:
// Uses XPCOM GetStorageName
already_AddRefed<Promise>
GetRoot();
GetRoot(ErrorResult& aRv);
static void
CreateDeviceStorageFor(nsPIDOMWindow* aWin,

View File

@ -4121,13 +4121,13 @@ nsDOMDeviceStorage::CanBeShared()
}
already_AddRefed<Promise>
nsDOMDeviceStorage::GetRoot()
nsDOMDeviceStorage::GetRoot(ErrorResult& aRv)
{
if (!mFileSystem) {
mFileSystem = new DeviceStorageFileSystem(mStorageType, mStorageName);
mFileSystem->Init(this);
}
return mozilla::dom::Directory::GetRoot(mFileSystem);
return mozilla::dom::Directory::GetRoot(mFileSystem, aRv);
}
NS_IMETHODIMP

View File

@ -18,7 +18,8 @@ namespace mozilla {
namespace dom {
CreateDirectoryTask::CreateDirectoryTask(FileSystemBase* aFileSystem,
const nsAString& aPath)
const nsAString& aPath,
ErrorResult& aRv)
: FileSystemTaskBase(aFileSystem)
, mTargetRealPath(aPath)
{
@ -29,7 +30,7 @@ CreateDirectoryTask::CreateDirectoryTask(FileSystemBase* aFileSystem,
if (!globalObject) {
return;
}
mPromise = new Promise(globalObject);
mPromise = Promise::Create(globalObject, aRv);
}
CreateDirectoryTask::CreateDirectoryTask(

View File

@ -9,6 +9,7 @@
#include "mozilla/dom/FileSystemTaskBase.h"
#include "nsAutoPtr.h"
#include "mozilla/ErrorResult.h"
namespace mozilla {
namespace dom {
@ -20,7 +21,8 @@ class CreateDirectoryTask MOZ_FINAL
{
public:
CreateDirectoryTask(FileSystemBase* aFileSystem,
const nsAString& aPath);
const nsAString& aPath,
ErrorResult& aRv);
CreateDirectoryTask(FileSystemBase* aFileSystem,
const FileSystemCreateDirectoryParams& aParam,
FileSystemRequestParent* aParent);

View File

@ -27,7 +27,8 @@ CreateFileTask::CreateFileTask(FileSystemBase* aFileSystem,
const nsAString& aPath,
nsIDOMBlob* aBlobData,
InfallibleTArray<uint8_t>& aArrayData,
bool replace)
bool replace,
ErrorResult& aRv)
: FileSystemTaskBase(aFileSystem)
, mTargetRealPath(aPath)
, mBlobData(aBlobData)
@ -46,7 +47,7 @@ CreateFileTask::CreateFileTask(FileSystemBase* aFileSystem,
if (!globalObject) {
return;
}
mPromise = new Promise(globalObject);
mPromise = Promise::Create(globalObject, aRv);
}
CreateFileTask::CreateFileTask(FileSystemBase* aFileSystem,

View File

@ -9,6 +9,7 @@
#include "mozilla/dom/FileSystemTaskBase.h"
#include "nsAutoPtr.h"
#include "mozilla/ErrorResult.h"
class nsIDOMBlob;
class nsIInputStream;
@ -27,7 +28,8 @@ public:
const nsAString& aPath,
nsIDOMBlob* aBlobData,
InfallibleTArray<uint8_t>& aArrayData,
bool replace);
bool replace,
ErrorResult& aRv);
CreateFileTask(FileSystemBase* aFileSystem,
const FileSystemCreateFileParams& aParam,
FileSystemRequestParent* aParent);

View File

@ -44,10 +44,13 @@ NS_INTERFACE_MAP_END
// static
already_AddRefed<Promise>
Directory::GetRoot(FileSystemBase* aFileSystem)
Directory::GetRoot(FileSystemBase* aFileSystem, ErrorResult& aRv)
{
nsRefPtr<GetFileOrDirectoryTask> task = new GetFileOrDirectoryTask(
aFileSystem, EmptyString(), true);
aFileSystem, EmptyString(), true, aRv);
if (aRv.Failed()) {
return nullptr;
}
FileSystemPermissionRequest::RequestForTask(task);
return task->GetPromise();
}
@ -95,7 +98,8 @@ Directory::GetName(nsString& aRetval) const
}
already_AddRefed<Promise>
Directory::CreateFile(const nsAString& aPath, const CreateFileOptions& aOptions)
Directory::CreateFile(const nsAString& aPath, const CreateFileOptions& aOptions,
ErrorResult& aRv)
{
nsresult error = NS_OK;
nsString realPath;
@ -128,14 +132,17 @@ Directory::CreateFile(const nsAString& aPath, const CreateFileOptions& aOptions)
}
nsRefPtr<CreateFileTask> task = new CreateFileTask(mFileSystem, realPath,
blobData, arrayData, replace);
blobData, arrayData, replace, aRv);
if (aRv.Failed()) {
return nullptr;
}
task->SetError(error);
FileSystemPermissionRequest::RequestForTask(task);
return task->GetPromise();
}
already_AddRefed<Promise>
Directory::CreateDirectory(const nsAString& aPath)
Directory::CreateDirectory(const nsAString& aPath, ErrorResult& aRv)
{
nsresult error = NS_OK;
nsString realPath;
@ -143,14 +150,17 @@ Directory::CreateDirectory(const nsAString& aPath)
error = NS_ERROR_DOM_FILESYSTEM_INVALID_PATH_ERR;
}
nsRefPtr<CreateDirectoryTask> task = new CreateDirectoryTask(
mFileSystem, realPath);
mFileSystem, realPath, aRv);
if (aRv.Failed()) {
return nullptr;
}
task->SetError(error);
FileSystemPermissionRequest::RequestForTask(task);
return task->GetPromise();
}
already_AddRefed<Promise>
Directory::Get(const nsAString& aPath)
Directory::Get(const nsAString& aPath, ErrorResult& aRv)
{
nsresult error = NS_OK;
nsString realPath;
@ -158,26 +168,30 @@ Directory::Get(const nsAString& aPath)
error = NS_ERROR_DOM_FILESYSTEM_INVALID_PATH_ERR;
}
nsRefPtr<GetFileOrDirectoryTask> task = new GetFileOrDirectoryTask(
mFileSystem, realPath, false);
mFileSystem, realPath, false, aRv);
if (aRv.Failed()) {
return nullptr;
}
task->SetError(error);
FileSystemPermissionRequest::RequestForTask(task);
return task->GetPromise();
}
already_AddRefed<Promise>
Directory::Remove(const StringOrFileOrDirectory& aPath)
Directory::Remove(const StringOrFileOrDirectory& aPath, ErrorResult& aRv)
{
return RemoveInternal(aPath, false);
return RemoveInternal(aPath, false, aRv);
}
already_AddRefed<Promise>
Directory::RemoveDeep(const StringOrFileOrDirectory& aPath)
Directory::RemoveDeep(const StringOrFileOrDirectory& aPath, ErrorResult& aRv)
{
return RemoveInternal(aPath, true);
return RemoveInternal(aPath, true, aRv);
}
already_AddRefed<Promise>
Directory::RemoveInternal(const StringOrFileOrDirectory& aPath, bool aRecursive)
Directory::RemoveInternal(const StringOrFileOrDirectory& aPath, bool aRecursive,
ErrorResult& aRv)
{
nsresult error = NS_OK;
nsString realPath;
@ -211,7 +225,10 @@ Directory::RemoveInternal(const StringOrFileOrDirectory& aPath, bool aRecursive)
parameters_check_done:
nsRefPtr<RemoveTask> task = new RemoveTask(mFileSystem, mPath, file, realPath,
aRecursive);
aRecursive, aRv);
if (aRv.Failed()) {
return nullptr;
}
task->SetError(error);
FileSystemPermissionRequest::RequestForTask(task);
return task->GetPromise();

View File

@ -8,6 +8,7 @@
#define mozilla_dom_Directory_h
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
@ -45,7 +46,7 @@ public:
public:
static already_AddRefed<Promise>
GetRoot(FileSystemBase* aFileSystem);
GetRoot(FileSystemBase* aFileSystem, ErrorResult& aRv);
Directory(FileSystemBase* aFileSystem, const nsAString& aPath);
@ -61,19 +62,20 @@ public:
GetName(nsString& aRetval) const;
already_AddRefed<Promise>
CreateFile(const nsAString& aPath, const CreateFileOptions& aOptions);
CreateFile(const nsAString& aPath, const CreateFileOptions& aOptions,
ErrorResult& aRv);
already_AddRefed<Promise>
CreateDirectory(const nsAString& aPath);
CreateDirectory(const nsAString& aPath, ErrorResult& aRv);
already_AddRefed<Promise>
Get(const nsAString& aPath);
Get(const nsAString& aPath, ErrorResult& aRv);
already_AddRefed<Promise>
Remove(const StringOrFileOrDirectory& aPath);
Remove(const StringOrFileOrDirectory& aPath, ErrorResult& aRv);
already_AddRefed<Promise>
RemoveDeep(const StringOrFileOrDirectory& aPath);
RemoveDeep(const StringOrFileOrDirectory& aPath, ErrorResult& aRv);
// =========== End WebIDL bindings.============
@ -93,7 +95,8 @@ private:
DOMPathToRealPath(const nsAString& aPath, nsAString& aRealPath) const;
already_AddRefed<Promise>
RemoveInternal(const StringOrFileOrDirectory& aPath, bool aRecursive);
RemoveInternal(const StringOrFileOrDirectory& aPath, bool aRecursive,
ErrorResult& aRv);
nsRefPtr<FileSystemBase> mFileSystem;
nsString mPath;

View File

@ -21,7 +21,8 @@ namespace dom {
GetFileOrDirectoryTask::GetFileOrDirectoryTask(
FileSystemBase* aFileSystem,
const nsAString& aTargetPath,
bool aDirectoryOnly)
bool aDirectoryOnly,
ErrorResult& aRv)
: FileSystemTaskBase(aFileSystem)
, mTargetRealPath(aTargetPath)
, mIsDirectory(aDirectoryOnly)
@ -33,7 +34,7 @@ GetFileOrDirectoryTask::GetFileOrDirectoryTask(
if (!globalObject) {
return;
}
mPromise = new Promise(globalObject);
mPromise = Promise::Create(globalObject, aRv);
}
GetFileOrDirectoryTask::GetFileOrDirectoryTask(

View File

@ -9,6 +9,7 @@
#include "mozilla/dom/FileSystemTaskBase.h"
#include "nsAutoPtr.h"
#include "mozilla/ErrorResult.h"
namespace mozilla {
namespace dom {
@ -22,7 +23,8 @@ public:
// If aDirectoryOnly is set, we should ensure that the target is a directory.
GetFileOrDirectoryTask(FileSystemBase* aFileSystem,
const nsAString& aTargetPath,
bool aDirectoryOnly);
bool aDirectoryOnly,
ErrorResult& aRv);
GetFileOrDirectoryTask(FileSystemBase* aFileSystem,
const FileSystemGetFileOrDirectoryParams& aParam,
FileSystemRequestParent* aParent);

View File

@ -21,7 +21,8 @@ RemoveTask::RemoveTask(FileSystemBase* aFileSystem,
const nsAString& aDirPath,
nsIDOMFile* aTargetFile,
const nsAString& aTargetPath,
bool aRecursive)
bool aRecursive,
ErrorResult& aRv)
: FileSystemTaskBase(aFileSystem)
, mDirRealPath(aDirPath)
, mTargetFile(aTargetFile)
@ -36,7 +37,7 @@ RemoveTask::RemoveTask(FileSystemBase* aFileSystem,
if (!globalObject) {
return;
}
mPromise = new Promise(globalObject);
mPromise = Promise::Create(globalObject, aRv);
}
RemoveTask::RemoveTask(FileSystemBase* aFileSystem,

View File

@ -9,6 +9,7 @@
#include "mozilla/dom/FileSystemTaskBase.h"
#include "nsAutoPtr.h"
#include "mozilla/ErrorResult.h"
namespace mozilla {
namespace dom {
@ -23,7 +24,8 @@ public:
const nsAString& aDirPath,
nsIDOMFile* aTargetFile,
const nsAString& aTargetPath,
bool aRecursive);
bool aRecursive,
ErrorResult& aRv);
RemoveTask(FileSystemBase* aFileSystem,
const FileSystemRemoveParams& aParam,
FileSystemRequestParent* aParent);

View File

@ -7,9 +7,11 @@
#include "mozilla/dom/Promise.h"
#include "jsfriendapi.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/DOMError.h"
#include "mozilla/dom/OwningNonNull.h"
#include "mozilla/dom/PromiseBinding.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/Preferences.h"
#include "PromiseCallback.h"
@ -261,7 +263,8 @@ protected:
{
NS_ASSERT_OWNINGTHREAD(ThenableResolverMixin);
ThreadsafeAutoJSContext cx;
JS::Rooted<JSObject*> wrapper(cx, mPromise->GetOrCreateWrapper(cx));
JS::Rooted<JSObject*> wrapper(cx, mPromise->GetWrapper());
MOZ_ASSERT(wrapper); // It was preserved!
if (!wrapper) {
return;
}
@ -434,31 +437,29 @@ Promise::WrapObject(JSContext* aCx)
return PromiseBinding::Wrap(aCx, this);
}
JSObject*
Promise::GetOrCreateWrapper(JSContext* aCx)
already_AddRefed<Promise>
Promise::Create(nsIGlobalObject* aGlobal, ErrorResult& aRv)
{
if (JSObject* wrapper = GetWrapper()) {
return wrapper;
AutoJSAPI jsapi;
if (!jsapi.Init(aGlobal)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
JSContext* cx = jsapi.cx();
nsIGlobalObject* global = GetParentObject();
MOZ_ASSERT(global);
nsRefPtr<Promise> p = new Promise(aGlobal);
JS::Rooted<JSObject*> scope(aCx, global->GetGlobalJSObject());
if (!scope) {
JS_ReportError(aCx, "can't get scope");
JS::Rooted<JS::Value> ignored(cx);
if (!WrapNewBindingObject(cx, p, &ignored)) {
JS_ClearPendingException(cx);
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
JSAutoCompartment ac(aCx, scope);
// Need the .get() bit here to get template deduction working right
dom::PreserveWrapper(p.get());
JS::Rooted<JS::Value> val(aCx);
if (!WrapNewBindingObject(aCx, this, &val)) {
MOZ_ASSERT(JS_IsExceptionPending(aCx));
return nullptr;
}
return GetWrapper();
return p.forget();
}
void
@ -606,7 +607,10 @@ Promise::Constructor(const GlobalObject& aGlobal,
return nullptr;
}
nsRefPtr<Promise> promise = new Promise(global);
nsRefPtr<Promise> promise = Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
}
JS::Rooted<JSObject*> resolveFunc(cx,
CreateFunction(cx, aGlobal.Get(), promise,
@ -674,7 +678,10 @@ Promise::Resolve(const GlobalObject& aGlobal,
Promise::Resolve(nsIGlobalObject* aGlobal, JSContext* aCx,
JS::Handle<JS::Value> aValue, ErrorResult& aRv)
{
nsRefPtr<Promise> promise = new Promise(aGlobal);
nsRefPtr<Promise> promise = Create(aGlobal, aRv);
if (aRv.Failed()) {
return nullptr;
}
promise->MaybeResolveInternal(aCx, aValue);
return promise.forget();
@ -698,7 +705,10 @@ Promise::Reject(const GlobalObject& aGlobal,
Promise::Reject(nsIGlobalObject* aGlobal, JSContext* aCx,
JS::Handle<JS::Value> aValue, ErrorResult& aRv)
{
nsRefPtr<Promise> promise = new Promise(aGlobal);
nsRefPtr<Promise> promise = Create(aGlobal, aRv);
if (aRv.Failed()) {
return nullptr;
}
promise->MaybeRejectInternal(aCx, aValue);
return promise.forget();
@ -706,9 +716,12 @@ Promise::Reject(nsIGlobalObject* aGlobal, JSContext* aCx,
already_AddRefed<Promise>
Promise::Then(JSContext* aCx, AnyCallback* aResolveCallback,
AnyCallback* aRejectCallback)
AnyCallback* aRejectCallback, ErrorResult& aRv)
{
nsRefPtr<Promise> promise = new Promise(GetParentObject());
nsRefPtr<Promise> promise = Create(GetParentObject(), aRv);
if (aRv.Failed()) {
return nullptr;
}
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
@ -726,10 +739,10 @@ Promise::Then(JSContext* aCx, AnyCallback* aResolveCallback,
}
already_AddRefed<Promise>
Promise::Catch(JSContext* aCx, AnyCallback* aRejectCallback)
Promise::Catch(JSContext* aCx, AnyCallback* aRejectCallback, ErrorResult& aRv)
{
nsRefPtr<AnyCallback> resolveCb;
return Then(aCx, resolveCb, aRejectCallback);
return Then(aCx, resolveCb, aRejectCallback, aRv);
}
/**
@ -892,7 +905,10 @@ Promise::All(const GlobalObject& aGlobal,
return Promise::Resolve(aGlobal, value, aRv);
}
nsRefPtr<Promise> promise = new Promise(global);
nsRefPtr<Promise> promise = Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
}
nsRefPtr<CountdownHolder> holder =
new CountdownHolder(aGlobal, promise, aIterable.Length());
@ -942,7 +958,10 @@ Promise::Race(const GlobalObject& aGlobal,
return nullptr;
}
nsRefPtr<Promise> promise = new Promise(global);
nsRefPtr<Promise> promise = Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
}
nsRefPtr<PromiseCallback> resolveCb =
new ResolvePromiseCallback(promise, obj);
@ -1021,10 +1040,8 @@ Promise::RunTask()
ThreadsafeAutoJSContext cx;
JS::Rooted<JS::Value> value(cx, mResult);
JS::Rooted<JSObject*> wrapper(cx, GetOrCreateWrapper(cx));
if (!wrapper) {
return;
}
JS::Rooted<JSObject*> wrapper(cx, GetWrapper());
MOZ_ASSERT(wrapper); // We preserved it
JSAutoCompartment ac(cx, wrapper);
if (!MaybeWrapValue(cx, &value)) {

View File

@ -72,7 +72,12 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Promise)
Promise(nsIGlobalObject* aGlobal);
// Promise creation tries to create a JS reflector for the Promise, so is
// fallible. Furthermore, we don't want to do JS-wrapping on a 0-refcount
// object, so we addref before doing that and return the addrefed pointer
// here.
static already_AddRefed<Promise>
Create(nsIGlobalObject* aGlobal, ErrorResult& aRv);
typedef void (Promise::*MaybeFunc)(JSContext* aCx,
JS::Handle<JS::Value> aValue);
@ -139,10 +144,10 @@ public:
already_AddRefed<Promise>
Then(JSContext* aCx, AnyCallback* aResolveCallback,
AnyCallback* aRejectCallback);
AnyCallback* aRejectCallback, ErrorResult& aRv);
already_AddRefed<Promise>
Catch(JSContext* aCx, AnyCallback* aRejectCallback);
Catch(JSContext* aCx, AnyCallback* aRejectCallback, ErrorResult& aRv);
static already_AddRefed<Promise>
All(const GlobalObject& aGlobal,
@ -155,6 +160,10 @@ public:
void AppendNativeHandler(PromiseNativeHandler* aRunnable);
private:
// Do NOT call this unless you're Promise::Create. I wish we could enforce
// that from inside this class too, somehow.
Promise(nsIGlobalObject* aGlobal);
friend class PromiseDebugging;
enum PromiseState {
@ -219,18 +228,11 @@ private:
JS::Handle<JS::Value> aValue,
PromiseTaskSync aSync = AsyncTask);
// Helper methods for using Promises from C++
JSObject* GetOrCreateWrapper(JSContext* aCx);
template <typename T>
void MaybeSomething(T& aArgument, MaybeFunc aFunc) {
ThreadsafeAutoJSContext cx;
JSObject* wrapper = GetOrCreateWrapper(cx);
if (!wrapper) {
HandleException(cx);
return;
}
JSObject* wrapper = GetWrapper();
MOZ_ASSERT(wrapper); // We preserved it!
JSAutoCompartment ac(cx, wrapper);
JS::Rooted<JS::Value> val(cx);

View File

@ -26,7 +26,10 @@ class WorkerPrivate;
// 1. Create a Promise on the worker thread and return it to the content
// script:
//
// nsRefPtr<Promise> promise = new Promise(workerPrivate->GlobalScope());
// nsRefPtr<Promise> promise = Promise::Create(workerPrivate->GlobalScope(), aRv);
// if (aRv.Failed()) {
// return nullptr;
// }
// // Pass |promise| around to the WorkerMainThreadRunnable
// return promise.forget();
//

View File

@ -744,7 +744,10 @@ Notification::Get(const GlobalObject& aGlobal,
return nullptr;
}
nsRefPtr<Promise> promise = new Promise(global);
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
}
nsCOMPtr<nsINotificationStorageCallback> callback =
new NotificationStorageCallback(aGlobal, window, promise);
nsString tag = aFilter.mTag.WasPassed() ?

View File

@ -242,14 +242,17 @@ Telephony::HasDialingCall()
already_AddRefed<Promise>
Telephony::DialInternal(uint32_t aServiceId, const nsAString& aNumber,
bool aEmergency)
bool aEmergency, ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
if (!global) {
return nullptr;
}
nsRefPtr<Promise> promise = new Promise(global);
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
}
if (!IsValidNumber(aNumber) || !IsValidServiceId(aServiceId)) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
@ -371,19 +374,21 @@ NS_IMPL_ISUPPORTS(Telephony::Callback, nsITelephonyCallback)
// Telephony WebIDL
already_AddRefed<Promise>
Telephony::Dial(const nsAString& aNumber, const Optional<uint32_t>& aServiceId)
Telephony::Dial(const nsAString& aNumber, const Optional<uint32_t>& aServiceId,
ErrorResult& aRv)
{
uint32_t serviceId = ProvidedOrDefaultServiceId(aServiceId);
nsRefPtr<Promise> promise = DialInternal(serviceId, aNumber, false);
nsRefPtr<Promise> promise = DialInternal(serviceId, aNumber, false, aRv);
return promise.forget();
}
already_AddRefed<Promise>
Telephony::DialEmergency(const nsAString& aNumber,
const Optional<uint32_t>& aServiceId)
const Optional<uint32_t>& aServiceId,
ErrorResult& aRv)
{
uint32_t serviceId = ProvidedOrDefaultServiceId(aServiceId);
nsRefPtr<Promise> promise = DialInternal(serviceId, aNumber, true);
nsRefPtr<Promise> promise = DialInternal(serviceId, aNumber, true, aRv);
return promise.forget();
}

View File

@ -70,10 +70,12 @@ public:
// WebIDL
already_AddRefed<Promise>
Dial(const nsAString& aNumber, const Optional<uint32_t>& aServiceId);
Dial(const nsAString& aNumber, const Optional<uint32_t>& aServiceId,
ErrorResult& aRv);
already_AddRefed<Promise>
DialEmergency(const nsAString& aNumber, const Optional<uint32_t>& aServiceId);
DialEmergency(const nsAString& aNumber, const Optional<uint32_t>& aServiceId,
ErrorResult& aRv);
void
StartTone(const nsAString& aDTMFChar, const Optional<uint32_t>& aServiceId,
@ -167,7 +169,8 @@ private:
HasDialingCall();
already_AddRefed<Promise>
DialInternal(uint32_t aServiceId, const nsAString& aNumber, bool aEmergency);
DialInternal(uint32_t aServiceId, const nsAString& aNumber, bool aEmergency,
ErrorResult& aRv);
already_AddRefed<TelephonyCallId>
CreateCallId(const nsAString& aNumber,

View File

@ -82,6 +82,6 @@ interface DeviceStorage : EventTarget {
// for storing new files.
readonly attribute boolean default;
[NewObject]
[NewObject, Throws]
Promise getRoot();
};

View File

@ -37,7 +37,7 @@ interface Directory {
* @return If succeeds, the promise is resolved with the new created
* File object. Otherwise, rejected with a DOM error.
*/
[NewObject]
[NewObject, Throws]
// Promise<File>
Promise createFile(DOMString path, optional CreateFileOptions options);
@ -50,7 +50,7 @@ interface Directory {
* @return If succeeds, the promise is resolved with the new created
* Directory object. Otherwise, rejected with a DOM error.
*/
[NewObject]
[NewObject, Throws]
// Promise<Directory>
Promise createDirectory(DOMString path);
@ -62,7 +62,7 @@ interface Directory {
* with a File or Directory object, depending on the entry's type. Otherwise,
* rejected with a DOM error.
*/
[NewObject]
[NewObject, Throws]
// Promise<(File or Directory)>
Promise get(DOMString path);
@ -77,7 +77,7 @@ interface Directory {
* exist, the promise is resolved with boolean false. If the target did exist
* and was successfully deleted, the promise is resolved with boolean true.
*/
[NewObject]
[NewObject, Throws]
// Promise<boolean>
Promise remove((DOMString or File or Directory) path);
@ -92,7 +92,7 @@ interface Directory {
* resolved with boolean false. If the target did exist and was successfully
* deleted, the promise is resolved with boolean true.
*/
[NewObject]
[NewObject, Throws]
// Promise<boolean>
Promise removeDeep((DOMString or File or Directory) path);
};

View File

@ -30,14 +30,14 @@ interface MediaKeySession : EventTarget {
// session operations
//Promise<any>
[NewObject]
[NewObject, Throws]
Promise update(Uint8Array response);
// Promise<any>
[NewObject]
[NewObject, Throws]
Promise close();
// Promise<any>
[NewObject]
[NewObject, Throws]
Promise remove();
};

View File

@ -18,15 +18,15 @@ interface MediaKeys {
readonly attribute DOMString keySystem;
// Promise<MediaKeySession>
[NewObject]
[NewObject, Throws]
Promise createSession(DOMString initDataType, Uint8Array initData, optional SessionType sessionType = "temporary");
// Promise<MediaKeySession>
[NewObject]
[NewObject, Throws]
Promise loadSession(DOMString sessionId);
// Promise<any>
[NewObject]
[NewObject, Throws]
Promise setServerCertificate(Uint8Array serverCertificate);
// Promise<MediaKeys>

View File

@ -83,7 +83,7 @@ interface NavigatorStorageUtils {
[NoInterfaceObject]
interface NavigatorFeatures {
[CheckPermissions="feature-detection"]
[CheckPermissions="feature-detection", Throws]
Promise getFeature(DOMString name);
};

View File

@ -32,11 +32,11 @@ interface Promise {
// The [TreatNonCallableAsNull] annotation is required since then() should do
// nothing instead of throwing errors when non-callable arguments are passed.
[NewObject]
[NewObject, Throws]
Promise then([TreatNonCallableAsNull] optional AnyCallback? fulfillCallback = null,
[TreatNonCallableAsNull] optional AnyCallback? rejectCallback = null);
[NewObject]
[NewObject, Throws]
Promise catch([TreatNonCallableAsNull] optional AnyCallback? rejectCallback = null);
[NewObject, Throws]

View File

@ -19,6 +19,7 @@ interface ServiceWorkerContainer {
[Unforgeable] readonly attribute ServiceWorker? controller;
// Promise<ServiceWorker>
[Throws]
readonly attribute Promise ready;
// Promise<sequence<ServiceWorker>?>

View File

@ -132,39 +132,49 @@ typedef (object or DOMString) AlgorithmIdentifier;
[Pref="dom.webcrypto.enabled"]
interface SubtleCrypto {
[Throws]
Promise encrypt(AlgorithmIdentifier algorithm,
CryptoKey key,
CryptoOperationData data);
[Throws]
Promise decrypt(AlgorithmIdentifier algorithm,
CryptoKey key,
CryptoOperationData data);
[Throws]
Promise sign(AlgorithmIdentifier algorithm,
CryptoKey key,
CryptoOperationData data);
[Throws]
Promise verify(AlgorithmIdentifier algorithm,
CryptoKey key,
CryptoOperationData signature,
CryptoOperationData data);
[Throws]
Promise digest(AlgorithmIdentifier algorithm,
CryptoOperationData data);
[Throws]
Promise generateKey(AlgorithmIdentifier algorithm,
boolean extractable,
sequence<KeyUsage> keyUsages );
[Throws]
Promise deriveKey(AlgorithmIdentifier algorithm,
CryptoKey baseKey,
AlgorithmIdentifier derivedKeyType,
boolean extractable,
sequence<KeyUsage> keyUsages );
[Throws]
Promise deriveBits(AlgorithmIdentifier algorithm,
CryptoKey baseKey,
unsigned long length);
[Throws]
Promise importKey(KeyFormat format,
KeyData keyData,
AlgorithmIdentifier algorithm,
boolean extractable,
sequence<KeyUsage> keyUsages );
[Throws]
Promise exportKey(KeyFormat format, CryptoKey key);
};

View File

@ -17,9 +17,11 @@ interface Telephony : EventTarget {
*/
// Promise<TelephonyCall>
[Throws]
Promise dial(DOMString number, optional unsigned long serviceId);
// Promise<TelephonyCall>
[Throws]
Promise dialEmergency(DOMString number, optional unsigned long serviceId);
[Throws]

View File

@ -479,7 +479,10 @@ WorkerDataStore::Get(JSContext* aCx,
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
nsRefPtr<Promise> promise = new Promise(workerPrivate->GlobalScope());
nsRefPtr<Promise> promise = Promise::Create(workerPrivate->GlobalScope(), aRv);
if (aRv.Failed()) {
return nullptr;
}
nsRefPtr<DataStoreGetRunnable> runnable =
new DataStoreGetRunnable(workerPrivate,
@ -503,7 +506,10 @@ WorkerDataStore::Put(JSContext* aCx,
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
nsRefPtr<Promise> promise = new Promise(workerPrivate->GlobalScope());
nsRefPtr<Promise> promise = Promise::Create(workerPrivate->GlobalScope(), aRv);
if (aRv.Failed()) {
return nullptr;
}
nsRefPtr<DataStorePutRunnable> runnable =
new DataStorePutRunnable(workerPrivate,
@ -530,7 +536,10 @@ WorkerDataStore::Add(JSContext* aCx,
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
nsRefPtr<Promise> promise = new Promise(workerPrivate->GlobalScope());
nsRefPtr<Promise> promise = Promise::Create(workerPrivate->GlobalScope(), aRv);
if (aRv.Failed()) {
return nullptr;
}
nsRefPtr<DataStoreAddRunnable> runnable =
new DataStoreAddRunnable(workerPrivate,
@ -556,7 +565,10 @@ WorkerDataStore::Remove(JSContext* aCx,
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
nsRefPtr<Promise> promise = new Promise(workerPrivate->GlobalScope());
nsRefPtr<Promise> promise = Promise::Create(workerPrivate->GlobalScope(), aRv);
if (aRv.Failed()) {
return nullptr;
}
nsRefPtr<DataStoreRemoveRunnable> runnable =
new DataStoreRemoveRunnable(workerPrivate,
@ -579,7 +591,10 @@ WorkerDataStore::Clear(JSContext* aCx,
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
nsRefPtr<Promise> promise = new Promise(workerPrivate->GlobalScope());
nsRefPtr<Promise> promise = Promise::Create(workerPrivate->GlobalScope(), aRv);
if (aRv.Failed()) {
return nullptr;
}
nsRefPtr<DataStoreClearRunnable> runnable =
new DataStoreClearRunnable(workerPrivate,
@ -650,7 +665,10 @@ WorkerDataStore::GetLength(JSContext* aCx, ErrorResult& aRv)
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
nsRefPtr<Promise> promise = new Promise(workerPrivate->GlobalScope());
nsRefPtr<Promise> promise = Promise::Create(workerPrivate->GlobalScope(), aRv);
if (aRv.Failed()) {
return nullptr;
}
nsRefPtr<DataStoreGetLengthRunnable> runnable =
new DataStoreGetLengthRunnable(workerPrivate,

View File

@ -147,7 +147,10 @@ WorkerDataStoreCursor::Next(JSContext* aCx, ErrorResult& aRv)
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
nsRefPtr<Promise> promise = new Promise(workerPrivate->GlobalScope());
nsRefPtr<Promise> promise = Promise::Create(workerPrivate->GlobalScope(), aRv);
if (aRv.Failed()) {
return nullptr;
}
nsRefPtr<DataStoreCursorNextRunnable> runnable =
new DataStoreCursorNextRunnable(workerPrivate,

View File

@ -261,7 +261,10 @@ WorkerNavigator::GetDataStores(JSContext* aCx,
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
nsRefPtr<Promise> promise = new Promise(workerPrivate->GlobalScope());
nsRefPtr<Promise> promise = Promise::Create(workerPrivate->GlobalScope(), aRv);
if (aRv.Failed()) {
return nullptr;
}
nsRefPtr<NavigatorGetDataStoresRunnable> runnable =
new NavigatorGetDataStoresRunnable(workerPrivate, promise, aName, aRv);

View File

@ -119,12 +119,11 @@ ServiceWorkerContainer::GetAll(ErrorResult& aRv)
}
already_AddRefed<Promise>
ServiceWorkerContainer::Ready()
ServiceWorkerContainer::GetReady(ErrorResult& aRv)
{
// FIXME(nsm): Bug 1025077
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow);
nsRefPtr<Promise> promise = new Promise(global);
return promise.forget();
return Promise::Create(global, aRv);
}
// XXXnsm, maybe this can be optimized to only add when a event handler is

View File

@ -73,7 +73,7 @@ public:
GetAll(ErrorResult& aRv);
already_AddRefed<Promise>
Ready();
GetReady(ErrorResult& aRv);
nsIURI*
GetDocumentURI() const

View File

@ -455,7 +455,11 @@ ServiceWorkerManager::Register(nsIDOMWindow* aWindow, const nsAString& aScope,
}
nsCOMPtr<nsIGlobalObject> sgo = do_QueryInterface(window);
nsRefPtr<Promise> promise = new Promise(sgo);
ErrorResult result;
nsRefPtr<Promise> promise = Promise::Create(sgo, result);
if (result.Failed()) {
return result.ErrorCode();
}
nsCOMPtr<nsIURI> documentURI = window->GetDocumentURI();
if (!documentURI) {