mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 839838 - Implement DOMRequest.then; r=sicking,bzbarsky
This is implemented by creating a Promise object internally and forwarding the .then() call to it. Any further callbacks passed to future .then() calls will be added as callbacks on the same internal promise object. We also take care of resolving or rejecting the promise if the success/error event of the DOMRequest object has been fired before .then() is called.
This commit is contained in:
parent
6c2570bcd8
commit
1d962eb79e
@ -43,6 +43,11 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
DOMCursor() MOZ_DELETE;
|
DOMCursor() MOZ_DELETE;
|
||||||
|
// Calling Then() on DOMCursor is a mistake, since the DOMCursor object
|
||||||
|
// should not have a .then() method from JS' point of view.
|
||||||
|
already_AddRefed<mozilla::dom::Promise>
|
||||||
|
Then(JSContext* aCx, AnyCallback* aResolveCallback,
|
||||||
|
AnyCallback* aRejectCallback, ErrorResult& aRv) MOZ_DELETE;
|
||||||
|
|
||||||
nsCOMPtr<nsICursorContinueCallback> mCallback;
|
nsCOMPtr<nsICursorContinueCallback> mCallback;
|
||||||
bool mFinished;
|
bool mFinished;
|
||||||
|
@ -10,11 +10,16 @@
|
|||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "DOMCursor.h"
|
#include "DOMCursor.h"
|
||||||
#include "nsIDOMEvent.h"
|
#include "nsIDOMEvent.h"
|
||||||
|
#include "mozilla/ErrorResult.h"
|
||||||
|
#include "mozilla/dom/Promise.h"
|
||||||
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
|
|
||||||
|
using mozilla::dom::AnyCallback;
|
||||||
using mozilla::dom::DOMError;
|
using mozilla::dom::DOMError;
|
||||||
using mozilla::dom::DOMRequest;
|
using mozilla::dom::DOMRequest;
|
||||||
using mozilla::dom::DOMRequestService;
|
using mozilla::dom::DOMRequestService;
|
||||||
using mozilla::dom::DOMCursor;
|
using mozilla::dom::DOMCursor;
|
||||||
|
using mozilla::dom::Promise;
|
||||||
using mozilla::AutoSafeJSContext;
|
using mozilla::AutoSafeJSContext;
|
||||||
|
|
||||||
DOMRequest::DOMRequest(nsPIDOMWindow* aWindow)
|
DOMRequest::DOMRequest(nsPIDOMWindow* aWindow)
|
||||||
@ -25,16 +30,24 @@ DOMRequest::DOMRequest(nsPIDOMWindow* aWindow)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DOMRequest::~DOMRequest()
|
||||||
|
{
|
||||||
|
mResult.setUndefined();
|
||||||
|
mozilla::DropJSObjects(this);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_CLASS(DOMRequest)
|
NS_IMPL_CYCLE_COLLECTION_CLASS(DOMRequest)
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DOMRequest,
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DOMRequest,
|
||||||
DOMEventTargetHelper)
|
DOMEventTargetHelper)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mError)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mError)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPromise)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DOMRequest,
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DOMRequest,
|
||||||
DOMEventTargetHelper)
|
DOMEventTargetHelper)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mError)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mError)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPromise)
|
||||||
tmp->mResult = JSVAL_VOID;
|
tmp->mResult = JSVAL_VOID;
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
@ -107,6 +120,10 @@ DOMRequest::FireSuccess(JS::Handle<JS::Value> aResult)
|
|||||||
mResult = aResult;
|
mResult = aResult;
|
||||||
|
|
||||||
FireEvent(NS_LITERAL_STRING("success"), false, false);
|
FireEvent(NS_LITERAL_STRING("success"), false, false);
|
||||||
|
|
||||||
|
if (mPromise) {
|
||||||
|
mPromise->MaybeResolve(mResult);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -120,6 +137,10 @@ DOMRequest::FireError(const nsAString& aError)
|
|||||||
mError = new DOMError(GetOwner(), aError);
|
mError = new DOMError(GetOwner(), aError);
|
||||||
|
|
||||||
FireEvent(NS_LITERAL_STRING("error"), true, true);
|
FireEvent(NS_LITERAL_STRING("error"), true, true);
|
||||||
|
|
||||||
|
if (mPromise) {
|
||||||
|
mPromise->MaybeRejectBrokenly(mError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -133,6 +154,10 @@ DOMRequest::FireError(nsresult aError)
|
|||||||
mError = new DOMError(GetOwner(), aError);
|
mError = new DOMError(GetOwner(), aError);
|
||||||
|
|
||||||
FireEvent(NS_LITERAL_STRING("error"), true, true);
|
FireEvent(NS_LITERAL_STRING("error"), true, true);
|
||||||
|
|
||||||
|
if (mPromise) {
|
||||||
|
mPromise->MaybeRejectBrokenly(mError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -147,6 +172,10 @@ DOMRequest::FireDetailedError(DOMError* aError)
|
|||||||
mError = aError;
|
mError = aError;
|
||||||
|
|
||||||
FireEvent(NS_LITERAL_STRING("error"), true, true);
|
FireEvent(NS_LITERAL_STRING("error"), true, true);
|
||||||
|
|
||||||
|
if (mPromise) {
|
||||||
|
mPromise->MaybeRejectBrokenly(mError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -175,6 +204,31 @@ DOMRequest::RootResultVal()
|
|||||||
mozilla::HoldJSObjects(this);
|
mozilla::HoldJSObjects(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
DOMRequest::Then(JSContext* aCx, AnyCallback* aResolveCallback,
|
||||||
|
AnyCallback* aRejectCallback, mozilla::ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
if (!mPromise) {
|
||||||
|
mPromise = Promise::Create(DOMEventTargetHelper::GetParentObject(), aRv);
|
||||||
|
if (aRv.Failed()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (mDone) {
|
||||||
|
// Since we create mPromise lazily, it's possible that the DOMRequest object
|
||||||
|
// has already fired its success/error event. In that case we should
|
||||||
|
// manually resolve/reject mPromise here. mPromise will take care of
|
||||||
|
// calling the callbacks on |promise| as needed.
|
||||||
|
if (mError) {
|
||||||
|
mPromise->MaybeRejectBrokenly(mError);
|
||||||
|
} else {
|
||||||
|
mPromise->MaybeResolve(mResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mPromise->Then(aCx, aResolveCallback, aRejectCallback, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(DOMRequestService, nsIDOMRequestService)
|
NS_IMPL_ISUPPORTS(DOMRequestService, nsIDOMRequestService)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
@ -253,7 +307,7 @@ public:
|
|||||||
const JS::Value& aResult)
|
const JS::Value& aResult)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
AutoSafeJSContext cx;
|
mozilla::ThreadsafeAutoSafeJSContext cx;
|
||||||
nsRefPtr<FireSuccessAsyncTask> asyncTask = new FireSuccessAsyncTask(cx, aRequest, aResult);
|
nsRefPtr<FireSuccessAsyncTask> asyncTask = new FireSuccessAsyncTask(cx, aRequest, aResult);
|
||||||
if (NS_FAILED(NS_DispatchToMainThread(asyncTask))) {
|
if (NS_FAILED(NS_DispatchToMainThread(asyncTask))) {
|
||||||
NS_WARNING("Failed to dispatch to main thread!");
|
NS_WARNING("Failed to dispatch to main thread!");
|
||||||
|
@ -16,14 +16,21 @@
|
|||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
class ErrorResult;
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
class AnyCallback;
|
||||||
|
class Promise;
|
||||||
|
|
||||||
class DOMRequest : public DOMEventTargetHelper,
|
class DOMRequest : public DOMEventTargetHelper,
|
||||||
public nsIDOMDOMRequest
|
public nsIDOMDOMRequest
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
JS::Heap<JS::Value> mResult;
|
JS::Heap<JS::Value> mResult;
|
||||||
nsRefPtr<DOMError> mError;
|
nsRefPtr<DOMError> mError;
|
||||||
|
nsRefPtr<Promise> mPromise;
|
||||||
bool mDone;
|
bool mDone;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -67,6 +74,9 @@ public:
|
|||||||
IMPL_EVENT_HANDLER(success)
|
IMPL_EVENT_HANDLER(success)
|
||||||
IMPL_EVENT_HANDLER(error)
|
IMPL_EVENT_HANDLER(error)
|
||||||
|
|
||||||
|
already_AddRefed<mozilla::dom::Promise>
|
||||||
|
Then(JSContext* aCx, AnyCallback* aResolveCallback,
|
||||||
|
AnyCallback* aRejectCallback, mozilla::ErrorResult& aRv);
|
||||||
|
|
||||||
void FireSuccess(JS::Handle<JS::Value> aResult);
|
void FireSuccess(JS::Handle<JS::Value> aResult);
|
||||||
void FireError(const nsAString& aError);
|
void FireError(const nsAString& aError);
|
||||||
@ -76,11 +86,7 @@ public:
|
|||||||
explicit DOMRequest(nsPIDOMWindow* aWindow);
|
explicit DOMRequest(nsPIDOMWindow* aWindow);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~DOMRequest()
|
virtual ~DOMRequest();
|
||||||
{
|
|
||||||
mResult = JSVAL_VOID;
|
|
||||||
mozilla::DropJSObjects(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FireEvent(const nsAString& aType, bool aBubble, bool aCancelable);
|
void FireEvent(const nsAString& aType, bool aBubble, bool aCancelable);
|
||||||
|
|
||||||
|
@ -51,6 +51,7 @@ var tests = [
|
|||||||
ok("readyState" in req, "cursor has readyState");
|
ok("readyState" in req, "cursor has readyState");
|
||||||
ok("done" in req, "cursor has finished");
|
ok("done" in req, "cursor has finished");
|
||||||
ok("continue" in req, "cursor has continue");
|
ok("continue" in req, "cursor has continue");
|
||||||
|
ok(!("then" in req), "cursor should not have a then method");
|
||||||
|
|
||||||
is(req.readyState, "pending", "readyState is pending");
|
is(req.readyState, "pending", "readyState is pending");
|
||||||
is(req.result, undefined, "result is undefined");
|
is(req.result, undefined, "result is undefined");
|
||||||
|
@ -17,59 +17,212 @@
|
|||||||
var reqserv = SpecialPowers.getDOMRequestService();
|
var reqserv = SpecialPowers.getDOMRequestService();
|
||||||
ok("createRequest" in reqserv, "appears to be a service");
|
ok("createRequest" in reqserv, "appears to be a service");
|
||||||
|
|
||||||
// create a request
|
function testBasics() {
|
||||||
var req = reqserv.createRequest(window);
|
// create a request
|
||||||
ok("result" in req, "request has result");
|
var req = reqserv.createRequest(window);
|
||||||
ok("error" in req, "request has error");
|
ok("result" in req, "request has result");
|
||||||
ok("onsuccess" in req, "request has onsuccess");
|
ok("error" in req, "request has error");
|
||||||
ok("onerror" in req, "request has onerror");
|
ok("onsuccess" in req, "request has onsuccess");
|
||||||
ok("readyState" in req, "request has readyState");
|
ok("onerror" in req, "request has onerror");
|
||||||
|
ok("readyState" in req, "request has readyState");
|
||||||
|
ok("then" in req, "request has then");
|
||||||
|
|
||||||
is(req.readyState, "pending", "readyState is pending");
|
is(req.readyState, "pending", "readyState is pending");
|
||||||
is(req.result, undefined, "result is undefined");
|
is(req.result, undefined, "result is undefined");
|
||||||
is(req.onsuccess, null, "onsuccess is null");
|
is(req.onsuccess, null, "onsuccess is null");
|
||||||
is(req.onerror, null, "onerror is null");
|
is(req.onerror, null, "onerror is null");
|
||||||
|
|
||||||
// fire success
|
runTest();
|
||||||
var ev = null;
|
|
||||||
req.onsuccess = function(e) {
|
|
||||||
ev = e;
|
|
||||||
}
|
}
|
||||||
reqserv.fireSuccess(req, "my result");
|
|
||||||
ok(ev, "got success event");
|
|
||||||
is(ev.type, "success", "correct type during success");
|
|
||||||
is(ev.target, req, "correct target during success");
|
|
||||||
is(req.readyState, "done", "correct readyState after success");
|
|
||||||
is(req.error, null, "correct error after success");
|
|
||||||
is(req.result, "my result", "correct result after success");
|
|
||||||
|
|
||||||
// fire error
|
function testSuccess() {
|
||||||
req = reqserv.createRequest(window);
|
// fire success
|
||||||
ev = null;
|
var req = reqserv.createRequest(window);
|
||||||
req.onerror = function(e) {
|
var ev = null;
|
||||||
ev = e;
|
req.onsuccess = function(e) {
|
||||||
|
ev = e;
|
||||||
|
}
|
||||||
|
var result = null;
|
||||||
|
var promise = req.then(function(r) {
|
||||||
|
is(r, "my result", "correct result when resolving the promise");
|
||||||
|
result = r;
|
||||||
|
runTest();
|
||||||
|
}, function(e) {
|
||||||
|
ok(false, "promise should not be rejected");
|
||||||
|
runTest();
|
||||||
|
});
|
||||||
|
ok(promise instanceof Promise, "then() should return a Promise");
|
||||||
|
reqserv.fireSuccess(req, "my result");
|
||||||
|
ok(ev, "got success event");
|
||||||
|
is(ev.type, "success", "correct type during success");
|
||||||
|
is(ev.target, req, "correct target during success");
|
||||||
|
is(req.readyState, "done", "correct readyState after success");
|
||||||
|
is(req.error, null, "correct error after success");
|
||||||
|
is(req.result, "my result", "correct result after success");
|
||||||
|
is(result, null, "Promise should not be resolved synchronously");
|
||||||
}
|
}
|
||||||
reqserv.fireError(req, "OhMyError");
|
|
||||||
ok(ev, "got error event");
|
|
||||||
is(ev.type, "error", "correct type during error");
|
|
||||||
is(ev.target, req, "correct target during error");
|
|
||||||
is(req.readyState, "done", "correct readyState after error");
|
|
||||||
is(req.error.name, "OhMyError", "correct error after error");
|
|
||||||
is(req.result, undefined, "correct result after error");
|
|
||||||
|
|
||||||
// fire detailed error
|
function testError() {
|
||||||
req = reqserv.createRequest(window);
|
// fire error
|
||||||
ev = null;
|
var req = reqserv.createRequest(window);
|
||||||
req.onerror = function(e) {
|
var ev = null;
|
||||||
ev = e;
|
req.onerror = function(e) {
|
||||||
};
|
ev = e;
|
||||||
reqserv.fireDetailedError(req, new DOMError("detailedError"));
|
}
|
||||||
ok(ev, "got error event");
|
var error = null;
|
||||||
is(ev.type, "error", "correct type during error");
|
var promise = req.then(function(r) {
|
||||||
is(ev.target, req, "correct target during error");
|
ok(false, "promise should not be resolved");
|
||||||
is(req.readyState, "done", "correct readyState after error");
|
runTest();
|
||||||
is(req.error.name, "detailedError", "correct error after error");
|
}, function(e) {
|
||||||
is(req.result, undefined, "correct result after error");
|
ok(e instanceof DOMError, "got error rejection");
|
||||||
|
ok(e === req.error, "got correct error when rejecting the promise");
|
||||||
|
error = e;
|
||||||
|
runTest();
|
||||||
|
});
|
||||||
|
ok(promise instanceof Promise, "then() should return a Promise");
|
||||||
|
reqserv.fireError(req, "OhMyError");
|
||||||
|
ok(ev, "got error event");
|
||||||
|
is(ev.type, "error", "correct type during error");
|
||||||
|
is(ev.target, req, "correct target during error");
|
||||||
|
is(req.readyState, "done", "correct readyState after error");
|
||||||
|
is(req.error.name, "OhMyError", "correct error after error");
|
||||||
|
is(req.result, undefined, "correct result after error");
|
||||||
|
is(error, null, "Promise should not be rejected synchronously");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testDetailedError() {
|
||||||
|
// fire detailed error
|
||||||
|
var req = reqserv.createRequest(window);
|
||||||
|
var ev = null;
|
||||||
|
req.onerror = function(e) {
|
||||||
|
ev = e;
|
||||||
|
};
|
||||||
|
var error = null;
|
||||||
|
var promise = req.then(function(r) {
|
||||||
|
ok(false, "promise should not be resolved");
|
||||||
|
runTest();
|
||||||
|
}, function(e) {
|
||||||
|
ok(e instanceof DOMError, "got error rejection");
|
||||||
|
ok(e === req.error, "got correct error when rejecting the promise");
|
||||||
|
error = e;
|
||||||
|
runTest();
|
||||||
|
});
|
||||||
|
ok(promise instanceof Promise, "then() should return a Promise");
|
||||||
|
reqserv.fireDetailedError(req, new DOMError("detailedError"));
|
||||||
|
ok(ev, "got error event");
|
||||||
|
is(ev.type, "error", "correct type during error");
|
||||||
|
is(ev.target, req, "correct target during error");
|
||||||
|
is(req.readyState, "done", "correct readyState after error");
|
||||||
|
is(req.error.name, "detailedError", "correct error after error");
|
||||||
|
is(req.result, undefined, "correct result after error");
|
||||||
|
is(error, null, "Promise should not be rejected synchronously");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testThenAfterSuccess() {
|
||||||
|
// fire success
|
||||||
|
var req = reqserv.createRequest(window);
|
||||||
|
var ev = null;
|
||||||
|
req.onsuccess = function(e) {
|
||||||
|
ev = e;
|
||||||
|
}
|
||||||
|
reqserv.fireSuccess(req, "my result");
|
||||||
|
ok(ev, "got success event");
|
||||||
|
is(ev.type, "success", "correct type during success");
|
||||||
|
is(ev.target, req, "correct target during success");
|
||||||
|
is(req.readyState, "done", "correct readyState after success");
|
||||||
|
is(req.error, null, "correct error after success");
|
||||||
|
is(req.result, "my result", "correct result after success");
|
||||||
|
var result = null;
|
||||||
|
var promise = req.then(function(r) {
|
||||||
|
is(r, "my result", "correct result when resolving the promise");
|
||||||
|
result = r;
|
||||||
|
runTest();
|
||||||
|
}, function(e) {
|
||||||
|
ok(false, "promise should not be rejected");
|
||||||
|
runTest();
|
||||||
|
});
|
||||||
|
ok(promise instanceof Promise, "then() should return a Promise");
|
||||||
|
is(result, null, "Promise should not be resolved synchronously");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testThenAfterError() {
|
||||||
|
// fire error
|
||||||
|
var req = reqserv.createRequest(window);
|
||||||
|
var ev = null;
|
||||||
|
req.onerror = function(e) {
|
||||||
|
ev = e;
|
||||||
|
}
|
||||||
|
reqserv.fireError(req, "OhMyError");
|
||||||
|
ok(ev, "got error event");
|
||||||
|
is(ev.type, "error", "correct type during error");
|
||||||
|
is(ev.target, req, "correct target during error");
|
||||||
|
is(req.readyState, "done", "correct readyState after error");
|
||||||
|
is(req.error.name, "OhMyError", "correct error after error");
|
||||||
|
is(req.result, undefined, "correct result after error");
|
||||||
|
var error = null;
|
||||||
|
var promise = req.then(function(r) {
|
||||||
|
ok(false, "promise should not be resolved");
|
||||||
|
runTest();
|
||||||
|
}, function(e) {
|
||||||
|
ok(e instanceof DOMError, "got error rejection");
|
||||||
|
ok(e === req.error, "got correct error when rejecting the promise");
|
||||||
|
error = e;
|
||||||
|
runTest();
|
||||||
|
});
|
||||||
|
ok(promise instanceof Promise, "then() should return a Promise");
|
||||||
|
is(error, null, "Promise should not be rejected synchronously");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testDetailedError() {
|
||||||
|
// fire detailed error
|
||||||
|
var req = reqserv.createRequest(window);
|
||||||
|
var ev = null;
|
||||||
|
req.onerror = function(e) {
|
||||||
|
ev = e;
|
||||||
|
};
|
||||||
|
var error = null;
|
||||||
|
var promise = req.then(function(r) {
|
||||||
|
ok(false, "promise should not be resolved");
|
||||||
|
runTest();
|
||||||
|
}, function(e) {
|
||||||
|
ok(e instanceof DOMError, "got error rejection");
|
||||||
|
ok(e === req.error, "got correct error when rejecting the promise");
|
||||||
|
error = e;
|
||||||
|
runTest();
|
||||||
|
});
|
||||||
|
ok(promise instanceof Promise, "then() should return a Promise");
|
||||||
|
reqserv.fireDetailedError(req, new DOMError("detailedError"));
|
||||||
|
ok(ev, "got error event");
|
||||||
|
is(ev.type, "error", "correct type during error");
|
||||||
|
is(ev.target, req, "correct target during error");
|
||||||
|
is(req.readyState, "done", "correct readyState after error");
|
||||||
|
is(req.error.name, "detailedError", "correct error after error");
|
||||||
|
is(req.result, undefined, "correct result after error");
|
||||||
|
is(error, null, "Promise should not be rejected synchronously");
|
||||||
|
}
|
||||||
|
|
||||||
|
var tests = [
|
||||||
|
testBasics,
|
||||||
|
testSuccess,
|
||||||
|
testError,
|
||||||
|
testDetailedError,
|
||||||
|
testThenAfterSuccess,
|
||||||
|
testThenAfterError,
|
||||||
|
];
|
||||||
|
|
||||||
|
function runTest() {
|
||||||
|
if (!tests.length) {
|
||||||
|
SimpleTest.finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var test = tests.shift();
|
||||||
|
test();
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
runTest();
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</pre>
|
</pre>
|
||||||
</body>
|
</body>
|
||||||
|
@ -352,6 +352,10 @@ DOMInterfaces = {
|
|||||||
'headerFile': 'mozilla/dom/DOMRect.h',
|
'headerFile': 'mozilla/dom/DOMRect.h',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'DOMRequest': {
|
||||||
|
'implicitJSContext': [ 'then' ],
|
||||||
|
},
|
||||||
|
|
||||||
'DOMSettableTokenList': {
|
'DOMSettableTokenList': {
|
||||||
'nativeType': 'nsDOMSettableTokenList',
|
'nativeType': 'nsDOMSettableTokenList',
|
||||||
},
|
},
|
||||||
|
@ -236,6 +236,24 @@ ToJSValue(JSContext* aCx, JS::Handle<JS::Value> aArgument,
|
|||||||
return MaybeWrapValue(aCx, aValue);
|
return MaybeWrapValue(aCx, aValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Accept existing JS values on the Heap (which may not be same-compartment with us
|
||||||
|
inline bool
|
||||||
|
ToJSValue(JSContext* aCx, const JS::Heap<JS::Value>& aArgument,
|
||||||
|
JS::MutableHandle<JS::Value> aValue)
|
||||||
|
{
|
||||||
|
aValue.set(aArgument);
|
||||||
|
return MaybeWrapValue(aCx, aValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept existing rooted JS values (which may not be same-compartment with us
|
||||||
|
inline bool
|
||||||
|
ToJSValue(JSContext* aCx, const JS::Rooted<JS::Value>& aArgument,
|
||||||
|
JS::MutableHandle<JS::Value> aValue)
|
||||||
|
{
|
||||||
|
aValue.set(aArgument);
|
||||||
|
return MaybeWrapValue(aCx, aValue);
|
||||||
|
}
|
||||||
|
|
||||||
// Accept nsresult, for use in rejections, and create an XPCOM
|
// Accept nsresult, for use in rejections, and create an XPCOM
|
||||||
// exception object representing that nsresult.
|
// exception object representing that nsresult.
|
||||||
bool
|
bool
|
||||||
|
@ -1316,17 +1316,8 @@ function sendMMI(aMmi) {
|
|||||||
let deferred = Promise.defer();
|
let deferred = Promise.defer();
|
||||||
|
|
||||||
telephony.dial(aMmi)
|
telephony.dial(aMmi)
|
||||||
.then(request => {
|
.then(result => {
|
||||||
ok(request instanceof DOMRequest,
|
deferred.resolve(result);
|
||||||
"request is instanceof " + request.constructor);
|
|
||||||
|
|
||||||
request.addEventListener("success", function(event) {
|
|
||||||
deferred.resolve(request.result);
|
|
||||||
});
|
|
||||||
|
|
||||||
request.addEventListener("error", function(event) {
|
|
||||||
deferred.reject(request.error);
|
|
||||||
});
|
|
||||||
}, cause => {
|
}, cause => {
|
||||||
deferred.reject(cause);
|
deferred.reject(cause);
|
||||||
});
|
});
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
interface DOMCursor : DOMRequest {
|
interface DOMCursor : EventTarget {
|
||||||
readonly attribute boolean done;
|
readonly attribute boolean done;
|
||||||
[Throws]
|
[Throws]
|
||||||
void continue();
|
void continue();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DOMCursor implements DOMRequestShared;
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
|
|
||||||
enum DOMRequestReadyState { "pending", "done" };
|
enum DOMRequestReadyState { "pending", "done" };
|
||||||
|
|
||||||
interface DOMRequest : EventTarget {
|
[NoInterfaceObject]
|
||||||
|
interface DOMRequestShared {
|
||||||
readonly attribute DOMRequestReadyState readyState;
|
readonly attribute DOMRequestReadyState readyState;
|
||||||
|
|
||||||
readonly attribute any result;
|
readonly attribute any result;
|
||||||
@ -14,3 +15,13 @@ interface DOMRequest : EventTarget {
|
|||||||
attribute EventHandler onsuccess;
|
attribute EventHandler onsuccess;
|
||||||
attribute EventHandler onerror;
|
attribute EventHandler onerror;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface DOMRequest : EventTarget {
|
||||||
|
// The [TreatNonCallableAsNull] annotation is required since then() should do
|
||||||
|
// nothing instead of throwing errors when non-callable arguments are passed.
|
||||||
|
[NewObject, Throws]
|
||||||
|
Promise<any> then([TreatNonCallableAsNull] optional AnyCallback? fulfillCallback = null,
|
||||||
|
[TreatNonCallableAsNull] optional AnyCallback? rejectCallback = null);
|
||||||
|
};
|
||||||
|
|
||||||
|
DOMRequest implements DOMRequestShared;
|
||||||
|
Loading…
Reference in New Issue
Block a user