Backout 8886b027527a (bug 718132) for xpcshell failures
authorEd Morley <bmo@edmorley.co.uk>
Mon, 23 Jan 2012 16:18:14 +0000
changeset 86346 aa713a50f43582b8286e996913e18695cbee56b0
parent 86345 2b0a5accb8ccc5a7f780c617ae6d9dc93247624c
child 86347 57fa9183c078ebbb464b9a02634c3cd6a6735b0c
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs718132
milestone12.0a1
backs out8886b027527ab9c4f0dff28c81321a65f5370e96
Backout 8886b027527a (bug 718132) for xpcshell failures
content/base/src/nsContentUtils.cpp
dom/base/nsDOMClassInfo.cpp
dom/indexedDB/AsyncConnectionHelper.cpp
dom/indexedDB/IDBCursor.cpp
dom/indexedDB/IDBCursor.h
dom/indexedDB/IDBDatabase.cpp
dom/indexedDB/IDBDatabase.h
dom/indexedDB/IDBFactory.cpp
dom/indexedDB/IDBFactory.h
dom/indexedDB/IDBIndex.cpp
dom/indexedDB/IDBIndex.h
dom/indexedDB/IDBObjectStore.cpp
dom/indexedDB/IDBObjectStore.h
dom/indexedDB/IDBRequest.cpp
dom/indexedDB/IDBRequest.h
dom/indexedDB/IDBTransaction.cpp
dom/indexedDB/IDBTransaction.h
dom/indexedDB/IDBWrapperCache.cpp
dom/indexedDB/IDBWrapperCache.h
dom/indexedDB/IndexedDatabaseManager.cpp
dom/indexedDB/Makefile.in
dom/indexedDB/OpenDatabaseHelper.cpp
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5431,19 +5431,18 @@ public:
   {
   }
   NS_IMETHOD_(void) NoteRoot(PRUint32 langID, void* root,
                              nsCycleCollectionParticipant* helper)
   {
   }
   NS_IMETHOD_(void) NoteScriptChild(PRUint32 langID, void* child)
   {
-    if (langID == nsIProgrammingLanguage::JAVASCRIPT &&
-        child == mWrapper) {
-      mFound = true;
+    if (langID == nsIProgrammingLanguage::JAVASCRIPT) {
+      mFound = child == mWrapper;
     }
   }
   NS_IMETHOD_(void) NoteXPCOMChild(nsISupports *child)
   {
   }
   NS_IMETHOD_(void) NoteNativeChild(void* child,
                                     nsCycleCollectionParticipant* helper)
   {
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -485,30 +485,27 @@
 #include "nsHTMLLegendElement.h"
 
 #include "DOMSVGLengthList.h"
 #include "DOMSVGNumberList.h"
 #include "DOMSVGPathSegList.h"
 #include "DOMSVGPointList.h"
 #include "DOMSVGTransformList.h"
 
-#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
 #include "mozilla/dom/indexedDB/IDBFactory.h"
 #include "mozilla/dom/indexedDB/IDBRequest.h"
 #include "mozilla/dom/indexedDB/IDBDatabase.h"
 #include "mozilla/dom/indexedDB/IDBEvents.h"
 #include "mozilla/dom/indexedDB/IDBObjectStore.h"
 #include "mozilla/dom/indexedDB/IDBTransaction.h"
 #include "mozilla/dom/indexedDB/IDBCursor.h"
 #include "mozilla/dom/indexedDB/IDBKeyRange.h"
 #include "mozilla/dom/indexedDB/IDBIndex.h"
 #include "nsIIDBDatabaseException.h"
 
-using mozilla::dom::indexedDB::IDBWrapperCache;
-
 #include "nsIDOMMediaQueryList.h"
 
 #include "nsDOMTouchEvent.h"
 #include "nsIDOMCustomEvent.h"
 
 #include "nsWrapperCacheInlines.h"
 #include "dombindings.h"
 
@@ -591,20 +588,16 @@ static const char kDOMStringBundleURL[] 
    nsIXPCScriptable::WANT_DELPROPERTY |                                       \
    nsIXPCScriptable::WANT_SETPROPERTY |                                       \
    nsIXPCScriptable::WANT_GETPROPERTY)
 
 #define EVENTTARGET_SCRIPTABLE_FLAGS                                          \
   (DOM_DEFAULT_SCRIPTABLE_FLAGS       |                                       \
    nsIXPCScriptable::WANT_ADDPROPERTY)
 
-#define IDBEVENTTARGET_SCRIPTABLE_FLAGS                                       \
-  (EVENTTARGET_SCRIPTABLE_FLAGS |                                             \
-   nsIXPCScriptable::WANT_POSTCREATE)
-
 #define DOMCLASSINFO_STANDARD_FLAGS                                           \
   (nsIClassInfo::MAIN_THREAD_ONLY | nsIClassInfo::DOM_OBJECT)
 
 
 #ifdef NS_DEBUG
 #define NS_DEFINE_CLASSINFO_DATA_DEBUG(_class)                                \
     eDOMClassInfo_##_class##_id,
 #else
@@ -656,47 +649,16 @@ DOMCI_DATA(DOMConstructor, void)
 
 #define NS_DEFINE_CLASSINFO_DATA(_class, _helper, _flags)                     \
   NS_DEFINE_CLASSINFO_DATA_WITH_NAME(_class, _class, _helper, _flags)
 
 #define NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(_class, _helper, _flags)          \
   NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA_WITH_NAME(_class, _class, _helper, \
                                                  _flags)
 
-namespace {
-
-class IDBEventTargetSH : public nsEventTargetSH
-{
-protected:
-  IDBEventTargetSH(nsDOMClassInfoData* aData) : nsEventTargetSH(aData)
-  { }
-
-  virtual ~IDBEventTargetSH()
-  { }
-
-public:
-  NS_IMETHOD PreCreate(nsISupports *aNativeObj, JSContext *aCx,
-                       JSObject *aGlobalObj, JSObject **aParentObj);
-
-  NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *aQrapper, JSContext *aCx,
-                        JSObject *aObj);
-
-  NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *aWrapper, JSContext *aCx,
-                         JSObject *aObj, jsid aId, jsval *aVp, bool *aRetval);
-
-  virtual void PreserveWrapper(nsISupports *aNative);
-
-  static nsIClassInfo *doCreate(nsDOMClassInfoData *aData)
-  {
-    return new IDBEventTargetSH(aData);
-  }
-};
-
-} // anonymous namespace
-
 // This list of NS_DEFINE_CLASSINFO_DATA macros is what gives the DOM
 // classes their correct behavior when used through XPConnect. The
 // arguments that are passed to NS_DEFINE_CLASSINFO_DATA are
 //
 // 1. Class name as it should appear in JavaScript, this name is also
 //    used to find the id of the class in nsDOMClassInfo
 //    (i.e. e<classname>_id)
 // 2. Scriptable helper class
@@ -1570,36 +1532,36 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(WebSocket, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(CloseEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(IDBFactory, 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(IDBRequest, nsEventTargetSH,
+                           EVENTTARGET_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(IDBDatabase, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBObjectStore, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(IDBTransaction, IDBEventTargetSH,
-                           IDBEVENTTARGET_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(IDBTransaction, nsDOMGenericSH,
+                           DOM_DEFAULT_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(IDBIndex, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBVersionChangeEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(IDBOpenDBRequest, IDBEventTargetSH,
-                           IDBEVENTTARGET_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(IDBOpenDBRequest, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBDatabaseException, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(Touch, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(TouchList, nsDOMTouchListSH,
                            ARRAY_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(TouchEvent, nsDOMGenericSH,
@@ -7645,56 +7607,16 @@ nsEventTargetSH::AddProperty(nsIXPConnec
 void
 nsEventTargetSH::PreserveWrapper(nsISupports *aNative)
 {
   nsDOMEventTargetWrapperCache *target =
     nsDOMEventTargetWrapperCache::FromSupports(aNative);
   nsContentUtils::PreserveWrapper(aNative, target);
 }
 
-// IDBEventTarget helper
-
-NS_IMETHODIMP
-IDBEventTargetSH::PreCreate(nsISupports *aNativeObj, JSContext *aCx,
-                            JSObject *aGlobalObj, JSObject **aParentObj)
-{
-  IDBWrapperCache *target = IDBWrapperCache::FromSupports(aNativeObj);
-  JSObject *parent = target->GetParentObject();
-  *aParentObj = parent ? parent : aGlobalObj;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-IDBEventTargetSH::PostCreate(nsIXPConnectWrappedNative *aWrapper,
-                             JSContext *aCx, JSObject *aObj)
-{
-  IDBWrapperCache *target = IDBWrapperCache::FromSupports(aWrapper->Native());
-  target->OnWrapperCreated();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-IDBEventTargetSH::AddProperty(nsIXPConnectWrappedNative *aWrapper,
-                              JSContext *aCx, JSObject *aObj, jsid aId,
-                              jsval *aVp, bool *aRetval)
-{
-  if (aId == sAddEventListener_id) {
-    return nsEventTargetSH::AddProperty(aWrapper, aCx, aObj, aId, aVp, aRetval);
-  }
-
-  IDBEventTargetSH::PreserveWrapper(GetNative(aWrapper, aObj));
-  return NS_OK;
-}
-
-void
-IDBEventTargetSH::PreserveWrapper(nsISupports *aNative)
-{
-  IDBWrapperCache *target = IDBWrapperCache::FromSupports(aNative);
-  nsContentUtils::PreserveWrapper(aNative, target);
-}
 
 // Element helper
 
 static bool
 GetBindingURL(Element *aElement, nsIDocument *aDocument,
               nsCSSValue::URL **aResult)
 {
   // If we have a frame the frame has already loaded the binding.  And
--- a/dom/indexedDB/AsyncConnectionHelper.cpp
+++ b/dom/indexedDB/AsyncConnectionHelper.cpp
@@ -141,21 +141,28 @@ HelperBase::WrapNative(JSContext* aCx,
                        nsISupports* aNative,
                        jsval* aResult)
 {
   NS_ASSERTION(aCx, "Null context!");
   NS_ASSERTION(aNative, "Null pointer!");
   NS_ASSERTION(aResult, "Null pointer!");
   NS_ASSERTION(mRequest, "Null request!");
 
-  JSObject* global = mRequest->GetParentObject();
-  NS_ASSERTION(global, "This should never be null!");
+  JSObject* obj;
+  if (mRequest->ScriptContext()) {
+    obj = mRequest->ScriptContext()->GetNativeGlobal();
+  }
+  else {
+    obj = mRequest->GetWrapper();
+  }
+
+  NS_ENSURE_TRUE(obj, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsresult rv =
-    nsContentUtils::WrapNative(aCx, global, aNative, aResult);
+    nsContentUtils::WrapNative(aCx, obj, aNative, aResult);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   return NS_OK;
 }
 
 void
 HelperBase::ReleaseMainThreadObjects()
 {
@@ -276,17 +283,17 @@ AsyncConnectionHelper::Run()
     if (NS_SUCCEEDED(rv)) {
       setProgressHandler = true;
     }
   }
 
   if (NS_SUCCEEDED(rv)) {
     bool hasSavepoint = false;
     if (mDatabase) {
-      IndexedDatabaseManager::SetCurrentWindow(mDatabase->GetOwner());
+      IndexedDatabaseManager::SetCurrentWindow(mDatabase->Owner());
 
       // Make the first savepoint.
       if (mTransaction) {
         if (!(hasSavepoint = mTransaction->StartSavepoint())) {
           NS_WARNING("Failed to make savepoint!");
         }
       }
     }
--- a/dom/indexedDB/IDBCursor.cpp
+++ b/dom/indexedDB/IDBCursor.cpp
@@ -59,17 +59,18 @@ USING_INDEXEDDB_NAMESPACE
 namespace {
 
 inline
 already_AddRefed<IDBRequest>
 GenerateRequest(IDBCursor* aCursor)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   IDBDatabase* database = aCursor->Transaction()->Database();
-  return IDBRequest::Create(aCursor, database, aCursor->Transaction());
+  return IDBRequest::Create(aCursor, database->ScriptContext(),
+                            database->Owner(), aCursor->Transaction());
 }
 
 } // anonymous namespace
 
 BEGIN_INDEXEDDB_NAMESPACE
 
 class ContinueHelper : public AsyncConnectionHelper
 {
@@ -256,35 +257,31 @@ IDBCursor::CreateCommon(IDBRequest* aReq
   NS_ASSERTION(aRequest, "Null pointer!");
   NS_ASSERTION(aTransaction, "Null pointer!");
   NS_ASSERTION(aObjectStore, "Null pointer!");
   NS_ASSERTION(!aContinueQuery.IsEmpty(), "Empty query!");
   NS_ASSERTION(!aContinueToQuery.IsEmpty(), "Empty query!");
 
   nsRefPtr<IDBCursor> cursor = new IDBCursor();
 
-  IDBDatabase* database = aTransaction->Database();
-  cursor->mScriptContext = database->GetScriptContext();
-  cursor->mOwner = database->GetOwner();
-  cursor->mScriptOwner = database->GetScriptOwner();
-
   cursor->mRequest = aRequest;
   cursor->mTransaction = aTransaction;
   cursor->mObjectStore = aObjectStore;
+  cursor->mScriptContext = aTransaction->Database()->ScriptContext();
+  cursor->mOwner = aTransaction->Database()->Owner();
   cursor->mDirection = aDirection;
   cursor->mContinueQuery = aContinueQuery;
   cursor->mContinueToQuery = aContinueToQuery;
   cursor->mRangeKey = aRangeKey;
 
   return cursor.forget();
 }
 
 IDBCursor::IDBCursor()
-: mScriptOwner(nsnull),
-  mType(OBJECTSTORE),
+: mType(OBJECTSTORE),
   mDirection(nsIIDBCursor::NEXT),
   mCachedKey(JSVAL_VOID),
   mCachedPrimaryKey(JSVAL_VOID),
   mCachedValue(JSVAL_VOID),
   mHaveCachedKey(false),
   mHaveCachedPrimaryKey(false),
   mHaveCachedValue(false),
   mRooted(false),
@@ -375,20 +372,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBCursor)
   NS_ASSERTION(tmp->mHaveCachedKey || JSVAL_IS_VOID(tmp->mCachedKey),
                "Should have a cached key");
   NS_ASSERTION(tmp->mHaveCachedPrimaryKey ||
                JSVAL_IS_VOID(tmp->mCachedPrimaryKey),
                "Should have a cached primary key");
   NS_ASSERTION(tmp->mHaveCachedValue || JSVAL_IS_VOID(tmp->mCachedValue),
                "Should have a cached value");
-  if (tmp->mScriptOwner) {
-    NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->mScriptOwner,
-                                               "mScriptOwner")
-  }
   if (JSVAL_IS_GCTHING(tmp->mCachedKey)) {
     void *gcThing = JSVAL_TO_GCTHING(tmp->mCachedKey);
     NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mCachedKey")
   }
   if (JSVAL_IS_GCTHING(tmp->mCachedPrimaryKey)) {
     void *gcThing = JSVAL_TO_GCTHING(tmp->mCachedPrimaryKey);
     NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mCachedPrimaryKey")
   }
@@ -397,17 +390,16 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDB
     NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mCachedValue")
   }
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBCursor)
   // Don't unlink mObjectStore, mIndex, or mTransaction!
   if (tmp->mRooted) {
     NS_DROP_JS_OBJECTS(tmp, IDBCursor);
-    tmp->mScriptOwner = nsnull;
     tmp->mCachedKey = JSVAL_VOID;
     tmp->mCachedPrimaryKey = JSVAL_VOID;
     tmp->mCachedValue = JSVAL_VOID;
     tmp->mHaveCachedKey = false;
     tmp->mHaveCachedPrimaryKey = false;
     tmp->mHaveCachedValue = false;
     tmp->mRooted = false;
     tmp->mHaveValue = false;
--- a/dom/indexedDB/IDBCursor.h
+++ b/dom/indexedDB/IDBCursor.h
@@ -149,17 +149,16 @@ protected:
 
   nsRefPtr<IDBRequest> mRequest;
   nsRefPtr<IDBTransaction> mTransaction;
   nsRefPtr<IDBObjectStore> mObjectStore;
   nsRefPtr<IDBIndex> mIndex;
 
   nsCOMPtr<nsIScriptContext> mScriptContext;
   nsCOMPtr<nsPIDOMWindow> mOwner;
-  JSObject* mScriptOwner;
 
   Type mType;
   PRUint16 mDirection;
   nsCString mContinueQuery;
   nsCString mContinueToQuery;
 
   // These are cycle-collected!
   jsval mCachedKey;
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -143,32 +143,32 @@ private:
   DatabaseInfo* mInfo;
   nsString mName;
 };
 
 } // anonymous namespace
 
 // static
 already_AddRefed<IDBDatabase>
-IDBDatabase::Create(IDBWrapperCache* aOwnerCache,
+IDBDatabase::Create(nsIScriptContext* aScriptContext,
+                    nsPIDOMWindow* aOwner,
                     already_AddRefed<DatabaseInfo> aDatabaseInfo,
                     const nsACString& aASCIIOrigin,
                     FileManager* aFileManager)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!aASCIIOrigin.IsEmpty(), "Empty origin!");
 
   nsRefPtr<DatabaseInfo> databaseInfo(aDatabaseInfo);
   NS_ASSERTION(databaseInfo, "Null pointer!");
 
   nsRefPtr<IDBDatabase> db(new IDBDatabase());
 
-  db->mScriptContext = aOwnerCache->GetScriptContext();
-  db->mOwner = aOwnerCache->GetOwner();
-  db->mScriptOwner = aOwnerCache->GetScriptOwner();
+  db->mScriptContext = aScriptContext;
+  db->mOwner = aOwner;
 
   db->mDatabaseId = databaseInfo->id;
   db->mName = databaseInfo->name;
   db->mFilePath = databaseInfo->filePath;
   databaseInfo.swap(db->mDatabaseInfo);
   db->mASCIIOrigin = aASCIIOrigin;
   db->mFileManager = aFileManager;
 
@@ -200,32 +200,30 @@ IDBDatabase::~IDBDatabase()
   if (mRegistered) {
     CloseInternal(true);
 
     IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
     if (mgr) {
       mgr->UnregisterDatabase(this);
     }
   }
-
-  nsContentUtils::ReleaseWrapper(static_cast<nsIDOMEventTarget*>(this), this);
 }
 
 void
 IDBDatabase::Invalidate()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   // Make sure we're closed too.
   Close();
 
   // When the IndexedDatabaseManager needs to invalidate databases, all it has
   // is an origin, so we call back into the manager to cancel any prompts for
   // our owner.
-  IndexedDatabaseManager::CancelPromptsForWindow(GetOwner());
+  IndexedDatabaseManager::CancelPromptsForWindow(Owner());
 
   mInvalidated = true;
 }
 
 bool
 IDBDatabase::IsInvalidated()
 {
   return !!mInvalidated;
@@ -277,18 +275,17 @@ IDBDatabase::ExitSetVersionTransaction()
   NS_ASSERTION(mRunningVersionChange, "How did that happen?");
   mRunningVersionChange = false;
 }
 
 void
 IDBDatabase::OnUnlink()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-  NS_ASSERTION(!GetOwner() && !GetScriptOwner(),
-               "Should have been cleared already!");
+  NS_ASSERTION(!mOwner, "Should have been cleared already!");
 
   // We've been unlinked, at the very least we should be able to prevent further
   // transactions from starting and unblock any other SetVersion callers.
   CloseInternal(true);
 
   // No reason for the IndexedDatabaseManager to track us any longer.
   IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
   if (mgr) {
@@ -296,45 +293,43 @@ IDBDatabase::OnUnlink()
 
     // Don't try to unregister again in the destructor.
     mRegistered = false;
   }
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(IDBDatabase)
 
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBDatabase, IDBWrapperCache)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(abort)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(versionchange)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBDatabase,
+                                                  nsDOMEventTargetHelper)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnAbortListener)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnVersionChangeListener)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBDatabase, IDBWrapperCache)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(abort)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(versionchange)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBDatabase,
+                                                nsDOMEventTargetHelper)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnAbortListener)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnVersionChangeListener)
 
   // 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_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBDatabase)
-NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
-NS_IMPL_ADDREF_INHERITED(IDBDatabase, IDBWrapperCache)
-NS_IMPL_RELEASE_INHERITED(IDBDatabase, IDBWrapperCache)
+NS_IMPL_ADDREF_INHERITED(IDBDatabase, nsDOMEventTargetHelper)
+NS_IMPL_RELEASE_INHERITED(IDBDatabase, nsDOMEventTargetHelper)
 
 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)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   aName.Assign(mName);
   return NS_OK;
 }
 
@@ -668,16 +663,57 @@ IDBDatabase::Close()
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   CloseInternal(false);
 
   NS_ASSERTION(mClosed, "Should have set the closed flag!");
   return NS_OK;
 }
 
+NS_IMETHODIMP
+IDBDatabase::SetOnabort(nsIDOMEventListener* aAbortListener)
+{
+  return RemoveAddEventListener(NS_LITERAL_STRING(ABORT_EVT_STR),
+                                mOnAbortListener, aAbortListener);
+}
+
+NS_IMETHODIMP
+IDBDatabase::GetOnabort(nsIDOMEventListener** aAbortListener)
+{
+  return GetInnerEventListener(mOnAbortListener, aAbortListener);
+}
+
+NS_IMETHODIMP
+IDBDatabase::SetOnerror(nsIDOMEventListener* aErrorListener)
+{
+  return RemoveAddEventListener(NS_LITERAL_STRING(ERROR_EVT_STR),
+                                mOnErrorListener, aErrorListener);
+}
+
+NS_IMETHODIMP
+IDBDatabase::GetOnerror(nsIDOMEventListener** aErrorListener)
+{
+  return GetInnerEventListener(mOnErrorListener, aErrorListener);
+}
+
+NS_IMETHODIMP
+IDBDatabase::SetOnversionchange(nsIDOMEventListener* aVersionChangeListener)
+{
+  return RemoveAddEventListener(NS_LITERAL_STRING(VERSIONCHANGE_EVT_STR),
+                                mOnVersionChangeListener,
+                                aVersionChangeListener);
+}
+
+NS_IMETHODIMP
+IDBDatabase::GetOnversionchange(nsIDOMEventListener** aVersionChangeListener)
+{
+  return GetInnerEventListener(mOnVersionChangeListener,
+                               aVersionChangeListener);
+}
+
 nsresult
 IDBDatabase::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
 {
   NS_ENSURE_TRUE(aVisitor.mDOMEvent, NS_ERROR_UNEXPECTED);
 
   if (!mOwner) {
     return NS_OK;
   }
--- a/dom/indexedDB/IDBDatabase.h
+++ b/dom/indexedDB/IDBDatabase.h
@@ -36,49 +36,52 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozilla_dom_indexeddb_idbdatabase_h__
 #define mozilla_dom_indexeddb_idbdatabase_h__
 
 #include "mozilla/dom/indexedDB/IndexedDatabase.h"
+#include "mozilla/dom/indexedDB/FileManager.h"
 
-#include "nsIDocument.h"
 #include "nsIIDBDatabase.h"
 
-#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
-#include "mozilla/dom/indexedDB/FileManager.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsDOMEventTargetHelper.h"
+#include "nsIDocument.h"
 
 class nsIScriptContext;
 class nsPIDOMWindow;
 
 BEGIN_INDEXEDDB_NAMESPACE
 
 class AsyncConnectionHelper;
 struct DatabaseInfo;
 class IDBIndex;
 class IDBObjectStore;
 class IDBTransaction;
 class IndexedDatabaseManager;
 
-class IDBDatabase : public IDBWrapperCache,
+class IDBDatabase : public nsDOMEventTargetHelper,
                     public nsIIDBDatabase
 {
   friend class AsyncConnectionHelper;
   friend class IndexedDatabaseManager;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIIDBDATABASE
 
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBDatabase, IDBWrapperCache)
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBDatabase,
+                                           nsDOMEventTargetHelper)
 
   static already_AddRefed<IDBDatabase>
-  Create(IDBWrapperCache* aOwnerCache,
+  Create(nsIScriptContext* aScriptContext,
+         nsPIDOMWindow* aOwner,
          already_AddRefed<DatabaseInfo> aDatabaseInfo,
          const nsACString& aASCIIOrigin,
          FileManager* aFileManager);
 
   // nsIDOMEventTarget
   virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
 
   nsIAtom* Id() const
@@ -96,16 +99,26 @@ public:
     return mName;
   }
 
   const nsString& FilePath()
   {
     return mFilePath;
   }
 
+  nsIScriptContext* ScriptContext()
+  {
+    return mScriptContext;
+  }
+
+  nsPIDOMWindow* Owner()
+  {
+    return mOwner;
+  }
+
   already_AddRefed<nsIDocument> GetOwnerDocument()
   {
     if (!mOwner) {
       return nsnull;
     }
 
     nsCOMPtr<nsIDocument> doc = do_QueryInterface(mOwner->GetExtantDocument());
     return doc.forget();
@@ -150,16 +163,16 @@ private:
   PRInt32 mInvalidated;
   bool mRegistered;
   bool mClosed;
   bool mRunningVersionChange;
 
   nsRefPtr<FileManager> mFileManager;
 
   // Only touched on the main thread.
-  NS_DECL_EVENT_HANDLER(abort);
-  NS_DECL_EVENT_HANDLER(error);
-  NS_DECL_EVENT_HANDLER(versionchange);
+  nsRefPtr<nsDOMEventListenerWrapper> mOnAbortListener;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnVersionChangeListener;
 };
 
 END_INDEXEDDB_NAMESPACE
 
 #endif // mozilla_dom_indexeddb_idbdatabase_h__
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -64,16 +64,17 @@
 #include "AsyncConnectionHelper.h"
 #include "CheckPermissionsHelper.h"
 #include "DatabaseInfo.h"
 #include "IDBDatabase.h"
 #include "IDBEvents.h"
 #include "IDBKeyRange.h"
 #include "IndexedDatabaseManager.h"
 #include "Key.h"
+#include "nsIScriptSecurityManager.h"
 
 using namespace mozilla;
 
 USING_INDEXEDDB_NAMESPACE
 
 namespace {
 
 GeckoProcessType gAllowedProcessType = GeckoProcessType_Invalid;
@@ -85,59 +86,38 @@ struct ObjectStoreInfoMap
 
   PRInt64 id;
   ObjectStoreInfo* info;
 };
 
 } // anonymous namespace
 
 IDBFactory::IDBFactory()
-: mOwningObject(nsnull)
 {
   IDBFactory::NoteUsedByProcessType(XRE_GetProcessType());
 }
 
-IDBFactory::~IDBFactory()
-{
-  if (mOwningObject) {
-    NS_DROP_JS_OBJECTS(this, IDBFactory);
-  }
-}
-
 // static
 already_AddRefed<nsIIDBFactory>
 IDBFactory::Create(nsPIDOMWindow* aWindow)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
-  NS_ENSURE_TRUE(aWindow, nsnull);
-
-  if (aWindow->IsOuterWindow()) {
+  if (aWindow && aWindow->IsOuterWindow()) {
     aWindow = aWindow->GetCurrentInnerWindow();
     NS_ENSURE_TRUE(aWindow, nsnull);
   }
 
   nsRefPtr<IDBFactory> factory = new IDBFactory();
-  factory->mWindow = aWindow;
-  return factory.forget();
-}
 
-// static
-already_AddRefed<nsIIDBFactory>
-IDBFactory::Create(JSContext* aCx,
-                   JSObject* aOwningObject)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-  NS_ASSERTION(aCx, "Null context!");
-  NS_ASSERTION(aOwningObject, "Null object!");
-  NS_ASSERTION(JS_GetGlobalForObject(aCx, aOwningObject) == aOwningObject,
-               "Not a global object!");
+  if (aWindow) {
+    factory->mWindow = do_GetWeakReference(aWindow);
+    NS_ENSURE_TRUE(factory->mWindow, nsnull);
+  }
 
-  nsRefPtr<IDBFactory> factory = new IDBFactory();
-  factory->mOwningObject = aOwningObject;
   return factory.forget();
 }
 
 // static
 already_AddRefed<mozIStorageConnection>
 IDBFactory::GetConnection(const nsAString& aDatabaseFilePath)
 {
   NS_ASSERTION(StringEndsWith(aDatabaseFilePath, NS_LITERAL_STRING(".sqlite")),
@@ -415,90 +395,65 @@ IDBFactory::SetDatabaseMetadata(Database
       NS_WARNING("Out of memory!");
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   return NS_OK;
 }
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(IDBFactory)
+NS_IMPL_ADDREF(IDBFactory)
+NS_IMPL_RELEASE(IDBFactory)
 
-NS_IMPL_CYCLE_COLLECTING_ADDREF(IDBFactory)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(IDBFactory)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IDBFactory)
+NS_INTERFACE_MAP_BEGIN(IDBFactory)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_INTERFACE_MAP_ENTRY(nsIIDBFactory)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBFactory)
 NS_INTERFACE_MAP_END
 
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBFactory)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mWindow)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBFactory)
-  if (tmp->mOwningObject) {
-    tmp->mOwningObject = nsnull;
-  }
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mWindow)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBFactory)
-  if (tmp->mOwningObject) {
-    NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->mOwningObject,
-                                               "mOwningObject")
-  }
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
 DOMCI_DATA(IDBFactory, IDBFactory)
 
 nsresult
 IDBFactory::OpenCommon(const nsAString& aName,
                        PRInt64 aVersion,
                        bool aDeleting,
                        nsIIDBOpenDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-  NS_ASSERTION(mWindow || mOwningObject, "Must have one of these!");
 
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     // Force ContentChild to cache the path from the parent, so that
     // we do not end up in a side thread that asks for the path (which
     // would make ContentChild try to send a message in a thread other
     // than the main one).
     ContentChild::GetSingleton()->GetIndexedDBPath();
   }
 
   nsCOMPtr<nsPIDOMWindow> window;
   nsCOMPtr<nsIScriptGlobalObject> sgo;
   nsIScriptContext* context = nsnull;
-  JSObject* scriptOwner = nsnull;
 
   if (mWindow) {
-    sgo = do_QueryInterface(mWindow);
+    window = do_QueryReferent(mWindow);
+    NS_ENSURE_TRUE(window, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    
+    sgo = do_QueryInterface(window);
     NS_ENSURE_TRUE(sgo, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
-
+    
     context = sgo->GetContext();
     NS_ENSURE_TRUE(context, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
-
-    window = mWindow;
-  }
-  else {
-    scriptOwner = mOwningObject;
   }
 
   nsCString origin;
   nsresult rv =
     IndexedDatabaseManager::GetASCIIOriginFromWindow(window, origin);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsRefPtr<IDBOpenDBRequest> request =
-    IDBOpenDBRequest::Create(context, window, scriptOwner);
+    IDBOpenDBRequest::Create(context, window);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<OpenDatabaseHelper> openHelper =
     new OpenDatabaseHelper(request, aName, origin, aVersion, aDeleting);
 
   rv = openHelper->Init();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
--- a/dom/indexedDB/IDBFactory.h
+++ b/dom/indexedDB/IDBFactory.h
@@ -40,42 +40,37 @@
 #ifndef mozilla_dom_indexeddb_idbfactory_h__
 #define mozilla_dom_indexeddb_idbfactory_h__
 
 #include "mozilla/dom/indexedDB/IndexedDatabase.h"
 
 #include "mozIStorageConnection.h"
 #include "nsIIDBFactory.h"
 
-#include "nsCycleCollectionParticipant.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsXULAppAPI.h"
 
+class nsPIDOMWindow;
 class nsIAtom;
-class nsPIDOMWindow;
 
 BEGIN_INDEXEDDB_NAMESPACE
 
 struct DatabaseInfo;
 class IDBDatabase;
 struct ObjectStoreInfo;
 
 class IDBFactory : public nsIIDBFactory
 {
   typedef nsTArray<nsRefPtr<ObjectStoreInfo> > ObjectStoreInfoArray;
-
 public:
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBFactory)
+  NS_DECL_ISUPPORTS
   NS_DECL_NSIIDBFACTORY
 
   static already_AddRefed<nsIIDBFactory> Create(nsPIDOMWindow* aWindow);
 
-  static already_AddRefed<nsIIDBFactory> Create(JSContext* aCx,
-                                                JSObject* aOwningObject);
-
   static already_AddRefed<mozIStorageConnection>
   GetConnection(const nsAString& aDatabaseFilePath);
 
   // Called when a process uses an IndexedDB factory. We only allow
   // a single process type to use IndexedDB - the chrome/single process
   // in Firefox, and the child process in Fennec - so access by more
   // than one process type is a very serious error.
   static void
@@ -96,25 +91,22 @@ public:
 
   static nsresult
   SetDatabaseMetadata(DatabaseInfo* aDatabaseInfo,
                       PRUint64 aVersion,
                       ObjectStoreInfoArray& aObjectStores);
 
 private:
   IDBFactory();
-  ~IDBFactory();
+  ~IDBFactory() { }
 
   nsresult
   OpenCommon(const nsAString& aName,
              PRInt64 aVersion,
              bool aDeleting,
              nsIIDBOpenDBRequest** _retval);
 
-  // If this factory lives on a window then mWindow must be non-null. Otherwise
-  // mOwningObject must be non-null.
-  nsCOMPtr<nsPIDOMWindow> mWindow;
-  JSObject* mOwningObject;
+  nsCOMPtr<nsIWeakReference> mWindow;
 };
 
 END_INDEXEDDB_NAMESPACE
 
 #endif // mozilla_dom_indexeddb_idbfactory_h__
--- a/dom/indexedDB/IDBIndex.cpp
+++ b/dom/indexedDB/IDBIndex.cpp
@@ -289,17 +289,18 @@ private:
 
 inline
 already_AddRefed<IDBRequest>
 GenerateRequest(IDBIndex* aIndex)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   IDBTransaction* transaction = aIndex->ObjectStore()->Transaction();
   IDBDatabase* database = transaction->Database();
-  return IDBRequest::Create(aIndex, database, transaction);
+  return IDBRequest::Create(aIndex, database->ScriptContext(),
+                            database->Owner(), transaction);
 }
 
 } // anonymous namespace
 
 // static
 already_AddRefed<IDBIndex>
 IDBIndex::Create(IDBObjectStore* aObjectStore,
                  const IndexInfo* aIndexInfo)
@@ -307,16 +308,19 @@ IDBIndex::Create(IDBObjectStore* aObject
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(aObjectStore, "Null pointer!");
   NS_ASSERTION(aIndexInfo, "Null pointer!");
 
   IDBDatabase* database = aObjectStore->Transaction()->Database();
 
   nsRefPtr<IDBIndex> index = new IDBIndex();
 
+  index->mScriptContext = database->ScriptContext();
+  index->mOwner = database->Owner();
+
   index->mObjectStore = aObjectStore;
   index->mId = aIndexInfo->id;
   index->mName = aIndexInfo->name;
   index->mKeyPath = aIndexInfo->keyPath;
   index->mKeyPathArray = aIndexInfo->keyPathArray;
   index->mUnique = aIndexInfo->unique;
   index->mMultiEntry = aIndexInfo->multiEntry;
 
@@ -334,20 +338,24 @@ IDBIndex::~IDBIndex()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(IDBIndex)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBIndex)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mObjectStore)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOwner)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptContext)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBIndex)
   // Don't unlink mObjectStore!
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptContext)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IDBIndex)
   NS_INTERFACE_MAP_ENTRY(nsIIDBIndex)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBIndex)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
--- a/dom/indexedDB/IDBIndex.h
+++ b/dom/indexedDB/IDBIndex.h
@@ -108,16 +108,19 @@ public:
   }
 
 private:
   IDBIndex();
   ~IDBIndex();
 
   nsRefPtr<IDBObjectStore> mObjectStore;
 
+  nsCOMPtr<nsIScriptContext> mScriptContext;
+  nsCOMPtr<nsPIDOMWindow> mOwner;
+
   PRInt64 mId;
   nsString mName;
   nsString mKeyPath;
   nsTArray<nsString> mKeyPathArray;
   bool mUnique;
   bool mMultiEntry;
 };
 
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -502,18 +502,18 @@ GetKeyFromValue(JSContext* aCx,
 
 
 inline
 already_AddRefed<IDBRequest>
 GenerateRequest(IDBObjectStore* aObjectStore)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   IDBDatabase* database = aObjectStore->Transaction()->Database();
-  return IDBRequest::Create(aObjectStore, database,
-                            aObjectStore->Transaction());
+  return IDBRequest::Create(aObjectStore, database->ScriptContext(),
+                            database->Owner(), aObjectStore->Transaction());
 }
 
 JSClass gDummyPropClass = {
   "dummy", 0,
   JS_PropertyStub,  JS_PropertyStub,
   JS_PropertyStub,  JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub,
   JS_ConvertStub, JS_FinalizeStub,
@@ -527,16 +527,19 @@ already_AddRefed<IDBObjectStore>
 IDBObjectStore::Create(IDBTransaction* aTransaction,
                        ObjectStoreInfo* aStoreInfo,
                        nsIAtom* aDatabaseId)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   nsRefPtr<IDBObjectStore> objectStore = new IDBObjectStore();
 
+  objectStore->mScriptContext = aTransaction->Database()->ScriptContext();
+  objectStore->mOwner = aTransaction->Database()->Owner();
+
   objectStore->mTransaction = aTransaction;
   objectStore->mName = aStoreInfo->name;
   objectStore->mId = aStoreInfo->id;
   objectStore->mKeyPath = aStoreInfo->keyPath;
   objectStore->mKeyPathArray = aStoreInfo->keyPathArray;
   objectStore->mAutoIncrement = !!aStoreInfo->nextAutoIncrementId;
   objectStore->mDatabaseId = aDatabaseId;
   objectStore->mInfo = aStoreInfo;
@@ -1368,25 +1371,29 @@ IDBObjectStore::AddOrPut(const jsval& aV
   return NS_OK;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(IDBObjectStore)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBObjectStore)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mTransaction,
                                                        nsIDOMEventTarget)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOwner)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptContext)
 
   for (PRUint32 i = 0; i < tmp->mCreatedIndexes.Length(); i++) {
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCreatedIndexes[i]");
     cb.NoteXPCOMChild(static_cast<nsIIDBIndex*>(tmp->mCreatedIndexes[i].get()));
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBObjectStore)
   // Don't unlink mTransaction!
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptContext)
 
   tmp->mCreatedIndexes.Clear();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IDBObjectStore)
   NS_INTERFACE_MAP_ENTRY(nsIIDBObjectStore)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBObjectStore)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
--- a/dom/indexedDB/IDBObjectStore.h
+++ b/dom/indexedDB/IDBObjectStore.h
@@ -36,24 +36,23 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozilla_dom_indexeddb_idbobjectstore_h__
 #define mozilla_dom_indexeddb_idbobjectstore_h__
 
 #include "mozilla/dom/indexedDB/IndexedDatabase.h"
+#include "mozilla/dom/indexedDB/IDBTransaction.h"
 
 #include "nsIIDBObjectStore.h"
 #include "nsIIDBTransaction.h"
 
 #include "nsCycleCollectionParticipant.h"
 
-#include "mozilla/dom/indexedDB/IDBTransaction.h"
-
 class nsIScriptContext;
 class nsPIDOMWindow;
 
 BEGIN_INDEXEDDB_NAMESPACE
 
 class AsyncConnectionHelper;
 class Key;
 
@@ -200,16 +199,19 @@ protected:
                     JSContext* aCx,
                     PRUint8 aOptionalArgCount,
                     nsIIDBRequest** _retval,
                     bool aOverwrite);
 
 private:
   nsRefPtr<IDBTransaction> mTransaction;
 
+  nsCOMPtr<nsIScriptContext> mScriptContext;
+  nsCOMPtr<nsPIDOMWindow> mOwner;
+
   PRInt64 mId;
   nsString mName;
   nsString mKeyPath;
   nsTArray<nsString> mKeyPathArray;
   bool mAutoIncrement;
   nsCOMPtr<nsIAtom> mDatabaseId;
   nsRefPtr<ObjectStoreInfo> mInfo;
   PRUint32 mStructuredCloneVersion;
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -57,63 +57,70 @@
 #include "IDBEvents.h"
 #include "IDBTransaction.h"
 
 USING_INDEXEDDB_NAMESPACE
 
 IDBRequest::IDBRequest()
 : mResultVal(JSVAL_VOID),
   mErrorCode(0),
-  mHaveResultOrErrorCode(false),
-  mManuallyRooted(false)
+  mResultValRooted(false),
+  mHaveResultOrErrorCode(false)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 }
 
 IDBRequest::~IDBRequest()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
-  UnrootResultVal();
+  if (mResultValRooted) {
+    // Calling a virtual from the destructor is bad... But we know that we won't
+    // call a subclass' implementation because mResultValRooted will be set to
+    // false.
+    UnrootResultVal();
+  }
 }
 
 // static
 already_AddRefed<IDBRequest>
 IDBRequest::Create(nsISupports* aSource,
-                   IDBWrapperCache* aOwnerCache,
+                   nsIScriptContext* aScriptContext,
+                   nsPIDOMWindow* aOwner,
                    IDBTransaction* aTransaction)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   nsRefPtr<IDBRequest> request(new IDBRequest());
 
   request->mSource = aSource;
   request->mTransaction = aTransaction;
-  request->mScriptContext = aOwnerCache->GetScriptContext();
-  request->mOwner = aOwnerCache->GetOwner();
-  request->mScriptOwner = aOwnerCache->GetScriptOwner();
+  request->mScriptContext = aScriptContext;
+  request->mOwner = aOwner;
 
   return request.forget();
 }
 
 void
 IDBRequest::Reset()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   mResultVal = JSVAL_VOID;
   mHaveResultOrErrorCode = false;
   mErrorCode = 0;
-  UnrootResultVal();
+  if (mResultValRooted) {
+    UnrootResultVal();
+  }
 }
 
 nsresult
 IDBRequest::NotifyHelperCompleted(HelperBase* aHelper)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!mHaveResultOrErrorCode, "Already called!");
-  NS_ASSERTION(!PreservingWrapper(), "Already rooted?!");
+  NS_ASSERTION(!mResultValRooted, "Already rooted?!");
   NS_ASSERTION(JSVAL_IS_VOID(mResultVal), "Should be undefined!");
 
   // See if our window is still valid. If not then we're going to pretend that
   // we never completed.
   if (NS_FAILED(CheckInnerWindowCorrectness())) {
     return NS_OK;
   }
 
@@ -123,106 +130,81 @@ IDBRequest::NotifyHelperCompleted(Helper
 
   // If the request failed then set the error code and return.
   if (NS_FAILED(rv)) {
     mErrorCode = NS_ERROR_GET_CODE(rv);
     return NS_OK;
   }
 
   // Otherwise we need to get the result from the helper.
-  JSContext* cx;
-  if (mScriptOwner) {
+  JSContext* cx = nsnull;
+  JSObject* obj = nsnull;
+  if (mScriptContext) {   
+    cx = mScriptContext->GetNativeContext();
+    NS_ASSERTION(cx, "Failed to get a context!");
+
+    obj = mScriptContext->GetNativeGlobal();
+    NS_ASSERTION(obj, "Failed to get global object!");
+  } 
+  else {
     nsIThreadJSContextStack* cxStack = nsContentUtils::ThreadJSContextStack();
     NS_ASSERTION(cxStack, "Failed to get thread context stack!");
 
-    if (NS_FAILED(cxStack->GetSafeJSContext(&cx))) {
-      NS_WARNING("Failed to get safe JSContext!");
-      rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
-      mErrorCode = NS_ERROR_GET_CODE(rv);
-      return rv;
-    }
+    NS_ENSURE_SUCCESS(cxStack->GetSafeJSContext(&cx),
+                      NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+
+    obj = GetWrapper();
+    NS_ENSURE_TRUE(obj, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
   }
-  else {
-    cx = mScriptContext->GetNativeContext();
-    NS_ASSERTION(cx, "Failed to get a context!");
-  } 
-
-  JSObject* global = GetParentObject();
-  NS_ASSERTION(global, "This should never be null!");
 
   JSAutoRequest ar(cx);
   JSAutoEnterCompartment ac;
-  if (ac.enter(cx, global)) {
+  if (!ac.enter(cx, obj)) {
+    rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+  }
+  else {
     RootResultVal();
 
     rv = aHelper->GetSuccessResult(cx, &mResultVal);
-    if (NS_FAILED(rv)) {
+    if (NS_SUCCEEDED(rv)) {
+      // Unroot if we don't really need to be rooted.
+      if (!JSVAL_IS_GCTHING(mResultVal)) {
+        UnrootResultVal();
+      }
+    }
+    else {
       NS_WARNING("GetSuccessResult failed!");
     }
   }
-  else {
-    NS_WARNING("Failed to enter correct compartment!");
-    rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
-  }
 
   if (NS_SUCCEEDED(rv)) {
     mErrorCode = 0;
   }
   else {
     mErrorCode = NS_ERROR_GET_CODE(rv);
     mResultVal = JSVAL_VOID;
   }
 
   return rv;
 }
 
 void
 IDBRequest::RootResultVal()
 {
-  // We want to use the preserved wrapper to keep our result alive, but we don't
-  // always get a wrapper right away. Manually root if we don't have a wrapper.
-  if (!PreservingWrapper() && GetWrapperPreserveColor()) {
-    NS_ASSERTION(!mManuallyRooted, "Should not be manually rooted here!");
-    nsContentUtils::PreserveWrapper(static_cast<nsIDOMEventTarget*>(this),
-                                    this);
-  }
-  else if (!mManuallyRooted) {
-    NS_HOLD_JS_OBJECTS(this, IDBRequest);
-    mManuallyRooted = true;
-  }
+  NS_ASSERTION(!mResultValRooted, "This should be false!");
+  NS_HOLD_JS_OBJECTS(this, IDBRequest);
+  mResultValRooted = true;
 }
 
 void
 IDBRequest::UnrootResultVal()
 {
-  if (mManuallyRooted) {
-    NS_ASSERTION(!PreservingWrapper(), "Shouldn't have a wrapper here!");
-    NS_DROP_JS_OBJECTS(this, IDBRequest);
-    mManuallyRooted = false;
-  }
-  else if (PreservingWrapper()) {
-    nsContentUtils::ReleaseWrapper(static_cast<nsIDOMEventTarget*>(this), this);
-  }
-}
-
-void
-IDBRequest::OnWrapperCreated()
-{
-  NS_ASSERTION(!PreservingWrapper(),
-               "Shouldn't have had a wrapper before now!");
-
-  // Update our rooting strategy to accommodate new wrapper if needed. We have
-  // to unroot the old way first. This is annoying because XPConnect uses a hash
-  // table to store these so we could be just fine adding an entry for a second
-  // time... However nsContentUtils keeps a counter that will get out of sync if
-  // we do. Safest to just remove the old holder and then add a new one.
-  if (mManuallyRooted) {
-    UnrootResultVal();
-    RootResultVal();
-  }
+  NS_ASSERTION(mResultValRooted, "This should be true!");
+  NS_DROP_JS_OBJECTS(this, IDBRequest);
+  mResultValRooted = false;
 }
 
 NS_IMETHODIMP
 IDBRequest::GetReadyState(PRUint16* aReadyState)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   *aReadyState = mHaveResultOrErrorCode ?
@@ -275,118 +257,165 @@ IDBRequest::GetErrorCode(PRUint16* aErro
     // XXX Need a real error code here.
     return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
   }
 
   *aErrorCode = mErrorCode;
   return NS_OK;
 }
 
+NS_IMETHODIMP
+IDBRequest::SetOnsuccess(nsIDOMEventListener* aSuccessListener)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+  return RemoveAddEventListener(NS_LITERAL_STRING(SUCCESS_EVT_STR),
+                                mOnSuccessListener, aSuccessListener);
+}
+
+NS_IMETHODIMP
+IDBRequest::GetOnsuccess(nsIDOMEventListener** aSuccessListener)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+  return GetInnerEventListener(mOnSuccessListener, aSuccessListener);
+}
+
+NS_IMETHODIMP
+IDBRequest::SetOnerror(nsIDOMEventListener* aErrorListener)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+  return RemoveAddEventListener(NS_LITERAL_STRING(ERROR_EVT_STR),
+                                mOnErrorListener, aErrorListener);
+}
+
+NS_IMETHODIMP
+IDBRequest::GetOnerror(nsIDOMEventListener** aErrorListener)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+  return GetInnerEventListener(mOnErrorListener, aErrorListener);
+}
+
 NS_IMPL_CYCLE_COLLECTION_CLASS(IDBRequest)
 
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
-  // Don't need NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS because
-  // nsDOMEventTargetHelper does it for us.
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(success)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBRequest,
+                                                  nsDOMEventTargetWrapperCache)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnSuccessListener)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSource)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mTransaction,
                                                        nsPIDOMEventTarget)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
-  tmp->mResultVal = JSVAL_VOID;
-  if (tmp->mManuallyRooted) {
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest,
+                                                nsDOMEventTargetWrapperCache)
+  if (tmp->mResultValRooted) {
+    tmp->mResultVal = JSVAL_VOID;
     tmp->UnrootResultVal();
   }
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(success)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnSuccessListener)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSource)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTransaction)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
-  // Don't need NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER because
-  // nsDOMEventTargetHelper does it for us.
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBRequest,
+                                               nsDOMEventTargetWrapperCache)
   if (JSVAL_IS_GCTHING(tmp->mResultVal)) {
     void *gcThing = JSVAL_TO_GCTHING(tmp->mResultVal);
     NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mResultVal")
   }
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBRequest)
   NS_INTERFACE_MAP_ENTRY(nsIIDBRequest)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBRequest)
-NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache)
 
-NS_IMPL_ADDREF_INHERITED(IDBRequest, IDBWrapperCache)
-NS_IMPL_RELEASE_INHERITED(IDBRequest, IDBWrapperCache)
+NS_IMPL_ADDREF_INHERITED(IDBRequest, nsDOMEventTargetWrapperCache)
+NS_IMPL_RELEASE_INHERITED(IDBRequest, nsDOMEventTargetWrapperCache)
 
 DOMCI_DATA(IDBRequest, IDBRequest)
 
-NS_IMPL_EVENT_HANDLER(IDBRequest, success);
-NS_IMPL_EVENT_HANDLER(IDBRequest, error);
-
 nsresult
 IDBRequest::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   aVisitor.mCanHandle = true;
   aVisitor.mParentTarget = mTransaction;
   return NS_OK;
 }
 
 IDBOpenDBRequest::~IDBOpenDBRequest()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
-  UnrootResultVal();
+  if (mResultValRooted) {
+    UnrootResultVal();
+  }
 }
 
 // static
 already_AddRefed<IDBOpenDBRequest>
 IDBOpenDBRequest::Create(nsIScriptContext* aScriptContext,
-                         nsPIDOMWindow* aOwner,
-                         JSObject* aScriptOwner)
+                         nsPIDOMWindow* aOwner)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   nsRefPtr<IDBOpenDBRequest> request(new IDBOpenDBRequest());
 
   request->mScriptContext = aScriptContext;
   request->mOwner = aOwner;
-  request->mScriptOwner = aScriptOwner;
 
   return request.forget();
 }
 
 void
 IDBOpenDBRequest::SetTransaction(IDBTransaction* aTransaction)
 {
   mTransaction = aTransaction;
 }
 
+void
+IDBOpenDBRequest::RootResultVal()
+{
+  NS_ASSERTION(!mResultValRooted, "This should be false!");
+  NS_HOLD_JS_OBJECTS(this, IDBOpenDBRequest);
+  mResultValRooted = true;
+}
+
+void
+IDBOpenDBRequest::UnrootResultVal()
+{
+  NS_ASSERTION(mResultValRooted, "This should be true!");
+  NS_DROP_JS_OBJECTS(this, IDBOpenDBRequest);
+  mResultValRooted = false;
+}
+
+NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, blocked)
+NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, upgradeneeded)
+
 NS_IMPL_CYCLE_COLLECTION_CLASS(IDBOpenDBRequest)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBOpenDBRequest,
                                                   IDBRequest)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(upgradeneeded)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(blocked)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnupgradeneededListener)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnblockedListener)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBOpenDBRequest,
                                                 IDBRequest)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(upgradeneeded)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(blocked)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnupgradeneededListener)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnblockedListener)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBOpenDBRequest)
   NS_INTERFACE_MAP_ENTRY(nsIIDBOpenDBRequest)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBOpenDBRequest)
 NS_INTERFACE_MAP_END_INHERITING(IDBRequest)
 
 NS_IMPL_ADDREF_INHERITED(IDBOpenDBRequest, IDBRequest)
 NS_IMPL_RELEASE_INHERITED(IDBOpenDBRequest, IDBRequest)
 
 DOMCI_DATA(IDBOpenDBRequest, IDBOpenDBRequest)
-
-NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, blocked);
-NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, upgradeneeded);
--- a/dom/indexedDB/IDBRequest.h
+++ b/dom/indexedDB/IDBRequest.h
@@ -41,38 +41,40 @@
 #ifndef mozilla_dom_indexeddb_idbrequest_h__
 #define mozilla_dom_indexeddb_idbrequest_h__
 
 #include "mozilla/dom/indexedDB/IndexedDatabase.h"
 
 #include "nsIIDBRequest.h"
 #include "nsIIDBOpenDBRequest.h"
 
-#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
+#include "nsDOMEventTargetWrapperCache.h"
+#include "nsCycleCollectionParticipant.h"
 
 class nsIScriptContext;
 class nsPIDOMWindow;
 
 BEGIN_INDEXEDDB_NAMESPACE
 
 class HelperBase;
 class IDBTransaction;
 
-class IDBRequest : public IDBWrapperCache,
+class IDBRequest : public nsDOMEventTargetWrapperCache,
                    public nsIIDBRequest
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIIDBREQUEST
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(IDBRequest,
-                                                         IDBWrapperCache)
+                                                         nsDOMEventTargetWrapperCache)
 
   static
   already_AddRefed<IDBRequest> Create(nsISupports* aSource,
-                                      IDBWrapperCache* aOwnerCache,
+                                      nsIScriptContext* aScriptContext,
+                                      nsPIDOMWindow* aOwner,
                                       IDBTransaction* aTransaction);
 
   // nsIDOMEventTarget
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
 
   nsISupports* Source()
   {
     return mSource;
@@ -85,66 +87,68 @@ public:
   void SetError(nsresult rv)
   {
     NS_ASSERTION(NS_FAILED(rv), "Er, what?");
     NS_ASSERTION(mErrorCode == NS_OK, "Already have an error?");
 
     mErrorCode = rv;
   }
 
-  void RootResultVal();
-  void UnrootResultVal();
+  nsIScriptContext* ScriptContext()
+  {
+    return mScriptContext;
+  }
 
-  virtual void OnWrapperCreated();
+  nsPIDOMWindow* Owner()
+  {
+    return mOwner;
+  }
+
+  virtual void RootResultVal();
+  virtual void UnrootResultVal();
 
 protected:
   IDBRequest();
   ~IDBRequest();
 
   nsCOMPtr<nsISupports> mSource;
   nsRefPtr<IDBTransaction> mTransaction;
 
-  NS_DECL_EVENT_HANDLER(success);
-  NS_DECL_EVENT_HANDLER(error);
+  nsRefPtr<nsDOMEventListenerWrapper> mOnSuccessListener;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
 
   jsval mResultVal;
 
   PRUint16 mErrorCode;
+  bool mResultValRooted;
   bool mHaveResultOrErrorCode;
-  bool mManuallyRooted;
 };
 
 class IDBOpenDBRequest : public IDBRequest,
                          public nsIIDBOpenDBRequest
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_FORWARD_NSIIDBREQUEST(IDBRequest::)
   NS_DECL_NSIIDBOPENDBREQUEST
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBOpenDBRequest, IDBRequest)
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBOpenDBRequest,
+                                           IDBRequest)
 
   static
   already_AddRefed<IDBOpenDBRequest>
   Create(nsIScriptContext* aScriptContext,
-         nsPIDOMWindow* aOwner,
-         JSObject* aScriptOwner);
-
-  static
-  already_AddRefed<IDBOpenDBRequest>
-  Create(IDBWrapperCache* aOwnerCache)
-  {
-    return Create(aOwnerCache->GetScriptContext(), aOwnerCache->GetOwner(),
-                  aOwnerCache->GetScriptOwner());
-  }
+         nsPIDOMWindow* aOwner);
 
   void SetTransaction(IDBTransaction* aTransaction);
 
+  virtual void RootResultVal();
+  virtual void UnrootResultVal();
+
 protected:
   ~IDBOpenDBRequest();
 
-  // Only touched on the main thread.
-  NS_DECL_EVENT_HANDLER(blocked);
-  NS_DECL_EVENT_HANDLER(upgradeneeded);
+  nsRefPtr<nsDOMEventListenerWrapper> mOnblockedListener;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnupgradeneededListener;
 };
 
 END_INDEXEDDB_NAMESPACE
 
 #endif // mozilla_dom_indexeddb_idbrequest_h__
--- a/dom/indexedDB/IDBTransaction.cpp
+++ b/dom/indexedDB/IDBTransaction.cpp
@@ -37,17 +37,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "IDBTransaction.h"
 
 #include "nsIScriptContext.h"
 
 #include "mozilla/storage.h"
-#include "nsContentUtils.h"
 #include "nsDOMClassInfoID.h"
 #include "nsDOMLists.h"
 #include "nsEventDispatcher.h"
 #include "nsPIDOMWindow.h"
 #include "nsProxyRelease.h"
 #include "nsThreadUtils.h"
 
 #include "AsyncConnectionHelper.h"
@@ -112,19 +111,18 @@ IDBTransaction::Create(IDBDatabase* aDat
                        nsTArray<nsString>& aObjectStoreNames,
                        PRUint16 aMode,
                        bool aDispatchDelayed)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   nsRefPtr<IDBTransaction> transaction = new IDBTransaction();
 
-  transaction->mScriptContext = aDatabase->GetScriptContext();
-  transaction->mOwner = aDatabase->GetOwner();
-  transaction->mScriptOwner = aDatabase->GetScriptOwner();
+  transaction->mScriptContext = aDatabase->ScriptContext();
+  transaction->mOwner = aDatabase->Owner();
 
   transaction->mDatabase = aDatabase;
   transaction->mMode = aMode;
   
   transaction->mDatabaseInfo = aDatabase->Info();
 
   if (!transaction->mObjectStoreNames.AppendElements(aObjectStoreNames)) {
     NS_ERROR("Out of memory!");
@@ -181,18 +179,16 @@ IDBTransaction::IDBTransaction()
 IDBTransaction::~IDBTransaction()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!mPendingRequests, "Should have no pending requests here!");
   NS_ASSERTION(!mSavepointCount, "Should have released them all!");
   NS_ASSERTION(!mConnection, "Should have called CommitOrRollback!");
   NS_ASSERTION(!mCreating, "Should have been cleared already!");
   NS_ASSERTION(mFiredCompleteOrAbort, "Should have fired event!");
-
-  nsContentUtils::ReleaseWrapper(static_cast<nsIDOMEventTarget*>(this), this);
 }
 
 void
 IDBTransaction::OnNewRequest()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   if (!mPendingRequests) {
     NS_ASSERTION(mReadyState == nsIIDBTransaction::INITIAL,
@@ -473,55 +469,53 @@ void
 IDBTransaction::ClearCreatedFileInfos()
 {
   mCreatedFileInfos.Clear();
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(IDBTransaction)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBTransaction,
-                                                  IDBWrapperCache)
+                                                  nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mDatabase,
                                                        nsIDOMEventTarget)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(complete)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(abort)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnCompleteListener)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnAbortListener)
 
   for (PRUint32 i = 0; i < tmp->mCreatedObjectStores.Length(); i++) {
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCreatedObjectStores[i]");
     cb.NoteXPCOMChild(static_cast<nsIIDBObjectStore*>(
                       tmp->mCreatedObjectStores[i].get()));
   }
+
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBTransaction, IDBWrapperCache)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBTransaction,
+                                                nsDOMEventTargetHelper)
   // Don't unlink mDatabase!
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(complete)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(abort)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnCompleteListener)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnAbortListener)
 
   tmp->mCreatedObjectStores.Clear();
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBTransaction)
   NS_INTERFACE_MAP_ENTRY(nsIIDBTransaction)
   NS_INTERFACE_MAP_ENTRY(nsIThreadObserver)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBTransaction)
-NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
-NS_IMPL_ADDREF_INHERITED(IDBTransaction, IDBWrapperCache)
-NS_IMPL_RELEASE_INHERITED(IDBTransaction, IDBWrapperCache)
+NS_IMPL_ADDREF_INHERITED(IDBTransaction, nsDOMEventTargetHelper)
+NS_IMPL_RELEASE_INHERITED(IDBTransaction, nsDOMEventTargetHelper)
 
 DOMCI_DATA(IDBTransaction, IDBTransaction)
 
-NS_IMPL_EVENT_HANDLER(IDBTransaction, error);
-NS_IMPL_EVENT_HANDLER(IDBTransaction, complete);
-NS_IMPL_EVENT_HANDLER(IDBTransaction, abort);
-
 NS_IMETHODIMP
 IDBTransaction::GetDb(nsIIDBDatabase** aDB)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   NS_ADDREF(*aDB = mDatabase);
   return NS_OK;
 }
@@ -627,16 +621,63 @@ IDBTransaction::Abort()
   // abort event will be fired when all outstanding requests finish.
   if (needToCommitOrRollback) {
     return CommitOrRollback();
   }
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+IDBTransaction::SetOnerror(nsIDOMEventListener* aErrorListener)
+{
+  return RemoveAddEventListener(NS_LITERAL_STRING(ERROR_EVT_STR),
+                                mOnErrorListener, aErrorListener);
+}
+
+NS_IMETHODIMP
+IDBTransaction::GetOnerror(nsIDOMEventListener** aErrorListener)
+{
+  return GetInnerEventListener(mOnErrorListener, aErrorListener);
+}
+
+NS_IMETHODIMP
+IDBTransaction::GetOncomplete(nsIDOMEventListener** aOncomplete)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+  return GetInnerEventListener(mOnCompleteListener, aOncomplete);
+}
+
+NS_IMETHODIMP
+IDBTransaction::SetOncomplete(nsIDOMEventListener* aOncomplete)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+  return RemoveAddEventListener(NS_LITERAL_STRING(COMPLETE_EVT_STR),
+                                mOnCompleteListener, aOncomplete);
+}
+
+NS_IMETHODIMP
+IDBTransaction::GetOnabort(nsIDOMEventListener** aOnabort)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+  return GetInnerEventListener(mOnAbortListener, aOnabort);
+}
+
+NS_IMETHODIMP
+IDBTransaction::SetOnabort(nsIDOMEventListener* aOnabort)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+  return RemoveAddEventListener(NS_LITERAL_STRING(ABORT_EVT_STR),
+                                mOnAbortListener, aOnabort);
+}
+
 nsresult
 IDBTransaction::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   aVisitor.mCanHandle = true;
   aVisitor.mParentTarget = mDatabase;
   return NS_OK;
 }
 
@@ -771,17 +812,17 @@ CommitHelper::Run()
   }
 
   IDBDatabase* database = mTransaction->Database();
   if (database->IsInvalidated()) {
     mAborted = true;
   }
 
   if (mConnection) {
-    IndexedDatabaseManager::SetCurrentWindow(database->GetOwner());
+    IndexedDatabaseManager::SetCurrentWindow(database->Owner());
 
     if (!mAborted && mUpdateFileRefcountFunction &&
         NS_FAILED(mUpdateFileRefcountFunction->UpdateDatabase(mConnection))) {
       mAborted = true;
     }
 
     if (!mAborted && NS_FAILED(WriteAutoIncrementCounts())) {
       mAborted = true;
--- a/dom/indexedDB/IDBTransaction.h
+++ b/dom/indexedDB/IDBTransaction.h
@@ -36,33 +36,34 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozilla_dom_indexeddb_idbtransaction_h__
 #define mozilla_dom_indexeddb_idbtransaction_h__
 
 #include "mozilla/dom/indexedDB/IndexedDatabase.h"
+#include "mozilla/dom/indexedDB/IDBDatabase.h"
+#include "mozilla/dom/indexedDB/FileInfo.h"
 
 #include "mozIStorageConnection.h"
 #include "mozIStorageStatement.h"
 #include "mozIStorageFunction.h"
 #include "nsIIDBTransaction.h"
 #include "nsIRunnable.h"
 #include "nsIThreadInternal.h"
 
+#include "nsDOMEventTargetHelper.h"
+#include "nsCycleCollectionParticipant.h"
+
 #include "nsAutoPtr.h"
 #include "nsClassHashtable.h"
 #include "nsHashKeys.h"
 #include "nsInterfaceHashtable.h"
 
-#include "mozilla/dom/indexedDB/IDBDatabase.h"
-#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
-#include "mozilla/dom/indexedDB/FileInfo.h"
-
 class nsIThread;
 
 BEGIN_INDEXEDDB_NAMESPACE
 
 class AsyncConnectionHelper;
 class CommitHelper;
 struct ObjectStoreInfo;
 class TransactionThreadPool;
@@ -72,31 +73,32 @@ class IDBTransactionListener
 {
 public:
   NS_IMETHOD_(nsrefcnt) AddRef() = 0;
   NS_IMETHOD_(nsrefcnt) Release() = 0;
 
   virtual nsresult NotifyTransactionComplete(IDBTransaction* aTransaction) = 0;
 };
 
-class IDBTransaction : public IDBWrapperCache,
+class IDBTransaction : public nsDOMEventTargetHelper,
                        public nsIIDBTransaction,
                        public nsIThreadObserver
 {
   friend class AsyncConnectionHelper;
   friend class CommitHelper;
   friend class ThreadObserver;
   friend class TransactionThreadPool;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIIDBTRANSACTION
   NS_DECL_NSITHREADOBSERVER
 
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBTransaction, IDBWrapperCache)
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBTransaction,
+                                           nsDOMEventTargetHelper)
 
   static already_AddRefed<IDBTransaction>
   Create(IDBDatabase* aDatabase,
          nsTArray<nsString>& aObjectStoreNames,
          PRUint16 aMode,
          bool aDispatchDelayed);
 
   // nsIDOMEventTarget
@@ -173,19 +175,19 @@ private:
   nsRefPtr<DatabaseInfo> mDatabaseInfo;
   nsTArray<nsString> mObjectStoreNames;
   PRUint16 mReadyState;
   PRUint16 mMode;
   PRUint32 mPendingRequests;
   PRUint32 mCreatedRecursionDepth;
 
   // Only touched on the main thread.
-  NS_DECL_EVENT_HANDLER(error);
-  NS_DECL_EVENT_HANDLER(complete);
-  NS_DECL_EVENT_HANDLER(abort);
+  nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnCompleteListener;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnAbortListener;
 
   nsInterfaceHashtable<nsCStringHashKey, mozIStorageStatement>
     mCachedStatements;
 
   nsRefPtr<IDBTransactionListener> mListener;
 
   // Only touched on the database thread.
   nsCOMPtr<mozIStorageConnection> mConnection;
deleted file mode 100644
--- a/dom/indexedDB/IDBWrapperCache.cpp
+++ /dev/null
@@ -1,38 +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 "IDBWrapperCache.h"
-
-USING_INDEXEDDB_NAMESPACE
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(IDBWrapperCache)
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBWrapperCache,
-                                                  nsDOMEventTargetWrapperCache)
-  // Don't need NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS because
-  // nsDOMEventTargetHelper does it for us.
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBWrapperCache,
-                                                nsDOMEventTargetWrapperCache)
-  tmp->mScriptOwner = nsnull;
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBWrapperCache,
-                                               nsDOMEventTargetWrapperCache)
-  // Don't need NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER because
-  // nsDOMEventTargetHelper does it for us.
-  if (tmp->mScriptOwner) {
-    NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->mScriptOwner,
-                                               "mScriptOwner")
-  }
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBWrapperCache)
-NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache)
-
-NS_IMPL_ADDREF_INHERITED(IDBWrapperCache, nsDOMEventTargetWrapperCache)
-NS_IMPL_RELEASE_INHERITED(IDBWrapperCache, nsDOMEventTargetWrapperCache)
deleted file mode 100644
--- a/dom/indexedDB/IDBWrapperCache.h
+++ /dev/null
@@ -1,74 +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/. */
-
-#ifndef mozilla_dom_indexeddb_idbwrappercache_h__
-#define mozilla_dom_indexeddb_idbwrappercache_h__
-
-#include "mozilla/dom/indexedDB/IndexedDatabase.h"
-
-#include "nsDOMEventTargetWrapperCache.h"
-
-BEGIN_INDEXEDDB_NAMESPACE
-
-class IDBWrapperCache : public nsDOMEventTargetWrapperCache
-{
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
-                                                   IDBWrapperCache,
-                                                   nsDOMEventTargetWrapperCache)
-
-  JSObject* GetScriptOwner() const
-  {
-    return mScriptOwner;
-  }
-
-  nsIScriptContext* GetScriptContext() const
-  {
-    return mScriptContext;
-  }
-
-  nsPIDOMWindow* GetOwner() const
-  {
-    return mOwner;
-  }
-
-  JSObject* GetParentObject()
-  {
-    if (mScriptOwner) {
-      return mScriptOwner;
-    }
-
-    // Do what nsEventTargetSH::PreCreate does.
-    nsCOMPtr<nsIScriptGlobalObject> parent;
-    nsDOMEventTargetWrapperCache::GetParentObject(getter_AddRefs(parent));
-
-    return parent ? parent->GetGlobalJSObject() : nsnull;
-  }
-
-  virtual void OnWrapperCreated()
-  { }
-
-  static IDBWrapperCache* FromSupports(nsISupports* aSupports)
-  {
-    return static_cast<IDBWrapperCache*>(
-      nsDOMEventTargetWrapperCache::FromSupports(aSupports));
-  }
-
-protected:
-  IDBWrapperCache()
-  : mScriptOwner(nsnull)
-  { }
-
-  virtual ~IDBWrapperCache()
-  { }
-
-  JSObject* mScriptOwner;
-};
-
-END_INDEXEDDB_NAMESPACE
-
-#endif // mozilla_dom_indexeddb_idbwrappercache_h__
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -500,17 +500,17 @@ IndexedDatabaseManager::AbortCloseDataba
 
   nsAutoTArray<IDBDatabase*, 50> liveDatabases;
   mLiveDatabases.EnumerateRead(EnumerateToTArray, &liveDatabases);
 
   TransactionThreadPool* pool = TransactionThreadPool::Get();
 
   for (PRUint32 index = 0; index < liveDatabases.Length(); index++) {
     IDBDatabase*& database = liveDatabases[index];
-    if (database->GetOwner() == aWindow) {
+    if (database->Owner() == aWindow) {
       if (NS_FAILED(database->Close())) {
         NS_WARNING("Failed to close database for dying window!");
       }
 
       if (pool) {
         pool->AbortTransactionsForDatabase(database);
       }
     }
@@ -528,17 +528,17 @@ IndexedDatabaseManager::HasOpenTransacti
 
   TransactionThreadPool* pool = TransactionThreadPool::Get();
   if (!pool) {
     return false;
   }
 
   for (PRUint32 index = 0; index < liveDatabases.Length(); index++) {
     IDBDatabase*& database = liveDatabases[index];
-    if (database->GetOwner() == aWindow &&
+    if (database->Owner() == aWindow &&
         pool->HasTransactionsForDatabase(database)) {
       return true;
     }
   }
   
   return false;
 }
 
@@ -1586,42 +1586,42 @@ IndexedDatabaseManager::SynchronizedOp::
 
   mDelayedRunnables.Clear();
 }
 
 NS_IMETHODIMP
 IndexedDatabaseManager::InitWindowless(const jsval& aObj, JSContext* aCx)
 {
   NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
-  NS_ENSURE_ARG(!JSVAL_IS_PRIMITIVE(aObj));
-
+  
   // Instantiating this class will register exception providers so even 
-  // in xpcshell we will get typed (dom) exceptions, instead of general
-  // exceptions.
+  // in xpcshell we will get typed (dom) exceptions, instead of general exceptions.
   nsCOMPtr<nsIDOMScriptObjectFactory> sof(do_GetService(kDOMSOF_CID));
 
-  JSObject* obj = JSVAL_TO_OBJECT(aObj);
-
-  JSObject* global = JS_GetGlobalForObject(aCx, obj);
+  // Defining IDBKeyrange static functions on the global.
+  if (JSVAL_IS_PRIMITIVE(aObj)) {
+    return NS_ERROR_INVALID_ARG;
+  }
 
-  nsCOMPtr<nsIIDBFactory> factory = IDBFactory::Create(aCx, global);
-  NS_ENSURE_TRUE(factory, NS_ERROR_FAILURE);
+  nsCOMPtr<nsIIDBFactory> factory = IDBFactory::Create(nsnull);
+  NS_ASSERTION(factory, "IDBFactory should not be null.");
 
+  JSObject* obj = JSVAL_TO_OBJECT(aObj);
   jsval mozIndexedDBVal;
   nsresult rv = nsContentUtils::WrapNative(aCx, obj, factory, &mozIndexedDBVal);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (!JS_DefineProperty(aCx, obj, "mozIndexedDB", mozIndexedDBVal, nsnull,
-                         nsnull, JSPROP_ENUMERATE)) {
+  if (!JS_DefineProperty(aCx, obj, "mozIndexedDB", mozIndexedDBVal, 
+      nsnull, nsnull, JSPROP_ENUMERATE)) {
     return NS_ERROR_FAILURE;
   }
 
   JSObject* keyrangeObj = JS_NewObject(aCx, nsnull, nsnull, nsnull);
   NS_ENSURE_TRUE(keyrangeObj, NS_ERROR_OUT_OF_MEMORY);
-
+    
   if (!IDBKeyRange::DefineConstructors(aCx, keyrangeObj)) {
     return NS_ERROR_FAILURE;
   }
 
   if (!JS_DefineProperty(aCx, obj, "IDBKeyRange", OBJECT_TO_JSVAL(keyrangeObj),
                          nsnull, nsnull, JSPROP_ENUMERATE)) {
     return NS_ERROR_FAILURE;
   }
--- a/dom/indexedDB/Makefile.in
+++ b/dom/indexedDB/Makefile.in
@@ -56,39 +56,37 @@ CPPSRCS = \
   CheckPermissionsHelper.cpp \
   CheckQuotaHelper.cpp \
   DatabaseInfo.cpp \
   FileInfo.cpp \
   FileManager.cpp \
   IDBCursor.cpp \
   IDBDatabase.cpp \
   IDBEvents.cpp \
-  IDBFactory.cpp \
   IDBIndex.cpp \
   IDBKeyRange.cpp \
   IDBObjectStore.cpp \
   IDBRequest.cpp \
   IDBTransaction.cpp \
-  IDBWrapperCache.cpp \
+  IDBFactory.cpp \
   IndexedDatabaseManager.cpp \
-  Key.cpp \
   OpenDatabaseHelper.cpp \
   TransactionThreadPool.cpp \
+  Key.cpp \
   $(NULL)
 
 EXPORTS_mozilla/dom/indexedDB = \
   IDBCursor.h \
   IDBDatabase.h \
   IDBEvents.h \
   IDBIndex.h \
   IDBKeyRange.h \
   IDBObjectStore.h \
   IDBRequest.h \
   IDBTransaction.h \
-  IDBWrapperCache.h \
   IndexedDatabase.h \
   IndexedDatabaseManager.h \
   IDBFactory.h \
   Key.h \
   FileManager.h \
   FileInfo.h \
   $(NULL)
 
--- a/dom/indexedDB/OpenDatabaseHelper.cpp
+++ b/dom/indexedDB/OpenDatabaseHelper.cpp
@@ -1606,19 +1606,17 @@ OpenDatabaseHelper::DoDatabaseWork()
   mState = eFiringEvents; // In case we fail somewhere along the line.
 
   if (IndexedDatabaseManager::IsShuttingDown()) {
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
   NS_ASSERTION(mOpenDBRequest, "This should never be null!");
 
-  // This will be null for non-window contexts.
-  nsPIDOMWindow* window = mOpenDBRequest->GetOwner();
-
+  nsPIDOMWindow* window = mOpenDBRequest->Owner();
   AutoEnterWindow autoWindow(window);
 
   nsCOMPtr<nsIFile> dbDirectory;
 
   IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
   NS_ASSERTION(mgr, "This should never be null!");
 
   nsresult rv = mgr->EnsureOriginIsInitialized(mASCIIOrigin,
@@ -2108,17 +2106,18 @@ OpenDatabaseHelper::EnsureSuccessResult(
 
     NS_ASSERTION(mObjectStores.IsEmpty(), "Should have swapped!");
   }
 
   dbInfo->nextObjectStoreId = mLastObjectStoreId + 1;
   dbInfo->nextIndexId = mLastIndexId + 1;
 
   nsRefPtr<IDBDatabase> database =
-    IDBDatabase::Create(mOpenDBRequest,
+    IDBDatabase::Create(mOpenDBRequest->ScriptContext(),
+                        mOpenDBRequest->Owner(),
                         dbInfo.forget(),
                         mASCIIOrigin,
                         mFileManager);
   if (!database) {
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
   NS_ASSERTION(!mDatabase, "Shouldn't have a database yet!");