Bug 1167650 - Expose DOMRequest and DOMCursor to workers. r=bent
authorAndrew Osmond <aosmond@mozilla.com>
Sun, 28 Jun 2015 09:34:01 -0700
changeset 268439 3723cf728d14127f9385b313bfcb27d95161704c
parent 268438 0ce16dc79b095d64ef2c53e96d9f529c910601d3
child 268440 206cd948c1d8060e8da40c89ec9ac29ac0f446bd
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-esr52@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent
bugs1167650
milestone41.0a1
Bug 1167650 - Expose DOMRequest and DOMCursor to workers. r=bent
dom/base/DOMCursor.cpp
dom/base/DOMCursor.h
dom/base/DOMRequest.cpp
dom/base/DOMRequest.h
dom/webidl/DOMCursor.webidl
dom/webidl/DOMRequest.webidl
dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
dom/workers/test/test_worker_interfaces.js
--- a/dom/base/DOMCursor.cpp
+++ b/dom/base/DOMCursor.cpp
@@ -22,16 +22,23 @@ NS_IMPL_RELEASE_INHERITED(DOMCursor, DOM
 
 DOMCursor::DOMCursor(nsPIDOMWindow* aWindow, nsICursorContinueCallback* aCallback)
   : DOMRequest(aWindow)
   , mCallback(aCallback)
   , mFinished(false)
 {
 }
 
+DOMCursor::DOMCursor(nsIGlobalObject* aGlobal, nsICursorContinueCallback* aCallback)
+  : DOMRequest(aGlobal)
+  , mCallback(aCallback)
+  , mFinished(false)
+{
+}
+
 void
 DOMCursor::Reset()
 {
   MOZ_ASSERT(!mFinished);
 
   // Reset the request state so we can FireSuccess() again.
   mResult.setUndefined();
   mDone = false;
--- a/dom/base/DOMCursor.h
+++ b/dom/base/DOMCursor.h
@@ -21,16 +21,17 @@ class DOMCursor : public DOMRequest
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDOMCURSOR
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMCursor,
                                            DOMRequest)
 
   DOMCursor(nsPIDOMWindow* aWindow, nsICursorContinueCallback *aCallback);
+  DOMCursor(nsIGlobalObject* aGlobal, nsICursorContinueCallback *aCallback);
 
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   bool Done() const
   {
     return mFinished;
   }
   virtual void Continue(ErrorResult& aRv);
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -15,26 +15,33 @@
 #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;
+using mozilla::dom::AutoJSAPI;
 
 DOMRequest::DOMRequest(nsPIDOMWindow* aWindow)
   : DOMEventTargetHelper(aWindow->IsInnerWindow() ?
                            aWindow : aWindow->GetCurrentInnerWindow())
   , mResult(JS::UndefinedValue())
   , mDone(false)
 {
 }
 
+DOMRequest::DOMRequest(nsIGlobalObject* aGlobal)
+  : DOMEventTargetHelper(aGlobal)
+  , mResult(JS::UndefinedValue())
+  , mDone(false)
+{
+}
+
 DOMRequest::~DOMRequest()
 {
   mResult.setUndefined();
   mozilla::DropJSObjects(this);
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(DOMRequest)
 
@@ -230,16 +237,17 @@ DOMRequest::Then(JSContext* aCx, AnyCall
 }
 
 NS_IMPL_ISUPPORTS(DOMRequestService, nsIDOMRequestService)
 
 NS_IMETHODIMP
 DOMRequestService::CreateRequest(nsIDOMWindow* aWindow,
                                  nsIDOMDOMRequest** aRequest)
 {
+  MOZ_ASSERT(NS_IsMainThread());
   nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(aWindow));
   NS_ENSURE_STATE(win);
   NS_ADDREF(*aRequest = new DOMRequest(win));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -301,38 +309,29 @@ 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;
     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;
-    }
+    MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToCurrentThread(asyncTask)));
     return NS_OK;
   }
 
   NS_IMETHODIMP
   Run()
   {
     mReq->FireSuccess(JS::Handle<JS::Value>::fromMarkedLocation(mResult.address()));
     return NS_OK;
   }
 
-  ~FireSuccessAsyncTask()
-  {
-    NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-  }
-
 private:
   nsRefPtr<DOMRequest> mReq;
   JS::PersistentRooted<JS::Value> mResult;
 };
 
 class FireErrorAsyncTask : public nsRunnable
 {
 public:
@@ -364,20 +363,17 @@ DOMRequestService::FireSuccessAsync(nsID
 
 NS_IMETHODIMP
 DOMRequestService::FireErrorAsync(nsIDOMDOMRequest* aRequest,
                                   const nsAString& aError)
 {
   NS_ENSURE_STATE(aRequest);
   nsCOMPtr<nsIRunnable> asyncTask =
     new FireErrorAsyncTask(static_cast<DOMRequest*>(aRequest), aError);
-  if (NS_FAILED(NS_DispatchToMainThread(asyncTask))) {
-    NS_WARNING("Failed to dispatch to main thread!");
-    return NS_ERROR_FAILURE;
-  }
+  MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToCurrentThread(asyncTask)));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DOMRequestService::FireDone(nsIDOMDOMCursor* aCursor) {
   NS_ENSURE_STATE(aCursor);
   static_cast<DOMCursor*>(aCursor)->FireDone();
 
--- a/dom/base/DOMRequest.h
+++ b/dom/base/DOMRequest.h
@@ -79,16 +79,17 @@ public:
        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);
+  explicit DOMRequest(nsIGlobalObject* aGlobal);
 
 protected:
   virtual ~DOMRequest();
 
   void FireEvent(const nsAString& aType, bool aBubble, bool aCancelable);
 
   void RootResultVal();
 };
--- a/dom/webidl/DOMCursor.webidl
+++ b/dom/webidl/DOMCursor.webidl
@@ -1,12 +1,13 @@
 /* -*- 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/. */
 
+[Exposed=(Window,Worker)]
 interface DOMCursor : EventTarget {
   readonly attribute boolean done;
   [Throws]
   void continue();
 };
 
 DOMCursor implements DOMRequestShared;
--- a/dom/webidl/DOMRequest.webidl
+++ b/dom/webidl/DOMRequest.webidl
@@ -1,26 +1,27 @@
 /* -*- 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]
+[Exposed=(Window,Worker), NoInterfaceObject]
 interface DOMRequestShared {
   readonly attribute DOMRequestReadyState readyState;
 
   readonly attribute any result;
   readonly attribute DOMError? error;
 
   attribute EventHandler onsuccess;
   attribute EventHandler onerror;
 };
 
+[Exposed=(Window,Worker)]
 interface DOMRequest : EventTarget {
   // The [TreatNonCallableAsNull] annotation is required since then() should do
   // nothing instead of throwing errors when non-callable arguments are passed.
   [NewObject]
   Promise<any> then([TreatNonCallableAsNull] optional AnyCallback? fulfillCallback = null,
                     [TreatNonCallableAsNull] optional AnyCallback? rejectCallback = null);
 };
 
--- a/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
+++ b/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
@@ -98,20 +98,24 @@ var interfaceNamesInGlobalScope =
     "Client",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Clients",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     { name: "DataStore", b2g: true },
 // IMPORTANT: Do not change this list without review from a DOM peer!
     { name: "DataStoreCursor", b2g: true },
 // IMPORTANT: Do not change this list without review from a DOM peer!
+    "DOMCursor",
+// IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMError",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMException",
 // IMPORTANT: Do not change this list without review from a DOM peer!
+    "DOMRequest",
+// IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMStringList",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Event",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "EventTarget",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "ExtendableEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
--- a/dom/workers/test/test_worker_interfaces.js
+++ b/dom/workers/test/test_worker_interfaces.js
@@ -94,20 +94,24 @@ var interfaceNamesInGlobalScope =
     { name: "CacheStorage", release: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DedicatedWorkerGlobalScope",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     { name: "DataStore", b2g: true },
 // IMPORTANT: Do not change this list without review from a DOM peer!
     { name: "DataStoreCursor", b2g: true },
 // IMPORTANT: Do not change this list without review from a DOM peer!
+    "DOMCursor",
+// IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMError",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMException",
 // IMPORTANT: Do not change this list without review from a DOM peer!
+    "DOMRequest",
+// IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMStringList",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Event",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "EventTarget",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "File",
 // IMPORTANT: Do not change this list without review from a DOM peer!