--- a/dom/base/DOMCursor.h
+++ b/dom/base/DOMCursor.h
@@ -38,21 +38,16 @@ public:
void Reset();
void FireDone();
protected:
~DOMCursor() {}
private:
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;
bool mFinished;
};
} // namespace dom
} // namespace mozilla
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -5,54 +5,41 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DOMRequest.h"
#include "DOMError.h"
#include "nsThreadUtils.h"
#include "DOMCursor.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::DOMRequest;
using mozilla::dom::DOMRequestService;
using mozilla::dom::DOMCursor;
-using mozilla::dom::Promise;
using mozilla::AutoSafeJSContext;
DOMRequest::DOMRequest(nsPIDOMWindow* aWindow)
: DOMEventTargetHelper(aWindow->IsInnerWindow() ?
aWindow : aWindow->GetCurrentInnerWindow())
, mResult(JSVAL_VOID)
, mDone(false)
{
}
-DOMRequest::~DOMRequest()
-{
- mResult.setUndefined();
- mozilla::DropJSObjects(this);
-}
-
NS_IMPL_CYCLE_COLLECTION_CLASS(DOMRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DOMRequest,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mError)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPromise)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DOMRequest,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mError)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mPromise)
tmp->mResult = JSVAL_VOID;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(DOMRequest,
DOMEventTargetHelper)
// Don't need NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER because
// DOMEventTargetHelper does it for us.
NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mResult)
@@ -115,72 +102,56 @@ DOMRequest::FireSuccess(JS::Handle<JS::V
mDone = true;
if (aResult.isGCThing()) {
RootResultVal();
}
mResult = aResult;
FireEvent(NS_LITERAL_STRING("success"), false, false);
-
- if (mPromise) {
- mPromise->MaybeResolve(mResult);
- }
}
void
DOMRequest::FireError(const nsAString& aError)
{
NS_ASSERTION(!mDone, "mDone shouldn't have been set to true already!");
NS_ASSERTION(!mError, "mError shouldn't have been set!");
NS_ASSERTION(mResult == JSVAL_VOID, "mResult shouldn't have been set!");
mDone = true;
mError = new DOMError(GetOwner(), aError);
FireEvent(NS_LITERAL_STRING("error"), true, true);
-
- if (mPromise) {
- mPromise->MaybeRejectBrokenly(mError);
- }
}
void
DOMRequest::FireError(nsresult aError)
{
NS_ASSERTION(!mDone, "mDone shouldn't have been set to true already!");
NS_ASSERTION(!mError, "mError shouldn't have been set!");
NS_ASSERTION(mResult == JSVAL_VOID, "mResult shouldn't have been set!");
mDone = true;
mError = new DOMError(GetOwner(), aError);
FireEvent(NS_LITERAL_STRING("error"), true, true);
-
- if (mPromise) {
- mPromise->MaybeRejectBrokenly(mError);
- }
}
void
DOMRequest::FireDetailedError(DOMError* aError)
{
NS_ASSERTION(!mDone, "mDone shouldn't have been set to true already!");
NS_ASSERTION(!mError, "mError shouldn't have been set!");
NS_ASSERTION(mResult == JSVAL_VOID, "mResult shouldn't have been set!");
NS_ASSERTION(aError, "No detailed error provided");
mDone = true;
mError = aError;
FireEvent(NS_LITERAL_STRING("error"), true, true);
-
- if (mPromise) {
- mPromise->MaybeRejectBrokenly(mError);
- }
}
void
DOMRequest::FireEvent(const nsAString& aType, bool aBubble, bool aCancelable)
{
if (NS_FAILED(CheckInnerWindowCorrectness())) {
return;
}
@@ -199,41 +170,16 @@ DOMRequest::FireEvent(const nsAString& a
}
void
DOMRequest::RootResultVal()
{
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_IMETHODIMP
DOMRequestService::CreateRequest(nsIDOMWindow* aWindow,
nsIDOMDOMRequest** aRequest)
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(aWindow));
NS_ENSURE_STATE(win);
@@ -302,17 +248,17 @@ public:
// Due to the fact that initialization can fail during shutdown (since we
// can't fetch a js context), set up an initiatization function to make sure
// we can return the failure appropriately
static nsresult
Dispatch(DOMRequest* aRequest,
const JS::Value& aResult)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
- mozilla::ThreadsafeAutoSafeJSContext cx;
+ AutoSafeJSContext cx;
nsRefPtr<FireSuccessAsyncTask> asyncTask = new FireSuccessAsyncTask(cx, aRequest, aResult);
if (NS_FAILED(NS_DispatchToMainThread(asyncTask))) {
NS_WARNING("Failed to dispatch to main thread!");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
--- a/dom/base/DOMRequest.h
+++ b/dom/base/DOMRequest.h
@@ -11,31 +11,24 @@
#include "mozilla/Attributes.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/DOMError.h"
#include "mozilla/dom/DOMRequestBinding.h"
#include "nsCOMPtr.h"
namespace mozilla {
-
-class ErrorResult;
-
namespace dom {
-class AnyCallback;
-class Promise;
-
class DOMRequest : public DOMEventTargetHelper,
public nsIDOMDOMRequest
{
protected:
JS::Heap<JS::Value> mResult;
nsRefPtr<DOMError> mError;
- nsRefPtr<Promise> mPromise;
bool mDone;
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIDOMDOMREQUEST
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(DOMRequest,
@@ -69,29 +62,30 @@ public:
NS_ASSERTION(mDone || !mError,
"Error should be null when pending");
return mError;
}
IMPL_EVENT_HANDLER(success)
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 FireError(const nsAString& aError);
void FireError(nsresult aError);
void FireDetailedError(DOMError* aError);
explicit DOMRequest(nsPIDOMWindow* aWindow);
protected:
- virtual ~DOMRequest();
+ virtual ~DOMRequest()
+ {
+ mResult = JSVAL_VOID;
+ mozilla::DropJSObjects(this);
+ }
void FireEvent(const nsAString& aType, bool aBubble, bool aCancelable);
void RootResultVal();
};
class DOMRequestService MOZ_FINAL : public nsIDOMRequestService
{
--- a/dom/base/test/test_domcursor.html
+++ b/dom/base/test/test_domcursor.html
@@ -46,17 +46,16 @@ var tests = [
});
ok("result" in req, "cursor has result");
ok("error" in req, "cursor has error");
ok("onsuccess" in req, "cursor has onsuccess");
ok("onerror" in req, "cursor has onerror");
ok("readyState" in req, "cursor has readyState");
ok("done" in req, "cursor has finished");
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.result, undefined, "result is undefined");
is(req.onsuccess, null, "onsuccess is null");
is(req.onerror, null, "onerror is null");
next();
},
function() {
--- a/dom/base/test/test_domrequest.html
+++ b/dom/base/test/test_domrequest.html
@@ -12,218 +12,65 @@
</div>
<pre id="test">
<script class="testbody" type="application/javascript;version=1.7">
"use strict";
var reqserv = SpecialPowers.getDOMRequestService();
ok("createRequest" in reqserv, "appears to be a service");
-function testBasics() {
- // create a request
- var req = reqserv.createRequest(window);
- ok("result" in req, "request has result");
- ok("error" in req, "request has error");
- ok("onsuccess" in req, "request has onsuccess");
- 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.result, undefined, "result is undefined");
- is(req.onsuccess, null, "onsuccess is null");
- is(req.onerror, null, "onerror is null");
-
- runTest();
-}
+// create a request
+var req = reqserv.createRequest(window);
+ok("result" in req, "request has result");
+ok("error" in req, "request has error");
+ok("onsuccess" in req, "request has onsuccess");
+ok("onerror" in req, "request has onerror");
+ok("readyState" in req, "request has readyState");
-function testSuccess() {
- // fire success
- var req = reqserv.createRequest(window);
- var ev = null;
- 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");
-}
+is(req.readyState, "pending", "readyState is pending");
+is(req.result, undefined, "result is undefined");
+is(req.onsuccess, null, "onsuccess is null");
+is(req.onerror, null, "onerror is null");
-function testError() {
- // fire 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.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");
+// fire success
+var ev = null;
+req.onsuccess = function(e) {
+ ev = e;
}
-
-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");
-}
+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");
-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");
+// fire error
+req = reqserv.createRequest(window);
+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");
-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();
-
+// fire detailed error
+req = reqserv.createRequest(window);
+ev = null;
+req.onerror = function(e) {
+ ev = e;
+};
+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");
</script>
</pre>
</body>
</html>
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -347,20 +347,16 @@ DOMInterfaces = {
'DOMRectList': {
'headerFile': 'mozilla/dom/DOMRect.h',
},
'DOMRectReadOnly': {
'headerFile': 'mozilla/dom/DOMRect.h',
},
-'DOMRequest': {
- 'implicitJSContext': [ 'then' ],
-},
-
'DOMSettableTokenList': {
'nativeType': 'nsDOMSettableTokenList',
},
'DOMStringMap': {
'nativeType': 'nsDOMStringMap'
},
--- a/dom/bindings/ToJSValue.h
+++ b/dom/bindings/ToJSValue.h
@@ -231,34 +231,16 @@ ToJSValue(JSContext* aCx,
inline bool
ToJSValue(JSContext* aCx, JS::Handle<JS::Value> aArgument,
JS::MutableHandle<JS::Value> aValue)
{
aValue.set(aArgument);
return MaybeWrapValue(aCx, aValue);
}
-// Accept existing JS values on the Heap (which may not be same-compartment with us
-inline bool
-ToJSValue(JSContext* aCx, 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, 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
// exception object representing that nsresult.
bool
ToJSValue(JSContext* aCx,
nsresult aArgument,
JS::MutableHandle<JS::Value> aValue);
// Accept pointers to other things we accept
--- a/dom/telephony/test/marionette/head.js
+++ b/dom/telephony/test/marionette/head.js
@@ -1311,16 +1311,25 @@ function startDSDSTest(test) {
finish();
}
}
function sendMMI(aMmi) {
let deferred = Promise.defer();
telephony.dial(aMmi)
- .then(result => {
- deferred.resolve(result);
+ .then(request => {
+ ok(request instanceof DOMRequest,
+ "request is instanceof " + request.constructor);
+
+ request.addEventListener("success", function(event) {
+ deferred.resolve(request.result);
+ });
+
+ request.addEventListener("error", function(event) {
+ deferred.reject(request.error);
+ });
}, cause => {
deferred.reject(cause);
});
return deferred.promise;
}
--- a/dom/webidl/DOMCursor.webidl
+++ b/dom/webidl/DOMCursor.webidl
@@ -1,12 +1,10 @@
/* -*- 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/. */
-interface DOMCursor : EventTarget {
+interface DOMCursor : DOMRequest {
readonly attribute boolean done;
[Throws]
void continue();
};
-
-DOMCursor implements DOMRequestShared;
--- a/dom/webidl/DOMRequest.webidl
+++ b/dom/webidl/DOMRequest.webidl
@@ -1,27 +1,16 @@
/* -*- 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/. */
enum DOMRequestReadyState { "pending", "done" };
-[NoInterfaceObject]
-interface DOMRequestShared {
+interface DOMRequest : EventTarget {
readonly attribute DOMRequestReadyState readyState;
readonly attribute any result;
readonly attribute DOMError? error;
attribute EventHandler onsuccess;
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;
--- a/js/public/RootingAPI.h
+++ b/js/public/RootingAPI.h
@@ -215,17 +215,17 @@ class Heap : public js::HeapBase<T>
explicit Heap(T p) { init(p); }
/*
* For Heap, move semantics are equivalent to copy semantics. In C++, a
* copy constructor taking const-ref is the way to get a single function
* that will be used for both lvalue and rvalue copies, so we can simply
* omit the rvalue variant.
*/
- Heap(const Heap<T> &p) { init(p.ptr); }
+ explicit Heap(const Heap<T> &p) { init(p.ptr); }
~Heap() {
if (js::GCMethods<T>::needsPostBarrier(ptr))
relocate();
}
bool operator==(const Heap<T> &other) { return ptr == other.ptr; }
bool operator!=(const Heap<T> &other) { return ptr != other.ptr; }