mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1035060 - Implement AbortablePromise. r=bz
This commit is contained in:
parent
6a9b2b1e98
commit
fcfee0071f
@ -91,6 +91,10 @@ DOMInterfaces = {
|
||||
'nativeType': 'mozilla::dom::Activity',
|
||||
},
|
||||
|
||||
'MozAbortablePromise': {
|
||||
'nativeType': 'mozilla::dom::AbortablePromise',
|
||||
},
|
||||
|
||||
'AbstractWorker': {
|
||||
'concrete': False
|
||||
},
|
||||
|
118
dom/promise/AbortablePromise.cpp
Normal file
118
dom/promise/AbortablePromise.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* vim: set ts=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/. */
|
||||
|
||||
#include "mozilla/dom/AbortablePromise.h"
|
||||
|
||||
#include "mozilla/dom/AbortablePromiseBinding.h"
|
||||
#include "mozilla/dom/PromiseNativeAbortCallback.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "PromiseCallback.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(PromiseNativeAbortCallback)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(PromiseNativeAbortCallback)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PromiseNativeAbortCallback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
NS_IMPL_CYCLE_COLLECTION_0(PromiseNativeAbortCallback)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(AbortablePromise, Promise)
|
||||
NS_IMPL_RELEASE_INHERITED(AbortablePromise, Promise)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(AbortablePromise)
|
||||
NS_INTERFACE_MAP_END_INHERITING(Promise)
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(AbortablePromise, Promise, mAbortCallback)
|
||||
|
||||
AbortablePromise::AbortablePromise(nsIGlobalObject* aGlobal,
|
||||
PromiseNativeAbortCallback& aAbortCallback)
|
||||
: Promise(aGlobal)
|
||||
, mAbortCallback(&aAbortCallback)
|
||||
{
|
||||
}
|
||||
|
||||
AbortablePromise::AbortablePromise(nsIGlobalObject* aGlobal)
|
||||
: Promise(aGlobal)
|
||||
{
|
||||
}
|
||||
|
||||
AbortablePromise::~AbortablePromise()
|
||||
{
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<AbortablePromise>
|
||||
AbortablePromise::Create(nsIGlobalObject* aGlobal,
|
||||
PromiseNativeAbortCallback& aAbortCallback,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsRefPtr<AbortablePromise> p = new AbortablePromise(aGlobal, aAbortCallback);
|
||||
p->CreateWrapper(aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
AbortablePromise::WrapObject(JSContext* aCx)
|
||||
{
|
||||
return MozAbortablePromiseBinding::Wrap(aCx, this);
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<AbortablePromise>
|
||||
AbortablePromise::Constructor(const GlobalObject& aGlobal, PromiseInit& aInit,
|
||||
AbortCallback& aAbortCallback, ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> global;
|
||||
global = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
if (!global) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<AbortablePromise> promise = new AbortablePromise(global);
|
||||
promise->CreateWrapper(aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
promise->CallInitFunction(aGlobal, aInit, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
promise->mAbortCallback = &aAbortCallback;
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
void
|
||||
AbortablePromise::Abort()
|
||||
{
|
||||
if (IsPending()) {
|
||||
return;
|
||||
}
|
||||
MaybeReject(NS_ERROR_ABORT);
|
||||
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
NS_NewRunnableMethod(this, &AbortablePromise::DoAbort);
|
||||
Promise::DispatchToMainOrWorkerThread(runnable);
|
||||
}
|
||||
|
||||
void
|
||||
AbortablePromise::DoAbort()
|
||||
{
|
||||
if (mAbortCallback.HasWebIDLCallback()) {
|
||||
ErrorResult rv;
|
||||
mAbortCallback.GetWebIDLCallback()->Call(rv);
|
||||
return;
|
||||
}
|
||||
mAbortCallback.GetXPCOMCallback()->Call();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
66
dom/promise/AbortablePromise.h
Normal file
66
dom/promise/AbortablePromise.h
Normal file
@ -0,0 +1,66 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* vim: set ts=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_AbortablePromise_h__
|
||||
#define mozilla_dom_AbortablePromise_h__
|
||||
|
||||
#include "js/TypeDecls.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/CallbackObject.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AbortCallback;
|
||||
class PromiseNativeAbortCallback;
|
||||
|
||||
class AbortablePromise
|
||||
: public Promise
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AbortablePromise, Promise)
|
||||
|
||||
public:
|
||||
// It is the same as Promise::Create except that this takes an extra
|
||||
// aAbortCallback parameter to set the abort callback handler.
|
||||
static already_AddRefed<AbortablePromise>
|
||||
Create(nsIGlobalObject* aGlobal, PromiseNativeAbortCallback& aAbortCallback,
|
||||
ErrorResult& aRv);
|
||||
|
||||
protected:
|
||||
// Constructor used to create native AbortablePromise with C++.
|
||||
AbortablePromise(nsIGlobalObject* aGlobal,
|
||||
PromiseNativeAbortCallback& aAbortCallback);
|
||||
|
||||
// Constructor used to create AbortablePromise for JavaScript. It should be
|
||||
// called by the static AbortablePromise::Constructor.
|
||||
AbortablePromise(nsIGlobalObject* aGlobal);
|
||||
|
||||
virtual ~AbortablePromise();
|
||||
|
||||
public:
|
||||
virtual JSObject*
|
||||
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
static already_AddRefed<AbortablePromise>
|
||||
Constructor(const GlobalObject& aGlobal, PromiseInit& aInit,
|
||||
AbortCallback& aAbortCallback, ErrorResult& aRv);
|
||||
|
||||
void Abort();
|
||||
|
||||
private:
|
||||
void DoAbort();
|
||||
|
||||
// The callback functions to abort the promise.
|
||||
CallbackObjectHolder<AbortCallback,
|
||||
PromiseNativeAbortCallback> mAbortCallback;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_AbortablePromise_h__
|
@ -325,26 +325,33 @@ Promise::WrapObject(JSContext* aCx)
|
||||
already_AddRefed<Promise>
|
||||
Promise::Create(nsIGlobalObject* aGlobal, ErrorResult& aRv)
|
||||
{
|
||||
AutoJSAPI jsapi;
|
||||
if (!jsapi.Init(aGlobal)) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
nsRefPtr<Promise> p = new Promise(aGlobal);
|
||||
p->CreateWrapper(aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
void
|
||||
Promise::CreateWrapper(ErrorResult& aRv)
|
||||
{
|
||||
AutoJSAPI jsapi;
|
||||
if (!jsapi.Init(mGlobal)) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return;
|
||||
}
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
nsRefPtr<Promise> p = new Promise(aGlobal);
|
||||
|
||||
JS::Rooted<JS::Value> ignored(cx);
|
||||
if (!WrapNewBindingObject(cx, p, &ignored)) {
|
||||
if (!WrapNewBindingObject(cx, this, &ignored)) {
|
||||
JS_ClearPendingException(cx);
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
// Need the .get() bit here to get template deduction working right
|
||||
dom::PreserveWrapper(p.get());
|
||||
|
||||
return p.forget();
|
||||
dom::PreserveWrapper(this);
|
||||
}
|
||||
|
||||
void
|
||||
@ -483,8 +490,6 @@ Promise::CreateThenableFunction(JSContext* aCx, Promise* aPromise, uint32_t aTas
|
||||
Promise::Constructor(const GlobalObject& aGlobal,
|
||||
PromiseInit& aInit, ErrorResult& aRv)
|
||||
{
|
||||
JSContext* cx = aGlobal.Context();
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global;
|
||||
global = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
if (!global) {
|
||||
@ -497,20 +502,34 @@ Promise::Constructor(const GlobalObject& aGlobal,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> resolveFunc(cx,
|
||||
CreateFunction(cx, aGlobal.Get(), promise,
|
||||
PromiseCallback::Resolve));
|
||||
if (!resolveFunc) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
promise->CallInitFunction(aGlobal, aInit, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
void
|
||||
Promise::CallInitFunction(const GlobalObject& aGlobal,
|
||||
PromiseInit& aInit, ErrorResult& aRv)
|
||||
{
|
||||
JSContext* cx = aGlobal.Context();
|
||||
|
||||
JS::Rooted<JSObject*> resolveFunc(cx,
|
||||
CreateFunction(cx, aGlobal.Get(), this,
|
||||
PromiseCallback::Resolve));
|
||||
if (!resolveFunc) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> rejectFunc(cx,
|
||||
CreateFunction(cx, aGlobal.Get(), promise,
|
||||
CreateFunction(cx, aGlobal.Get(), this,
|
||||
PromiseCallback::Reject));
|
||||
if (!rejectFunc) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
aInit.Call(resolveFunc, rejectFunc, aRv, CallbackObject::eRethrowExceptions);
|
||||
@ -524,13 +543,11 @@ Promise::Constructor(const GlobalObject& aGlobal,
|
||||
// function Promise(arg) { try { arg(a, b); } catch (e) { this.reject(e); }}
|
||||
if (!JS_WrapValue(cx, &value)) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeRejectInternal(cx, value);
|
||||
MaybeRejectInternal(cx, value);
|
||||
}
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<Promise>
|
||||
|
@ -50,9 +50,9 @@ public:
|
||||
Notify(JSContext* aCx, workers::Status aStatus) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
class Promise MOZ_FINAL : public nsISupports,
|
||||
public nsWrapperCache,
|
||||
public SupportsWeakPtr<Promise>
|
||||
class Promise : public nsISupports,
|
||||
public nsWrapperCache,
|
||||
public SupportsWeakPtr<Promise>
|
||||
{
|
||||
friend class NativePromiseCallback;
|
||||
friend class PromiseResolverTask;
|
||||
@ -65,8 +65,6 @@ class Promise MOZ_FINAL : public nsISupports,
|
||||
friend class ThenableResolverTask;
|
||||
friend class WrapperPromiseCallback;
|
||||
|
||||
~Promise();
|
||||
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Promise)
|
||||
@ -159,11 +157,32 @@ public:
|
||||
|
||||
void AppendNativeHandler(PromiseNativeHandler* aRunnable);
|
||||
|
||||
private:
|
||||
protected:
|
||||
// Do NOT call this unless you're Promise::Create. I wish we could enforce
|
||||
// that from inside this class too, somehow.
|
||||
explicit Promise(nsIGlobalObject* aGlobal);
|
||||
|
||||
virtual ~Promise();
|
||||
|
||||
// Queue an async task to current main or worker thread.
|
||||
static void
|
||||
DispatchToMainOrWorkerThread(nsIRunnable* aRunnable);
|
||||
|
||||
// Do JS-wrapping after Promise creation.
|
||||
void CreateWrapper(ErrorResult& aRv);
|
||||
|
||||
// Create the JS resolving functions of resolve() and reject(). And provide
|
||||
// references to the two functions by calling PromiseInit passed from Promise
|
||||
// constructor.
|
||||
void CallInitFunction(const GlobalObject& aGlobal, PromiseInit& aInit,
|
||||
ErrorResult& aRv);
|
||||
|
||||
bool IsPending()
|
||||
{
|
||||
return mResolvePending;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class PromiseDebugging;
|
||||
|
||||
enum PromiseState {
|
||||
@ -189,10 +208,6 @@ private:
|
||||
mResult = aValue;
|
||||
}
|
||||
|
||||
// Queue an async task to current main or worker thread.
|
||||
static void
|
||||
DispatchToMainOrWorkerThread(nsIRunnable* aRunnable);
|
||||
|
||||
// This method processes promise's resolve/reject callbacks with promise's
|
||||
// result. It's executed when the resolver.resolve() or resolver.reject() is
|
||||
// called or when the promise already has a result and new callbacks are
|
||||
|
@ -20,13 +20,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PromiseCallback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(PromiseCallback)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(PromiseCallback)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(PromiseCallback)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_0(PromiseCallback)
|
||||
|
||||
PromiseCallback::PromiseCallback()
|
||||
{
|
||||
|
36
dom/promise/PromiseNativeAbortCallback.h
Normal file
36
dom/promise/PromiseNativeAbortCallback.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* vim: set ts=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_PromiseNativeAbortCallback_h
|
||||
#define mozilla_dom_PromiseNativeAbortCallback_h
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/*
|
||||
* PromiseNativeAbortCallback allows C++ to react to an AbortablePromise being
|
||||
* aborted.
|
||||
*/
|
||||
class PromiseNativeAbortCallback : public nsISupports
|
||||
{
|
||||
protected:
|
||||
virtual ~PromiseNativeAbortCallback()
|
||||
{ }
|
||||
|
||||
public:
|
||||
// Implemented in AbortablePromise.cpp.
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(PromiseNativeAbortCallback)
|
||||
|
||||
virtual void Call() = 0;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_PromiseNativeAbortCallback_h
|
@ -5,13 +5,16 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'AbortablePromise.h',
|
||||
'Promise.h',
|
||||
'PromiseDebugging.h',
|
||||
'PromiseNativeAbortCallback.h',
|
||||
'PromiseNativeHandler.h',
|
||||
'PromiseWorkerProxy.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'AbortablePromise.cpp',
|
||||
'Promise.cpp',
|
||||
'PromiseCallback.cpp',
|
||||
'PromiseDebugging.cpp'
|
||||
|
@ -4,3 +4,4 @@
|
||||
[test_promise.html]
|
||||
[test_promise_utils.html]
|
||||
[test_resolve.html]
|
||||
[test_abortable_promise.html]
|
||||
|
115
dom/promise/tests/test_abortable_promise.html
Normal file
115
dom/promise/tests/test_abortable_promise.html
Normal file
@ -0,0 +1,115 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Promise.resolve(anything) Test</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript"><!--
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.abortablepromise.enabled", true]]},
|
||||
runTest);
|
||||
var gTests = [testPending, testResolved, testRejected];
|
||||
|
||||
function runTest() {
|
||||
if (gTests.length == 0) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
new Promise(gTests.shift()).then(runTest, SimpleTest.finish);
|
||||
}
|
||||
|
||||
// Aborting pending promise should first reject the promise and then call the
|
||||
// abortable callback.
|
||||
// The test succeeds once both the rejection handler and the abort handler have
|
||||
// been called.
|
||||
function testPending(succeed, fail) {
|
||||
var rejected = false;
|
||||
var aborted = false;
|
||||
|
||||
var p = new MozAbortablePromise(function(resolve, reject) {
|
||||
// Wait for a while so that the promise can be aborted before resolved.
|
||||
SimpleTest.executeSoon(function() {
|
||||
resolve(0);
|
||||
});
|
||||
}, function abortable() {
|
||||
aborted = true;
|
||||
ok(true, "Promise aborted.");
|
||||
if (rejected) {
|
||||
succeed();
|
||||
}
|
||||
});
|
||||
|
||||
p.then(function() {
|
||||
ok(false, "Failed to abort pending promise.");
|
||||
fail();
|
||||
}, function(what) {
|
||||
rejected = true;
|
||||
var isAbortException = (what && what.name) == "NS_ERROR_ABORT";
|
||||
ok(isAbortException, "Should have NS_ERROR_ABORT exception");
|
||||
if (!isAbortException) {
|
||||
fail();
|
||||
}
|
||||
if (aborted) {
|
||||
succeed();
|
||||
}
|
||||
});
|
||||
|
||||
// Abort the promise on creation.
|
||||
p.abort();
|
||||
}
|
||||
|
||||
// Do nothing when aborting resolved promise.
|
||||
function testResolved(succeed, fail) {
|
||||
var p = new MozAbortablePromise(function(resolve, reject) {
|
||||
resolve();
|
||||
}, function abortable() {
|
||||
ok(false, "Should not abort a resolved promise.");
|
||||
fail();
|
||||
});
|
||||
p.then(function() {
|
||||
ok(true, "Promise resolved.");
|
||||
// Wait for a while to ensure abort handle won't be called.
|
||||
setTimeout(succeed, 1000);
|
||||
}, function(what) {
|
||||
ok(false, "Failed to resolve promise: " + what);
|
||||
fail();
|
||||
});
|
||||
p.abort();
|
||||
}
|
||||
|
||||
// Do nothing when aborting rejected promise.
|
||||
function testRejected(succeed, fail) {
|
||||
var p = new MozAbortablePromise(function(resolve, reject) {
|
||||
reject(0);
|
||||
}, function abortable() {
|
||||
ok(false, "Should not abort a rejected promise.");
|
||||
fail();
|
||||
});
|
||||
|
||||
p.then(function() {
|
||||
ok(false, "Failed to reject promise.");
|
||||
fail();
|
||||
}, function(what) {
|
||||
is(what, 0, "promise rejected: " + what);
|
||||
// Wait for a while to ensure abort handle won't be called.
|
||||
setTimeout(succeed, 1000);
|
||||
});
|
||||
p.abort();
|
||||
}
|
||||
// -->
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -118,6 +118,8 @@ var legacyMozPrefixedInterfaces =
|
||||
// IMPORTANT: Do not change the list below without review from a DOM peer!
|
||||
var interfaceNamesInGlobalScope =
|
||||
[
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "MozAbortablePromise", pref: "dom.abortablepromise.enabled"},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "AlarmsManager", pref: "dom.mozAlarms.enabled"},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
19
dom/webidl/AbortablePromise.webidl
Normal file
19
dom/webidl/AbortablePromise.webidl
Normal file
@ -0,0 +1,19 @@
|
||||
/* -*- 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/.
|
||||
*/
|
||||
|
||||
callback AbortCallback = void ();
|
||||
|
||||
[Constructor(PromiseInit init, AbortCallback abortCallback),
|
||||
Pref="dom.abortablepromise.enabled"]
|
||||
interface MozAbortablePromise : _Promise {
|
||||
/*
|
||||
* Aborts the promise.
|
||||
* If the promise has not been resolved or rejected, it should be rejected
|
||||
* with an Exception of type abort and then AbortCallback is called
|
||||
* asynchronously. Otherwise, nothing should be done.
|
||||
*/
|
||||
void abort();
|
||||
};
|
@ -16,6 +16,7 @@ PREPROCESSED_WEBIDL_FILES = [
|
||||
]
|
||||
|
||||
WEBIDL_FILES = [
|
||||
'AbortablePromise.webidl',
|
||||
'AbstractWorker.webidl',
|
||||
'ActivityRequestHandler.webidl',
|
||||
'AlarmsManager.webidl',
|
||||
|
@ -107,6 +107,9 @@ pref("offline-apps.quota.warn", 51200);
|
||||
// cache compression turned off for now - see bug #715198
|
||||
pref("browser.cache.compression_level", 0);
|
||||
|
||||
// Whether or not MozAbortablePromise is enabled.
|
||||
pref("dom.abortablepromise.enabled", false);
|
||||
|
||||
// Whether or not testing features are enabled.
|
||||
pref("dom.quotaManager.testing", false);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user