Bug 888596 - Move IDBDatabase to WebIDL, r=janv
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 31 Jul 2013 17:48:46 +0200
changeset 153074 9f455064253542311a0f971eb7e9c2698cccc733
parent 153073 afac636489dee5201f001d2c7153e24120856540
child 153075 ff70392e847d790644db8acad0931623fdc77ddc
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjanv
bugs888596
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 888596 - Move IDBDatabase to WebIDL, r=janv
addon-sdk/source/lib/sdk/indexed-db.js
addon-sdk/source/test/test-indexed-db.js
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/bindings/Bindings.conf
dom/indexedDB/AsyncConnectionHelper.cpp
dom/indexedDB/IDBDatabase.cpp
dom/indexedDB/IDBDatabase.h
dom/indexedDB/IDBFileHandle.cpp
dom/indexedDB/IDBFileHandle.h
dom/indexedDB/IDBTransaction.cpp
dom/indexedDB/IDBTransaction.h
dom/indexedDB/OpenDatabaseHelper.cpp
dom/indexedDB/ipc/IndexedDBChild.cpp
dom/indexedDB/ipc/IndexedDBParent.cpp
dom/indexedDB/moz.build
dom/indexedDB/nsIIDBDatabase.idl
dom/indexedDB/test/browser_permissionsPromptAllow.js
dom/indexedDB/test/browser_perwindow_privateBrowsing.js
dom/indexedDB/test/unit/head.js
dom/quota/nsIOfflineStorage.h
dom/webidl/DummyBinding.webidl
dom/webidl/IDBDatabase.webidl
dom/webidl/IDBFileHandle.webidl
dom/webidl/IDBObjectStore.webidl
js/xpconnect/src/dom_quickstubs.qsconf
--- a/addon-sdk/source/lib/sdk/indexed-db.js
+++ b/addon-sdk/source/lib/sdk/indexed-db.js
@@ -50,10 +50,9 @@ exports.indexedDB = Object.freeze({
   deleteDatabase: indexedDB.deleteForPrincipal.bind(indexedDB, principal),
   cmp: indexedDB.cmp
 });
 
 exports.IDBKeyRange = IDBKeyRange;
 exports.DOMException = Ci.nsIDOMDOMException;
 exports.IDBCursor = Ci.nsIIDBCursor;
 exports.IDBOpenDBRequest = Ci.nsIIDBOpenDBRequest;
-exports.IDBDatabase = Ci.nsIIDBDatabase;
 exports.IDBRequest = Ci.nsIIDBRequest;
--- a/addon-sdk/source/test/test-indexed-db.js
+++ b/addon-sdk/source/test/test-indexed-db.js
@@ -4,32 +4,31 @@
 
 "use strict";
 
 let xulApp = require("sdk/system/xul-app");
 if (xulApp.versionInRange(xulApp.platformVersion, "16.0a1", "*")) {
 new function tests() {
 
 const { indexedDB, IDBKeyRange, DOMException, IDBCursor,
-        IDBOpenDBRequest, IDBDatabase, IDBRequest
+        IDBOpenDBRequest, IDBRequest
       } = require("sdk/indexed-db");
 
 exports["test indexedDB is frozen"] = function(assert){
   let original = indexedDB.open;
   let f = function(){};
   assert.throws(function(){indexedDB.open = f});
   assert.equal(indexedDB.open,original);
   assert.notEqual(indexedDB.open,f);
 
 };
 
 exports["test db variables"] = function(assert) {
   [ indexedDB, IDBKeyRange, DOMException, IDBCursor,
-    IDBOpenDBRequest, IDBOpenDBRequest, IDBDatabase,
-    IDBRequest
+    IDBOpenDBRequest, IDBOpenDBRequest, IDBRequest
   ].forEach(function(value) {
     assert.notEqual(typeof(value), "undefined", "variable is defined");
   });
 }
 
 exports["test open"] = function(assert, done) {
   let request = indexedDB.open("MyTestDatabase");
   request.onerror = function(event) {
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -198,17 +198,16 @@
 #include "nsDOMFile.h"
 
 #include "nsIEventListenerService.h"
 #include "nsIMessageManager.h"
 #include "mozilla/dom/Element.h"
 
 #include "mozilla/dom/indexedDB/IDBWrapperCache.h"
 #include "mozilla/dom/indexedDB/IDBRequest.h"
-#include "mozilla/dom/indexedDB/IDBDatabase.h"
 #include "mozilla/dom/indexedDB/IDBCursor.h"
 #include "mozilla/dom/indexedDB/IDBKeyRange.h"
 
 using mozilla::dom::indexedDB::IDBWrapperCache;
 using mozilla::dom::workers::ResolveWorkerClasses;
 
 #include "nsIDOMMediaQueryList.h"
 
@@ -629,18 +628,16 @@ static nsDOMClassInfoData sClassInfoData
                                        nsIXPCScriptable::IS_GLOBAL_OBJECT)
   NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageBroadcaster, nsDOMGenericSH,
                                        DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageSender, nsDOMGenericSH,
                                        DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(IDBRequest, IDBEventTargetSH,
                            IDBEVENTTARGET_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(IDBDatabase, IDBEventTargetSH,
-                           IDBEVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBCursor, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBCursorWithValue, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBKeyRange, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBOpenDBRequest, IDBEventTargetSH,
                            IDBEVENTTARGET_SCRIPTABLE_FLAGS)
@@ -1530,21 +1527,16 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_MAP_ENTRY(nsIMessageSender)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(IDBRequest, nsIIDBRequest)
     DOM_CLASSINFO_MAP_ENTRY(nsIIDBRequest)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(IDBDatabase, nsIIDBDatabase)
-    DOM_CLASSINFO_MAP_ENTRY(nsIIDBDatabase)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
-  DOM_CLASSINFO_MAP_END
-
   DOM_CLASSINFO_MAP_BEGIN(IDBCursor, nsIIDBCursor)
     DOM_CLASSINFO_MAP_ENTRY(nsIIDBCursor)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(IDBCursorWithValue, nsIIDBCursorWithValue)
     DOM_CLASSINFO_MAP_ENTRY(nsIIDBCursor)
     DOM_CLASSINFO_MAP_ENTRY(nsIIDBCursorWithValue)
   DOM_CLASSINFO_MAP_END
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -115,17 +115,16 @@ DOMCI_CLASS(DataTransfer)
 
 DOMCI_CLASS(EventListenerInfo)
 
 DOMCI_CLASS(ContentFrameMessageManager)
 DOMCI_CLASS(ChromeMessageBroadcaster)
 DOMCI_CLASS(ChromeMessageSender)
 
 DOMCI_CLASS(IDBRequest)
-DOMCI_CLASS(IDBDatabase)
 DOMCI_CLASS(IDBCursor)
 DOMCI_CLASS(IDBCursorWithValue)
 DOMCI_CLASS(IDBKeyRange)
 DOMCI_CLASS(IDBOpenDBRequest)
 
 
 DOMCI_CLASS(MozCSSKeyframeRule)
 DOMCI_CLASS(MozCSSKeyframesRule)
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -533,16 +533,20 @@ DOMInterfaces = {
         'sheet'
     ]
 },
 
 'HTMLUListElement': {
     'nativeType' : 'mozilla::dom::HTMLSharedListElement'
 },
 
+'IDBDatabase': {
+    'nativeType': 'mozilla::dom::indexedDB::IDBDatabase',
+},
+
 'IDBFactory': {
     'nativeType': 'mozilla::dom::indexedDB::IDBFactory',
 },
 
 'IDBFileHandle': {
     'nativeType': 'mozilla::dom::indexedDB::IDBFileHandle',
 },
 
@@ -1670,17 +1674,16 @@ addExternalIface('DeviceRotationRate', h
 addExternalIface('mozIDOMApplication', nativeType='mozIDOMApplication', headerFile='nsIDOMApplicationRegistry.h')
 addExternalIface('CSSRuleList')
 addExternalIface('DOMStringList')
 addExternalIface('RTCDataChannel', nativeType='nsIDOMDataChannel')
 addExternalIface('File')
 addExternalIface('FileCallback', nativeType='nsIFileCallback',
                  headerFile='nsIDOMHTMLCanvasElement.h')
 addExternalIface('HitRegionOptions', nativeType='nsISupports')
-addExternalIface('IDBDatabase', nativeType='nsIIDBDatabase')
 addExternalIface('IDBOpenDBRequest', nativeType='nsIIDBOpenDBRequest')
 addExternalIface('IDBRequest', nativeType='nsIIDBRequest')
 addExternalIface('imgINotificationObserver', nativeType='imgINotificationObserver')
 addExternalIface('imgIRequest', nativeType='imgIRequest', notflattened=True)
 addExternalIface('LockedFile')
 addExternalIface('MediaList')
 addExternalIface('MenuBuilder', nativeType='nsIMenuBuilder', notflattened=True)
 addExternalIface('MozBluetoothManager', nativeType='nsIDOMBluetoothManager')
--- a/dom/indexedDB/AsyncConnectionHelper.cpp
+++ b/dom/indexedDB/AsyncConnectionHelper.cpp
@@ -168,17 +168,17 @@ AsyncConnectionHelper::~AsyncConnectionH
     mTransaction.forget(&transaction);
 
     nsCOMPtr<nsIThread> mainThread;
     NS_GetMainThread(getter_AddRefs(mainThread));
     NS_WARN_IF_FALSE(mainThread, "Couldn't get the main thread!");
 
     if (mainThread) {
       if (database) {
-        NS_ProxyRelease(mainThread, static_cast<nsIIDBDatabase*>(database));
+        NS_ProxyRelease(mainThread, static_cast<IDBWrapperCache*>(database));
       }
       if (transaction) {
         NS_ProxyRelease(mainThread, static_cast<IDBWrapperCache*>(transaction));
       }
     }
   }
 
   NS_ASSERTION(!mOldProgressHandler, "Should not have anything here!");
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -38,16 +38,17 @@
 
 #include "mozilla/dom/IDBDatabaseBinding.h"
 
 USING_INDEXEDDB_NAMESPACE
 using mozilla::dom::ContentParent;
 using mozilla::dom::quota::AssertIsOnIOThread;
 using mozilla::dom::quota::Client;
 using mozilla::dom::quota::QuotaManager;
+using mozilla::ErrorResult;
 using namespace mozilla::dom;
 
 namespace {
 
 class NoRequestDatabaseHelper : public AsyncConnectionHelper
 {
 public:
   NoRequestDatabaseHelper(IDBTransaction* aTransaction)
@@ -233,16 +234,18 @@ IDBDatabase::IDBDatabase()
   mActorParent(nullptr),
   mContentParent(nullptr),
   mInvalidated(false),
   mRegistered(false),
   mClosed(false),
   mRunningVersionChange(false)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+  SetIsDOMBinding();
 }
 
 IDBDatabase::~IDBDatabase()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 }
 
 void
@@ -396,422 +399,342 @@ IDBDatabase::OnUnlink()
   if (quotaManager) {
     quotaManager->UnregisterStorage(this);
 
     // Don't try to unregister again in the destructor.
     mRegistered = false;
   }
 }
 
-nsresult
+already_AddRefed<IDBObjectStore>
 IDBDatabase::CreateObjectStoreInternal(IDBTransaction* aTransaction,
                                        const ObjectStoreInfoGuts& aInfo,
-                                       IDBObjectStore** _retval)
+                                       ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(aTransaction, "Null transaction!");
 
   DatabaseInfo* databaseInfo = aTransaction->DBInfo();
 
   nsRefPtr<ObjectStoreInfo> newInfo = new ObjectStoreInfo();
   *static_cast<ObjectStoreInfoGuts*>(newInfo.get()) = aInfo;
 
   newInfo->nextAutoIncrementId = aInfo.autoIncrement ? 1 : 0;
   newInfo->comittedAutoIncrementId = newInfo->nextAutoIncrementId;
 
   if (!databaseInfo->PutObjectStore(newInfo)) {
     NS_WARNING("Put failed!");
-    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
   }
 
   // Don't leave this in the hash if we fail below!
   AutoRemoveObjectStore autoRemove(databaseInfo, newInfo->name);
 
   nsRefPtr<IDBObjectStore> objectStore =
     aTransaction->GetOrCreateObjectStore(newInfo->name, newInfo, true);
-  NS_ENSURE_TRUE(objectStore, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  if (!objectStore) {
+    NS_WARNING("Failed to get objectStore!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
   if (IndexedDatabaseManager::IsMainProcess()) {
     nsRefPtr<CreateObjectStoreHelper> helper =
       new CreateObjectStoreHelper(aTransaction, objectStore);
 
     nsresult rv = helper->DispatchToTransactionPool();
-    NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    if (NS_FAILED(rv)) {
+      NS_WARNING("Failed to dispatch!");
+      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+      return nullptr;
+    }
   }
 
   autoRemove.forget();
 
   IDB_PROFILER_MARK("IndexedDB Pseudo-request: "
                     "database(%s).transaction(%s).createObjectStore(%s)",
                     "MT IDBDatabase.createObjectStore()",
                     IDB_PROFILER_STRING(this),
                     IDB_PROFILER_STRING(aTransaction),
                     IDB_PROFILER_STRING(objectStore));
 
-  objectStore.forget(_retval);
-
-  return NS_OK;
+  return objectStore.forget();
 }
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBDatabase, IDBWrapperCache)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFactory)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBDatabase, IDBWrapperCache)
   // Don't unlink mFactory!
 
   // Do some cleanup.
   tmp->OnUnlink();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBDatabase)
-  NS_INTERFACE_MAP_ENTRY(nsIIDBDatabase)
   NS_INTERFACE_MAP_ENTRY(nsIFileStorage)
   NS_INTERFACE_MAP_ENTRY(nsIOfflineStorage)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBDatabase)
 NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache)
 
 NS_IMPL_ADDREF_INHERITED(IDBDatabase, IDBWrapperCache)
 NS_IMPL_RELEASE_INHERITED(IDBDatabase, IDBWrapperCache)
 
-DOMCI_DATA(IDBDatabase, IDBDatabase)
-
-NS_IMPL_EVENT_HANDLER(IDBDatabase, abort)
-NS_IMPL_EVENT_HANDLER(IDBDatabase, error)
-NS_IMPL_EVENT_HANDLER(IDBDatabase, versionchange)
-
-NS_IMETHODIMP
-IDBDatabase::GetName(nsAString& aName)
+JSObject*
+IDBDatabase::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
 {
-  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-  aName.Assign(mName);
-  return NS_OK;
+  return IDBDatabaseBinding::Wrap(aCx, aScope, this);
 }
 
-NS_IMETHODIMP
-IDBDatabase::GetVersion(uint64_t* aVersion)
+uint64_t
+IDBDatabase::Version() const
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-
   DatabaseInfo* info = Info();
-  *aVersion = info->version;
-
-  return NS_OK;
+  return info->version;
 }
 
-NS_IMETHODIMP
-IDBDatabase::GetObjectStoreNames(nsIDOMDOMStringList** aObjectStores)
+already_AddRefed<nsIDOMDOMStringList>
+IDBDatabase::GetObjectStoreNames(ErrorResult& aRv) const
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   DatabaseInfo* info = Info();
 
   nsAutoTArray<nsString, 10> objectStoreNames;
   if (!info->GetObjectStoreNames(objectStoreNames)) {
     NS_WARNING("Couldn't get names!");
-    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
   }
 
   nsRefPtr<nsDOMStringList> list(new nsDOMStringList());
   uint32_t count = objectStoreNames.Length();
   for (uint32_t index = 0; index < count; index++) {
-    NS_ENSURE_TRUE(list->Add(objectStoreNames[index]),
-                   NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    if (!list->Add(objectStoreNames[index])) {
+      NS_WARNING("Failed to add element");
+      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+      return nullptr;
+    }
   }
 
-  list.forget(aObjectStores);
-  return NS_OK;
+  return list.forget();
 }
 
-NS_IMETHODIMP
-IDBDatabase::CreateObjectStore(const nsAString& aName,
-                               const jsval& aOptions,
-                               JSContext* aCx,
-                               nsISupports** _retval)
+already_AddRefed<IDBObjectStore>
+IDBDatabase::CreateObjectStore(
+                            JSContext* aCx, const nsAString& aName,
+                            const IDBObjectStoreParameters& aOptionalParameters,
+                            ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   IDBTransaction* transaction = AsyncConnectionHelper::GetCurrentTransaction();
 
   if (!transaction ||
       transaction->GetMode() != IDBTransaction::VERSION_CHANGE) {
-    return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return nullptr;
   }
 
   DatabaseInfo* databaseInfo = transaction->DBInfo();
 
-  RootedDictionary<IDBObjectStoreParameters> params(aCx);
-  JS::Rooted<JS::Value> options(aCx, aOptions);
-  if (!params.Init(aCx, options)) {
-    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
-  }
-
   KeyPath keyPath(0);
-  if (NS_FAILED(KeyPath::Parse(aCx, params.mKeyPath, &keyPath))) {
-    return NS_ERROR_DOM_SYNTAX_ERR;
+  if (NS_FAILED(KeyPath::Parse(aCx, aOptionalParameters.mKeyPath, &keyPath))) {
+    aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+    return nullptr;
   }
 
   if (databaseInfo->ContainsStoreName(aName)) {
-    return NS_ERROR_DOM_INDEXEDDB_CONSTRAINT_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_CONSTRAINT_ERR);
+    return nullptr;
   }
 
-  if (!keyPath.IsAllowedForObjectStore(params.mAutoIncrement)) {
-    return NS_ERROR_DOM_INVALID_ACCESS_ERR;
+  if (!keyPath.IsAllowedForObjectStore(aOptionalParameters.mAutoIncrement)) {
+    aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
+    return nullptr;
   }
 
   ObjectStoreInfoGuts guts;
 
   guts.name = aName;
   guts.id = databaseInfo->nextObjectStoreId++;
   guts.keyPath = keyPath;
-  guts.autoIncrement = params.mAutoIncrement;
+  guts.autoIncrement = aOptionalParameters.mAutoIncrement;
 
-  nsRefPtr<IDBObjectStore> objectStore;
-  nsresult rv = CreateObjectStoreInternal(transaction, guts,
-                                          getter_AddRefs(objectStore));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  objectStore.forget(_retval);
-  return NS_OK;
+  return CreateObjectStoreInternal(transaction, guts, aRv);
 }
 
-NS_IMETHODIMP
-IDBDatabase::DeleteObjectStore(const nsAString& aName)
+void
+IDBDatabase::DeleteObjectStore(const nsAString& aName, ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   IDBTransaction* transaction = AsyncConnectionHelper::GetCurrentTransaction();
 
   if (!transaction ||
       transaction->GetMode() != IDBTransaction::VERSION_CHANGE) {
-    return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return;
   }
 
   DatabaseInfo* info = transaction->DBInfo();
   ObjectStoreInfo* objectStoreInfo = info->GetObjectStore(aName);
   if (!objectStoreInfo) {
-    return NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR);
+    return;
   }
 
-  nsresult rv;
-
   if (IndexedDatabaseManager::IsMainProcess()) {
     nsRefPtr<DeleteObjectStoreHelper> helper =
       new DeleteObjectStoreHelper(transaction, objectStoreInfo->id);
 
-    rv = helper->DispatchToTransactionPool();
-    NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    nsresult rv = helper->DispatchToTransactionPool();
+    if (NS_FAILED(rv)) {
+      NS_WARNING("Failed to dispatch!");
+      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+      return;
+    }
   }
   else {
     IndexedDBTransactionChild* actor = transaction->GetActorChild();
     NS_ASSERTION(actor, "Must have an actor here!");
 
     actor->SendDeleteObjectStore(nsString(aName));
   }
 
   transaction->RemoveObjectStore(aName);
 
   IDB_PROFILER_MARK("IndexedDB Pseudo-request: "
                     "database(%s).transaction(%s).deleteObjectStore(\"%s\")",
                     "MT IDBDatabase.deleteObjectStore()",
                     IDB_PROFILER_STRING(this),
                     IDB_PROFILER_STRING(transaction),
                     NS_ConvertUTF16toUTF8(aName).get());
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-IDBDatabase::Transaction(const jsval& aStoreNames,
-                         const nsAString& aMode,
-                         JSContext* aCx,
-                         uint8_t aOptionalArgCount,
-                         nsISupports** _retval)
+already_AddRefed<indexedDB::IDBTransaction>
+IDBDatabase::Transaction(const Sequence<nsString>& aStoreNames,
+                         IDBTransactionMode aMode, ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (QuotaManager::IsShuttingDown()) {
-    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
   }
 
   if (mClosed) {
-    return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return nullptr;
   }
 
   if (mRunningVersionChange) {
-    return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return nullptr;
+  }
+
+  if (aStoreNames.IsEmpty()) {
+    aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
+    return nullptr;
   }
 
   IDBTransaction::Mode transactionMode = IDBTransaction::READ_ONLY;
-  if (aOptionalArgCount) {
-    if (aMode.EqualsLiteral("readwrite")) {
+  switch (aMode) {
+    case IDBTransactionMode::Readonly:
+      transactionMode = IDBTransaction::READ_ONLY;
+      break;
+    case IDBTransactionMode::Readwrite:
       transactionMode = IDBTransaction::READ_WRITE;
-    }
-    else if (!aMode.EqualsLiteral("readonly")) {
-      return NS_ERROR_TYPE_ERR;
-    }
-  }
-
-  nsresult rv;
-  nsTArray<nsString> storesToOpen;
-
-  if (!JSVAL_IS_PRIMITIVE(aStoreNames)) {
-    JS::Rooted<JSObject*> obj(aCx, JSVAL_TO_OBJECT(aStoreNames));
-
-    // See if this is a JS array.
-    if (JS_IsArrayObject(aCx, obj)) {
-      uint32_t length;
-      if (!JS_GetArrayLength(aCx, obj, &length)) {
-        return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
-      }
-
-      if (!length) {
-        return NS_ERROR_DOM_INVALID_ACCESS_ERR;
-      }
-
-      storesToOpen.SetCapacity(length);
-
-      for (uint32_t index = 0; index < length; index++) {
-        JS::Rooted<JS::Value> val(aCx);
-        JSString* jsstr;
-        nsDependentJSString str;
-        if (!JS_GetElement(aCx, obj, index, val.address()) ||
-            !(jsstr = JS_ValueToString(aCx, val)) ||
-            !str.init(aCx, jsstr)) {
-          return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
-        }
-
-        storesToOpen.AppendElement(str);
-      }
-
-      NS_ASSERTION(!storesToOpen.IsEmpty(),
-                   "Must have something here or else code below will "
-                   "misbehave!");
-    }
-    else {
-      // Perhaps some kind of wrapped object?
-      nsIXPConnect* xpc = nsContentUtils::XPConnect();
-      NS_ASSERTION(xpc, "This should never be null!");
-
-      nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
-      rv = xpc->GetWrappedNativeOfJSObject(aCx, obj, getter_AddRefs(wrapper));
-      NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
-
-      if (wrapper) {
-        nsISupports* wrappedObject = wrapper->Native();
-        NS_ENSURE_TRUE(wrappedObject, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
-
-        // We only accept DOMStringList.
-        nsCOMPtr<nsIDOMDOMStringList> list = do_QueryInterface(wrappedObject);
-        if (list) {
-          uint32_t length;
-          rv = list->GetLength(&length);
-          NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
-
-          if (!length) {
-            return NS_ERROR_DOM_INVALID_ACCESS_ERR;
-          }
-
-          storesToOpen.SetCapacity(length);
-
-          for (uint32_t index = 0; index < length; index++) {
-            nsString* item = storesToOpen.AppendElement();
-            NS_ASSERTION(item, "This should never fail!");
-
-            rv = list->Item(index, *item);
-            NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
-          }
-
-          NS_ASSERTION(!storesToOpen.IsEmpty(),
-                       "Must have something here or else code below will "
-                       "misbehave!");
-        }
-      }
-    }
-  }
-
-  // If our list is empty here then the argument must have been an object that
-  // we don't support or a primitive. Either way we convert to a string.
-  if (storesToOpen.IsEmpty()) {
-    JSString* jsstr;
-    nsDependentJSString str;
-    if (!(jsstr = JS_ValueToString(aCx, aStoreNames)) ||
-        !str.init(aCx, jsstr)) {
-      return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
-    }
-
-    storesToOpen.AppendElement(str);
+      break;
+    case IDBTransactionMode::Versionchange:
+      transactionMode = IDBTransaction::VERSION_CHANGE;
+      break;
+    default:
+      MOZ_CRASH("Unknown mode!");
   }
 
   // Now check to make sure the object store names we collected actually exist.
   DatabaseInfo* info = Info();
-  for (uint32_t index = 0; index < storesToOpen.Length(); index++) {
-    if (!info->ContainsStoreName(storesToOpen[index])) {
-      return NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR;
+  for (uint32_t index = 0; index < aStoreNames.Length(); index++) {
+    if (!info->ContainsStoreName(aStoreNames[index])) {
+      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR);
+      return nullptr;
     }
   }
 
   nsRefPtr<IDBTransaction> transaction =
-    IDBTransaction::Create(this, storesToOpen, transactionMode, false);
-  NS_ENSURE_TRUE(transaction, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    IDBTransaction::Create(this, aStoreNames, transactionMode, false);
+  if (!transaction) {
+    NS_WARNING("Failed to create the transaction!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
   IDB_PROFILER_MARK("IndexedDB Transaction %llu: database(%s).transaction(%s)",
                     "IDBTransaction[%llu] MT Started",
                     transaction->GetSerialNumber(), IDB_PROFILER_STRING(this),
                     IDB_PROFILER_STRING(transaction));
 
-  nsRefPtr<IDBWrapperCache> tmp = transaction.get();
-  tmp.forget(_retval);
-  return NS_OK;
+  return transaction.forget();
 }
 
-NS_IMETHODIMP
+already_AddRefed<IDBRequest>
 IDBDatabase::MozCreateFileHandle(const nsAString& aName,
-                                 const nsAString& aType,
-                                 JSContext* aCx,
-                                 nsIIDBRequest** _retval)
+                                 const Optional<nsAString>& aType,
+                                 ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!IndexedDatabaseManager::IsMainProcess()) {
     NS_WARNING("Not supported yet!");
-    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
   }
 
   if (QuotaManager::IsShuttingDown()) {
-    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
   }
 
   if (mClosed) {
-    return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return nullptr;
   }
 
   nsRefPtr<IDBRequest> request = IDBRequest::Create(nullptr, this, nullptr);
 
   nsRefPtr<CreateFileHelper> helper =
-    new CreateFileHelper(this, request, aName, aType);
+    new CreateFileHelper(this, request, aName,
+                         aType.WasPassed() ? aType.Value() : EmptyString());
 
   QuotaManager* quotaManager = QuotaManager::Get();
   NS_ASSERTION(quotaManager, "We should definitely have a manager here");
 
   nsresult rv = helper->Dispatch(quotaManager->IOThread());
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Failed to dispatch!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
 
-  request.forget(_retval);
-  return NS_OK;
+  return request.forget();
 }
 
 NS_IMETHODIMP
 IDBDatabase::Close()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   CloseInternal(false);
 
   NS_ASSERTION(mClosed, "Should have set the closed flag!");
+
   return NS_OK;
 }
 
 NS_IMETHODIMP_(nsIAtom*)
 IDBDatabase::Id()
 {
   return mDatabaseId;
 }
--- a/dom/indexedDB/IDBDatabase.h
+++ b/dom/indexedDB/IDBDatabase.h
@@ -2,27 +2,29 @@
 /* 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_indexeddb_idbdatabase_h__
 #define mozilla_dom_indexeddb_idbdatabase_h__
 
-#include "mozilla/Attributes.h"
 #include "mozilla/dom/indexedDB/IndexedDatabase.h"
 
 #include "nsIDocument.h"
 #include "nsIFileStorage.h"
-#include "nsIIDBDatabase.h"
 #include "nsIOfflineStorage.h"
 
+#include "mozilla/Attributes.h"
+#include "mozilla/dom/IDBObjectStoreBinding.h"
+#include "mozilla/dom/IDBTransactionBinding.h"
 #include "nsDOMEventTargetHelper.h"
 
 #include "mozilla/dom/indexedDB/FileManager.h"
+#include "mozilla/dom/indexedDB/IDBRequest.h"
 #include "mozilla/dom/indexedDB/IDBWrapperCache.h"
 
 class nsIScriptContext;
 class nsPIDOMWindow;
 
 namespace mozilla {
 namespace dom {
 class ContentParent;
@@ -41,28 +43,26 @@ class IDBIndex;
 class IDBObjectStore;
 class IDBTransaction;
 class IndexedDatabaseManager;
 class IndexedDBDatabaseChild;
 class IndexedDBDatabaseParent;
 struct ObjectStoreInfoGuts;
 
 class IDBDatabase : public IDBWrapperCache,
-                    public nsIIDBDatabase,
                     public nsIOfflineStorage
 {
   friend class AsyncConnectionHelper;
   friend class IndexedDatabaseManager;
   friend class IndexedDBDatabaseChild;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIIDBDATABASE
   NS_DECL_NSIFILESTORAGE
-  NS_DECL_NSIOFFLINESTORAGE_NOCLOSE
+  NS_DECL_NSIOFFLINESTORAGE
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBDatabase, IDBWrapperCache)
 
   static already_AddRefed<IDBDatabase>
   Create(IDBWrapperCache* aOwnerCache,
          IDBFactory* aFactory,
          already_AddRefed<DatabaseInfo> aDatabaseInfo,
          const nsACString& aASCIIOrigin,
@@ -151,20 +151,73 @@ public:
   }
 
   mozilla::dom::ContentParent*
   GetContentParent() const
   {
     return mContentParent;
   }
 
-  nsresult
+  already_AddRefed<IDBObjectStore>
   CreateObjectStoreInternal(IDBTransaction* aTransaction,
                             const ObjectStoreInfoGuts& aInfo,
-                            IDBObjectStore** _retval);
+                            ErrorResult& aRv);
+
+  // nsWrapperCache
+  virtual JSObject*
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
+
+  // WebIDL
+  nsPIDOMWindow*
+  GetParentObject() const
+  {
+    return GetOwner();
+  }
+
+  void
+  GetName(nsString& aName) const
+  {
+    NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+    aName.Assign(mName);
+  }
+
+  uint64_t
+  Version() const;
+
+  already_AddRefed<nsIDOMDOMStringList>
+  GetObjectStoreNames(ErrorResult& aRv) const;
+
+  already_AddRefed<IDBObjectStore>
+  CreateObjectStore(JSContext* aCx, const nsAString& aName,
+                    const IDBObjectStoreParameters& aOptionalParameters,
+                    ErrorResult& aRv);
+
+  void
+  DeleteObjectStore(const nsAString& name, ErrorResult& aRv);
+
+  already_AddRefed<indexedDB::IDBTransaction>
+  Transaction(const nsAString& aStoreName, IDBTransactionMode aMode,
+              ErrorResult& aRv)
+  {
+    Sequence<nsString> list;
+    list.AppendElement(aStoreName);
+    return Transaction(list, aMode, aRv);
+  }
+
+  already_AddRefed<indexedDB::IDBTransaction>
+  Transaction(const Sequence<nsString>& aStoreNames, IDBTransactionMode aMode,
+              ErrorResult& aRv);
+
+  IMPL_EVENT_HANDLER(abort)
+  IMPL_EVENT_HANDLER(error)
+  IMPL_EVENT_HANDLER(versionchange)
+
+  already_AddRefed<IDBRequest>
+  MozCreateFileHandle(const nsAString& aName, const Optional<nsAString>& aType,
+                      ErrorResult& aRv);
 
   virtual void LastRelease() MOZ_OVERRIDE;
 private:
   IDBDatabase();
   ~IDBDatabase();
 
   void OnUnlink();
 
--- a/dom/indexedDB/IDBFileHandle.cpp
+++ b/dom/indexedDB/IDBFileHandle.cpp
@@ -101,17 +101,17 @@ IDBFileHandle::CreateFileObject(mozilla:
                                 uint32_t aFileSize)
 {
   nsCOMPtr<nsIDOMFile> file = new mozilla::dom::file::File(
     mName, mType, aFileSize, mFile, aLockedFile, mFileInfo);
 
   return file.forget();
 }
 
-nsIIDBDatabase*
+IDBDatabase*
 IDBFileHandle::Database()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   IDBDatabase* database = static_cast<IDBDatabase*>(mFileStorage.get());
   MOZ_ASSERT(database);
 
   return database;
--- a/dom/indexedDB/IDBFileHandle.h
+++ b/dom/indexedDB/IDBFileHandle.h
@@ -7,19 +7,19 @@
 #ifndef mozilla_dom_indexeddb_idbfilehandle_h__
 #define mozilla_dom_indexeddb_idbfilehandle_h__
 
 #include "IndexedDatabase.h"
 
 #include "mozilla/dom/file/FileHandle.h"
 #include "mozilla/dom/indexedDB/FileInfo.h"
 
-class nsIIDBDatabase;
+BEGIN_INDEXEDDB_NAMESPACE
 
-BEGIN_INDEXEDDB_NAMESPACE
+class IDBDatabase;
 
 class IDBFileHandle : public mozilla::dom::file::FileHandle
 {
 public:
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   NS_IMETHOD_(int64_t)
@@ -40,17 +40,18 @@ public:
 
   virtual already_AddRefed<nsISupports>
   CreateStream(nsIFile* aFile, bool aReadOnly);
 
   virtual already_AddRefed<nsIDOMFile>
   CreateFileObject(mozilla::dom::file::LockedFile* aLockedFile,
                    uint32_t aFileSize);
 
-  nsIIDBDatabase* Database();
+  IDBDatabase*
+  Database();
 
 private:
   IDBFileHandle()
   { }
 
   ~IDBFileHandle()
   { }
 
--- a/dom/indexedDB/IDBTransaction.cpp
+++ b/dom/indexedDB/IDBTransaction.cpp
@@ -87,17 +87,17 @@ NS_IMETHODIMP_(nsrefcnt) StartTransactio
 NS_IMPL_QUERY_INTERFACE1(StartTransactionRunnable, nsIRunnable)
 
 } // anonymous namespace
 
 
 // static
 already_AddRefed<IDBTransaction>
 IDBTransaction::CreateInternal(IDBDatabase* aDatabase,
-                               nsTArray<nsString>& aObjectStoreNames,
+                               const Sequence<nsString>& aObjectStoreNames,
                                Mode aMode,
                                bool aDispatchDelayed,
                                bool aIsVersionChangeTransactionChild)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(IndexedDatabaseManager::IsMainProcess() || !aDispatchDelayed,
                "No support for delayed-dispatch transactions in child "
                "process!");
--- a/dom/indexedDB/IDBTransaction.h
+++ b/dom/indexedDB/IDBTransaction.h
@@ -84,17 +84,17 @@ public:
     INITIAL = 0,
     LOADING,
     COMMITTING,
     DONE
   };
 
   static already_AddRefed<IDBTransaction>
   Create(IDBDatabase* aDatabase,
-         nsTArray<nsString>& aObjectStoreNames,
+         const Sequence<nsString>& aObjectStoreNames,
          Mode aMode,
          bool aDispatchDelayed)
   {
     return CreateInternal(aDatabase, aObjectStoreNames, aMode, aDispatchDelayed,
                           false);
   }
 
   // nsIDOMEventTarget
@@ -225,17 +225,17 @@ public:
   GetParentObject() const
   {
     return GetOwner();
   }
 
   IDBTransactionMode
   GetMode(ErrorResult& aRv) const;
 
-  nsIIDBDatabase*
+  IDBDatabase*
   Db() const
   {
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     return mDatabase;
   }
 
   DOMError*
   GetError(ErrorResult& aRv);
@@ -260,17 +260,17 @@ public:
 private:
   nsresult
   AbortInternal(nsresult aAbortCode,
                 already_AddRefed<mozilla::dom::DOMError> aError);
 
   // Should only be called directly through IndexedDBDatabaseChild.
   static already_AddRefed<IDBTransaction>
   CreateInternal(IDBDatabase* aDatabase,
-                 nsTArray<nsString>& aObjectStoreNames,
+                 const Sequence<nsString>& aObjectStoreNames,
                  Mode aMode,
                  bool aDispatchDelayed,
                  bool aIsVersionChangeTransactionChild);
 
   IDBTransaction();
   ~IDBTransaction();
 
   nsresult CommitOrRollback();
--- a/dom/indexedDB/OpenDatabaseHelper.cpp
+++ b/dom/indexedDB/OpenDatabaseHelper.cpp
@@ -2054,17 +2054,17 @@ OpenDatabaseHelper::StartSetVersion()
   NS_ASSERTION(mState == eSetVersionPending, "Why are we here?");
 
   // In case we fail, fire error events
   mState = eFiringEvents;
 
   nsresult rv = EnsureSuccessResult();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsTArray<nsString> storesToOpen;
+  Sequence<nsString> storesToOpen;
   nsRefPtr<IDBTransaction> transaction =
     IDBTransaction::Create(mDatabase, storesToOpen,
                            IDBTransaction::VERSION_CHANGE, true);
   NS_ENSURE_TRUE(transaction, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<SetVersionHelper> helper =
     new SetVersionHelper(transaction, mOpenDBRequest, this, mRequestedVersion,
                          mCurrentVersion);
--- a/dom/indexedDB/ipc/IndexedDBChild.cpp
+++ b/dom/indexedDB/ipc/IndexedDBChild.cpp
@@ -503,17 +503,17 @@ IndexedDBDatabaseChild::RecvPIndexedDBTr
 
   if (!EnsureDatabase(mRequest, dbInfo, osInfo)) {
     return false;
   }
 
   nsRefPtr<IPCOpenDatabaseHelper> helper =
     new IPCOpenDatabaseHelper(mDatabase, mRequest);
 
-  nsTArray<nsString> storesToOpen;
+  Sequence<nsString> storesToOpen;
   nsRefPtr<IDBTransaction> transaction =
     IDBTransaction::CreateInternal(mDatabase, storesToOpen,
                                    IDBTransaction::VERSION_CHANGE, false, true);
   NS_ENSURE_TRUE(transaction, false);
 
   nsRefPtr<IPCSetVersionHelper> versionHelper =
     new IPCSetVersionHelper(transaction, mRequest, oldVersion, mVersion);
 
--- a/dom/indexedDB/ipc/IndexedDBParent.cpp
+++ b/dom/indexedDB/ipc/IndexedDBParent.cpp
@@ -1,36 +1,40 @@
 /* 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 "IndexedDBParent.h"
 
-#include "AsyncConnectionHelper.h"
+#include "nsIDOMEvent.h"
+#include "nsIDOMFile.h"
+#include "nsIXPConnect.h"
+
 #include "mozilla/AppProcessChecker.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/ContentParent.h"
-#include "mozilla/dom/indexedDB/DatabaseInfo.h"
-#include "mozilla/dom/indexedDB/IDBDatabase.h"
-#include "mozilla/dom/indexedDB/IDBEvents.h"
-#include "mozilla/dom/indexedDB/IDBFactory.h"
-#include "mozilla/dom/indexedDB/IDBIndex.h"
-#include "mozilla/dom/indexedDB/IDBKeyRange.h"
-#include "mozilla/dom/indexedDB/IDBObjectStore.h"
-#include "mozilla/dom/indexedDB/IDBTransaction.h"
+#include "mozilla/dom/IDBDatabaseBinding.h"
 #include "mozilla/dom/ipc/Blob.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/unused.h"
 #include "mozilla/Util.h"
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
-#include "nsIDOMEvent.h"
-#include "nsIDOMFile.h"
-#include "nsIXPConnect.h"
+
+#include "AsyncConnectionHelper.h"
+#include "DatabaseInfo.h"
+#include "IDBDatabase.h"
+#include "IDBEvents.h"
+#include "IDBFactory.h"
+#include "IDBIndex.h"
+#include "IDBKeyRange.h"
+#include "IDBObjectStore.h"
+#include "IDBTransaction.h"
 
 #define CHROME_ORIGIN "chrome"
 #define PERMISSION_PREFIX "indexedDB-chrome-"
 #define PERMISSION_SUFFIX_READ "-read"
 #define PERMISSION_SUFFIX_WRITE "-write"
 
 USING_INDEXEDDB_NAMESPACE
 
@@ -372,41 +376,32 @@ IndexedDBDatabaseParent::HandleRequestEv
 
     if (!SendBlocked(oldVersion)) {
       return NS_ERROR_FAILURE;
     }
 
     return NS_OK;
   }
 
-  nsIXPConnect* xpc = nsContentUtils::XPConnect();
-  MOZ_ASSERT(xpc);
-
   AutoSafeJSContext cx;
 
   JS::Rooted<JS::Value> result(cx);
   rv = mOpenRequest->GetResult(result.address());
   NS_ENSURE_SUCCESS(rv, rv);
 
   MOZ_ASSERT(!JSVAL_IS_PRIMITIVE(result));
 
-  nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
-  rv = xpc->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(result),
-                                       getter_AddRefs(wrapper));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIIDBDatabase> database;
-  if (!wrapper || !(database = do_QueryInterface(wrapper->Native()))) {
+  IDBDatabase *database;
+  rv = UnwrapObject<IDBDatabase>(cx, &result.toObject(), database);
+  if (NS_FAILED(rv)) {
     NS_WARNING("Didn't get the object we expected!");
-    return NS_ERROR_FAILURE;
+    return rv;
   }
 
-  IDBDatabase* databaseConcrete = static_cast<IDBDatabase*>(database.get());
-
-  DatabaseInfo* dbInfo = databaseConcrete->Info();
+  DatabaseInfo* dbInfo = database->Info();
   MOZ_ASSERT(dbInfo);
 
   nsAutoTArray<nsString, 20> objectStoreNames;
   if (!dbInfo->GetObjectStoreNames(objectStoreNames)) {
     MOZ_CRASH("This should never fail!");
   }
 
   InfallibleTArray<ObjectStoreInfoGuts> objectStoreInfos;
@@ -422,18 +417,17 @@ IndexedDBDatabaseParent::HandleRequestEv
       objectStoreInfos.AppendElement(*osInfo);
     }
   }
 
   if (aType.EqualsLiteral(SUCCESS_EVT_STR)) {
     nsRefPtr<IDBOpenDBRequest> request;
     mOpenRequest.swap(request);
 
-    EventTarget* target =
-      static_cast<EventTarget*>(databaseConcrete);
+    EventTarget* target = static_cast<EventTarget*>(database);
 
 #ifdef DEBUG
     {
       nsresult rvDEBUG =
         target->AddEventListener(NS_LITERAL_STRING(ERROR_EVT_STR),
                                  mEventListener, false);
       NS_WARN_IF_FALSE(NS_SUCCEEDED(rvDEBUG), "Failed to add error listener!");
     }
@@ -442,34 +436,34 @@ IndexedDBDatabaseParent::HandleRequestEv
     NS_NAMED_LITERAL_STRING(versionChange, VERSIONCHANGE_EVT_STR);
     rv = target->AddEventListener(versionChange, mEventListener, false);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (!SendSuccess(*dbInfo, objectStoreInfos)) {
       return NS_ERROR_FAILURE;
     }
 
-    MOZ_ASSERT(!mDatabase || mDatabase == databaseConcrete);
+    MOZ_ASSERT(!mDatabase || mDatabase == database);
 
     if (!mDatabase) {
-      databaseConcrete->SetActor(this);
-      mDatabase = databaseConcrete;
+      database->SetActor(this);
+      mDatabase = database;
     }
 
     return NS_OK;
   }
 
   if (aType.EqualsLiteral(UPGRADENEEDED_EVT_STR)) {
     MOZ_ASSERT(!mDatabase);
 
     IDBTransaction* transaction =
       AsyncConnectionHelper::GetCurrentTransaction();
     MOZ_ASSERT(transaction);
 
-    if (!CheckWritePermission(databaseConcrete->Name())) {
+    if (!CheckWritePermission(database->Name())) {
       // If we get here then the child process is either dead or in the process
       // of being killed. Abort the transaction now to prevent any changes to
       // the database.
       ErrorResult rv;
       transaction->Abort(rv);
       if (rv.Failed()) {
         NS_WARNING("Failed to abort transaction!");
       }
@@ -492,18 +486,18 @@ IndexedDBDatabaseParent::HandleRequestEv
     versionChangeParams.osInfo() = objectStoreInfos;
     versionChangeParams.oldVersion() = oldVersion;
 
     if (!SendPIndexedDBTransactionConstructor(actor.forget(),
                                               versionChangeParams)) {
       return NS_ERROR_FAILURE;
     }
 
-    databaseConcrete->SetActor(this);
-    mDatabase = databaseConcrete;
+    database->SetActor(this);
+    mDatabase = database;
 
     return NS_OK;
   }
 
   MOZ_CRASH("Unexpected message type!");
 }
 
 nsresult
@@ -595,17 +589,17 @@ IndexedDBDatabaseParent::RecvPIndexedDBT
     return false;
   }
 
   if (mDatabase->IsClosed()) {
     // If the window was navigated then we won't be able to do anything here.
     return true;
   }
 
-  nsTArray<nsString> storesToOpen;
+  Sequence<nsString> storesToOpen;
   storesToOpen.AppendElements(params.names());
 
   nsRefPtr<IDBTransaction> transaction =
     IDBTransaction::Create(mDatabase, storesToOpen, params.mode(), false);
   NS_ENSURE_TRUE(transaction, false);
 
   nsresult rv = actor->SetTransaction(transaction);
   NS_ENSURE_SUCCESS(rv, false);
@@ -865,26 +859,24 @@ IndexedDBVersionChangeTransactionParent:
     // If we've invalidated this database in the parent then we should bail out
     // now to avoid logic problems that could force-kill the child.
     return true;
   }
 
   IDBDatabase* db = mTransaction->Database();
   MOZ_ASSERT(db);
 
-  nsresult rv;
+  ErrorResult rv;
 
   {
     AutoSetCurrentTransaction asct(mTransaction);
-
-    rv = db->DeleteObjectStore(aName);
+    db->DeleteObjectStore(aName, rv);
   }
 
-  NS_ENSURE_SUCCESS(rv, false);
-
+  ENSURE_SUCCESS(rv, false);
   return true;
 }
 
 bool
 IndexedDBVersionChangeTransactionParent::RecvPIndexedDBObjectStoreConstructor(
                                     PIndexedDBObjectStoreParent* aActor,
                                     const ObjectStoreConstructorParams& aParams)
 {
@@ -915,26 +907,25 @@ IndexedDBVersionChangeTransactionParent:
 
     const ObjectStoreInfoGuts& info = params.info();
 
     IDBDatabase* db = mTransaction->Database();
     MOZ_ASSERT(db);
 
     nsRefPtr<IDBObjectStore> objectStore;
 
-    nsresult rv;
+    ErrorResult rv;
 
     {
       AutoSetCurrentTransaction asct(mTransaction);
 
-      rv = db->CreateObjectStoreInternal(mTransaction, info,
-                                         getter_AddRefs(objectStore));
+      objectStore = db->CreateObjectStoreInternal(mTransaction, info, rv);
     }
 
-    NS_ENSURE_SUCCESS(rv, false);
+    ENSURE_SUCCESS(rv, false);
 
     actor->SetObjectStore(objectStore);
     objectStore->SetActor(actor);
     return true;
   }
 
   return
     IndexedDBTransactionParent::RecvPIndexedDBObjectStoreConstructor(aActor,
--- a/dom/indexedDB/moz.build
+++ b/dom/indexedDB/moz.build
@@ -5,17 +5,16 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['ipc']
 TEST_DIRS += ['test']
 
 XPIDL_SOURCES += [
     'nsIIDBCursor.idl',
     'nsIIDBCursorWithValue.idl',
-    'nsIIDBDatabase.idl',
     'nsIIDBKeyRange.idl',
     'nsIIDBOpenDBRequest.idl',
     'nsIIDBRequest.idl',
     'nsIIndexedDatabaseManager.idl',
 ]
 
 XPIDL_MODULE = 'dom_indexeddb'
 
deleted file mode 100644
--- a/dom/indexedDB/nsIIDBDatabase.idl
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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 "nsISupports.idl"
-
-interface nsIIDBRequest;
-interface nsIDOMDOMStringList;
-interface nsIDOMEventListener;
-
-/**
- * IDBDatabase interface.  See
- * http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBDatabase
- * for more information.
- */
-[scriptable, builtinclass, uuid(89299bf8-e078-4ebc-abda-d97fe5618602)]
-interface nsIIDBDatabase : nsISupports
-{
-  readonly attribute DOMString name;
-
-  readonly attribute unsigned long long version;
-
-  readonly attribute nsIDOMDOMStringList objectStoreNames;
-
-  [implicit_jscontext]
-  nsISupports // IDBObjectStore
-  createObjectStore([Null(Stringify)] in DOMString name,
-                    /* IDBObjectStoreParameters */
-                    [optional /* none */] in jsval options);
-
-  void
-  deleteObjectStore([Null(Stringify)] in DOMString name);
-
-  // mode can be either "readonly" or "readwrite"
-  [optional_argc, implicit_jscontext]
-  nsISupports
-  transaction(in jsval storeNames, // js array of strings
-              [optional /* "readonly" */] in DOMString mode);
-
-  [implicit_jscontext]
-  nsIIDBRequest
-  mozCreateFileHandle(in DOMString name,
-                      [optional] in DOMString type);
-
-  void
-  close();
-
-  [implicit_jscontext] attribute jsval onabort;
-
-  [implicit_jscontext] attribute jsval onerror;
-
-  [implicit_jscontext] attribute jsval onversionchange;
-};
--- a/dom/indexedDB/test/browser_permissionsPromptAllow.js
+++ b/dom/indexedDB/test/browser_permissionsPromptAllow.js
@@ -19,17 +19,17 @@ function test1()
 {
   info("creating tab");
   gBrowser.selectedTab = gBrowser.addTab();
 
   gBrowser.selectedBrowser.addEventListener("load", function () {
     gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
 
     setFinishedCallback(function(result, exception) {
-      ok(result instanceof Components.interfaces.nsIIDBDatabase,
+      ok(result instanceof IDBDatabase,
          "First database creation was successful");
       ok(!exception, "No exception");
       is(getPermission(testPageURL, "indexedDB"),
          Components.interfaces.nsIPermissionManager.UNKNOWN_ACTION,
          "Correct permission set");
       gBrowser.removeCurrentTab();
       executeSoon(test2);
     });
@@ -55,17 +55,17 @@ function test2()
 {
   info("creating tab");
   gBrowser.selectedTab = gBrowser.addTab();
 
   gBrowser.selectedBrowser.addEventListener("load", function () {
     gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
 
     setFinishedCallback(function(result, exception) {
-      ok(result instanceof Components.interfaces.nsIIDBDatabase,
+      ok(result instanceof IDBDatabase,
          "First database creation was successful");
       ok(!exception, "No exception");
       is(getPermission(testPageURL, "indexedDB"),
          Components.interfaces.nsIPermissionManager.UNKNOWN_ACTION,
          "Correct permission set");
       gBrowser.removeCurrentTab();
       unregisterAllPopupEventHandlers();
       removePermission(testPageURL, "indexedDB");
--- a/dom/indexedDB/test/browser_perwindow_privateBrowsing.js
+++ b/dom/indexedDB/test/browser_perwindow_privateBrowsing.js
@@ -15,17 +15,17 @@ function test()
 
 function test1()
 {
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", function () {
     gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
 
     setFinishedCallback(function(result, exception) {
-      ok(result instanceof Components.interfaces.nsIIDBDatabase,
+      ok(result instanceof IDBDatabase,
          "First database creation was successful");
       ok(!exception, "No exception");
       gBrowser.removeCurrentTab();
 
       executeSoon(test2);
     });
   }, true);
   content.location = testPageURL;
--- a/dom/indexedDB/test/unit/head.js
+++ b/dom/indexedDB/test/unit/head.js
@@ -3,17 +3,16 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 const { 'classes': Cc, 'interfaces': Ci } = Components;
 
 const DOMException = Ci.nsIDOMDOMException;
 const IDBCursor = Ci.nsIIDBCursor;
 const IDBOpenDBRequest = Ci.nsIIDBOpenDBRequest;
-const IDBDatabase = Ci.nsIIDBDatabase
 const IDBRequest = Ci.nsIIDBRequest
 
 function is(a, b, msg) {
   dump("is(" + a + ", " + b + ", \"" + msg + "\")");
   do_check_eq(a, b, Components.stack.caller);
 }
 
 function ok(cond, msg) {
--- a/dom/quota/nsIOfflineStorage.h
+++ b/dom/quota/nsIOfflineStorage.h
@@ -68,25 +68,9 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIOffline
   Close() MOZ_OVERRIDE;                                                        \
                                                                                \
   NS_IMETHOD_(bool)                                                            \
   IsClosed() MOZ_OVERRIDE;                                                     \
                                                                                \
   NS_IMETHOD_(void)                                                            \
   Invalidate() MOZ_OVERRIDE;
 
-#define NS_DECL_NSIOFFLINESTORAGE_NOCLOSE                                      \
-  NS_IMETHOD_(Client*)                                                         \
-  GetClient() MOZ_OVERRIDE;                                                    \
-                                                                               \
-  NS_IMETHOD_(bool)                                                            \
-  IsOwned(nsPIDOMWindow* aOwner) MOZ_OVERRIDE;                                 \
-                                                                               \
-  NS_IMETHOD_(const nsACString&)                                               \
-  Origin() MOZ_OVERRIDE;                                                       \
-                                                                               \
-  NS_IMETHOD_(bool)                                                            \
-  IsClosed() MOZ_OVERRIDE;                                                     \
-                                                                               \
-  NS_IMETHOD_(void)                                                            \
-  Invalidate() MOZ_OVERRIDE;
-
 #endif // nsIOfflineStorage_h__
--- a/dom/webidl/DummyBinding.webidl
+++ b/dom/webidl/DummyBinding.webidl
@@ -12,17 +12,16 @@ interface DummyInterface {
   FilePropertyBag fileBag();
   InspectorRGBTriple rgbTriple();
   Function getFunction();
   void funcSocketsDict(optional SocketsDict arg);
   void funcHttpConnDict(optional HttpConnDict arg);
   void funcWebSocketDict(optional WebSocketDict arg);
   void funcDNSCacheDict(optional DNSCacheDict arg);
   void frameRequestCallback(FrameRequestCallback arg);
-  void idbObjectStoreParams(optional IDBObjectStoreParameters arg);
   void CameraPictureOptions(optional CameraPictureOptions arg);
   void MmsParameters(optional MmsParameters arg);
   void MmsAttachment(optional MmsAttachment arg);
 };
 
 interface DummyInterfaceWorkers {
   BlobPropertyBag blobBag();
 };
--- a/dom/webidl/IDBDatabase.webidl
+++ b/dom/webidl/IDBDatabase.webidl
@@ -5,16 +5,45 @@
  *
  * The origin of this IDL file is
  * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBObjectStoreParameters
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-dictionary IDBObjectStoreParameters {
-  // XXXbz this should be "(DOMString or sequence<DOMString>)?", but
-  // we don't support unions in dictionaries yet.  See bug 767926.
-  any keyPath = null;
-  boolean autoIncrement = false;
+interface IDBDatabase : EventTarget {
+    readonly    attribute DOMString          name;
+    readonly    attribute unsigned long long version;
+
+    [Throws]
+    readonly    attribute DOMStringList      objectStoreNames;
+
+    [Throws]
+    IDBObjectStore createObjectStore (DOMString name, optional IDBObjectStoreParameters optionalParameters);
+
+    [Throws]
+    void           deleteObjectStore (DOMString name);
+
+    // This should be:
+    // IDBTransaction transaction ((DOMString or sequence<DOMString>) storeNames, optional IDBTransactionMode mode = "readonly");
+    // but unions are not currently supported.
+
+    [Throws]
+    IDBTransaction transaction (DOMString storeName, optional IDBTransactionMode mode = "readonly");
+
+    [Throws]
+    IDBTransaction transaction (sequence<DOMString> storeNames, optional IDBTransactionMode mode = "readonly");
+
+    void           close ();
+
+    [SetterThrows]
+                attribute EventHandler       onabort;
+    [SetterThrows]
+                attribute EventHandler       onerror;
+    [SetterThrows]
+                attribute EventHandler       onversionchange;
 };
 
-// If we start using IDBObjectStoreParameters here, remove it from DummyBinding.
+partial interface IDBDatabase {
+    [Throws]
+    IDBRequest mozCreateFileHandle (DOMString name, optional DOMString type);
+};
--- a/dom/webidl/IDBFileHandle.webidl
+++ b/dom/webidl/IDBFileHandle.webidl
@@ -1,10 +1,8 @@
 /* -*- 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 IDBDatabase;
-
 interface IDBFileHandle : FileHandle {
   readonly attribute IDBDatabase database;
 };
--- a/dom/webidl/IDBObjectStore.webidl
+++ b/dom/webidl/IDBObjectStore.webidl
@@ -4,16 +4,22 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * The origin of this IDL file is
  * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBObjectStore
  */
 
 interface IDBRequest;
 
+dictionary IDBObjectStoreParameters {
+    // TODO (DOMString or sequence<DOMString>)? keyPath = null;
+    any                                         keyPath = null;
+    boolean                             autoIncrement = false;
+};
+
 interface IDBObjectStore {
     readonly    attribute DOMString      name;
 
     [Throws]
     readonly    attribute any            keyPath;
 
     [Throws]
     readonly    attribute DOMStringList  indexNames;
--- a/js/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/xpconnect/src/dom_quickstubs.qsconf
@@ -81,17 +81,16 @@ members = [
     'nsIBoxObject.screenX',
     'nsIBoxObject.screenY',
     'nsIBoxObject.width',
     'nsIBoxObject.height',
 
     # dom/indexedDB
     'nsIIDBCursor.*',
     'nsIIDBCursorWithValue.*',
-    'nsIIDBDatabase.*',
     'nsIIDBKeyRange.*',
     'nsIIDBRequest.*',
     'nsIIDBOpenDBRequest.*',
     'nsIIndexedDatabaseManager.*',
 
     # dom/file
     'nsIDOMLockedFile.*',