diff --git a/dom/base/DOMCursor.h b/dom/base/DOMCursor.h index 6c4694399241..08bd987354b9 100644 --- a/dom/base/DOMCursor.h +++ b/dom/base/DOMCursor.h @@ -43,11 +43,6 @@ protected: 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 - Then(JSContext* aCx, AnyCallback* aResolveCallback, - AnyCallback* aRejectCallback, ErrorResult& aRv) MOZ_DELETE; nsCOMPtr mCallback; bool mFinished; diff --git a/dom/base/DOMRequest.cpp b/dom/base/DOMRequest.cpp index 3afc8334bee7..a6c21cb47703 100644 --- a/dom/base/DOMRequest.cpp +++ b/dom/base/DOMRequest.cpp @@ -10,16 +10,11 @@ #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) @@ -30,24 +25,16 @@ DOMRequest::DOMRequest(nsPIDOMWindow* aWindow) { } -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 @@ -120,10 +107,6 @@ DOMRequest::FireSuccess(JS::Handle aResult) mResult = aResult; FireEvent(NS_LITERAL_STRING("success"), false, false); - - if (mPromise) { - mPromise->MaybeResolve(mResult); - } } void @@ -137,10 +120,6 @@ DOMRequest::FireError(const nsAString& aError) mError = new DOMError(GetOwner(), aError); FireEvent(NS_LITERAL_STRING("error"), true, true); - - if (mPromise) { - mPromise->MaybeRejectBrokenly(mError); - } } void @@ -154,10 +133,6 @@ DOMRequest::FireError(nsresult aError) mError = new DOMError(GetOwner(), aError); FireEvent(NS_LITERAL_STRING("error"), true, true); - - if (mPromise) { - mPromise->MaybeRejectBrokenly(mError); - } } void @@ -172,10 +147,6 @@ DOMRequest::FireDetailedError(DOMError* aError) mError = aError; FireEvent(NS_LITERAL_STRING("error"), true, true); - - if (mPromise) { - mPromise->MaybeRejectBrokenly(mError); - } } void @@ -204,31 +175,6 @@ DOMRequest::RootResultVal() mozilla::HoldJSObjects(this); } -already_AddRefed -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 @@ -307,7 +253,7 @@ public: const JS::Value& aResult) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - mozilla::ThreadsafeAutoSafeJSContext cx; + AutoSafeJSContext cx; nsRefPtr asyncTask = new FireSuccessAsyncTask(cx, aRequest, aResult); if (NS_FAILED(NS_DispatchToMainThread(asyncTask))) { NS_WARNING("Failed to dispatch to main thread!"); diff --git a/dom/base/DOMRequest.h b/dom/base/DOMRequest.h index 56236c156779..cd19dc02adca 100644 --- a/dom/base/DOMRequest.h +++ b/dom/base/DOMRequest.h @@ -16,21 +16,14 @@ #include "nsCOMPtr.h" namespace mozilla { - -class ErrorResult; - namespace dom { -class AnyCallback; -class Promise; - class DOMRequest : public DOMEventTargetHelper, public nsIDOMDOMRequest { protected: JS::Heap mResult; nsRefPtr mError; - nsRefPtr mPromise; bool mDone; public: @@ -74,9 +67,6 @@ public: IMPL_EVENT_HANDLER(success) IMPL_EVENT_HANDLER(error) - already_AddRefed - Then(JSContext* aCx, AnyCallback* aResolveCallback, - AnyCallback* aRejectCallback, mozilla::ErrorResult& aRv); void FireSuccess(JS::Handle aResult); void FireError(const nsAString& aError); @@ -86,7 +76,11 @@ public: explicit DOMRequest(nsPIDOMWindow* aWindow); protected: - virtual ~DOMRequest(); + virtual ~DOMRequest() + { + mResult = JSVAL_VOID; + mozilla::DropJSObjects(this); + } void FireEvent(const nsAString& aType, bool aBubble, bool aCancelable); diff --git a/dom/base/test/test_domcursor.html b/dom/base/test/test_domcursor.html index d33581f124e6..bb975a67f373 100644 --- a/dom/base/test/test_domcursor.html +++ b/dom/base/test/test_domcursor.html @@ -51,7 +51,6 @@ var tests = [ 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"); diff --git a/dom/base/test/test_domrequest.html b/dom/base/test/test_domrequest.html index 85636ba52972..0620ad52b1e7 100644 --- a/dom/base/test/test_domrequest.html +++ b/dom/base/test/test_domrequest.html @@ -17,212 +17,59 @@ 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"); +// 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"); - 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"); +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(); +// fire success +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"); -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"); +// 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 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"); -} - -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(); - +// 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"); diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index ed41c3d9e9a9..dcd93b3835e8 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -352,10 +352,6 @@ DOMInterfaces = { 'headerFile': 'mozilla/dom/DOMRect.h', }, -'DOMRequest': { - 'implicitJSContext': [ 'then' ], -}, - 'DOMSettableTokenList': { 'nativeType': 'nsDOMSettableTokenList', }, diff --git a/dom/bindings/ToJSValue.h b/dom/bindings/ToJSValue.h index 415a411dd92a..1f365ddde360 100644 --- a/dom/bindings/ToJSValue.h +++ b/dom/bindings/ToJSValue.h @@ -236,24 +236,6 @@ ToJSValue(JSContext* aCx, JS::Handle 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 aArgument, - JS::MutableHandle 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 aArgument, - JS::MutableHandle aValue) -{ - aValue.set(aArgument); - return MaybeWrapValue(aCx, aValue); -} - // Accept nsresult, for use in rejections, and create an XPCOM // exception object representing that nsresult. bool diff --git a/dom/telephony/test/marionette/head.js b/dom/telephony/test/marionette/head.js index 059b3a2542f6..ea7ea2933ef6 100644 --- a/dom/telephony/test/marionette/head.js +++ b/dom/telephony/test/marionette/head.js @@ -1316,8 +1316,17 @@ 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); }); diff --git a/dom/webidl/DOMCursor.webidl b/dom/webidl/DOMCursor.webidl index 3ad36a76fa1a..b18a75539bdf 100644 --- a/dom/webidl/DOMCursor.webidl +++ b/dom/webidl/DOMCursor.webidl @@ -3,10 +3,8 @@ * 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; diff --git a/dom/webidl/DOMRequest.webidl b/dom/webidl/DOMRequest.webidl index 039446904563..a93704bd2211 100644 --- a/dom/webidl/DOMRequest.webidl +++ b/dom/webidl/DOMRequest.webidl @@ -5,8 +5,7 @@ enum DOMRequestReadyState { "pending", "done" }; -[NoInterfaceObject] -interface DOMRequestShared { +interface DOMRequest : EventTarget { readonly attribute DOMRequestReadyState readyState; readonly attribute any result; @@ -15,13 +14,3 @@ interface DOMRequestShared { 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 then([TreatNonCallableAsNull] optional AnyCallback? fulfillCallback = null, - [TreatNonCallableAsNull] optional AnyCallback? rejectCallback = null); -}; - -DOMRequest implements DOMRequestShared; diff --git a/js/public/RootingAPI.h b/js/public/RootingAPI.h index bc0277c66b29..275d06005c26 100644 --- a/js/public/RootingAPI.h +++ b/js/public/RootingAPI.h @@ -220,7 +220,7 @@ class Heap : public js::HeapBase * that will be used for both lvalue and rvalue copies, so we can simply * omit the rvalue variant. */ - Heap(const Heap &p) { init(p.ptr); } + explicit Heap(const Heap &p) { init(p.ptr); } ~Heap() { if (js::GCMethods::needsPostBarrier(ptr))