Merge m-c to s-c.
authorRichard Newman <rnewman@mozilla.com>
Fri, 29 Jun 2012 23:45:13 -0700
changeset 98765 ea8c4810d3d5a5a2d60452143024ded37bc318fa
parent 98764 9d0bf5dddfc4b97b89f95f134e226da6a7b46d5e (current diff)
parent 98047 f08d285b63b0f9c8d30152dad07875725753d9c9 (diff)
child 98766 c73c500bd6e7c119aa7f2c25f81895fa63559a98
push id11640
push userryanvm@gmail.com
push dateTue, 10 Jul 2012 00:53:29 +0000
treeherdermozilla-inbound@6b0d194eabed [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone16.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
Merge m-c to s-c.
browser/components/nsBrowserGlue.js
dom/indexedDB/test/exceptions_in_success_events_iframe.html
dom/indexedDB/test/test_exceptions_in_success_events.html
other-licenses/virtualenv/virtualenv_support/distribute-0.6.24.tar.gz
--- a/browser/base/content/openLocation.js
+++ b/browser/base/content/openLocation.js
@@ -2,24 +2,26 @@
 #
 # 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/.
 
 var browser;
 var dialog = {};
 var pref = null;
+let openLocationModule = {};
 try {
   pref = Components.classes["@mozilla.org/preferences-service;1"]
                    .getService(Components.interfaces.nsIPrefBranch);
 } catch (ex) {
   // not critical, remain silent
 }
 
-Components.utils.import("resource:///modules/openLocationLastURL.jsm");
+Components.utils.import("resource:///modules/openLocationLastURL.jsm", openLocationModule);
+let gOpenLocationLastURL = new openLocationModule.OpenLocationLastURL(window.opener);
 
 function onLoad()
 {
   dialog.input         = document.getElementById("dialog.input");
   dialog.open          = document.documentElement.getButton("accept");
   dialog.openWhereList = document.getElementById("openWhereList");
   dialog.openTopWindow = document.getElementById("currentWindow");
   dialog.bundle        = document.getElementById("openLocationBundle");
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -476,20 +476,23 @@ BrowserGlue.prototype = {
     //
     // aQuitType == "lastwindow" is overloaded. "lastwindow" is used to indicate
     // "the last window is closing but we're not quitting (a non-browser window is open)"
     // and also "we're quitting by closing the last window".
 
     var windowcount = 0;
     var pagecount = 0;
     var browserEnum = Services.wm.getEnumerator("navigator:browser");
+    let allWindowsPrivate = true;
     while (browserEnum.hasMoreElements()) {
       windowcount++;
 
       var browser = browserEnum.getNext();
+      if (("gPrivateBrowsingUI" in browser) && !browser.gPrivateBrowsingUI.privateWindow)
+        allWindowsPrivate = false;
       var tabbrowser = browser.document.getElementById("content");
       if (tabbrowser)
         pagecount += tabbrowser.browsers.length - tabbrowser._numPinnedTabs;
     }
 
     this._saveSession = false;
     if (pagecount < 2)
       return;
@@ -523,20 +526,18 @@ BrowserGlue.prototype = {
       // we should show the window closing warning instead. warnAboutClosing
       // tabs checks browser.tabs.warnOnClose and returns if it's ok to close
       // the window. It doesn't actually close the window.
       mostRecentBrowserWindow = Services.wm.getMostRecentWindow("navigator:browser");
       aCancelQuit.data = !mostRecentBrowserWindow.gBrowser.warnAboutClosingTabs(true);
       return;
     }
 
-    var inPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
-                            getService(Ci.nsIPrivateBrowsingService).
-                            privateBrowsingEnabled;
-    if (inPrivateBrowsing)
+    // Never show a prompt inside private browsing mode
+    if (allWindowsPrivate)
       return;
 
     if (!showPrompt)
       return;
 
     var quitBundle = Services.strings.createBundle("chrome://browser/locale/quitDialog.properties");
     var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
 
@@ -1596,31 +1597,29 @@ ContentPermissionPrompt.prototype = {
       accessKey: browserBundle.GetStringFromName("geolocation.shareLocation.accesskey"),
       callback: function(notification) {
         request.allow();
       },
     };
 
     var message;
     var secondaryActions = [];
+    var requestingWindow = request.window.top;
+    var chromeWin = getChromeWindow(requestingWindow).wrappedJSObject;
 
     // Different message/options if it is a local file
     if (requestingURI.schemeIs("file")) {
       message = browserBundle.formatStringFromName("geolocation.shareWithFile",
                                                    [requestingURI.path], 1);
     } else {
       message = browserBundle.formatStringFromName("geolocation.shareWithSite",
                                                    [requestingURI.host], 1);
 
       // Don't offer to "always/never share" in PB mode
-      var inPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
-                              getService(Ci.nsIPrivateBrowsingService).
-                              privateBrowsingEnabled;
-
-      if (!inPrivateBrowsing) {
+      if (("gPrivateBrowsingUI" in chromeWin) && !chromeWin.gPrivateBrowsingUI.privateWindow) {
         secondaryActions.push({
           label: browserBundle.GetStringFromName("geolocation.alwaysShareLocation"),
           accessKey: browserBundle.GetStringFromName("geolocation.alwaysShareLocation.accesskey"),
           callback: function () {
             Services.perms.add(requestingURI, "geo", Ci.nsIPermissionManager.ALLOW_ACTION);
             request.allow();
           }
         });
@@ -1630,18 +1629,16 @@ ContentPermissionPrompt.prototype = {
           callback: function () {
             Services.perms.add(requestingURI, "geo", Ci.nsIPermissionManager.DENY_ACTION);
             request.cancel();
           }
         });
       }
     }
 
-    var requestingWindow = request.window.top;
-    var chromeWin = getChromeWindow(requestingWindow).wrappedJSObject;
     var browser = chromeWin.gBrowser.getBrowserForDocument(requestingWindow.document);
 
     chromeWin.PopupNotifications.show(browser, "geolocation", message, "geo-notification-icon",
                                       mainAction, secondaryActions);
   }
 };
 
 var components = [BrowserGlue, ContentPermissionPrompt];
--- a/browser/components/places/content/sidebarUtils.js
+++ b/browser/components/places/content/sidebarUtils.js
@@ -61,21 +61,21 @@ var SidebarUtils = {
       // selection as an indication of which link to load.
       tbo.view.selection.select(row.value);
       PlacesUIUtils.openNodeWithEvent(aTree.selectedNode, aEvent, aTree);
     }
   },
 
   handleTreeKeyPress: function SU_handleTreeKeyPress(aEvent) {
     // XXX Bug 627901: Post Fx4, this method should take a tree parameter.
-    let node = aEvent.target.selectedNode;
+    let tree = aEvent.target;
+    let node = tree.selectedNode;
     if (node) {
-      let view = PlacesUIUtils.getViewForNode(node);
       if (aEvent.keyCode == KeyEvent.DOM_VK_RETURN)
-        PlacesUIUtils.openNodeWithEvent(node, aEvent, view);
+        PlacesUIUtils.openNodeWithEvent(node, aEvent, tree);
     }
   },
 
   /**
    * The following function displays the URL of a node that is being
    * hovered over.
    */
   handleTreeMouseMove: function SU_handleTreeMouseMove(aEvent) {
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -1,12 +1,19 @@
 /* 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/. */
 
+Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
+
+const PTV_interfaces = [Ci.nsITreeView,
+                        Ci.nsINavHistoryResultObserver,
+                        Ci.nsINavHistoryResultTreeViewer,
+                        Ci.nsISupportsWeakReference];
+
 function PlacesTreeView(aFlatList, aOnOpenFlatContainer, aController) {
   this._tree = null;
   this._result = null;
   this._selection = null;
   this._rootNode = null;
   this._rows = [];
   this._flatList = aFlatList;
   this._openContainerCallback = aOnOpenFlatContainer;
@@ -34,25 +41,27 @@ PlacesTreeView.prototype = {
   get _dateService() {
     if (!this.__dateService) {
       this.__dateService = Cc["@mozilla.org/intl/scriptabledateformat;1"].
                            getService(Ci.nsIScriptableDateFormat);
     }
     return this.__dateService;
   },
 
-  QueryInterface: function PTV_QueryInterface(aIID) {
-    if (aIID.equals(Ci.nsITreeView) ||
-        aIID.equals(Ci.nsINavHistoryResultObserver) ||
-        aIID.equals(Ci.nsINavHistoryResultTreeViewer) ||
-        aIID.equals(Ci.nsISupportsWeakReference) ||
-        aIID.equals(Ci.nsISupports))
-      return this;
-    throw Cr.NS_ERROR_NO_INTERFACE;
-  },
+  QueryInterface: XPCOMUtils.generateQI(PTV_interfaces),
+
+  // Bug 761494:
+  // ----------
+  // Some addons use methods from nsINavHistoryResultObserver and
+  // nsINavHistoryResultTreeViewer, without QIing to these intefaces first.
+  // That's not a problem when the view is retrieved through the
+  // <tree>.view getter (which returns the wrappedJSObject of this object),
+  // it raises an issue when the view retrieved through the treeBoxObject.view
+  // getter.  Thus, to avoid breaking addons, the interfaces are prefetched.
+  classInfo: XPCOMUtils.generateCI({ interfaces: PTV_interfaces }),
 
   /**
    * This is called once both the result and the tree are set.
    */
   _finishInit: function PTV__finishInit() {
     let selection = this.selection;
     if (selection)
       selection.selectEventsSuppressed = true;
--- a/browser/components/privatebrowsing/test/unit/test_openLocationLastURL.js
+++ b/browser/components/privatebrowsing/test/unit/test_openLocationLastURL.js
@@ -1,69 +1,78 @@
 /* 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/. */
 
 // Test the correct behavior of the openLocationLastURL.jsm JS module.
 
 function run_test_on_service()
 {
-  Cu.import("resource:///modules/openLocationLastURL.jsm");
-
+  let openLocationModule = {};
+  // This variable fakes the window required for getting the PB flag
+  let window = { gPrivateBrowsingUI: { privateWindow: false } };
+  Cu.import("resource:///modules/openLocationLastURL.jsm", openLocationModule);
+  let gOpenLocationLastURL = new openLocationModule.OpenLocationLastURL(window);
+  
   function clearHistory() {
     // simulate clearing the private data
     Cc["@mozilla.org/observer-service;1"].
     getService(Ci.nsIObserverService).
     notifyObservers(null, "browser:purge-session-history", "");
   }
-
+  
   let pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
            getService(Ci.nsIPrivateBrowsingService);
   let pref = Cc["@mozilla.org/preferences-service;1"].
              getService(Ci.nsIPrefBranch);
   gOpenLocationLastURL.reset();
 
   do_check_eq(typeof gOpenLocationLastURL, "object");
   do_check_eq(gOpenLocationLastURL.value, "");
 
+  function switchPrivateBrowsing(flag) {
+    pb.privateBrowsingEnabled = flag;
+    window.gPrivateBrowsingUI.privateWindow = flag;
+  }
+
   const url1 = "mozilla.org";
   const url2 = "mozilla.com";
 
   gOpenLocationLastURL.value = url1;
   do_check_eq(gOpenLocationLastURL.value, url1);
 
   gOpenLocationLastURL.value = "";
   do_check_eq(gOpenLocationLastURL.value, "");
 
   gOpenLocationLastURL.value = url2;
   do_check_eq(gOpenLocationLastURL.value, url2);
 
   clearHistory();
   do_check_eq(gOpenLocationLastURL.value, "");
   gOpenLocationLastURL.value = url2;
 
-  pb.privateBrowsingEnabled = true;
+  switchPrivateBrowsing(true);
   do_check_eq(gOpenLocationLastURL.value, "");
-
-  pb.privateBrowsingEnabled = false;
+  
+  switchPrivateBrowsing(false);
   do_check_eq(gOpenLocationLastURL.value, url2);
-  pb.privateBrowsingEnabled = true;
+  switchPrivateBrowsing(true);
 
   gOpenLocationLastURL.value = url1;
   do_check_eq(gOpenLocationLastURL.value, url1);
 
-  pb.privateBrowsingEnabled = false;
+  switchPrivateBrowsing(false);
   do_check_eq(gOpenLocationLastURL.value, url2);
 
-  pb.privateBrowsingEnabled = true;
+  switchPrivateBrowsing(true);
   gOpenLocationLastURL.value = url1;
   do_check_neq(gOpenLocationLastURL.value, "");
   clearHistory();
   do_check_eq(gOpenLocationLastURL.value, "");
 
-  pb.privateBrowsingEnabled = false;
+  switchPrivateBrowsing(false);
   do_check_eq(gOpenLocationLastURL.value, "");
 }
 
 // Support running tests on both the service itself and its wrapper
 function run_test() {
   run_test_on_all_services();
 }
--- a/browser/modules/openLocationLastURL.jsm
+++ b/browser/modules/openLocationLastURL.jsm
@@ -1,65 +1,78 @@
 /* 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/. */
 
 const LAST_URL_PREF = "general.open_location.last_url";
 const nsISupportsString = Components.interfaces.nsISupportsString;
-
-var EXPORTED_SYMBOLS = [ "gOpenLocationLastURL" ];
+const Ci = Components.interfaces;
 
-let pbSvc = Components.classes["@mozilla.org/privatebrowsing;1"]
-                      .getService(Components.interfaces.nsIPrivateBrowsingService);
+var EXPORTED_SYMBOLS = [ "OpenLocationLastURL" ];
+
 let prefSvc = Components.classes["@mozilla.org/preferences-service;1"]
                         .getService(Components.interfaces.nsIPrefBranch);
+let gOpenLocationLastURLData = "";
 
 let observer = {
   QueryInterface: function (aIID) {
     if (aIID.equals(Components.interfaces.nsIObserver) ||
         aIID.equals(Components.interfaces.nsISupports) ||
         aIID.equals(Components.interfaces.nsISupportsWeakReference))
       return this;
     throw Components.results.NS_NOINTERFACE;
   },
   observe: function (aSubject, aTopic, aData) {
     switch (aTopic) {
-      case "private-browsing":
+      case "last-pb-context-exited":
         gOpenLocationLastURLData = "";
         break;
       case "browser:purge-session-history":
-        gOpenLocationLastURL.reset();
+        prefSvc.clearUserPref(LAST_URL_PREF);
+        gOpenLocationLastURLData = "";
         break;
     }
   }
 };
 
 let os = Components.classes["@mozilla.org/observer-service;1"]
                    .getService(Components.interfaces.nsIObserverService);
-os.addObserver(observer, "private-browsing", true);
+os.addObserver(observer, "last-pb-context-exited", true);
 os.addObserver(observer, "browser:purge-session-history", true);
 
-let gOpenLocationLastURLData = "";
-let gOpenLocationLastURL = {
+
+function OpenLocationLastURL(aWindow) {
+  this.window = aWindow;
+}
+
+OpenLocationLastURL.prototype = {
+  isPrivate: function OpenLocationLastURL_isPrivate() {
+    // Assume not in private browsing mode, unless the browser window is
+    // in private mode.
+    if (!this.window || !("gPrivateBrowsingUI" in this.window))
+      return false;
+  
+    return this.window.gPrivateBrowsingUI.privateWindow;
+  },
   get value() {
-    if (pbSvc.privateBrowsingEnabled)
+    if (this.isPrivate())
       return gOpenLocationLastURLData;
     else {
       try {
         return prefSvc.getComplexValue(LAST_URL_PREF, nsISupportsString).data;
       }
       catch (e) {
         return "";
       }
     }
   },
   set value(val) {
     if (typeof val != "string")
       val = "";
-    if (pbSvc.privateBrowsingEnabled)
+    if (this.isPrivate())
       gOpenLocationLastURLData = val;
     else {
       let str = Components.classes["@mozilla.org/supports-string;1"]
                           .createInstance(Components.interfaces.nsISupportsString);
       str.data = val;
       prefSvc.setComplexValue(LAST_URL_PREF, nsISupportsString, str);
     }
   },
--- a/build/mobile/robocop/FennecNativeActions.java.in
+++ b/build/mobile/robocop/FennecNativeActions.java.in
@@ -31,34 +31,36 @@ import org.json.*;
 import com.jayway.android.robotium.solo.Solo;
 
 import static @ANDROID_PACKAGE_NAME@.FennecNativeDriver.LogLevel;
 
 public class FennecNativeActions implements Actions {
     private Solo mSolo;
     private Instrumentation mInstr;
     private Activity mGeckoApp;
+    private Assert mAsserter;
 
     // Objects for reflexive access of fennec classes.
     private ClassLoader mClassLoader;
     private Class mGel;
     private Class mGe;
     private Class mGas;
     private Class mDrawListener;
     private Method mRegisterGEL;
     private Method mUnregisterGEL;
     private Method mSendGE;
     private Method mGetLayerClient;
     private Method mSetDrawListener;
     private static final String LOGTAG = "FennecNativeActions";
 
-    public FennecNativeActions(Activity activity, Solo robocop, Instrumentation instrumentation) {
+    public FennecNativeActions(Activity activity, Solo robocop, Instrumentation instrumentation, Assert asserter) {
         mSolo = robocop;
         mInstr = instrumentation;
         mGeckoApp = activity;
+        mAsserter = asserter;
         // Set up reflexive access of java classes and methods.
         try {
             mClassLoader = activity.getClassLoader();
             mGel = mClassLoader.loadClass("org.mozilla.gecko.GeckoEventListener");
             mGe = mClassLoader.loadClass("org.mozilla.gecko.GeckoEvent");
             mGas = mClassLoader.loadClass("org.mozilla.gecko.GeckoAppShell");
             Class [] parameters = new Class[2];
             parameters[0] = String.class;
@@ -112,30 +114,39 @@ public class FennecNativeActions impleme
             return null;
         }
     }
 
     class GeckoEventExpecter implements EventExpecter {
         private final String mGeckoEvent;
         private final Object[] mRegistrationParams;
         private boolean mEventReceived;
+        private static final int MAX_WAIT_MS = 90000;
 
         GeckoEventExpecter(String geckoEvent, Object[] registrationParams) {
             mGeckoEvent = geckoEvent;
             mRegistrationParams = registrationParams;
         }
 
         public synchronized void blockForEvent() {
+            long startTime = SystemClock.uptimeMillis();
+            long endTime = 0;
             while (! mEventReceived) {
                 try {
-                    this.wait();
+                    this.wait(MAX_WAIT_MS);
                 } catch (InterruptedException ie) {
                     FennecNativeDriver.log(LogLevel.ERROR, ie);
                     break;
                 }
+                endTime = SystemClock.uptimeMillis();
+                if (!mEventReceived && (endTime - startTime >= MAX_WAIT_MS)) {
+                    mAsserter.ok(false, "GeckoEventExpecter", 
+                        "blockForEvent timeout: "+mGeckoEvent);
+                    return;
+                }
             }
             FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG,
                 "unblocked on expecter for " + mGeckoEvent);
         }
 
         public synchronized boolean eventReceived() {
             return mEventReceived;
         }
@@ -217,37 +228,45 @@ public class FennecNativeActions impleme
             }
             return null;
         }
     }
 
     class PaintExpecter implements RepeatedEventExpecter {
         private Object mLayerClient;
         private boolean mPaintDone;
+        private static final int MAX_WAIT_MS = 90000;
 
         PaintExpecter() throws IllegalAccessException, InvocationTargetException {
             mLayerClient = mGetLayerClient.invoke(mGeckoApp);
             mSetDrawListener.invoke(mLayerClient, Proxy.newProxyInstance(mClassLoader, new Class[] { mDrawListener }, new DrawListenerProxy(this)));
         }
 
         void notifyOfEvent() {
             synchronized (this) {
                 mPaintDone = true;
                 this.notifyAll();
             }
         }
 
         public synchronized void blockForEvent() {
+            long startTime = SystemClock.uptimeMillis();
+            long endTime = 0;
             while (!mPaintDone) {
                 try {
-                    this.wait();
+                    this.wait(MAX_WAIT_MS);
                 } catch (InterruptedException ie) {
                     FennecNativeDriver.log(LogLevel.ERROR, ie);
                     break;
                 }
+                endTime = SystemClock.uptimeMillis();
+                if (!mPaintDone && (endTime - startTime >= MAX_WAIT_MS)) {
+                    mAsserter.ok(false, "PaintExpecter", "blockForEvent timeout");
+                    return;
+                }
             }
             try {
                 mSetDrawListener.invoke(mLayerClient, (Object)null);
             } catch (Exception e) {
                 FennecNativeDriver.log(LogLevel.ERROR, e);
             }
         }
 
@@ -255,34 +274,41 @@ public class FennecNativeActions impleme
             return mPaintDone;
         }
 
         public synchronized void blockUntilClear(long millis) {
             if (millis <= 0) {
                 throw new IllegalArgumentException("millis must be > 0");
             }
             // wait for at least one event
+            long startTime = SystemClock.uptimeMillis();
+            long endTime = 0;
             while (!mPaintDone) {
                 try {
-                    this.wait();
+                    this.wait(MAX_WAIT_MS);
                 } catch (InterruptedException ie) {
                     FennecNativeDriver.log(LogLevel.ERROR, ie);
                     break;
                 }
+                endTime = SystemClock.uptimeMillis();
+                if (!mPaintDone && (endTime - startTime >= MAX_WAIT_MS)) {
+                    mAsserter.ok(false, "PaintExpecter", "blockUtilClear timeout");
+                    return;
+                }
             }
             // now wait for a period of millis where we don't get an event
-            long startTime = SystemClock.uptimeMillis();
+            startTime = SystemClock.uptimeMillis();
             while (true) {
                 try {
                     this.wait(millis);
                 } catch (InterruptedException ie) {
                     FennecNativeDriver.log(LogLevel.ERROR, ie);
                     break;
                 }
-                long endTime = SystemClock.uptimeMillis();
+                endTime = SystemClock.uptimeMillis();
                 if (endTime - startTime >= millis) {
                     // success
                     break;
                 }
                 // we got a notify() before we could wait long enough, so we need to start over
                 startTime = endTime;
             }
             try {
--- a/caps/idl/nsIScriptSecurityManager.idl
+++ b/caps/idl/nsIScriptSecurityManager.idl
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 #include "nsIPrincipal.idl"
 #include "nsIXPCSecurityManager.idl"
 interface nsIURI;
 interface nsIChannel;
 
-[scriptable, uuid(3708aa92-e2d9-4fd1-9e46-edfa3eb5ebf5)]
+[scriptable, uuid(cdb27711-492b-4973-938b-de81ac124658)]
 interface nsIScriptSecurityManager : nsIXPCSecurityManager
 {
     ///////////////// Security Checks //////////////////
     /**
      * Checks whether the running script is allowed to access aProperty.
      */
     [noscript] void checkPropertyAccess(in JSContextPtr aJSContext,
                                         in JSObjectPtr aJSObject,
@@ -255,37 +255,14 @@ interface nsIScriptSecurityManager : nsI
      * Same as getSubjectPrincipal(), only faster. cx must *never* be
      * passed null, and it must be the context on the top of the
      * context stack. Does *not* reference count the returned
      * principal.
      */
     [noscript,notxpcom] nsIPrincipal getCxSubjectPrincipal(in JSContextPtr cx);
     [noscript,notxpcom] nsIPrincipal getCxSubjectPrincipalAndFrame(in JSContextPtr cx,
                                                                    out JSStackFramePtr fp);
-
-    /**
-     * If no scripted code is running "above" (or called from) fp, then
-     * instead of looking at cx->globalObject, we will return |principal|.
-     * This function only affects |cx|. If someone pushes another context onto
-     * the context stack, then it supersedes this call.
-     * NOTE: If |fp| is non-null popContextPrincipal must be called before fp
-     * has finished executing.
-     *
-     * @param cx The context to clamp.
-     * @param fp The frame pointer to clamp at. May be 'null'.
-     * @param principal The principal to clamp to.
-     */
-    [noscript] void pushContextPrincipal(in JSContextPtr cx,
-                                         in JSStackFramePtr fp,
-                                         in nsIPrincipal principal);
-
-    /**
-     * Removes a clamp set by pushContextPrincipal from cx. This must be
-     * called in a stack-like fashion (e.g., given two contexts |a| and |b|,
-     * it is not legal to do: push(a) push(b) pop(a)).
-     */
-    [noscript] void popContextPrincipal(in JSContextPtr cx);
 };
 
 %{C++
 #define NS_SCRIPTSECURITYMANAGER_CONTRACTID "@mozilla.org/scriptsecuritymanager;1"
 #define NS_SCRIPTSECURITYMANAGER_CLASSNAME "scriptsecuritymanager"
 %}
--- a/caps/include/nsScriptSecurityManager.h
+++ b/caps/include/nsScriptSecurityManager.h
@@ -398,22 +398,21 @@ private:
     ObjectPrincipalFinder(JSObject *obj);
     
     // Decides, based on CSP, whether or not eval() and stuff can be executed.
     static JSBool
     ContentSecurityPolicyPermitsJSAction(JSContext *cx);
 
     // Returns null if a principal cannot be found; generally callers
     // should error out at that point.
-    static nsIPrincipal*
-    doGetObjectPrincipal(JSObject *obj
+    static nsIPrincipal* doGetObjectPrincipal(JSObject *obj);
 #ifdef DEBUG
-                         , bool aAllowShortCircuit = true
+    static nsIPrincipal*
+    old_doGetObjectPrincipal(JSObject *obj, bool aAllowShortCircuit = true);
 #endif
-                         );
 
     // Returns null if a principal cannot be found.  Note that rv can be NS_OK
     // when this happens -- this means that there was no JS running.
     nsIPrincipal*
     doGetSubjectPrincipal(nsresult* rv);
     
     nsresult
     CheckPropertyAccessImpl(PRUint32 aAction,
@@ -549,40 +548,28 @@ private:
     nsresult
     InitPrincipals(PRUint32 prefCount, const char** prefNames);
 
 #ifdef DEBUG_CAPS_HACKER
     void
     PrintPolicyDB();
 #endif
 
-    struct ContextPrincipal {
-        ContextPrincipal(ContextPrincipal *next, JSContext *cx,
-                         JSStackFrame *fp, nsIPrincipal *principal)
-            : mNext(next), mCx(cx), mFp(fp), mPrincipal(principal) {}
-
-        ContextPrincipal *mNext;
-        JSContext *mCx;
-        JSStackFrame *mFp;
-        nsCOMPtr<nsIPrincipal> mPrincipal;
-    };
-
     // JS strings we need to clean up on shutdown
     static jsid sEnabledID;
 
     inline void
     ScriptSecurityPrefChanged();
 
     nsObjectHashtable* mOriginToPolicyMap;
     DomainPolicy* mDefaultPolicy;
     nsObjectHashtable* mCapabilities;
 
     nsCOMPtr<nsIPrincipal> mSystemPrincipal;
     nsCOMPtr<nsIPrincipal> mSystemCertificate;
-    ContextPrincipal *mContextPrincipals;
     nsInterfaceHashtable<PrincipalKey, nsIPrincipal> mPrincipals;
     bool mPrefInitialized;
     bool mIsJavaScriptEnabled;
     bool mIsWritingPrefs;
     bool mPolicyPrefsChanged;
 
     static bool sStrictFileOriginPolicy;
 
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -158,54 +158,16 @@ GetPrincipalDomainOrigin(nsIPrincipal* a
 }
 
 static nsIScriptContext *
 GetScriptContext(JSContext *cx)
 {
     return GetScriptContextFromJSContext(cx);
 }
 
-// Callbacks for the JS engine to use to push/pop context principals.
-static JSBool
-PushPrincipalCallback(JSContext *cx, JSPrincipals *principals)
-{
-    // We should already be in the compartment of the given principal.
-    MOZ_ASSERT(principals ==
-               JS_GetCompartmentPrincipals((js::GetContextCompartment(cx))));
-
-    // Get the security manager.
-    nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
-    if (!ssm) {
-        return true;
-    }
-
-    // Push the principal.
-    JSStackFrame *fp = NULL;
-    nsresult rv = ssm->PushContextPrincipal(cx, JS_FrameIterator(cx, &fp),
-                                            nsJSPrincipals::get(principals));
-    if (NS_FAILED(rv)) {
-        JS_ReportOutOfMemory(cx);
-        return false;
-    }
-
-    return true;
-}
-
-static JSBool
-PopPrincipalCallback(JSContext *cx)
-{
-    nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
-    if (ssm) {
-        ssm->PopContextPrincipal(cx);
-    }
-
-    return true;
-}
-
-
 inline void SetPendingException(JSContext *cx, const char *aMsg)
 {
     JSAutoRequest ar(cx);
     JS_ReportError(cx, "%s", aMsg);
 }
 
 inline void SetPendingException(JSContext *cx, const PRUnichar *aMsg)
 {
@@ -400,44 +362,16 @@ nsScriptSecurityManager::GetCxSubjectPri
     nsresult rv = NS_ERROR_FAILURE;
     nsIPrincipal *principal = GetPrincipalAndFrame(cx, fp, &rv);
     if (NS_FAILED(rv))
         return nsnull;
 
     return principal;
 }
 
-NS_IMETHODIMP
-nsScriptSecurityManager::PushContextPrincipal(JSContext *cx,
-                                              JSStackFrame *fp,
-                                              nsIPrincipal *principal)
-{
-    NS_ASSERTION(principal, "Must pass a non-null principal");
-
-    ContextPrincipal *cp = new ContextPrincipal(mContextPrincipals, cx, fp,
-                                                principal);
-    if (!cp)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    mContextPrincipals = cp;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsScriptSecurityManager::PopContextPrincipal(JSContext *cx)
-{
-    NS_ASSERTION(mContextPrincipals->mCx == cx, "Mismatched push/pop");
-
-    ContextPrincipal *next = mContextPrincipals->mNext;
-    delete mContextPrincipals;
-    mContextPrincipals = next;
-
-    return NS_OK;
-}
-
 ////////////////////
 // Policy Storage //
 ////////////////////
 
 // Table of security levels
 static bool
 DeleteCapability(nsHashKey *aKey, void *aData, void* closure)
 {
@@ -2299,62 +2233,29 @@ nsScriptSecurityManager::GetPrincipalAnd
 {
     NS_PRECONDITION(rv, "Null out param");
     //-- If there's no principal on the stack, look at the global object
     //   and return the innermost frame for annotations.
     *rv = NS_OK;
 
     if (cx)
     {
-        JSStackFrame *target = nsnull;
-        nsIPrincipal *targetPrincipal = nsnull;
-        for (ContextPrincipal *cp = mContextPrincipals; cp; cp = cp->mNext)
-        {
-            if (cp->mCx == cx)
-            {
-                target = cp->mFp;
-                targetPrincipal = cp->mPrincipal;
-                break;
-            }
-        }
-
         // Get principals from innermost JavaScript frame.
         JSStackFrame *fp = nsnull; // tell JS_FrameIterator to start at innermost
         for (fp = JS_FrameIterator(cx, &fp); fp; fp = JS_FrameIterator(cx, &fp))
         {
-            if (fp == target)
-                break;
             nsIPrincipal* result = GetFramePrincipal(cx, fp, rv);
             if (result)
             {
                 NS_ASSERTION(NS_SUCCEEDED(*rv), "Weird return");
                 *frameResult = fp;
                 return result;
             }
         }
 
-        // If targetPrincipal is non-null, then it means that someone wants to
-        // clamp the principals on this context to this principal. Note that
-        // fp might not equal target here (fp might be null) because someone
-        // could have set aside the frame chain in the meantime.
-        if (targetPrincipal)
-        {
-            if (fp && fp == target)
-            {
-                *frameResult = fp;
-            }
-            else
-            {
-                JSStackFrame *inner = nsnull;
-                *frameResult = JS_FrameIterator(cx, &inner);
-            }
-
-            return targetPrincipal;
-        }
-
         nsIScriptContextPrincipal* scp =
             GetScriptContextPrincipalFromJSContext(cx);
         if (scp)
         {
             nsIScriptObjectPrincipal* globalData = scp->GetObjectPrincipal();
             if (!globalData)
             {
                 *rv = NS_ERROR_FAILURE;
@@ -2375,47 +2276,67 @@ nsScriptSecurityManager::GetPrincipalAnd
 
     return nsnull;
 }
 
 nsIPrincipal*
 nsScriptSecurityManager::GetSubjectPrincipal(JSContext *cx,
                                              nsresult* rv)
 {
-    NS_PRECONDITION(rv, "Null out param");
-    JSStackFrame *fp;
-    return GetPrincipalAndFrame(cx, &fp, rv);
+    *rv = NS_OK;
+    JSCompartment *compartment = js::GetContextCompartment(cx);
+
+    // The context should always be in a compartment, either one it has entered
+    // or the one associated with its global.
+    MOZ_ASSERT(!!compartment);
+
+    JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment);
+    return nsJSPrincipals::get(principals);
 }
 
 NS_IMETHODIMP
 nsScriptSecurityManager::GetObjectPrincipal(JSContext *aCx, JSObject *aObj,
                                             nsIPrincipal **result)
 {
     *result = doGetObjectPrincipal(aObj);
     if (!*result)
         return NS_ERROR_FAILURE;
     NS_ADDREF(*result);
     return NS_OK;
 }
 
 // static
 nsIPrincipal*
-nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
+nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj)
+{
+    JSCompartment *compartment = js::GetObjectCompartment(aObj);
+    JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment);
+    nsIPrincipal *principal = nsJSPrincipals::get(principals);
+
+    // We leave the old code in for a little while to make sure that pulling
+    // object principals directly off the compartment always gives an equivalent
+    // result (from a security perspective).
 #ifdef DEBUG
-                                              , bool aAllowShortCircuit
+    nsIPrincipal *old = old_doGetObjectPrincipal(aObj);
+    MOZ_ASSERT(NS_SUCCEEDED(CheckSameOriginPrincipal(principal, old)));
 #endif
-                                              )
+
+    return principal;
+}
+
+#ifdef DEBUG
+// static
+nsIPrincipal*
+nsScriptSecurityManager::old_doGetObjectPrincipal(JSObject *aObj,
+                                                  bool aAllowShortCircuit)
 {
     NS_ASSERTION(aObj, "Bad call to doGetObjectPrincipal()!");
     nsIPrincipal* result = nsnull;
 
-#ifdef DEBUG
     JSObject* origObj = aObj;
-#endif
-    
     js::Class *jsClass = js::GetObjectClass(aObj);
 
     // A common case seen in this code is that we enter this function
     // with aObj being a Function object, whose parent is a Call
     // object. Neither of those have object principals, so we can skip
     // those objects here before we enter the below loop. That way we
     // avoid wasting time checking properties of their classes etc in
     // the loop.
@@ -2439,48 +2360,41 @@ nsScriptSecurityManager::doGetObjectPrin
     }
 
     do {
         // Note: jsClass is set before this loop, and also at the
         // *end* of this loop.
         
         if (IS_WRAPPER_CLASS(jsClass)) {
             result = sXPConnect->GetPrincipal(aObj,
-#ifdef DEBUG
-                                              aAllowShortCircuit
-#else
-                                              true
-#endif
-                                              );
+                                              aAllowShortCircuit);
             if (result) {
                 break;
             }
         } else {
             nsISupports *priv;
             if (!(~jsClass->flags & (JSCLASS_HAS_PRIVATE |
                                      JSCLASS_PRIVATE_IS_NSISUPPORTS))) {
                 priv = (nsISupports *) js::GetObjectPrivate(aObj);
             } else if (IsDOMClass(jsClass) &&
                        DOMJSClass::FromJSClass(jsClass)->mDOMObjectIsISupports) {
                 priv = UnwrapDOMObject<nsISupports>(aObj);
             } else {
                 priv = nsnull;
             }
 
-#ifdef DEBUG
             if (aAllowShortCircuit) {
                 nsCOMPtr<nsIXPConnectWrappedNative> xpcWrapper =
                     do_QueryInterface(priv);
 
                 NS_ASSERTION(!xpcWrapper ||
                              !strcmp(jsClass->name, "XPCNativeWrapper"),
                              "Uh, an nsIXPConnectWrappedNative with the "
                              "wrong JSClass or getObjectOps hooks!");
             }
-#endif
 
             nsCOMPtr<nsIScriptObjectPrincipal> objPrin =
                 do_QueryInterface(priv);
 
             if (objPrin) {
                 result = objPrin->GetPrincipal();
 
                 if (result) {
@@ -2492,63 +2406,47 @@ nsScriptSecurityManager::doGetObjectPrin
         aObj = js::GetObjectParentMaybeScope(aObj);
 
         if (!aObj)
             break;
 
         jsClass = js::GetObjectClass(aObj);
     } while (1);
 
-#ifdef DEBUG
     if (aAllowShortCircuit) {
-        nsIPrincipal *principal = doGetObjectPrincipal(origObj, false);
+        nsIPrincipal *principal = old_doGetObjectPrincipal(origObj, false);
 
         // Because of inner window reuse, we can have objects with one principal
         // living in a scope with a different (but same-origin) principal. So
         // just check same-origin here.
         NS_ASSERTION(NS_SUCCEEDED(CheckSameOriginPrincipal(result, principal)),
                      "Principal mismatch.  Not good");
     }
-#endif
 
     return result;
 }
+#endif /* DEBUG */
 
 ///////////////// Capabilities API /////////////////////
 NS_IMETHODIMP
 nsScriptSecurityManager::IsCapabilityEnabled(const char *capability,
                                              bool *result)
 {
     nsresult rv;
     JSStackFrame *fp = nsnull;
     JSContext *cx = GetCurrentJSContext();
     fp = cx ? JS_FrameIterator(cx, &fp) : nsnull;
 
-    JSStackFrame *target = nsnull;
-    nsIPrincipal *targetPrincipal = nsnull;
-    for (ContextPrincipal *cp = mContextPrincipals; cp; cp = cp->mNext)
-    {
-        if (cp->mCx == cx)
-        {
-            target = cp->mFp;
-            targetPrincipal = cp->mPrincipal;
-            break;
-        }
-    }
-
     if (!fp)
     {
-        // No script code on stack. If we had a principal pushed for this
-        // context and fp is null, then we use that principal. Otherwise, we
-        // don't have enough information and have to allow execution.
-
-        *result = (targetPrincipal && !target)
-                  ? (targetPrincipal == mSystemPrincipal)
-                  : true;
-
+        // No script code on stack. Allow access if and only if the subject
+        // principal is system.
+        nsresult ignored;
+        nsIPrincipal *subjectPrin = doGetSubjectPrincipal(&ignored);
+        *result = (!subjectPrin || subjectPrin == mSystemPrincipal);
         return NS_OK;
     }
 
     *result = false;
     nsIPrincipal* previousPrincipal = nsnull;
     do
     {
         nsIPrincipal* principal = GetFramePrincipal(cx, fp, &rv);
@@ -2581,17 +2479,17 @@ nsScriptSecurityManager::IsCapabilityEna
         if (NS_FAILED(rv)) return rv;
         if (*result)
             return NS_OK;
 
         // Capabilities do not extend to calls into C/C++ and then back into
         // the JS engine via JS_EvaluateScript or similar APIs.
         if (JS_IsGlobalFrame(cx, fp))
             break;
-    } while (fp != target && (fp = JS_FrameIterator(cx, &fp)) != nsnull);
+    } while ((fp = JS_FrameIterator(cx, &fp)) != nsnull);
 
     if (!previousPrincipal)
     {
         // No principals on the stack, all native code.  Allow
         // execution if the subject principal is the system principal.
 
         return SubjectPrincipalIsSystem(result);
     }
@@ -3065,17 +2963,16 @@ nsScriptSecurityManager::Observe(nsISupp
 
 /////////////////////////////////////////////
 // Constructor, Destructor, Initialization //
 /////////////////////////////////////////////
 nsScriptSecurityManager::nsScriptSecurityManager(void)
     : mOriginToPolicyMap(nsnull),
       mDefaultPolicy(nsnull),
       mCapabilities(nsnull),
-      mContextPrincipals(nsnull),
       mPrefInitialized(false),
       mIsJavaScriptEnabled(false),
       mIsWritingPrefs(false),
       mPolicyPrefsChanged(true)
 {
     MOZ_STATIC_ASSERT(sizeof(intptr_t) == sizeof(void*),
                       "intptr_t and void* have different lengths on this platform. "
                       "This may cause a security failure with the SecurityLevel union.");
@@ -3126,19 +3023,17 @@ nsresult nsScriptSecurityManager::Init()
 
     rv = runtimeService->GetRuntime(&sRuntime);
     NS_ENSURE_SUCCESS(rv, rv);
 
     static const JSSecurityCallbacks securityCallbacks = {
         CheckObjectAccess,
         nsJSPrincipals::Subsume,
         ObjectPrincipalFinder,
-        ContentSecurityPolicyPermitsJSAction,
-        PushPrincipalCallback,
-        PopPrincipalCallback
+        ContentSecurityPolicyPermitsJSAction
     };
 
     MOZ_ASSERT(!JS_GetSecurityCallbacks(sRuntime));
     JS_SetSecurityCallbacks(sRuntime, &securityCallbacks);
     JS_InitDestroyPrincipalsCallback(sRuntime, nsJSPrincipals::Destroy);
 
     JS_SetTrustedPrincipals(sRuntime, system);
 
@@ -3147,17 +3042,16 @@ nsresult nsScriptSecurityManager::Init()
 
 static nsRefPtr<nsScriptSecurityManager> gScriptSecMan;
 
 jsid nsScriptSecurityManager::sEnabledID   = JSID_VOID;
 
 nsScriptSecurityManager::~nsScriptSecurityManager(void)
 {
     Preferences::RemoveObservers(this, kObservedPrefs);
-    NS_ASSERTION(!mContextPrincipals, "Leaking mContextPrincipals");
     delete mOriginToPolicyMap;
     if(mDefaultPolicy)
         mDefaultPolicy->Drop();
     delete mCapabilities;
 }
 
 void
 nsScriptSecurityManager::Shutdown()
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -252,17 +252,17 @@ nsFrameMessageManager::SendAsyncMessage(
   }
   return SendAsyncMessageInternal(aMessageName, json);
 }
 
 NS_IMETHODIMP
 nsFrameMessageManager::Dump(const nsAString& aStr)
 {
 #ifdef ANDROID
-  __android_log_print(ANDROID_LOG_INFO, "Gecko", NS_ConvertUTF16toUTF8(aStr).get());
+  __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", NS_ConvertUTF16toUTF8(aStr).get());
 #endif
   fputs(NS_ConvertUTF16toUTF8(aStr).get(), stdout);
   fflush(stdout);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFrameMessageManager::PrivateNoteIntentionalCrash()
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -208,24 +208,30 @@ nsEventListenerManager::AddEventListener
 
   mNoListenerForEvent = NS_EVENT_TYPE_NULL;
   mNoListenerForEventAtom = nsnull;
 
   ls = mListeners.AppendElement();
   ls->mListener = aListener;
   ls->mEventType = aType;
   ls->mTypeAtom = aTypeAtom;
-  ls->mWrappedJS = false;
   ls->mFlags = aFlags;
   ls->mHandlerIsString = false;
 
-  nsCOMPtr<nsIXPConnectWrappedJS> wjs = do_QueryInterface(aListener);
-  if (wjs) {
-    ls->mWrappedJS = true;
+  // Detect the type of event listener.
+  nsCOMPtr<nsIXPConnectWrappedJS> wjs;
+  if (aFlags & NS_PRIV_EVENT_FLAG_SCRIPT) {
+    ls->mListenerType = eJSEventListener;
+  } else if ((wjs = do_QueryInterface(aListener))) {
+    ls->mListenerType = eWrappedJSListener;
+  } else {
+    ls->mListenerType = eNativeListener;
   }
+
+
   if (aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) {
     mMayHaveSystemGroupListeners = true;
   }
   if (aFlags & NS_EVENT_FLAG_CAPTURE) {
     mMayHaveCapturingListeners = true;
   }
 
   if (aType == NS_AFTERPAINT) {
@@ -453,17 +459,18 @@ nsEventListenerManager::FindJSEventListe
 {
   // Run through the listeners for this type and see if a script
   // listener is registered
   nsListenerStruct *ls;
   PRUint32 count = mListeners.Length();
   for (PRUint32 i = 0; i < count; ++i) {
     ls = &mListeners.ElementAt(i);
     if (EVENT_TYPE_EQUALS(ls, aEventType, aTypeAtom) &&
-        ls->mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) {
+        (ls->mListenerType == eJSEventListener))
+    {
       return ls;
     }
   }
   return nsnull;
 }
 
 nsresult
 nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext,
@@ -791,17 +798,17 @@ nsEventListenerManager::HandleEventSubTy
                                            nsIDOMEventTarget* aCurrentTarget,
                                            PRUint32 aPhaseFlags,
                                            nsCxPusher* aPusher)
 {
   nsresult result = NS_OK;
 
   // If this is a script handler and we haven't yet
   // compiled the event handler itself
-  if ((aListenerStruct->mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) &&
+  if ((aListenerStruct->mListenerType == eJSEventListener) &&
       aListenerStruct->mHandlerIsString) {
     nsIJSEventListener *jslistener = aListenerStruct->GetJSListener();
     result = CompileEventHandlerInternal(aListenerStruct,
                                          jslistener->GetEventContext() !=
                                            aPusher->GetCurrentScriptContext(),
                                          nsnull);
   }
 
@@ -858,23 +865,38 @@ nsEventListenerManager::HandleEventInter
         }
         if (*aDOMEvent) {
           if (!aEvent->currentTarget) {
             aEvent->currentTarget = aCurrentTarget->GetTargetForDOMEvent();
             if (!aEvent->currentTarget) {
               break;
             }
           }
+
+          // Push the appropriate context. Note that we explicitly don't push a
+          // context in the case that the listener is non-scripted, in which case
+          // it's the native code's responsibility to push a context if it ever
+          // enters JS. Ideally we'd do things this way for all scripted callbacks,
+          // but that would involve a lot of changes and context pushing is going
+          // away soon anyhow.
+          //
+          // NB: Since we're looping here, the no-RePush() case needs to actually be
+          // a Pop(), otherwise we might end up with whatever was pushed in a
+          // previous iteration.
+          if (ls->mListenerType == eNativeListener) {
+            aPusher->Pop();
+          } else if (!aPusher->RePush(aCurrentTarget)) {
+            continue;
+          }
+
           nsRefPtr<nsIDOMEventListener> kungFuDeathGrip = ls->mListener;
-          if (aPusher->RePush(aCurrentTarget)) {
-            if (NS_FAILED(HandleEventSubType(ls, ls->mListener, *aDOMEvent,
-                                             aCurrentTarget, aFlags,
-                                             aPusher))) {
-              aEvent->flags |= NS_EVENT_FLAG_EXCEPTION_THROWN;
-            }
+          if (NS_FAILED(HandleEventSubType(ls, ls->mListener, *aDOMEvent,
+                                           aCurrentTarget, aFlags,
+                                           aPusher))) {
+            aEvent->flags |= NS_EVENT_FLAG_EXCEPTION_THROWN;
           }
         }
       }
     }
   }
 
   aEvent->currentTarget = nsnull;
 
@@ -987,17 +1009,17 @@ nsEventListenerManager::GetListenerInfo(
   PRUint32 count = mListeners.Length();
   for (PRUint32 i = 0; i < count; ++i) {
     const nsListenerStruct& ls = mListeners.ElementAt(i);
     bool capturing = !!(ls.mFlags & NS_EVENT_FLAG_CAPTURE);
     bool systemGroup = !!(ls.mFlags & NS_EVENT_FLAG_SYSTEM_EVENT);
     bool allowsUntrusted = !!(ls.mFlags & NS_PRIV_EVENT_UNTRUSTED_PERMITTED);
     // If this is a script handler and we haven't yet
     // compiled the event handler itself go ahead and compile it
-    if ((ls.mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) && ls.mHandlerIsString) {
+    if ((ls.mListenerType == eJSEventListener) && ls.mHandlerIsString) {
       CompileEventHandlerInternal(const_cast<nsListenerStruct*>(&ls),
                                   true, nsnull);
     }
     const nsDependentSubstring& eventType =
       Substring(nsDependentAtomString(ls.mTypeAtom), 2);
     nsRefPtr<nsEventListenerInfo> info =
       new nsEventListenerInfo(eventType, ls.mListener, capturing,
                               allowsUntrusted, systemGroup);
@@ -1102,13 +1124,13 @@ nsEventListenerManager::UnmarkGrayJSList
 {
   PRUint32 count = mListeners.Length();
   for (PRUint32 i = 0; i < count; ++i) {
     const nsListenerStruct& ls = mListeners.ElementAt(i);
     nsIJSEventListener* jsl = ls.GetJSListener();
     if (jsl) {
       xpc_UnmarkGrayObject(jsl->GetHandler());
       xpc_UnmarkGrayObject(jsl->GetEventScope());
-    } else if (ls.mWrappedJS) {
+    } else if (ls.mListenerType == eWrappedJSListener) {
       xpc_TryUnmarkWrappedGrayObject(ls.mListener);
     }
   }
 }
--- a/content/events/src/nsEventListenerManager.h
+++ b/content/events/src/nsEventListenerManager.h
@@ -26,33 +26,40 @@ class nsIWidget;
 struct nsPoint;
 struct EventTypeData;
 class nsEventTargetChainItem;
 class nsPIDOMWindow;
 class nsCxPusher;
 class nsIEventListenerInfo;
 class nsIDocument;
 
+typedef enum
+{
+    eNativeListener = 0,
+    eJSEventListener,
+    eWrappedJSListener
+} nsListenerType;
+
 struct nsListenerStruct
 {
   nsRefPtr<nsIDOMEventListener> mListener;
   PRUint32                      mEventType;
   nsCOMPtr<nsIAtom>             mTypeAtom;
   PRUint16                      mFlags;
+  PRUint8                       mListenerType;
   bool                          mHandlerIsString;
-  bool                          mWrappedJS;
 
   nsIJSEventListener* GetJSListener() const {
-    return (mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) ?
+    return (mListenerType == eJSEventListener) ?
       static_cast<nsIJSEventListener *>(mListener.get()) : nsnull;
   }
 
   ~nsListenerStruct()
   {
-    if ((mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) && mListener) {
+    if ((mListenerType == eJSEventListener) && mListener) {
       static_cast<nsIJSEventListener*>(mListener.get())->Disconnect();
     }
   }
 };
 
 /*
  * Event listener manager
  */
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -275,16 +275,22 @@ nsXBLPrototypeHandler::ExecuteHandler(ns
   nsISupports *scriptTarget;
 
   if (winRoot) {
     scriptTarget = boundGlobal;
   } else {
     scriptTarget = aTarget;
   }
 
+  // We're about to create a new nsJSEventListener, which means that we're
+  // responsible for pushing the context of the event target. See the similar
+  // comment in nsEventManagerListener.cpp.
+  nsCxPusher pusher;
+  NS_ENSURE_STATE(pusher.Push(aTarget));
+
   rv = EnsureEventHandler(boundGlobal, boundContext, onEventAtom, handler);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Bind it to the bound element
   JSObject* scope = boundGlobal->GetGlobalJSObject();
   nsScriptObjectHolder<JSObject> boundHandler(boundContext);
   rv = boundContext->BindCompiledEventHandler(scriptTarget, scope,
                                               handler.get(), boundHandler);
--- a/dom/base/IndexedDBHelper.jsm
+++ b/dom/base/IndexedDBHelper.jsm
@@ -41,17 +41,17 @@ IndexedDBHelper.prototype = {
    * @param successCb
    *        Success callback to call once database is open.
    * @param failureCb
    *        Error callback to call when an error is encountered.
    */
   open: function open(aSuccessCb, aFailureCb) {
     let self = this;
     debug("Try to open database:" + self.dbName + " " + self.dbVersion);
-    let req = this.dbGlobal.mozIndexedDB.open(this.dbName, this.dbVersion);
+    let req = this.dbGlobal.indexedDB.open(this.dbName, this.dbVersion);
     req.onsuccess = function (event) {
       debug("Opened database:" + self.dbName + " " + self.dbName);
       self._db = event.target.result;
       self._db.onversionchange = function(event) {
         debug("WARNING: DB modified from a different window.");
       }
       aSuccessCb();
     };
@@ -130,17 +130,17 @@ IndexedDBHelper.prototype = {
    * 
    * @param aDBName
    *        DB name for the open call.
    * @param aDBVersion
    *        Current DB version. User has to implement upgradeSchema.
    * @param aDBStoreName
    *        ObjectStore that is used.
    * @param aGlobal
-   *        Global object that has mozIndexedDB property.
+   *        Global object that has indexedDB property.
    */
   initDBHelper: function initDBHelper(aDBName, aDBVersion, aDBStoreName, aGlobal) {
     this.dbName = aDBName;
     this.dbVersion = aDBVersion;
     this.dbStoreName = aDBStoreName;
     this.dbGlobal = aGlobal;
   }
 }
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -8239,17 +8239,17 @@ nsGlobalWindow::GetLocalStorage(nsIDOMSt
   return NS_OK;
 }
 
 //*****************************************************************************
 // nsGlobalWindow::nsIDOMStorageIndexedDB
 //*****************************************************************************
 
 NS_IMETHODIMP
-nsGlobalWindow::GetMozIndexedDB(nsIIDBFactory** _retval)
+nsGlobalWindow::GetIndexedDB(nsIIDBFactory** _retval)
 {
   if (!mIndexedDB) {
     nsresult rv;
 
     if (!IsChromeWindow()) {
       nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
         do_GetService(THIRDPARTYUTIL_CONTRACTID);
       NS_ENSURE_TRUE(thirdPartyUtil, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1194,56 +1194,55 @@ nsJSContext::EvaluateStringWithValue(con
     }
 
     return NS_OK;
   }
 
   xpc_UnmarkGrayObject(aScopeObject);
   nsAutoMicroTask mt;
 
-  // Safety first: get an object representing the script's principals, i.e.,
-  // the entities who signed this script, or the fully-qualified-domain-name
-  // or "codebase" from which it was loaded.
-  nsCOMPtr<nsIPrincipal> principal = aPrincipal;
-  nsresult rv;
-  if (!aPrincipal) {
-    nsIScriptGlobalObject *global = GetGlobalObject();
-    if (!global)
-      return NS_ERROR_FAILURE;
-    nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
-      do_QueryInterface(global, &rv);
-    if (NS_FAILED(rv))
-      return NS_ERROR_FAILURE;
-    principal = objPrincipal->GetPrincipal();
-    if (!principal)
-      return NS_ERROR_FAILURE;
-  }
+  // Ignore the principal that was passed in, and just assert that it matches
+  // the one we pull off the global.
+  nsCOMPtr<nsIPrincipal> principal;
+  nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal = do_QueryInterface(GetGlobalObject());
+  if (!objPrincipal)
+    return NS_ERROR_FAILURE;
+  principal = objPrincipal->GetPrincipal();
+  if (!principal)
+    return NS_ERROR_FAILURE;
+#ifdef DEBUG
+  bool equal = false;
+  principal->Equals(aPrincipal, &equal);
+  MOZ_ASSERT(equal);
+  nsIPrincipal *scopeObjectPrincipal =
+    nsJSPrincipals::get(JS_GetCompartmentPrincipals(js::GetObjectCompartment(aScopeObject)));
+  equal = false;
+  principal->Equals(scopeObjectPrincipal, &equal);
+  MOZ_ASSERT(equal);
+#endif
 
   bool ok = false;
 
-  rv = sSecurityManager->CanExecuteScripts(mContext, principal, &ok);
+  nsresult rv = sSecurityManager->CanExecuteScripts(mContext, principal, &ok);
   if (NS_FAILED(rv)) {
     return NS_ERROR_FAILURE;
   }
 
   // Push our JSContext on the current thread's context stack so JS called
   // from native code via XPConnect uses the right context.  Do this whether
   // or not the SecurityManager said "ok", in order to simplify control flow
   // below where we pop before returning.
   nsCOMPtr<nsIJSContextStack> stack =
            do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
   if (NS_FAILED(rv) || NS_FAILED(stack->Push(mContext))) {
     return NS_ERROR_FAILURE;
   }
 
   jsval val;
 
-  rv = sSecurityManager->PushContextPrincipal(mContext, nsnull, principal);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   nsJSContext::TerminationFuncHolder holder(this);
 
   // SecurityManager said "ok", but don't compile if aVersion is unknown.
   // Since the caller is responsible for parsing the version strings, we just
   // check it isn't JSVERSION_UNKNOWN.
   if (ok && ((JSVersion)aVersion) != JSVERSION_UNKNOWN) {
 
     XPCAutoRequest ar(mContext);
@@ -1289,18 +1288,16 @@ nsJSContext::EvaluateStringWithValue(con
     // tricky...
   }
   else {
     if (aIsUndefined) {
       *aIsUndefined = true;
     }
   }
 
-  sSecurityManager->PopContextPrincipal(mContext);
-
   // Pop here, after JS_ValueToString and any other possible evaluation.
   if (NS_FAILED(stack->Pop(nsnull)))
     rv = NS_ERROR_FAILURE;
 
   // ScriptEvaluated needs to come after we pop the stack
   ScriptEvaluated(true);
 
   return rv;
@@ -1396,29 +1393,35 @@ nsJSContext::EvaluateString(const nsAStr
   nsAutoMicroTask mt;
 
   if (!aScopeObject) {
     aScopeObject = JS_GetGlobalObject(mContext);
   }
 
   xpc_UnmarkGrayObject(aScopeObject);
 
-  // Safety first: get an object representing the script's principals, i.e.,
-  // the entities who signed this script, or the fully-qualified-domain-name
-  // or "codebase" from which it was loaded.
-  nsCOMPtr<nsIPrincipal> principal = aPrincipal;
-  if (!aPrincipal) {
-    nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
-      do_QueryInterface(GetGlobalObject());
-    if (!objPrincipal)
-      return NS_ERROR_FAILURE;
-    principal = objPrincipal->GetPrincipal();
-    if (!principal)
-      return NS_ERROR_FAILURE;
-  }
+  // Ignore the principal that was passed in, and just assert that it matches
+  // the one we pull off the global.
+  nsCOMPtr<nsIPrincipal> principal;
+  nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal = do_QueryInterface(GetGlobalObject());
+  if (!objPrincipal)
+    return NS_ERROR_FAILURE;
+  principal = objPrincipal->GetPrincipal();
+  if (!principal)
+    return NS_ERROR_FAILURE;
+#ifdef DEBUG
+  bool equal = false;
+  principal->Equals(aPrincipal, &equal);
+  MOZ_ASSERT(equal);
+  nsIPrincipal *scopeObjectPrincipal =
+    nsJSPrincipals::get(JS_GetCompartmentPrincipals(js::GetObjectCompartment(aScopeObject)));
+  equal = false;
+  principal->Equals(scopeObjectPrincipal, &equal);
+  MOZ_ASSERT(equal);
+#endif
 
   bool ok = false;
 
   nsresult rv = sSecurityManager->CanExecuteScripts(mContext, principal, &ok);
   if (NS_FAILED(rv)) {
     return NS_ERROR_FAILURE;
   }
 
@@ -1433,19 +1436,16 @@ nsJSContext::EvaluateString(const nsAStr
   }
 
   // The result of evaluation, used only if there were no errors.  This need
   // not be a GC root currently, provided we run the GC only from the
   // operation callback or from ScriptEvaluated.
   jsval val = JSVAL_VOID;
   jsval* vp = aRetValue ? &val : NULL;
 
-  rv = sSecurityManager->PushContextPrincipal(mContext, nsnull, principal);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   nsJSContext::TerminationFuncHolder holder(this);
 
   ++mExecuteDepth;
 
   // SecurityManager said "ok", but don't compile if aVersion is unknown.
   // Since the caller is responsible for parsing the version strings, we just
   // check it isn't JSVERSION_UNKNOWN.
   if (ok && JSVersion(aVersion) != JSVERSION_UNKNOWN) {
@@ -1487,18 +1487,16 @@ nsJSContext::EvaluateString(const nsAStr
 
     if (aRetValue) {
       aRetValue->Truncate();
     }
   }
 
   --mExecuteDepth;
 
-  sSecurityManager->PopContextPrincipal(mContext);
-
   // Pop here, after JS_ValueToString and any other possible evaluation.
   if (NS_FAILED(stack->Pop(nsnull)))
     rv = NS_ERROR_FAILURE;
 
   // ScriptEvaluated needs to come after we pop the stack
   ScriptEvaluated(true);
 
   return rv;
@@ -1586,25 +1584,16 @@ nsJSContext::ExecuteScript(JSScript* aSc
   // called from JS calls back into JS via XPConnect.
   nsresult rv;
   nsCOMPtr<nsIJSContextStack> stack =
            do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
   if (NS_FAILED(rv) || NS_FAILED(stack->Push(mContext))) {
     return NS_ERROR_FAILURE;
   }
 
-  nsCOMPtr<nsIPrincipal> principal;
-  rv = sSecurityManager->GetObjectPrincipal(mContext,
-                                            JS_GetGlobalFromScript(aScriptObject),
-                                            getter_AddRefs(principal));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = sSecurityManager->PushContextPrincipal(mContext, nsnull, principal);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   nsJSContext::TerminationFuncHolder holder(this);
   XPCAutoRequest ar(mContext);
   ++mExecuteDepth;
 
   // The result of evaluation, used only if there were no errors. This need
   // not be a GC root currently, provided we run the GC only from the
   // operation callback or from ScriptEvaluated.
   jsval val;
@@ -1621,18 +1610,16 @@ nsJSContext::ExecuteScript(JSScript* aSc
 
     if (aRetValue) {
       aRetValue->Truncate();
     }
   }
 
   --mExecuteDepth;
 
-  sSecurityManager->PopContextPrincipal(mContext);
-
   // Pop here, after JS_ValueToString and any other possible evaluation.
   if (NS_FAILED(stack->Pop(nsnull)))
     rv = NS_ERROR_FAILURE;
 
   // ScriptEvaluated needs to come after we pop the stack
   ScriptEvaluated(true);
 
   return rv;
@@ -1863,34 +1850,22 @@ nsJSContext::CallEventHandler(nsISupport
   nsJSContext::TerminationFuncHolder holder(this);
 
   if (NS_SUCCEEDED(rv)) {
     // Convert args to jsvals.
     PRUint32 argc = 0;
     jsval *argv = nsnull;
 
     JSObject *funobj = aHandler;
-    nsCOMPtr<nsIPrincipal> principal;
-    rv = sSecurityManager->GetObjectPrincipal(mContext, funobj,
-                                              getter_AddRefs(principal));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    JSStackFrame *currentfp = nsnull;
-    rv = sSecurityManager->PushContextPrincipal(mContext,
-                                                JS_FrameIterator(mContext, &currentfp),
-                                                principal);
-    NS_ENSURE_SUCCESS(rv, rv);
-
     jsval funval = OBJECT_TO_JSVAL(funobj);
     JSAutoEnterCompartment ac;
     js::ForceFrame ff(mContext, funobj);
     if (!ac.enter(mContext, funobj) || !ff.enter() ||
         !JS_WrapObject(mContext, &target)) {
       ReportPendingException();
-      sSecurityManager->PopContextPrincipal(mContext);
       return NS_ERROR_FAILURE;
     }
 
     Maybe<nsRootedJSValueArray> tempStorage;
 
     // Use |target| as the scope for wrapping the arguments, since aScope is
     // the safe scope in many cases, which isn't very useful.  Wrapping aTarget
     // was OK because those typically have PreCreate methods that give them the
@@ -1923,18 +1898,16 @@ nsJSContext::CallEventHandler(nsISupport
       rv = nsContentUtils::XPConnect()->JSToVariant(mContext, rval, arv);
     }
 
     // Tell XPConnect about any pending exceptions. This is needed
     // to avoid dropping JS exceptions in case we got here through
     // nested calls through XPConnect.
     if (NS_FAILED(rv))
       ReportPendingException();
-
-    sSecurityManager->PopContextPrincipal(mContext);
   }
 
   pusher.Pop();
 
   // ScriptEvaluated needs to come after we pop the stack
   ScriptEvaluated(true);
 
   return rv;
--- a/dom/file/test/helpers.js
+++ b/dom/file/test/helpers.js
@@ -113,28 +113,28 @@ function resetUnlimitedQuota(url)
 function getFileHandle(fileStorageKey, name)
 {
   var requestService = SpecialPowers.getDOMRequestService();
   var request = requestService.createRequest(window);
 
   switch (fileStorageKey) {
     case IndexedDatabaseKey:
       var dbname = window.location.pathname;
-      mozIndexedDB.open(dbname, 1).onsuccess = function(event) {
+      indexedDB.open(dbname, 1).onsuccess = function(event) {
         var db = event.target.result;
         db.mozCreateFileHandle(name).onsuccess = function(event) {
           var fileHandle = event.target.result;
           requestService.fireSuccess(request, fileHandle);
         }
       }
       break;
 
     case DeviceStorageKey:
       var dbname = window.location.pathname;
-      mozIndexedDB.open(dbname, 1).onsuccess = function(event) {
+      indexedDB.open(dbname, 1).onsuccess = function(event) {
         var db = event.target.result;
         db.mozCreateFileHandle(name).onsuccess = function(event) {
           var fileHandle = event.target.result;
           requestService.fireSuccess(request, fileHandle);
         }
       }
       break;
   }
--- a/dom/indexedDB/AsyncConnectionHelper.cpp
+++ b/dom/indexedDB/AsyncConnectionHelper.cpp
@@ -433,17 +433,17 @@ AsyncConnectionHelper::OnSuccess()
   NS_ASSERTION(!mTransaction ||
                mTransaction->IsOpen() ||
                mTransaction->IsAborted(),
                "How else can this be closed?!");
 
   if ((internalEvent->flags & NS_EVENT_FLAG_EXCEPTION_THROWN) &&
       mTransaction &&
       mTransaction->IsOpen()) {
-    rv = mTransaction->Abort();
+    rv = mTransaction->Abort(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 void
 AsyncConnectionHelper::OnError()
@@ -463,16 +463,26 @@ AsyncConnectionHelper::OnError()
   bool doDefault;
   nsresult rv = mRequest->DispatchEvent(event, &doDefault);
   if (NS_SUCCEEDED(rv)) {
     NS_ASSERTION(!mTransaction ||
                  mTransaction->IsOpen() ||
                  mTransaction->IsAborted(),
                  "How else can this be closed?!");
 
+    nsEvent* internalEvent = event->GetInternalNSEvent();
+    NS_ASSERTION(internalEvent, "This should never be null!");
+
+    if ((internalEvent->flags & NS_EVENT_FLAG_EXCEPTION_THROWN) &&
+        mTransaction &&
+        mTransaction->IsOpen() &&
+        NS_FAILED(mTransaction->Abort(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR))) {
+      NS_WARNING("Failed to abort transaction!");
+    }
+
     if (doDefault &&
         mTransaction &&
         mTransaction->IsOpen() &&
         NS_FAILED(mTransaction->Abort(mRequest))) {
       NS_WARNING("Failed to abort transaction!");
     }
   }
   else {
--- a/dom/indexedDB/DatabaseInfo.cpp
+++ b/dom/indexedDB/DatabaseInfo.cpp
@@ -19,17 +19,17 @@ typedef nsDataHashtable<nsISupportsHashK
 DatabaseHash* gDatabaseHash = nsnull;
 
 PLDHashOperator
 EnumerateObjectStoreNames(const nsAString& aKey,
                           ObjectStoreInfo* aData,
                           void* aUserArg)
 {
   nsTArray<nsString>* array = static_cast<nsTArray<nsString>*>(aUserArg);
-  if (!array->AppendElement(aData->name)) {
+  if (!array->InsertElementSorted(aData->name)) {
     NS_ERROR("Out of memory?");
     return PL_DHASH_STOP;
   }
   return PL_DHASH_NEXT;
 }
 
 PLDHashOperator
 CloneObjectStoreInfo(const nsAString& aKey,
@@ -268,18 +268,16 @@ DatabaseInfo::RemoveObjectStore(const ns
   if (objectStoreHash) {
     objectStoreHash->Remove(aName);
   }
 }
 
 already_AddRefed<DatabaseInfo>
 DatabaseInfo::Clone()
 {
-  NS_ASSERTION(!cloned, "Should never clone a clone!");
-
   nsRefPtr<DatabaseInfo> dbInfo(new DatabaseInfo());
 
   dbInfo->cloned = true;
   dbInfo->name = name;
   dbInfo->origin = origin;
   dbInfo->version = version;
   dbInfo->id = id;
   dbInfo->filePath = filePath;
--- a/dom/indexedDB/DatabaseInfo.h
+++ b/dom/indexedDB/DatabaseInfo.h
@@ -127,17 +127,18 @@ struct ObjectStoreInfoGuts
   // Make sure to update ipc/SerializationHelpers.h when changing members here!
 
   // Constant members, can be gotten on any thread
   nsString name;
   PRInt64 id;
   KeyPath keyPath;
   bool autoIncrement;
 
-  // Main-thread only members. This must *not* be touced on the database thread
+  // Main-thread only members. This must *not* be touched on the database
+  // thread.
   nsTArray<IndexInfo> indexes;
 };
 
 struct ObjectStoreInfo : public ObjectStoreInfoGuts
 {
 #ifdef NS_BUILD_REFCNT_LOGGING
   ObjectStoreInfo();
 #else
--- a/dom/indexedDB/IDBCursor.cpp
+++ b/dom/indexedDB/IDBCursor.cpp
@@ -681,21 +681,16 @@ IDBCursor::Update(const jsval& aValue,
 
   nsresult rv;
 
   JSAutoRequest ar(aCx);
 
   Key& objectKey = (mType == OBJECTSTORE) ? mKey : mObjectKey;
 
   if (mObjectStore->HasValidKeyPath()) {
-    // This has to be an object.
-    if (JSVAL_IS_PRIMITIVE(aValue)) {
-      return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
-    }
-
     // Make sure the object given has the correct keyPath value set on it.
     const KeyPath& keyPath = mObjectStore->GetKeyPath();
     Key key;
 
     rv = keyPath.ExtractKey(aCx, aValue, key);
     if (NS_FAILED(rv)) {
       return rv;
     }
@@ -740,21 +735,21 @@ IDBCursor::Delete(JSContext* aCx,
   jsval key;
   nsresult rv = objectKey.ToJSVal(aCx, &key);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return mObjectStore->Delete(key, aCx, _retval);
 }
 
 NS_IMETHODIMP
-IDBCursor::Advance(PRInt32 aCount)
+IDBCursor::Advance(PRInt64 aCount)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
-  if (aCount < 1) {
+  if (aCount < 1 || aCount > PR_UINT32_MAX) {
     return NS_ERROR_TYPE_ERR;
   }
 
   Key key;
   return ContinueInternal(key, aCount);
 }
 
 void
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -7,17 +7,16 @@
 #include "base/basictypes.h"
 
 #include "IDBDatabase.h"
 
 #include "mozilla/Mutex.h"
 #include "mozilla/storage.h"
 #include "nsDOMClassInfo.h"
 #include "nsDOMLists.h"
-#include "nsEventDispatcher.h"
 #include "nsJSUtils.h"
 #include "nsProxyRelease.h"
 #include "nsThreadUtils.h"
 
 #include "AsyncConnectionHelper.h"
 #include "CheckQuotaHelper.h"
 #include "DatabaseInfo.h"
 #include "IDBEvents.h"
@@ -306,27 +305,40 @@ IDBDatabase::IsClosed()
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   return mClosed;
 }
 
 void
 IDBDatabase::EnterSetVersionTransaction()
 {
   NS_ASSERTION(!mRunningVersionChange, "How did that happen?");
+
+  mPreviousDatabaseInfo = mDatabaseInfo->Clone();
+
   mRunningVersionChange = true;
 }
 
 void
 IDBDatabase::ExitSetVersionTransaction()
 {
   NS_ASSERTION(mRunningVersionChange, "How did that happen?");
+
+  mPreviousDatabaseInfo = nsnull;
+
   mRunningVersionChange = false;
 }
 
 void
+IDBDatabase::RevertToPreviousState()
+{
+  mDatabaseInfo = mPreviousDatabaseInfo;
+  mPreviousDatabaseInfo = nsnull;
+}
+
+void
 IDBDatabase::OnUnlink()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   // 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);
 
@@ -699,29 +711,30 @@ IDBDatabase::Transaction(const jsval& aS
 
   transaction.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IDBDatabase::MozCreateFileHandle(const nsAString& aName,
                                  const nsAString& aType,
+                                 JSContext* aCx,
                                  nsIIDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (IndexedDatabaseManager::IsShuttingDown()) {
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
   if (mClosed) {
     return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
   }
 
-  nsRefPtr<IDBRequest> request = IDBRequest::Create(nsnull, this, nsnull);
+  nsRefPtr<IDBRequest> request = IDBRequest::Create(nsnull, this, nsnull, aCx);
 
   nsRefPtr<CreateFileHelper> helper =
     new CreateFileHelper(this, request, aName, aType);
 
   IndexedDatabaseManager* manager = IndexedDatabaseManager::Get();
   NS_ASSERTION(manager, "We should definitely have a manager here");
 
   nsresult rv = helper->Dispatch(manager->IOThread());
@@ -771,45 +784,17 @@ void
 IDBDatabase::UnsetThreadLocals()
 {
   IndexedDatabaseManager::SetCurrentWindow(nsnull);
 }
 
 nsresult
 IDBDatabase::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
 {
-  NS_ENSURE_TRUE(aVisitor.mDOMEvent, NS_ERROR_UNEXPECTED);
-
-  nsPIDOMWindow* owner = GetOwner();
-  if (!owner) {
-    return NS_OK;
-  }
-
-  if (aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault) {
-    nsString type;
-    nsresult rv = aVisitor.mDOMEvent->GetType(type);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (type.EqualsLiteral(ERROR_EVT_STR)) {
-      nsRefPtr<nsDOMEvent> duplicateEvent =
-        CreateGenericEvent(type, eDoesNotBubble, eNotCancelable);
-      NS_ENSURE_STATE(duplicateEvent);
-
-      nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(owner));
-      NS_ASSERTION(target, "How can this happen?!");
-
-      bool dummy;
-      rv = target->DispatchEvent(duplicateEvent, &dummy);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-    }
-  }
-
-  return NS_OK;
+  return IndexedDatabaseManager::FireWindowOnError(GetOwner(), aVisitor);
 }
 
 HelperBase::ChildProcessSendResult
 NoRequestDatabaseHelper::MaybeSendResponseToChildProcess(nsresult aResultCode)
 {
   NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
   return Success_NotSent;
 }
@@ -828,17 +813,17 @@ NoRequestDatabaseHelper::OnSuccess()
   NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
   return NS_OK;
 }
 
 void
 NoRequestDatabaseHelper::OnError()
 {
   NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
-  mTransaction->AbortWithCode(GetResultCode());
+  mTransaction->Abort(GetResultCode());
 }
 
 nsresult
 CreateObjectStoreHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
 {
   nsCOMPtr<mozIStorageStatement> stmt =
     mTransaction->GetCachedStatement(NS_LITERAL_CSTRING(
     "INSERT INTO object_store (id, auto_increment, name, key_path) "
--- a/dom/indexedDB/IDBDatabase.h
+++ b/dom/indexedDB/IDBDatabase.h
@@ -32,16 +32,17 @@ class IndexedDBDatabaseParent;
 struct ObjectStoreInfoGuts;
 
 class IDBDatabase : public IDBWrapperCache,
                     public nsIIDBDatabase,
                     public nsIFileStorage
 {
   friend class AsyncConnectionHelper;
   friend class IndexedDatabaseManager;
+  friend class IndexedDBDatabaseChild;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIIDBDATABASE
   NS_DECL_NSIFILESTORAGE
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBDatabase, IDBWrapperCache)
 
@@ -99,16 +100,20 @@ public:
   void CloseInternal(bool aIsDead);
 
   // Whether or not the database has had Close called on it.
   bool IsClosed();
 
   void EnterSetVersionTransaction();
   void ExitSetVersionTransaction();
 
+  // Called when a versionchange transaction is aborted to reset the
+  // DatabaseInfo.
+  void RevertToPreviousState();
+
   FileManager* Manager() const
   {
     return mFileManager;
   }
 
   void
   SetActor(IndexedDBDatabaseChild* aActorChild)
   {
@@ -137,16 +142,19 @@ public:
 
 private:
   IDBDatabase();
   ~IDBDatabase();
 
   void OnUnlink();
 
   nsRefPtr<DatabaseInfo> mDatabaseInfo;
+  // Set to a copy of the existing DatabaseInfo when starting a versionchange
+  // transaction.
+  nsRefPtr<DatabaseInfo> mPreviousDatabaseInfo;
   nsCOMPtr<nsIAtom> mDatabaseId;
   nsString mName;
   nsString mFilePath;
   nsCString mASCIIOrigin;
 
   nsRefPtr<FileManager> mFileManager;
 
   // Only touched on the main thread.
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -396,16 +396,17 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDB
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 DOMCI_DATA(IDBFactory, IDBFactory)
 
 nsresult
 IDBFactory::OpenCommon(const nsAString& aName,
                        PRInt64 aVersion,
                        bool aDeleting,
+                       JSContext* aCallingCx,
                        IDBOpenDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(mWindow || mOwningObject, "Must have one of these!");
 
   nsCOMPtr<nsPIDOMWindow> window;
   nsCOMPtr<nsIScriptGlobalObject> sgo;
   JSObject* scriptOwner = nsnull;
@@ -413,17 +414,17 @@ IDBFactory::OpenCommon(const nsAString& 
   if (mWindow) {
     window = mWindow;
   }
   else {
     scriptOwner = mOwningObject;
   }
 
   nsRefPtr<IDBOpenDBRequest> request =
-    IDBOpenDBRequest::Create(window, scriptOwner);
+    IDBOpenDBRequest::Create(window, scriptOwner, aCallingCx);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsresult rv;
 
   if (IndexedDatabaseManager::IsMainProcess()) {
     nsRefPtr<OpenDatabaseHelper> openHelper =
       new OpenDatabaseHelper(request, aName, mASCIIOrigin, aVersion, aDeleting);
 
@@ -463,37 +464,40 @@ IDBFactory::OpenCommon(const nsAString& 
 
   request.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IDBFactory::Open(const nsAString& aName,
                  PRInt64 aVersion,
+                 JSContext* aCx,
                  PRUint8 aArgc,
                  nsIIDBOpenDBRequest** _retval)
 {
   if (aVersion < 1 && aArgc) {
     return NS_ERROR_TYPE_ERR;
   }
 
   nsRefPtr<IDBOpenDBRequest> request;
-  nsresult rv = OpenCommon(aName, aVersion, false, getter_AddRefs(request));
+  nsresult rv = OpenCommon(aName, aVersion, false, aCx,
+                           getter_AddRefs(request));
   NS_ENSURE_SUCCESS(rv, rv);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IDBFactory::DeleteDatabase(const nsAString& aName,
+                           JSContext* aCx,
                            nsIIDBOpenDBRequest** _retval)
 {
   nsRefPtr<IDBOpenDBRequest> request;
-  nsresult rv = OpenCommon(aName, 0, true, getter_AddRefs(request));
+  nsresult rv = OpenCommon(aName, 0, true, aCx, getter_AddRefs(request));
   NS_ENSURE_SUCCESS(rv, rv);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IDBFactory::Cmp(const jsval& aFirst,
--- a/dom/indexedDB/IDBFactory.h
+++ b/dom/indexedDB/IDBFactory.h
@@ -68,16 +68,17 @@ public:
   SetDatabaseMetadata(DatabaseInfo* aDatabaseInfo,
                       PRUint64 aVersion,
                       ObjectStoreInfoArray& aObjectStores);
 
   nsresult
   OpenCommon(const nsAString& aName,
              PRInt64 aVersion,
              bool aDeleting,
+             JSContext* aCallingCx,
              IDBOpenDBRequest** _retval);
 
   void
   SetActor(IndexedDBChild* aActorChild)
   {
     NS_ASSERTION(!aActorChild || !mActorChild, "Shouldn't have more than one!");
     mActorChild = aActorChild;
   }
--- a/dom/indexedDB/IDBIndex.cpp
+++ b/dom/indexedDB/IDBIndex.cpp
@@ -333,22 +333,22 @@ public:
 
 private:
   nsRefPtr<IDBKeyRange> mKeyRange;
   PRUint64 mCount;
 };
 
 inline
 already_AddRefed<IDBRequest>
-GenerateRequest(IDBIndex* aIndex)
+GenerateRequest(IDBIndex* aIndex, JSContext* aCx)
 {
   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, transaction, aCx);
 }
 
 } // anonymous namespace
 
 // static
 already_AddRefed<IDBIndex>
 IDBIndex::Create(IDBObjectStore* aObjectStore,
                  const IndexInfo* aIndexInfo,
@@ -418,180 +418,187 @@ IDBIndex::~IDBIndex()
     NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
     mActorChild->Send__delete__(mActorChild);
     NS_ASSERTION(!mActorChild, "Should have cleared in Send__delete__!");
   }
 }
 
 nsresult
 IDBIndex::GetInternal(IDBKeyRange* aKeyRange,
+                      JSContext* aCx,
                       IDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   IDBTransaction* transaction = mObjectStore->Transaction();
   if (!transaction->IsOpen()) {
     return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
   }
 
-  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  nsRefPtr<IDBRequest> request = GenerateRequest(this, aCx);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<GetHelper> helper =
     new GetHelper(transaction, request, this, aKeyRange);
 
   nsresult rv = helper->DispatchToTransactionPool();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 nsresult
 IDBIndex::GetKeyInternal(IDBKeyRange* aKeyRange,
+                         JSContext* aCx,
                          IDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   IDBTransaction* transaction = mObjectStore->Transaction();
   if (!transaction->IsOpen()) {
     return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
   }
 
-  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  nsRefPtr<IDBRequest> request = GenerateRequest(this, aCx);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<GetKeyHelper> helper =
     new GetKeyHelper(transaction, request, this, aKeyRange);
 
   nsresult rv = helper->DispatchToTransactionPool();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 nsresult
 IDBIndex::GetAllInternal(IDBKeyRange* aKeyRange,
                          PRUint32 aLimit,
+                         JSContext* aCx,
                          IDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   IDBTransaction* transaction = mObjectStore->Transaction();
   if (!transaction->IsOpen()) {
     return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
   }
 
-  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  nsRefPtr<IDBRequest> request = GenerateRequest(this, aCx);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<GetAllHelper> helper =
     new GetAllHelper(transaction, request, this, aKeyRange, aLimit);
 
   nsresult rv = helper->DispatchToTransactionPool();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 nsresult
 IDBIndex::GetAllKeysInternal(IDBKeyRange* aKeyRange,
                              PRUint32 aLimit,
+                             JSContext* aCx,
                              IDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   IDBTransaction* transaction = mObjectStore->Transaction();
   if (!transaction->IsOpen()) {
     return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
   }
 
-  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  nsRefPtr<IDBRequest> request = GenerateRequest(this, aCx);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<GetAllKeysHelper> helper =
     new GetAllKeysHelper(transaction, request, this, aKeyRange, aLimit);
 
   nsresult rv = helper->DispatchToTransactionPool();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 nsresult
 IDBIndex::CountInternal(IDBKeyRange* aKeyRange,
+                        JSContext* aCx,
                         IDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   IDBTransaction* transaction = mObjectStore->Transaction();
   if (!transaction->IsOpen()) {
     return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
   }
 
-  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  nsRefPtr<IDBRequest> request = GenerateRequest(this, aCx);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<CountHelper> helper =
     new CountHelper(transaction, request, this, aKeyRange);
 
   nsresult rv = helper->DispatchToTransactionPool();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 nsresult
 IDBIndex::OpenKeyCursorInternal(IDBKeyRange* aKeyRange,
                                 size_t aDirection,
+                                JSContext* aCx,
                                 IDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   IDBTransaction* transaction = mObjectStore->Transaction();
   if (!transaction->IsOpen()) {
     return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
   }
 
   IDBCursor::Direction direction =
     static_cast<IDBCursor::Direction>(aDirection);
 
-  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  nsRefPtr<IDBRequest> request = GenerateRequest(this, aCx);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<OpenKeyCursorHelper> helper =
     new OpenKeyCursorHelper(transaction, request, this, aKeyRange, direction);
 
   nsresult rv = helper->DispatchToTransactionPool();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 nsresult
 IDBIndex::OpenCursorInternal(IDBKeyRange* aKeyRange,
                              size_t aDirection,
+                             JSContext* aCx,
                              IDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   IDBTransaction* transaction = mObjectStore->Transaction();
   if (!transaction->IsOpen()) {
     return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
   }
 
   IDBCursor::Direction direction =
     static_cast<IDBCursor::Direction>(aDirection);
 
-  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  nsRefPtr<IDBRequest> request = GenerateRequest(this, aCx);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<OpenCursorHelper> helper =
     new OpenCursorHelper(transaction, request, this, aKeyRange, direction);
 
   nsresult rv = helper->DispatchToTransactionPool();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
@@ -774,17 +781,17 @@ IDBIndex::Get(const jsval& aKey,
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!keyRange) {
     // Must specify a key or keyRange for get().
     return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
   }
 
   nsRefPtr<IDBRequest> request;
-  rv = GetInternal(keyRange, getter_AddRefs(request));
+  rv = GetInternal(keyRange, aCx, getter_AddRefs(request));
   NS_ENSURE_SUCCESS(rv, rv);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IDBIndex::GetKey(const jsval& aKey,
@@ -803,17 +810,17 @@ IDBIndex::GetKey(const jsval& aKey,
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!keyRange) {
     // Must specify a key or keyRange for get().
     return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
   }
 
   nsRefPtr<IDBRequest> request;
-  rv = GetKeyInternal(keyRange, getter_AddRefs(request));
+  rv = GetKeyInternal(keyRange, aCx, getter_AddRefs(request));
   NS_ENSURE_SUCCESS(rv, rv);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IDBIndex::GetAll(const jsval& aKey,
@@ -837,17 +844,17 @@ IDBIndex::GetAll(const jsval& aKey,
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (aOptionalArgCount < 2 || aLimit == 0) {
     aLimit = PR_UINT32_MAX;
   }
 
   nsRefPtr<IDBRequest> request;
-  rv = GetAllInternal(keyRange, aLimit, getter_AddRefs(request));
+  rv = GetAllInternal(keyRange, aLimit, aCx, getter_AddRefs(request));
   NS_ENSURE_SUCCESS(rv, rv);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IDBIndex::GetAllKeys(const jsval& aKey,
@@ -871,17 +878,17 @@ IDBIndex::GetAllKeys(const jsval& aKey,
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (aOptionalArgCount < 2 || aLimit == 0) {
     aLimit = PR_UINT32_MAX;
   }
 
   nsRefPtr<IDBRequest> request;
-  rv = GetAllKeysInternal(keyRange, aLimit, getter_AddRefs(request));
+  rv = GetAllKeysInternal(keyRange, aLimit, aCx, getter_AddRefs(request));
   NS_ENSURE_SUCCESS(rv, rv);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IDBIndex::OpenCursor(const jsval& aKey,
@@ -907,17 +914,17 @@ IDBIndex::OpenCursor(const jsval& aKey,
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (aOptionalArgCount >= 2) {
       rv = IDBCursor::ParseDirection(aDirection, &direction);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
-  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  nsRefPtr<IDBRequest> request = GenerateRequest(this, aCx);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<OpenCursorHelper> helper =
     new OpenCursorHelper(transaction, request, this, keyRange, direction);
 
   rv = helper->DispatchToTransactionPool();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
@@ -950,17 +957,18 @@ IDBIndex::OpenKeyCursor(const jsval& aKe
 
     if (aOptionalArgCount >= 2) {
       rv = IDBCursor::ParseDirection(aDirection, &direction);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   nsRefPtr<IDBRequest> request;
-  rv = OpenKeyCursorInternal(keyRange, direction, getter_AddRefs(request));
+  rv = OpenKeyCursorInternal(keyRange, direction, aCx,
+                             getter_AddRefs(request));
   NS_ENSURE_SUCCESS(rv, rv);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IDBIndex::Count(const jsval& aKey,
@@ -977,17 +985,17 @@ IDBIndex::Count(const jsval& aKey,
 
   nsRefPtr<IDBKeyRange> keyRange;
   if (aOptionalArgCount) {
     rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   nsRefPtr<IDBRequest> request;
-  rv = CountInternal(keyRange, getter_AddRefs(request));
+  rv = CountInternal(keyRange, aCx, getter_AddRefs(request));
   NS_ENSURE_SUCCESS(rv, rv);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 void
 IndexHelper::ReleaseMainThreadObjects()
--- a/dom/indexedDB/IDBIndex.h
+++ b/dom/indexedDB/IDBIndex.h
@@ -96,45 +96,52 @@ public:
 
   IndexedDBIndexParent*
   GetActorParent() const
   {
     return mActorParent;
   }
 
   nsresult GetInternal(IDBKeyRange* aKeyRange,
+                       JSContext* aCx,
                        IDBRequest** _retval);
 
   nsresult GetKeyInternal(IDBKeyRange* aKeyRange,
+                          JSContext* aCx,
                           IDBRequest** _retval);
 
   nsresult GetAllInternal(IDBKeyRange* aKeyRange,
                           PRUint32 aLimit,
+                          JSContext* aCx,
                           IDBRequest** _retval);
 
   nsresult GetAllKeysInternal(IDBKeyRange* aKeyRange,
                               PRUint32 aLimit,
+                              JSContext* aCx,
                               IDBRequest** _retval);
 
   nsresult CountInternal(IDBKeyRange* aKeyRange,
+                         JSContext* aCx,
                          IDBRequest** _retval);
 
   nsresult OpenCursorFromChildProcess(
                             IDBRequest* aRequest,
                             size_t aDirection,
                             const Key& aKey,
                             const Key& aObjectKey,
                             IDBCursor** _retval);
 
   nsresult OpenKeyCursorInternal(IDBKeyRange* aKeyRange,
                                  size_t aDirection,
+                                 JSContext* aCx,
                                  IDBRequest** _retval);
 
   nsresult OpenCursorInternal(IDBKeyRange* aKeyRange,
                               size_t aDirection,
+                              JSContext* aCx,
                               IDBRequest** _retval);
 
   nsresult OpenCursorFromChildProcess(
                             IDBRequest* aRequest,
                             size_t aDirection,
                             const Key& aKey,
                             const Key& aObjectKey,
                             const SerializedStructuredCloneReadInfo& aCloneInfo,
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -545,22 +545,22 @@ JSClass ThreadLocalJSRuntime::sGlobalCla
   "IndexedDBTransactionThreadGlobal",
   JSCLASS_GLOBAL_FLAGS,
   JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
 };
 
 inline
 already_AddRefed<IDBRequest>
-GenerateRequest(IDBObjectStore* aObjectStore)
+GenerateRequest(IDBObjectStore* aObjectStore, JSContext* aCx)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   IDBDatabase* database = aObjectStore->Transaction()->Database();
   return IDBRequest::Create(aObjectStore, database,
-                            aObjectStore->Transaction());
+                            aObjectStore->Transaction(), aCx);
 }
 
 struct GetAddInfoClosure
 {
   IDBObjectStore* mThis;
   StructuredCloneWriteInfo& mCloneWriteInfo;
   jsval mValue;
 };
@@ -1427,17 +1427,17 @@ IDBObjectStore::AddOrPut(const jsval& aV
   nsTArray<IndexUpdateInfo> updateInfo;
 
   nsresult rv = GetAddInfo(aCx, aValue, keyval, cloneWriteInfo, key,
                            updateInfo);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  nsRefPtr<IDBRequest> request = GenerateRequest(this, aCx);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<AddHelper> helper =
     new AddHelper(mTransaction, request, this, cloneWriteInfo, key,
                   aOverwrite, updateInfo);
 
   rv = helper->DispatchToTransactionPool();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@@ -1460,17 +1460,17 @@ IDBObjectStore::AddOrPutInternal(
   if (!mTransaction->IsOpen()) {
     return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
   }
 
   if (!IsWriteAllowed()) {
     return NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR;
   }
 
-  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  nsRefPtr<IDBRequest> request = GenerateRequest(this, nsnull);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   StructuredCloneWriteInfo cloneWriteInfo;
   if (!cloneWriteInfo.SetFromSerialized(aCloneWriteInfo)) {
     NS_WARNING("Failed to copy structured clone buffer!");
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
@@ -1486,152 +1486,158 @@ IDBObjectStore::AddOrPutInternal(
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 nsresult
 IDBObjectStore::GetInternal(IDBKeyRange* aKeyRange,
+                            JSContext* aCx,
                             IDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(aKeyRange, "Null pointer!");
 
   if (!mTransaction->IsOpen()) {
     return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
   }
 
-  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  nsRefPtr<IDBRequest> request = GenerateRequest(this, aCx);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<GetHelper> helper =
     new GetHelper(mTransaction, request, this, aKeyRange);
 
   nsresult rv = helper->DispatchToTransactionPool();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 nsresult
 IDBObjectStore::GetAllInternal(IDBKeyRange* aKeyRange,
                                PRUint32 aLimit,
+                               JSContext* aCx,
                                IDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!mTransaction->IsOpen()) {
     return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
   }
 
-  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  nsRefPtr<IDBRequest> request = GenerateRequest(this, aCx);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<GetAllHelper> helper =
     new GetAllHelper(mTransaction, request, this, aKeyRange, aLimit);
 
   nsresult rv = helper->DispatchToTransactionPool();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 nsresult
 IDBObjectStore::DeleteInternal(IDBKeyRange* aKeyRange,
+                               JSContext* aCx,
                                IDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(aKeyRange, "Null key range!");
 
   if (!mTransaction->IsOpen()) {
     return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
   }
 
   if (!IsWriteAllowed()) {
     return NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR;
   }
 
-  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  nsRefPtr<IDBRequest> request = GenerateRequest(this, aCx);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<DeleteHelper> helper =
     new DeleteHelper(mTransaction, request, this, aKeyRange);
 
   nsresult rv = helper->DispatchToTransactionPool();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 nsresult
-IDBObjectStore::ClearInternal(IDBRequest** _retval)
+IDBObjectStore::ClearInternal(JSContext* aCx,
+                              IDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!mTransaction->IsOpen()) {
     return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
   }
 
   if (!IsWriteAllowed()) {
     return NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR;
   }
 
-  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  nsRefPtr<IDBRequest> request = GenerateRequest(this, aCx);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<ClearHelper> helper(new ClearHelper(mTransaction, request, this));
 
   nsresult rv = helper->DispatchToTransactionPool();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 nsresult
 IDBObjectStore::CountInternal(IDBKeyRange* aKeyRange,
+                              JSContext* aCx,
                               IDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!mTransaction->IsOpen()) {
     return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
   }
 
-  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  nsRefPtr<IDBRequest> request = GenerateRequest(this, aCx);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<CountHelper> helper =
     new CountHelper(mTransaction, request, this, aKeyRange);
   nsresult rv = helper->DispatchToTransactionPool();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   request.forget(_retval);
   return NS_OK;
 }
 
 nsresult
 IDBObjectStore::OpenCursorInternal(IDBKeyRange* aKeyRange,
                                    size_t aDirection,
+                                   JSContext* aCx,
                                    IDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!mTransaction->IsOpen()) {
     return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
   }
 
   IDBCursor::Direction direction =
     static_cast<IDBCursor::Direction>(aDirection);
 
-  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  nsRefPtr<IDBRequest> request = GenerateRequest(this, aCx);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<OpenCursorHelper> helper =
     new OpenCursorHelper(mTransaction, request, this, aKeyRange, direction);
 
   nsresult rv = helper->DispatchToTransactionPool();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
@@ -1668,16 +1674,25 @@ IDBObjectStore::OpenCursorFromChildProce
   NS_ENSURE_TRUE(cursor, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   NS_ASSERTION(!cloneInfo.mCloneBuffer.data(), "Should have swapped!");
 
   cursor.forget(_retval);
   return NS_OK;
 }
 
+void
+IDBObjectStore::SetInfo(ObjectStoreInfo* aInfo)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread");
+  NS_ASSERTION(aInfo != mInfo, "This is nonsense");
+
+  mInfo = aInfo;
+}
+
 nsresult
 IDBObjectStore::CreateIndexInternal(const IndexInfo& aInfo,
                                     IDBIndex** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   IndexInfo* indexInfo = mInfo->indexes.AppendElement();
 
@@ -1848,19 +1863,26 @@ IDBObjectStore::GetAutoIncrement(bool* a
 
 NS_IMETHODIMP
 IDBObjectStore::GetIndexNames(nsIDOMDOMStringList** aIndexNames)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   nsRefPtr<nsDOMStringList> list(new nsDOMStringList());
 
+  nsAutoTArray<nsString, 10> names;
   PRUint32 count = mInfo->indexes.Length();
+  names.SetCapacity(count);
+
   for (PRUint32 index = 0; index < count; index++) {
-    NS_ENSURE_TRUE(list->Add(mInfo->indexes[index].name),
+    names.InsertElementSorted(mInfo->indexes[index].name);
+  }
+
+  for (PRUint32 index = 0; index < count; index++) {
+    NS_ENSURE_TRUE(list->Add(names[index]),
                    NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
   }
 
   list.forget(aIndexNames);
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -1879,17 +1901,17 @@ IDBObjectStore::Get(const jsval& aKey,
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!keyRange) {
     // Must specify a key or keyRange for get().
     return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
   }
 
   nsRefPtr<IDBRequest> request;
-  rv = GetInternal(keyRange, getter_AddRefs(request));
+  rv = GetInternal(keyRange, aCx, getter_AddRefs(request));
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   request.forget(_retval);
   return NS_OK;
 }
 
@@ -1914,17 +1936,17 @@ IDBObjectStore::GetAll(const jsval& aKey
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (aOptionalArgCount < 2 || aLimit == 0) {
     aLimit = PR_UINT32_MAX;
   }
 
   nsRefPtr<IDBRequest> request;
-  rv = GetAllInternal(keyRange, aLimit, getter_AddRefs(request));
+  rv = GetAllInternal(keyRange, aLimit, aCx, getter_AddRefs(request));
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   request.forget(_retval);
   return NS_OK;
 }
 
@@ -1990,32 +2012,32 @@ IDBObjectStore::Delete(const jsval& aKey
   }
 
   if (!keyRange) {
     // Must specify a key or keyRange for delete().
     return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
   }
 
   nsRefPtr<IDBRequest> request;
-  rv = DeleteInternal(keyRange, getter_AddRefs(request));
+  rv = DeleteInternal(keyRange, aCx, getter_AddRefs(request));
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   request.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-IDBObjectStore::Clear(nsIIDBRequest** _retval)
+IDBObjectStore::Clear(JSContext* aCx, nsIIDBRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   nsRefPtr<IDBRequest> request;
-  nsresult rv = ClearInternal(getter_AddRefs(request));
+  nsresult rv = ClearInternal(aCx, getter_AddRefs(request));
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   request.forget(_retval);
   return NS_OK;
 }
 
@@ -2045,17 +2067,18 @@ IDBObjectStore::OpenCursor(const jsval& 
       rv = IDBCursor::ParseDirection(aDirection, &direction);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   size_t argDirection = static_cast<size_t>(direction);
 
   nsRefPtr<IDBRequest> request;
-  rv = OpenCursorInternal(keyRange, argDirection, getter_AddRefs(request));
+  rv = OpenCursorInternal(keyRange, argDirection, aCx,
+                          getter_AddRefs(request));
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   request.forget(_retval);
   return NS_OK;
 }
 
@@ -2224,17 +2247,17 @@ IDBObjectStore::Count(const jsval& aKey,
 
   nsRefPtr<IDBKeyRange> keyRange;
   if (aOptionalArgCount) {
     rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   nsRefPtr<IDBRequest> request;
-  rv = CountInternal(keyRange, getter_AddRefs(request));
+  rv = CountInternal(keyRange, aCx, getter_AddRefs(request));
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   request.forget(_retval);
   return NS_OK;
 }
 
@@ -2329,17 +2352,17 @@ NoRequestObjectStoreHelper::OnSuccess()
   NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
   return NS_OK;
 }
 
 void
 NoRequestObjectStoreHelper::OnError()
 {
   NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
-  mTransaction->AbortWithCode(GetResultCode());
+  mTransaction->Abort(GetResultCode());
 }
 
 nsresult
 AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
 {
   NS_ASSERTION(aConnection, "Passed a null connection!");
 
   nsresult rv;
--- a/dom/indexedDB/IDBObjectStore.h
+++ b/dom/indexedDB/IDBObjectStore.h
@@ -182,41 +182,50 @@ public:
   nsresult AddOrPutInternal(
                       const SerializedStructuredCloneWriteInfo& aCloneWriteInfo,
                       const Key& aKey,
                       const InfallibleTArray<IndexUpdateInfo>& aUpdateInfoArray,
                       bool aOverwrite,
                       IDBRequest** _retval);
 
   nsresult GetInternal(IDBKeyRange* aKeyRange,
+                       JSContext* aCx,
                        IDBRequest** _retval);
 
   nsresult GetAllInternal(IDBKeyRange* aKeyRange,
                           PRUint32 aLimit,
+                          JSContext* aCx,
                           IDBRequest** _retval);
 
   nsresult DeleteInternal(IDBKeyRange* aKeyRange,
+                          JSContext* aCx,
                           IDBRequest** _retval);
 
-  nsresult ClearInternal(IDBRequest** _retval);
+  nsresult ClearInternal(JSContext* aCx,
+                         IDBRequest** _retval);
 
   nsresult CountInternal(IDBKeyRange* aKeyRange,
+                         JSContext* aCx,
                          IDBRequest** _retval);
 
   nsresult OpenCursorInternal(IDBKeyRange* aKeyRange,
                               size_t aDirection,
+                              JSContext* aCx,
                               IDBRequest** _retval);
 
   nsresult OpenCursorFromChildProcess(
                             IDBRequest* aRequest,
                             size_t aDirection,
                             const Key& aKey,
                             const SerializedStructuredCloneReadInfo& aCloneInfo,
                             IDBCursor** _retval);
 
+  void
+  SetInfo(ObjectStoreInfo* aInfo);
+
   static JSClass sDummyPropJSClass;
 
 protected:
   IDBObjectStore();
   ~IDBObjectStore();
 
   nsresult GetAddInfo(JSContext* aCx,
                       jsval aValue,
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -9,16 +9,17 @@
 #include "nsIJSContextStack.h"
 #include "nsIScriptContext.h"
 
 #include "nsComponentManagerUtils.h"
 #include "nsDOMClassInfoID.h"
 #include "nsDOMJSUtils.h"
 #include "nsContentUtils.h"
 #include "nsEventDispatcher.h"
+#include "nsJSUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsStringGlue.h"
 #include "nsThreadUtils.h"
 #include "nsWrapperCacheInlines.h"
 
 #include "AsyncConnectionHelper.h"
 #include "IDBEvents.h"
 #include "IDBTransaction.h"
@@ -26,44 +27,48 @@
 
 USING_INDEXEDDB_NAMESPACE
 
 IDBRequest::IDBRequest()
 : mResultVal(JSVAL_VOID),
   mActorParent(nsnull),
   mErrorCode(NS_OK),
   mHaveResultOrErrorCode(false),
-  mRooted(false)
+  mRooted(false),
+  mLineNo(0)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 }
 
 IDBRequest::~IDBRequest()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   UnrootResultVal();
 }
 
 // static
 already_AddRefed<IDBRequest>
 IDBRequest::Create(nsISupports* aSource,
                    IDBWrapperCache* aOwnerCache,
-                   IDBTransaction* aTransaction)
+                   IDBTransaction* aTransaction,
+                   JSContext* aCallingCx)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   nsRefPtr<IDBRequest> request(new IDBRequest());
 
   request->mSource = aSource;
   request->mTransaction = aTransaction;
   request->BindToOwner(aOwnerCache);
   if (!request->SetScriptOwner(aOwnerCache->GetScriptOwner())) {
     return nsnull;
   }
 
+  request->CaptureCaller(aCallingCx);
+
   return request.forget();
 }
 
 void
 IDBRequest::Reset()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   mResultVal = JSVAL_VOID;
@@ -203,16 +208,43 @@ IDBRequest::GetJSContext()
 
   cx = sc->GetNativeContext();
   NS_ASSERTION(cx, "Failed to get a context!");
 
   return cx;
 }
 
 void
+IDBRequest::CaptureCaller(JSContext* aCx)
+{
+  if (!aCx) {
+    // We may not have a JSContext.  This happens if our caller is in another
+    // process.
+    return;
+  }
+
+  const char* filename = nsnull;
+  PRUint32 lineNo = 0;
+  if (!nsJSUtils::GetCallingLocation(aCx, &filename, &lineNo)) {
+    NS_WARNING("Failed to get caller.");
+    return;
+  }
+
+  mFilename.Assign(NS_ConvertUTF8toUTF16(filename));
+  mLineNo = lineNo;
+}
+
+void
+IDBRequest::FillScriptErrorEvent(nsScriptErrorEvent* aEvent) const
+{
+  aEvent->lineNr = mLineNo;
+  aEvent->fileName = mFilename.get();
+}
+
+void
 IDBRequest::RootResultValInternal()
 {
   NS_HOLD_JS_OBJECTS(this, IDBRequest);
 }
 
 void
 IDBRequest::UnrootResultValInternal()
 {
@@ -336,26 +368,29 @@ IDBOpenDBRequest::~IDBOpenDBRequest()
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   UnrootResultVal();
 }
 
 // static
 already_AddRefed<IDBOpenDBRequest>
 IDBOpenDBRequest::Create(nsPIDOMWindow* aOwner,
-                         JSObject* aScriptOwner)
+                         JSObject* aScriptOwner,
+                         JSContext* aCallingCx)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   nsRefPtr<IDBOpenDBRequest> request(new IDBOpenDBRequest());
 
   request->BindToOwner(aOwner);
   if (!request->SetScriptOwner(aScriptOwner)) {
     return nsnull;
   }
 
+  request->CaptureCaller(aCallingCx);
+
   return request.forget();
 }
 
 void
 IDBOpenDBRequest::SetTransaction(IDBTransaction* aTransaction)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
@@ -402,38 +437,10 @@ NS_IMPL_RELEASE_INHERITED(IDBOpenDBReque
 DOMCI_DATA(IDBOpenDBRequest, IDBOpenDBRequest)
 
 NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, blocked);
 NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, upgradeneeded);
 
 nsresult
 IDBOpenDBRequest::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
 {
-  NS_ENSURE_TRUE(aVisitor.mDOMEvent, NS_ERROR_UNEXPECTED);
-
-  nsPIDOMWindow* owner = GetOwner();
-  if (!owner) {
-    return NS_OK;
-  }
-
-  if (aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault) {
-    nsString type;
-    nsresult rv = aVisitor.mDOMEvent->GetType(type);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (type.EqualsLiteral(ERROR_EVT_STR)) {
-      nsRefPtr<nsDOMEvent> duplicateEvent =
-        CreateGenericEvent(type, eDoesNotBubble, eNotCancelable);
-      NS_ENSURE_STATE(duplicateEvent);
-
-      nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(owner));
-      NS_ASSERTION(target, "How can this happen?!");
-
-      bool dummy;
-      rv = target->DispatchEvent(duplicateEvent, &dummy);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-    }
-  }
-
-  return NS_OK;
+  return IndexedDatabaseManager::FireWindowOnError(GetOwner(), aVisitor);
 }
--- a/dom/indexedDB/IDBRequest.h
+++ b/dom/indexedDB/IDBRequest.h
@@ -30,17 +30,18 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIIDBREQUEST
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(IDBRequest,
                                                          IDBWrapperCache)
 
   static
   already_AddRefed<IDBRequest> Create(nsISupports* aSource,
                                       IDBWrapperCache* aOwnerCache,
-                                      IDBTransaction* aTransaction);
+                                      IDBTransaction* aTransaction,
+                                      JSContext* aCallingCx);
 
   // nsIDOMEventTarget
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
 
   nsISupports* Source()
   {
     return mSource;
   }
@@ -73,16 +74,20 @@ public:
   }
 
   IndexedDBRequestParentBase*
   GetActorParent() const
   {
     return mActorParent;
   }
 
+  void CaptureCaller(JSContext* aCx);
+
+  void FillScriptErrorEvent(nsScriptErrorEvent* aEvent) const;
+
 protected:
   IDBRequest();
   ~IDBRequest();
 
   virtual void RootResultValInternal();
   virtual void UnrootResultValInternal();
 
   void RootResultVal()
@@ -111,39 +116,35 @@ protected:
 
   nsCOMPtr<nsIDOMDOMError> mError;
 
   IndexedDBRequestParentBase* mActorParent;
 
   nsresult mErrorCode;
   bool mHaveResultOrErrorCode;
   bool mRooted;
+
+  nsString mFilename;
+  PRUint32 mLineNo;
 };
 
 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)
 
   static
   already_AddRefed<IDBOpenDBRequest>
   Create(nsPIDOMWindow* aOwner,
-         JSObject* aScriptOwner);
-
-  static
-  already_AddRefed<IDBOpenDBRequest>
-  Create(IDBWrapperCache* aOwnerCache)
-  {
-    return Create(aOwnerCache->GetOwner(),
-                  aOwnerCache->GetScriptOwner());
-  }
+         JSObject* aScriptOwner,
+         JSContext* aCallingCx);
 
   void SetTransaction(IDBTransaction* aTransaction);
 
   // nsIDOMEventTarget
   virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
 
 protected:
   ~IDBOpenDBRequest();
--- a/dom/indexedDB/IDBTransaction.cpp
+++ b/dom/indexedDB/IDBTransaction.cpp
@@ -106,16 +106,17 @@ IDBTransaction::CreateInternal(IDBDataba
   if (!transaction->SetScriptOwner(aDatabase->GetScriptOwner())) {
     return nsnull;
   }
 
   transaction->mDatabase = aDatabase;
   transaction->mMode = aMode;
   transaction->mDatabaseInfo = aDatabase->Info();
   transaction->mObjectStoreNames.AppendElements(aObjectStoreNames);
+  transaction->mObjectStoreNames.Sort();
 
   IndexedDBTransactionChild* actor = nsnull;
 
   transaction->mCreatedFileInfos.Init();
 
   if (IndexedDatabaseManager::IsMainProcess()) {
     transaction->mCachedStatements.Init();
 
@@ -223,17 +224,19 @@ IDBTransaction::RemoveObjectStore(const 
 {
   NS_ASSERTION(mMode == IDBTransaction::VERSION_CHANGE,
                "Only remove object stores on VERSION_CHANGE transactions");
 
   mDatabaseInfo->RemoveObjectStore(aName);
 
   for (PRUint32 i = 0; i < mCreatedObjectStores.Length(); i++) {
     if (mCreatedObjectStores[i]->Name() == aName) {
+      nsRefPtr<IDBObjectStore> objectStore = mCreatedObjectStores[i];
       mCreatedObjectStores.RemoveElementAt(i);
+      mDeletedObjectStores.AppendElement(objectStore);
       break;
     }
   }
 }
 
 void
 IDBTransaction::SetTransactionListener(IDBTransactionListener* aListener)
 {
@@ -490,36 +493,70 @@ IDBTransaction::AddFileInfo(nsIDOMBlob* 
 
 void
 IDBTransaction::ClearCreatedFileInfos()
 {
   mCreatedFileInfos.Clear();
 }
 
 nsresult
-IDBTransaction::AbortWithCode(nsresult aAbortCode)
+IDBTransaction::AbortInternal(nsresult aAbortCode,
+                              already_AddRefed<nsIDOMDOMError> aError)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
+  nsCOMPtr<nsIDOMDOMError> error = aError;
+
   if (IsFinished()) {
     return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
   }
 
   if (mActorChild) {
     NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
     mActorChild->SendAbort(aAbortCode);
   }
 
   bool needToCommitOrRollback = mReadyState == IDBTransaction::INITIAL;
 
   mAbortCode = aAbortCode;
   mReadyState = IDBTransaction::DONE;
+  mError = error.forget();
 
-  if (Mode() == IDBTransaction::VERSION_CHANGE) {
-    // If a version change transaction is aborted, the db must be closed
+  if (GetMode() == IDBTransaction::VERSION_CHANGE) {
+    // If a version change transaction is aborted, we must revert the world
+    // back to its previous state.
+    mDatabase->RevertToPreviousState();
+
+    DatabaseInfo* dbInfo = mDatabase->Info();
+
+    for (PRUint32 i = 0; i < mCreatedObjectStores.Length(); i++) {
+      nsRefPtr<IDBObjectStore>& objectStore = mCreatedObjectStores[i];
+      ObjectStoreInfo* info = dbInfo->GetObjectStore(objectStore->Name());
+
+      if (!info) {
+        info = new ObjectStoreInfo(*objectStore->Info());
+        info->indexes.Clear();
+      }
+
+      objectStore->SetInfo(info);
+    }
+
+    for (PRUint32 i = 0; i < mDeletedObjectStores.Length(); i++) {
+      nsRefPtr<IDBObjectStore>& objectStore = mDeletedObjectStores[i];
+      ObjectStoreInfo* info = dbInfo->GetObjectStore(objectStore->Name());
+
+      if (!info) {
+        info = new ObjectStoreInfo(*objectStore->Info());
+        info->indexes.Clear();
+      }
+
+      objectStore->SetInfo(info);
+    }
+
+    // and then the db must be closed
     mDatabase->Close();
   }
 
   // Fire the abort event if there are no outstanding requests. Otherwise the
   // abort event will be fired when all outstanding requests finish.
   if (needToCommitOrRollback) {
     return CommitOrRollback();
   }
@@ -528,19 +565,28 @@ IDBTransaction::AbortWithCode(nsresult a
 }
 
 nsresult
 IDBTransaction::Abort(IDBRequest* aRequest)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(aRequest, "This is undesirable.");
 
-  aRequest->GetError(getter_AddRefs(mError));
+  nsCOMPtr<nsIDOMDOMError> error;
+  aRequest->GetError(getter_AddRefs(error));
+
+  return AbortInternal(aRequest->GetErrorCode(), error.forget());
+}
 
-  return AbortWithCode(aRequest->GetErrorCode());
+nsresult
+IDBTransaction::Abort(nsresult aErrorCode)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+  return AbortInternal(aErrorCode, DOMError::CreateForNSResult(aErrorCode));
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(IDBTransaction)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBTransaction,
                                                   IDBWrapperCache)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mDatabase,
                                                        nsIDOMEventTarget)
@@ -549,26 +595,32 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(complete)
   NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(abort)
 
   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()));
   }
+  for (PRUint32 i = 0; i < tmp->mDeletedObjectStores.Length(); i++) {
+    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mDeletedObjectStores[i]");
+    cb.NoteXPCOMChild(static_cast<nsIIDBObjectStore*>(
+                      tmp->mDeletedObjectStores[i].get()));
+  }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBTransaction, IDBWrapperCache)
   // Don't unlink mDatabase!
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mError);
   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(complete)
   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(abort)
 
   tmp->mCreatedObjectStores.Clear();
+  tmp->mDeletedObjectStores.Clear();
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBTransaction)
   NS_INTERFACE_MAP_ENTRY(nsIIDBTransaction)
   NS_INTERFACE_MAP_ENTRY(nsIRunnable)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBTransaction)
 NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache)
@@ -703,17 +755,17 @@ IDBTransaction::ObjectStoreInternal(cons
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 IDBTransaction::Abort()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-  return AbortWithCode(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR);
+  return AbortInternal(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR, nsnull);
 }
 
 nsresult
 IDBTransaction::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   aVisitor.mCanHandle = true;
   aVisitor.mParentTarget = mDatabase;
   return NS_OK;
--- a/dom/indexedDB/IDBTransaction.h
+++ b/dom/indexedDB/IDBTransaction.h
@@ -188,28 +188,31 @@ public:
     return mActorChild;
   }
 
   nsresult
   ObjectStoreInternal(const nsAString& aName,
                       IDBObjectStore** _retval);
 
   nsresult
-  AbortWithCode(nsresult aAbortCode);
+  Abort(IDBRequest* aRequest);
 
   nsresult
-  Abort(IDBRequest* aRequest);
+  Abort(nsresult aAbortCode);
 
   nsresult
   GetAbortCode() const
   {
     return mAbortCode;
   }
 
 private:
+  nsresult
+  AbortInternal(nsresult aAbortCode, already_AddRefed<nsIDOMDOMError> aError);
+
   // Should only be called directly through IndexedDBDatabaseChild.
   static already_AddRefed<IDBTransaction>
   CreateInternal(IDBDatabase* aDatabase,
                  nsTArray<nsString>& aObjectStoreNames,
                  Mode aMode,
                  bool aDispatchDelayed,
                  bool aIsVersionChangeTransactionChild);
 
@@ -238,16 +241,17 @@ private:
 
   // Only touched on the database thread.
   nsCOMPtr<mozIStorageConnection> mConnection;
 
   // Only touched on the database thread.
   PRUint32 mSavepointCount;
 
   nsTArray<nsRefPtr<IDBObjectStore> > mCreatedObjectStores;
+  nsTArray<nsRefPtr<IDBObjectStore> > mDeletedObjectStores;
 
   nsRefPtr<UpdateRefcountFunction> mUpdateFileRefcountFunction;
   nsRefPtrHashtable<nsISupportsHashKey, FileInfo> mCreatedFileInfos;
 
   IndexedDBTransactionChild* mActorChild;
   IndexedDBTransactionParent* mActorParent;
 
   nsresult mAbortCode;
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -3,34 +3,37 @@
 /* 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 "IndexedDatabaseManager.h"
 #include "DatabaseInfo.h"
 
 #include "nsIAtom.h"
+#include "nsIConsoleService.h"
 #include "nsIDOMScriptObjectFactory.h"
 #include "nsIFile.h"
 #include "nsIFileStorage.h"
 #include "nsIObserverService.h"
+#include "nsIScriptError.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsISHEntry.h"
 #include "nsISimpleEnumerator.h"
 #include "nsITimer.h"
 
 #include "mozilla/dom/file/FileService.h"
 #include "mozilla/LazyIdleThread.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/storage.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsContentUtils.h"
 #include "nsDirectoryServiceUtils.h"
+#include "nsEventDispatcher.h"
 #include "nsThreadUtils.h"
 #include "nsXPCOM.h"
 #include "nsXPCOMPrivate.h"
 #include "test_quota.h"
 #include "xpcpublic.h"
 
 #include "AsyncConnectionHelper.h"
 #include "CheckQuotaHelper.h"
@@ -311,16 +314,96 @@ IndexedDatabaseManager::GetDatabaseId(co
   str.Append(NS_ConvertUTF16toUTF8(aName));
 
   nsCOMPtr<nsIAtom> atom = do_GetAtom(str);
   NS_ENSURE_TRUE(atom, nsnull);
 
   return atom.forget();
 }
 
+// static
+nsresult
+IndexedDatabaseManager::FireWindowOnError(nsPIDOMWindow* aOwner,
+                                          nsEventChainPostVisitor& aVisitor)
+{
+  NS_ENSURE_TRUE(aVisitor.mDOMEvent, NS_ERROR_UNEXPECTED);
+  if (!aOwner) {
+    return NS_OK;
+  }
+
+  if (aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault) {
+    return NS_OK;
+  }
+
+  nsString type;
+  nsresult rv = aVisitor.mDOMEvent->GetType(type);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (!type.EqualsLiteral(ERROR_EVT_STR)) {
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsIDOMEventTarget> eventTarget;
+  rv = aVisitor.mDOMEvent->GetTarget(getter_AddRefs(eventTarget));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIIDBRequest> strongRequest = do_QueryInterface(eventTarget);
+  IDBRequest* request = static_cast<IDBRequest*>(strongRequest.get());
+  NS_ENSURE_TRUE(request, NS_ERROR_UNEXPECTED);
+
+  nsCOMPtr<nsIDOMDOMError> error;
+  rv = request->GetError(getter_AddRefs(error));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsString errorName;
+  if (error) {
+    rv = error->GetName(errorName);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  nsScriptErrorEvent event(true, NS_LOAD_ERROR);
+  request->FillScriptErrorEvent(&event);
+  event.errorMsg = errorName.get();
+
+  nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(aOwner));
+  NS_ASSERTION(sgo, "How can this happen?!");
+
+  nsEventStatus status = nsEventStatus_eIgnore;
+  if (NS_FAILED(sgo->HandleScriptError(&event, &status))) {
+    NS_WARNING("Failed to dispatch script error event");
+    status = nsEventStatus_eIgnore;
+  }
+
+  bool preventDefaultCalled = status == nsEventStatus_eConsumeNoDefault;
+  if (preventDefaultCalled) {
+    return NS_OK;
+  }
+
+  // Log an error to the error console.
+  nsCOMPtr<nsIScriptError> scriptError =
+    do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (NS_FAILED(scriptError->InitWithWindowID(event.errorMsg,
+                                              event.fileName,
+                                              nsnull, event.lineNr,
+                                              nsnull, 0,
+                                              "IndexedDB",
+                                              aOwner->WindowID()))) {
+    NS_WARNING("Failed to init script error!");
+    return NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIConsoleService> consoleService =
+    do_GetService(NS_CONSOLESERVICE_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return consoleService->LogMessage(scriptError);
+}
+
 bool
 IndexedDatabaseManager::RegisterDatabase(IDBDatabase* aDatabase)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(aDatabase, "Null pointer!");
 
   // Don't allow any new databases to be created after shutdown.
   if (IsShuttingDown()) {
@@ -1822,21 +1905,21 @@ IndexedDatabaseManager::InitWindowless(c
   JSObject* global = JS_GetGlobalForObject(aCx, obj);
 
   nsRefPtr<IDBFactory> factory;
   nsresult rv = IDBFactory::Create(aCx, global, getter_AddRefs(factory));
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   NS_ASSERTION(factory, "This should never fail for chrome!");
 
-  jsval mozIndexedDBVal;
-  rv = nsContentUtils::WrapNative(aCx, obj, factory, &mozIndexedDBVal);
+  jsval indexedDBVal;
+  rv = nsContentUtils::WrapNative(aCx, obj, factory, &indexedDBVal);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (!JS_DefineProperty(aCx, obj, "mozIndexedDB", mozIndexedDBVal, nsnull,
+  if (!JS_DefineProperty(aCx, obj, "indexedDB", indexedDBVal, 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)) {
--- a/dom/indexedDB/IndexedDatabaseManager.h
+++ b/dom/indexedDB/IndexedDatabaseManager.h
@@ -23,16 +23,17 @@
 
 #define INDEXEDDB_MANAGER_CONTRACTID "@mozilla.org/dom/indexeddb/manager;1"
 
 class mozIStorageQuotaCallback;
 class nsIAtom;
 class nsIFile;
 class nsITimer;
 class nsPIDOMWindow;
+class nsEventChainPostVisitor;
 
 BEGIN_INDEXEDDB_NAMESPACE
 
 class AsyncConnectionHelper;
 class CheckQuotaHelper;
 class FileManager;
 class IDBDatabase;
 
@@ -191,16 +192,18 @@ public:
 
     return mgr->mFileMutex;
   }
 
   static already_AddRefed<nsIAtom>
   GetDatabaseId(const nsACString& aOrigin,
                 const nsAString& aName);
 
+  static nsresult
+  FireWindowOnError(nsPIDOMWindow* aOwner, nsEventChainPostVisitor& aVisitor);
 private:
   IndexedDatabaseManager();
   ~IndexedDatabaseManager();
 
   nsresult AcquireExclusiveAccess(const nsACString& aOrigin,
                                   IDBDatabase* aDatabase,
                                   AsyncConnectionHelper* aHelper,
                                   nsIRunnable* aRunnable,
--- a/dom/indexedDB/OpenDatabaseHelper.cpp
+++ b/dom/indexedDB/OpenDatabaseHelper.cpp
@@ -1631,17 +1631,21 @@ OpenDatabaseHelper::DoDatabaseWork()
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   rv = fileManagerDirectory->Append(filename);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsCOMPtr<mozIStorageConnection> connection;
   rv = CreateDatabaseConnection(mName, dbFile, fileManagerDirectory,
                                 getter_AddRefs(connection));
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  if (NS_FAILED(rv) &&
+      NS_ERROR_GET_MODULE(rv) != NS_ERROR_MODULE_DOM_INDEXEDDB) {
+    rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+  }
+  NS_ENSURE_SUCCESS(rv, rv);
 
   rv = IDBFactory::LoadDatabaseInformation(connection, mDatabaseId,
                                            &mCurrentVersion, mObjectStores);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   if (mForDeletion) {
     mState = eDeletePending;
     return NS_OK;
@@ -1832,17 +1836,22 @@ OpenDatabaseHelper::CreateDatabaseConnec
 
         rv = connection->GetSchemaVersion(&schemaVersion);
         NS_ENSURE_SUCCESS(rv, rv);
       }
 
       NS_ASSERTION(schemaVersion == kSQLiteSchemaVersion, "Huh?!");
     }
 
-    rv = transaction.Commit();
+    rv = transaction.Commit();    
+    if (rv == NS_ERROR_FILE_NO_DEVICE_SPACE) {
+      // mozstorage translates SQLITE_FULL to NS_ERROR_FILE_NO_DEVICE_SPACE,
+      // which we know better as NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR.
+      rv = NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
+    }
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (vacuumNeeded) {
     rv = connection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
       "VACUUM;"
     ));
     NS_ENSURE_SUCCESS(rv, rv);
--- a/dom/indexedDB/crashtests/726376-1.html
+++ b/dom/indexedDB/crashtests/726376-1.html
@@ -1,7 +1,7 @@
 <script>
 
 var a = [];
 a[0] = a;
-mozIndexedDB.cmp.bind(mozIndexedDB)(a, a);
+indexedDB.cmp.bind(indexedDB)(a, a);
 
 </script>
--- a/dom/indexedDB/ipc/IndexedDBChild.cpp
+++ b/dom/indexedDB/ipc/IndexedDBChild.cpp
@@ -465,16 +465,17 @@ IndexedDBDatabaseChild::RecvPIndexedDBTr
     IDBTransaction::CreateInternal(mDatabase, storesToOpen,
                                    IDBTransaction::VERSION_CHANGE, false, true);
   NS_ENSURE_TRUE(transaction, false);
 
   nsRefPtr<IPCSetVersionHelper> versionHelper =
     new IPCSetVersionHelper(actor, transaction, mRequest, oldVersion, mVersion);
 
   mDatabase->EnterSetVersionTransaction();
+  mDatabase->mPreviousDatabaseInfo->version = oldVersion;
 
   MainThreadEventTarget target;
   if (NS_FAILED(versionHelper->Dispatch(&target))) {
     NS_WARNING("Dispatch of IPCSetVersionHelper failed!");
     return false;
   }
 
   actor->SetTransaction(transaction);
--- a/dom/indexedDB/ipc/IndexedDBParent.cpp
+++ b/dom/indexedDB/ipc/IndexedDBParent.cpp
@@ -65,17 +65,18 @@ IndexedDBParent::ActorDestroy(ActorDestr
 bool
 IndexedDBParent::RecvPIndexedDBDatabaseConstructor(
                                                PIndexedDBDatabaseParent* aActor,
                                                const nsString& aName,
                                                const uint64_t& aVersion)
 {
   nsRefPtr<IDBOpenDBRequest> request;
   nsresult rv =
-    mFactory->OpenCommon(aName, aVersion, false, getter_AddRefs(request));
+    mFactory->OpenCommon(aName, aVersion, false, nsnull,
+                         getter_AddRefs(request));
   NS_ENSURE_SUCCESS(rv, false);
 
   IndexedDBDatabaseParent* actor =
     static_cast<IndexedDBDatabaseParent*>(aActor);
 
   rv = actor->SetOpenRequest(request);
   NS_ENSURE_SUCCESS(rv, false);
 
@@ -88,17 +89,17 @@ IndexedDBParent::RecvPIndexedDBDeleteDat
                                   const nsString& aName)
 {
   IndexedDBDeleteDatabaseRequestParent* actor =
     static_cast<IndexedDBDeleteDatabaseRequestParent*>(aActor);
 
   nsRefPtr<IDBOpenDBRequest> request;
 
   nsresult rv =
-    mFactory->OpenCommon(aName, 0, true, getter_AddRefs(request));
+    mFactory->OpenCommon(aName, 0, true, nsnull, getter_AddRefs(request));
   NS_ENSURE_SUCCESS(rv, false);
 
   rv = actor->SetOpenRequest(request);
   NS_ENSURE_SUCCESS(rv, false);
 
   return true;
 }
 
@@ -372,17 +373,17 @@ IndexedDBDatabaseParent::HandleDatabaseE
 {
   MOZ_ASSERT(mDatabase);
   MOZ_ASSERT(!aType.EqualsLiteral(ERROR_EVT_STR),
              "Should never get error events in the parent process!");
 
   nsresult rv;
 
   if (aType.EqualsLiteral(VERSIONCHANGE_EVT_STR)) {
-    JSContext* cx = nsContentUtils::GetCurrentJSContext();
+    JSContext* cx = nsContentUtils::GetSafeJSContext();
     NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
 
     nsCOMPtr<nsIIDBVersionChangeEvent> changeEvent = do_QueryInterface(aEvent);
     NS_ENSURE_TRUE(changeEvent, NS_ERROR_FAILURE);
 
     PRUint64 oldVersion;
     rv = changeEvent->GetOldVersion(&oldVersion);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -572,17 +573,17 @@ IndexedDBTransactionParent::ActorDestroy
     mTransaction->SetActor(static_cast<IndexedDBTransactionParent*>(NULL));
   }
 }
 
 bool
 IndexedDBTransactionParent::RecvAbort(const nsresult& aAbortCode)
 {
   MOZ_ASSERT(mTransaction);
-  mTransaction->AbortWithCode(aAbortCode);
+  mTransaction->Abort(aAbortCode);
   return true;
 }
 
 bool
 IndexedDBTransactionParent::RecvAllRequestsFinished()
 {
   MOZ_ASSERT(mTransaction);
   MOZ_ASSERT(mArtificialRequestCount);
@@ -1191,17 +1192,18 @@ IndexedDBObjectStoreRequestParent::Get(c
 
   nsRefPtr<IDBKeyRange> keyRange =
     IDBKeyRange::FromSerializedKeyRange(aParams.keyRange());
   MOZ_ASSERT(keyRange);
 
   {
     AutoSetCurrentTransaction asct(mObjectStore->Transaction());
 
-    nsresult rv = mObjectStore->GetInternal(keyRange, getter_AddRefs(request));
+    nsresult rv = mObjectStore->GetInternal(keyRange, nsnull,
+                                            getter_AddRefs(request));
     NS_ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
 
@@ -1230,16 +1232,17 @@ IndexedDBObjectStoreRequestParent::GetAl
       MOZ_NOT_REACHED("Unknown param type!");
       return false;
   }
 
   {
     AutoSetCurrentTransaction asct(mObjectStore->Transaction());
 
     nsresult rv = mObjectStore->GetAllInternal(keyRange, aParams.limit(),
+                                               nsnull,
                                                getter_AddRefs(request));
     NS_ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
@@ -1302,17 +1305,17 @@ IndexedDBObjectStoreRequestParent::Delet
   nsRefPtr<IDBKeyRange> keyRange =
     IDBKeyRange::FromSerializedKeyRange(aParams.keyRange());
   MOZ_ASSERT(keyRange);
 
   {
     AutoSetCurrentTransaction asct(mObjectStore->Transaction());
 
     nsresult rv =
-      mObjectStore->DeleteInternal(keyRange, getter_AddRefs(request));
+      mObjectStore->DeleteInternal(keyRange, nsnull, getter_AddRefs(request));
     NS_ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
 
@@ -1321,17 +1324,17 @@ IndexedDBObjectStoreRequestParent::Clear
 {
   MOZ_ASSERT(mRequestType == ParamsUnionType::TClearParams);
 
   nsRefPtr<IDBRequest> request;
 
   {
     AutoSetCurrentTransaction asct(mObjectStore->Transaction());
 
-    nsresult rv = mObjectStore->ClearInternal(getter_AddRefs(request));
+    nsresult rv = mObjectStore->ClearInternal(nsnull, getter_AddRefs(request));
     NS_ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
 
@@ -1360,17 +1363,17 @@ IndexedDBObjectStoreRequestParent::Count
   }
 
   nsRefPtr<IDBRequest> request;
 
   {
     AutoSetCurrentTransaction asct(mObjectStore->Transaction());
 
     nsresult rv =
-      mObjectStore->CountInternal(keyRange, getter_AddRefs(request));
+      mObjectStore->CountInternal(keyRange, nsnull, getter_AddRefs(request));
     NS_ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
 
@@ -1401,17 +1404,17 @@ IndexedDBObjectStoreRequestParent::OpenC
   size_t direction = static_cast<size_t>(aParams.direction());
 
   nsRefPtr<IDBRequest> request;
 
   {
     AutoSetCurrentTransaction asct(mObjectStore->Transaction());
 
     nsresult rv =
-      mObjectStore->OpenCursorInternal(keyRange, direction,
+      mObjectStore->OpenCursorInternal(keyRange, direction, nsnull,
                                        getter_AddRefs(request));
     NS_ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
@@ -1445,17 +1448,18 @@ IndexedDBIndexRequestParent::Get(const G
 
   nsRefPtr<IDBKeyRange> keyRange =
     IDBKeyRange::FromSerializedKeyRange(aParams.keyRange());
   MOZ_ASSERT(keyRange);
 
   {
     AutoSetCurrentTransaction asct(mIndex->ObjectStore()->Transaction());
 
-    nsresult rv = mIndex->GetInternal(keyRange, getter_AddRefs(request));
+    nsresult rv = mIndex->GetInternal(keyRange, nsnull,
+                                      getter_AddRefs(request));
     NS_ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
 
@@ -1468,17 +1472,18 @@ IndexedDBIndexRequestParent::GetKey(cons
 
   nsRefPtr<IDBKeyRange> keyRange =
     IDBKeyRange::FromSerializedKeyRange(aParams.keyRange());
   MOZ_ASSERT(keyRange);
 
   {
     AutoSetCurrentTransaction asct(mIndex->ObjectStore()->Transaction());
 
-    nsresult rv = mIndex->GetKeyInternal(keyRange, getter_AddRefs(request));
+    nsresult rv = mIndex->GetKeyInternal(keyRange, nsnull,
+                                         getter_AddRefs(request));
     NS_ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
 
@@ -1506,17 +1511,17 @@ IndexedDBIndexRequestParent::GetAll(cons
     default:
       MOZ_NOT_REACHED("Unknown param type!");
       return false;
   }
 
   {
     AutoSetCurrentTransaction asct(mIndex->ObjectStore()->Transaction());
 
-    nsresult rv = mIndex->GetAllInternal(keyRange, aParams.limit(),
+    nsresult rv = mIndex->GetAllInternal(keyRange, aParams.limit(), nsnull,
                                          getter_AddRefs(request));
     NS_ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
@@ -1545,17 +1550,17 @@ IndexedDBIndexRequestParent::GetAllKeys(
     default:
       MOZ_NOT_REACHED("Unknown param type!");
       return false;
   }
 
   {
     AutoSetCurrentTransaction asct(mIndex->ObjectStore()->Transaction());
 
-    nsresult rv = mIndex->GetAllKeysInternal(keyRange, aParams.limit(),
+    nsresult rv = mIndex->GetAllKeysInternal(keyRange, aParams.limit(), nsnull,
                                              getter_AddRefs(request));
     NS_ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
@@ -1584,17 +1589,18 @@ IndexedDBIndexRequestParent::Count(const
       return false;
   }
 
   nsRefPtr<IDBRequest> request;
 
   {
     AutoSetCurrentTransaction asct(mIndex->ObjectStore()->Transaction());
 
-    nsresult rv = mIndex->CountInternal(keyRange, getter_AddRefs(request));
+    nsresult rv = mIndex->CountInternal(keyRange, nsnull,
+                                        getter_AddRefs(request));
     NS_ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
 
@@ -1625,17 +1631,18 @@ IndexedDBIndexRequestParent::OpenCursor(
   size_t direction = static_cast<size_t>(aParams.direction());
 
   nsRefPtr<IDBRequest> request;
 
   {
     AutoSetCurrentTransaction asct(mIndex->ObjectStore()->Transaction());
 
     nsresult rv =
-      mIndex->OpenCursorInternal(keyRange, direction, getter_AddRefs(request));
+      mIndex->OpenCursorInternal(keyRange, direction, nsnull,
+                                 getter_AddRefs(request));
     NS_ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
 
@@ -1666,17 +1673,17 @@ IndexedDBIndexRequestParent::OpenKeyCurs
   size_t direction = static_cast<size_t>(aParams.direction());
 
   nsRefPtr<IDBRequest> request;
 
   {
     AutoSetCurrentTransaction asct(mIndex->ObjectStore()->Transaction());
 
     nsresult rv =
-      mIndex->OpenKeyCursorInternal(keyRange, direction,
+      mIndex->OpenKeyCursorInternal(keyRange, direction, nsnull,
                                     getter_AddRefs(request));
     NS_ENSURE_SUCCESS(rv, false);
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
--- a/dom/indexedDB/nsIIDBCursor.idl
+++ b/dom/indexedDB/nsIIDBCursor.idl
@@ -8,17 +8,17 @@
 
 interface nsIIDBRequest;
 
 /**
  * IDBCursor interface.  See
  * http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBCursor for more
  * information.
  */
-[scriptable, builtinclass, uuid(01136b3a-d84c-487c-b929-f5d012346c44)]
+[scriptable, builtinclass, uuid(148579a3-6b28-4b2a-92c3-ff5719e8e03e)]
 interface nsIIDBCursor : nsISupports
 {
   // "next", "nextunique", "prev" or "prevunique"
   readonly attribute DOMString direction;
 
   readonly attribute nsISupports source;
 
   [implicit_jscontext]
@@ -36,10 +36,10 @@ interface nsIIDBCursor : nsISupports
   [implicit_jscontext]
   nsIIDBRequest update(in jsval value);
 
   // Success fires IDBTransactionEvent, result == null
   [implicit_jscontext]
   nsIIDBRequest delete();
 
   void
-  advance(in long count);
+  advance(in long long count);
 };
--- a/dom/indexedDB/nsIIDBDatabase.idl
+++ b/dom/indexedDB/nsIIDBDatabase.idl
@@ -18,17 +18,17 @@ dictionary IDBObjectStoreParameters
   boolean autoIncrement;
 };
 
 /**
  * IDBDatabase interface.  See
  * http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBDatabase
  * for more information.
  */
-[scriptable, builtinclass, uuid(4543dbad-2b37-4741-8729-73b08b7ee37e)]
+[scriptable, builtinclass, uuid(601a43a0-dce2-402f-8ba5-238fe5d5f8d2)]
 interface nsIIDBDatabase : nsISupports
 {
   readonly attribute DOMString name;
 
   readonly attribute unsigned long long version;
 
   readonly attribute nsIDOMDOMStringList objectStoreNames;
 
@@ -42,16 +42,17 @@ interface nsIIDBDatabase : nsISupports
   deleteObjectStore([Null(Stringify)] in DOMString name);
 
   // mode can be either "readonly" or "readwrite"
   [optional_argc, implicit_jscontext]
   nsIIDBTransaction
   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();
 
   attribute nsIDOMEventListener onabort;
--- a/dom/indexedDB/nsIIDBFactory.idl
+++ b/dom/indexedDB/nsIIDBFactory.idl
@@ -9,24 +9,25 @@
 interface nsIIDBKeyRange;
 interface nsIIDBOpenDBRequest;
 
 /**
  * Interface that defines the indexedDB property on a window.  See
  * http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBFactory
  * for more information.
  */
-[scriptable, builtinclass, uuid(885abbb7-cf81-4945-b5f1-07fed07ada82)]
+[scriptable, builtinclass, uuid(3c763a8f-df53-491d-9635-e1d959e43c0c)]
 interface nsIIDBFactory : nsISupports
 {
-  [optional_argc]
+  [implicit_jscontext, optional_argc]
   nsIIDBOpenDBRequest
   open([Null(Stringify)] in DOMString name,
        [optional] in long long version);
 
+  [implicit_jscontext]
   nsIIDBOpenDBRequest
   deleteDatabase(in AString name);
 
   [implicit_jscontext]
   short
   cmp(in jsval first,
       in jsval second);
 };
--- a/dom/indexedDB/nsIIDBIndex.idl
+++ b/dom/indexedDB/nsIIDBIndex.idl
@@ -33,25 +33,25 @@ interface nsIIDBIndex : nsISupports
   [implicit_jscontext]
   nsIIDBRequest
   get(in jsval key);
 
   [implicit_jscontext]
   nsIIDBRequest
   getKey(in jsval key);
 
-  [implicit_jscontext, optional_argc]
+  [implicit_jscontext, optional_argc, binaryname(GetAll)]
   nsIIDBRequest
-  getAll([optional /* null */] in jsval key,
-         [optional /* unlimited */] in unsigned long limit);
+  mozGetAll([optional /* null */] in jsval key,
+            [optional /* unlimited */] in unsigned long limit);
 
-  [implicit_jscontext, optional_argc]
+  [implicit_jscontext, optional_argc, binaryname(GetAllKeys)]
   nsIIDBRequest
-  getAllKeys([optional /* null */] in jsval key,
-             [optional /* unlimited */] in unsigned long limit);
+  mozGetAllKeys([optional /* null */] in jsval key,
+                [optional /* unlimited */] in unsigned long limit);
 
   // direction can be "next", "nextunique", "prev" or "prevunique"
   [implicit_jscontext, optional_argc]
   nsIIDBRequest
   openCursor([optional /* null */] in jsval key,
              [optional /* "next" */] in DOMString direction);
 
   // direction can be "next", "nextunique", "prev" or "prevunique"
--- a/dom/indexedDB/nsIIDBObjectStore.idl
+++ b/dom/indexedDB/nsIIDBObjectStore.idl
@@ -18,17 +18,17 @@ dictionary IDBIndexParameters
   boolean multiEntry;
 };
 
 /**
  * nsIIDBObjectStore interface.  See
  * http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-nsIIDBObjectStore
  * for more information.
  */
-[scriptable, builtinclass, uuid(43157a3c-bed1-4ce7-98c0-11365b852560)]
+[scriptable, builtinclass, uuid(dd189afd-e1b7-4496-bf8d-629c58709595)]
 interface nsIIDBObjectStore : nsISupports
 {
   readonly attribute DOMString name;
 
   [implicit_jscontext]
   readonly attribute jsval keyPath;
 
   readonly attribute nsIDOMDOMStringList indexNames;
@@ -38,20 +38,20 @@ interface nsIIDBObjectStore : nsISupport
   readonly attribute boolean autoIncrement;
 
   // Success fires IDBTransactionEvent, result == value for key
   [implicit_jscontext]
   nsIIDBRequest
   get(in jsval key);
 
   // Success fires IDBTransactionEvent, result == array of values for given keys
-  [implicit_jscontext, optional_argc]
+  [implicit_jscontext, optional_argc, binaryname(GetAll)]
   nsIIDBRequest
-  getAll([optional /* null */] in jsval key,
-         [optional /* unlimited */] in unsigned long limit);
+  mozGetAll([optional /* null */] in jsval key,
+            [optional /* unlimited */] in unsigned long limit);
 
   // Success fires IDBTransactionEvent, result == key
   [implicit_jscontext, optional_argc]
   nsIIDBRequest
   add(in jsval value,
       [optional /* undefined */] in jsval key);
 
   // Success fires IDBTransactionEvent, result == key
@@ -61,16 +61,17 @@ interface nsIIDBObjectStore : nsISupport
       [optional /* undefined */] in jsval key);
 
   // Success fires IDBTransactionEvent, result == null
   [implicit_jscontext]
   nsIIDBRequest
   delete(in jsval key);
 
   // Success fires IDBTransactionEvent, result == null
+  [implicit_jscontext]
   nsIIDBRequest
   clear();
 
   // Success fires IDBTransactionEvent, result == IDBCursor or result == null if
   // no match.
   // direction can be "next", "nextunique", "prev" or "prevunique"
   [implicit_jscontext, optional_argc]
   nsIIDBRequest
--- a/dom/indexedDB/nsIIndexedDatabaseManager.idl
+++ b/dom/indexedDB/nsIIndexedDatabaseManager.idl
@@ -52,17 +52,17 @@ interface nsIIndexedDatabaseManager : ns
    * deleted immediately depending on prohibitive concurrent operations.
    *
    * @param aURI
    *        The URI whose databases are to be cleared.
    */
   void clearDatabasesForURI(in nsIURI aURI);
 
   /**
-   * Defines mozIndexedDB and IDBKeyrange with its static functions on 
+   * Defines indexedDB and IDBKeyrange with its static functions on 
    * aObject and initializes DOM exception providers if needed.
    *
    * @param aObject
-   *        The object, mozIndexedDB and IDBKeyrange should be defined on.
+   *        The object, indexedDB and IDBKeyrange should be defined on.
    */
   [implicit_jscontext]
   void initWindowless(in jsval aObject);
 };
--- a/dom/indexedDB/test/Makefile.in
+++ b/dom/indexedDB/test/Makefile.in
@@ -15,17 +15,17 @@ XPCSHELL_TESTS = unit
 
 include $(topsrcdir)/config/rules.mk
 
 TEST_FILES = \
   bfcache_iframe1.html \
   bfcache_iframe2.html \
   error_events_abort_transactions_iframe.html \
   event_propagation_iframe.html \
-  exceptions_in_success_events_iframe.html \
+  exceptions_in_events_iframe.html \
   file.js \
   helpers.js \
   leaving_page_iframe.html \
   test_add_put.html \
   test_add_twice_failure.html \
   test_advance.html \
   test_autoIncrement_indexes.html \
   test_autoIncrement.html \
@@ -39,17 +39,17 @@ TEST_FILES = \
   test_cursors.html \
   test_cursor_mutation.html \
   test_cursor_update_updates_indexes.html \
   test_deleteDatabase.html \
   test_deleteDatabase_interactions.html \
   test_error_events_abort_transactions.html \
   test_event_propagation.html \
   test_event_source.html \
-  test_exceptions_in_success_events.html \
+  test_exceptions_in_events.html \
   test_file_array.html \
   test_file_cross_database_copying.html \
   test_file_delete.html \
   test_file_os_delete.html \
   test_file_put_get_object.html \
   test_file_put_get_values.html \
   test_file_replace.html \
   test_file_resurrection_delete.html \
@@ -66,16 +66,17 @@ TEST_FILES = \
   test_index_object_cursors.html \
   test_index_update_delete.html \
   test_indexes.html \
   test_indexes_bad_values.html \
   test_key_requirements.html \
   test_keys.html \
   test_leaving_page.html \
   test_multientry.html \
+  test_names_sorted.html \
   test_objectCursors.html \
   test_objectStore_inline_autoincrement_key_added_on_put.html \
   test_objectStore_remove_values.html \
   test_object_identity.html \
   test_odd_result_order.html \
   test_open_empty_db.html \
   test_open_objectStore.html \
   test_optionalArguments.html \
--- a/dom/indexedDB/test/bfcache_iframe1.html
+++ b/dom/indexedDB/test/bfcache_iframe1.html
@@ -1,13 +1,13 @@
 <!DOCTYPE html>
 <html>
 <head>
   <script>
-  var request = mozIndexedDB.open(parent.location, 1);
+  var request = indexedDB.open(parent.location, 1);
   request.onupgradeneeded = function(e) {
     var db = e.target.result;
     // This should never be called
     db.onversionchange = function(e) {
       db.transaction(["mystore"]).objectStore("mystore").put({ hello: "fail" }, 42);
     }
     var trans = e.target.transaction;
     if (db.objectStoreNames.contains("mystore")) {
--- a/dom/indexedDB/test/bfcache_iframe2.html
+++ b/dom/indexedDB/test/bfcache_iframe2.html
@@ -1,14 +1,14 @@
 <!DOCTYPE html>
 <html>
 <head>
   <script>
   var res = {};
-  var request = mozIndexedDB.open(parent.location, 2);
+  var request = indexedDB.open(parent.location, 2);
   request.onblocked = function() {
     res.blockedFired = true;
   }
   request.onupgradeneeded  = function(e) {
     var db = e.target.result;
     res.version = db.version;
     res.storeCount = db.objectStoreNames.length;
 
--- a/dom/indexedDB/test/browser_forgetThisSiteAdd.html
+++ b/dom/indexedDB/test/browser_forgetThisSiteAdd.html
@@ -4,17 +4,17 @@
 -->
 <html>
   <head>
     <title>Indexed Database Test</title>
 
     <script type="text/javascript;version=1.7">
       function testSteps()
       {
-        let request = mozIndexedDB.open("browser_forgetThisSite.js", 11);
+        let request = indexedDB.open("browser_forgetThisSite.js", 11);
         request.onerror = grabEventAndContinueHandler;
         request.onupgradeneeded = grabEventAndContinueHandler;
         let event = yield;
 
         if (event.type == "error") {
           testException = event.target.error.name;
         }
         else {
--- a/dom/indexedDB/test/browser_forgetThisSiteGet.html
+++ b/dom/indexedDB/test/browser_forgetThisSiteGet.html
@@ -4,17 +4,17 @@
 -->
 <html>
   <head>
     <title>Indexed Database Test</title>
 
     <script type="text/javascript;version=1.7">
       function testSteps()
       {
-        let request = mozIndexedDB.open("browser_forgetThisSite.js");
+        let request = indexedDB.open("browser_forgetThisSite.js");
         request.onerror = grabEventAndContinueHandler;
         request.onsuccess = grabEventAndContinueHandler;
         let event = yield;
 
         if (event.type == "error") {
           testException = event.target.error.name;
         }
         else {
--- a/dom/indexedDB/test/browser_permissionsPrompt.html
+++ b/dom/indexedDB/test/browser_permissionsPrompt.html
@@ -7,28 +7,30 @@
     <title>Indexed Database Test</title>
 
     <script type="text/javascript;version=1.7">
       function testSteps()
       {
         const name = window.location.pathname;
         const description = "My Test Database";
 
-        let request = mozIndexedDB.open(name, 1, description);
+        let request = indexedDB.open(name, 1, description);
         request.onerror = grabEventAndContinueHandler;
         request.onsuccess = grabEventAndContinueHandler;
         let event = yield;
 
         if (event.type == "success") {
           testResult = event.target.result;
         }
         else {
           testException = event.target.error.name;
         }
 
+        event.preventDefault();
+
         finishTest()
         yield;
       }
     </script>
 
     <script type="text/javascript;version=1.7" src="browserHelpers.js"></script>
 
   </head>
--- a/dom/indexedDB/test/browser_quotaPrompt.html
+++ b/dom/indexedDB/test/browser_quotaPrompt.html
@@ -30,17 +30,17 @@
           objectStore.add(obj).onerror = errorHandler;
         }
       }
 
       function onDone() {
         window.removeEventListener("indexedDB-addMore", onAddMore, true);
         window.removeEventListener("indexedDB-done", onDone, true);
 
-        let request = mozIndexedDB.open(window.location.pathname, version++);
+        let request = indexedDB.open(window.location.pathname, version++);
         request.onerror = errorHandler;
         request.onupgradeneeded = function(event) {
           db.deleteObjectStore("foo");
           db.onversionchange = function () { db.close(); };
           request.transaction.oncomplete = function(event) {
             testResult = "finished";
             testException = undefined;
             finishTest();
@@ -51,17 +51,17 @@
       function testSteps()
       {
         const name = window.location.pathname;
         const description = "My Test Database";
 
         window.addEventListener("indexedDB-addMore", onAddMore, true);
         window.addEventListener("indexedDB-done", onDone, true);
 
-        let request = mozIndexedDB.open(name, version++, description);
+        let request = indexedDB.open(name, version++, description);
         request.onerror = errorHandler;
         request.onupgradeneeded = grabEventAndContinueHandler;
         let event = yield;
 
         db = event.target.result;
 
         db.onversionchange = function () { db.close(); };
 
--- a/dom/indexedDB/test/browser_quotaPromptDatabases.html
+++ b/dom/indexedDB/test/browser_quotaPromptDatabases.html
@@ -8,17 +8,17 @@
 
     <script type="text/javascript;version=1.7">
       let db;
       let i = 0;
 
       function onAddMore() {
         const name = window.location.pathname + i++;
 
-        let request = mozIndexedDB.open(name, 1);
+        let request = indexedDB.open(name, 1);
         request.onerror = errorHandler;
         request.onsuccess = grabEventAndContinueHandler;
 
         request.onsuccess = function(event) {
           setTimeout(testFinishedCallback, 0, "complete");
         }
         request.onerror = function(event) {
           setTimeout(testFinishedCallback, 0, "abort");
--- a/dom/indexedDB/test/browser_quotaPromptDelete.html
+++ b/dom/indexedDB/test/browser_quotaPromptDelete.html
@@ -39,22 +39,22 @@
         testResult = "finished";
         testException = undefined;
         finishTest();
       }
 
       function onReset() {
         db.close();
         // N.B. the spec provides no ordering guarantee w.r.t deleteDatabase.
-        let deleteRequest = mozIndexedDB.deleteDatabase(name);
+        let deleteRequest = indexedDB.deleteDatabase(name);
 
         deleteRequest.onerror = errorHandler;
         deleteRequest.onsuccess = function () {
           // It is imperative that we open a different database this time.
-          let request = mozIndexedDB.open("take2", 1);
+          let request = indexedDB.open("take2", 1);
           request.onerror = errorHandler;
           request.onupgradeneeded = function(event) {
             db = event.target.result;
             db.createObjectStore("foo", { autoIncrement: true });
           }
           request.onsuccess = function ()
             { setTimeout(testFinishedCallback, 0, "resetDone"); };
           request.onblocked = errorHandler;
@@ -62,17 +62,17 @@
       }
 
       function testSteps()
       {
         window.addEventListener("indexedDB-addMore", onAddMore, true);
         window.addEventListener("indexedDB-reset", onReset, true);
         window.addEventListener("indexedDB-done", onDone, true);
 
-        let request = mozIndexedDB.open(name, 1);
+        let request = indexedDB.open(name, 1);
         request.onerror = errorHandler;
         request.onupgradeneeded = grabEventAndContinueHandler;
         let event = yield;
 
         db = event.target.result;
 
         db.onversionchange = function () { db.close(); };
 
--- a/dom/indexedDB/test/error_events_abort_transactions_iframe.html
+++ b/dom/indexedDB/test/error_events_abort_transactions_iframe.html
@@ -39,23 +39,24 @@
       setTimeout(function() {
         setTimeout(function() {
           testGenerator.close();
           window.parent.postMessage("SimpleTest.finish();", "*");
         }, 0);
       }, 0);
     }
 
-    window.onerror = function(event) {
+    window.onerror = function(message, filename, lineno) {
+      is(message, "ConstraintError", "Expect a constraint error");
     };
 
     function testSteps() {
       window.parent.SpecialPowers.addPermission("indexedDB", true, document);
 
-      let request = mozIndexedDB.open(window.location.pathname, 1);
+      let request = indexedDB.open(window.location.pathname, 1);
       request.onsuccess = unexpectedSuccessHandler;
       request.onerror = grabEventAndContinueHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       let event = yield;
 
       let db = event.target.result;
 
       is(db.version, 1, "Correct version");
@@ -80,29 +81,29 @@
       request = objectStore.add({}, 1);
       request.onsuccess = unexpectedSuccessHandler;
       request.onerror = function(event) {
         // Don't do anything! We want this error.
       }
       event = yield;
 
       is(event.type, "abort", "Got a transaction abort event");
-      is(db.version, 1, "Correct version");
-      is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
+      is(db.version, 0, "Correct version");
+      is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
       is(trans.error.name, "ConstraintError", "Right error");
       ok(trans.error === request.error, "Object identity holds");
       is(originalRequest.transaction, trans, "request.transaction should still be set");
 
       event = yield;
       is(event.type, "error", "Got request error event");
       is(event.target, originalRequest, "error event has right target");
       is(event.target.error.name, "ConstraintError", "Right error");
       is(originalRequest.transaction, null, "request.transaction should now be null");
 
-      let request = mozIndexedDB.open(window.location.pathname, 1);
+      let request = indexedDB.open(window.location.pathname, 1);
       request.onerror = errorHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       let event = yield;
 
       let db = event.target.result;
 
       event.target.transaction.oncomplete = grabEventAndContinueHandler;
       event.target.transaction.onabort = unexpectedSuccessHandler;
@@ -110,34 +111,114 @@
       is(db.version, "1", "Correct version");
       is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
 
       let objectStore = db.createObjectStore("foo");
 
       is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
       ok(db.objectStoreNames.contains("foo"), "Has correct objectStore");
 
+      objectStore.createIndex("baz", "key.path");
+      objectStore.createIndex("dontDeleteMe", "");
+
+      is(objectStore.indexNames.length, 2, "Correct indexNames length");
+      ok(objectStore.indexNames.contains("baz"), "Has correct index");
+      ok(objectStore.indexNames.contains("dontDeleteMe"), "Has correct index");
+
+      let objectStoreForDeletion = db.createObjectStore("bar");
+
+      is(db.objectStoreNames.length, 2, "Correct objectStoreNames length");
+      ok(db.objectStoreNames.contains("bar"), "Has correct objectStore");
+
+      objectStoreForDeletion.createIndex("foo", "key.path");
+
+      is(objectStoreForDeletion.indexNames.length, 1, "Correct indexNames length");
+      ok(objectStoreForDeletion.indexNames.contains("foo"), "Has correct index");
+
       request = objectStore.add({}, 1);
       request.onsuccess = grabEventAndContinueHandler;
       request.onerror = errorHandler;
       event = yield;
 
       request = objectStore.add({}, 1);
       request.onsuccess = unexpectedSuccessHandler;
       request.onerror = function(event) {
         // Expected, but prevent the abort.
         event.preventDefault();
       }
       event = yield;
 
       is(event.type, "complete", "Got a transaction complete event");
 
       is(db.version, "1", "Correct version");
-      is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
+      is(db.objectStoreNames.length, 2, "Correct objectStoreNames length");
+      ok(db.objectStoreNames.contains("foo"), "Has correct objectStore");
+      ok(db.objectStoreNames.contains("bar"), "Has correct objectStore");
+
+      db.close();
+
+      let request = indexedDB.open(window.location.pathname, 2);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+
+      let trans = event.target.transaction;
+      trans.oncomplete = unexpectedSuccessHandler;
+
+      is(db.version, "2", "Correct version");
+      is(db.objectStoreNames.length, 2, "Correct objectStoreNames length");
       ok(db.objectStoreNames.contains("foo"), "Has correct objectStore");
+      ok(db.objectStoreNames.contains("bar"), "Has correct objectStore");
+
+      let createdObjectStore = db.createObjectStore("newlyCreated");
+      let objectStore = trans.objectStore("foo");
+      let deletedObjectStore = trans.objectStore("bar");
+      deletedObjectStore.deleteIndex("foo");
+      db.deleteObjectStore("bar");
+
+      createdObjectStore.createIndex("newIndex", "key.path");
+      objectStore.createIndex("newIndex", "key.path");
+      objectStore.deleteIndex("baz");
+
+      is(db.objectStoreNames.length, 2, "Correct objectStoreNames length");
+      ok(db.objectStoreNames.contains("newlyCreated"), "Has correct objectStore");
+      ok(db.objectStoreNames.contains("foo"), "Has correct objectStore");
+
+      is(createdObjectStore.indexNames.length, 1, "Correct indexNames length");
+      ok(createdObjectStore.indexNames.contains("newIndex"), "Has correct index");
+
+      is(objectStore.indexNames.length, 2, "Correct indexNames length");
+      ok(objectStore.indexNames.contains("dontDeleteMe"), "Has correct index");
+      ok(objectStore.indexNames.contains("newIndex"), "Has correct index");
+
+      objectStore.add({}, 1);
+      trans.onabort = grabEventAndContinueHandler;
+
+      event = yield;
+
+      // Test that the world has been restored.
+      is(db.version, "1", "Correct version");
+      is(db.objectStoreNames.length, 2, "Correct objectStoreNames length");
+      ok(db.objectStoreNames.contains("foo"), "Has correct objectStore");
+      ok(db.objectStoreNames.contains("bar"), "Has correct objectStore");
+
+      is(objectStore.indexNames.length, 2, "Correct indexNames length");
+      ok(objectStore.indexNames.contains("dontDeleteMe"), "Has correct index");
+      ok(objectStore.indexNames.contains("baz"), "Has correct index");
+
+      is(createdObjectStore.indexNames.length, 0, "Correct indexNames length");
+
+      is(deletedObjectStore.indexNames.length, 1, "Correct indexNames length");
+      ok(deletedObjectStore.indexNames.contains("foo"), "Has correct index");
+
+      request.onerror = grabEventAndContinueHandler;
+
+      event = yield;
 
       finishTest();
       yield;
     }
   </script>
 
 </head>
 
--- a/dom/indexedDB/test/event_propagation_iframe.html
+++ b/dom/indexedDB/test/event_propagation_iframe.html
@@ -84,17 +84,17 @@
           finishTest();
         }
       }
     }
 
     function testSteps() {
       window.parent.SpecialPowers.addPermission("indexedDB", true, document);
 
-      let request = mozIndexedDB.open(window.location.pathname, 1);
+      let request = indexedDB.open(window.location.pathname, 1);
       request.onerror = errorHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       let event = yield;
 
       let db = event.target.result;
       db.onerror = errorEventCounter;
       db.addEventListener("error", errorEventCounter, true);
 
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/exceptions_in_events_iframe.html
@@ -0,0 +1,182 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+  <title>Indexed Database Property Test</title>
+
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+  <script type="text/javascript;version=1.7">
+    let testGenerator = testSteps();
+
+    function ok(val, message) {
+      val = val ? "true" : "false";
+      window.parent.postMessage("SimpleTest.ok(" + val + ", '" + message +
+                                "');", "*");
+    }
+
+    function is(a, b, message) {
+      ok(a == b, message);
+    }
+
+    function grabEventAndContinueHandler(event) {
+      testGenerator.send(event);
+    }
+
+    function errorHandler(event) {
+      ok(false, "indexedDB error, code " + event.target.errorCode);
+      finishTest();
+    }
+
+    function unexpectedSuccessHandler(event) {
+      ok(false, "got success when it was not expected!");
+      finishTest();
+    }
+
+    function finishTest() {
+      // Let window.onerror have a chance to fire
+      setTimeout(function() {
+        setTimeout(function() {
+          testGenerator.close();
+          window.parent.postMessage("SimpleTest.finish();", "*");
+        }, 0);
+      }, 0);
+    }
+
+    window.onerror = function() {
+      return false;
+    };
+
+    function testSteps() {
+      window.parent.SpecialPowers.addPermission("indexedDB", true, document);
+
+      // Test 1: Throwing an exception in an upgradeneeded handler should
+      // abort the versionchange transaction and fire an error at the request.
+      let request = indexedDB.open(window.location.pathname, 1);
+      request.onerror = errorHandler;
+      request.onsuccess = unexpectedSuccessHandler;
+      request.onupgradeneeded = function () {
+        let transaction = request.transaction;
+        transaction.oncomplete = unexpectedSuccessHandler;
+        transaction.onabort = grabEventAndContinueHandler
+        throw "STOP";
+      };
+
+      let event = yield;
+      is(event.type, "abort",
+         "Throwing during an upgradeneeded event should abort the transaction.");
+      is(event.target.error.name, "AbortError", "Got AbortError object");
+
+      request.onerror = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.type, "error",
+         "Throwing during an upgradeneeded event should fire an error.");
+
+      // Test 2: Throwing during a request's success handler should abort the
+      // transaction.
+      let request = indexedDB.open(window.location.pathname, 1);
+      request.onerror = errorHandler;
+      request.onblocked = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      request.onsuccess = unexpectedSuccessHandler;
+      let openrequest = request;
+      let event = yield;
+
+      request.onupgradeneeded = unexpectedSuccessHandler;
+
+      let db = event.target.result;
+      db.onerror = function(event) {
+        event.preventDefault();
+      };
+
+      event.target.transaction.oncomplete = unexpectedSuccessHandler;
+      event.target.transaction.onabort = grabEventAndContinueHandler;
+
+      is(db.version, 1, "Correct version");
+      is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
+
+      let objectStore = db.createObjectStore("foo");
+
+      is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
+      ok(db.objectStoreNames.contains("foo"), "Has correct objectStore");
+
+      request = objectStore.add({}, 1);
+      request.onsuccess = function(event) {
+        throw "foo";
+      };
+
+      event = yield;
+
+      is(event.type, "abort", "Got transaction abort event");
+      is(event.target.error.name, "AbortError", "Got AbortError object");
+      openrequest.onerror = grabEventAndContinueHandler;
+
+      event = yield;
+
+      is(event.type, "error", "Got IDBOpenDBRequest error event");
+      is(event.target, openrequest, "Right event target");
+      is(event.target.error.name, "AbortError", "Right error name");
+
+      // Test 3: Throwing during a request's error handler should abort the
+      // transaction, even if preventDefault is called on the error event.
+      let request = indexedDB.open(window.location.pathname, 1);
+      request.onerror = errorHandler;
+      request.onblocked = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      request.onsuccess = unexpectedSuccessHandler;
+      let openrequest = request;
+      let event = yield;
+
+      request.onupgradeneeded = unexpectedSuccessHandler;
+
+      let db = event.target.result;
+      db.onerror = function(event) {
+        event.preventDefault();
+      };
+
+      event.target.transaction.oncomplete = unexpectedSuccessHandler;
+      event.target.transaction.onabort = grabEventAndContinueHandler;
+
+      is(db.version, 1, "Correct version");
+      is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
+
+      let objectStore = db.createObjectStore("foo");
+
+      is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
+      ok(db.objectStoreNames.contains("foo"), "Has correct objectStore");
+
+      request = objectStore.add({}, 1);
+      request.onerror = errorHandler;
+      request = objectStore.add({}, 1);
+      request.onsuccess = unexpectedSuccessHandler;
+      request.onerror = function (event) {
+        event.preventDefault();
+        throw "STOP";
+      };
+
+      event = yield;
+
+      is(event.type, "abort", "Got transaction abort event");
+      is(event.target.error.name, "AbortError", "Got AbortError object");
+      openrequest.onerror = grabEventAndContinueHandler;
+
+      event = yield;
+
+      is(event.type, "error", "Got IDBOpenDBRequest error event");
+      is(event.target, openrequest, "Right event target");
+      is(event.target.error.name, "AbortError", "Right error name");
+
+      finishTest();
+      yield;
+    }
+  </script>
+
+</head>
+
+<body onload="testGenerator.next();"></body>
+
+</html>
deleted file mode 100644
--- a/dom/indexedDB/test/exceptions_in_success_events_iframe.html
+++ /dev/null
@@ -1,116 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<html>
-<head>
-  <title>Indexed Database Property Test</title>
-
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-
-  <script type="text/javascript;version=1.7">
-    let testGenerator = testSteps();
-
-    function ok(val, message) {
-      val = val ? "true" : "false";
-      window.parent.postMessage("SimpleTest.ok(" + val + ", '" + message +
-                                "');", "*");
-    }
-
-    function is(a, b, message) {
-      ok(a == b, message);
-    }
-
-    function grabEventAndContinueHandler(event) {
-      testGenerator.send(event);
-    }
-
-    function errorHandler(event) {
-      ok(false, "indexedDB error, code " + event.target.errorCode);
-      finishTest();
-    }
-
-    function unexpectedSuccessHandler(event) {
-      ok(false, "got success when it was not expected!");
-      finishTest();
-    }
-
-    function finishTest() {
-      // Let window.onerror have a chance to fire
-      setTimeout(function() {
-        setTimeout(function() {
-          testGenerator.close();
-          window.parent.postMessage("SimpleTest.finish();", "*");
-        }, 0);
-      }, 0);
-    }
-
-    window.onerror = function() {
-      return false;
-    };
-
-    function testSteps() {
-      window.parent.SpecialPowers.addPermission("indexedDB", true, document);
-
-      let request = mozIndexedDB.open(window.location.pathname, 1);
-      request.onerror = grabEventAndContinueHandler;
-      request.onsuccess = errorHandler;
-      request.onupgradeneeded = function () {
-        throw "STOP";
-      };
-
-      let event = yield;
-
-      is(event.type, "error",
-         "Throwing during an upgradeneeded event should fire an error.");
-
-      let request = mozIndexedDB.open(window.location.pathname, 1);
-      request.onerror = grabEventAndContinueHandler;
-      request.onblocked = errorHandler;
-      request.onupgradeneeded = grabEventAndContinueHandler;
-      let openrequest = request;
-      let event = yield;
-
-      let db = event.target.result;
-      db.onerror = function(event) {
-        event.preventDefault();
-      };
-
-      event.target.transaction.oncomplete = unexpectedSuccessHandler;
-      event.target.transaction.onabort = grabEventAndContinueHandler;
-
-      is(db.version, 1, "Correct version");
-      is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
-
-      let objectStore = db.createObjectStore("foo");
-
-      is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
-      ok(db.objectStoreNames.contains("foo"), "Has correct objectStore");
-
-      request = objectStore.add({}, 1);
-      request.onsuccess = function(event) {
-        throw "foo";
-      };
-
-      event = yield;
-
-      is(event.type, "abort", "Got transaction abort event");
-      is(event.target.error, null, "Got null error object");
-
-      event = yield;
-
-      is(event.type, "error", "Got IDBOpenDBRequest error event");
-      is(event.target, openrequest, "Right event target");
-      is(event.target.error.name, "AbortError", "Right error name");
-
-      finishTest();
-      yield;
-    }
-  </script>
-
-</head>
-
-<body onload="testGenerator.next();"></body>
-
-</html>
--- a/dom/indexedDB/test/leaving_page_iframe.html
+++ b/dom/indexedDB/test/leaving_page_iframe.html
@@ -1,15 +1,15 @@
 <!DOCTYPE html>
 <html>
 <head>
   <script>
 var db;
 function startDBWork() {
-  mozIndexedDB.open(parent.location, 1).onupgradeneeded = function(e) {
+  indexedDB.open(parent.location, 1).onupgradeneeded = function(e) {
     db = e.target.result;
     var trans = e.target.transaction;
     if (db.objectStoreNames.contains("mystore")) {
       db.deleteObjectStore("mystore");
     }
     var store = db.createObjectStore("mystore");
     store.add({ hello: "world" }, 42);
     e.target.onsuccess = madeMod;
--- a/dom/indexedDB/test/test_autoIncrement.html
+++ b/dom/indexedDB/test/test_autoIncrement.html
@@ -31,17 +31,17 @@
 
     function testSteps()
     {
       const dbname = window.location.pathname;
       const RW = IDBTransaction.READ_WRITE
       let c1 = 1;
       let c2 = 1;
 
-      let openRequest = mozIndexedDB.open(dbname, 1);
+      let openRequest = indexedDB.open(dbname, 1);
       openRequest.onerror = errorHandler;
       openRequest.onupgradeneeded = grabEventAndContinueHandler;
       openRequest.onsuccess = unexpectedSuccessHandler;
       let event = yield;
       let db = event.target.result;
       let trans = event.target.transaction;
 
       // Create test stores
@@ -367,17 +367,17 @@
         grabEventAndContinueHandler;
       trans.objectStore("store2").clear().onsuccess =
         grabEventAndContinueHandler;
       yield; yield;
       db.close();
 
       SpecialPowers.gc();
 
-      openRequest = mozIndexedDB.open(dbname, 2);
+      openRequest = indexedDB.open(dbname, 2);
       openRequest.onerror = errorHandler;
       openRequest.onupgradeneeded = grabEventAndContinueHandler;
       openRequest.onsuccess = unexpectedSuccessHandler;
       event = yield;
       db = event.target.result;
       trans = event.target.transaction;
 
       trans.objectStore("store1").add({ reopen: 1 }).onsuccess =
--- a/dom/indexedDB/test/test_create_objectStore.html
+++ b/dom/indexedDB/test/test_create_objectStore.html
@@ -26,17 +26,17 @@
         { name: "9", options: { autoIncrement: false } },
         { name: "10", options: { keyPath: "foo", autoIncrement: false } },
         { name: "11", options: { keyPath: "foo", autoIncrement: true } },
         { name: "" },
         { name: null },
         { name: undefined }
       ];
 
-      let request = mozIndexedDB.open(name, 1, description);
+      let request = indexedDB.open(name, 1, description);
       request.onerror = errorHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       let event = yield;
 
       let db = event.target.result;
 
       let count = db.objectStoreNames.length;
       is(count, 0, "correct objectStoreNames length");
--- a/dom/indexedDB/test/test_deleteDatabase_interactions.html
+++ b/dom/indexedDB/test/test_deleteDatabase_interactions.html
@@ -10,17 +10,17 @@
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
   <script type="text/javascript;version=1.7">
 
   function testSteps()
   {
     const name = window.location.pathname;
 
-    let request = mozIndexedDB.open(name, 10);
+    let request = indexedDB.open(name, 10);
     request.onerror = errorHandler;
     request.onsuccess = unexpectedSuccessHandler;
     request.onupgradeneeded = grabEventAndContinueHandler;
 
     ok(request instanceof IDBOpenDBRequest, "Expect an IDBOpenDBRequest");
 
     let event = yield;
 
@@ -36,24 +36,24 @@
 
     is(event.type, "success", "Expect a success event");
     is(event.target, request, "Event has right target");
     ok(event.target.result instanceof IDBDatabase, "Result should be a database");
     is(db.objectStoreNames.length, 1, "Expect an objectStore here");
 
     db.close();
 
-    let request = mozIndexedDB.deleteDatabase(name);
+    let request = indexedDB.deleteDatabase(name);
 
     request.onerror = errorHandler;
     request.onsuccess = grabEventAndContinueHandler;
 
     ok(request instanceof IDBOpenDBRequest, "Expect an IDBOpenDBRequest");
 
-    let openRequest = mozIndexedDB.open(name, 1);
+    let openRequest = indexedDB.open(name, 1);
     openRequest.onerror = errorHandler;
     openRequest.onsuccess = unexpectedSuccessHandler;
 
     event = yield;
     is(event.type, "success", "expect a success event");
     is(event.target, request, "event has right target");
     is(event.target.result, null, "event should have no result");
 
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/test_exceptions_in_events.html
@@ -0,0 +1,30 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+  <title>Indexed Database Property Test</title>
+
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+  <script type="text/javascript;version=1.7">
+    function runTest() {
+      SimpleTest.waitForExplicitFinish();
+
+      function messageListener(event) {
+        eval(event.data);
+      }
+
+      window.addEventListener("message", messageListener, false);
+    }
+  </script>
+
+</head>
+
+<body onload="runTest();">
+  <iframe src="exceptions_in_events_iframe.html"></iframe>
+</body>
+
+</html>
deleted file mode 100644
--- a/dom/indexedDB/test/test_exceptions_in_success_events.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<html>
-<head>
-  <title>Indexed Database Property Test</title>
-
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-
-  <script type="text/javascript;version=1.7">
-    function runTest() {
-      SimpleTest.waitForExplicitFinish();
-
-      function messageListener(event) {
-        eval(event.data);
-      }
-
-      window.addEventListener("message", messageListener, false);
-    }
-  </script>
-
-</head>
-
-<body onload="runTest();">
-  <iframe src="exceptions_in_success_events_iframe.html"></iframe>
-</body>
-
-</html>
--- a/dom/indexedDB/test/test_file_array.html
+++ b/dom/indexedDB/test/test_file_array.html
@@ -30,17 +30,17 @@
       { key: 1, blobs: [ b1, b1, b1, b1, b1, b1, b1, b1, b1, b1 ],
         expectedFileIds: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] },
       { key: 2, blobs: [ b2[0], b2[1], b2[2], b2[3], b2[4], b2[5], b2[6] ],
         expectedFileIds: [2, 3, 4, 5, 6, 7, 8] },
       { key: 3, blobs: [ b3[0], b3[0], b3[1], b3[2], b3[2], b3[0], b3[0] ],
         expectedFileIds: [9, 9, 10, 11, 11, 9, 9] }
     ];
 
-    let request = mozIndexedDB.open(name, 1, description);
+    let request = indexedDB.open(name, 1, description);
     request.onerror = errorHandler;
     request.onupgradeneeded = grabEventAndContinueHandler;
     request.onsuccess = grabEventAndContinueHandler;
     let event = yield;
 
     is(event.type, "upgradeneeded", "Got correct event type");
 
     let db = event.target.result;
--- a/dom/indexedDB/test/test_file_cross_database_copying.html
+++ b/dom/indexedDB/test/test_file_cross_database_copying.html
@@ -20,17 +20,17 @@
     ];
 
     const objectStoreName = "Blobs";
 
     const fileData = { key: 1, file: getRandomFile("random.bin", 100000) };
 
     let databases = [];
     for each (let info in databaseInfo) {
-      let request = mozIndexedDB.open(info.name, 1, info.description);
+      let request = indexedDB.open(info.name, 1, info.description);
       request.onerror = errorHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       request.onsuccess = grabEventAndContinueHandler;
       let event = yield;
 
       is(event.type, "upgradeneeded", "Got correct event type");
 
       let db = event.target.result;
--- a/dom/indexedDB/test/test_file_delete.html
+++ b/dom/indexedDB/test/test_file_delete.html
@@ -19,17 +19,17 @@
 
     const objectStoreName = "Blobs";
 
     const fileData1 = { key: 1, file: getRandomFile("random1.bin", 110000) };
     const fileData2 = { key: 2, file: getRandomFile("random2.bin", 120000) };
     const fileData3 = { key: 3, file: getRandomFile("random3.bin", 130000) };
 
     {
-      let request = mozIndexedDB.open(name, 1, description);
+      let request = indexedDB.open(name, 1, description);
       request.onerror = errorHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       request.onsuccess = grabEventAndContinueHandler;
       let event = yield;
 
       is(event.type, "upgradeneeded", "Got correct event type");
 
       let db = event.target.result;
@@ -62,17 +62,17 @@
     scheduleGC();
     yield;
 
     ok(!hasFileInfo(name, 1), "Correct ref count");
     ok(hasFileInfo(name, 2), "Correct ref count");
     ok(hasFileInfo(name, 3), "Correct ref count");
 
     {
-      let request = mozIndexedDB.open(name, 1, description);
+      let request = indexedDB.open(name, 1, description);
       request.onerror = errorHandler;
       request.onsuccess = grabEventAndContinueHandler;
       let event = yield;
 
       is(event.type, "success", "Got correct event type");
 
       let db = event.target.result;
       db.onerror = errorHandler;
--- a/dom/indexedDB/test/test_file_os_delete.html
+++ b/dom/indexedDB/test/test_file_os_delete.html
@@ -20,17 +20,17 @@
     const objectStoreName = "Blobs";
 
     getUsage(grabFileUsageAndContinueHandler);
     let startUsage = yield;
 
     const fileData = { key: 1, file: getRandomFile("random.bin", 100000) };
 
     {
-      let request = mozIndexedDB.open(name, 1, description);
+      let request = indexedDB.open(name, 1, description);
       request.onerror = errorHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       request.onsuccess = grabEventAndContinueHandler;
       let event = yield;
 
       is(event.type, "upgradeneeded", "Got correct event type");
 
       let db = event.target.result;
--- a/dom/indexedDB/test/test_file_put_get_object.html
+++ b/dom/indexedDB/test/test_file_put_get_object.html
@@ -20,17 +20,17 @@
     const objectStoreName = "Blobs";
 
     const blob = getRandomBlob(1000);
     const file = getRandomFile("random.bin", 100000);
 
     const objectData1 = { key: 1, object: { foo: blob, bar: blob } };
     const objectData2 = { key: 2, object: { foo: file, bar: file } };
 
-    let request = mozIndexedDB.open(name, 1, description);
+    let request = indexedDB.open(name, 1, description);
     request.onerror = errorHandler;
     request.onupgradeneeded = grabEventAndContinueHandler;
     request.onsuccess = grabEventAndContinueHandler;
     let event = yield;
 
     is(event.type, "upgradeneeded", "Got correct event type");
 
     let db = event.target.result;
--- a/dom/indexedDB/test/test_file_put_get_values.html
+++ b/dom/indexedDB/test/test_file_put_get_values.html
@@ -17,17 +17,17 @@
     const name = window.location.pathname;
     const description = "My Test Database";
 
     const objectStoreName = "Blobs";
 
     const blobData = { key: 1, blob: getRandomBlob(10000) };
     const fileData = { key: 2, file: getRandomFile("random.bin", 100000) };
 
-    let request = mozIndexedDB.open(name, 1, description);
+    let request = indexedDB.open(name, 1, description);
     request.onerror = errorHandler;
     request.onupgradeneeded = grabEventAndContinueHandler;
     request.onsuccess = grabEventAndContinueHandler;
     let event = yield;
 
     is(event.type, "upgradeneeded", "Got correct event type");
 
     let db = event.target.result;
--- a/dom/indexedDB/test/test_file_quota.html
+++ b/dom/indexedDB/test/test_file_quota.html
@@ -18,17 +18,17 @@
     const name = window.location.pathname;
     const description = "My Test Database";
 
     const objectStoreName = "Blobs";
 
     const testData = { key: 0, value: {} };
     const fileData = { key: 1, file: null };
 
-    let request = mozIndexedDB.open(name, 1, description);
+    let request = indexedDB.open(name, 1, description);
     request.onerror = errorHandler;
     request.onupgradeneeded = grabEventAndContinueHandler;
     request.onsuccess = grabEventAndContinueHandler;
     let event = yield;
 
     is(event.type, "upgradeneeded", "Got correct event type");
 
     let db = event.target.result;
--- a/dom/indexedDB/test/test_file_replace.html
+++ b/dom/indexedDB/test/test_file_replace.html
@@ -18,17 +18,17 @@
     const objectStoreName = "Blobs";
 
     const blobData = { key: 42, blobs: [] };
 
     for (let i = 0; i < 100; i++) {
       blobData.blobs[i] = getRandomBlob(i);
     }
 
-    let request = mozIndexedDB.open(name, 1, description);
+    let request = indexedDB.open(name, 1, description);
     request.onerror = errorHandler;
     request.onupgradeneeded = grabEventAndContinueHandler;
     request.onsuccess = grabEventAndContinueHandler;
     let event = yield;
 
     is(event.type, "upgradeneeded", "Got correct event type");
 
     let db = event.target.result;
--- a/dom/indexedDB/test/test_file_resurrection_delete.html
+++ b/dom/indexedDB/test/test_file_resurrection_delete.html
@@ -17,17 +17,17 @@
     const name = window.location.pathname;
     const description = "My Test Database";
 
     const objectStoreName = "Blobs";
 
     const fileData = { key: 1, file: getRandomFile("random.bin", 100000) };
 
     {
-      let request = mozIndexedDB.open(name, 1, description);
+      let request = indexedDB.open(name, 1, description);
       request.onerror = errorHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       request.onsuccess = grabEventAndContinueHandler;
       let event = yield;
 
       is(event.type, "upgradeneeded", "Got correct event type");
 
       let db = event.target.result;
@@ -67,17 +67,17 @@
     }
 
     scheduleGC();
     yield;
 
     is(getFileRefCount(name, 1), 0, "Correct ref count");
 
     {
-      let request = mozIndexedDB.open(name, 1, description);
+      let request = indexedDB.open(name, 1, description);
       request.onerror = errorHandler;
       request.onsuccess = grabEventAndContinueHandler;
       let event = yield;
 
       is(event.type, "success", "Got correct event type");
 
       let db = event.target.result;
       db.onerror = errorHandler;
--- a/dom/indexedDB/test/test_file_resurrection_transaction_abort.html
+++ b/dom/indexedDB/test/test_file_resurrection_transaction_abort.html
@@ -17,17 +17,17 @@
     const name = window.location.pathname;
     const description = "My Test Database";
 
     const objectStoreName = "Blobs";
 
     const fileData = { key: 1, file: getRandomFile("random.bin", 100000) };
 
     {
-      let request = mozIndexedDB.open(name, 1, description);
+      let request = indexedDB.open(name, 1, description);
       request.onerror = errorHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       request.onsuccess = grabEventAndContinueHandler;
       let event = yield;
 
       is(event.type, "upgradeneeded", "Got correct event type");
 
       let db = event.target.result;
--- a/dom/indexedDB/test/test_file_sharing.html
+++ b/dom/indexedDB/test/test_file_sharing.html
@@ -19,17 +19,17 @@
 
     const objectStoreInfo = [
       { name: "Blobs", options: { } },
       { name: "Other Blobs", options: { } }
     ];
 
     const fileData = { key: 1, file: getRandomFile("random.bin", 100000) };
 
-    let request = mozIndexedDB.open(name, 1, description);
+    let request = indexedDB.open(name, 1, description);
     request.onerror = errorHandler;
     request.onupgradeneeded = grabEventAndContinueHandler;
     request.onsuccess = grabEventAndContinueHandler;
     let event = yield;
 
     is(event.type, "upgradeneeded", "Got correct event type");
 
     let db = event.target.result;
--- a/dom/indexedDB/test/test_file_transaction_abort.html
+++ b/dom/indexedDB/test/test_file_transaction_abort.html
@@ -17,17 +17,17 @@
     const name = window.location.pathname;
     const description = "My Test Database";
 
     const objectStoreName = "Blobs";
 
     const fileData = { key: 1, file: getRandomFile("random.bin", 100000) };
 
     {
-      let request = mozIndexedDB.open(name, 1, description);
+      let request = indexedDB.open(name, 1, description);
       request.onerror = errorHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       request.onsuccess = grabEventAndContinueHandler;
       let event = yield;
 
       is(event.type, "upgradeneeded", "Got correct event type");
 
       let db = event.target.result;
--- a/dom/indexedDB/test/test_filehandle_quota.html
+++ b/dom/indexedDB/test/test_filehandle_quota.html
@@ -13,17 +13,17 @@
   function testSteps()
   {
     const READ_WRITE = IDBTransaction.READ_WRITE;
     const DEFAULT_QUOTA_MB = 50;
 
     const name = window.location.pathname;
     const description = "My Test Database";
 
-    let request = mozIndexedDB.open(name, 1, description);
+    let request = indexedDB.open(name, 1, description);
     request.onerror = errorHandler;
     request.onupgradeneeded = grabEventAndContinueHandler;
     request.onsuccess = grabEventAndContinueHandler;
     let event = yield;
 
     is(event.type, "upgradeneeded", "Got correct event type");
 
     let db = event.target.result;
--- a/dom/indexedDB/test/test_filehandle_serialization.html
+++ b/dom/indexedDB/test/test_filehandle_serialization.html
@@ -20,17 +20,17 @@
     ];
 
     const objectStoreName = "Blobs";
 
     const testFile = getRandomFile("random.bin", 100000);
 
     let databases = [];
     for each (let info in databaseInfo) {
-      let request = mozIndexedDB.open(info.name, 1, info.description);
+      let request = indexedDB.open(info.name, 1, info.description);
       request.onerror = errorHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       request.onsuccess = grabEventAndContinueHandler;
       let event = yield;
 
       is(event.type, "upgradeneeded", "Got correct event type");
 
       let db = event.target.result;
--- a/dom/indexedDB/test/test_filehandle_store_snapshot.html
+++ b/dom/indexedDB/test/test_filehandle_store_snapshot.html
@@ -16,17 +16,17 @@
 
     const name = window.location.pathname;
     const description = "My Test Database";
 
     const objectStoreName = "Blobs";
 
     const testFile = getRandomFile("random.bin", 100000);
 
-    let request = mozIndexedDB.open(name, 1, description);
+    let request = indexedDB.open(name, 1, description);
     request.onerror = errorHandler;
     request.onupgradeneeded = grabEventAndContinueHandler;
     request.onsuccess = grabEventAndContinueHandler;
     let event = yield;
 
     is(event.type, "upgradeneeded", "Got correct event type");
 
     let db = event.target.result;
--- a/dom/indexedDB/test/test_leaving_page.html
+++ b/dom/indexedDB/test/test_leaving_page.html
@@ -33,17 +33,17 @@
       iframe.onload = continueToNextStep;
       yield;
       is(iframe.contentWindow.location.href, $("a").href,
          "should navigate to iframe page");
       yield;
       is(iframe.contentWindow.location.href, "about:blank",
          "should nagivate to about:blank");
          
-      let request = mozIndexedDB.open(location, 1);
+      let request = indexedDB.open(location, 1);
       request.onsuccess = grabEventAndContinueHandler;
       let event = yield;
 
       let db = event.target.result;
       db.transaction(["mystore"]).objectStore("mystore").get(42).onsuccess =
         grabEventAndContinueHandler;
       event = yield;
       is(event.target.result.hello, "world", "second modification rolled back");
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/test_names_sorted.html
@@ -0,0 +1,18 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+  <title>Indexed Database Property Test</title>
+
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+  <script type="text/javascript;version=1.7" src="unit/test_names_sorted.js"></script>
+  <script type="text/javascript;version=1.7" src="helpers.js"></script>
+</head>
+
+<body onload="runTest();"></body>
+
+</html>
--- a/dom/indexedDB/test/test_readonly_transactions.html
+++ b/dom/indexedDB/test/test_readonly_transactions.html
@@ -11,17 +11,17 @@
 
   <script type="text/javascript;version=1.7">
     function testSteps()
     {
       const name = window.location.pathname;
       const description = "My Test Database";
       const osName = "foo";
 
-      let request = mozIndexedDB.open(name, 1, description);
+      let request = indexedDB.open(name, 1, description);
       request.onerror = errorHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       request.onsuccess = grabEventAndContinueHandler;
       let event = yield;
 
       let db = event.target.result;
       is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
 
--- a/dom/indexedDB/test/test_unique_index_update.html
+++ b/dom/indexedDB/test/test_unique_index_update.html
@@ -7,17 +7,17 @@
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
   <script type="text/javascript;version=1.7">
     function testSteps()
     {
-      let request = mozIndexedDB.open(window.location.pathname, 1);
+      let request = indexedDB.open(window.location.pathname, 1);
       request.onerror = errorHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       request.onsuccess = grabEventAndContinueHandler;
 
       let event = yield;
 
       let db = event.target.result;
 
--- a/dom/indexedDB/test/test_writer_starvation.html
+++ b/dom/indexedDB/test/test_writer_starvation.html
@@ -12,17 +12,17 @@
   <script type="text/javascript;version=1.7">
     function testSteps()
     {
       const name = window.location.pathname;
 
       // Needs to be enough to saturate the thread pool.
       const SYNC_REQUEST_COUNT = 25;
 
-      let request = mozIndexedDB.open(name, 1);
+      let request = indexedDB.open(name, 1);
       request.onerror = errorHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       request.onsuccess = grabEventAndContinueHandler;
       let event = yield;
 
       let db = event.target.result;
       db.onerror = errorHandler;
 
--- a/dom/indexedDB/test/third_party_iframe2.html
+++ b/dom/indexedDB/test/third_party_iframe2.html
@@ -10,17 +10,17 @@
     function report(result) {
       let message = { source: "iframe" };
       message.result = result;
       window.parent.postMessage(message.toSource(), "*");
     }
 
     function runIndexedDBTest() {
       try {
-        let request = mozIndexedDB.open(window.location.pathname, 1);
+        let request = indexedDB.open(window.location.pathname, 1);
         request.onsuccess = function(event) {
           report(!!(event.target.result instanceof IDBDatabase));
         }
       }
       catch (e) {
         report(false);
       }
     }
--- a/dom/indexedDB/test/unit/Makefile.in
+++ b/dom/indexedDB/test/unit/Makefile.in
@@ -34,16 +34,17 @@ TEST_FILES = \
   test_index_getAllObjects.js \
   test_index_object_cursors.js \
   test_index_update_delete.js \
   test_indexes.js \
   test_indexes_bad_values.js \
   test_key_requirements.js \
   test_keys.js \
   test_multientry.js \
+  test_names_sorted.js \
   test_object_identity.js \
   test_objectCursors.js \
   test_objectStore_inline_autoincrement_key_added_on_put.js \
   test_objectStore_remove_values.js \
   test_odd_result_order.js \
   test_open_empty_db.js \
   test_open_objectStore.js \
   test_optionalArguments.js \
--- a/dom/indexedDB/test/unit/test_add_put.js
+++ b/dom/indexedDB/test/unit/test_add_put.js
@@ -3,17 +3,17 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
-  let openRequest = mozIndexedDB.open(name, 1);
+  let openRequest = indexedDB.open(name, 1);
   openRequest.onerror = errorHandler;
   openRequest.onupgradeneeded = grabEventAndContinueHandler;
   openRequest.onsuccess = unexpectedSuccessHandler;
   let event = yield;
   let db = event.target.result;
   let trans = event.target.transaction;
 
   for each (let autoincrement in [true, false]) {
--- a/dom/indexedDB/test/unit/test_add_twice_failure.js
+++ b/dom/indexedDB/test/unit/test_add_twice_failure.js
@@ -5,17 +5,17 @@
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = request.result;
 
   ok(event.target === request, "Good event target");
 
--- a/dom/indexedDB/test/unit/test_advance.js
+++ b/dom/indexedDB/test/unit/test_advance.js
@@ -4,17 +4,17 @@
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
   const dataCount = 30;
 
-  let request = mozIndexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
+  let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
   db.onerror = errorHandler;
 
   event.target.onsuccess = continueToNextStep;
--- a/dom/indexedDB/test/unit/test_autoIncrement_indexes.js
+++ b/dom/indexedDB/test/unit/test_autoIncrement_indexes.js
@@ -2,17 +2,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
-  let request = mozIndexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
+  let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = request.result;
   db.onerror = errorHandler;
 
   let objectStore = db.createObjectStore("foo", { keyPath: "id",
--- a/dom/indexedDB/test/unit/test_clear.js
+++ b/dom/indexedDB/test/unit/test_clear.js
@@ -6,17 +6,17 @@
 var testGenerator = testSteps();
 
 function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
   const entryCount = 1000;
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = request.result;
 
   event.target.onsuccess = continueToNextStep;
 
--- a/dom/indexedDB/test/unit/test_complex_keyPaths.js
+++ b/dom/indexedDB/test/unit/test_complex_keyPaths.js
@@ -34,16 +34,17 @@ function testSteps()
     { keyPath: "",        value: /x/ },
     { keyPath: "foo.bar", value: { baz: 1, foo: { baz2: 2, bar: "xo" } },     key: "xo" },
     { keyPath: "foo.bar.baz", value: { foo: { bar: { bazz: 16, baz: 17 } } }, key: 17 },
     { keyPath: "foo..id", exception: true },
     { keyPath: "foo.",    exception: true },
     { keyPath: "fo o",    exception: true },
     { keyPath: "foo ",    exception: true },
     { keyPath: "foo[bar]",exception: true },
+    { keyPath: "foo[1]",  exception: true },
     { keyPath: "$('id').stuff", exception: true },
     { keyPath: "foo.2.bar", exception: true },
     { keyPath: "foo. .bar", exception: true },
     { keyPath: ".bar",    exception: true },
 
     { keyPath: ["foo", "bar"],        value: { foo: 1, bar: 2 },              key: [1, 2] },
     { keyPath: ["foo"],               value: { foo: 1, bar: 2 },              key: [1] },
     { keyPath: ["foo", "bar", "bar"], value: { foo: 1, bar: "x" },            key: [1, "x", "x"] },
@@ -60,17 +61,17 @@ function testSteps()
     { keyPath: ["x", "y"],            value: { x: null, y: 1 } },
     { keyPath: ["x", "y.bar"],        value: { x: null, y: { bar: "x"} } },
     { keyPath: ["x", "y"],            value: { x: 1, y: false } },
     { keyPath: ["x", "y", "z"],       value: { x: 1, y: false, z: "a" } },
     { keyPath: [".x", "y", "z"],      exception: true },
     { keyPath: ["x", "y ", "z"],      exception: true },
   ];
 
-  let openRequest = mozIndexedDB.open(name, 1);
+  let openRequest = indexedDB.open(name, 1);
   openRequest.onerror = errorHandler;
   openRequest.onupgradeneeded = grabEventAndContinueHandler;
   openRequest.onsuccess = unexpectedSuccessHandler;
   let event = yield;
   let db = event.target.result;
 
   let stores = {};
 
@@ -113,22 +114,55 @@ function testSteps()
 
     request.onerror = errorHandler;
     request.onsuccess = grabEventAndContinueHandler;
 
     let e = yield;
     is(e.type, "success", "inserted successfully" + test);
     is(e.target, request, "expected target" + test);
     ok(compareKeys(request.result, info.key), "found correct key" + test);
-    is(mozIndexedDB.cmp(request.result, info.key), 0, "returned key compares correctly" + test);
+    is(indexedDB.cmp(request.result, info.key), 0, "returned key compares correctly" + test);
 
     store.get(info.key).onsuccess = grabEventAndContinueHandler;
     e = yield;
     isnot(e.target.result, undefined, "Did find entry");
 
+    // Check that cursor.update work as expected
+    request = store.openCursor();
+    request.onerror = errorHandler;
+    request.onsuccess = grabEventAndContinueHandler;
+    e = yield;
+    let cursor = e.target.result;
+    request = cursor.update(info.value);
+    request.onerror = errorHandler;
+    request.onsuccess = grabEventAndContinueHandler;
+    yield;
+    ok(true, "Successfully updated cursor" + test);
+
+    // Check that cursor.update throws as expected when key is changed
+    let newValue = cursor.value;
+    let destProp = Array.isArray(info.keyPath) ? info.keyPath[0] : info.keyPath;
+    if (destProp) {
+      eval("newValue." + destProp + " = 'newKeyValue'");
+    }
+    else {
+      newValue = 'newKeyValue';
+    }
+    let didThrow;
+    try {
+      cursor.update(newValue);
+    }
+    catch (ex) {
+      didThrow = ex;
+    }
+    ok(didThrow instanceof DOMException, "Got a DOMException" + test);
+    is(didThrow.name, "DataError", "expect a DataError" + test);
+    is(didThrow.code, 0, "expect zero" + test);
+
+    // Clear object store to prepare for next test
     store.clear().onsuccess = grabEventAndContinueHandler;
     yield;
   }
 
   // Attempt to create indexes and insert data
   let store = db.createObjectStore("indexStore");
   let indexes = {};
   for (let i = 0; i < keyPaths.length; i++) {
--- a/dom/indexedDB/test/unit/test_count.js
+++ b/dom/indexedDB/test/unit/test_count.js
@@ -24,17 +24,17 @@ function testSteps()
   const indexData = {
     name: "weight",
     keyPath: "weight",
     options: { unique: false }
   };
 
   const weightSort = [1, 0, 3, 7, 4, 2];
 
-  let request = mozIndexedDB.open(name, 1);
+  let request = indexedDB.open(name, 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   request.onsuccess = grabEventAndContinueHandler;
   let event = yield;
 
   is(event.type, "upgradeneeded", "Got correct event type");
 
   let db = event.target.result;
--- a/dom/indexedDB/test/unit/test_create_index.js
+++ b/dom/indexedDB/test/unit/test_create_index.js
@@ -16,17 +16,17 @@ function testSteps()
     { name: "1", keyPath: "unique_value", options: { unique: true } },
     { name: "2", keyPath: "value", options: { unique: false } },
     { name: "3", keyPath: "value", options: { unique: false } },
     { name: "", keyPath: "value", options: { unique: false } },
     { name: null, keyPath: "value", options: { unique: false } },
     { name: undefined, keyPath: "value", options: { unique: false } },
   ];
 
-  let request = mozIndexedDB.open(name, 1);
+  let request = indexedDB.open(name, 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   request.onsuccess = unexpectedSuccessHandler;
   let event = yield;
   let db = event.target.result;
 
   for (let i = 0; i < objectStoreInfo.length; i++) {
     let info = objectStoreInfo[i];
@@ -105,17 +105,17 @@ function testSteps()
 
       ok(event.target.transaction, "event has a transaction");
       ok(event.target.transaction.db === db,
          "transaction has the right db");
       is(event.target.transaction.mode, "versionchange",
          "transaction has the correct mode");
       is(event.target.transaction.objectStoreNames.length, i + 1,
          "transaction only has one object store");
-      is(event.target.transaction.objectStoreNames.item(0), objectStoreName,
+      ok(event.target.transaction.objectStoreNames.contains(objectStoreName),
          "transaction has the correct object store");
     }
   }
 
   request.onsuccess = grabEventAndContinueHandler;
   request.onupgradeneeded = unexpectedSuccessHandler;
 
   event = yield;
--- a/dom/indexedDB/test/unit/test_create_index_with_integer_keys.js
+++ b/dom/indexedDB/test/unit/test_create_index_with_integer_keys.js
@@ -5,33 +5,33 @@
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
   const data = { id: new Date().getTime(),
                  num: parseInt(Math.random() * 1000) };
 
-  let request = mozIndexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
+  let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
   db.onerror = errorHandler;
 
   event.target.onsuccess = continueToNextStep;
 
   // Make object store, add data.
   let objectStore = db.createObjectStore("foo", { keyPath: "id" });
   objectStore.add(data);
   yield;
   db.close();
 
-  let request = mozIndexedDB.open(this.window ? window.location.pathname : "Splendid Test", 2);
+  let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 2);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db2 = event.target.result;
   db2.onerror = errorHandler;
 
   event.target.onsuccess = continueToNextStep;
--- a/dom/indexedDB/test/unit/test_create_objectStore.js
+++ b/dom/indexedDB/test/unit/test_create_objectStore.js
@@ -20,17 +20,17 @@ function testSteps()
     { name: "9", options: { autoIncrement: false } },
     { name: "10", options: { keyPath: "foo", autoIncrement: false } },
     { name: "11", options: { keyPath: "foo", autoIncrement: true } },
     { name: "" },
     { name: null },
     { name: undefined }
   ];
 
-  let request = mozIndexedDB.open(name, 1);
+  let request = indexedDB.open(name, 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   request.onsuccess = unexpectedSuccessHandler;
   let event = yield;
 
   let db = event.target.result;
 
   let count = db.objectStoreNames.length;
--- a/dom/indexedDB/test/unit/test_cursor_mutation.js
+++ b/dom/indexedDB/test/unit/test_cursor_mutation.js
@@ -19,17 +19,17 @@ function testSteps()
 
     // This one will be added.
     { ss: "237-23-7737", name: "Pat" }
   ];
 
   // Post-add and post-remove data ordered by name.
   const objectStoreDataNameSort = [ 1, 4, 5, 2, 3 ];
 
-  let request = mozIndexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
+  let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
   event.target.onsuccess = continueToNextStep;
 
   let objectStore = db.createObjectStore("foo", { keyPath: "ss" });
--- a/dom/indexedDB/test/unit/test_cursor_update_updates_indexes.js
+++ b/dom/indexedDB/test/unit/test_cursor_update_updates_indexes.js
@@ -22,17 +22,17 @@ function testSteps()
       entry: { data: START_DATA } },
   ];
 
   for (let i = 0; i < objectStoreInfo.length; i++) {
     // Create our object stores.
     let info = objectStoreInfo[i];
 
     ok(true, "1");
-    request = mozIndexedDB.open(name, i + 1, description);
+    request = indexedDB.open(name, i + 1, description);
     request.onerror = errorHandler;
     request.onupgradeneeded = grabEventAndContinueHandler;
     event = yield;
 
     let db = event.target.result;
 
     ok(true, "2");
     let objectStore = info.hasOwnProperty("options") ?
--- a/dom/indexedDB/test/unit/test_cursors.js
+++ b/dom/indexedDB/test/unit/test_cursors.js
@@ -9,17 +9,17 @@ function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
   const keys = [1, -1, 0, 10, 2000, "q", "z", "two", "b", "a"];
   const sortedKeys = [-1, 0, 1, 10, 2000, "a", "b", "q", "two", "z"];
 
   is(keys.length, sortedKeys.length, "Good key setup");
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
 
   let objectStore = db.createObjectStore("autoIncrement",
                                          { autoIncrement: true });
--- a/dom/indexedDB/test/unit/test_deleteDatabase.js
+++ b/dom/indexedDB/test/unit/test_deleteDatabase.js
@@ -4,19 +4,19 @@
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
 
-  ok(mozIndexedDB.deleteDatabase, "deleteDatabase function should exist!");
+  ok(indexedDB.deleteDatabase, "deleteDatabase function should exist!");
 
-  let request = mozIndexedDB.open(name, 10);
+  let request = indexedDB.open(name, 10);
   request.onerror = errorHandler;
   request.onsuccess = unexpectedSuccessHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
 
   ok(request instanceof IDBOpenDBRequest, "Expect an IDBOpenDBRequest");
 
   let event = yield;
 
@@ -30,17 +30,17 @@ function testSteps()
 
   event = yield;
 
   is(event.type, "success", "Expect a success event");
   is(event.target, request, "Event has right target");
   ok(event.target.result instanceof IDBDatabase, "Result should be a database");
   is(db.objectStoreNames.length, 1, "Expect an objectStore here");
 
-  let request = mozIndexedDB.open(name, 10);
+  let request = indexedDB.open(name, 10);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
 
   event = yield;
   is(event.type, "success", "Expect a success event");
   is(event.target, request, "Event has right target");
   ok(event.target.result instanceof IDBDatabase, "Result should be a database");
   let db2 = event.target.result;
@@ -61,45 +61,45 @@ function testSteps()
     db2.onversionchange = unexpectedSuccessHandler;
   };
 
   // The IDB spec doesn't guarantee the order that onversionchange will fire
   // on the dbs.
   db.onversionchange = closeDBs;
   db2.onversionchange = closeDBs;
 
-  let request = mozIndexedDB.deleteDatabase(name);
+  let request = indexedDB.deleteDatabase(name);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
 
   ok(request instanceof IDBOpenDBRequest, "Expect an IDBOpenDBRequest");
 
   event = yield;
   ok(onversionchangecalled, "Expected versionchange events");
   is(event.type, "success", "expect a success event");
   is(event.target, request, "event has right target");
   ok(event.target.result === undefined, "event should have no result");
 
-  let request = mozIndexedDB.open(name, 1);
+  let request = indexedDB.open(name, 1);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
 
   event = yield;
   is(event.target.result.version, 1, "DB has proper version");
   is(event.target.result.objectStoreNames.length, 0, "DB should have no object stores");
 
 
-  let request = mozIndexedDB.deleteDatabase("thisDatabaseHadBetterNotExist");
+  let request = indexedDB.deleteDatabase("thisDatabaseHadBetterNotExist");
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
 
   event = yield;
   ok(true, "deleteDatabase on a non-existent database succeeded");
 
-  let request = mozIndexedDB.open("thisDatabaseHadBetterNotExist");
+  let request = indexedDB.open("thisDatabaseHadBetterNotExist");
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
 
   event = yield;
   ok(true, "after deleting a non-existent database, open should work");
 
   finishTest();
   yield;
--- a/dom/indexedDB/test/unit/test_event_source.js
+++ b/dom/indexedDB/test/unit/test_event_source.js
@@ -6,17 +6,17 @@
 var testGenerator = testSteps();
 
 function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
   const objectStoreName = "Objects";
 
-  var request = mozIndexedDB.open(name, 1, description);
+  var request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   var event = yield;
 
   is(event.target.source, null, "correct event.target.source");
 
   var db = event.target.result;
   var objectStore = db.createObjectStore(objectStoreName,
--- a/dom/indexedDB/test/unit/test_getAll.js
+++ b/dom/indexedDB/test/unit/test_getAll.js
@@ -7,27 +7,27 @@ var testGenerator = testSteps();
 
 function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
 
   const values = [ "a", "1", 1, "foo", 300, true, false, 4.5, null ];
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
 
   let objectStore = db.createObjectStore("foo", { autoIncrement: true });
 
   request.onsuccess = grabEventAndContinueHandler;
-  request = objectStore.getAll();
+  request = objectStore.mozGetAll();
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 0, "No elements");
 
   let addedCount = 0;
@@ -39,93 +39,93 @@ function testSteps()
       if (++addedCount == values.length) {
         executeSoon(function() { testGenerator.next(); });
       }
     }
   }
   yield;
   yield;
 
-  request = db.transaction("foo").objectStore("foo").getAll();
+  request = db.transaction("foo").objectStore("foo").mozGetAll();
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, values.length, "Same length");
 
   for (let i in event.target.result) {
     is(event.target.result[i], values[i], "Same value");
   }
 
-  request = db.transaction("foo").objectStore("foo").getAll(null, 5);
+  request = db.transaction("foo").objectStore("foo").mozGetAll(null, 5);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 5, "Correct length");
 
   for (let i in event.target.result) {
     is(event.target.result[i], values[i], "Same value");
   }
 
   let keyRange = IDBKeyRange.bound(1, 9);
 
-  request = db.transaction("foo").objectStore("foo").getAll(keyRange);
+  request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, values.length, "Correct length");
 
   for (let i in event.target.result) {
     is(event.target.result[i], values[i], "Same value");
   }
 
-  request = db.transaction("foo").objectStore("foo").getAll(keyRange, 0);
+  request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange, 0);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, values.length, "Correct length");
 
   for (let i in event.target.result) {
     is(event.target.result[i], values[i], "Same value");
   }
 
-  request = db.transaction("foo").objectStore("foo").getAll(keyRange, null);
+  request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange, null);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, values.length, "Correct length");
 
   for (let i in event.target.result) {
     is(event.target.result[i], values[i], "Same value");
   }
 
-  request = db.transaction("foo").objectStore("foo").getAll(keyRange, undefined);
+  request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange, undefined);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, values.length, "Correct length");
 
   for (let i in event.target.result) {
     is(event.target.result[i], values[i], "Same value");
   }
 
   keyRange = IDBKeyRange.bound(4, 7);
 
-  request = db.transaction("foo").objectStore("foo").getAll(keyRange);
+  request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 4, "Correct length");
 
   for (let i in event.target.result) {
@@ -136,55 +136,55 @@ function testSteps()
   request = db.transaction("foo").objectStore("foo").get(keyRange);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, false, "Not an array object");
   is(event.target.result, values[3], "Correct value");
 
-  request = db.transaction("foo").objectStore("foo").getAll(keyRange, 2);
+  request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange, 2);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 2, "Correct length");
 
   for (let i in event.target.result) {
     is(event.target.result[i], values[parseInt(i) + 3], "Same value");
   }
 
   keyRange = IDBKeyRange.bound(4, 7);
 
-  request = db.transaction("foo").objectStore("foo").getAll(keyRange, 50);
+  request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange, 50);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 4, "Correct length");
 
   for (let i in event.target.result) {
     is(event.target.result[i], values[parseInt(i) + 3], "Same value");
   }
 
   keyRange = IDBKeyRange.bound(4, 7);
 
-  request = db.transaction("foo").objectStore("foo").getAll(keyRange, 0);
+  request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange, 0);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 4, "Correct length");
 
   keyRange = IDBKeyRange.bound(4, 7, true, true);
 
-  request = db.transaction("foo").objectStore("foo").getAll(keyRange);
+  request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 2, "Correct length");
 
   for (let i in event.target.result) {
--- a/dom/indexedDB/test/unit/test_global_data.js
+++ b/dom/indexedDB/test/unit/test_global_data.js
@@ -7,31 +7,31 @@ var testGenerator = testSteps();
 
 function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
   const objectStore =  { name: "Objects",
                          options: { keyPath: "id", autoIncrement: true } };
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db1 = event.target.result;
 
   is(db1.objectStoreNames.length, 0, "No objectStores in db1");
 
   db1.createObjectStore(objectStore.name, objectStore.options);
 
   continueToNextStep();
   yield;
 
-  request = mozIndexedDB.open(name, 1, description);
+  request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   let db2 = event.target.result;
 
   ok(db1 !== db2, "Databases are not the same object");
 
--- a/dom/indexedDB/test/unit/test_index_empty_keyPath.js
+++ b/dom/indexedDB/test/unit/test_index_empty_keyPath.js
@@ -10,17 +10,17 @@ function testSteps()
   const name = this.window ? window.location.pathname : "Splendid Test";
 
   const objectStoreData = [
     { key: "1", value: "foo" },
     { key: "2", value: "bar" },
     { key: "3", value: "baz" }
   ];
 
-  let request = mozIndexedDB.open(name, 1);
+  let request = indexedDB.open(name, 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   request.onsuccess = grabEventAndContinueHandler;
   let event = yield; // upgradeneeded
 
   let db = event.target.result;
 
   let objectStore = db.createObjectStore("data", { keyPath: null });
--- a/dom/indexedDB/test/unit/test_index_getAll.js
+++ b/dom/indexedDB/test/unit/test_index_getAll.js
@@ -47,17 +47,17 @@ function testSteps()
     { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
     { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
     { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
     { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
     { key: "237-23-7737", value: { name: "Pat", height: 65 } },
     { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
   ];
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   request.onsuccess = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
 
   let objectStore = db.createObjectStore(objectStoreName);
@@ -85,100 +85,100 @@ function testSteps()
 
   is(objectStore.indexNames.length, indexData.length, "Good index count");
   yield;
 
   ok(true, "2");
   objectStore = db.transaction(objectStoreName)
                   .objectStore(objectStoreName);
 
-  request = objectStore.index("height").getAllKeys(65);
+  request = objectStore.index("height").mozGetAllKeys(65);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
   ok(true, "3");
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 2, "Correct length");
 
   for (let i in event.target.result) {
     is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
        "Correct key");
   }
 
-  request = objectStore.index("height").getAllKeys(65, 0);
+  request = objectStore.index("height").mozGetAllKeys(65, 0);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
   ok(true, "3");
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 2, "Correct length");
 
   for (let i in event.target.result) {
     is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
        "Correct key");
   }
 
-  request = objectStore.index("height").getAllKeys(65, null);
+  request = objectStore.index("height").mozGetAllKeys(65, null);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
   ok(true, "3");
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 2, "Correct length");
 
   for (let i in event.target.result) {
     is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
        "Correct key");
   }
 
-  request = objectStore.index("height").getAllKeys(65, undefined);
+  request = objectStore.index("height").mozGetAllKeys(65, undefined);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
   ok(true, "3");
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 2, "Correct length");
 
   for (let i in event.target.result) {
     is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
        "Correct key");
   }
 
-  request = objectStore.index("height").getAllKeys();
+  request = objectStore.index("height").mozGetAllKeys();
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
   ok(true, "4");
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, objectStoreDataHeightSort.length,
      "Correct length");
 
   for (let i in event.target.result) {
     is(event.target.result[i], objectStoreDataHeightSort[i].key, "Correct key");
   }
 
-  request = objectStore.index("height").getAllKeys(null, 4);
+  request = objectStore.index("height").mozGetAllKeys(null, 4);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   ok(true, "5");
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 4, "Correct length");
 
   for (let i in event.target.result) {
     is(event.target.result[i], objectStoreDataHeightSort[i].key, "Correct key");
   }
 
-  request = objectStore.index("height").getAllKeys(65, 1);
+  request = objectStore.index("height").mozGetAllKeys(65, 1);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   ok(true, "6");
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 1, "Correct length");
 
--- a/dom/indexedDB/test/unit/test_index_getAllObjects.js
+++ b/dom/indexedDB/test/unit/test_index_getAllObjects.js
@@ -47,17 +47,17 @@ function testSteps()
     { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
     { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
     { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
     { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
     { key: "237-23-7737", value: { name: "Pat", height: 65 } },
     { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
   ];
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   request.onsuccess = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
 
   let objectStore = db.createObjectStore(objectStoreName, {});
@@ -83,17 +83,17 @@ function testSteps()
   }
 
   is(objectStore.indexNames.length, indexData.length, "Good index count");
   yield;
 
   objectStore = db.transaction(objectStoreName)
                   .objectStore(objectStoreName);
 
-  request = objectStore.index("height").getAll(65);
+  request = objectStore.index("height").mozGetAll(65);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 2, "Correct length");
 
   for (let i in event.target.result) {
@@ -103,17 +103,17 @@ function testSteps()
     is(result.name, testObj.name, "Correct name");
     is(result.height, testObj.height, "Correct height");
 
     if (testObj.hasOwnProperty("weight")) {
       is(result.weight, testObj.weight, "Correct weight");
     }
   }
 
-  request = objectStore.index("height").getAll(65, 0);
+  request = objectStore.index("height").mozGetAll(65, 0);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 2, "Correct length");
 
   for (let i in event.target.result) {
@@ -123,17 +123,17 @@ function testSteps()
     is(result.name, testObj.name, "Correct name");
     is(result.height, testObj.height, "Correct height");
 
     if (testObj.hasOwnProperty("weight")) {
       is(result.weight, testObj.weight, "Correct weight");
     }
   }
 
-  request = objectStore.index("height").getAll(65, null);
+  request = objectStore.index("height").mozGetAll(65, null);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 2, "Correct length");
 
   for (let i in event.target.result) {
@@ -143,17 +143,17 @@ function testSteps()
     is(result.name, testObj.name, "Correct name");
     is(result.height, testObj.height, "Correct height");
 
     if (testObj.hasOwnProperty("weight")) {
       is(result.weight, testObj.weight, "Correct weight");
     }
   }
 
-  request = objectStore.index("height").getAll(65, undefined);
+  request = objectStore.index("height").mozGetAll(65, undefined);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 2, "Correct length");
 
   for (let i in event.target.result) {
@@ -163,17 +163,17 @@ function testSteps()
     is(result.name, testObj.name, "Correct name");
     is(result.height, testObj.height, "Correct height");
 
     if (testObj.hasOwnProperty("weight")) {
       is(result.weight, testObj.weight, "Correct weight");
     }
   }
 
-  request = objectStore.index("height").getAll();
+  request = objectStore.index("height").mozGetAll();
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, objectStoreDataHeightSort.length,
      "Correct length");
 
@@ -184,17 +184,17 @@ function testSteps()
     is(result.name, testObj.name, "Correct name");
     is(result.height, testObj.height, "Correct height");
 
     if (testObj.hasOwnProperty("weight")) {
       is(result.weight, testObj.weight, "Correct weight");
     }
   }
 
-  request = objectStore.index("height").getAll(null, 4);
+  request = objectStore.index("height").mozGetAll(null, 4);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 4, "Correct length");
 
   for (let i in event.target.result) {
@@ -204,17 +204,17 @@ function testSteps()
     is(result.name, testObj.name, "Correct name");
     is(result.height, testObj.height, "Correct height");
 
     if (testObj.hasOwnProperty("weight")) {
       is(result.weight, testObj.weight, "Correct weight");
     }
   }
 
-  request = objectStore.index("height").getAll(65, 1);
+  request = objectStore.index("height").mozGetAll(65, 1);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array object");
   is(event.target.result.length, 1, "Correct length");
 
   for (let i in event.target.result) {
--- a/dom/indexedDB/test/unit/test_index_object_cursors.js
+++ b/dom/indexedDB/test/unit/test_index_object_cursors.js
@@ -19,17 +19,17 @@ function testSteps()
     { name: null, keyPath: "height", options: { } }
   ];
 
   const data = [
     { ss: "237-23-7732", name: "Ann", height: 60 },
     { ss: "237-23-7733", name: "Bob", height: 65 }
   ];
 
-  let request = mozIndexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
+  let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
   db.onerror = errorHandler;
 
   event.target.onsuccess = continueToNextStep;
--- a/dom/indexedDB/test/unit/test_index_update_delete.js
+++ b/dom/indexedDB/test/unit/test_index_update_delete.js
@@ -3,17 +3,17 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
   let name = this.window ? window.location.pathname : "Splendid Test";
-  let request = mozIndexedDB.open(name, 1);
+  let request = indexedDB.open(name, 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   request.onsuccess = grabEventAndContinueHandler;
 
   let event = yield;
 
   let db = event.target.result;
   db.onerror = errorHandler;
--- a/dom/indexedDB/test/unit/test_indexes.js
+++ b/dom/indexedDB/test/unit/test_indexes.js
@@ -48,17 +48,17 @@ function testSteps()
     { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
     { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
     { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
     { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
     { key: "237-23-7737", value: { name: "Pat", height: 65 } },
     { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
   ];
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   request.onsuccess = grabEventAndContinueHandler;
   let event = yield;
   let db = event.target.result;
 
   let objectStore = db.createObjectStore(objectStoreName, { keyPath: null });
 
--- a/dom/indexedDB/test/unit/test_indexes_bad_values.js
+++ b/dom/indexedDB/test/unit/test_indexes_bad_values.js
@@ -34,17 +34,17 @@ function testSteps()
   const objectStoreDataWeightSort = [
     { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
     { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
     { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
     { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
     { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
   ];
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   request.onsuccess = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
 
   let objectStore = db.createObjectStore(objectStoreName, { } );
--- a/dom/indexedDB/test/unit/test_key_requirements.js
+++ b/dom/indexedDB/test/unit/test_key_requirements.js
@@ -5,17 +5,17 @@
 
 var testGenerator = testSteps(); 
 
 function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
   db.addEventListener("error", function(event) {
     event.preventDefault();
   }, false);
--- a/dom/indexedDB/test/unit/test_keys.js
+++ b/dom/indexedDB/test/unit/test_keys.js
@@ -7,17 +7,17 @@ var testGenerator = testSteps();
 
 function testSteps()
 {
   const dbname = this.window ? window.location.pathname : "Splendid Test";
   const RW = "readwrite"
   let c1 = 1;
   let c2 = 1;
 
-  let openRequest = mozIndexedDB.open(dbname, 1);
+  let openRequest = indexedDB.open(dbname, 1);
   openRequest.onerror = errorHandler;
   openRequest.onupgradeneeded = grabEventAndContinueHandler;
   openRequest.onsuccess = unexpectedSuccessHandler;
   let event = yield;
   let db = event.target.result;
   let trans = event.target.transaction;
 
   // Create test stores
@@ -150,28 +150,28 @@ function testSteps()
     [[[]], [[1]]],
     [[[]], [[[]]]],
     [[[1]]],
     [[[[]], []]],
     ];
 
   for (var i = 0; i < keys.length; ++i) {
     let keyI = keys[i];
-    is(mozIndexedDB.cmp(keyI, keyI), 0, i + " compared to self");
+    is(indexedDB.cmp(keyI, keyI), 0, i + " compared to self");
 
     function doCompare(keyI) {
       for (var j = i-1; j >= i-10 && j >= 0; --j) {
-        is(mozIndexedDB.cmp(keyI, keys[j]), 1, i + " compared to " + j);
-        is(mozIndexedDB.cmp(keys[j], keyI), -1, j + " compared to " + i);
+        is(indexedDB.cmp(keyI, keys[j]), 1, i + " compared to " + j);
+        is(indexedDB.cmp(keys[j], keyI), -1, j + " compared to " + i);
       }
     }
     
     doCompare(keyI);
     store.add(i, keyI).onsuccess = function(e) {
-      is(mozIndexedDB.cmp(e.target.result, keyI), 0,
+      is(indexedDB.cmp(e.target.result, keyI), 0,
          "Returned key should cmp as equal");
       ok(compareKeys(e.target.result, keyI),
          "Returned key should actually be equal");
     };
     
     // Test that -0 compares the same as 0
     if (keyI === 0) {
       doCompare(-0);
@@ -188,17 +188,17 @@ function testSteps()
       yield;
     }
   }
 
   store.openCursor().onsuccess = grabEventAndContinueHandler;
   for (i = 0; i < keys.length; ++i) {
     event = yield;
     let cursor = event.target.result;
-    is(mozIndexedDB.cmp(cursor.key, keys[i]), 0,
+    is(indexedDB.cmp(cursor.key, keys[i]), 0,
        "Read back key should cmp as equal");
     ok(compareKeys(cursor.key, keys[i]),
        "Read back key should actually be equal");
     is(cursor.value, i, "Stored with right value");
 
     cursor.continue();
   }
   event = yield;
@@ -228,26 +228,26 @@ function testSteps()
     [1, [undefined]],
     [1, [null]],
     [1, [/x/]],
     [1, [{}]],
     ];
   
   for (i = 0; i < invalidKeys.length; ++i) {
     try {
-      mozIndexedDB.cmp(invalidKeys[i], 1);
+      indexedDB.cmp(invalidKeys[i], 1);
       ok(false, "didn't throw");
     }
     catch(ex) {
       ok(ex instanceof DOMException, "Threw DOMException");
       is(ex.name, "DataError", "Threw right DOMException");
       is(ex.code, 0, "Threw with right code");
     }
     try {
-      mozIndexedDB.cmp(1, invalidKeys[i]);
+      indexedDB.cmp(1, invalidKeys[i]);
       ok(false, "didn't throw2");
     }
     catch(ex) {
       ok(ex instanceof DOMException, "Threw DOMException2");
       is(ex.name, "DataError", "Threw right DOMException2");
       is(ex.code, 0, "Threw with right code2");
     }
     try {
--- a/dom/indexedDB/test/unit/test_multientry.js
+++ b/dom/indexedDB/test/unit/test_multientry.js
@@ -5,17 +5,17 @@
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
   // Test object stores
   
   let name = this.window ? window.location.pathname : "Splendid Test";
-  let openRequest = mozIndexedDB.open(name, 1);
+  let openRequest = indexedDB.open(name, 1);
   openRequest.onerror = errorHandler;
   openRequest.onupgradeneeded = grabEventAndContinueHandler;
   openRequest.onsuccess = unexpectedSuccessHandler;
   let event = yield;
   let db = event.target.result;
   db.onerror = errorHandler;
   let tests =
     [{ add:     { x: 1, id: 1 },
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/unit/test_names_sorted.js
@@ -0,0 +1,114 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var testGenerator = testSteps();
+
+function testSteps()
+{
+  const name = this.window ? window.location.pathname : "Splendid Test";
+  const objectStoreInfo = [
+    { name: "foo", options: { keyPath: "id" }, location: 1 },
+    { name: "bar", options: { keyPath: "id" }, location: 0 },
+  ];
+  const indexInfo = [
+    { name: "foo", keyPath: "value", location: 1 },
+    { name: "bar", keyPath: "value", location: 0 },
+  ];
+
+  let request = indexedDB.open(name, 1);
+  request.onerror = errorHandler;
+  request.onupgradeneeded = grabEventAndContinueHandler;
+  request.onsuccess = unexpectedSuccessHandler;
+  let event = yield;
+  let db = event.target.result;
+
+  for (let i = 0; i < objectStoreInfo.length; i++) {
+    let info = objectStoreInfo[i];
+    let objectStore = info.hasOwnProperty("options") ?
+                      db.createObjectStore(info.name, info.options) :
+                      db.createObjectStore(info.name);
+
+    // Test index creation, and that it ends up in indexNames.
+    let objectStoreName = info.name;
+    for (let j = 0; j < indexInfo.length; j++) {
+      let info = indexInfo[j];
+      let count = objectStore.indexNames.length;
+      let index = info.hasOwnProperty("options") ?
+                  objectStore.createIndex(info.name, info.keyPath,
+                                          info.options) :
+                  objectStore.createIndex(info.name, info.keyPath);
+    }
+  }
+
+  request.onsuccess = grabEventAndContinueHandler;
+  request.onupgradeneeded = unexpectedSuccessHandler;
+
+  event = yield;
+
+  let objectStoreNames = []
+  for (let i = 0; i < objectStoreInfo.length; i++) {
+    let info = objectStoreInfo[i];
+    objectStoreNames.push(info.name);
+
+    is(db.objectStoreNames[info.location], info.name,
+       "Got objectStore name in the right location");
+
+    let trans = db.transaction(info.name);
+    let objectStore = trans.objectStore(info.name);
+    for (let j = 0; j < indexInfo.length; j++) {
+      let info = indexInfo[j];
+      is(objectStore.indexNames[info.location], info.name,
+         "Got index name in the right location");
+    }
+  }
+
+  let trans = db.transaction(objectStoreNames);
+  for (let i = 0; i < objectStoreInfo.length; i++) {
+    let info = objectStoreInfo[i];
+  
+    is(trans.objectStoreNames[info.location], info.name,
+       "Got objectStore name in the right location");
+  }
+
+  db.close();
+
+  let request = indexedDB.open(name, 1);
+  request.onerror = errorHandler;
+  request.onsuccess = grabEventAndContinueHandler;
+  request.onupgradeneeded = unexpectedSuccessHandler;
+  let event = yield;
+
+  let db = event.target.result;
+
+  let objectStoreNames = []
+  for (let i = 0; i < objectStoreInfo.length; i++) {
+    let info = objectStoreInfo[i];
+    objectStoreNames.push(info.name);
+
+    is(db.objectStoreNames[info.location], info.name,
+       "Got objectStore name in the right location");
+
+    let trans = db.transaction(info.name);
+    let objectStore = trans.objectStore(info.name);
+    for (let j = 0; j < indexInfo.length; j++) {
+      let info = indexInfo[j];
+      is(objectStore.indexNames[info.location], info.name,
+         "Got index name in the right location");
+    }
+  }
+
+  let trans = db.transaction(objectStoreNames);
+  for (let i = 0; i < objectStoreInfo.length; i++) {
+    let info = objectStoreInfo[i];
+  
+    is(trans.objectStoreNames[info.location], info.name,
+       "Got objectStore name in the right location");
+  }
+
+  db.close();
+
+  finishTest();
+  yield;
+}
--- a/dom/indexedDB/test/unit/test_objectCursors.js
+++ b/dom/indexedDB/test/unit/test_objectCursors.js
@@ -17,17 +17,17 @@ function testSteps()
 
   const indexes = [
     { name: "a", options: { } },
     { name: "b", options: { unique: true } }
   ];
 
   var j = 0;
   for (let i in objectStores) {
-    let request = mozIndexedDB.open(name, ++j, description);
+    let request = indexedDB.open(name, ++j, description);
     request.onerror = errorHandler;
     request.onupgradeneeded = grabEventAndContinueHandler;
     let event = yield;
 
     let db = event.target.result;
 
     let objectStore =
       db.createObjectStore(objectStores[i].name,
@@ -50,17 +50,17 @@ function testSteps()
 
     ok(event.target.result == 1 || event.target.result == 2, "Good id");
     db.close();
   }
 
   executeSoon(function() { testGenerator.next(); });
   yield;
 
-  let request = mozIndexedDB.open(name, j, description);
+  let request = indexedDB.open(name, j, description);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
 
   for (let i in objectStores) {
     for (let j in indexes) {
--- a/dom/indexedDB/test/unit/test_objectStore_inline_autoincrement_key_added_on_put.js
+++ b/dom/indexedDB/test/unit/test_objectStore_inline_autoincrement_key_added_on_put.js
@@ -6,17 +6,17 @@
 var testGenerator = testSteps();
 
 function testSteps()
 {
   const IDBObjectStore = Components.interfaces.nsIIDBObjectStore;
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
 
-  var request = mozIndexedDB.open(name, 1, description);
+  var request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   var event = yield;
 
   var db = event.target.result;
 
   var test = {
     name: "inline key; key generator",
--- a/dom/indexedDB/test/unit/test_objectStore_remove_values.js
+++ b/dom/indexedDB/test/unit/test_objectStore_remove_values.js
@@ -36,17 +36,17 @@ function testSteps()
       keyName: null,
       keyValue: 1,
     }
   ];
 
   for (let i = 0; i < data.length; i++) {
     let test = data[i];
 
-    let request = mozIndexedDB.open(name, i+1, description);
+    let request = indexedDB.open(name, i+1, description);
     request.onerror = errorHandler;
     request.onupgradeneeded = grabEventAndContinueHandler;
     let event = yield;
 
     let db = event.target.result;
 
     let objectStore = db.createObjectStore(test.name,
                                            { keyPath: test.keyName,
--- a/dom/indexedDB/test/unit/test_object_identity.js
+++ b/dom/indexedDB/test/unit/test_object_identity.js
@@ -2,17 +2,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
-  let request = mozIndexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
+  let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
   let transaction = event.target.transaction;
 
   let objectStore1 = db.createObjectStore("foo");
--- a/dom/indexedDB/test/unit/test_odd_result_order.js
+++ b/dom/indexedDB/test/unit/test_odd_result_order.js
@@ -4,17 +4,17 @@
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
   const data = { key: 5, index: 10 };
 
-  let request = mozIndexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
+  let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
 
   ok(db instanceof IDBDatabase, "Got a real database");
 
--- a/dom/indexedDB/test/unit/test_open_empty_db.js
+++ b/dom/indexedDB/test/unit/test_open_empty_db.js
@@ -12,17 +12,17 @@ function testSteps()
     null,
     undefined,
     this.window ? window.location.pathname : "Splendid Test"
   ];
 
   const version = 1;
 
   for each (let name in names) {
-    let request = mozIndexedDB.open(name, version);
+    let request = indexedDB.open(name, version);
     request.onerror = errorHandler;
     request.onsuccess = grabEventAndContinueHandler;
     let event = yield;
 
     if (name === null) {
       name = "null";
     }
     else if (name === undefined) {
--- a/dom/indexedDB/test/unit/test_open_objectStore.js
+++ b/dom/indexedDB/test/unit/test_open_objectStore.js
@@ -7,17 +7,17 @@ var testGenerator = testSteps();
 
 function testSteps()
 {
   const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
   const objectStoreName = "Objects";
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   request.onsuccess = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
   is(db.objectStoreNames.length, 0, "Bad objectStores list");
 
--- a/dom/indexedDB/test/unit/test_optionalArguments.js
+++ b/dom/indexedDB/test/unit/test_optionalArguments.js
@@ -18,17 +18,17 @@ function testSteps()
     { ssn: "237-23-7736", name: "Joe", height: 65, weight: 150 },
     { ssn: "237-23-7737", name: "Pat", height: 65 },
     { ssn: "237-23-7738", name: "Mel", height: 66, weight: {} },
     { ssn: "237-23-7739", name: "Tom", height: 62, weight: 130 }
   ];
 
   const weightSort = [1, 0, 3, 7, 4, 2];
 
-  let request = mozIndexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
+  let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   request.onsuccess = grabEventAndContinueHandler;
   let event = yield;
 
   is(event.type, "upgradeneeded", "Got upgradeneeded event");
 
   let db = event.target.result;
@@ -1557,150 +1557,150 @@ function testSteps()
       testGenerator.next();
     }
   }
   yield;
 
   is(count, 1,
      "Correct count for only keyRange arg to index.openKeyCursor");
 
-  objectStore.getAll(data[1].ssn).onsuccess = grabEventAndContinueHandler;
+  objectStore.mozGetAll(data[1].ssn).onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array");
   is(event.target.result.length, 1, "Got correct length");
   is(event.target.result[0].ssn, data[1].ssn, "Got correct result");
 
-  objectStore.getAll(null).onsuccess = grabEventAndContinueHandler;
+  objectStore.mozGetAll(null).onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array");
   is(event.target.result.length, data.length, "Got correct length");
   for (let i in event.target.result) {
     is(event.target.result[i].ssn, data[i].ssn, "Got correct value");
   }
 
-  objectStore.getAll(undefined).onsuccess = grabEventAndContinueHandler;
+  objectStore.mozGetAll(undefined).onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array");
   is(event.target.result.length, data.length, "Got correct length");
   for (let i in event.target.result) {
     is(event.target.result[i].ssn, data[i].ssn, "Got correct value");
   }
 
-  objectStore.getAll().onsuccess = grabEventAndContinueHandler;
+  objectStore.mozGetAll().onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array");
   is(event.target.result.length, data.length, "Got correct length");
   for (let i in event.target.result) {
     is(event.target.result[i].ssn, data[i].ssn, "Got correct value");
   }
 
   keyRange = IDBKeyRange.lowerBound(0);
 
-  objectStore.getAll(keyRange).onsuccess = grabEventAndContinueHandler;
+  objectStore.mozGetAll(keyRange).onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array");
   is(event.target.result.length, data.length, "Got correct length");
   for (let i in event.target.result) {
     is(event.target.result[i].ssn, data[i].ssn, "Got correct value");
   }
 
-  index.getAll().onsuccess = grabEventAndContinueHandler;
+  index.mozGetAll().onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array");
   is(event.target.result.length, weightSort.length, "Got correct length");
   for (let i in event.target.result) {
     is(event.target.result[i].ssn, data[weightSort[i]].ssn,
        "Got correct value");
   }
 
-  index.getAll(undefined).onsuccess = grabEventAndContinueHandler;
+  index.mozGetAll(undefined).onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array");
   is(event.target.result.length, weightSort.length, "Got correct length");
   for (let i in event.target.result) {
     is(event.target.result[i].ssn, data[weightSort[i]].ssn,
        "Got correct value");
   }
 
-  index.getAll(null).onsuccess = grabEventAndContinueHandler;
+  index.mozGetAll(null).onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array");
   is(event.target.result.length, weightSort.length, "Got correct length");
   for (let i in event.target.result) {
     is(event.target.result[i].ssn, data[weightSort[i]].ssn,
        "Got correct value");
   }
 
-  index.getAll(data[weightSort[0]].weight).onsuccess = grabEventAndContinueHandler;
+  index.mozGetAll(data[weightSort[0]].weight).onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array");
   is(event.target.result.length, 1, "Got correct length");
   is(event.target.result[0].ssn, data[weightSort[0]].ssn, "Got correct result");
 
   keyRange = IDBKeyRange.lowerBound(0);
 
-  index.getAll(keyRange).onsuccess = grabEventAndContinueHandler;
+  index.mozGetAll(keyRange).onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array");
   is(event.target.result.length, weightSort.length, "Got correct length");
   for (let i in event.target.result) {
     is(event.target.result[i].ssn, data[weightSort[i]].ssn,
        "Got correct value");
   }
 
-  index.getAllKeys().onsuccess = grabEventAndContinueHandler;
+  index.mozGetAllKeys().onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array");
   is(event.target.result.length, weightSort.length, "Got correct length");
   for (let i in event.target.result) {
     is(event.target.result[i], data[weightSort[i]].ssn,
        "Got correct value");
   }
 
-  index.getAllKeys(undefined).onsuccess = grabEventAndContinueHandler;
+  index.mozGetAllKeys(undefined).onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array");
   is(event.target.result.length, weightSort.length, "Got correct length");
   for (let i in event.target.result) {
     is(event.target.result[i], data[weightSort[i]].ssn,
        "Got correct value");
   }
 
-  index.getAllKeys(null).onsuccess = grabEventAndContinueHandler;
+  index.mozGetAllKeys(null).onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array");
   is(event.target.result.length, weightSort.length, "Got correct length");
   for (let i in event.target.result) {
     is(event.target.result[i], data[weightSort[i]].ssn,
        "Got correct value");
   }
 
-  index.getAllKeys(data[weightSort[0]].weight).onsuccess = grabEventAndContinueHandler;
+  index.mozGetAllKeys(data[weightSort[0]].weight).onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array");
   is(event.target.result.length, 1, "Got correct length");
   is(event.target.result[0], data[weightSort[0]].ssn, "Got correct result");
 
   keyRange = IDBKeyRange.lowerBound(0);
 
-  index.getAllKeys(keyRange).onsuccess = grabEventAndContinueHandler;
+  index.mozGetAllKeys(keyRange).onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result instanceof Array, true, "Got an array");
   is(event.target.result.length, weightSort.length, "Got correct length");
   for (let i in event.target.result) {
     is(event.target.result[i], data[weightSort[i]].ssn,
        "Got correct value");
   }
--- a/dom/indexedDB/test/unit/test_overlapping_transactions.js
+++ b/dom/indexedDB/test/unit/test_overlapping_transactions.js
@@ -6,17 +6,17 @@
 var testGenerator = testSteps();
 
 function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
   const objectStores = [ "foo", "bar" ];
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
   is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
 
   event.target.onsuccess = grabEventAndContinueHandler;
--- a/dom/indexedDB/test/unit/test_put_get_values.js
+++ b/dom/indexedDB/test/unit/test_put_get_values.js
@@ -9,17 +9,17 @@ function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
   const objectStoreName = "Objects";
 
   let testString = { key: 0, value: "testString" };
   let testInt = { key: 1, value: 1002 };
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
 
   let objectStore = db.createObjectStore(objectStoreName,
                                          { autoIncrement: 0 });
--- a/dom/indexedDB/test/unit/test_put_get_values_autoIncrement.js
+++ b/dom/indexedDB/test/unit/test_put_get_values_autoIncrement.js
@@ -9,17 +9,17 @@ function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
   const objectStoreName = "Objects";
 
   let testString = { value: "testString" };
   let testInt = { value: 1002 };
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
 
   let objectStore = db.createObjectStore(objectStoreName,
                                          { autoIncrement: 1 });
--- a/dom/indexedDB/test/unit/test_remove_index.js
+++ b/dom/indexedDB/test/unit/test_remove_index.js
@@ -8,17 +8,17 @@ var testGenerator = testSteps();
 function testSteps()
 {
   const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
 
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
   const indexName = "My Test Index";
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
   is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
 
   let objectStore = db.createObjectStore("test store", { keyPath: "foo" });
--- a/dom/indexedDB/test/unit/test_remove_objectStore.js
+++ b/dom/indexedDB/test/unit/test_remove_objectStore.js
@@ -8,17 +8,17 @@ var testGenerator = testSteps();
 function testSteps()
 {
   const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
 
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
   const objectStoreName = "Objects";
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
   is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
 
   let objectStore = db.createObjectStore(objectStoreName,
@@ -37,17 +37,17 @@ function testSteps()
   }
   yield;
 
   is(db.objectStoreNames.length, 1, "Correct objectStoreNames list");
   is(db.objectStoreNames.item(0), objectStoreName, "Correct name");
 
   db.close();
 
-  let request = mozIndexedDB.open(name, 2, description);
+  let request = indexedDB.open(name, 2, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
   let trans = event.target.transaction;
 
   let oldObjectStore = trans.objectStore(objectStoreName);
@@ -81,17 +81,17 @@ function testSteps()
   db.deleteObjectStore(objectStore.name);
   is(db.objectStoreNames.length, 0, "Correct objectStores list");
 
   continueToNextStep();
   yield;
 
   db.close();
 
-  let request = mozIndexedDB.open(name, 3, description);
+  let request = indexedDB.open(name, 3, description);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
 
   objectStore = db.createObjectStore(objectStoreName, { keyPath: "foo" });
 
--- a/dom/indexedDB/test/unit/test_request_readyState.js
+++ b/dom/indexedDB/test/unit/test_request_readyState.js
@@ -5,17 +5,17 @@
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   is(request.readyState, "pending", "Correct readyState");
 
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   is(request.readyState, "done", "Correct readyState");
 
--- a/dom/indexedDB/test/unit/test_setVersion.js
+++ b/dom/indexedDB/test/unit/test_setVersion.js
@@ -5,17 +5,17 @@
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
 
   // Check default state.
   is(db.version, 1, "Correct default version for a new database.");
@@ -25,17 +25,17 @@ function testSteps()
     42,
   ];
 
   db.close();
 
   for (let i = 0; i < versions.length; i++) {
     let version = versions[i];
 
-    let request = mozIndexedDB.open(name, version, description);
+    let request = indexedDB.open(name, version, description);
     request.onerror = errorHandler;
     request.onupgradeneeded = grabEventAndContinueHandler;
     let event = yield;
 
     let db = event.target.result;
 
     is(db.version, version, "Database version number updated correctly");
     is(event.target.transaction.mode, "versionchange", "Correct mode");
--- a/dom/indexedDB/test/unit/test_setVersion_abort.js
+++ b/dom/indexedDB/test/unit/test_setVersion_abort.js
@@ -3,75 +3,96 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
-  const description = "My Test Database";
 
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1);
   request.onerror = errorHandler;
   request.onsuccess = unexpectedSuccessHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
 
   let objectStore = db.createObjectStore("foo");
   let index = objectStore.createIndex("bar", "baz");
 
   is(db.version, 1, "Correct version");
   is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
   is(objectStore.indexNames.length, 1, "Correct indexNames length");
 
   let transaction = event.target.transaction;
+  is(transaction.mode, "versionchange", "Correct transaction mode");
   transaction.oncomplete = unexpectedSuccessHandler;
   transaction.onabort = grabEventAndContinueHandler;
   transaction.abort();
 
+  is(db.version, 0, "Correct version");
+  is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
+  is(objectStore.indexNames.length, 0, "Correct indexNames length");
+
+  // Test that the db is actually closed.
+  try {
+    db.transaction("");
+    ok(false, "Expect an exception");
+  } catch (e) {
+    ok(true, "Expect an exception");
+    is(e.name, "InvalidStateError", "Expect an InvalidStateError");
+  }
+
   event = yield;
   is(event.type, "abort", "Got transaction abort event");
   is(event.target, transaction, "Right target");
   is(event.target.transaction, null, "No transaction");
 
-  is(db.version, 1, "Correct version");
-  is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
+  is(db.version, 0, "Correct version");
+  is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
+  is(objectStore.indexNames.length, 0, "Correct indexNames length");
 
   request.onerror = grabEventAndContinueHandler;
   request.onupgradeneeded = unexpectedSuccessHandler;
 
   event = yield;
 
   is(event.type, "error", "Got request error event");
   is(event.target, request, "Right target");
   is(event.target.transaction, null, "No transaction");
 
   event.preventDefault();
 
-  request = mozIndexedDB.open(name, 1, description);
+  request = indexedDB.open(name, 1);
   request.onerror = errorHandler;
   request.onsuccess = unexpectedSuccessHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   event = yield;
 
   is(event.type, "upgradeneeded", "Got upgradeneeded event");
 
   let db2 = event.target.result;
 
   isnot(db, db2, "Should give a different db instance");
   is(db2.version, 1, "Correct version");
   is(db2.objectStoreNames.length, 0, "Correct objectStoreNames length");
 
+  let objectStore2 = db2.createObjectStore("foo");
+  let index2 = objectStore2.createIndex("bar", "baz");
+
   request.onsuccess = grabEventAndContinueHandler;
   request.onupgradeneeded = unexpectedSuccessHandler;
   event = yield;
 
   is(event.target.result, db2, "Correct target");
   is(event.type, "success", "Got success event");
   is(db2.version, 1, "Correct version");
-  is(db2.objectStoreNames.length, 0, "Correct objectStoreNames length");
+  is(db2.objectStoreNames.length, 1, "Correct objectStoreNames length");
+  is(objectStore2.indexNames.length, 1, "Correct indexNames length");
+  is(db.version, 0, "Correct version still");
+  is(db.objectStoreNames.length, 0, "Correct objectStoreNames length still");
+  is(objectStore.indexNames.length, 0, "Correct indexNames length still");
 
   finishTest();
   yield;
 }
--- a/dom/indexedDB/test/unit/test_setVersion_events.js
+++ b/dom/indexedDB/test/unit/test_setVersion_events.js
@@ -6,17 +6,17 @@
 var testGenerator = testSteps();
 
 function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
   const description = "My Test Database";
 
   // Open a datbase for the first time.
-  let request = mozIndexedDB.open(name, 1, description);
+  let request = indexedDB.open(name, 1, description);
 
   // Sanity checks
   ok(request instanceof IDBRequest, "Request should be an IDBRequest");
   ok(request instanceof IDBOpenDBRequest, "Request should be an IDBOpenDBRequest");
   //ok(request instanceof EventTarget, "Request should be an EventTarget");
   is(request.source, null, "Request should have no source");
   try {
     request.result;
@@ -41,17 +41,17 @@ function testSteps()
     is(event.target.version, 1, "Correct db version");
     is(event.oldVersion, 1, "Correct event oldVersion");
     is(event.newVersion, 2, "Correct event newVersion");
     is(versionChangeEventCount++, 0, "Correct count");
     db1.close();
   }, false);
 
   // Open the database again and trigger an upgrade that should succeed
-  request = mozIndexedDB.open(name, 2, description);
+  request = indexedDB.open(name, 2, description);
   request.onerror = errorHandler;
   request.onsuccess = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   if (SpecialPowers.isMainProcess()) {
     request.onblocked = errorHandler;
   }
   else {
     todo(false, "Need to fix blocked events in child processes!");
@@ -79,31 +79,31 @@ function testSteps()
     is(event.target, db2, "Correct target");
     is(event.target.version, 2, "Correct db version");
     is(event.oldVersion, 2, "Correct event oldVersion");
     is(event.newVersion, 3, "Correct event newVersion");
     is(versionChangeEventCount++, 1, "Correct count");
   }, false);
 
   // Test opening the existing version again
-  request = mozIndexedDB.open(name, 2, description);
+  request = indexedDB.open(name, 2, description);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   if (SpecialPowers.isMainProcess()) {
     request.onblocked = errorHandler;
   }
   else {
     todo(false, "Need to fix blocked events in child processes!");
   }
   event = yield;
 
   db3 = event.target.result;
 
   // Test an upgrade that should fail
-  request = mozIndexedDB.open(name, 3, description);
+  request = indexedDB.open(name, 3, description);
   request.onerror = errorHandler;
   request.onsuccess = errorHandler;
   request.onupgradeneeded = errorHandler;
   request.onblocked = grabEventAndContinueHandler;
 
   event = yield;
   ok(true, "Got version change blocked event");
   ok(event instanceof IDBVersionChangeEvent, "Event is of the right type");
@@ -122,17 +122,17 @@ function testSteps()
 
   event = yield;
   event = yield;
 
   db3 = event.target.result;
   db3.close();
 
   // Test another upgrade that should succeed.
-  request = mozIndexedDB.open(name, 4);
+  request = indexedDB.open(name, 4);
   request.onerror = errorHandler;
   request.onsuccess = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   if (SpecialPowers.isMainProcess()) {
     request.onblocked = errorHandler;
   }
   else {
     todo(false, "Need to fix blocked events in child processes!");
--- a/dom/indexedDB/test/unit/test_setVersion_exclusion.js
+++ b/dom/indexedDB/test/unit/test_setVersion_exclusion.js
@@ -4,22 +4,22 @@
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
 
-  let request = mozIndexedDB.open(name, 1);
+  let request = indexedDB.open(name, 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   request.onsuccess = unexpectedSuccessHandler;
 
-  let request2 = mozIndexedDB.open(name, 2);
+  let request2 = indexedDB.open(name, 2);
   request2.onerror = errorHandler;
   request2.onupgradeneeded = unexpectedSuccessHandler;
   request2.onsuccess = unexpectedSuccessHandler;
 
   let event = yield;
   is(event.type, "upgradeneeded", "Expect an upgradeneeded event");
   is(event.target, request, "Event should be fired on the request");
   ok(event.target.result instanceof IDBDatabase, "Expect a database here");
--- a/dom/indexedDB/test/unit/test_success_events_after_abort.js
+++ b/dom/indexedDB/test/unit/test_success_events_after_abort.js
@@ -2,17 +2,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
-  let request = mozIndexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
+  let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
 
   event.target.onsuccess = continueToNextStep;
 
--- a/dom/indexedDB/test/unit/test_traffic_jam.js
+++ b/dom/indexedDB/test/unit/test_traffic_jam.js
@@ -6,17 +6,17 @@
 var testGenerator = testSteps();
 
 function testSteps()
 {
   const name = this.window ? window.location.pathname : "Splendid Test";
 
   let requests = [];
   function doOpen(version, errorCallback, upgradeNeededCallback, successCallback) {
-    let request = mozIndexedDB.open(name, version);
+    let request = indexedDB.open(name, version);
     request.onerror = errorCallback;
     request.onupgradeneeded = upgradeNeededCallback;
     request.onsuccess = successCallback;
     requests.push(request);
   }
 
   doOpen(1, errorHandler, grabEventAndContinueHandler, grabEventAndContinueHandler);
   doOpen(2, errorHandler, unexpectedSuccessHandler, unexpectedSuccessHandler);
--- a/dom/indexedDB/test/unit/test_transaction_abort.js
+++ b/dom/indexedDB/test/unit/test_transaction_abort.js
@@ -14,17 +14,17 @@ function abortListener(evt)
 }
 
 function testSteps()
 {
   const Ci = Components.interfaces;
 
   const name = this.window ? window.location.pathname : "Splendid Test";
 
-  let request = mozIndexedDB.open(name, 1);
+  let request = indexedDB.open(name, 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   request.onsuccess = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
   db.onabort = abortListener;
 
--- a/dom/indexedDB/test/unit/test_transaction_lifetimes.js
+++ b/dom/indexedDB/test/unit/test_transaction_lifetimes.js
@@ -2,17 +2,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
-  let request = mozIndexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
+  let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   request.onsuccess = unexpectedSuccessHandler;
   let event = yield;
 
   let db = event.target.result;
   db.onerror = errorHandler;
 
--- a/dom/indexedDB/test/unit/test_transaction_lifetimes_nested.js
+++ b/dom/indexedDB/test/unit/test_transaction_lifetimes_nested.js
@@ -2,17 +2,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
-  let request = mozIndexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
+  let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
   db.onerror = errorHandler;
 
   event.target.onsuccess = continueToNextStep;
--- a/dom/indexedDB/test/unit/test_transaction_ordering.js
+++ b/dom/indexedDB/test/unit/test_transaction_ordering.js
@@ -2,17 +2,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var testGenerator = testSteps();
 
 function testSteps()
 {
-  let request = mozIndexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
+  let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
   request.onerror = errorHandler;
   request.onupgradeneeded = grabEventAndContinueHandler;
   let event = yield;
 
   let db = event.target.result;
   db.onerror = errorHandler;
 
   request.onsuccess = continueToNextStep;
--- a/dom/indexedDB/test/unit/xpcshell.ini
+++ b/dom/indexedDB/test/unit/xpcshell.ini
@@ -24,16 +24,17 @@ tail =
 [test_index_getAllObjects.js]
 [test_index_object_cursors.js]
 [test_index_update_delete.js]
 [test_indexes.js]
 [test_indexes_bad_values.js]
 [test_key_requirements.js]
 [test_keys.js]
 [test_multientry.js]
+[test_names_sorted.js]
 [test_object_identity.js]
 [test_objectCursors.js]
 [test_objectStore_inline_autoincrement_key_added_on_put.js]
 [test_objectStore_remove_values.js]
 [test_odd_result_order.js]
 [test_open_empty_db.js]
 [test_open_objectStore.js]
 [test_optionalArguments.js]
--- a/dom/interfaces/storage/nsIDOMStorageIndexedDB.idl
+++ b/dom/interfaces/storage/nsIDOMStorageIndexedDB.idl
@@ -10,16 +10,16 @@
  * http://www.whatwg.org/specs/web-apps/current-work/#scs-client-side and
  * http://www.w3.org/TR/IndexedDB/ for more information.
  *
  * Allows access to contextual storage areas.
  */
 
 interface nsIIDBFactory;
 
-[scriptable, uuid(d20d48e4-0b94-40c7-a9c7-ba1d6ad44442)]
+[scriptable, uuid(c5982775-3f65-4d3e-b5f0-2400c987a900)]
 interface nsIDOMStorageIndexedDB : nsISupports
 {
   /**
    * Indexed Databases for the current browsing context.
    */
-  readonly attribute nsIIDBFactory mozIndexedDB;
+  readonly attribute nsIIDBFactory indexedDB;
 };
--- a/dom/settings/SettingsManager.js
+++ b/dom/settings/SettingsManager.js
@@ -80,18 +80,18 @@ SettingsLock.prototype = {
             };
 
             req.onerror = function() {
               Services.DOMRequest.fireError(request, 0)
             };
           }
           break;
         case "get":
-          req = (info.name === "*") ? store.getAll()
-                                    : store.getAll(info.name);
+          req = (info.name === "*") ? store.mozGetAll()
+                                    : store.mozGetAll(info.name);
 
           req.onsuccess = function(event) {
             debug("Request for '" + info.name + "' successful. " + 
                   "Record count: " + event.target.result.length);
             debug("result: " + JSON.stringify(event.target.result));
 
             if (event.target.result.length == 0) {
               dump("MOZSETTINGS-GET-WARNING: " + info.name + " is not in the database. Please add it to build/settings.js\n");
--- a/dom/settings/SettingsService.js
+++ b/dom/settings/SettingsService.js
@@ -65,17 +65,17 @@ SettingsServiceLock.prototype = {
               value: value
             }));
             lock._open = false;
           };
 
           req.onerror = function(event) { callback ? callback.handleError(event.target.errorMessage) : null; };
           break;
         case "get":
-          req = store.getAll(name);
+          req = store.mozGetAll(name);
           req.onsuccess = function(event) {
             debug("Request successful. Record count:" + event.target.result.length);
             debug("result: " + JSON.stringify(event.target.result));
             this._open = true;
             if (callback) {
               if (event.target.result[0]) {
                 if (event.target.result.length > 1) {
                   debug("Warning: overloaded setting:" + name);
--- a/dom/sms/src/ril/SmsDatabaseService.js
+++ b/dom/sms/src/ril/SmsDatabaseService.js
@@ -137,17 +137,17 @@ SmsDatabaseService.prototype = {
     }
 
     let self = this;
     function gotDB(db) {
       self.db = db;
       callback(null, db);
     }
 
-    let request = GLOBAL_SCOPE.mozIndexedDB.open(DB_NAME, DB_VERSION);
+    let request = GLOBAL_SCOPE.indexedDB.open(DB_NAME, DB_VERSION);
     request.onsuccess = function (event) {
       if (DEBUG) debug("Opened database:", DB_NAME, DB_VERSION);
       gotDB(event.target.result);
     };
     request.onupgradeneeded = function (event) {
       if (DEBUG) {
         debug("Database needs upgrade:", DB_NAME,
               event.oldVersion, event.newVersion);
--- a/dom/sms/tests/test_smsdatabaseservice.xul
+++ b/dom/sms/tests/test_smsdatabaseservice.xul
@@ -139,17 +139,17 @@ gIDBManager.initWindowless(this);
 let _db;
 function ensureDB(callback) {
   if (_db) {
     callback(_db);
     return;
   }
   let request;
   try {
-    request = mozIndexedDB.open(DB_NAME, DB_VERSION);
+    request = indexedDB.open(DB_NAME, DB_VERSION);
   } catch (ex) {
     ok(false, ex);
   }
   request.onsuccess = function onsuccess(event) {
     _db = request.result;
     callback(_db);
   };
   request.onerror =
--- a/dom/src/json/nsJSON.cpp
+++ b/dom/src/json/nsJSON.cpp
@@ -172,42 +172,25 @@ NS_IMETHODIMP
 nsJSON::EncodeFromJSVal(JS::Value *value, JSContext *cx, nsAString &result)
 {
   result.Truncate();
 
   // Begin a new request
   JSAutoRequest ar(cx);
 
   JSAutoEnterCompartment ac;
-  nsIScriptSecurityManager *ssm = nsnull;
   if (value->isObject()) {
     JSObject *obj = &value->toObject();
     if (!ac.enter(cx, obj)) {
       return NS_ERROR_FAILURE;
     }
-
-    nsCOMPtr<nsIPrincipal> principal;
-    ssm = nsContentUtils::GetSecurityManager();
-    nsresult rv = ssm->GetObjectPrincipal(cx, obj, getter_AddRefs(principal));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    JSStackFrame *fp = nsnull;
-    rv = ssm->PushContextPrincipal(cx, JS_FrameIterator(cx, &fp), principal);
-    NS_ENSURE_SUCCESS(rv, rv);
   }
 
   nsJSONWriter writer;
-  JSBool ok = JS_Stringify(cx, value, NULL, JSVAL_NULL,
-                           WriteCallback, &writer);
-
-  if (ssm) {
-    ssm->PopContextPrincipal(cx);
-  }
-
-  if (!ok) {
+  if (!JS_Stringify(cx, value, NULL, JSVAL_NULL, WriteCallback, &writer)) {
     return NS_ERROR_XPC_BAD_CONVERT_JS;
   }
 
   NS_ENSURE_TRUE(writer.DidWrite(), NS_ERROR_UNEXPECTED);
   writer.FlushBuffer();
   result.Assign(writer.mOutputString);
   return NS_OK;
 }
--- a/dom/tests/mochitest/whatwg/postMessage_chrome_helper.html
+++ b/dom/tests/mochitest/whatwg/postMessage_chrome_helper.html
@@ -32,19 +32,17 @@
           msg += " wrong-message(" + evt.data + ")";
 
         respond(msg);
       }
     }
     
     function respond(msg)
     {
-      // ...so get privileges and test that this works with privileges
-      netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-      window.parent.postMessage(msg, "*");
+      SpecialPowers.wrap(window).parent.postMessage(msg, "*");
     }
     
     window.addEventListener("message", receiveMessage, false);
   </script>
 </head>
 <body>
 <h1 id="domain">example.org</h1>
 </body>
--- a/dom/tests/mochitest/whatwg/test_postMessage_chrome.html
+++ b/dom/tests/mochitest/whatwg/test_postMessage_chrome.html
@@ -88,20 +88,16 @@ function chromePathIsSet(evt)
 
 /*************
  * RECEIVERS *
  *************/
 
 function receiveContent(evt)
 {
   is(evt.isTrusted, true, "should have sent a trusted event");
-  is(evt.origin, "http://example.org", "content response event has wrong URI");
-  is(evt.source, window.frames.contentDomain,
-     "wrong source for same-domain message!");
-
   finish();
 }
 
 
 /**************
  * TEST SETUP *
  **************/
 
--- a/dom/wifi/DOMWifiManager.js
+++ b/dom/wifi/DOMWifiManager.js
@@ -50,16 +50,17 @@ DOMWifiManager.prototype = {
     this._connectionStatus = "disconnected";
     this._enabled = true;
     this._lastConnectionInfo = null;
 
     const messages = ["WifiManager:setEnabled:Return:OK", "WifiManager:setEnabled:Return:NO",
                       "WifiManager:getNetworks:Return:OK", "WifiManager:getNetworks:Return:NO",
                       "WifiManager:associate:Return:OK", "WifiManager:associate:Return:NO",
                       "WifiManager:forget:Return:OK", "WifiManager:forget:Return:NO",
+                      "WifiManager:wifiDown", "WifiManager:wifiUp",
                       "WifiManager:onconnecting", "WifiManager:onassociate",
                       "WifiManager:onconnect", "WifiManager:ondisconnect",
                       "WifiManager:connectionInfoUpdate"];
     this.initHelper(aWindow, messages);
     this._mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);
 
     var state = this._mm.sendSyncMessage("WifiManager:getState")[0];
     if (state) {
@@ -71,21 +72,20 @@ DOMWifiManager.prototype = {
       this._currentNetwork = null;
       this._lastConnectionInfo = null;
       this._enabled = false;
       this._connectionStatus = "disconnected";
     }
   },
 
   uninit: function() {
-    this._onConnecting = null;
-    this._onAssociate = null;
-    this._onConnect = null;
-    this._onDisconnect = null;
+    this._onStatusChange = null;
     this._onConnectionInfoUpdate = null;
+    this._onEnabled = null;
+    this._onDisabled = null;
   },
 
   _sendMessageForRequest: function(name, data, request) {
     let id = this.getRequestId(request);
     this._mm.sendAsyncMessage(name, { data: data, rid: id, mid: this._id });
   },
 
   receiveMessage: function(aMessage) {
@@ -133,16 +133,27 @@ DOMWifiManager.prototype = {
         Services.DOMRequest.fireSuccess(request, true);
         break;
 
       case "WifiManager:forget:Return:NO":
         request = this.takeRequest(msg.rid);
         Services.DOMRequest.fireError(request, msg.data);
         break;
 
+      case "WifiManager:wifiDown":
+        this._enabled = false;
+        this._currentNetwork = null;
+        this._fireEnabledOrDisabled(false);
+        break;
+
+      case "WifiManager:wifiUp":
+        this._enabled = true;
+        this._fireEnabledOrDisabled(true);
+        break;
+
       case "WifiManager:onconnecting":
         this._currentNetwork = msg.network;
         this._connectionStatus = "connecting";
         this._fireStatusChangeEvent();
         break;
 
       case "WifiManager:onassociate":
         this._currentNetwork = msg.network;
@@ -189,16 +200,24 @@ DOMWifiManager.prototype = {
                                                               signalStrength: info.signalStrength,
                                                               relSignalStrength: info.relSignalStrength,
                                                               linkSpeed: info.linkSpeed
                                                             });
       this._onConnectionInfoUpdate.handleEvent(evt);
     }
   },
 
+  _fireEnabledOrDisabled: function enabledDisabled(enabled) {
+    var handler = enabled ? this._onEnabled : this._onDisabled;
+    if (handler) {
+      var evt = new this._window.Event("WifiEnabled");
+      handler.handleEvent(evt);
+    }
+  },
+
   // nsIDOMWifiManager
   setEnabled: function nsIDOMWifiManager_setEnabled(enabled) {
     if (!this._hasPrivileges)
       throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
     var request = this.createRequest();
     this._sendMessageForRequest("WifiManager:setEnabled", enabled, request);
     return request;
   },
@@ -250,16 +269,28 @@ DOMWifiManager.prototype = {
       throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
     this._onStatusChange = callback;
   },
 
   set connectionInfoUpdate(callback) {
     if (!this._hasPrivileges)
       throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
     this._onConnectionInfoUpdate = callback;
+  },
+
+  set onenabled(callback) {
+    if (!this._hasPrivileges)
+      throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
+    this._onEnabled = callback;
+  },
+
+  set ondisabled(callback) {
+    if (!this._hasPrivileges)
+      throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
+    this._onDisabled = callback;
   }
 };
 
 const NSGetFactory = XPCOMUtils.generateNSGetFactory([DOMWifiManager]);
 
 let debug;
 if (DEBUG) {
   debug = function (s) {
--- a/dom/wifi/WifiWorker.js
+++ b/dom/wifi/WifiWorker.js
@@ -27,43 +27,44 @@ XPCOMUtils.defineLazyServiceGetter(this,
 // A note about errors and error handling in this file:
 // The libraries that we use in this file are intended for C code. For
 // C code, it is natural to return -1 for errors and 0 for success.
 // Therefore, the code that interacts directly with the worker uses this
 // convention (note: command functions do get boolean results since the
 // command always succeeds and we do a string/boolean check for the
 // expected results).
 var WifiManager = (function() {
-  function getSdkVersion() {
+  function getSdkVersionAndDevice() {
     Cu.import("resource://gre/modules/ctypes.jsm");
     try {
       let cutils = ctypes.open("libcutils.so");
       let cbuf = ctypes.char.array(4096)();
       let c_property_get = cutils.declare("property_get", ctypes.default_abi,
                                           ctypes.int,       // return value: length
                                           ctypes.char.ptr,  // key
                                           ctypes.char.ptr,  // value
                                           ctypes.char.ptr); // default
       let property_get = function (key, defaultValue) {
         if (defaultValue === undefined) {
           defaultValue = null;
         }
         c_property_get(key, cbuf, defaultValue);
         return cbuf.readString();
       }
-      return parseInt(property_get("ro.build.version.sdk"));
+      return { sdkVersion: parseInt(property_get("ro.build.version.sdk")),
+               device: property_get("ro.product.device") };
     } catch(e) {
       // Eat it.  Hopefully we're on a non-Gonk system ...
       // 
       // XXX we should check that
       return 0;
     }
   }
 
-  let sdkVersion = getSdkVersion();
+  let { sdkVersion, device } = getSdkVersionAndDevice();
 
   var controlWorker = new ChromeWorker(WIFIWORKER_WORKER);
   var eventWorker = new ChromeWorker(WIFIWORKER_WORKER);
 
   // Callbacks to invoke when a reply arrives from the controlWorker.
   var controlCallbacks = Object.create(null);
   var idgen = 0;
 
@@ -577,23 +578,23 @@ var WifiManager = (function() {
       return;
     }
     if (connectTries++ < 3) {
       // try again in 5 seconds
       if (!retryTimer)
         retryTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
 
       retryTimer.initWithCallback(function(timer) {
-          connectToSupplicant(connectCallback);
-        }, 5000, Ci.nsITimer.TYPE_ONE_SHOT);
+        connectToSupplicant(connectCallback);
+      }, 5000, Ci.nsITimer.TYPE_ONE_SHOT);
       return;
     }
 
     retryTimer = null;
-    notify("supplicantlost");
+    notify("supplicantfailed");
   }
 
   manager.connectionDropped = function(callback) {
     // If we got disconnected, kill the DHCP client in preparation for
     // reconnection.
     resetConnections(manager.ifname, function() {
       stopDhcp(manager.ifname, function() {
         callback();
@@ -713,34 +714,39 @@ var WifiManager = (function() {
         if (kv.length === 2)
           fields[kv[0]] = kv[1];
       }
       if (!("state" in fields))
         return true;
       fields.state = supplicantStatesMap[fields.state];
 
       // The BSSID field is only valid in the ASSOCIATING and ASSOCIATED
-      // states.
-      if (fields.state === "ASSOCIATING" || fields.state == "ASSOCIATED")
+      // states, except when we "reauth", except this seems to depend on the
+      // driver, so simply check to make sure that we don't have a null BSSID.
+      if (fields.BSSID !== "00:00:00:00:00:00")
         manager.connectionInfo.bssid = fields.BSSID;
+
       notifyStateChange(fields);
       return true;
     }
     if (eventData.indexOf("CTRL-EVENT-DRIVER-STATE") === 0) {
       var handlerName = driverEventMap[eventData];
       if (handlerName)
         notify(handlerName);
       return true;
     }
     if (eventData.indexOf("CTRL-EVENT-TERMINATING") === 0) {
       // If the monitor socket is closed, we have already stopped the
       // supplicant and we can stop waiting for more events and
-      // simply exit here (we don't have to notify).
-      if (eventData.indexOf("connection closed") !== -1)
+      // simply exit here (we don't have to notify about having lost
+      // the connection).
+      if (eventData.indexOf("connection closed") !== -1) {
+        notify("supplicantlost");
         return false;
+      }
 
       // As long we haven't seen too many recv errors yet, we
       // will keep going for a bit longer
       if (eventData.indexOf("recv error") !== -1 && ++recvErrors < 10)
         return true;
 
       notifyStateChange({ state: "DISCONNECTED", BSSID: null, id: -1 });
       notify("supplicantlost");
@@ -823,16 +829,18 @@ var WifiManager = (function() {
       }
 
       // It's running, try to reconnect to it.
       connectToSupplicant(function (retval) {
         if (retval === 0) {
           // Successfully reconnected! Don't do anything else.
           debug("Successfully connected!");
 
+          manager.supplicantStarted = true;
+
           // It is important that we call parseStatus (in
           // didConnectSupplicant) before calling the callback here.
           // Otherwise, WifiManager.start will reconnect to it.
           didConnectSupplicant(true, function() { callback(true) });
           return;
         }
 
         debug("Didn't connect, trying other method.");
@@ -845,24 +853,24 @@ var WifiManager = (function() {
           });
         });
       });
     });
   }
 
   // Initial state
   manager.state = "UNINITIALIZED";
+  manager.enabled = false;
+  manager.supplicantStarted = false;
   manager.connectionInfo = { ssid: null, bssid: null, id: -1 };
-  manager.enabled = true;
 
   // Public interface of the wifi service
   manager.setWifiEnabled = function(enable, callback) {
-    if ((enable && manager.state !== "UNINITIALIZED") ||
-        (!enable && manager.state === "UNINITIALIZED")) {
-      callback(0);
+    if (enabled === manager.enabled) {
+      callback("no change");
       return;
     }
 
     if (enable) {
       // Kill any existing connections if necessary.
       getProperty("wifi.interface", "tiwlan0", function (ifname) {
         if (!ifname) {
           callback(-1);
@@ -887,25 +895,44 @@ var WifiManager = (function() {
             return;
           }
 
           loadDriver(function (status) {
             if (status < 0) {
               callback(status);
               return;
             }
-            startSupplicant(function (status) {
-              if (status < 0) {
-                callback(status);
-                return;
-              }
-              enableInterface(ifname, function (ok) {
-                callback(ok ? 0 : -1);
+
+            let timer;
+            function doStartSupplicant() {
+              timer = null;
+              startSupplicant(function (status) {
+                if (status < 0) {
+                  unloadDriver(function() {
+                    callback(status);
+                  });
+                  return;
+                }
+
+                manager.supplicantStarted = true;
+                enableInterface(ifname, function (ok) {
+                  callback(ok ? 0 : -1);
+                });
               });
-            });
+            }
+
+            // Driver startup on the otoro takes longer than it takes for us
+            // to return from loadDriver, so wait 2 seconds before starting
+            // the supplicant to give it a chance to start.
+            if (device === "otoro") {
+              timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+              timer.init(doStartSupplicant, 2000, Ci.nsITimer.TYPE_ONE_SHOT);
+            } else {
+              doStartSupplicant();
+            }
           });
         });
       });
     } else {
       // Note these following calls ignore errors. If we fail to kill the
       // supplicant gracefully, then we need to continue telling it to die
       // until it does.
       terminateSupplicant(function (ok) {
@@ -1194,16 +1221,19 @@ function WifiWorker() {
   this.configuredNetworks = Object.create(null);
 
   this.currentNetwork = null;
 
   this._lastConnectionInfo = null;
   this._connectionInfoTimer = null;
   this._reconnectOnDisconnect = false;
 
+  // A list of requests to turn wifi on or off.
+  this._stateRequests = [];
+
   // Given a connection status network, takes a network from
   // self.configuredNetworks and prepares it for the DOM.
   netToDOM = function(net) {
     var pub = { ssid: dequote(net.ssid) };
     if (net.netId)
       pub.known = true;
     return pub;
   };
@@ -1261,29 +1291,51 @@ function WifiWorker() {
       configured.auth_alg = net.auth_alg = "OPEN SHARED";
     }
 
     return net;
   };
 
   WifiManager.onsupplicantconnection = function() {
     debug("Connected to supplicant");
+    WifiManager.enabled = true;
     WifiManager.getMacAddress(function (mac) {
       debug("Got mac: " + mac);
     });
 
     self._reloadConfiguredNetworks(function(ok) {
       // Prime this.networks.
       if (!ok)
         return;
       self.waitForScan(function firstScan() {});
     });
+
+    // Check if we need to fire request replies first:
+    if (self._stateRequests.length > 0)
+      self._notifyAfterStateChange(true, true);
+
+    // Notify everybody, even if they didn't ask us to come up.
+    self._fireEvent("wifiUp", {});
   }
   WifiManager.onsupplicantlost = function() {
+    WifiManager.enabled = WifiManager.supplicantStarted = false;
     debug("Supplicant died!");
+
+    // Check if we need to fire request replies first:
+    if (self._stateRequests.length > 0)
+      self._notifyAfterStateChange(true, false);
+
+    // Notify everybody, even if they didn't ask us to come up.
+    self._fireEvent("wifiDown", {});
+  }
+  WifiManager.onsupplicantfailed = function() {
+    WifiManager.enabled = WifiManager.supplicantStarted = false;
+    debug("Couldn't connect to supplicant");
+    if (self._stateRequests.length > 0)
+      self._notifyAfterStateChange(false, false);
   }
 
   WifiManager.onstatechange = function() {
     debug("State change: " + this.prevState + " -> " + this.state);
 
     if (self._connectionInfoTimer &&
         this.state !== "CONNECTED" &&
         this.state !== "COMPLETED") {
@@ -1446,21 +1498,21 @@ function WifiWorker() {
       }
 
       self.wantScanResults.forEach(function(callback) { callback(self.networks) });
       self.wantScanResults = [];
     });
   }
 
   WifiManager.setWifiEnabled(true, function (ok) {
-      if (ok === 0)
-        WifiManager.start();
-      else
-        debug("Couldn't start Wifi");
-    });
+    if (ok === 0)
+      WifiManager.start();
+    else
+      debug("Couldn't start Wifi");
+  });
 
   debug("Wifi starting");
 }
 
 function translateState(state) {
   switch (state) {
     case "INTERFACE_DISABLED":
     case "INACTIVE":
@@ -1685,17 +1737,17 @@ WifiWorker.prototype = {
         break;
       case "WifiManager:forget":
         this.forget(msg.data, msg.rid, msg.mid);
         break;
       case "WifiManager:getState": {
         let net = this.currentNetwork ? netToDOM(this.currentNetwork) : null;
         return { network: net,
                  connectionInfo: this._lastConnectionInfo,
-                 enabled: WifiManager.state !== "UNINITIALIZED",
+                 enabled: WifiManager.enabled,
                  status: translateState(WifiManager.state) };
       }
     }
   },
 
   getNetworks: function(rid, mid) {
     const message = "WifiManager:getNetworks:Return";
     if (WifiManager.state === "UNINITIALIZED") {
@@ -1704,23 +1756,76 @@ WifiWorker.prototype = {
     }
 
     this.waitForScan((function (networks) {
       this._sendMessage(message, networks !== null, networks, rid, mid);
     }).bind(this));
     WifiManager.scan(true, function() {});
   },
 
+  _notifyAfterStateChange: function(success, newState) {
+    // First, notify all of the requests that were trying to make this change.
+    let state = this._stateRequests[0].enabled;
+
+    // If the new state is not the same as state, then we weren't processing
+    // the first request (we were racing somehow) so don't notify.
+    if (!success || state === newState) {
+      do {
+        let req = this._stateRequests.shift();
+        this._sendMessage("WifiManager:setEnabled:Return",
+                          success, state, req.rid, req.mid);
+
+        // Don't remove more than one request if the previous one failed.
+      } while (success &&
+               this._stateRequests.length &&
+               this._stateRequests[0].enabled === state);
+    }
+
+    // If there were requests queued after this one, run them.
+    if (this._stateRequests.length > 0) {
+      let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+      let self = this;
+      timer.initWithCallback(function(timer) {
+        WifiManager.setWifiEnabled(self._stateRequests[0].enabled,
+                                   self._setWifiEnabledCallback.bind(this));
+        timer = null;
+      }, 1000, Ci.nsITimer.TYPE_ONE_SHOT);
+    }
+  },
+
+  _setWifiEnabledCallback: function(status) {
+    if (status === "no change") {
+      this._notifyAfterStateChange(true, this._stateRequests[0].enabled);
+      return;
+    }
+
+    if (status) {
+      // Don't call notifyAndContinue because we don't want to skip another
+      // attempt to turn wifi on or off if this one failed.
+      this._notifyAfterStateChange(false, this._stateRequests[0].enabled);
+      return;
+    }
+
+    // If we're enabling ourselves, then wait until we've connected to the
+    // supplicant to notify. If we're disabling, we take care of this in
+    // supplicantlost.
+    if (WifiManager.supplicantStarted)
+      WifiManager.start();
+  },
+
   setWifiEnabled: function(enable, rid, mid) {
-    WifiManager.setWifiEnabled(enable, (function (status) {
-      if (enable && status === 0)
-        WifiManager.start();
-      this._sendMessage("WifiManager:setEnabled:Return",
-                        (status === 0), enable, rid, mid);
-    }).bind(this));
+    // There are two problems that we're trying to solve here:
+    //   - If we get multiple requests to turn on and off wifi before the
+    //     current request has finished, then we need to queue up the requests
+    //     and handle each on/off request in turn.
+    //   - Because we can't pass a callback to WifiManager.start, we need to
+    //     have a way to communicate with our onsupplicantconnection callback.
+    this._stateRequests.push({ enabled: enable, rid: rid, mid: mid });
+    if (this._stateRequests.length === 1)
+      WifiManager.setWifiEnabled(enable, this._setWifiEnabledCallback.bind(this));
   },
 
   associate: function(network, rid, mid) {
     const MAX_PRIORITY = 9999;
     const message = "WifiManager:associate:Return";
     if (WifiManager.state === "UNINITIALIZED") {
       this._sendMessage(message, false, "Wifi is disabled", rid, mid);
       return;
--- a/dom/wifi/nsIWifi.idl
+++ b/dom/wifi/nsIWifi.idl
@@ -12,17 +12,17 @@ interface nsIVariant;
 interface nsIWifi : nsISupports
 {
     /**
      * Shutdown the wifi system.
      */
     void shutdown();
 };
 
-[scriptable, uuid(e3d5a7d7-6abd-4ac2-83dc-5315ec08a1c3)]
+[scriptable, uuid(eda793cd-0bb3-475e-9223-0e778856ebd1)]
 interface nsIDOMWifiManager : nsISupports
 {
     /**
      * TODO Remove in favor of a settings API.
      * Activates or disactivates wifi.
      * onsuccess: Wifi has been successfully activated and can start
      *            attempting to connect to networks. request.value will be true.
      * onerror: Wifi was not successfully activated. (TODO provide details!)
@@ -106,16 +106,23 @@ interface nsIDOMWifiManager : nsISupport
      */
     attribute nsIDOMEventListener onstatuschange;
 
     /**
      * An event listener that is called with information about the signal
      * strength and link speed every 5 seconds.
      */
     attribute nsIDOMEventListener connectionInfoUpdate;
+
+    /**
+     * These two events fire when the wifi system is brought online or taken
+     * offline.
+     */
+    attribute nsIDOMEventListener onenabled;
+    attribute nsIDOMEventListener ondisabled;
 };
 
 [scriptable, builtinclass, uuid(ba1dab70-b70d-11e1-afa6-0800200c9a66)]
 interface nsIDOMMozWifiStatusChangeEvent : nsIDOMEvent
 {
     /**
      * Network object with a SSID field describing the network affected by
      * this change. This might be null.
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -1228,17 +1228,17 @@ public:
       else {
         NS_WARNING("Failed to log script error!");
       }
     }
 
     if (!logged) {
       NS_ConvertUTF16toUTF8 msg(aMessage);
 #ifdef ANDROID
-      __android_log_print(ANDROID_LOG_INFO, "Gecko", msg.get());
+      __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", msg.get());
 #endif
       fputs(msg.get(), stderr);
       fflush(stderr);
     }
 
     return true;
   }
 };
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -537,17 +537,17 @@ private:
       }
 
       JSAutoByteString buffer(aCx, str);
       if (!buffer) {
         return false;
       }
 
 #ifdef ANDROID
-      __android_log_print(ANDROID_LOG_INFO, "Gecko", buffer.ptr());
+      __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", buffer.ptr());
 #endif
       fputs(buffer.ptr(), stdout);
       fflush(stdout);
     }
 
     return true;
   }
 
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -1142,19 +1142,19 @@ public:
     mBody.swap(aBody);
     mClonedObjects.SwapElements(aClonedObjects);
   }
 
   nsresult
   MainThreadRun()
   {
     nsCOMPtr<nsIVariant> variant;
-    RuntimeService::AutoSafeJSContext cx;
 
     if (mBody.data()) {
+      RuntimeService::AutoSafeJSContext cx;
       nsIXPConnect* xpc = nsContentUtils::XPConnect();
       NS_ASSERTION(xpc, "This should never be null!");
 
       nsresult rv = NS_OK;
 
       JSStructuredCloneCallbacks* callbacks =
         mWorkerPrivate->IsChromeWorker() ?
         ChromeWorkerStructuredCloneCallbacks(true) :
--- a/gfx/thebes/gfxGDIFontList.cpp
+++ b/gfx/thebes/gfxGDIFontList.cpp
@@ -744,34 +744,37 @@ gfxGDIFontList::LookupLocalFont(const gf
 
     // lookup in name lookup tables, return null if not found
     if (!(lookup = mPostscriptNames.GetWeak(aFullname)) &&
         !(lookup = mFullnames.GetWeak(aFullname))) 
     {
         return nsnull;
     }
 
-    // create a new font entry with the proxy entry style characteristics
-    PRUint16 w = (aProxyEntry->mWeight == 0 ? 400 : aProxyEntry->mWeight);
     bool isCFF = false; // jtdfix -- need to determine this
     
     // use the face name from the lookup font entry, which will be the localized
     // face name which GDI mapping tables use (e.g. with the system locale set to
     // Dutch, a fullname of 'Arial Bold' will find a font entry with the face name
     // 'Arial Vet' which can be used as a key in GDI font lookups).
-    gfxFontEntry *fe = GDIFontEntry::CreateFontEntry(lookup->Name(), 
+    GDIFontEntry *fe = GDIFontEntry::CreateFontEntry(lookup->Name(), 
         gfxWindowsFontType(isCFF ? GFX_FONT_TYPE_PS_OPENTYPE : GFX_FONT_TYPE_TRUETYPE) /*type*/, 
-        PRUint32(aProxyEntry->mItalic ? NS_FONT_STYLE_ITALIC : NS_FONT_STYLE_NORMAL), 
-        w, aProxyEntry->mStretch, nsnull);
+        lookup->mItalic ? NS_FONT_STYLE_ITALIC : NS_FONT_STYLE_NORMAL,
+        lookup->mWeight, aProxyEntry->mStretch, nsnull);
         
     if (!fe)
         return nsnull;
 
     fe->mIsUserFont = true;
     fe->mIsLocalUserFont = true;
+
+    // make the new font entry match the proxy entry style characteristics
+    fe->mWeight = (aProxyEntry->mWeight == 0 ? 400 : aProxyEntry->mWeight);
+    fe->mItalic = aProxyEntry->mItalic;
+
     return fe;
 }
 
 void gfxGDIFontList::InitializeFontEmbeddingProcs()
 {
     static HMODULE fontlib = LoadLibraryW(L"t2embed.dll");
     if (!fontlib)
         return;
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -875,30 +875,16 @@ FullTrustSecMan::GetCxSubjectPrincipal(J
 NS_IMETHODIMP_(nsIPrincipal *)
 FullTrustSecMan::GetCxSubjectPrincipalAndFrame(JSContext *cx,
                                                JSStackFrame **fp)
 {
     *fp = nsnull;
     return mSystemPrincipal;
 }
 
-NS_IMETHODIMP
-FullTrustSecMan::PushContextPrincipal(JSContext *cx,
-                                      JSStackFrame *fp,
-                                      nsIPrincipal *principal)
-{
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-FullTrustSecMan::PopContextPrincipal(JSContext *cx)
-{
-    return NS_OK;
-}
-
 NS_IMETHODIMP_(nsrefcnt)
 XPCShellDirProvider::AddRef()
 {
     return 2;
 }
 
 NS_IMETHODIMP_(nsrefcnt)
 XPCShellDirProvider::Release()
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1660,26 +1660,16 @@ typedef JSPrincipals *
 /*
  * Used to check if a CSP instance wants to disable eval() and friends.
  * See js_CheckCSPPermitsJSAction() in jsobj.
  */
 typedef JSBool
 (* JSCSPEvalChecker)(JSContext *cx);
 
 /*
- * Security callbacks for pushing and popping context principals. These are only
- * temporarily necessary and will hopefully be gone again in a matter of weeks.
- */
-typedef JSBool
-(* JSPushContextPrincipalOp)(JSContext *cx, JSPrincipals *principals);
-
-typedef JSBool
-(* JSPopContextPrincipalOp)(JSContext *cx);
-
-/*
  * Callback used to ask the embedding for the cross compartment wrapper handler
  * that implements the desired prolicy for this kind of object in the
  * destination compartment.
  */
 typedef JSObject *
 (* JSWrapObjectCallback)(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent,
                          unsigned flags);
 
@@ -4338,18 +4328,16 @@ JS_HoldPrincipals(JSPrincipals *principa
 extern JS_PUBLIC_API(void)
 JS_DropPrincipals(JSRuntime *rt, JSPrincipals *principals);
 
 struct JSSecurityCallbacks {
     JSCheckAccessOp            checkObjectAccess;
     JSSubsumePrincipalsOp      subsumePrincipals;
     JSObjectPrincipalsFinder   findObjectPrincipals;
     JSCSPEvalChecker           contentSecurityPolicyAllows;
-    JSPushContextPrincipalOp   pushContextPrincipal;
-    JSPopContextPrincipalOp    popContextPrincipal;
 };
 
 extern JS_PUBLIC_API(void)
 JS_SetSecurityCallbacks(JSRuntime *rt, const JSSecurityCallbacks *callbacks);
 
 extern JS_PUBLIC_API(const JSSecurityCallbacks *)
 JS_GetSecurityCallbacks(JSRuntime *rt);
 
--- a/js/src/jsclone.cpp
+++ b/js/src/jsclone.cpp
@@ -467,47 +467,16 @@ JSStructuredCloneWriter::startObject(JSO
     if (!objs.append(ObjectValue(*obj)) || !counts.append(count))
         return false;
     checkStack();
 
     /* Write the header for obj. */
     return out.writePair(obj->isArray() ? SCTAG_ARRAY_OBJECT : SCTAG_OBJECT_OBJECT, 0);
 }
 
-class AutoEnterCompartmentAndPushPrincipal : public JSAutoEnterCompartment
-{
-  public:
-    bool enter(JSContext *cx, JSObject *target) {
-        // First, enter the compartment.
-        if (!JSAutoEnterCompartment::enter(cx, target))
-            return false;
-
-        // We only need to push a principal if we changed compartments.
-        if (state != STATE_OTHER_COMPARTMENT)
-            return true;
-
-        // Push.
-        const JSSecurityCallbacks *cb = cx->runtime->securityCallbacks;
-        if (cb->pushContextPrincipal)
-          return cb->pushContextPrincipal(cx, target->principals(cx));
-        return true;
-    }
-
-    ~AutoEnterCompartmentAndPushPrincipal() {
-        // Pop the principal if necessary.
-        if (state == STATE_OTHER_COMPARTMENT) {
-            AutoCompartment *ac = getAutoCompartment();
-            const JSSecurityCallbacks *cb = ac->context->runtime->securityCallbacks;
-            if (cb->popContextPrincipal)
-              cb->popContextPrincipal(ac->context);
-        }
-    }
-};
-
-
 bool
 JSStructuredCloneWriter::startWrite(const Value &v)
 {
     assertSameCompartment(context(), v);
 
     if (v.isString()) {
         return writeString(SCTAG_STRING, v.toString());
     } else if (v.isNumber()) {
@@ -524,17 +493,17 @@ JSStructuredCloneWriter::startWrite(cons
         // The object might be a security wrapper. See if we can clone what's
         // behind it. If we can, unwrap the object.
         obj = UnwrapObjectChecked(context(), obj);
         if (!obj)
             return false;
 
         // If we unwrapped above, we'll need to enter the underlying compartment.
         // Let the AutoEnterCompartment do the right thing for us.
-        AutoEnterCompartmentAndPushPrincipal ac;
+        JSAutoEnterCompartment ac;
         if (!ac.enter(context(), obj))
             return false;
 
         if (obj->isRegExp()) {
             RegExpObject &reobj = obj->asRegExp();
             return out.writePair(SCTAG_REGEXP_OBJECT, reobj.getFlags()) &&
                    writeString(SCTAG_STRING, reobj.getSource());
         } else if (obj->isDate()) {
@@ -569,17 +538,17 @@ JSStructuredCloneWriter::write(const Val
 {
     if (!startWrite(v))
         return false;
 
     while (!counts.empty()) {
         RootedObject obj(context(), &objs.back().toObject());
 
         // The objects in |obj| can live in other compartments.
-        AutoEnterCompartmentAndPushPrincipal ac;
+        JSAutoEnterCompartment ac;
         if (!ac.enter(context(), obj))
             return false;
 
         if (counts.back()) {
             counts.back()--;
             RootedId id(context(), ids.back());
             ids.popBack();
             checkStack();
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -908,27 +908,26 @@ inline InterpreterFrames::InterpreterFra
 
 inline InterpreterFrames::~InterpreterFrames()
 {
     context->runtime->interpreterFrames = older;
 }
 
 #if defined(DEBUG) && !defined(JS_THREADSAFE) && !defined(JSGC_ROOT_ANALYSIS)
 void
-js::AssertValidPropertyCacheHit(JSContext *cx,
-                                JSObject *start_, JSObject *found,
-                                PropertyCacheEntry *entry)
+js::AssertValidPropertyCacheHit(JSContext *cx, JSObject *start_,
+                                JSObject *found, PropertyCacheEntry *entry)
 {
     jsbytecode *pc;
-    cx->stack.currentScript(&pc);
+    JSScript *script = cx->stack.currentScript(&pc);
 
     uint64_t sample = cx->runtime->gcNumber;
     PropertyCacheEntry savedEntry = *entry;
 
-    RootedPropertyName name(cx, GetNameFromBytecode(cx, pc, JSOp(*pc)));
+    RootedPropertyName name(cx, GetNameFromBytecode(cx, script, pc, JSOp(*pc)));
     RootedObject start(cx, start_);
 
     JSObject *obj, *pobj;
     JSProperty *prop;
     JSBool ok;
 
     if (JOF_OPMODE(*pc) == JOF_NAME)
         ok = FindProperty(cx, name, start, &obj, &pobj, &prop);
@@ -2325,17 +2324,17 @@ BEGIN_CASE(JSOP_THIS)
 END_CASE(JSOP_THIS)
 
 BEGIN_CASE(JSOP_GETPROP)
 BEGIN_CASE(JSOP_GETXPROP)
 BEGIN_CASE(JSOP_LENGTH)
 BEGIN_CASE(JSOP_CALLPROP)
 {
     RootedValue rval(cx);
-    if (!GetPropertyOperation(cx, regs.pc, regs.sp[-1], rval.address()))
+    if (!GetPropertyOperation(cx, script, regs.pc, regs.sp[-1], rval.address()))
         goto error;
 
     TypeScript::Monitor(cx, script, regs.pc, rval.reference());
 
     regs.sp[-1] = rval;
     assertSameCompartment(cx, regs.sp[-1]);
 }
 END_CASE(JSOP_GETPROP)
@@ -2537,17 +2536,17 @@ END_CASE(JSOP_IMPLICITTHIS)
 
 BEGIN_CASE(JSOP_GETGNAME)
 BEGIN_CASE(JSOP_CALLGNAME)
 BEGIN_CASE(JSOP_NAME)
 BEGIN_CASE(JSOP_CALLNAME)
 {
     RootedValue &rval = rootValue0;
 
-    if (!NameOperation(cx, regs.pc, rval.address()))
+    if (!NameOperation(cx, script, regs.pc, rval.address()))
         goto error;
 
     PUSH_COPY(rval);
     TypeScript::Monitor(cx, script, regs.pc, rval);
 }
 END_CASE(JSOP_NAME)
 
 BEGIN_CASE(JSOP_UINT16)
--- a/js/src/jsinterpinlines.h
+++ b/js/src/jsinterpinlines.h
@@ -161,17 +161,18 @@ GetPropertyGenericMaybeCallXML(JSContext
     if (op == JSOP_CALLPROP && obj->isXML())
         return js_GetXMLMethod(cx, obj, id, vp);
 #endif
 
     return obj->getGeneric(cx, id, vp);
 }
 
 inline bool
-GetPropertyOperation(JSContext *cx, jsbytecode *pc, const Value &lval, Value *vp)
+GetPropertyOperation(JSContext *cx, JSScript *script, jsbytecode *pc,
+                     const Value &lval, Value *vp)
 {
     JS_ASSERT(vp != &lval);
 
     JSOp op = JSOp(*pc);
 
     if (op == JSOP_LENGTH) {
         /* Optimize length accesses on strings, arrays, and arguments. */
         if (lval.isString()) {
@@ -315,17 +316,17 @@ SetPropertyOperation(JSContext *cx, jsby
         if (!obj->setGeneric(cx, id, rref.address(), strict))
             return false;
     }
 
     return true;
 }
 
 inline bool
-NameOperation(JSContext *cx, jsbytecode *pc, Value *vp)
+NameOperation(JSContext *cx, JSScript *script, jsbytecode *pc, Value *vp)
 {
     RootedObject obj(cx, cx->stack.currentScriptedScopeChain());
 
     /*
      * Skip along the scope chain to the enclosing global object. This is
      * used for GNAME opcodes where the bytecode emitter has determined a
      * name access must be on the global. It also insulates us from bugs
      * in the emitter: type inference will assume that GNAME opcodes are
--- a/js/src/jsopcodeinlines.h
+++ b/js/src/jsopcodeinlines.h
@@ -6,27 +6,26 @@
 
 #include "jsautooplen.h"
 
 #include "frontend/BytecodeEmitter.h"
 
 namespace js {
 
 static inline PropertyName *
-GetNameFromBytecode(JSContext *cx, jsbytecode *pc, JSOp op)
+GetNameFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc, JSOp op)
 {
     if (op == JSOP_LENGTH)
         return cx->runtime->atomState.lengthAtom;
 
     // The method JIT's implementation of instanceof contains an internal lookup
     // of the prototype property.
     if (op == JSOP_INSTANCEOF)
         return cx->runtime->atomState.classPrototypeAtom;
 
-    JSScript *script = cx->stack.currentScriptWithDiagnostics();
     PropertyName *name;
     GET_NAME_FROM_BYTECODE(script, pc, 0, name);
     return name;
 }
 
 class BytecodeRange {
   public:
     BytecodeRange(JSScript *script)
--- a/js/src/jspropertycache.cpp
+++ b/js/src/jspropertycache.cpp
@@ -117,32 +117,30 @@ PropertyCache::fill(JSContext *cx, JSObj
     return entry;
 }
 
 PropertyName *
 PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject **pobjp,
                         PropertyCacheEntry *entry)
 {
     JSObject *obj, *pobj, *tmp;
-#ifdef DEBUG
     JSScript *script = cx->stack.currentScript();
-#endif
 
     JS_ASSERT(this == &JS_PROPERTY_CACHE(cx));
     JS_ASSERT(uint32_t(pc - script->code) < script->length);
 
     JSOp op = JSOp(*pc);
     const JSCodeSpec &cs = js_CodeSpec[op];
 
     obj = *objp;
 
     if (entry->kpc != pc) {
         PCMETER(kpcmisses++);
 
-        PropertyName *name = GetNameFromBytecode(cx, pc, op);
+        PropertyName *name = GetNameFromBytecode(cx, script, pc, op);
 #ifdef DEBUG_notme
         JSAutoByteString printable;
         fprintf(stderr,
                 "id miss for %s from %s:%u"
                 " (pc %u, kpc %u, kshape %p, shape %p)\n",
                 js_AtomToPrintableString(cx, name, &printable),
                 script->filename,
                 js_PCToLineNumber(cx, script, pc),
@@ -155,17 +153,17 @@ PropertyCache::fullTest(JSContext *cx, j
                                 JS_FALSE, stderr);
 #endif
 
         return name;
     }
 
     if (entry->kshape != obj->lastProperty()) {
         PCMETER(kshapemisses++);
-        return GetNameFromBytecode(cx, pc, op);
+        return GetNameFromBytecode(cx, script, pc, op);
     }
 
     /*
      * PropertyCache::test handles only the direct and immediate-prototype hit
      * cases. All others go here.
      */
     pobj = obj;
 
@@ -188,25 +186,25 @@ PropertyCache::fullTest(JSContext *cx, j
         if (!tmp || !tmp->isNative())
             break;
         pobj = tmp;
         protoIndex--;
     }
 
     if (pobj->lastProperty() == entry->pshape) {
 #ifdef DEBUG
-        PropertyName *name = GetNameFromBytecode(cx, pc, op);
+        PropertyName *name = GetNameFromBytecode(cx, script, pc, op);
         JS_ASSERT(pobj->nativeContains(cx, NameToId(name)));
 #endif
         *pobjp = pobj;
         return NULL;
     }
 
     PCMETER(vcapmisses++);
-    return GetNameFromBytecode(cx, pc, op);
+    return GetNameFromBytecode(cx, script, pc, op);
 }
 
 #ifdef DEBUG
 void
 PropertyCache::assertEmpty()
 {
     JS_ASSERT(empty);
     for (unsigned i = 0; i < SIZE; i++) {
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -19,17 +19,17 @@ class Wrapper;
 class JS_FRIEND_API(BaseProxyHandler) {
     void *mFamily;
   public:
     explicit BaseProxyHandler(void *family);
     virtual ~BaseProxyHandler();
 
     inline void *family() {
         return mFamily;
-    };
+    }
 
     virtual bool isOuterWindow() {
         return false;
     }
 
     /*
      * The function Wrapper::wrapperHandler takes a pointer to a
      * BaseProxyHandler and returns a pointer to a Wrapper if and only if the
--- a/js/src/methodjit/PolyIC.cpp
+++ b/js/src/methodjit/PolyIC.cpp
@@ -1919,17 +1919,17 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic
     if (!monitor.recompiled() && pic->shouldUpdate(f.cx)) {
         GetPropCompiler cc(f, script, obj, *pic, name, stub);
         if (!cc.update())
             THROW();
     }
 
     Value v;
     if (cached) {
-        if (!GetPropertyOperation(f.cx, f.pc(), f.regs.sp[-1], &v))
+        if (!GetPropertyOperation(f.cx, f.script(), f.pc(), f.regs.sp[-1], &v))
             THROW();
     } else {
         if (!obj->getProperty(f.cx, name, &v))
             THROW();
     }
 
     f.regs.sp[-1] = v;
 }
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -93,17 +93,17 @@ stubs::SetGlobalName(VMFrame &f, Propert
 
 template void JS_FASTCALL stubs::SetGlobalName<true>(VMFrame &f, PropertyName *name);
 template void JS_FASTCALL stubs::SetGlobalName<false>(VMFrame &f, PropertyName *name);
 
 void JS_FASTCALL
 stubs::Name(VMFrame &f)
 {
     Value rval;
-    if (!NameOperation(f.cx, f.pc(), &rval))
+    if (!NameOperation(f.cx, f.script(), f.pc(), &rval))
         THROW();
     f.regs.sp[0] = rval;
 }
 
 void JS_FASTCALL
 stubs::GetElem(VMFrame &f)
 {
     Value &lref = f.regs.sp[-2];
@@ -975,17 +975,17 @@ stubs::Lambda(VMFrame &f, JSFunction *fu
 
 void JS_FASTCALL
 stubs::GetProp(VMFrame &f, PropertyName *name)
 {
     JSContext *cx = f.cx;
     FrameRegs &regs = f.regs;
 
     Value rval;
-    if (!GetPropertyOperation(cx, f.pc(), f.regs.sp[-1], &rval))
+    if (!GetPropertyOperation(cx, f.script(), f.pc(), f.regs.sp[-1], &rval))
         THROW();
 
     regs.sp[-1] = rval;
 }
 
 void JS_FASTCALL
 stubs::GetPropNoCache(VMFrame &f, PropertyName *name)
 {
--- a/js/src/vm/Stack-inl.h
+++ b/js/src/vm/Stack-inl.h
@@ -552,55 +552,16 @@ ContextStack::currentScript(jsbytecode *
     if (script->compartment() != cx_->compartment)
         return NULL;
 
     if (ppc)
         *ppc = fp->pcQuadratic(*this);
     return script;
 }
 
-inline JSScript *
-ContextStack::currentScriptWithDiagnostics(jsbytecode **ppc) const
-{
-    if (ppc)
-        *ppc = NULL;
-
-    FrameRegs *regs = maybeRegs();
-    StackFrame *fp = regs ? regs->fp() : NULL;
-    while (fp && fp->isDummyFrame())
-        fp = fp->prev();
-    if (!fp)
-        *(int *) 0x10 = 0;
-
-#ifdef JS_METHODJIT
-    mjit::CallSite *inlined = regs->inlined();
-    if (inlined) {
-        mjit::JITChunk *chunk = fp->jit()->chunk(regs->pc);
-        JS_ASSERT(inlined->inlineIndex < chunk->nInlineFrames);
-        mjit::InlineFrame *frame = &chunk->inlineFrames()[inlined->inlineIndex];
-        JSScript *script = frame->fun->script();
-        if (script->compartment() != cx_->compartment)
-            *(int *) 0x20 = 0;
-        if (ppc)
-            *ppc = script->code + inlined->pcOffset;
-        return script;
-    }
-#endif
-
-    JSScript *script = fp->script();
-    if (script->compartment() != cx_->compartment)
-        *(int *) 0x30 = 0;
-
-    if (ppc)
-        *ppc = fp->pcQuadratic(*this);
-    if (!script)
-        *(int *) 0x40 = 0;
-    return script;
-}
-
 inline HandleObject
 ContextStack::currentScriptedScopeChain() const
 {
     return fp()->scopeChain();
 }
 
 } /* namespace js */
 #endif /* Stack_inl_h__ */
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -1655,17 +1655,16 @@ class ContextStack
                          InitialFrameFlags initial, Value **stackLimit);
     void popInlineFrame(FrameRegs &regs);
 
     /* Pop a partially-pushed frame after hitting the limit before throwing. */
     void popFrameAfterOverflow();
 
     /* Get the topmost script and optional pc on the stack. */
     inline JSScript *currentScript(jsbytecode **pc = NULL) const;
-    inline JSScript *currentScriptWithDiagnostics(jsbytecode **pc = NULL) const;
 
     /* Get the scope chain for the topmost scripted call on the stack. */
     inline HandleObject currentScriptedScopeChain() const;
 
     /*
      * Called by the methodjit for an arity mismatch. Arity mismatch can be
      * hot, so getFixupFrame avoids doing call setup performed by jit code when
      * FixupArity returns.
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -171,17 +171,17 @@ Dump(JSContext *cx, unsigned argc, jsval
 
     size_t length;
     const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length);
     if (!chars)
         return false;
 
     NS_ConvertUTF16toUTF8 utf8str(reinterpret_cast<const PRUnichar*>(chars));
 #ifdef ANDROID
-    __android_log_print(ANDROID_LOG_INFO, "Gecko", utf8str.get());
+    __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", utf8str.get());
 #endif
     fputs(utf8str.get(), stdout);
     fflush(stdout);
     return true;
 }
 
 static JSBool
 Debug(JSContext *cx, unsigned argc, jsval *vp)
--- a/js/xpconnect/shell/xpcshell.cpp
+++ b/js/xpconnect/shell/xpcshell.cpp
@@ -418,17 +418,17 @@ Dump(JSContext *cx, unsigned argc, jsval
     if (!str)
         return false;
 
     JSAutoByteString bytes(cx, str);
     if (!bytes)
         return false;
 
 #ifdef ANDROID
-    __android_log_print(ANDROID_LOG_INFO, "Gecko", bytes.ptr());
+    __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", bytes.ptr());
 #endif
     fputs(bytes.ptr(), gOutFile);
     fflush(gOutFile);
     return true;
 }
 
 static JSBool
 Load(JSContext *cx, unsigned argc, jsval *vp)
@@ -1376,30 +1376,16 @@ FullTrustSecMan::CanExecuteScripts(JSCon
 /* [noscript] nsIPrincipal getSubjectPrincipal (); */
 NS_IMETHODIMP
 FullTrustSecMan::GetSubjectPrincipal(nsIPrincipal **_retval)
 {
     NS_IF_ADDREF(*_retval = mSystemPrincipal);
     return *_retval ? NS_OK : NS_ERROR_FAILURE;
 }
 
-/* [noscript] void pushContextPrincipal (in JSContextPtr cx, in JSStackFramePtr fp, in nsIPrincipal principal); */
-NS_IMETHODIMP
-FullTrustSecMan::PushContextPrincipal(JSContext * cx, JSStackFrame * fp, nsIPrincipal *principal)
-{
-    return NS_OK;
-}
-
-/* [noscript] void popContextPrincipal (in JSContextPtr cx); */
-NS_IMETHODIMP
-FullTrustSecMan::PopContextPrincipal(JSContext * cx)
-{
-    return NS_OK;
-}
-
 /* [noscript] nsIPrincipal getSystemPrincipal (); */
 NS_IMETHODIMP
 FullTrustSecMan::GetSystemPrincipal(nsIPrincipal **_retval)
 {
     NS_IF_ADDREF(*_retval = mSystemPrincipal);
     return *_retval ? NS_OK : NS_ERROR_FAILURE;
 }
 
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -1107,27 +1107,16 @@ nsXPCWrappedJSClass::CheckForException(X
         // see if JS code signaled failure result without throwing exception
         if (NS_FAILED(pending_result)) {
             return pending_result;
         }
     }
     return NS_ERROR_FAILURE;
 }
 
-class ContextPrincipalGuard
-{
-    nsIScriptSecurityManager *ssm;
-    XPCCallContext &ccx;
-  public:
-    ContextPrincipalGuard(XPCCallContext &ccx)
-      : ssm(nsnull), ccx(ccx) {}
-    void principalPushed(nsIScriptSecurityManager *ssm) { this->ssm = ssm; }
-    ~ContextPrincipalGuard() { if (ssm) ssm->PopContextPrincipal(ccx); }
-};
-
 NS_IMETHODIMP
 nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex,
                                 const XPTMethodDescriptor* info,
                                 nsXPTCMiniVariant* nativeParams)
 {
     jsval* sp = nsnull;
     jsval* argv = nsnull;
     uint8_t i;
@@ -1161,53 +1150,29 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
     JSAutoEnterCompartment ac;
     if (!ac.enter(cx, obj))
         return NS_ERROR_FAILURE;
 
     ccx.SetScopeForNewJSObjects(obj);
 
     JS::AutoValueVector args(cx);
     AutoScriptEvaluate scriptEval(cx);
-    ContextPrincipalGuard principalGuard(ccx);
 
     // XXX ASSUMES that retval is last arg. The xpidl compiler ensures this.
     uint8_t paramCount = info->num_args;
     uint8_t argc = paramCount -
         (paramCount && XPT_PD_IS_RETVAL(info->params[paramCount-1].flags) ? 1 : 0);
 
     if (!scriptEval.StartEvaluating(obj, xpcWrappedJSErrorReporter))
         goto pre_call_clean_up;
 
     xpcc->SetPendingResult(pending_result);
     xpcc->SetException(nsnull);
     XPCJSRuntime::Get()->SetPendingException(nsnull);
 
-    // This scoping is necessary due to the gotos here. Ugh.
-    {
-        // TODO Remove me in favor of security wrappers.
-        nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
-        if (ssm) {
-            nsIPrincipal *objPrincipal =
-                xpc::AccessCheck::getPrincipal(js::GetObjectCompartment(obj));
-            if (objPrincipal) {
-                JSStackFrame* fp = nsnull;
-                nsresult rv =
-                    ssm->PushContextPrincipal(ccx, JS_FrameIterator(ccx, &fp),
-                                              objPrincipal);
-                if (NS_FAILED(rv)) {
-                    JS_ReportOutOfMemory(ccx);
-                    retval = NS_ERROR_OUT_OF_MEMORY;
-                    goto pre_call_clean_up;
-                }
-
-                principalGuard.principalPushed(ssm);
-            }
-        }
-    }
-
     // We use js_Invoke so that the gcthings we use as args will be rooted by
     // the engine as we do conversions and prepare to do the function call.
 
     // setup stack
 
     // if this isn't a function call then we don't need to push extra stuff
     if (!(XPT_MD_IS_SETTER(info->flags) || XPT_MD_IS_GETTER(info->flags))) {
         // We get fval before allocating the stack to avoid gc badness that can
--- a/js/xpconnect/wrappers/CrossOriginWrapper.cpp
+++ b/js/xpconnect/wrappers/CrossOriginWrapper.cpp
@@ -10,25 +10,17 @@
 #include "XPCWrapper.h"
 
 #include "CrossOriginWrapper.h"
 #include "AccessCheck.h"
 #include "WrapperFactory.h"
 
 namespace xpc {
 
-NoWaiverWrapper::NoWaiverWrapper(unsigned flags) : js::CrossCompartmentWrapper(flags)
-{
-}
-
-NoWaiverWrapper::~NoWaiverWrapper()
-{
-}
-
-CrossOriginWrapper::CrossOriginWrapper(unsigned flags) : NoWaiverWrapper(flags)
+CrossOriginWrapper::CrossOriginWrapper(unsigned flags) : js::CrossCompartmentWrapper(flags)
 {
 }
 
 CrossOriginWrapper::~CrossOriginWrapper()
 {
 }
 
 bool
@@ -65,41 +57,9 @@ CrossOriginWrapper::call(JSContext *cx, 
 bool
 CrossOriginWrapper::construct(JSContext *cx, JSObject *wrapper,
                               unsigned argc, js::Value *argv, js::Value *rval)
 {
     return CrossCompartmentWrapper::construct(cx, wrapper, argc, argv, rval) &&
            WrapperFactory::WaiveXrayAndWrap(cx, rval);
 }
 
-bool
-NoWaiverWrapper::enter(JSContext *cx, JSObject *wrapper, jsid id, Action act, bool *bp)
-{
-    *bp = true; // always allowed
-    nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
-    if (!ssm) {
-        return true;
-    }
-
-    // Note: By the time enter is called here, CrossCompartmentWrapper has
-    // already pushed the fake stack frame onto cx. Because of this, the frame
-    // that we're clamping is the one that we want (the one in our compartment).
-    JSStackFrame *fp = NULL;
-    nsIPrincipal *principal = GetCompartmentPrincipal(js::GetObjectCompartment(wrappedObject(wrapper)));
-    nsresult rv = ssm->PushContextPrincipal(cx, JS_FrameIterator(cx, &fp), principal);
-    if (NS_FAILED(rv)) {
-        NS_WARNING("Not allowing call because we're out of memory");
-        JS_ReportOutOfMemory(cx);
-        return false;
-    }
-    return true;
 }
-
-void
-NoWaiverWrapper::leave(JSContext *cx, JSObject *wrapper)
-{
-    nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
-    if (ssm) {
-        ssm->PopContextPrincipal(cx);
-    }
-}
-
-}
--- a/js/xpconnect/wrappers/CrossOriginWrapper.h
+++ b/js/xpconnect/wrappers/CrossOriginWrapper.h
@@ -10,28 +10,17 @@
 
 #include "mozilla/Attributes.h"
 
 #include "jsapi.h"
 #include "jswrapper.h"
 
 namespace xpc {
 
-class NoWaiverWrapper : public js::CrossCompartmentWrapper {
-  public:
-    NoWaiverWrapper(unsigned flags);
-    virtual ~NoWaiverWrapper();
-
-    virtual bool enter(JSContext *cx, JSObject *wrapper, jsid id, Action act, bool *bp) MOZ_OVERRIDE;
-    virtual void leave(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE;
-
-    static NoWaiverWrapper singleton;
-};
-
-class CrossOriginWrapper : public NoWaiverWrapper {
+class CrossOriginWrapper : public js::CrossCompartmentWrapper {
   public:
     CrossOriginWrapper(unsigned flags);
     virtual ~CrossOriginWrapper();
 
     virtual bool getPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id,
                                        bool set, js::PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id,
                                           bool set, js::PropertyDescriptor *desc) MOZ_OVERRIDE;
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -26,23 +26,16 @@ namespace xpc {
 // .wrappedJSObject, we want it to cross the membrane into the
 // chrome compartment without automatically being wrapped into an
 // X-ray wrapper. We achieve this by wrapping it into a special
 // transparent wrapper in the origin (non-chrome) compartment. When
 // an object with that special wrapper applied crosses into chrome,
 // we know to not apply an X-ray wrapper.
 DirectWrapper WaiveXrayWrapperWrapper(WrapperFactory::WAIVE_XRAY_WRAPPER_FLAG);
 
-// Objects that haven't been explicitly waived, but have been exposed
-// to chrome don't want a CrossOriginWrapper, since that deeply-waives
-// but need the transparent behavior of a CrossOriginWrapper. The
-// NoWaiverWrapper is like a CrossOriginWrapper that can also hand out
-// XrayWrappers as return values.
-NoWaiverWrapper NoWaiverWrapper::singleton(0);
-
 // When objects for which we waived the X-ray wrapper cross into
 // chrome, we wrap them into a special cross-compartment wrapper
 // that transitively extends the waiver to all properties we get
 // off it.
 CrossOriginWrapper CrossOriginWrapper::singleton(0);
 
 static JSObject *
 GetCurrentOuter(JSContext *cx, JSObject *obj)
@@ -336,17 +329,17 @@ WrapperFactory::Rewrap(JSContext *cx, JS
                     wrapper = &XrayDOM::singleton;
                 } else if (type == XrayForDOMProxyObject) {
                     wrapper = &XrayProxy::singleton;
                 } else if (type == XrayForWrappedNative) {
                     typedef XrayWrapper<CrossCompartmentWrapper> Xray;
                     usingXray = true;
                     wrapper = &Xray::singleton;
                 } else {
-                    wrapper = &NoWaiverWrapper::singleton;
+                    wrapper = &CrossCompartmentWrapper::singleton;
                 }
             }
         }
     } else if (AccessCheck::isChrome(origin)) {
         JSFunction *fun = JS_GetObjectFunction(obj);
         if (fun) {
             if (JS_IsBuiltinEvalFunction(fun) || JS_IsBuiltinFunctionConstructor(fun)) {
                 JS_ReportError(cx, "Not allowed to access chrome eval or Function from content");
--- a/layout/base/nsDisplayItemTypes.h
+++ b/layout/base/nsDisplayItemTypes.h
@@ -51,17 +51,17 @@ enum Type {
   TYPE_PRINT_PLUGIN,
   TYPE_REMOTE,
   TYPE_REMOTE_SHADOW,
   TYPE_SCROLL_LAYER,
   TYPE_SCROLL_INFO_LAYER,
   TYPE_SELECTION_OVERLAY,
   TYPE_SOLID_COLOR,
   TYPE_SVG_EFFECTS,
-  TYPE_SVG_EVENT_RECEIVER,
+  TYPE_SVG_OUTER_SVG,
   TYPE_TABLE_CELL_BACKGROUND,
   TYPE_TABLE_CELL_SELECTION,
   TYPE_TABLE_ROW_BACKGROUND,
   TYPE_TABLE_ROW_GROUP_BACKGROUND,
   TYPE_TABLE_BORDER_BACKGROUND,
   TYPE_TEXT,
   TYPE_TEXT_DECORATION,
   TYPE_TEXT_OVERFLOW,
--- a/layout/reftests/font-face/local-1-ref.html
+++ b/layout/reftests/font-face/local-1-ref.html
@@ -2,17 +2,18 @@
 <html>
 <head>
 	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 	<meta http-equiv="Content-Style-Type" content="text/css">
 	<title>test src: local() reference</title>
 	<style type="text/css">
 	  body {
 	    font-family: Nimbus Sans L, Helvetica, Bitstream Vera Sans,
-                         Arial, Liberation Sans, SwissA, serif;
+                         Arial, Liberation Sans, SwissA,
+                         Droid Sans, Roboto, serif;
 	  }
 	</style>
 </head>
 <body>
   <p style="font-weight: normal;">
     The quick brown fox jumped over the lazy dog
   </p>
   <p style="font-weight: bold;">
--- a/layout/reftests/font-face/local-1.html
+++ b/layout/reftests/font-face/local-1.html
@@ -29,25 +29,27 @@
 	  obvious.
 
 	  -->
 	<style type="text/css">
 	  @font-face {
 	     font-family: "Local";
 	     src: local(Nimbus Sans L), local(NimbusSansL-Regu),
 	          local(Helvetica), local(Bitstream Vera Sans),
-	          local(Arial), local(Liberation Sans), local(SwissA);
+	          local(Arial), local(Liberation Sans), local(SwissA),
+	          local(Droid Sans), local(Roboto);
 	     font-weight: 100;
 	  }
 	  @font-face {
 	     font-family: "Local";
 	     src: local(Nimbus Sans L Bold), local(NimbusSansL-Bold),
 	          local(Helvetica Bold), local(Helvetica-Bold),
                   local(Bitstream Vera Sans  Bold),
-	          local(Arial Bold), local(Liberation Sans Bold), local(SwissA Bold);
+	          local(Arial Bold), local(Liberation Sans Bold), local(SwissA Bold),
+	          local(Droid Sans Bold), local(Roboto Bold);
 	     font-weight: normal;
 	  }
 	  body { font-family: Local, serif }
 	</style>
 </head>
 <body>
   <p style="font-weight: 100">
     The quick brown fox jumped over the lazy dog
new file mode 100644
--- /dev/null
+++ b/layout/reftests/font-face/local-styled-1-ref.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style type="text/css">
+@font-face {
+  font-family: test;
+  src: local(Nimbus Sans L), local(NimbusSansL-Regu),
+       local(Helvetica), local(Bitstream Vera Sans),
+       local(Arial), local(Liberation Sans), local(SwissA),
+       local(Droid Sans), local(Roboto);
+}
+div {
+  font-family: test, serif;
+  margin: 10px;
+}
+</style>
+</head>
+<body>
+<div style="font-family:serif">
+This serif font should NOT be used below.
+</div>
+<hr>
+<div>
+These three lines should all use the same font face.
+</div>
+<div>
+This line should NOT be bold.
+</div>
+<div>
+This line should NOT be italic.
+</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/font-face/local-styled-1.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style type="text/css">
+@font-face {
+  font-family: test;
+  src: local(Nimbus Sans L), local(NimbusSansL-Regu),
+       local(Helvetica), local(Bitstream Vera Sans),
+       local(Arial), local(Liberation Sans), local(SwissA),
+       local(Droid Sans), local(Roboto);
+}
+@font-face {
+  font-family: test;
+  font-style: italic;
+  src: local(Nimbus Sans L), local(NimbusSansL-Regu),
+       local(Helvetica), local(Bitstream Vera Sans),
+       local(Arial), local(Liberation Sans), local(SwissA),
+       local(Droid Sans), local(Roboto);
+}
+@font-face {
+  font-family: test;
+  font-weight: bold;
+  src: local(Nimbus Sans L), local(NimbusSansL-Regu),
+       local(Helvetica), local(Bitstream Vera Sans),
+       local(Arial), local(Liberation Sans), local(SwissA),
+       local(Droid Sans), local(Roboto);
+}
+div {
+  font-family: test, serif;
+  margin: 10px;
+}
+</style>
+</head>
+<body>
+<div style="font-family:serif">
+This serif font should NOT be used below.
+</div>
+<hr>
+<div>
+These three lines should all use the same font face.
+</div>
+<div>
+<b>This line should NOT be bold.</b>
+</div>
+<div>
+<i>This line should NOT be italic.</i>
+</div>
+</body>
+</html>
--- a/layout/reftests/font-face/reftest.list
+++ b/layout/reftests/font-face/reftest.list
@@ -89,17 +89,20 @@ HTTP(..) == ahem-metrics-1.html ahem-met
 HTTP(..) == ex-unit-1.html ex-unit-1-ref.html
 HTTP(..) == ex-unit-1-dynamic.html ex-unit-1-ref.html
 
 # bug 493976 - for some reason the Arabic tests below cause Tinderbox timeouts
 # Arabic support requires AAT fonts under Mac OS, OpenType otherwise
 # random-if(!cocoaWidget) HTTP(..) == src-format-arabic.html src-format-arabic-aat-ref.html
 # random-if(cocoaWidget) HTTP(..) == src-format-arabic.html src-format-arabic-ot-ref.html
 
+# bug 769194 - src:local() completely broken on android
 fails-if(Android) == local-1.html local-1-ref.html
+fails-if(Android) == local-styled-1.html local-styled-1-ref.html
+
 HTTP(..) == synthetic-weight-style.html synthetic-weight-style-ref.html
 HTTP(..) == synthetic-variations.html synthetic-variations-ref.html
 
 # Leak test
 HTTP(..) load 486974-1.html
 
 # compare fonts with and without bad head checksum
 HTTP(..) == load-badchecksum.html load-badchecksum-ref.html
--- a/layout/reftests/position-dynamic-changes/relative/reftest.list
+++ b/layout/reftests/position-dynamic-changes/relative/reftest.list
@@ -1,4 +1,4 @@
-fuzzy-if(d2d,85,20) == move-right-bottom.html move-right-bottom-ref.html # Bug 742176
+random-if(cocoaWidget) fuzzy-if(d2d,85,20) == move-right-bottom.html move-right-bottom-ref.html # Bug 742176
 random-if(cocoaWidget) fuzzy-if(d2d,85,20) == move-top-left.html move-top-left-ref.html # Bug 688545, bug 742176
-fuzzy-if(d2d,85,20) == move-right-bottom-table.html move-right-bottom-table-ref.html # Bug 742176
+random-if(cocoaWidget) fuzzy-if(d2d,85,20) == move-right-bottom-table.html move-right-bottom-table-ref.html # Bug 742176
 random-if(cocoaWidget) fuzzy-if(d2d,85,20) == move-top-left-table.html move-top-left-table-ref.html # Bug 688545, bug 742176
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/svg-integration/mask-transformed-html-01.xhtml
@@ -0,0 +1,42 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+  <title>Test SVG masking of transformed HTML elements</title>
+  <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=769103 -->
+  <style type="text/css">
+
+* { margin: 0; border: 0; padding: 0;}
+
+div {
+  position: absolute;
+  left: 1px;
+  top: 1px;
+  width: 3px;
+  height: 3px;
+  -moz-transform: scale(100,100);
+  -moz-transform-origin: 0 0;
+}
+
+  </style>
+</head>
+<body bgcolor="lime">
+
+  <svg xmlns="http://www.w3.org/2000/svg" width="300" height="300"
+       style="display:block; position:absolute;">
+    <mask id="mask1" x="0" y="0" width="1" height="1" maskContentUnits="objectBoundingBox">
+      <circle cx="0.5" cy="0.5" r="0.48" fill="white"/>
+    </mask>
+    <mask id="mask2" x="0" y="0" width="1" height="1" maskContentUnits="objectBoundingBox">
+      <circle cx="0.5" cy="0.5" r="0.5" fill="white"/>
+    </mask>
+    <circle cx="150" cy="150" r="147" fill="red"/>
+  </svg>
+
+  <div style="background: red; mask: url(#mask1);"/>
+  <div style="background: lime; mask: url(#mask2);"/>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/svg-integration/mask-transformed-html-02.xhtml
@@ -0,0 +1,42 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+  <title>Test SVG masking of transformed HTML elements</title>
+  <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=769103 -->
+  <style type="text/css">
+
+* { margin: 0; border: 0; padding: 0;}
+
+div {
+  position: absolute;
+  left: 50px;
+  top: 50px;
+  width: 150px;
+  height: 150px;
+  -moz-transform: scale(2,2);
+  -moz-transform-origin: 0 0;
+}
+
+  </style>
+</head>
+<body bgcolor="lime">
+
+  <svg xmlns="http://www.w3.org/2000/svg" width="350" height="350"
+       style="display:block; position:absolute;">
+    <mask id="mask1" x="0" y="0" width="1" height="1" maskContentUnits="objectBoundingBox">
+      <circle cx="0.5" cy="0.5" r="0.48" fill="white"/>
+    </mask>
+    <mask id="mask2" x="0" y="0" width="1" height="1" maskContentUnits="objectBoundingBox">
+      <circle cx="0.5" cy="0.5" r="0.50" fill="white"/>
+    </mask>
+    <circle cx="200" cy="200" r="147" fill="red"/>
+  </svg>
+
+  <div style="background: red; mask: url(#mask1);"/>
+  <div style="background: lime; mask: url(#mask2);"/>
+
+</body>
+</html>
--- a/layout/reftests/svg/svg-integration/reftest.list
+++ b/layout/reftests/svg/svg-integration/reftest.list
@@ -20,8 +20,12 @@
 == filter-html-01.xhtml filter-html-01-ref.svg
 == filter-html-01-extref.xhtml filter-html-01-ref.svg
 == filter-html-zoomed-01.xhtml filter-html-01-ref.svg
 == mask-html-01.xhtml mask-html-01-ref.svg
 == mask-html-01-extref-01.xhtml mask-html-01-ref.svg
 == mask-html-01-extref-02.xhtml mask-html-01-ref.svg
 == mask-html-zoomed-01.xhtml mask-html-01-ref.svg
 == mask-html-xbl-bound-01.html mask-html-01-ref.svg
+== mask-transformed-html-01.xhtml ../pass.svg
+== mask-transformed-html-02.xhtml ../pass.svg
+
+
--- a/layout/svg/base/src/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/base/src/nsSVGIntegrationUtils.cpp
@@ -358,23 +358,23 @@ private:
   nsDisplayListBuilder* mBuilder;
   nsDisplayList* mInnerList;
   nsIFrame* mFrame;
   nsPoint mOffset;
 };
 
 void
 nsSVGIntegrationUtils::PaintFramesWithEffects(nsRenderingContext* aCtx,
-                                              nsIFrame* aEffectsFrame,
+                                              nsIFrame* aFrame,
                                               const nsRect& aDirtyRect,
                                               nsDisplayListBuilder* aBuilder,
                                               nsDisplayList* aInnerList)
 {
 #ifdef DEBUG
-  nsISVGChildFrame *svgChildFrame = do_QueryFrame(aEffectsFrame);
+  nsISVGChildFrame *svgChildFrame = do_QueryFrame(aFrame);
   NS_ASSERTION(!svgChildFrame, "Should never be called on an SVG frame");
 #endif
 
   /* SVG defines the following rendering model:
    *
    *  1. Render geometry
    *  2. Apply filter
    *  3. Apply clipping, masking, group opacity
@@ -382,25 +382,25 @@ nsSVGIntegrationUtils::PaintFramesWithEf
    * We follow this, but perform a couple of optimizations:
    *
    * + Use cairo's clipPath when representable natively (single object
    *   clip region).
    *
    * + Merge opacity and masking if both used together.
    */
 
-  float opacity = aEffectsFrame->GetStyleDisplay()->mOpacity;
+  float opacity = aFrame->GetStyleDisplay()->mOpacity;
   if (opacity == 0.0f) {
     return;
   }
 
   /* Properties are added lazily and may have been removed by a restyle,
      so make sure all applicable ones are set again. */
   nsIFrame* firstFrame =
-    nsLayoutUtils::GetFirstContinuationOrSpecialSibling(aEffectsFrame);
+    nsLayoutUtils::GetFirstContinuationOrSpecialSibling(aFrame);
   nsSVGEffects::EffectProperties effectProperties =
     nsSVGEffects::GetEffectProperties(firstFrame);
 
   bool isOK = true;
   nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame(&isOK);
   nsSVGFilterFrame *filterFrame = effectProperties.GetFilterFrame(&isOK);
   nsSVGMaskFrame *maskFrame = effectProperties.GetMaskFrame(&isOK);
   if (!isOK) {
@@ -408,76 +408,76 @@ nsSVGIntegrationUtils::PaintFramesWithEf
   }
 
   bool isTrivialClip = clipPathFrame ? clipPathFrame->IsTrivial() : true;
 
   gfxContext* gfx = aCtx->ThebesContext();
   gfxContextMatrixAutoSaveRestore matrixAutoSaveRestore(gfx);
 
   PRInt32 appUnitsPerDevPixel = 
-    aEffectsFrame->PresContext()->AppUnitsPerDevPixel();
+    aFrame->PresContext()->AppUnitsPerDevPixel();
   nsPoint firstFrameOffset = GetOffsetToUserSpace(firstFrame);
   nsPoint offset = (aBuilder->ToReferenceFrame(firstFrame) - firstFrameOffset).
                      ToNearestPixels(appUnitsPerDevPixel).
                      ToAppUnits(appUnitsPerDevPixel);
   aCtx->Translate(offset);
 
-  gfxMatrix cssPxToDevPxMatrix = GetCSSPxToDevPxMatrix(aEffectsFrame);
+  gfxMatrix cssPxToDevPxMatrix = GetCSSPxToDevPxMatrix(aFrame);
 
   bool complexEffects = false;
   /* Check if we need to do additional operations on this child's
    * rendering, which necessitates rendering into another surface. */
   if (opacity != 1.0f || maskFrame || (clipPathFrame && !isTrivialClip)) {
     complexEffects = true;
     gfx->Save();
-    aCtx->IntersectClip(aEffectsFrame->GetVisualOverflowRect());
+    aCtx->IntersectClip(aFrame->GetVisualOverflowRect());
     gfx->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
   }
 
   /* If this frame has only a trivial clipPath, set up cairo's clipping now so
    * we can just do normal painting and get it clipped appropriately.
    */
   if (clipPathFrame && isTrivialClip) {
     gfx->Save();
-    clipPathFrame->ClipPaint(aCtx, aEffectsFrame, cssPxToDevPxMatrix);
+    clipPathFrame->ClipPaint(aCtx, aFrame, cssPxToDevPxMatrix);
   }
 
   /* Paint the child */
   if (filterFrame) {
-    RegularFramePaintCallback callback(aBuilder, aInnerList, aEffectsFrame,
+    RegularFramePaintCallback callback(aBuilder, aInnerList, aFrame,
                                        offset);
     nsRect dirtyRect = aDirtyRect - offset;
-    filterFrame->PaintFilteredFrame(aCtx, aEffectsFrame, &callback, &dirtyRect);
+    filterFrame->PaintFilteredFrame(aCtx, aFrame, &callback, &dirtyRect);
   } else {
     gfx->SetMatrix(matrixAutoSaveRestore.Matrix());
-    aInnerList->PaintForFrame(aBuilder, aCtx, aEffectsFrame,
+    aInnerList->PaintForFrame(aBuilder, aCtx, aFrame,
                               nsDisplayList::PAINT_DEFAULT);
     aCtx->Translate(offset);
   }
 
   if (clipPathFrame && isTrivialClip) {
     gfx->Restore();
   }
 
   /* No more effects, we're done. */
   if (!complexEffects) {
     return;
   }
 
   gfx->PopGroupToSource();
 
   nsRefPtr<gfxPattern> maskSurface =
-    maskFrame ? maskFrame->ComputeMaskAlpha(aCtx, aEffectsFrame,
+    maskFrame ? maskFrame->ComputeMaskAlpha(aCtx, aFrame,
                                             cssPxToDevPxMatrix, opacity) : nsnull;
 
   nsRefPtr<gfxPattern> clipMaskSurface;
   if (clipPathFrame && !isTrivialClip) {
     gfx->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
 
-    nsresult rv = clipPathFrame->ClipPaint(aCtx, aEffectsFrame, cssPxToDevPxMatrix);
+    nsresult rv = clipPathFrame->ClipPaint(aCtx, aFrame, cssPxToDevPxMatrix);
     clipMaskSurface = gfx->PopGroup();
 
     if (NS_SUCCEEDED(rv) && clipMaskSurface) {
       // Still more set after clipping, so clip to another surface
       if (maskSurface || opacity != 1.0f) {
         gfx->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
         gfx->Mask(clipMaskSurface);
         gfx->PopGroupToSource();
--- a/layout/svg/base/src/nsSVGIntegrationUtils.h
+++ b/layout/svg/base/src/nsSVGIntegrationUtils.h
@@ -124,22 +124,20 @@ public:
    * Returns true if the given point is not clipped out by effects.
    * @param aPt in appunits relative to aFrame
    */
   static bool
   HitTestFrameForEffects(nsIFrame* aFrame, const nsPoint& aPt);
 
   /**
    * Paint non-SVG frame with SVG effects.
-   * @param aOffset the offset in appunits where aFrame should be positioned
-   * in aCtx's coordinate system
    */
   static void
   PaintFramesWithEffects(nsRenderingContext* aCtx,
-                         nsIFrame* aEffectsFrame, const nsRect& aDirtyRect,
+                         nsIFrame* aFrame, const nsRect& aDirtyRect,
                          nsDisplayListBuilder* aBuilder,
                          nsDisplayList* aInnerList);
 
   /**
    * SVG frames expect to paint in SVG user units, which are equal to CSS px
    * units. This method provides a transform matrix to multiply onto a
    * gfxContext's current transform to convert the context's current units from
    * its usual dev pixels to SVG user units/CSS px to keep the SVG code happy.
--- a/layout/svg/base/src/nsSVGMaskFrame.cpp
+++ b/layout/svg/base/src/nsSVGMaskFrame.cpp
@@ -48,28 +48,24 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsRende
     bbox = nsSVGUtils::GetBBox(aParent);
   }
 
   gfxRect maskArea = nsSVGUtils::GetRelativeRect(units,
     &mask->mLengthAttributes[nsSVGMaskElement::X], bbox, aParent);
 
   gfxContext *gfx = aContext->ThebesContext();
 
+  // Get the clip extents in device space:
   gfx->Save();
   nsSVGUtils::SetClipRect(gfx, aMatrix, maskArea);
+  gfx->IdentityMatrix();
   gfxRect clipExtents = gfx->GetClipExtents();
   clipExtents.RoundOut();
   gfx->Restore();
 
-#ifdef DEBUG_tor
-  fprintf(stderr, "clip extent: %f,%f %fx%f\n",
-          clipExtents.X(), clipExtents.Y(),
-          clipExtents.Width(), clipExtents.Height());
-#endif
-
   bool resultOverflows;
   gfxIntSize surfaceSize =
     nsSVGUtils::ConvertToSurfaceSize(gfxSize(clipExtents.Width(),
                                              clipExtents.Height()),
                                      &resultOverflows);
 
   // 0 disables mask, < 0 is an error
   if (surfaceSize.width <= 0 || surfaceSize.height <= 0)
@@ -77,20 +73,29 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsRende
 
   if (resultOverflows)
     return nsnull;
 
   nsRefPtr<gfxImageSurface> image =
     new gfxImageSurface(surfaceSize, gfxASurface::ImageFormatARGB32);
   if (!image || image->CairoStatus())
     return nsnull;
-  image->SetDeviceOffset(-clipExtents.TopLeft());
+
+  // We would like to use gfxImageSurface::SetDeviceOffset() to position
+  // 'image'. However, we need to set the same matrix on the temporary context
+  // and pattern that we create below as is currently set on 'gfx'.
+  // Unfortunately, any device offset set by SetDeviceOffset() is affected by
+  // the transform passed to the SetMatrix() calls, so to avoid that we account
+  // for the device offset in the transform rather than use SetDeviceOffset().
+  gfxMatrix matrix =
+    gfx->CurrentMatrix() * gfxMatrix().Translate(-clipExtents.TopLeft());
 
   nsRenderingContext tmpCtx;
   tmpCtx.Init(this->PresContext()->DeviceContext(), image);
+  tmpCtx.ThebesContext()->SetMatrix(matrix);
 
   mMaskParent = aParent;
   if (mMaskParentMatrix) {
     *mMaskParentMatrix = aMatrix;
   } else {
     mMaskParentMatrix = new gfxMatrix(aMatrix);
   }
 
@@ -127,16 +132,17 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsRende
                         pixel[GFX_ARGB32_OFFSET_G] * 0.7154 +
                         pixel[GFX_ARGB32_OFFSET_B] * 0.0721) *
                        (pixel[GFX_ARGB32_OFFSET_A] / 255.0) * aOpacity);
 
       memset(pixel, alpha, 4);
     }
 
   gfxPattern *retval = new gfxPattern(image);
+  retval->SetMatrix(matrix);
   NS_IF_ADDREF(retval);
   return retval;
 }
 
 /* virtual */ void
 nsSVGMaskFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
 {
   nsSVGEffects::InvalidateDirectRenderingObservers(this);
--- a/layout/svg/base/src/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/base/src/nsSVGOuterSVGFrame.cpp
@@ -435,39 +435,39 @@ nsSVGOuterSVGFrame::DidReflow(nsPresCont
   PresContext()->PresShell()->SynthesizeMouseMove(false);
 
   return rv;
 }
 
 //----------------------------------------------------------------------
 // container methods
 
-class nsDisplaySVG : public nsDisplayItem {
+class nsDisplayOuterSVG : public nsDisplayItem {
 public:
-  nsDisplaySVG(nsDisplayListBuilder* aBuilder,
-               nsSVGOuterSVGFrame* aFrame) :
+  nsDisplayOuterSVG(nsDisplayListBuilder* aBuilder,
+                    nsSVGOuterSVGFrame* aFrame) :
     nsDisplayItem(aBuilder, aFrame) {
-    MOZ_COUNT_CTOR(nsDisplaySVG);
+    MOZ_COUNT_CTOR(nsDisplayOuterSVG);
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
-  virtual ~nsDisplaySVG() {
-    MOZ_COUNT_DTOR(nsDisplaySVG);
+  virtual ~nsDisplayOuterSVG() {
+    MOZ_COUNT_DTOR(nsDisplayOuterSVG);
   }
 #endif
 
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
   virtual void Paint(nsDisplayListBuilder* aBuilder,
                      nsRenderingContext* aCtx);
-  NS_DISPLAY_DECL_NAME("SVGEventReceiver", TYPE_SVG_EVENT_RECEIVER)
+  NS_DISPLAY_DECL_NAME("SVGOuterSVG", TYPE_SVG_OUTER_SVG)
 };
 
 void
-nsDisplaySVG::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
-                      HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
+nsDisplayOuterSVG::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
+                           HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
 {
   nsSVGOuterSVGFrame *outerSVGFrame = static_cast<nsSVGOuterSVGFrame*>(mFrame);
   nsRect rectAtOrigin = aRect - ToReferenceFrame();
   nsRect thisRect(nsPoint(0,0), outerSVGFrame->GetSize());
   if (!thisRect.Intersects(rectAtOrigin))
     return;
 
   nsPoint rectCenter(rectAtOrigin.x + rectAtOrigin.width / 2,
@@ -477,39 +477,43 @@ nsDisplaySVG::HitTest(nsDisplayListBuild
     outerSVGFrame, rectCenter + outerSVGFrame->GetPosition() -
                    outerSVGFrame->GetContentRect().TopLeft());
   if (frame) {
     aOutFrames->AppendElement(frame);
   }
 }
 
 void
-nsDisplaySVG::Paint(nsDisplayListBuilder* aBuilder,
-                    nsRenderingContext* aContext)
+nsDisplayOuterSVG::Paint(nsDisplayListBuilder* aBuilder,
+                         nsRenderingContext* aContext)
 {
-  nsSVGOuterSVGFrame *frame = static_cast<nsSVGOuterSVGFrame*>(mFrame);
-
-  if (frame->GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)
-    return;
-
 #if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING)
   PRTime start = PR_Now();
 #endif
 
   aContext->PushState();
 
+  nsSVGOuterSVGFrame *frame = static_cast<nsSVGOuterSVGFrame*>(mFrame);
+
 #ifdef XP_MACOSX
   if (frame->BitmapFallbackEnabled()) {
     // nquartz fallback paths, which svg tends to trigger, need
     // a non-window context target
     aContext->ThebesContext()->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
   }
 #endif
 
-  frame->Paint(aBuilder, aContext, mVisibleRect, ToReferenceFrame());
+  nsRect viewportRect =
+    frame->GetContentRectRelativeToSelf() + ToReferenceFrame();
+  nsRect clipRect = mVisibleRect.Intersect(viewportRect);
+
+  aContext->IntersectClip(clipRect);
+  aContext->Translate(viewportRect.TopLeft());
+
+  frame->Paint(aBuilder, aContext, clipRect - viewportRect.TopLeft());
 
 #ifdef XP_MACOSX
   if (frame->BitmapFallbackEnabled()) {
     // show the surface we pushed earlier for fallbacks
     aContext->ThebesContext()->PopGroupToSource();
     aContext->ThebesContext()->Paint();
   }
 
@@ -614,55 +618,51 @@ nsSVGOuterSVGFrame::AttributeChanged(PRI
 //----------------------------------------------------------------------
 // painting
 
 NS_IMETHODIMP
 nsSVGOuterSVGFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                      const nsRect&           aDirtyRect,
                                      const nsDisplayListSet& aLists)
 {
+  if (GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD) {
+    return NS_OK;
+  }
+
   nsresult rv = DisplayBorderBackgroundOutline(aBuilder, aLists);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsDisplayList replacedContent;
 
   rv = replacedContent.AppendNewToTop(
-      new (aBuilder) nsDisplaySVG(aBuilder, this));
+      new (aBuilder) nsDisplayOuterSVG(aBuilder, this));
   NS_ENSURE_SUCCESS(rv, rv);
 
   WrapReplacedContentForBorderRadius(aBuilder, &replacedContent, aLists);
 
   return NS_OK;
 }
 
 void
 nsSVGOuterSVGFrame::Paint(const nsDisplayListBuilder* aBuilder,
                           nsRenderingContext* aContext,
-                          const nsRect& aDirtyRect, nsPoint aPt)
+                          const nsRect& aDirtyRect)
 {
-  nsRect viewportRect = GetContentRect();
-  nsPoint viewportOffset = aPt + viewportRect.TopLeft() - GetPosition();
-  viewportRect.MoveTo(viewportOffset);
-
-  nsRect clipRect;
-  clipRect.IntersectRect(aDirtyRect, viewportRect);
-  aContext->IntersectClip(clipRect);
-  aContext->Translate(viewportRect.TopLeft());
-  nsRect dirtyRect = clipRect - viewportOffset;
-
-  nsIntRect dirtyPxRect = dirtyRect.ToOutsidePixels(PresContext()->AppUnitsPerDevPixel());
-
   // Create an SVGAutoRenderState so we can call SetPaintingToWindow on
   // it, but don't change the render mode:
   SVGAutoRenderState state(aContext, SVGAutoRenderState::GetRenderMode(aContext));
 
   if (aBuilder->IsPaintingToWindow()) {
     state.SetPaintingToWindow(true);
   }
 
+  // Convert the (content area relative) dirty rect to dev pixels:
+  nsIntRect dirtyPxRect =
+    aDirtyRect.ToOutsidePixels(PresContext()->AppUnitsPerDevPixel());
+
   nsSVGUtils::PaintFrameWithEffects(aContext, &dirtyPxRect, this);
 }
 
 nsSplittableType
 nsSVGOuterSVGFrame::GetSplittableType() const
 {
   return NS_FRAME_NOT_SPLITTABLE;
 }
--- a/layout/svg/base/src/nsSVGOuterSVGFrame.h
+++ b/layout/svg/base/src/nsSVGOuterSVGFrame.h
@@ -62,17 +62,17 @@ public:
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::svgOuterSVGFrame
    */
   virtual nsIAtom* GetType() const;
 
   void Paint(const nsDisplayListBuilder* aBuilder,
              nsRenderingContext* aContext,
-             const nsRect& aDirtyRect, nsPoint aPt);
+             const nsRect& aDirtyRect);
 
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGOuterSVG"), aResult);
   }
 #endif
 
--- a/mobile/android/base/AwesomeBar.java
+++ b/mobile/android/base/AwesomeBar.java
@@ -215,16 +215,25 @@ public class AwesomeBar extends GeckoAct
                     openUserEnteredAndFinish(mText.getText().toString());
                     return true;
                 } else {
                     return false;
                 }
             }
         });
 
+        mText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+            public void onFocusChange(View v, boolean hasFocus) {
+                if (!hasFocus) {
+                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
+                }
+            }
+        });
+
         registerForContextMenu(mAwesomeTabs.findViewById(R.id.all_pages_list));
         registerForContextMenu(mAwesomeTabs.findViewById(R.id.bookmarks_list));
         registerForContextMenu(mAwesomeTabs.findViewById(R.id.history_list));
 
         GeckoAppShell.registerGeckoEventListener("SearchEngines:Data", this);
         GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("SearchEngines:Get", null));
     }
 
@@ -348,16 +357,21 @@ public class AwesomeBar extends GeckoAct
         resultIntent.putExtra(URL_KEY, url);
         resultIntent.putExtra(TARGET_KEY, mTarget);
         resultIntent.putExtra(SEARCH_KEY, engine);
         finishWithResult(resultIntent);
     }
 
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
+        // Galaxy Note sends key events for the stylus that are outside of the
+        // valid keyCode range (see bug 758427)
+        if (keyCode > KeyEvent.getMaxKeyCode())
+            return true;
+
         // This method is called only if the key event was not handled
         // by any of the views, which usually means the edit box lost focus
         if (keyCode == KeyEvent.KEYCODE_BACK ||
             keyCode == KeyEvent.KEYCODE_MENU ||
             keyCode == KeyEvent.KEYCODE_SEARCH ||
             keyCode == KeyEvent.KEYCODE_DPAD_UP ||
             keyCode == KeyEvent.KEYCODE_DPAD_DOWN ||
             keyCode == KeyEvent.KEYCODE_DPAD_LEFT ||
--- a/mobile/android/base/AwesomeBarTabs.java
+++ b/mobile/android/base/AwesomeBarTabs.java
@@ -63,16 +63,17 @@ public class AwesomeBarTabs extends TabH
     private static final String HISTORY_TAB = "history";
 
     private static enum HistorySection { TODAY, YESTERDAY, WEEK, OLDER };
 
     private Context mContext;
     private boolean mInflated;
     private LayoutInflater mInflater;
     private OnUrlOpenListener mUrlOpenListener;
+    private View.OnTouchListener mListTouchListener;
     private ContentResolver mContentResolver;
     private ContentObserver mContentObserver;
     private SearchEngine mSuggestEngine;
     private ArrayList<SearchEngine> mSearchEngines;
 
     private BookmarksQueryTask mBookmarksQueryTask;
     private HistoryQueryTask mHistoryQueryTask;
     
@@ -881,16 +882,24 @@ public class AwesomeBarTabs extends TabH
             return;
 
         mInflated = true;
 
         // This should be called before adding any tabs
         // to the TabHost.
         setup();
 
+        mListTouchListener = new View.OnTouchListener() {
+            public boolean onTouch(View view, MotionEvent event) {
+                if (event.getAction() == MotionEvent.ACTION_DOWN)
+                    hideSoftInput(view);
+                return false;
+            }
+        };
+
         addAllPagesTab();
         addBookmarksTab();
         addHistoryTab();
 
         setOnTabChangedListener(new TabHost.OnTabChangeListener() {
             public void onTabChanged(String tabId) {
                 boolean hideSoftInput = true;
 
@@ -969,39 +978,42 @@ public class AwesomeBarTabs extends TabH
 
         allPagesList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                 ((AwesomeBarItem) allPagesList.getItemAtPosition(position)).onClick();
             }
         });
 
         allPagesList.setAdapter(mAllPagesCursorAdapter);
+        allPagesList.setOnTouchListener(mListTouchListener);
     }
 
     private void addBookmarksTab() {
         Log.d(LOGTAG, "Creating Bookmarks tab");
 
         addAwesomeTab(BOOKMARKS_TAB,
                       R.string.awesomebar_bookmarks_title,
                       R.id.bookmarks_list);
 
         ListView bookmarksList = (ListView) findViewById(R.id.bookmarks_list);
+        bookmarksList.setOnTouchListener(mListTouchListener);
 
         // Only load bookmark list when tab is actually used.
         // See OnTabChangeListener above.
     }
 
     private void addHistoryTab() {
         Log.d(LOGTAG, "Creating History tab");
 
         addAwesomeTab(HISTORY_TAB,
                       R.string.awesomebar_history_title,
                       R.id.history_list);
 
         ListView historyList = (ListView) findViewById(R.id.history_list);
+        historyList.setOnTouchListener(mListTouchListener);
 
         // Only load history list when tab is actually used.
         // See OnTabChangeListener above.
     }
 
     private boolean hideSoftInput(View view) {
         InputMethodManager imm =
                 (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
@@ -1219,21 +1231,9 @@ public class AwesomeBarTabs extends TabH
                 mAllPagesCursorAdapter.notifyDataSetChanged();
             }
         });
     }
 
     public boolean isInReadingList() {
         return mInReadingList;
     }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        // we should only have to hide the soft keyboard once - when the user
-        // initially touches the screen
-        if (ev.getAction() == MotionEvent.ACTION_DOWN)
-            hideSoftInput(this);
-
-        // the android docs make no sense, but returning false will cause this and other
-        // motion events to be sent to the view the user tapped on
-        return false;
-    }
 }
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -2147,17 +2147,17 @@ abstract public class GeckoApp
      * compatable with our previous implementations
      */
     private String getURIFromIntent(Intent intent) {
         String uri = intent.getDataString();
         if (uri != null)
             return uri;
 
         final String action = intent.getAction();
-        if (action.startsWith(ACTION_WEBAPP_PREFIX) || ACTION_BOOKMARK.equals(action)) {
+        if ((action != null && action.startsWith(ACTION_WEBAPP_PREFIX)) || ACTION_BOOKMARK.equals(action)) {
             uri = intent.getStringExtra("args");
             if (uri != null && uri.startsWith("--url=")) {
                 uri.replace("--url=", "");
             }
         }
         return uri;
     }
 
--- a/mobile/android/base/GeckoInputConnection.java
+++ b/mobile/android/base/GeckoInputConnection.java
@@ -871,16 +871,19 @@ public class GeckoInputConnection
     }
 
     private boolean processKeyDown(int keyCode, KeyEvent event, boolean isPreIme) {
         if (DEBUG) {
             Log.d(LOGTAG, "IME: processKeyDown(keyCode=" + keyCode + ", event=" + event + ", "
                           + isPreIme + ")");
         }
 
+        if (keyCode > KeyEvent.getMaxKeyCode())
+            return false;
+
         clampSelection();
 
         switch (keyCode) {
             case KeyEvent.KEYCODE_MENU:
             case KeyEvent.KEYCODE_BACK:
             case KeyEvent.KEYCODE_VOLUME_UP:
             case KeyEvent.KEYCODE_VOLUME_DOWN:
             case KeyEvent.KEYCODE_SEARCH:
@@ -930,16 +933,19 @@ public class GeckoInputConnection
     }
 
     private boolean processKeyUp(int keyCode, KeyEvent event, boolean isPreIme) {
         if (DEBUG) {
             Log.d(LOGTAG, "IME: processKeyUp(keyCode=" + keyCode + ", event=" + event + ", "
                           + isPreIme + ")");
         }
 
+        if (keyCode > KeyEvent.getMaxKeyCode())
+            return false;
+
         switch (keyCode) {
             case KeyEvent.KEYCODE_BACK:
             case KeyEvent.KEYCODE_SEARCH:
             case KeyEvent.KEYCODE_MENU:
                 return false;
             default:
                 break;
         }
--- a/mobile/android/base/GeckoThread.java
+++ b/mobile/android/base/GeckoThread.java
@@ -68,19 +68,22 @@ public class GeckoThread extends Thread 
         Configuration config = res.getConfiguration();
         config.locale = locale;
         res.updateConfiguration(config, res.getDisplayMetrics());
 
         Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - runGecko");
 
         // find the right intent type
         final String action = mIntent.getAction();
-        String type = action.startsWith(GeckoApp.ACTION_WEBAPP_PREFIX) ? "-webapp" :
-                      GeckoApp.ACTION_BOOKMARK.equals(action) ? "-bookmark" :
-                      null;
+        String type = null;
+
+        if (action != null && action.startsWith(GeckoApp.ACTION_WEBAPP_PREFIX))
+            type = "-webapp";
+        else if (GeckoApp.ACTION_BOOKMARK.equals(action))
+            type = "-bookmark";
 
         String args = mIntent.getStringExtra("args");
 
         // if this isn't the default BrowserApp, send the apps default profile to gecko
         if (!(app instanceof BrowserApp)) {
             String profile = app.getDefaultProfileName();
             args = (args != null ? args : "") + "-P " + profile;
         }
--- a/mobile/android/base/tests/BaseTest.java.in
+++ b/mobile/android/base/tests/BaseTest.java.in
@@ -63,33 +63,33 @@ abstract class BaseTest extends Activity
         Intent i = new Intent(Intent.ACTION_MAIN);
         mProfile = (String)config.get("profile");
         i.putExtra("args", "-no-remote -profile " + mProfile);
 
         // Start the activity
         setActivityIntent(i);
         mActivity = getActivity();
 
-        // Set up Robotium.solo and Driver objects
-        mSolo = new Solo(getInstrumentation());
-        mDriver = new FennecNativeDriver(mActivity, mSolo);
-        mActions = new FennecNativeActions(mActivity, mSolo, getInstrumentation());
-
         mLogFile = (String)config.get("logfile");
         mBaseUrl = ((String)config.get("host")).replaceAll("(/$)", "");
         mRawBaseUrl = ((String)config.get("rawhost")).replaceAll("(/$)", "");
 
         // Initialize the asserter
         if (getTestType() == TEST_TALOS) {
             mAsserter = new FennecTalosAssert();
         } else {
             mAsserter = new FennecMochitestAssert();
         }
         mAsserter.setLogFile(mLogFile);
         mAsserter.setTestName(this.getClass().getName());
+
+        // Set up Robotium.solo and Driver objects
+        mSolo = new Solo(getInstrumentation());
+        mDriver = new FennecNativeDriver(mActivity, mSolo);
+        mActions = new FennecNativeActions(mActivity, mSolo, getInstrumentation(), mAsserter);
     }
 
     @Override
     protected void runTest() throws Throwable {
         try {
             super.runTest();
         } catch (Throwable t) {
             if (mAsserter != null) {
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1379,16 +1379,17 @@ var NativeWindow = {
     }
   }
 };
 
 var SelectionHandler = {
   // Keeps track of data about the dimensions of the selection
   cache: null,
   _active: false,
+  _viewOffset: null,
 
   // The window that holds the selection (can be a sub-frame)
   get _view() {
     if (this._viewRef)
       return this._viewRef.get();
     return null;
   },
 
@@ -1422,27 +1423,41 @@ var SelectionHandler = {
   // Units in pixels
   HANDLE_WIDTH: 35,
   HANDLE_HEIGHT: 64,
   HANDLE_PADDING: 20,
   HANDLE_VERTICAL_OFFSET: 10,
 
   init: function sh_init() {
     Services.obs.addObserver(this, "Gesture:SingleTap", false);
+    Services.obs.addObserver(this, "Window:Resize", false);
   },
 
   uninit: function sh_uninit() {
     Services.obs.removeObserver(this, "Gesture:SingleTap", false);
+    Services.obs.removeObserver(this, "Window:Resize", false);
   },
 
   observe: function sh_observe(aSubject, aTopic, aData) {
-    let data = JSON.parse(aData);
-
-    if (this._active)
-      this.endSelection(data.x, data.y);
+    switch (aTopic) {
+      case "Gesture:SingleTap": {
+        if (!this._active)
+          return;
+
+        let data = JSON.parse(aData);
+        this.endSelection(data.x, data.y);
+        break;
+      }
+      case "Window:Resize": {
+        // Knowing when the page is done drawing is hard, so let's just cancel
+        // the selection when the window changes. We should fix this later.
+        this.endSelection();
+        break;
+      }
+    }
   },
 
   notifySelectionChanged: function sh_notifySelectionChanged(aDoc, aSel, aReason) {
     // If the selection was removed, call endSelection() to clean up
     if (aSel == "" && aReason == Ci.nsISelectionListener.NO_REASON)
       this.endSelection();
   },
 
@@ -1458,16 +1473,20 @@ var SelectionHandler = {
       // Clear out any existing selection
       this.endSelection();
     }
 
     // Get the element's view
     this._view = aElement.ownerDocument.defaultView;
     this._isRTL = (this._view.getComputedStyle(aElement, "").direction == "rtl");
 
+    let computedStyle = this._view.getComputedStyle(this._view.document.documentElement);
+    this._viewOffset = { top: parseInt(computedStyle.getPropertyValue("margin-top").replace("px", "")),
+                         left: parseInt(computedStyle.getPropertyValue("margin-left").replace("px", "")) };
+
     // Remove any previous selected or created ranges. Tapping anywhere on a
     // page will create an empty range.
     let selection = this._view.getSelection();
     selection.removeAllRanges();
 
     // Position the caret using a fake mouse click
     let cwu = BrowserApp.selectedBrowser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).
                                                        getInterface(Ci.nsIDOMWindowUtils);
@@ -1572,21 +1591,21 @@ var SelectionHandler = {
     if (!element || element instanceof Ci.nsIDOMHTMLInputElement ||
                     element instanceof Ci.nsIDOMHTMLTextAreaElement ||
                     element.ownerDocument.defaultView != this._view)
       return;
     */
 
     // Update the handle position as it's dragged
     if (aIsStartHandle) {
-      this._start.style.left = aX + this._view.scrollX + "px";
-      this._start.style.top = aY + this._view.scrollY + "px";
+      this._start.style.left = aX + this._view.scrollX - this._viewOffset.left + "px";
+      this._start.style.top = aY + this._view.scrollY - this._viewOffset.top + "px";
     } else {
-      this._end.style.left = aX + this._view.scrollX + "px";
-      this._end.style.top = aY + this._view.scrollY + "px";
+      this._end.style.left = aX + this._view.scrollX - this._viewOffset.left + "px";
+      this._end.style.top = aY + this._view.scrollY - this._viewOffset.top + "px";
     }
 
     let cwu = this._view.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
 
     // The handles work the same on both LTR and RTL pages, but the underlying selection
     // works differently, so we need to reverse how we send mouse events on RTL pages.
     if (this._isRTL) {
       // Position the caret at the end handle using a fake mouse click
@@ -1691,16 +1710,17 @@ var SelectionHandler = {
         let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
         clipboard.copyString(selectedText, element.ownerDocument);
         NativeWindow.toast.show(Strings.browser.GetStringFromName("selectionHelper.textCopied"), "short");
       }
     }
 
     this._isRTL = false;
     this._view = null;
+    this._viewOffset = null;
     this.cache = null;
 
     return selectedText;
   },
 
   _pointInSelection: function sh_pointInSelection(aX, aY) {
     let offset = { x: 0, y: 0 };
     let win = this._view;
@@ -1739,21 +1759,21 @@ var SelectionHandler = {
     this.cache.end = end;
 
     return selectionReversed;
   },
 
   // Adjust start/end positions to account for scroll, and account for the dimensions of the
   // handle elements to ensure the handles point exactly at the ends of the selection.
   positionHandles: function sh_positionHandles() {
-    this._start.style.left = (this.cache.start.x + this._view.scrollX - this.HANDLE_WIDTH - this.HANDLE_PADDING) + "px";
-    this._start.style.top = (this.cache.start.y + this._view.scrollY - this.HANDLE_VERTICAL_OFFSET) + "px";
-
-    this._end.style.left = (this.cache.end.x + this._view.scrollX - this.HANDLE_PADDING) + "px";
-    this._end.style.top = (this.cache.end.y + this._view.scrollY - this.HANDLE_VERTICAL_OFFSET) + "px";
+    this._start.style.left = (this.cache.start.x + this._view.scrollX - this._viewOffset.left - this.HANDLE_WIDTH - this.HANDLE_PADDING) + "px";
+    this._start.style.top = (this.cache.start.y + this._view.scrollY - this._viewOffset.top - this.HANDLE_VERTICAL_OFFSET) + "px";
+
+    this._end.style.left = (this.cache.end.x + this._view.scrollX - this._viewOffset.left - this.HANDLE_PADDING) + "px";
+    this._end.style.top = (this.cache.end.