Merge inbound to m-c a=merge
authorWes Kocher <wkocher@mozilla.com>
Fri, 29 Apr 2016 14:54:44 -0700
changeset 334468 6ce48a7c22d55187daa471ff10d136b7ab02a5ee
parent 334288 8c3fd523d75bd30f691ca2d6cfdad18d576392a1 (current diff)
parent 334467 1d4795f0b4e28db3ddf6a5751653c179fef68726 (diff)
child 334469 e640f0802a806921d0533168e2bdd2b56cd9829a
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone49.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 inbound to m-c a=merge MozReview-Commit-ID: BKbqwBtHrBR
dom/animation/NonOwningAnimationTarget.h
dom/datastore/DataStore.cpp
dom/datastore/DataStore.h
dom/datastore/DataStore.manifest
dom/datastore/DataStoreCallbacks.h
dom/datastore/DataStoreChangeNotifier.jsm
dom/datastore/DataStoreCursor.cpp
dom/datastore/DataStoreCursor.h
dom/datastore/DataStoreCursorImpl.jsm
dom/datastore/DataStoreDB.cpp
dom/datastore/DataStoreDB.h
dom/datastore/DataStoreDB.jsm
dom/datastore/DataStoreImpl.js
dom/datastore/DataStoreRevision.cpp
dom/datastore/DataStoreRevision.h
dom/datastore/DataStoreService.cpp
dom/datastore/DataStoreService.h
dom/datastore/moz.build
dom/datastore/nsIDataStore.idl
dom/datastore/nsIDataStoreService.idl
dom/datastore/tests/file_app.sjs
dom/datastore/tests/file_app.template.webapp
dom/datastore/tests/file_app2.template.webapp
dom/datastore/tests/file_app_install.html
dom/datastore/tests/file_arrays.html
dom/datastore/tests/file_basic.html
dom/datastore/tests/file_basic_common.js
dom/datastore/tests/file_basic_worker.html
dom/datastore/tests/file_basic_worker.js
dom/datastore/tests/file_bug1008044.html
dom/datastore/tests/file_bug1058108.html
dom/datastore/tests/file_bug924104.html
dom/datastore/tests/file_bug957086.html
dom/datastore/tests/file_bug976311.html
dom/datastore/tests/file_bug976311.template.webapp
dom/datastore/tests/file_bug986056.html
dom/datastore/tests/file_bug986056.template.webapp
dom/datastore/tests/file_certifiedApp.html
dom/datastore/tests/file_changes.html
dom/datastore/tests/file_changes2.html
dom/datastore/tests/file_duplicate.html
dom/datastore/tests/file_event_maker.html
dom/datastore/tests/file_event_receiver.html
dom/datastore/tests/file_keys.html
dom/datastore/tests/file_notify_system_message.html
dom/datastore/tests/file_readonly.html
dom/datastore/tests/file_sync.html
dom/datastore/tests/file_sync_common.js
dom/datastore/tests/file_sync_worker.html
dom/datastore/tests/file_sync_worker.js
dom/datastore/tests/file_transactions.html
dom/datastore/tests/file_worker_close.html
dom/datastore/tests/file_worker_close.js
dom/datastore/tests/mochitest.ini
dom/datastore/tests/test_app_install.html
dom/datastore/tests/test_arrays.html
dom/datastore/tests/test_basic.html
dom/datastore/tests/test_basic_worker.html
dom/datastore/tests/test_bug1008044.html
dom/datastore/tests/test_bug1058108.html
dom/datastore/tests/test_bug924104.html
dom/datastore/tests/test_bug957086.html
dom/datastore/tests/test_bug976311.html
dom/datastore/tests/test_bug986056.html
dom/datastore/tests/test_certifiedApp.html
dom/datastore/tests/test_changes.html
dom/datastore/tests/test_duplicate.html
dom/datastore/tests/test_keys.html
dom/datastore/tests/test_notify_system_message.html
dom/datastore/tests/test_oop.html
dom/datastore/tests/test_oop_events.html
dom/datastore/tests/test_readonly.html
dom/datastore/tests/test_sync.html
dom/datastore/tests/test_sync_worker.html
dom/datastore/tests/test_transactions.html
dom/datastore/tests/test_worker_close.html
dom/webidl/DataStore.webidl
dom/webidl/DataStoreChangeEvent.webidl
dom/webidl/DataStoreImpl.webidl
dom/workers/DataStore.cpp
dom/workers/DataStore.h
dom/workers/DataStoreCursor.cpp
dom/workers/DataStoreCursor.h
gfx/skia/skia/include/core/SkComposeShader.h
gfx/skia/skia/include/core/SkFixed.h
gfx/skia/skia/include/core/SkImageDecoder.h
gfx/skia/skia/include/core/SkPackBits.h
gfx/skia/skia/include/core/SkTArray.h
gfx/skia/skia/include/core/SkTDArray.h
gfx/skia/skia/include/core/SkTDStack.h
gfx/skia/skia/include/core/SkTInternalLList.h
gfx/skia/skia/include/core/SkUtils.h
gfx/skia/skia/include/device/xps/SkConstexprMath.h
gfx/skia/skia/include/device/xps/SkXPSDevice.h
gfx/skia/skia/include/effects/SkDrawExtraPathEffect.h
gfx/skia/skia/include/effects/SkLerpXfermode.h
gfx/skia/skia/include/effects/SkPixelXorXfermode.h
gfx/skia/skia/include/gpu/gl/SkGLContext.h
gfx/skia/skia/include/gpu/gl/SkNullGLContext.h
gfx/skia/skia/include/gpu/gl/angle/SkANGLEGLContext.h
gfx/skia/skia/include/gpu/gl/command_buffer/SkCommandBufferGLContext.h
gfx/skia/skia/include/images/SkDecodingImageGenerator.h
gfx/skia/skia/include/images/SkPageFlipper.h
gfx/skia/skia/include/private/SkUniquePtr.h
gfx/skia/skia/include/utils/SkDebugUtils.h
gfx/skia/skia/include/views/SkBGViewArtist.h
gfx/skia/skia/include/views/SkParsePaint.h
gfx/skia/skia/include/views/SkStackViewLayout.h
gfx/skia/skia/include/views/SkViewInflate.h
gfx/skia/skia/include/views/SkWidget.h
gfx/skia/skia/include/views/animated/SkBorderView.h
gfx/skia/skia/include/views/animated/SkImageView.h
gfx/skia/skia/include/views/animated/SkProgressBarView.h
gfx/skia/skia/include/views/animated/SkScrollBarView.h
gfx/skia/skia/include/views/animated/SkWidgetViews.h
gfx/skia/skia/src/animator/SkTime.cpp
gfx/skia/skia/src/codec/SkCodec_libpng.cpp
gfx/skia/skia/src/codec/SkCodec_libpng.h
gfx/skia/skia/src/codec/SkJpegUtility_codec.cpp
gfx/skia/skia/src/codec/SkJpegUtility_codec.h
gfx/skia/skia/src/core/SkPackBits.cpp
gfx/skia/skia/src/core/SkRWBuffer.h
gfx/skia/skia/src/core/SkRemote.cpp
gfx/skia/skia/src/core/SkRemote.h
gfx/skia/skia/src/core/SkRemote_protocol.h
gfx/skia/skia/src/core/SkValue.h
gfx/skia/skia/src/device/xps/SkXPSDevice.cpp
gfx/skia/skia/src/doc/SkDocument.cpp
gfx/skia/skia/src/doc/SkDocument_PDF.cpp
gfx/skia/skia/src/doc/SkDocument_PDF_None.cpp
gfx/skia/skia/src/doc/SkDocument_XPS.cpp
gfx/skia/skia/src/doc/SkDocument_XPS_None.cpp
gfx/skia/skia/src/effects/SkLerpXfermode.cpp
gfx/skia/skia/src/effects/SkPixelXorXfermode.cpp
gfx/skia/skia/src/gpu/GrContextFactory.cpp
gfx/skia/skia/src/gpu/GrContextFactory.h
gfx/skia/skia/src/gpu/GrGeometryBuffer.h
gfx/skia/skia/src/gpu/GrIndexBuffer.h
gfx/skia/skia/src/gpu/GrTest.cpp
gfx/skia/skia/src/gpu/GrTest.h
gfx/skia/skia/src/gpu/GrTransferBuffer.h
gfx/skia/skia/src/gpu/GrVertexBuffer.h
gfx/skia/skia/src/gpu/GrVertices.h
gfx/skia/skia/src/gpu/effects/GrYUVtoRGBEffect.cpp
gfx/skia/skia/src/gpu/effects/GrYUVtoRGBEffect.h
gfx/skia/skia/src/gpu/gl/GrGLAssembleInterface.h
gfx/skia/skia/src/gpu/gl/GrGLBufferImpl.cpp
gfx/skia/skia/src/gpu/gl/GrGLBufferImpl.h
gfx/skia/skia/src/gpu/gl/GrGLIndexBuffer.cpp
gfx/skia/skia/src/gpu/gl/GrGLIndexBuffer.h
gfx/skia/skia/src/gpu/gl/GrGLNoOpInterface.cpp
gfx/skia/skia/src/gpu/gl/GrGLNoOpInterface.h
gfx/skia/skia/src/gpu/gl/GrGLTransferBuffer.cpp
gfx/skia/skia/src/gpu/gl/GrGLTransferBuffer.h
gfx/skia/skia/src/gpu/gl/GrGLVertexBuffer.cpp
gfx/skia/skia/src/gpu/gl/GrGLVertexBuffer.h
gfx/skia/skia/src/gpu/gl/SkGLContext.cpp
gfx/skia/skia/src/gpu/gl/SkNullGLContext.cpp
gfx/skia/skia/src/gpu/gl/angle/GrGLCreateANGLEInterface.cpp
gfx/skia/skia/src/gpu/gl/angle/SkANGLEGLContext.cpp
gfx/skia/skia/src/gpu/gl/command_buffer/SkCommandBufferGLContext.cpp
gfx/skia/skia/src/gpu/gl/debug/GrBufferObj.cpp
gfx/skia/skia/src/gpu/gl/debug/GrBufferObj.h
gfx/skia/skia/src/gpu/gl/debug/GrDebugGL.cpp
gfx/skia/skia/src/gpu/gl/debug/GrDebugGL.h
gfx/skia/skia/src/gpu/gl/debug/GrFBBindableObj.h
gfx/skia/skia/src/gpu/gl/debug/GrFakeRefObj.h
gfx/skia/skia/src/gpu/gl/debug/GrFrameBufferObj.cpp
gfx/skia/skia/src/gpu/gl/debug/GrFrameBufferObj.h
gfx/skia/skia/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp
gfx/skia/skia/src/gpu/gl/debug/GrProgramObj.cpp
gfx/skia/skia/src/gpu/gl/debug/GrProgramObj.h
gfx/skia/skia/src/gpu/gl/debug/GrRenderBufferObj.h
gfx/skia/skia/src/gpu/gl/debug/GrShaderObj.cpp
gfx/skia/skia/src/gpu/gl/debug/GrShaderObj.h
gfx/skia/skia/src/gpu/gl/debug/GrTextureObj.cpp
gfx/skia/skia/src/gpu/gl/debug/GrTextureObj.h
gfx/skia/skia/src/gpu/gl/debug/GrTextureUnitObj.cpp
gfx/skia/skia/src/gpu/gl/debug/GrTextureUnitObj.h
gfx/skia/skia/src/gpu/gl/debug/GrVertexArrayObj.h
gfx/skia/skia/src/gpu/gl/debug/SkDebugGLContext.cpp
gfx/skia/skia/src/gpu/gl/debug/SkDebugGLContext.h
gfx/skia/skia/src/gpu/gl/egl/SkCreatePlatformGLContext_egl.cpp
gfx/skia/skia/src/gpu/gl/glx/SkCreatePlatformGLContext_glx.cpp
gfx/skia/skia/src/gpu/gl/iOS/SkCreatePlatformGLContext_iOS.mm
gfx/skia/skia/src/gpu/gl/mac/SkCreatePlatformGLContext_mac.cpp
gfx/skia/skia/src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp
gfx/skia/skia/src/gpu/gl/mesa/SkMesaGLContext.cpp
gfx/skia/skia/src/gpu/gl/mesa/SkMesaGLContext.h
gfx/skia/skia/src/gpu/gl/nacl/SkCreatePlatformGLContext_nacl.cpp
gfx/skia/skia/src/gpu/gl/win/SkCreatePlatformGLContext_win.cpp
gfx/skia/skia/src/gpu/text/GrTextContext.cpp
gfx/skia/skia/src/gpu/text/GrTextContext.h
gfx/skia/skia/src/images/SkDecodingImageGenerator.cpp
gfx/skia/skia/src/images/SkImageDecoder.cpp
gfx/skia/skia/src/images/SkImageDecoder_FactoryDefault.cpp
gfx/skia/skia/src/images/SkImageDecoder_FactoryRegistrar.cpp
gfx/skia/skia/src/images/SkImageDecoder_astc.cpp
gfx/skia/skia/src/images/SkImageDecoder_ktx.cpp
gfx/skia/skia/src/images/SkImageDecoder_libbmp.cpp
gfx/skia/skia/src/images/SkImageDecoder_libgif.cpp
gfx/skia/skia/src/images/SkImageDecoder_libico.cpp
gfx/skia/skia/src/images/SkImageDecoder_libjpeg.cpp
gfx/skia/skia/src/images/SkImageDecoder_libpng.cpp
gfx/skia/skia/src/images/SkImageDecoder_libwebp.cpp
gfx/skia/skia/src/images/SkImageDecoder_pkm.cpp
gfx/skia/skia/src/images/SkImageDecoder_wbmp.cpp
gfx/skia/skia/src/images/SkImageEncoder_argb.cpp
gfx/skia/skia/src/images/SkJpegUtility.cpp
gfx/skia/skia/src/images/SkJpegUtility.h
gfx/skia/skia/src/images/SkMovie_gif.cpp
gfx/skia/skia/src/images/SkPageFlipper.cpp
gfx/skia/skia/src/images/SkScaledBitmapSampler.cpp
gfx/skia/skia/src/images/SkScaledBitmapSampler.h
gfx/skia/skia/src/images/bmpdecoderhelper.cpp
gfx/skia/skia/src/images/bmpdecoderhelper.h
gfx/skia/skia/src/opts/SkBlitRow_opts_SSE4.cpp
gfx/skia/skia/src/opts/SkBlitRow_opts_SSE4.h
gfx/skia/skia/src/opts/SkFloatingPoint_opts.h
gfx/skia/skia/src/opts/SkNx_avx.h
gfx/skia/skia/src/opts/SkOpts_avx.cpp
gfx/skia/skia/src/opts/SkUtils_opts.h
gfx/skia/skia/src/ports/SkImageDecoder_CG.cpp
gfx/skia/skia/src/ports/SkImageDecoder_WIC.cpp
gfx/skia/skia/src/ports/SkImageDecoder_empty.cpp
gfx/skia/skia/src/ports/SkTime_Unix.cpp
gfx/skia/skia/src/ports/SkTime_win.cpp
gfx/skia/skia/src/utils/SkBitmapHasher.cpp
gfx/skia/skia/src/utils/SkBitmapHasher.h
gfx/skia/skia/src/utils/SkImageGeneratorUtils.cpp
gfx/skia/skia/src/utils/SkImageGeneratorUtils.h
gfx/skia/skia/src/utils/SkRunnable.h
gfx/skia/skia/src/utils/SkSHA1.cpp
gfx/skia/skia/src/utils/SkSHA1.h
gfx/skia/skia/src/utils/SkTFitsIn.h
gfx/skia/skia/src/utils/debugger/SkDebugCanvas.cpp
gfx/skia/skia/src/utils/debugger/SkDebugCanvas.h
gfx/skia/skia/src/utils/debugger/SkDrawCommand.cpp
gfx/skia/skia/src/utils/debugger/SkDrawCommand.h
gfx/skia/skia/src/utils/debugger/SkObjectParser.cpp
gfx/skia/skia/src/utils/debugger/SkObjectParser.h
gfx/skia/skia/src/views/SkBGViewArtist.cpp
gfx/skia/skia/src/views/SkParsePaint.cpp
gfx/skia/skia/src/views/SkProgressView.cpp
gfx/skia/skia/src/views/SkStackViewLayout.cpp
gfx/skia/skia/src/views/SkViewInflate.cpp
gfx/skia/skia/src/views/SkWidgets.cpp
gfx/skia/skia/src/views/animated/SkBorderView.cpp
gfx/skia/skia/src/views/animated/SkImageView.cpp
gfx/skia/skia/src/views/animated/SkProgressBarView.cpp
gfx/skia/skia/src/views/animated/SkScrollBarView.cpp
gfx/skia/skia/src/views/animated/SkStaticTextView.cpp
gfx/skia/skia/src/views/animated/SkWidgetViews.cpp
toolkit/mozapps/update/tests/chrome/test_0012_check_basic_license.xul
toolkit/mozapps/update/tests/chrome/test_0013_check_incompat_basic.xul
toolkit/mozapps/update/tests/chrome/test_0014_check_incompat_basic_license.xul
toolkit/mozapps/update/tests/chrome/test_0015_check_incompat_basic_addons.xul
toolkit/mozapps/update/tests/chrome/test_0016_check_incompat_basic_license_addons.xul
toolkit/mozapps/update/tests/chrome/test_0022_check_billboard_license.xul
toolkit/mozapps/update/tests/chrome/test_0023_check_incompat_billboard.xul
toolkit/mozapps/update/tests/chrome/test_0024_check_incompat_billboard_license.xul
toolkit/mozapps/update/tests/chrome/test_0025_check_incompat_billboard_addons.xul
toolkit/mozapps/update/tests/chrome/test_0026_check_incompat_billboard_license_addons.xul
toolkit/mozapps/update/tests/chrome/test_0032_available_basic_license.xul
toolkit/mozapps/update/tests/chrome/test_0033_available_incompat_basic.xul
toolkit/mozapps/update/tests/chrome/test_0034_available_incompat_basic_license.xul
toolkit/mozapps/update/tests/chrome/test_0035_available_incompat_basic_addons.xul
toolkit/mozapps/update/tests/chrome/test_0036_available_incompat_basic_license_addons.xul
toolkit/mozapps/update/tests/chrome/test_0042_available_billboard_license.xul
toolkit/mozapps/update/tests/chrome/test_0043_available_incompat_billboard.xul
toolkit/mozapps/update/tests/chrome/test_0044_available_incompat_billboard_license.xul
toolkit/mozapps/update/tests/chrome/test_0045_available_incompat_billboard_addons.xul
toolkit/mozapps/update/tests/chrome/test_0046_available_incompat_billboard_license_addons.xul
toolkit/mozapps/update/tests/chrome/test_0053_check_billboard_license_noAttr.xul
toolkit/mozapps/update/tests/chrome/test_0054_check_billboard_license_404.xul
toolkit/mozapps/update/tests/chrome/test_0104_background_restartNotification_NoIncompatAddons.xul
toolkit/mozapps/update/tests/chrome/test_0105_background_restartNotification_VersionCompatAddons.xul
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-Merge day clobber
\ No newline at end of file
+Bug 1265131 - Update Skia to m51 branch
--- a/accessible/base/EventTree.cpp
+++ b/accessible/base/EventTree.cpp
@@ -178,23 +178,22 @@ TreeMutation::Done()
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // EventTree
 
 void
 EventTree::Process()
 {
-  EventTree* node = mFirst;
-  while (node) {
+  while (mFirst) {
     // Skip a node and its subtree if its container is not in the document.
-    if (node->mContainer->IsInDocument()) {
-      node->Process();
+    if (mFirst->mContainer->IsInDocument()) {
+      mFirst->Process();
     }
-    node = node->mNext;
+    mFirst = mFirst->mNext.forget();
   }
 
   MOZ_ASSERT(mContainer || mDependentEvents.IsEmpty(),
              "No container, no events");
   MOZ_ASSERT(!mContainer || !mContainer->IsDefunct(),
              "Processing events for defunct container");
 
   // Fire mutation events.
--- a/accessible/base/NotificationController.cpp
+++ b/accessible/base/NotificationController.cpp
@@ -397,17 +397,16 @@ NotificationController::WillRefresh(mozi
   mRelocations.Clear();
 
   // If a generic notification occurs after this point then we may be allowed to
   // process it synchronously.  However we do not want to reenter if fireing
   // events causes script to run.
   mObservingState = eRefreshProcessing;
 
   mEventTree.Process();
-  mEventTree.Clear();
 
   ProcessEventQueue();
 
   if (IPCAccessibilityActive()) {
     size_t newDocCount = newChildDocs.Length();
     for (size_t i = 0; i < newDocCount; i++) {
       DocAccessible* childDoc = newChildDocs[i];
       Accessible* parent = childDoc->Parent();
--- a/accessible/ipc/DocAccessibleParent.h
+++ b/accessible/ipc/DocAccessibleParent.h
@@ -161,17 +161,17 @@ private:
     enum { ALLOW_MEMMOVE = true };
 
     ProxyAccessible* mProxy;
   };
 
   uint32_t AddSubtree(ProxyAccessible* aParent,
                       const nsTArray<AccessibleData>& aNewTree, uint32_t aIdx,
                       uint32_t aIdxInParent);
-  MOZ_WARN_UNUSED_RESULT bool CheckDocTree() const;
+  MOZ_MUST_USE bool CheckDocTree() const;
   xpcAccessibleGeneric* GetXPCAccessible(ProxyAccessible* aProxy);
 
   nsTArray<DocAccessibleParent*> mChildDocs;
   DocAccessibleParent* mParentDoc;
 
   /*
    * Conceptually this is a map from IDs to proxies, but we store the ID in the
    * proxy object so we can't use a real map.
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -522,18 +522,16 @@ pref("b2g.update.apply-prompt-timeout", 
 pref("b2g.update.apply-idle-timeout", 600000); // milliseconds
 // Amount of time after which connection will be restarted if no progress
 pref("b2g.update.download-watchdog-timeout", 120000); // milliseconds
 pref("b2g.update.download-watchdog-max-retries", 5);
 
 pref("app.update.enabled", true);
 pref("app.update.auto", false);
 pref("app.update.silent", false);
-pref("app.update.mode", 0);
-pref("app.update.incompatible.mode", 0);
 pref("app.update.staging.enabled", true);
 pref("app.update.service.enabled", true);
 
 pref("app.update.url", "https://aus5.mozilla.org/update/5/%PRODUCT%/%VERSION%/%BUILD_ID%/%PRODUCT_DEVICE%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/%IMEI%/update.xml");
 pref("app.update.channel", "@MOZ_UPDATE_CHANNEL@");
 
 // Interval at which update manifest is fetched.  In units of seconds.
 pref("app.update.interval", 86400); // 1 day
@@ -882,23 +880,16 @@ pref("disk_space_watcher.enabled", true)
 // SNTP preferences.
 pref("network.sntp.maxRetryCount", 10);
 pref("network.sntp.refreshPeriod", 86400); // In seconds.
 pref("network.sntp.pools", // Servers separated by ';'.
      "0.pool.ntp.org;1.pool.ntp.org;2.pool.ntp.org;3.pool.ntp.org");
 pref("network.sntp.port", 123);
 pref("network.sntp.timeout", 30); // In seconds.
 
-// Enable dataStore
-pref("dom.datastore.enabled", true);
-// When an entry is changed, use two timers to fire system messages in a more
-// moderate pattern.
-pref("dom.datastore.sysMsgOnChangeShortTimeoutSec", 10);
-pref("dom.datastore.sysMsgOnChangeLongTimeoutSec", 60);
-
 // DOM Inter-App Communication API.
 pref("dom.inter-app-communication-api.enabled", true);
 
 // Allow ADB to run for this many hours before disabling
 // (only applies when marionette is disabled)
 // 0 disables the timer.
 pref("b2g.adb.timeout-hours", 12);
 
@@ -1003,16 +994,19 @@ pref("dom.apps.reviewer_paths", "/review
 
 // New implementation to unify touch-caret and selection-carets.
 pref("layout.accessiblecaret.enabled", true);
 
 // Show the selection bars at the two ends of the selection highlight. Required
 // by the spec in bug 921965.
 pref("layout.accessiblecaret.bar.enabled", true);
 
+// Hide the caret in cursor mode after 3 seconds.
+pref("layout.accessiblecaret.timeout_ms", 3000);
+
 // APZ on real devices supports long tap events.
 #ifdef MOZ_WIDGET_GONK
 pref("layout.accessiblecaret.use_long_tap_injector", false);
 #endif
 
 // Hide carets and text selection dialog during scrolling.
 pref("layout.accessiblecaret.always_show_when_scrolling", false);
 
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -2,17 +2,16 @@
 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
 /* 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/. */
 
 window.performance.mark('gecko-shell-loadstart');
 
 Cu.import('resource://gre/modules/ContactService.jsm');
-Cu.import('resource://gre/modules/DataStoreChangeNotifier.jsm');
 Cu.import('resource://gre/modules/AlarmService.jsm');
 Cu.import('resource://gre/modules/ActivitiesService.jsm');
 Cu.import('resource://gre/modules/NotificationDB.jsm');
 Cu.import('resource://gre/modules/Payment.jsm');
 Cu.import("resource://gre/modules/AppsUtils.jsm");
 Cu.import('resource://gre/modules/UserAgentOverrides.jsm');
 Cu.import('resource://gre/modules/Keyboard.jsm');
 Cu.import('resource://gre/modules/ErrorPage.jsm');
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -927,20 +927,16 @@ bin/libfreebl_32int64_3.so
 
 #ifndef MOZ_WIDGET_GONK
 @RESPATH@/components/SimulatorScreen.js
 #endif
 
 @RESPATH@/components/FxAccountsUIGlue.js
 @RESPATH@/components/services_fxaccounts.xpt
 
-@RESPATH@/components/DataStore.manifest
-@RESPATH@/components/DataStoreImpl.js
-@RESPATH@/components/dom_datastore.xpt
-
 @RESPATH@/components/MobileIdentity.manifest
 @RESPATH@/components/MobileIdentity.js
 @RESPATH@/components/dom_mobileidentity.xpt
 @RESPATH@/components/MobileIdentityUIGlue.js
 @RESPATH@/components/services_mobileidentity.xpt
 
 #ifdef MOZ_WEBSPEECH
 @RESPATH@/components/dom_webspeechsynth.xpt
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -142,24 +142,21 @@ pref("app.update.backgroundMaxErrors", 1
 // not valid. Bug 1182352 will remove the update xml certificate checks and the
 // following two preferences.
 pref("app.update.cert.requireBuiltIn", false);
 pref("app.update.cert.checkAttributes", false);
 
 // Whether or not app updates are enabled
 pref("app.update.enabled", true);
 
-// This preference turns on app.update.mode and allows automatic download and
-// install to take place. We use a separate boolean toggle for this to make
-// the UI easier to construct.
+// If set to true, the Update Service will automatically download updates when
+// app updates are enabled per the app.update.enabled preference and if the user
+// can apply updates.
 pref("app.update.auto", true);
 
-// See chart in nsUpdateService.js source for more details
-pref("app.update.mode", 1);
-
 // If set to true, the Update Service will present no UI for any event.
 pref("app.update.silent", false);
 
 // If set to true, the hamburger button will show badges for update events.
 #ifndef RELEASE_BUILD
 pref("app.update.badge", true);
 #else
 pref("app.update.badge", false);
@@ -186,23 +183,16 @@ pref("app.update.idletime", 60);
 
 // Whether or not we show a dialog box informing the user that the update was
 // successfully applied. This is off in Firefox by default since we show a
 // upgrade start page instead! Other apps may wish to show this UI, and supply
 // a whatsNewURL field in their brand.properties that contains a link to a page
 // which tells users what's new in this new update.
 pref("app.update.showInstalledUI", false);
 
-// 0 = suppress prompting for incompatibilities if there are updates available
-//     to newer versions of installed addons that resolve them.
-// 1 = suppress prompting for incompatibilities only if there are VersionInfo
-//     updates available to installed addons that resolve them, not newer
-//     versions.
-pref("app.update.incompatible.mode", 0);
-
 // Whether or not to attempt using the service for updates.
 #ifdef MOZ_MAINTENANCE_SERVICE
 pref("app.update.service.enabled", true);
 #endif
 
 // Symmetric (can be overridden by individual extensions) update preferences.
 // e.g.
 //  extensions.{GUID}.update.enabled
@@ -1052,17 +1042,16 @@ pref("services.sync.prefs.sync.accessibi
 pref("services.sync.prefs.sync.accessibility.typeaheadfind", true);
 pref("services.sync.prefs.sync.accessibility.typeaheadfind.linksonly", true);
 pref("services.sync.prefs.sync.addons.ignoreUserEnabledChanges", true);
 // The addons prefs related to repository verification are intentionally
 // not synced for security reasons. If a system is compromised, a user
 // could weaken the pref locally, install an add-on from an untrusted
 // source, and this would propagate automatically to other,
 // uncompromised Sync-connected devices.
-pref("services.sync.prefs.sync.app.update.mode", true);
 pref("services.sync.prefs.sync.browser.formfill.enable", true);
 pref("services.sync.prefs.sync.browser.link.open_newwindow", true);
 pref("services.sync.prefs.sync.browser.newtabpage.enabled", true);
 pref("services.sync.prefs.sync.browser.newtabpage.enhanced", true);
 pref("services.sync.prefs.sync.browser.newtabpage.pinned", true);
 pref("services.sync.prefs.sync.browser.offline-apps.notify", true);
 pref("services.sync.prefs.sync.browser.safebrowsing.enabled", true);
 pref("services.sync.prefs.sync.browser.safebrowsing.malware.enabled", true);
--- a/browser/base/content/aboutDialog-appUpdater.js
+++ b/browser/base/content/aboutDialog-appUpdater.js
@@ -1,17 +1,16 @@
 /* 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/. */
 
 // Note: this file is included in aboutDialog.xul if MOZ_UPDATER is defined.
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
-Components.utils.import("resource://gre/modules/AddonManager.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
                                   "resource://gre/modules/UpdateUtils.jsm");
 
 var gAppUpdater;
 
 function onUnload(aEvent) {
   if (gAppUpdater.isChecking)
@@ -186,31 +185,16 @@ appUpdater.prototype =
   checkForUpdates: function() {
     this.selectPanel("checkingForUpdates");
     this.isChecking = true;
     this.checker.checkForUpdates(this.updateCheckListener, true);
     // after checking, onCheckComplete() is called
   },
 
   /**
-   * Check for addon compat, or start the download right away
-   */
-  doUpdate: function() {
-    // skip the compatibility check if the update doesn't provide appVersion,
-    // or the appVersion is unchanged, e.g. nightly update
-    if (!this.update.appVersion ||
-        Services.vc.compare(gAppUpdater.update.appVersion,
-                            Services.appinfo.version) == 0) {
-      this.startDownload();
-    } else {
-      this.checkAddonCompatibility();
-    }
-  },
-
-  /**
    * Handles oncommand for the "Restart to Update" button
    * which is presented after the download has been downloaded.
    */
   buttonRestartAfterDownload: function() {
     if (!this.isPending && !this.isApplied)
       return;
 
       // Notify all windows that an application quit has been requested.
@@ -232,17 +216,17 @@ appUpdater.prototype =
       }
 
       appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit |
                       Components.interfaces.nsIAppStartup.eRestart);
     },
 
   /**
    * Handles oncommand for the "Apply Update…" button
-   * which is presented if we need to show the billboard or license.
+   * which is presented if we need to show the billboard.
    */
   buttonApplyBillboard: function() {
     const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul";
     var ary = null;
     ary = Components.classes["@mozilla.org/supports-array;1"].
           createInstance(Components.interfaces.nsISupportsArray);
     ary.AppendElement(this.update);
     var openFeatures = "chrome,centerscreen,dialog=no,resizable=no,titlebar,toolbar=no";
@@ -277,25 +261,23 @@ appUpdater.prototype =
         return;
       }
 
       if (!gAppUpdater.aus.canApplyUpdates) {
         gAppUpdater.selectPanel("manualUpdate");
         return;
       }
 
-      // Firefox no longer displays a license for updates and the licenseURL
-      // check is just in case a distibution does.
-      if (gAppUpdater.update.billboardURL || gAppUpdater.update.licenseURL) {
+      if (gAppUpdater.update.billboardURL) {
         gAppUpdater.selectPanel("applyBillboard");
         return;
       }
 
       if (gAppUpdater.updateAuto) // automatically download and install
-        gAppUpdater.doUpdate();
+        gAppUpdater.startDownload();
       else // ask
         gAppUpdater.selectPanel("downloadAndInstall");
     },
 
     /**
      * See nsIUpdateService.idl
      */
     onError: function(aRequest, aUpdate) {
@@ -313,128 +295,16 @@ appUpdater.prototype =
       if (!aIID.equals(Components.interfaces.nsIUpdateCheckListener) &&
           !aIID.equals(Components.interfaces.nsISupports))
         throw Components.results.NS_ERROR_NO_INTERFACE;
       return this;
     }
   },
 
   /**
-   * Checks the compatibility of add-ons for the application update.
-   */
-  checkAddonCompatibility: function() {
-    try {
-      var hotfixID = Services.prefs.getCharPref(PREF_EM_HOTFIX_ID);
-    }
-    catch (e) { }
-
-    var self = this;
-    AddonManager.getAllAddons(function(aAddons) {
-      self.addons = [];
-      self.addonsCheckedCount = 0;
-      aAddons.forEach(function(aAddon) {
-        // Protect against code that overrides the add-ons manager and doesn't
-        // implement the isCompatibleWith or the findUpdates method.
-        if (!("isCompatibleWith" in aAddon) || !("findUpdates" in aAddon)) {
-          let errMsg = "Add-on doesn't implement either the isCompatibleWith " +
-                       "or the findUpdates method!";
-          if (aAddon.id)
-            errMsg += " Add-on ID: " + aAddon.id;
-          Components.utils.reportError(errMsg);
-          return;
-        }
-
-        // If an add-on isn't appDisabled and isn't userDisabled then it is
-        // either active now or the user expects it to be active after the
-        // restart. If that is the case and the add-on is not installed by the
-        // application and is not compatible with the new application version
-        // then the user should be warned that the add-on will become
-        // incompatible. If an addon's type equals plugin it is skipped since
-        // checking plugins compatibility information isn't supported and
-        // getting the scope property of a plugin breaks in some environments
-        // (see bug 566787). The hotfix add-on is also ignored as it shouldn't
-        // block the user from upgrading.
-        try {
-          if (aAddon.type != "plugin" && aAddon.id != hotfixID &&
-              !aAddon.appDisabled && !aAddon.userDisabled &&
-              aAddon.scope != AddonManager.SCOPE_APPLICATION &&
-              aAddon.isCompatible &&
-              !aAddon.isCompatibleWith(self.update.appVersion,
-                                       self.update.platformVersion))
-            self.addons.push(aAddon);
-        }
-        catch (e) {
-          Components.utils.reportError(e);
-        }
-      });
-      self.addonsTotalCount = self.addons.length;
-      if (self.addonsTotalCount == 0) {
-        self.startDownload();
-        return;
-      }
-
-      self.checkAddonsForUpdates();
-    });
-  },
-
-  /**
-   * Checks if there are updates for add-ons that are incompatible with the
-   * application update.
-   */
-  checkAddonsForUpdates: function() {
-    this.addons.forEach(function(aAddon) {
-      aAddon.findUpdates(this, AddonManager.UPDATE_WHEN_NEW_APP_DETECTED,
-                         this.update.appVersion,
-                         this.update.platformVersion);
-    }, this);
-  },
-
-  /**
-   * See XPIProvider.jsm
-   */
-  onCompatibilityUpdateAvailable: function(aAddon) {
-    for (var i = 0; i < this.addons.length; ++i) {
-      if (this.addons[i].id == aAddon.id) {
-        this.addons.splice(i, 1);
-        break;
-      }
-    }
-  },
-
-  /**
-   * See XPIProvider.jsm
-   */
-  onUpdateAvailable: function(aAddon, aInstall) {
-    if (!Services.blocklist.isAddonBlocklisted(aAddon,
-                                               this.update.appVersion,
-                                               this.update.platformVersion)) {
-      // Compatibility or new version updates mean the same thing here.
-      this.onCompatibilityUpdateAvailable(aAddon);
-    }
-  },
-
-  /**
-   * See XPIProvider.jsm
-   */
-  onUpdateFinished: function(aAddon) {
-    ++this.addonsCheckedCount;
-
-    if (this.addonsCheckedCount < this.addonsTotalCount)
-      return;
-
-    if (this.addons.length == 0) {
-      // Compatibility updates or new version updates were found for all add-ons
-      this.startDownload();
-      return;
-    }
-
-    this.selectPanel("applyBillboard");
-  },
-
-  /**
    * Starts the download of an update mar.
    */
   startDownload: function() {
     if (!this.update)
       this.update = this.um.activeUpdate;
     this.update.QueryInterface(Components.interfaces.nsIWritablePropertyBag);
     this.update.setProperty("foregroundDownload", "true");
 
--- a/browser/base/content/aboutDialog.js
+++ b/browser/base/content/aboutDialog.js
@@ -1,18 +1,16 @@
 /* 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/. */
 
 // Services = object with smart getters for common XPCOM services
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/AppConstants.jsm");
 
-const PREF_EM_HOTFIX_ID = "extensions.hotfix.id";
-
 function init(aEvent)
 {
   if (aEvent.target != document)
     return;
 
   try {
     var distroId = Services.prefs.getCharPref("distribution.id");
     if (distroId) {
--- a/browser/branding/aurora/pref/firefox-branding.js
+++ b/browser/branding/aurora/pref/firefox-branding.js
@@ -8,18 +8,18 @@ pref("startup.homepage_override_url", ""
 pref("startup.homepage_welcome_url", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/firstrun/");
 pref("startup.homepage_welcome_url.additional", "");
 // The time interval between checks for a new version (in seconds)
 pref("app.update.interval", 28800); // 8 hours
 // The time interval between the downloading of mar file chunks in the
 // background (in seconds)
 // 0 means "download everything at once"
 pref("app.update.download.backgroundInterval", 0);
-// Give the user x seconds to react before showing the big UI. default=168 hours
-pref("app.update.promptWaitTime", 604800);
+// Give the user x seconds to react before showing the big UI. default=184 hours
+pref("app.update.promptWaitTime", 691200);
 // URL user can browse to manually if for some reason all update installation
 // attempts fail.
 pref("app.update.url.manual", "https://www.mozilla.org/firefox/aurora/");
 // A default value for the "More information about this update" link
 // supplied in the "An update is available" page of the update wizard.
 pref("app.update.url.details", "https://www.mozilla.org/firefox/aurora/");
 
 // The number of days a binary is permitted to be old
--- a/browser/branding/official/pref/firefox-branding.js
+++ b/browser/branding/official/pref/firefox-branding.js
@@ -5,18 +5,18 @@
 pref("startup.homepage_override_url", "");
 pref("startup.homepage_welcome_url", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/firstrun/");
 pref("startup.homepage_welcome_url.additional", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/firstrun/learnmore/");
 // Interval: Time between checks for a new version (in seconds)
 pref("app.update.interval", 43200); // 12 hours
 // The time interval between the downloading of mar file chunks in the
 // background (in seconds)
 pref("app.update.download.backgroundInterval", 60);
-// Give the user x seconds to react before showing the big UI. default=48 hours
-pref("app.update.promptWaitTime", 172800);
+// Give the user x seconds to react before showing the big UI. default=184 hours
+pref("app.update.promptWaitTime", 691200);
 // URL user can browse to manually if for some reason all update installation
 // attempts fail.
 pref("app.update.url.manual", "https://www.mozilla.org/firefox/");
 // A default value for the "More information about this update" link
 // supplied in the "An update is available" page of the update wizard.
 pref("app.update.url.details", "https://www.mozilla.org/%LOCALE%/firefox/notes");
 
 // The number of days a binary is permitted to be old
--- a/browser/components/preferences/in-content/advanced.js
+++ b/browser/components/preferences/in-content/advanced.js
@@ -632,60 +632,43 @@ var gAdvancedPane = {
 
   // UPDATE TAB
 
   /*
    * Preferences:
    *
    * app.update.enabled
    * - true if updates to the application are enabled, false otherwise
+   * app.update.auto
+   * - true if updates should be automatically downloaded and installed and
+   * false if the user should be asked what he wants to do when an update is
+   * available
    * extensions.update.enabled
    * - true if updates to extensions and themes are enabled, false otherwise
    * browser.search.update
    * - true if updates to search engines are enabled, false otherwise
-   * app.update.auto
-   * - true if updates should be automatically downloaded and installed,
-   *   possibly with a warning if incompatible extensions are installed (see
-   *   app.update.mode); false if the user should be asked what he wants to do
-   *   when an update is available
-   * app.update.mode
-   * - an integer:
-   *     0    do not warn if an update will disable extensions or themes
-   *     1    warn if an update will disable extensions or themes
-   *     2    warn if an update will disable extensions or themes *or* if the
-   *          update is a major update
    */
 
 #ifdef MOZ_UPDATER
   /**
-   * Selects the item of the radiogroup, and sets the warnIncompatible checkbox
-   * based on the pref values and locked states.
+   * Selects the item of the radiogroup based on the pref values and locked
+   * states.
    *
    * UI state matrix for update preference conditions
    *
    * UI Components:                              Preferences
    * Radiogroup                                  i   = app.update.enabled
-   * Warn before disabling extensions checkbox   ii  = app.update.auto
-   *                                             iii = app.update.mode
+   *                                             ii  = app.update.auto
    *
    * Disabled states:
    * Element           pref  value  locked  disabled
    * radiogroup        i     t/f    f       false
    *                   i     t/f    *t*     *true*
    *                   ii    t/f    f       false
    *                   ii    t/f    *t*     *true*
-   *                   iii   0/1/2  t/f     false
-   * warnIncompatible  i     t      f       false
-   *                   i     t      *t*     *true*
-   *                   i     *f*    t/f     *true*
-   *                   ii    t      f       false
-   *                   ii    t      *t*     *true*
-   *                   ii    *f*    t/f     *true*
-   *                   iii   0/1/2  f       false
-   *                   iii   0/1/2  *t*     *true*
    */
   updateReadPrefs: function ()
   {
     var enabledPref = document.getElementById("app.update.enabled");
     var autoPref = document.getElementById("app.update.auto");
     var radiogroup = document.getElementById("updateRadioGroup");
 
     if (!enabledPref.value)   // Don't care for autoPref.value in this case.
@@ -698,22 +681,16 @@ var gAdvancedPane = {
     var canCheck = Components.classes["@mozilla.org/updates/update-service;1"].
                      getService(Components.interfaces.nsIApplicationUpdateService).
                      canCheckForUpdates;
     // canCheck is false if the enabledPref is false and locked,
     // or the binary platform or OS version is not known.
     // A locked pref is sufficient to disable the radiogroup.
     radiogroup.disabled = !canCheck || enabledPref.locked || autoPref.locked;
 
-    var modePref = document.getElementById("app.update.mode");
-    var warnIncompatible = document.getElementById("warnIncompatible");
-    // the warnIncompatible checkbox value is set by readAddonWarn
-    warnIncompatible.disabled = radiogroup.disabled || modePref.locked ||
-                                !enabledPref.value || !autoPref.value;
-
 #ifdef MOZ_MAINTENANCE_SERVICE
     // Check to see if the maintenance service is installed.
     // If it is don't show the preference at all.
     var installed;
     try {
       var wrk = Components.classes["@mozilla.org/windows-registry-key;1"]
                 .createInstance(Components.interfaces.nsIWindowsRegKey);
       wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE,
@@ -725,84 +702,36 @@ var gAdvancedPane = {
     }
     if (installed != 1) {
       document.getElementById("useService").hidden = true;
     }
 #endif
   },
 
   /**
-   * Sets the pref values based on the selected item of the radiogroup,
-   * and sets the disabled state of the warnIncompatible checkbox accordingly.
+   * Sets the pref values based on the selected item of the radiogroup.
    */
   updateWritePrefs: function ()
   {
     var enabledPref = document.getElementById("app.update.enabled");
     var autoPref = document.getElementById("app.update.auto");
-    var modePref = document.getElementById("app.update.mode");
     var radiogroup = document.getElementById("updateRadioGroup");
     switch (radiogroup.value) {
       case "auto":      // 1. Automatically install updates for Desktop only
         enabledPref.value = true;
         autoPref.value = true;
         break;
       case "checkOnly": // 2. Check, but let me choose
         enabledPref.value = true;
         autoPref.value = false;
         break;
       case "manual":    // 3. Never check for updates.
         enabledPref.value = false;
         autoPref.value = false;
     }
-
-    var warnIncompatible = document.getElementById("warnIncompatible");
-    warnIncompatible.disabled = enabledPref.locked || !enabledPref.value ||
-                                autoPref.locked || !autoPref.value ||
-                                modePref.locked;
-  },
-
-  /**
-   * Stores the value of the app.update.mode preference, which is a tristate
-   * integer preference.  We store the value here so that we can properly
-   * restore the preference value if the UI reflecting the preference value
-   * is in a state which can represent either of two integer values (as
-   * opposed to only one possible value in the other UI state).
-   */
-  _modePreference: -1,
-
-  /**
-   * Reads the app.update.mode preference and converts its value into a
-   * true/false value for use in determining whether the "Warn me if this will
-   * disable extensions or themes" checkbox is checked.  We also save the value
-   * of the preference so that the preference value can be properly restored if
-   * the user's preferences cannot adequately be expressed by a single checkbox.
-   *
-   * app.update.mode          Checkbox State    Meaning
-   * 0                        Unchecked         Do not warn
-   * 1                        Checked           Warn if there are incompatibilities
-   * 2                        Checked           Warn if there are incompatibilities,
-   *                                            or the update is major.
-   */
-  readAddonWarn: function ()
-  {
-    var preference = document.getElementById("app.update.mode");
-    var warn = preference.value != 0;
-    gAdvancedPane._modePreference = warn ? preference.value : 1;
-    return warn;
-  },
-
-  /**
-   * Converts the state of the "Warn me if this will disable extensions or
-   * themes" checkbox into the integer preference which represents it,
-   * returning that value.
-   */
-  writeAddonWarn: function ()
-  {
-    var warnIncompatible = document.getElementById("warnIncompatible");
-    return !warnIncompatible.checked ? 0 : gAdvancedPane._modePreference;
   },
 
   /**
    * Displays the history of installed updates.
    */
   showUpdates: function ()
   {
     var prompter = Components.classes["@mozilla.org/updates/update-prompt;1"]
--- a/browser/components/preferences/in-content/advanced.xul
+++ b/browser/components/preferences/in-content/advanced.xul
@@ -70,19 +70,16 @@
  <!-- Update tab -->
 #ifdef MOZ_UPDATER
   <preference id="app.update.enabled"
               name="app.update.enabled"
               type="bool"/>
   <preference id="app.update.auto"
               name="app.update.auto"
               type="bool"/>
-  <preference id="app.update.mode"
-              name="app.update.mode"
-              type="int"/>
 
   <preference id="app.update.disable_button.showUpdateHistory"
               name="app.update.disable_button.showUpdateHistory"
               type="bool"/>
 
 #ifdef MOZ_MAINTENANCE_SERVICE
   <preference id="app.update.service.enabled"
               name="app.update.service.enabled"
@@ -331,24 +328,16 @@
 #ifdef MOZ_UPDATER
       <groupbox id="updateApp" align="start">
         <caption><label>&updateApp.label;</label></caption>
         <radiogroup id="updateRadioGroup" align="start">
           <radio id="autoDesktop"
                  value="auto"
                  label="&updateAuto1.label;"
                  accesskey="&updateAuto1.accesskey;"/>
-          <hbox class="indent">
-            <checkbox id="warnIncompatible"
-                      label="&updateAutoAddonWarn.label;"
-                      accesskey="&updateAutoAddonWarn.accesskey;"
-                      preference="app.update.mode"
-                      onsyncfrompreference="return gAdvancedPane.readAddonWarn();"
-                      onsynctopreference="return gAdvancedPane.writeAddonWarn();"/>
-          </hbox>
           <radio value="checkOnly"
                 label="&updateCheck.label;"
                 accesskey="&updateCheck.accesskey;"/>
           <radio value="manual"
                 label="&updateManual.label;"
                 accesskey="&updateManual.accesskey;"/>
         </radiogroup>
         <separator class="thin"/>
--- a/browser/components/sessionstore/test/browser.ini
+++ b/browser/components/sessionstore/test/browser.ini
@@ -152,17 +152,17 @@ skip-if = true
 [browser_500328.js]
 [browser_514751.js]
 [browser_522375.js]
 [browser_522545.js]
 [browser_524745.js]
 [browser_528776.js]
 [browser_579868.js]
 [browser_579879.js]
-skip-if = os == "linux" && e10s && debug # Bug 1234404 - Intermittent | Found an unexpected tab at the end of test run about:blank
+skip-if = (os == 'linux' && e10s && (debug||asan)) # Bug 1234404
 [browser_581937.js]
 [browser_586147.js]
 [browser_586068-apptabs.js]
 [browser_586068-apptabs_ondemand.js]
 [browser_586068-browser_state_interrupted.js]
 [browser_586068-cascade.js]
 [browser_586068-multi_window.js]
 [browser_586068-reload.js]
--- a/browser/extensions/moz.build
+++ b/browser/extensions/moz.build
@@ -4,9 +4,10 @@
 # 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/.
 
 DIRS += [
     'e10srollout',
     'loop',
     'pdfjs',
     'pocket',
+    'webcompat',
 ]
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/bootstrap.js
@@ -0,0 +1,10 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// for now we ship a stub, that can be upgraded as-needed after release
+function startup() {}
+function shutdown() {}
+function install() {}
+function uninstall() {}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/install.rdf.in
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!-- 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/. -->
+
+#filter substitution
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>webcompat@mozilla.org</em:id>
+    <em:version>1.0</em:version>
+    <em:type>2</em:type>
+    <em:bootstrap>true</em:bootstrap>
+
+    <!-- Target Application this theme can install into,
+        with minimum and maximum supported versions. -->
+    <em:targetApplication>
+      <Description>
+        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+        <em:minVersion>@FIREFOX_VERSION@</em:minVersion>
+        <em:maxVersion>@FIREFOX_VERSION@</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+
+    <!-- Front End MetaData -->
+    <em:name>Web Compat</em:name>
+    <em:description>Urgent post-release fixes for web compatibility.</em:description>
+  </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/moz.build
@@ -0,0 +1,15 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+FINAL_TARGET_FILES.features['webcompat@mozilla.org'] += [
+  'bootstrap.js'
+]
+
+FINAL_TARGET_PP_FILES.features['webcompat@mozilla.org'] += [
+  'install.rdf.in'
+]
+
+BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/test/browser.ini
@@ -0,0 +1,3 @@
+[DEFAULT]
+
+[browser_webcompat_stub_check.js]
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/test/browser_webcompat_stub_check.js
@@ -0,0 +1,15 @@
+"use strict";
+
+// make sure that the stub is present and enabled
+add_task(function* stub_enabled() {
+  let addon = yield new Promise(
+    resolve => AddonManager.getAddonByID("webcompat@mozilla.org", resolve)
+  );
+  isnot(addon, null, "Webcompat stub addon should exist");
+  is(addon.version, "1.0");
+  is(addon.name, "Web Compat");
+  ok(addon.isCompatible, "Webcompat stub addon is compatible with Firefox");
+  ok(!addon.appDisabled, "Webcompat stub addon is not app disabled");
+  ok(addon.isActive, "Webcompat stub addon is active");
+  is(addon.type, "extension", "Webcompat stub addon is type extension");
+});
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -827,20 +827,16 @@ bin/libfreebl_32int64_3.so
 #endif
 #endif
 @RESPATH@/browser/crashreporter-override.ini
 #ifdef MOZ_CRASHREPORTER_INJECTOR
 @BINPATH@/breakpadinjector.dll
 #endif
 #endif
 
-@RESPATH@/components/DataStore.manifest
-@RESPATH@/components/DataStoreImpl.js
-@RESPATH@/components/dom_datastore.xpt
-
 @RESPATH@/components/dom_audiochannel.xpt
 
 ; Shutdown Terminator
 @RESPATH@/components/nsTerminatorTelemetry.js
 @RESPATH@/components/terminator.manifest
 
 #if defined(CLANG_CXX)
 #if defined(MOZ_ASAN) || defined(MOZ_TSAN)
--- a/browser/locales/en-US/chrome/browser/preferences/advanced.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/advanced.dtd
@@ -78,19 +78,16 @@
 <!ENTITY updateApp.label                 "&brandShortName; updates:">
 <!ENTITY updateAuto1.label               "Automatically install updates (recommended: improved security)">
 <!ENTITY updateAuto1.accesskey           "A">
 <!ENTITY updateCheck.label               "Check for updates, but let me choose whether to install them">
 <!ENTITY updateCheck.accesskey           "C">
 <!ENTITY updateManual.label              "Never check for updates (not recommended: security risk)">
 <!ENTITY updateManual.accesskey          "N">
 
-<!ENTITY updateAutoAddonWarn.label       "Warn me if this will disable any of my add-ons">
-<!ENTITY updateAutoAddonWarn.accesskey   "W">
-
 <!ENTITY updateHistory.label             "Show Update History">
 <!ENTITY updateHistory.accesskey         "p">
 
 <!ENTITY useService.label                "Use a background service to install updates">
 <!ENTITY useService.accesskey            "b">
 
 <!ENTITY updateOthers.label              "Automatically update:">
 <!ENTITY enableSearchUpdate.label        "Search Engines">
--- a/browser/modules/WindowsPreviewPerTab.jsm
+++ b/browser/modules/WindowsPreviewPerTab.jsm
@@ -45,48 +45,44 @@ this.EXPORTED_SYMBOLS = ["AeroPeek"];
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/NetUtil.jsm");
 Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/PageThumbs.jsm");
 
 // Pref to enable/disable preview-per-tab
 const TOGGLE_PREF_NAME = "browser.taskbar.previews.enable";
 // Pref to determine the magic auto-disable threshold
 const DISABLE_THRESHOLD_PREF_NAME = "browser.taskbar.previews.max";
 // Pref to control the time in seconds that tab contents live in the cache
 const CACHE_EXPIRATION_TIME_PREF_NAME = "browser.taskbar.previews.cachetime";
 
 const WINTASKBAR_CONTRACTID = "@mozilla.org/windows-taskbar;1";
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Various utility properties
-XPCOMUtils.defineLazyServiceGetter(this, "ioSvc",
-                                   "@mozilla.org/network/io-service;1",
-                                   "nsIIOService");
 XPCOMUtils.defineLazyServiceGetter(this, "imgTools",
                                    "@mozilla.org/image/tools;1",
                                    "imgITools");
 XPCOMUtils.defineLazyServiceGetter(this, "faviconSvc",
                                    "@mozilla.org/browser/favicon-service;1",
                                    "nsIFaviconService");
 
 // nsIURI -> imgIContainer
 function _imageFromURI(doc, uri, privateMode, callback) {
-  let channel = ioSvc.newChannelFromURI2(uri,
-                                         null,
-                                         Services.scriptSecurityManager.getSystemPrincipal(),
-                                         null,
-                                         Ci.nsILoadInfo.SEC_NORMAL,
-                                         Ci.nsIContentPolicy.TYPE_INTERNAL_IMAGE);
+  let channel = NetUtil.newChannel({
+    uri: uri,
+    loadUsingSystemPrincipal: true,
+    contentPolicyType: Ci.nsIContentPolicy.TYPE_INTERNAL_IMAGE
+  });
+
   try {
     channel.QueryInterface(Ci.nsIPrivateBrowsingChannel);
     channel.setPrivate(privateMode);
   } catch (e) {
     // Ignore channels which do not support nsIPrivateBrowsingChannel
   }
   NetUtil.asyncFetch(channel, function(inputStream, resultCode) {
     if (!Components.isSuccessCode(resultCode))
--- a/build/clang-plugin/clang-plugin.cpp
+++ b/build/clang-plugin/clang-plugin.cpp
@@ -331,17 +331,17 @@ static CustomTypeAnnotation GlobalClass 
     CustomTypeAnnotation("moz_global_class", "global");
 static CustomTypeAnnotation NonHeapClass =
     CustomTypeAnnotation("moz_nonheap_class", "non-heap");
 static CustomTypeAnnotation HeapClass =
     CustomTypeAnnotation("moz_heap_class", "heap");
 static CustomTypeAnnotation NonTemporaryClass =
     CustomTypeAnnotation("moz_non_temporary_class", "non-temporary");
 static CustomTypeAnnotation MustUse =
-    CustomTypeAnnotation("moz_must_use", "must-use");
+    CustomTypeAnnotation("moz_must_use_type", "must-use");
 
 class MemMoveAnnotation final : public CustomTypeAnnotation {
 public:
   MemMoveAnnotation()
       : CustomTypeAnnotation("moz_non_memmovable", "non-memmove()able") {}
 
   virtual ~MemMoveAnnotation() {}
 
--- a/build/clang-plugin/tests/TestMultipleAnnotations.cpp
+++ b/build/clang-plugin/tests/TestMultipleAnnotations.cpp
@@ -1,12 +1,12 @@
-#define MOZ_MUST_USE __attribute__((annotate("moz_must_use")))
+#define MOZ_MUST_USE_TYPE __attribute__((annotate("moz_must_use_type")))
 #define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class")))
 
-class MOZ_MUST_USE MOZ_STACK_CLASS TestClass {};
+class MOZ_MUST_USE_TYPE MOZ_STACK_CLASS TestClass {};
 
 TestClass foo; // expected-error {{variable of type 'TestClass' only valid on the stack}} expected-note {{value incorrectly allocated in a global variable}}
 
 TestClass f()
 {
   TestClass bar;
   return bar;
 }
--- a/build/clang-plugin/tests/TestMustUse.cpp
+++ b/build/clang-plugin/tests/TestMustUse.cpp
@@ -1,12 +1,12 @@
-#define MOZ_MUST_USE __attribute__((annotate("moz_must_use")))
+#define MOZ_MUST_USE_TYPE __attribute__((annotate("moz_must_use_type")))
 
 struct Temporary { ~Temporary(); };
-class MOZ_MUST_USE MustUse {};
+class MOZ_MUST_USE_TYPE MustUse {};
 class MayUse {};
 
 MustUse producesMustUse();
 MustUse *producesMustUsePointer();
 MustUse &producesMustUseRef();
 
 MustUse producesMustUse(const Temporary& t);
 MustUse *producesMustUsePointer(const Temporary& t);
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/Animation.cpp
@@ -3,20 +3,20 @@
 /* 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 "Animation.h"
 #include "AnimationUtils.h"
 #include "mozilla/dom/AnimationBinding.h"
 #include "mozilla/dom/AnimationPlaybackEvent.h"
+#include "mozilla/AnimationTarget.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/AsyncEventDispatcher.h" // For AsyncEventDispatcher
 #include "mozilla/Maybe.h" // For Maybe
-#include "mozilla/NonOwningAnimationTarget.h"
 #include "nsAnimationManager.h" // For CSSAnimation
 #include "nsDOMMutationObserver.h" // For nsAutoAnimationMutationBatch
 #include "nsIDocument.h" // For nsIDocument
 #include "nsIPresShell.h" // For nsIPresShell
 #include "nsLayoutUtils.h" // For PostRestyleEvent (remove after bug 1073336)
 #include "nsThreadUtils.h" // For nsRunnableMethod and nsRevocableEventPtr
 #include "nsTransitionManager.h" // For CSSTransition
 #include "PendingAnimationTracker.h" // For PendingAnimationTracker
rename from dom/animation/NonOwningAnimationTarget.h
rename to dom/animation/AnimationTarget.h
--- a/dom/animation/NonOwningAnimationTarget.h
+++ b/dom/animation/AnimationTarget.h
@@ -1,32 +1,78 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef mozilla_NonOwningAnimationTarget_h
-#define mozilla_NonOwningAnimationTarget_h
+#ifndef mozilla_AnimationTarget_h
+#define mozilla_AnimationTarget_h
 
 #include "mozilla/Attributes.h"   // For MOZ_NON_OWNING_REF
+#include "mozilla/Maybe.h"
+#include "mozilla/RefPtr.h"
 #include "nsCSSPseudoElements.h"
 
 namespace mozilla {
 
 namespace dom {
 class Element;
 } // namespace dom
 
+struct OwningAnimationTarget
+{
+  OwningAnimationTarget(dom::Element* aElement, CSSPseudoElementType aType)
+    : mElement(aElement), mPseudoType(aType) { }
+
+  explicit OwningAnimationTarget(dom::Element* aElement)
+    : mElement(aElement) { }
+
+  bool operator==(const OwningAnimationTarget& aOther) const
+  {
+     return mElement == aOther.mElement &&
+            mPseudoType == aOther.mPseudoType;
+  }
+
+  // mElement represents the parent element of a pseudo-element, not the
+  // generated content element.
+  RefPtr<dom::Element> mElement;
+  CSSPseudoElementType mPseudoType = CSSPseudoElementType::NotPseudo;
+};
+
 struct NonOwningAnimationTarget
 {
   NonOwningAnimationTarget(dom::Element* aElement, CSSPseudoElementType aType)
     : mElement(aElement), mPseudoType(aType) { }
 
+  explicit NonOwningAnimationTarget(const OwningAnimationTarget& aOther)
+    : mElement(aOther.mElement), mPseudoType(aOther.mPseudoType) { }
+
   // mElement represents the parent element of a pseudo-element, not the
   // generated content element.
   dom::Element* MOZ_NON_OWNING_REF mElement = nullptr;
   CSSPseudoElementType mPseudoType = CSSPseudoElementType::NotPseudo;
 };
 
+
+// Helper functions for cycle-collecting Maybe<OwningAnimationTarget>
+inline void
+ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
+                            Maybe<OwningAnimationTarget>& aTarget,
+                            const char* aName,
+                            uint32_t aFlags = 0)
+{
+  if (aTarget) {
+    ImplCycleCollectionTraverse(aCallback, aTarget->mElement, aName, aFlags);
+  }
+}
+
+inline void
+ImplCycleCollectionUnlink(Maybe<OwningAnimationTarget>& aTarget)
+{
+  if (aTarget) {
+    ImplCycleCollectionUnlink(aTarget->mElement);
+  }
+}
+
 } // namespace mozilla
 
-#endif // mozilla_NonOwningAnimationTarget_h
+#endif // mozilla_AnimationTarget_h
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -4,18 +4,19 @@
  * 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 "EffectCompositor.h"
 
 #include "mozilla/dom/Animation.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/KeyframeEffect.h" // For KeyframeEffectReadOnly
+#include "mozilla/AnimationPerformanceWarning.h"
+#include "mozilla/AnimationTarget.h"
 #include "mozilla/AnimationUtils.h"
-#include "mozilla/AnimationPerformanceWarning.h"
 #include "mozilla/EffectSet.h"
 #include "mozilla/InitializerList.h"
 #include "mozilla/LayerAnimationInfo.h"
 #include "mozilla/RestyleManagerHandle.h"
 #include "mozilla/RestyleManagerHandleInlines.h"
 #include "nsComputedDOMStyle.h" // nsComputedDOMStyle::GetPresShellForContent
 #include "nsCSSPropertySet.h"
 #include "nsCSSProps.h"
--- a/dom/animation/EffectCompositor.h
+++ b/dom/animation/EffectCompositor.h
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_EffectCompositor_h
 #define mozilla_EffectCompositor_h
 
 #include "mozilla/EnumeratedArray.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/OwningNonNull.h"
-#include "mozilla/NonOwningAnimationTarget.h"
 #include "mozilla/PseudoElementHashEntry.h"
 #include "mozilla/RefPtr.h"
 #include "nsCSSProperty.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDataHashtable.h"
 #include "nsIStyleRuleProcessor.h"
 #include "nsTArray.h"
 
@@ -25,16 +24,17 @@ class nsIStyleRule;
 class nsPresContext;
 class nsStyleContext;
 
 namespace mozilla {
 
 class EffectSet;
 class RestyleTracker;
 struct AnimationPerformanceWarning;
+struct NonOwningAnimationTarget;
 
 namespace dom {
 class Animation;
 class Element;
 }
 
 class EffectCompositor
 {
--- a/dom/animation/KeyframeEffect.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -4,17 +4,16 @@
  * 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 "mozilla/dom/KeyframeEffect.h"
 
 #include "mozilla/dom/AnimatableBinding.h"
 #include "mozilla/dom/KeyframeEffectBinding.h"
 #include "mozilla/AnimationUtils.h"
-#include "mozilla/EffectCompositor.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/LookAndFeel.h" // For LookAndFeel::GetInt
 #include "mozilla/KeyframeUtils.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "Layers.h" // For Layer
 #include "nsComputedDOMStyle.h" // nsComputedDOMStyle::GetStyleContextForElement
 #include "nsCSSPropertySet.h"
 #include "nsCSSProps.h" // For nsCSSProps::PropHasFlags
@@ -71,38 +70,34 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(KeyframeEffectReadOnly)
 NS_INTERFACE_MAP_END_INHERITING(AnimationEffectReadOnly)
 
 NS_IMPL_ADDREF_INHERITED(KeyframeEffectReadOnly, AnimationEffectReadOnly)
 NS_IMPL_RELEASE_INHERITED(KeyframeEffectReadOnly, AnimationEffectReadOnly)
 
 KeyframeEffectReadOnly::KeyframeEffectReadOnly(
   nsIDocument* aDocument,
-  Element* aTarget,
-  CSSPseudoElementType aPseudoType,
+  const Maybe<OwningAnimationTarget>& aTarget,
   const TimingParams& aTiming)
-  : KeyframeEffectReadOnly(aDocument, aTarget, aPseudoType,
+  : KeyframeEffectReadOnly(aDocument, aTarget,
                            new AnimationEffectTimingReadOnly(aDocument,
                                                              aTiming))
 {
 }
 
 KeyframeEffectReadOnly::KeyframeEffectReadOnly(
   nsIDocument* aDocument,
-  Element* aTarget,
-  CSSPseudoElementType aPseudoType,
+  const Maybe<OwningAnimationTarget>& aTarget,
   AnimationEffectTimingReadOnly* aTiming)
   : AnimationEffectReadOnly(aDocument)
   , mTarget(aTarget)
   , mTiming(aTiming)
-  , mPseudoType(aPseudoType)
   , mInEffectOnLastAnimationTimingUpdate(false)
 {
   MOZ_ASSERT(aTiming);
-  MOZ_ASSERT(aTarget, "null animation target is not yet supported");
 }
 
 JSObject*
 KeyframeEffectReadOnly::WrapObject(JSContext* aCx,
                                    JS::Handle<JSObject*> aGivenProto)
 {
   return KeyframeEffectReadOnlyBinding::Wrap(aCx, this, aGivenProto);
 }
@@ -157,17 +152,18 @@ KeyframeEffectReadOnly::NotifyAnimationT
     ResetIsRunningOnCompositor();
   }
 
   // Detect changes to "in effect" status since we need to recalculate the
   // animation cascade for this element whenever that changes.
   bool inEffect = IsInEffect();
   if (inEffect != mInEffectOnLastAnimationTimingUpdate) {
     if (mTarget) {
-      EffectSet* effectSet = EffectSet::GetEffectSet(mTarget, mPseudoType);
+      EffectSet* effectSet = EffectSet::GetEffectSet(mTarget->mElement,
+                                                     mTarget->mPseudoType);
       if (effectSet) {
         effectSet->MarkCascadeNeedsUpdate();
       }
     }
     mInEffectOnLastAnimationTimingUpdate = inEffect;
   }
 
   // Request restyle if necessary.
@@ -183,22 +179,17 @@ KeyframeEffectReadOnly::NotifyAnimationT
   //
   // Bug 1216843: When we implement iteration composite modes, we need to
   // also detect if the current iteration has changed.
   if (mAnimation && GetComputedTiming().mProgress != mProgressOnLastCompose) {
     EffectCompositor::RestyleType restyleType =
       CanThrottle() ?
       EffectCompositor::RestyleType::Throttled :
       EffectCompositor::RestyleType::Standard;
-    nsPresContext* presContext = GetPresContext();
-    if (presContext) {
-      presContext->EffectCompositor()->
-        RequestRestyle(mTarget, mPseudoType, restyleType,
-                       mAnimation->CascadeLevel());
-    }
+    RequestRestyle(restyleType);
 
     // If we're not relevant, we will have been removed from the EffectSet.
     // As a result, when the restyle we requested above is fulfilled, our
     // ComposeStyle will not get called and mProgressOnLastCompose will not
     // be updated. Instead, we need to manually clear it.
     if (!isRelevant) {
       mProgressOnLastCompose.SetNull();
     }
@@ -455,20 +446,21 @@ KeyframeEffectReadOnly::SetFrames(JSCont
   if (aRv.Failed()) {
     return;
   }
 
   RefPtr<nsStyleContext> styleContext;
   nsIPresShell* shell = doc->GetShell();
   if (shell && mTarget) {
     nsIAtom* pseudo =
-      mPseudoType < CSSPseudoElementType::Count ?
-      nsCSSPseudoElements::GetPseudoAtom(mPseudoType) : nullptr;
+      mTarget->mPseudoType < CSSPseudoElementType::Count ?
+      nsCSSPseudoElements::GetPseudoAtom(mTarget->mPseudoType) : nullptr;
     styleContext =
-      nsComputedDOMStyle::GetStyleContextForElement(mTarget, pseudo, shell);
+      nsComputedDOMStyle::GetStyleContextForElement(mTarget->mElement,
+                                                    pseudo, shell);
   }
 
   SetFrames(Move(keyframes), styleContext);
 }
 
 void
 KeyframeEffectReadOnly::SetFrames(nsTArray<Keyframe>&& aFrames,
                                   nsStyleContext* aStyleContext)
@@ -522,18 +514,18 @@ void
 KeyframeEffectReadOnly::UpdateProperties(nsStyleContext* aStyleContext)
 {
   MOZ_ASSERT(aStyleContext);
 
   nsTArray<AnimationProperty> properties;
   if (mTarget) {
     properties =
       KeyframeUtils::GetAnimationPropertiesFromKeyframes(aStyleContext,
-                                                         mTarget,
-                                                         mPseudoType,
+                                                         mTarget->mElement,
+                                                         mTarget->mPseudoType,
                                                          mFrames);
   }
 
   if (mProperties == properties) {
     return;
   }
 
   // Preserve the state of mWinsInCascade and mIsRunningOnCompositor flags.
@@ -554,30 +546,23 @@ KeyframeEffectReadOnly::UpdateProperties
   for (AnimationProperty& property : mProperties) {
     property.mWinsInCascade =
       winningInCascadeProperties.HasProperty(property.mProperty);
     property.mIsRunningOnCompositor =
       runningOnCompositorProperties.HasProperty(property.mProperty);
   }
 
   if (mTarget) {
-    EffectSet* effectSet = EffectSet::GetEffectSet(mTarget, mPseudoType);
+    EffectSet* effectSet = EffectSet::GetEffectSet(mTarget->mElement,
+                                                   mTarget->mPseudoType);
     if (effectSet) {
       effectSet->MarkCascadeNeedsUpdate();
     }
-  }
 
-  if (mAnimation) {
-    nsPresContext* presContext = GetPresContext();
-    if (presContext) {
-      presContext->EffectCompositor()->
-        RequestRestyle(mTarget, mPseudoType,
-                       EffectCompositor::RestyleType::Layer,
-                       mAnimation->CascadeLevel());
-    }
+    RequestRestyle(EffectCompositor::RestyleType::Layer);
   }
 }
 
 void
 KeyframeEffectReadOnly::ComposeStyle(RefPtr<AnimValuesStyleRule>& aStyleRule,
                                      nsCSSPropertySet& aSetProperties)
 {
   ComputedTiming computedTiming = GetComputedTiming();
@@ -711,16 +696,39 @@ KeyframeEffectReadOnly::SetIsRunningOnCo
     }
   }
 }
 
 KeyframeEffectReadOnly::~KeyframeEffectReadOnly()
 {
 }
 
+static Maybe<OwningAnimationTarget>
+ConvertTarget(const Nullable<ElementOrCSSPseudoElement>& aTarget)
+{
+  // Return value optimization.
+  Maybe<OwningAnimationTarget> result;
+
+  if (aTarget.IsNull()) {
+    return result;
+  }
+
+  const ElementOrCSSPseudoElement& target = aTarget.Value();
+  MOZ_ASSERT(target.IsElement() || target.IsCSSPseudoElement(),
+             "Uninitialized target");
+
+  if (target.IsElement()) {
+    result.emplace(&target.GetAsElement());
+  } else {
+    RefPtr<Element> elem = target.GetAsCSSPseudoElement().ParentElement();
+    result.emplace(elem, target.GetAsCSSPseudoElement().GetType());
+  }
+  return result;
+}
+
 template <class KeyframeEffectType, class OptionsType>
 /* static */ already_AddRefed<KeyframeEffectType>
 KeyframeEffectReadOnly::ConstructKeyframeEffect(
     const GlobalObject& aGlobal,
     const Nullable<ElementOrCSSPseudoElement>& aTarget,
     JS::Handle<JSObject*> aFrames,
     const OptionsType& aOptions,
     ErrorResult& aRv)
@@ -732,38 +740,20 @@ KeyframeEffectReadOnly::ConstructKeyfram
   }
 
   TimingParams timingParams =
     TimingParams::FromOptionsUnion(aOptions, doc, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
-  if (aTarget.IsNull()) {
-    // We don't support null targets yet.
-    aRv.Throw(NS_ERROR_DOM_ANIM_NO_TARGET_ERR);
-    return nullptr;
-  }
-
-  const ElementOrCSSPseudoElement& target = aTarget.Value();
-  MOZ_ASSERT(target.IsElement() || target.IsCSSPseudoElement(),
-             "Uninitialized target");
+  Maybe<OwningAnimationTarget> target = ConvertTarget(aTarget);
+  RefPtr<KeyframeEffectType> effect =
+    new KeyframeEffectType(doc, target, timingParams);
 
-  RefPtr<Element> targetElement;
-  CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo;
-  if (target.IsElement()) {
-    targetElement = &target.GetAsElement();
-  } else {
-    targetElement = target.GetAsCSSPseudoElement().ParentElement();
-    pseudoType = target.GetAsCSSPseudoElement().GetType();
-  }
-
-  RefPtr<KeyframeEffectType> effect =
-    new KeyframeEffectType(targetElement->OwnerDoc(), targetElement,
-                           pseudoType, timingParams);
   effect->SetFrames(aGlobal.Context(), aFrames, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   return effect.forget();
 }
 
@@ -771,46 +761,73 @@ void
 KeyframeEffectReadOnly::ResetIsRunningOnCompositor()
 {
   for (AnimationProperty& property : mProperties) {
     property.mIsRunningOnCompositor = false;
   }
 }
 
 void
+KeyframeEffectReadOnly::ResetWinsInCascade()
+{
+  for (AnimationProperty& property : mProperties) {
+    property.mWinsInCascade = false;
+  }
+}
+
+void
 KeyframeEffectReadOnly::UpdateTargetRegistration()
 {
   if (!mTarget) {
     return;
   }
 
   bool isRelevant = mAnimation && mAnimation->IsRelevant();
 
   // Animation::IsRelevant() returns a cached value. It only updates when
   // something calls Animation::UpdateRelevance. Whenever our timing changes,
   // we should be notifying our Animation before calling this, so
   // Animation::IsRelevant() should be up-to-date by the time we get here.
   MOZ_ASSERT(isRelevant == IsCurrent() || IsInEffect(),
              "Out of date Animation::IsRelevant value");
 
   if (isRelevant) {
-    EffectSet* effectSet = EffectSet::GetOrCreateEffectSet(mTarget,
-                                                           mPseudoType);
+    EffectSet* effectSet =
+      EffectSet::GetOrCreateEffectSet(mTarget->mElement, mTarget->mPseudoType);
     effectSet->AddEffect(*this);
   } else {
-    EffectSet* effectSet = EffectSet::GetEffectSet(mTarget, mPseudoType);
-    if (effectSet) {
-      effectSet->RemoveEffect(*this);
-      if (effectSet->IsEmpty()) {
-        EffectSet::DestroyEffectSet(mTarget, mPseudoType);
-      }
+    UnregisterTarget();
+  }
+}
+
+void
+KeyframeEffectReadOnly::UnregisterTarget()
+{
+  EffectSet* effectSet =
+    EffectSet::GetEffectSet(mTarget->mElement, mTarget->mPseudoType);
+  if (effectSet) {
+    effectSet->RemoveEffect(*this);
+    if (effectSet->IsEmpty()) {
+      EffectSet::DestroyEffectSet(mTarget->mElement, mTarget->mPseudoType);
     }
   }
 }
 
+void
+KeyframeEffectReadOnly::RequestRestyle(
+  EffectCompositor::RestyleType aRestyleType)
+{
+  nsPresContext* presContext = GetPresContext();
+  if (presContext && mTarget && mAnimation) {
+    presContext->EffectCompositor()->
+      RequestRestyle(mTarget->mElement, mTarget->mPseudoType,
+                     aRestyleType, mAnimation->CascadeLevel());
+  }
+}
+
 #ifdef DEBUG
 void
 DumpAnimationProperties(nsTArray<AnimationProperty>& aAnimationProperties)
 {
   for (auto& p : aAnimationProperties) {
     printf("%s\n", nsCSSProps::GetStringValue(p.mProperty).get());
     for (auto& s : p.mSegments) {
       nsString fromValue, toValue;
@@ -854,25 +871,26 @@ void
 KeyframeEffectReadOnly::GetTarget(
     Nullable<OwningElementOrCSSPseudoElement>& aRv) const
 {
   if (!mTarget) {
     aRv.SetNull();
     return;
   }
 
-  switch (mPseudoType) {
+  switch (mTarget->mPseudoType) {
     case CSSPseudoElementType::before:
     case CSSPseudoElementType::after:
       aRv.SetValue().SetAsCSSPseudoElement() =
-        CSSPseudoElement::GetCSSPseudoElement(mTarget, mPseudoType);
+        CSSPseudoElement::GetCSSPseudoElement(mTarget->mElement,
+                                              mTarget->mPseudoType);
       break;
 
     case CSSPseudoElementType::NotPseudo:
-      aRv.SetValue().SetAsElement() = mTarget;
+      aRv.SetValue().SetAsElement() = mTarget->mElement;
       break;
 
     default:
       NS_NOTREACHED("Animation of unsupported pseudo-type");
       aRv.SetNull();
   }
 }
 
@@ -1068,17 +1086,18 @@ KeyframeEffectReadOnly::CanThrottle() co
         LayerAnimationInfo::sRecords) {
     // Skip properties that are overridden in the cascade.
     // (GetAnimationOfProperty, as called by HasAnimationOfProperty,
     // only returns an animation if it currently wins in the cascade.)
     if (!HasAnimationOfProperty(record.mProperty)) {
       continue;
     }
 
-    EffectSet* effectSet = EffectSet::GetEffectSet(mTarget, mPseudoType);
+    EffectSet* effectSet = EffectSet::GetEffectSet(mTarget->mElement,
+                                                   mTarget->mPseudoType);
     MOZ_ASSERT(effectSet, "CanThrottle should be called on an effect "
                           "associated with a target element");
     layers::Layer* layer =
       FrameLayerBuilder::GetDedicatedLayer(frame, record.mLayerType);
     // Unthrottle if the layer needs to be brought up to date
     if (!layer ||
         effectSet->GetAnimationGeneration() !=
           layer->GetAnimationGeneration()) {
@@ -1116,17 +1135,18 @@ KeyframeEffectReadOnly::CanThrottleTrans
   nsPresContext* presContext = GetPresContext();
   // CanThrottleTransformChanges is only called as part of a refresh driver tick
   // in which case we expect to has a pres context.
   MOZ_ASSERT(presContext);
 
   TimeStamp now =
     presContext->RefreshDriver()->MostRecentRefresh();
 
-  EffectSet* effectSet = EffectSet::GetEffectSet(mTarget, mPseudoType);
+  EffectSet* effectSet = EffectSet::GetEffectSet(mTarget->mElement,
+                                                 mTarget->mPseudoType);
   MOZ_ASSERT(effectSet, "CanThrottleTransformChanges is expected to be called"
                         " on an effect in an effect set");
   MOZ_ASSERT(mAnimation, "CanThrottleTransformChanges is expected to be called"
                          " on an effect with a parent animation");
   TimeStamp animationRuleRefreshTime =
     effectSet->AnimationRuleRefreshTime(mAnimation->CascadeLevel());
   // If this animation can cause overflow, we can throttle some of the ticks.
   if (!animationRuleRefreshTime.IsNull() &&
@@ -1154,43 +1174,43 @@ KeyframeEffectReadOnly::CanThrottleTrans
 
 nsIFrame*
 KeyframeEffectReadOnly::GetAnimationFrame() const
 {
   if (!mTarget) {
     return nullptr;
   }
 
-  nsIFrame* frame = mTarget->GetPrimaryFrame();
+  nsIFrame* frame = mTarget->mElement->GetPrimaryFrame();
   if (!frame) {
     return nullptr;
   }
 
-  if (mPseudoType == CSSPseudoElementType::before) {
+  if (mTarget->mPseudoType == CSSPseudoElementType::before) {
     frame = nsLayoutUtils::GetBeforeFrame(frame);
-  } else if (mPseudoType == CSSPseudoElementType::after) {
+  } else if (mTarget->mPseudoType == CSSPseudoElementType::after) {
     frame = nsLayoutUtils::GetAfterFrame(frame);
   } else {
-    MOZ_ASSERT(mPseudoType == CSSPseudoElementType::NotPseudo,
-               "unknown mPseudoType");
+    MOZ_ASSERT(mTarget->mPseudoType == CSSPseudoElementType::NotPseudo,
+               "unknown mTarget->mPseudoType");
   }
   if (!frame) {
     return nullptr;
   }
 
   return nsLayoutUtils::GetStyleFrame(frame);
 }
 
 nsIDocument*
 KeyframeEffectReadOnly::GetRenderedDocument() const
 {
   if (!mTarget) {
     return nullptr;
   }
-  return mTarget->GetComposedDoc();
+  return mTarget->mElement->GetComposedDoc();
 }
 
 nsPresContext*
 KeyframeEffectReadOnly::GetPresContext() const
 {
   nsIDocument* doc = GetRenderedDocument();
   if (!doc) {
     return nullptr;
@@ -1298,34 +1318,33 @@ KeyframeEffectReadOnly::SetPerformanceWa
         (!property.mPerformanceWarning ||
          *property.mPerformanceWarning != aWarning)) {
       property.mPerformanceWarning = Some(aWarning);
 
       nsXPIDLString localizedString;
       if (nsLayoutUtils::IsAnimationLoggingEnabled() &&
           property.mPerformanceWarning->ToLocalizedString(localizedString)) {
         nsAutoCString logMessage = NS_ConvertUTF16toUTF8(localizedString);
-        AnimationUtils::LogAsyncAnimationFailure(logMessage, mTarget);
+        AnimationUtils::LogAsyncAnimationFailure(logMessage, mTarget->mElement);
       }
       return;
     }
   }
 }
 
 //---------------------------------------------------------------------
 //
 // KeyframeEffect
 //
 //---------------------------------------------------------------------
 
 KeyframeEffect::KeyframeEffect(nsIDocument* aDocument,
-                               Element* aTarget,
-                               CSSPseudoElementType aPseudoType,
+                               const Maybe<OwningAnimationTarget>& aTarget,
                                const TimingParams& aTiming)
-  : KeyframeEffectReadOnly(aDocument, aTarget, aPseudoType,
+  : KeyframeEffectReadOnly(aDocument, aTarget,
                            new AnimationEffectTiming(aDocument, aTiming, this))
 {
 }
 
 JSObject*
 KeyframeEffect::WrapObject(JSContext* aCx,
                            JS::Handle<JSObject*> aGivenProto)
 {
@@ -1351,41 +1370,100 @@ KeyframeEffect::Constructor(
     JS::Handle<JSObject*> aFrames,
     const UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions,
     ErrorResult& aRv)
 {
   return ConstructKeyframeEffect<KeyframeEffect>(aGlobal, aTarget, aFrames,
                                                  aOptions, aRv);
 }
 
-void KeyframeEffect::NotifySpecifiedTimingUpdated()
+void
+KeyframeEffect::NotifySpecifiedTimingUpdated()
 {
   // Use the same document for a pseudo element and its parent element.
-  nsAutoAnimationMutationBatch mb(mTarget->OwnerDoc());
+  // Use nullptr if we don't have mTarget, so disable the mutation batch.
+  nsAutoAnimationMutationBatch mb(mTarget ? mTarget->mElement->OwnerDoc()
+                                          : nullptr);
 
   if (mAnimation) {
     mAnimation->NotifyEffectTimingUpdated();
 
     if (mAnimation->IsRelevant()) {
       nsNodeUtils::AnimationChanged(mAnimation);
     }
 
-    nsPresContext* presContext = GetPresContext();
-    if (presContext) {
-      presContext->EffectCompositor()->
-        RequestRestyle(mTarget, mPseudoType,
-                       EffectCompositor::RestyleType::Layer,
-                       mAnimation->CascadeLevel());
+    RequestRestyle(EffectCompositor::RestyleType::Layer);
+  }
+}
+
+void
+KeyframeEffect::SetTarget(const Nullable<ElementOrCSSPseudoElement>& aTarget)
+{
+  Maybe<OwningAnimationTarget> newTarget = ConvertTarget(aTarget);
+  if (mTarget == newTarget) {
+    // Assign the same target, skip it.
+    return;
+  }
+
+  if (mTarget) {
+    UnregisterTarget();
+    ResetIsRunningOnCompositor();
+    ResetWinsInCascade();
+
+    RequestRestyle(EffectCompositor::RestyleType::Layer);
+
+    nsAutoAnimationMutationBatch mb(mTarget->mElement->OwnerDoc());
+    if (mAnimation) {
+      nsNodeUtils::AnimationRemoved(mAnimation);
+    }
+  }
+
+  mTarget = newTarget;
+
+  if (mTarget) {
+    UpdateTargetRegistration();
+    MaybeUpdateProperties();
+
+    RequestRestyle(EffectCompositor::RestyleType::Layer);
+
+    nsAutoAnimationMutationBatch mb(mTarget->mElement->OwnerDoc());
+    if (mAnimation) {
+      nsNodeUtils::AnimationAdded(mAnimation);
     }
   }
 }
 
 KeyframeEffect::~KeyframeEffect()
 {
   // mTiming is cycle collected, so we have to do null check first even though
   // mTiming shouldn't be null during the lifetime of KeyframeEffect.
   if (mTiming) {
     mTiming->Unlink();
   }
 }
 
+void
+KeyframeEffect::MaybeUpdateProperties()
+{
+  if (!mTarget) {
+    return;
+  }
+
+  nsIDocument* doc = mTarget->mElement->OwnerDoc();
+  if (!doc) {
+    return;
+  }
+
+  nsIAtom* pseudo = mTarget->mPseudoType < CSSPseudoElementType::Count ?
+                    nsCSSPseudoElements::GetPseudoAtom(mTarget->mPseudoType) :
+                    nullptr;
+  RefPtr<nsStyleContext> styleContext =
+    nsComputedDOMStyle::GetStyleContextForElement(mTarget->mElement, pseudo,
+                                                  doc->GetShell());
+  if (!styleContext) {
+    return;
+  }
+
+  UpdateProperties(styleContext);
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/animation/KeyframeEffect.h
+++ b/dom/animation/KeyframeEffect.h
@@ -9,22 +9,23 @@
 
 #include "nsAutoPtr.h"
 #include "nsCSSProperty.h"
 #include "nsCSSValue.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsTArray.h"
 #include "nsWrapperCache.h"
 #include "mozilla/AnimationPerformanceWarning.h"
+#include "mozilla/AnimationTarget.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ComputedTiming.h"
 #include "mozilla/ComputedTimingFunction.h"
+#include "mozilla/EffectCompositor.h"
 #include "mozilla/LayerAnimationInfo.h" // LayerAnimations::kRecords
 #include "mozilla/Maybe.h"
-#include "mozilla/NonOwningAnimationTarget.h"
 #include "mozilla/OwningNonNull.h"      // OwningNonNull<...>
 #include "mozilla/StickyTimeDuration.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/TimingParams.h"
 #include "mozilla/dom/AnimationEffectReadOnly.h"
 #include "mozilla/dom/AnimationEffectTimingReadOnly.h"
 #include "mozilla/dom/Element.h"
@@ -185,18 +186,17 @@ struct ElementPropertyTransition;
 namespace dom {
 
 class Animation;
 
 class KeyframeEffectReadOnly : public AnimationEffectReadOnly
 {
 public:
   KeyframeEffectReadOnly(nsIDocument* aDocument,
-                         Element* aTarget,
-                         CSSPseudoElementType aPseudoType,
+                         const Maybe<OwningAnimationTarget>& aTarget,
                          const TimingParams& aTiming);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(KeyframeEffectReadOnly,
                                                         AnimationEffectReadOnly)
 
   virtual JSObject* WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aGivenProto) override;
@@ -215,17 +215,17 @@ public:
               const UnrestrictedDoubleOrKeyframeEffectOptions& aOptions,
               ErrorResult& aRv);
 
   void GetTarget(Nullable<OwningElementOrCSSPseudoElement>& aRv) const;
   Maybe<NonOwningAnimationTarget> GetTarget() const
   {
     Maybe<NonOwningAnimationTarget> result;
     if (mTarget) {
-      result.emplace(mTarget, mPseudoType);
+      result.emplace(*mTarget);
     }
     return result;
   }
   void GetFrames(JSContext*& aCx,
                  nsTArray<JSObject*>& aResult,
                  ErrorResult& aRv);
   void GetProperties(nsTArray<AnimationPropertyDetails>& aProperties,
                      ErrorResult& aRv) const;
@@ -332,48 +332,52 @@ public:
   // compositor. |aParams| and |aParamsLength| are optional parameters which
   // will be used to generate a localized message for devtools.
   void SetPerformanceWarning(
     nsCSSProperty aProperty,
     const AnimationPerformanceWarning& aWarning);
 
 protected:
   KeyframeEffectReadOnly(nsIDocument* aDocument,
-                         Element* aTarget,
-                         CSSPseudoElementType aPseudoType,
+                         const Maybe<OwningAnimationTarget>& aTarget,
                          AnimationEffectTimingReadOnly* aTiming);
 
   virtual ~KeyframeEffectReadOnly();
 
   template<class KeyframeEffectType, class OptionsType>
   static already_AddRefed<KeyframeEffectType>
   ConstructKeyframeEffect(const GlobalObject& aGlobal,
                           const Nullable<ElementOrCSSPseudoElement>& aTarget,
                           JS::Handle<JSObject*> aFrames,
                           const OptionsType& aOptions,
                           ErrorResult& aRv);
 
   void ResetIsRunningOnCompositor();
+  void ResetWinsInCascade();
 
   // This effect is registered with its target element so long as:
   //
   // (a) It has a target element, and
   // (b) It is "relevant" (i.e. yet to finish but not idle, or finished but
   //     filling forwards)
   //
   // As a result, we need to make sure this gets called whenever anything
   // changes with regards to this effects's timing including changes to the
   // owning Animation's timing.
   void UpdateTargetRegistration();
 
-  nsCOMPtr<Element> mTarget;
+  // Remove the current effect target from its EffectSet.
+  void UnregisterTarget();
+
+  void RequestRestyle(EffectCompositor::RestyleType aRestyleType);
+
+  Maybe<OwningAnimationTarget> mTarget;
   RefPtr<Animation> mAnimation;
 
   RefPtr<AnimationEffectTimingReadOnly> mTiming;
-  CSSPseudoElementType mPseudoType;
 
   // The specified keyframes.
   nsTArray<Keyframe>          mFrames;
 
   // A set of per-property value arrays, derived from |mFrames|.
   nsTArray<AnimationProperty> mProperties;
 
   // The computed progress last time we composed the style rule. This is
@@ -401,18 +405,17 @@ private:
 
   static const TimeDuration OverflowRegionRefreshInterval();
 };
 
 class KeyframeEffect : public KeyframeEffectReadOnly
 {
 public:
   KeyframeEffect(nsIDocument* aDocument,
-                 Element* aTarget,
-                 CSSPseudoElementType aPseudoType,
+                 const Maybe<OwningAnimationTarget>& aTarget,
                  const TimingParams& aTiming);
 
   JSObject* WrapObject(JSContext* aCx,
                        JS::Handle<JSObject*> aGivenProto) override;
 
   static already_AddRefed<KeyframeEffect>
   Constructor(const GlobalObject& aGlobal,
               const Nullable<ElementOrCSSPseudoElement>& aTarget,
@@ -427,16 +430,29 @@ public:
   Constructor(const GlobalObject& aGlobal,
               const Nullable<ElementOrCSSPseudoElement>& aTarget,
               JS::Handle<JSObject*> aFrames,
               const UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions,
               ErrorResult& aRv);
 
   void NotifySpecifiedTimingUpdated();
 
+  // This method calls MaybeUpdateProperties which is not safe to use when
+  // we are in the middle of updating style. If we need to use this when
+  // updating style, we should pass the nsStyleContext into this method and use
+  // that to update the properties rather than calling
+  // GetStyleContextForElement.
+  void SetTarget(const Nullable<ElementOrCSSPseudoElement>& aTarget);
+
 protected:
   ~KeyframeEffect() override;
+
+  // We need to be careful to *not* call this when we are updating the style
+  // context. That's because calling GetStyleContextForElement when we are in
+  // the process of building a style context may trigger various forms of
+  // infinite recursion.
+  void MaybeUpdateProperties();
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_KeyframeEffect_h
--- a/dom/animation/PseudoElementHashEntry.h
+++ b/dom/animation/PseudoElementHashEntry.h
@@ -3,18 +3,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_PseudoElementHashEntry_h
 #define mozilla_PseudoElementHashEntry_h
 
 #include "mozilla/dom/Element.h"
+#include "mozilla/AnimationTarget.h"
 #include "mozilla/HashFunctions.h"
-#include "mozilla/NonOwningAnimationTarget.h"
 #include "PLDHashTable.h"
 
 namespace mozilla {
 
 // A hash entry that uses a RefPtr<dom::Element>, CSSPseudoElementType pair
 class PseudoElementHashEntry : public PLDHashEntryHdr
 {
 public:
--- a/dom/animation/moz.build
+++ b/dom/animation/moz.build
@@ -16,24 +16,24 @@ EXPORTS.mozilla.dom += [
     'CSSPseudoElement.h',
     'DocumentTimeline.h',
     'KeyframeEffect.h',
 ]
 
 EXPORTS.mozilla += [
     'AnimationComparator.h',
     'AnimationPerformanceWarning.h',
+    'AnimationTarget.h',
     'AnimationUtils.h',
     'AnimValuesStyleRule.h',
     'ComputedTiming.h',
     'ComputedTimingFunction.h',
     'EffectCompositor.h',
     'EffectSet.h',
     'KeyframeUtils.h',
-    'NonOwningAnimationTarget.h',
     'PendingAnimationTracker.h',
     'PseudoElementHashEntry.h',
     'TimingParams.h',
 ]
 
 UNIFIED_SOURCES += [
     'Animation.cpp',
     'AnimationEffectReadOnly.cpp',
--- a/dom/animation/test/chrome/test_animation_observers.html
+++ b/dom/animation/test/chrome/test_animation_observers.html
@@ -1713,16 +1713,91 @@ addAsyncAnimTest("exclude_animations_tar
 
   anim.finish();
   pAnim.finish();
   yield await_frame();
   assert_records([{ added: [], changed: [], removed: [anim] }],
                  "records after animation is finished");
 });
 
+addAsyncAnimTest("create_animation_without_target",
+                 { observe: document, subtree: true }, function*() {
+  var effect = new KeyframeEffectReadOnly(null,
+                                          { opacity: [ 0, 1 ] },
+                                          { duration: 10000 });
+  var anim = new Animation(effect, document.timeline);
+  anim.play();
+  yield await_frame();
+  assert_records([], "no records after animation is added");
+
+  anim.cancel();
+  yield await_frame();
+  assert_records([], "no records after animation is removed");
+});
+
+addAsyncAnimTest("set_animation_target",
+                 { observe: document, subtree: true }, function*() {
+  var anim = div.animate({ opacity: [ 0, 1 ] },
+                         { duration: 100 * MS_PER_SEC });
+
+  yield await_frame();
+  assert_records([{ added: [anim], changed: [], removed: [] }],
+                 "records after animation is added");
+
+  anim.effect.target = null;
+  yield await_frame();
+  assert_records([{ added: [], changed: [], removed: [anim] }],
+                 "records after setting null");
+
+  anim.effect.target = div;
+  yield await_frame();
+  assert_records([{ added: [anim], changed: [], removed: [] }],
+                 "records after setting a target");
+
+  var newTarget = document.createElement("div");
+  document.body.appendChild(newTarget);
+  anim.effect.target = newTarget;
+  yield await_frame();
+  assert_records([{ added: [], changed: [], removed: [anim] },
+                  { added: [anim], changed: [], removed: [] }],
+                 "records after setting a different target");
+
+  anim.cancel();
+  yield await_frame();
+  assert_records([{ added: [], changed: [], removed: [anim] }],
+                 "records after animation ends");
+
+  newTarget.remove();
+});
+
+addAsyncAnimTest("set_redundant_animation_target",
+                 { observe: div, subtree: true }, function*() {
+  var anim = div.animate({ opacity: [ 0, 1 ] },
+                         { duration: 100 * MS_PER_SEC });
+  yield await_frame();
+  assert_records([{ added: [anim], changed: [], removed: [] }],
+                 "records after animation is added");
+
+  anim.effect.target = div;
+  yield await_frame();
+  assert_records([], "no records after setting the same target");
+
+  anim.effect.target = null;
+  yield await_frame();
+  assert_records([{ added: [], changed: [], removed: [anim] }],
+                 "records after setting null");
+
+  anim.effect.target = null;
+  yield await_frame();
+  assert_records([], "records after setting redundant null");
+
+  anim.cancel();
+  yield await_frame();
+});
+
 // Run the tests.
 SimpleTest.requestLongerTimeout(2);
 SimpleTest.waitForExplicitFinish();
 
 runAllAsyncTests().then(function() {
   SimpleTest.finish();
 }, function(aError) {
   ok(false, "Something failed: " + aError);
--- a/dom/animation/test/chrome/test_running_on_compositor.html
+++ b/dom/animation/test/chrome/test_running_on_compositor.html
@@ -404,11 +404,49 @@ promise_test(function(t) {
   }).then(function() {
     assert_equals(animation.isRunningOnCompositor, false,
       'Animation reports that it is NOT running on the compositor'
       + ' when currentTime is after endTime');
   });
 }, 'animation is NOT running on compositor' +
    ' when endTime is positive and endDelay is negative');
 
-</script>
+promise_test(function(t) {
+  var effect = new KeyframeEffect(null,
+                                  { opacity: [ 0, 1 ] },
+                                  100 * MS_PER_SEC);
+  var animation = new Animation(effect, document.timeline);
+  animation.play();
+
+  var div = addDiv(t);
+
+  return animation.ready.then(function() {
+    assert_equals(animation.isRunningOnCompositor, false,
+                  'Animation with null target reports that it is not running ' +
+                  'on the compositor');
+
+    animation.effect.target = div;
+    return waitForFrame();
+  }).then(function() {
+    assert_equals(animation.isRunningOnCompositor, omtaEnabled,
+                  'Animation reports that it is running on the compositor ' +
+                  'after setting a valid target');
+  });
+}, 'animation is added to the compositor when setting a valid target');
+
+promise_test(function(t) {
+  var div = addDiv(t);
+  var animation = div.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
+
+  return animation.ready.then(function() {
+    assert_equals(animation.isRunningOnCompositor, omtaEnabled,
+                  'Animation reports that it is running on the compositor');
+
+    animation.effect.target = null;
+    assert_equals(animation.isRunningOnCompositor, false,
+                  'Animation reports that it is NOT running on the ' +
+                  'compositor after setting null target');
+  });
+}, 'animation is removed from the compositor when setting null target');
+
+
 </script>
 </body>
--- a/dom/apps/AppsService.js
+++ b/dom/apps/AppsService.js
@@ -165,17 +165,13 @@ AppsService.prototype = {
     // properly in child processes.
     if (Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) {
       throw Cr.NS_ERROR_FAILURE;
     }
 
     return UserCustomizations.isFromExtension(aURI);
   },
 
-  updateDataStoreEntriesFromLocalId: function(aLocalId) {
-    return DOMApplicationRegistry.updateDataStoreEntriesFromLocalId(aLocalId);
-  },
-
   classID : APPS_SERVICE_CID,
   QueryInterface : XPCOMUtils.generateQI([Ci.nsIAppsService])
 }
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AppsService])
--- a/dom/apps/AppsServiceChild.jsm
+++ b/dom/apps/AppsServiceChild.jsm
@@ -413,16 +413,12 @@ this.DOMApplicationRegistry = {
   },
 
   areAnyAppsInstalled: function() {
     return AppsUtils.areAnyAppsInstalled(this.webapps);
   },
 
   getAppInfo: function getAppInfo(aAppId) {
     return AppsUtils.getAppInfo(this.webapps, aAppId);
-  },
-
-  updateDataStoreEntriesFromLocalId: function(aLocalId) {
-    debug("updateDataStoreEntriesFromLocalId() not yet supported on child!");
   }
 }
 
 DOMApplicationRegistry.init();
--- a/dom/apps/Webapps.jsm
+++ b/dom/apps/Webapps.jsm
@@ -142,20 +142,16 @@ XPCOMUtils.defineLazyServiceGetter(this,
                                    "@mozilla.org/childprocessmessagemanager;1",
                                    "nsIMessageSender");
 
 XPCOMUtils.defineLazyGetter(this, "interAppCommService", function() {
   return Cc["@mozilla.org/inter-app-communication-service;1"]
          .getService(Ci.nsIInterAppCommService);
 });
 
-XPCOMUtils.defineLazyServiceGetter(this, "dataStoreService",
-                                   "@mozilla.org/datastore-service;1",
-                                   "nsIDataStoreService");
-
 XPCOMUtils.defineLazyServiceGetter(this, "appsService",
                                    "@mozilla.org/AppsService;1",
                                    "nsIAppsService");
 
 XPCOMUtils.defineLazyGetter(this, "msgmgr", function() {
   return Cc["@mozilla.org/system-message-internal;1"]
          .getService(Ci.nsISystemMessagesInternal);
 });
@@ -445,28 +441,16 @@ this.DOMApplicationRegistry = {
         Langpacks.register(app, aResult.manifest);
       });
 
       // Nothing else to do but notifying we're ready.
       this.notifyAppsRegistryReady();
     }
   }),
 
-  updateDataStoreForApp: Task.async(function*(aId) {
-    if (!this.webapps[aId]) {
-      return;
-    }
-
-    // Create or Update the DataStore for this app
-    let results = yield this._readManifests([{ id: aId }]);
-    let app = this.webapps[aId];
-    this.updateDataStore(app.localId, app.origin, app.manifestURL,
-                         results[0].manifest, app.appStatus);
-  }),
-
   appKind: function(aApp, aManifest) {
     if (aApp.origin.startsWith("android://")) {
       return this.kAndroid;
     } if (aApp.origin.startsWith("app://")) {
       return this.kPackaged;
     } else {
       // Hosted apps, can be appcached or not.
       let kind = this.kHosted;
@@ -808,62 +792,20 @@ this.DOMApplicationRegistry = {
         }
         // Need to update the persisted list of apps since
         // installPreinstalledApp() removes the ones failing to install.
         yield this._saveApps();
 
         Services.prefs.setBoolPref("dom.apps.reset-permissions", true);
       }
 
-      // DataStores must be initialized at startup.
-      for (let id in this.webapps) {
-        yield this.updateDataStoreForApp(id);
-      }
-
       yield this.registerAppsHandlers(runUpdate);
     }.bind(this)).then(null, Cu.reportError);
   },
 
-  updateDataStore: function(aId, aOrigin, aManifestURL, aManifest) {
-    if (!aManifest) {
-      debug("updateDataStore: no manifest for " + aOrigin);
-      return;
-    }
-
-    let uri = Services.io.newURI(aOrigin, null, null);
-    let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
-                   .getService(Ci.nsIScriptSecurityManager);
-    let principal = secMan.createCodebasePrincipal(uri, {appId: aId});
-    if (!dataStoreService.checkPermission(principal)) {
-      return;
-    }
-
-    if ('datastores-owned' in aManifest) {
-      for (let name in aManifest['datastores-owned']) {
-        let readonly = "access" in aManifest['datastores-owned'][name]
-                         ? aManifest['datastores-owned'][name].access == 'readonly'
-                         : false;
-
-        dataStoreService.installDataStore(aId, name, aOrigin, aManifestURL,
-                                          readonly);
-      }
-    }
-
-    if ('datastores-access' in aManifest) {
-      for (let name in aManifest['datastores-access']) {
-        let readonly = ("readonly" in aManifest['datastores-access'][name]) &&
-                       !aManifest['datastores-access'][name].readonly
-                         ? false : true;
-
-        dataStoreService.installAccessDataStore(aId, name, aOrigin,
-                                                aManifestURL, readonly);
-      }
-    }
-  },
-
   // |aEntryPoint| is either the entry_point name or the null in which case we
   // use the root of the manifest.
   //
   // TODO Bug 908094 Refine _registerSystemMessagesForEntryPoint(...).
   _registerSystemMessagesForEntryPoint: function(aManifest, aApp, aEntryPoint) {
     let root = aManifest;
     if (aEntryPoint && aManifest.entry_points[aEntryPoint]) {
       root = aManifest.entry_points[aEntryPoint];
@@ -1964,18 +1906,16 @@ this.DOMApplicationRegistry = {
 
     if (supportUseCurrentProfile()) {
       PermissionsInstaller.installPermissions(
         { manifest: newManifest,
           origin: app.origin,
           manifestURL: app.manifestURL },
         true);
     }
-    this.updateDataStore(this.webapps[id].localId, app.origin,
-                         app.manifestURL, newManifest);
     MessageBroadcaster.broadcastMessage("Webapps:UpdateState", {
       app: app,
       manifest: newManifest,
       id: app.id
     });
     MessageBroadcaster.broadcastMessage("Webapps:FireEvent", {
       eventType: "downloadapplied",
       manifestURL: app.manifestURL
@@ -2414,19 +2354,16 @@ this.DOMApplicationRegistry = {
         // Update the permissions for this app.
         PermissionsInstaller.installPermissions({
           manifest: aApp.manifest,
           origin: aApp.origin,
           manifestURL: aData.manifestURL
         }, true);
       }
 
-      this.updateDataStore(this.webapps[aId].localId, aApp.origin,
-                           aApp.manifestURL, aApp.manifest);
-
       aApp.name = aNewManifest.name;
       aApp.csp = manifest.csp || "";
       aApp.updateTime = Date.now();
     }
 
     // Update the registry.
     this.webapps[aId] = aApp;
     yield this._saveApps();
@@ -3071,19 +3008,16 @@ this.DOMApplicationRegistry = {
             manifestURL: appObject.manifestURL,
             manifest: jsonManifest,
             kind: appObject.kind
           },
           isReinstall,
           this.doUninstall.bind(this, aData, aData.mm)
         );
       }
-
-      this.updateDataStore(this.webapps[id].localId,  this.webapps[id].origin,
-                           this.webapps[id].manifestURL, jsonManifest);
     }
 
     for (let prop of ["installState", "downloadAvailable", "downloading",
                            "downloadSize", "readyToApplyDownload"]) {
       aData.app[prop] = appObject[prop];
     }
 
     let dontNeedNetwork = false;
@@ -3212,19 +3146,16 @@ this.DOMApplicationRegistry = {
       PermissionsInstaller.installPermissions({
         manifest: aManifest,
         origin: aNewApp.origin,
         manifestURL: aNewApp.manifestURL,
         kind: this.webapps[aId].kind
       }, true);
     }
 
-    this.updateDataStore(this.webapps[aId].localId, aNewApp.origin,
-                         aNewApp.manifestURL, aManifest);
-
     if (aInstallSuccessCallback) {
       yield aInstallSuccessCallback(aNewApp, aManifest, zipFile.path);
     }
 
     MessageBroadcaster.broadcastMessage("Webapps:UpdateState", {
       app: app,
       manifest: aManifest,
       manifestURL: aNewApp.manifestURL
@@ -4750,23 +4681,16 @@ this.DOMApplicationRegistry = {
   getWebAppsBasePath: function() {
     return OS.Path.dirname(this.appsFile);
   },
 
   areAnyAppsInstalled: function() {
     return AppsUtils.areAnyAppsInstalled(this.webapps);
   },
 
-  updateDataStoreEntriesFromLocalId: function(aLocalId) {
-    let app = appsService.getAppByLocalId(aLocalId);
-    if (app) {
-      this.updateDataStoreForApp(app.id);
-    }
-  },
-
   _notifyCategoryAndObservers: function(subject, topic, data,  msg) {
     const serviceMarker = "service,";
 
     // First create observers from the category manager.
     let cm =
       Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
     let enumerator = cm.enumerateCategory(topic);
 
--- a/dom/apps/tests/test_widget_browser.html
+++ b/dom/apps/tests/test_widget_browser.html
@@ -1,13 +1,13 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <meta charset="utf-8">
-  <title>Test for DataStore - basic operation on a readonly db</title>
+  <title>?!?</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="file_test_widget.js"></script>
   <script type="application/javascript" src="common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
 <div id="container"></div>
   <script type="application/javascript;version=1.7">
--- a/dom/base/FragmentOrElement.h
+++ b/dom/base/FragmentOrElement.h
@@ -137,17 +137,17 @@ public:
   {
     return SetText(aStr.BeginReading(), aStr.Length(), aNotify);
   }
   virtual nsresult AppendText(const char16_t* aBuffer, uint32_t aLength,
                               bool aNotify) override;
   virtual bool TextIsOnlyWhitespace() override;
   virtual bool HasTextForTranslation() override;
   virtual void AppendTextTo(nsAString& aResult) override;
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   virtual bool AppendTextTo(nsAString& aResult, const mozilla::fallible_t&) override;
   virtual nsIContent *GetBindingParent() const override;
   virtual nsXBLBinding *GetXBLBinding() const override;
   virtual void SetXBLBinding(nsXBLBinding* aBinding,
                              nsBindingManager* aOldBindingManager = nullptr) override;
   virtual ShadowRoot *GetShadowRoot() const override;
   virtual ShadowRoot *GetContainingShadow() const override;
   virtual nsTArray<nsIContent*> &DestInsertionPoints() override;
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -91,17 +91,16 @@
 #include "AudioChannelManager.h"
 #endif
 
 #ifdef MOZ_B2G_FM
 #include "mozilla/dom/FMRadio.h"
 #endif
 
 #include "nsIDOMGlobalPropertyInitializer.h"
-#include "mozilla/dom/DataStoreService.h"
 #include "nsJSUtils.h"
 
 #include "nsScriptNameSpaceManager.h"
 
 #include "mozilla/dom/NavigatorBinding.h"
 #include "mozilla/dom/Promise.h"
 
 #include "nsIUploadChannel2.h"
@@ -1514,48 +1513,16 @@ Navigator::GetDeprecatedBattery(ErrorRes
 
     mBatteryManager = new battery::BatteryManager(mWindow);
     mBatteryManager->Init();
   }
 
   return mBatteryManager;
 }
 
-/* static */ already_AddRefed<Promise>
-Navigator::GetDataStores(nsPIDOMWindowInner* aWindow,
-                         const nsAString& aName,
-                         const nsAString& aOwner,
-                         ErrorResult& aRv)
-{
-  if (!aWindow || !aWindow->GetDocShell()) {
-    aRv.Throw(NS_ERROR_UNEXPECTED);
-    return nullptr;
-  }
-
-  RefPtr<DataStoreService> service = DataStoreService::GetOrCreate();
-  if (!service) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  nsCOMPtr<nsISupports> promise;
-  aRv = service->GetDataStores(aWindow, aName, aOwner, getter_AddRefs(promise));
-
-  RefPtr<Promise> p = static_cast<Promise*>(promise.get());
-  return p.forget();
-}
-
-already_AddRefed<Promise>
-Navigator::GetDataStores(const nsAString& aName,
-                         const nsAString& aOwner,
-                         ErrorResult& aRv)
-{
-  return GetDataStores(mWindow, aName, aOwner, aRv);
-}
-
 already_AddRefed<Promise>
 Navigator::GetFeature(const nsAString& aName, ErrorResult& aRv)
 {
   nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
   RefPtr<Promise> p = Promise::Create(go, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
@@ -2305,85 +2272,16 @@ bool
 Navigator::HasUserMediaSupport(JSContext* /* unused */,
                                JSObject* /* unused */)
 {
   // Make enabling peerconnection enable getUserMedia() as well
   return Preferences::GetBool("media.navigator.enabled", false) ||
          Preferences::GetBool("media.peerconnection.enabled", false);
 }
 
-/* static */
-bool
-Navigator::HasDataStoreSupport(nsIPrincipal* aPrincipal)
-{
-  workers::AssertIsOnMainThread();
-
-  return DataStoreService::CheckPermission(aPrincipal);
-}
-
-// A WorkerMainThreadRunnable to synchronously dispatch the call of
-// HasDataStoreSupport() from the worker thread to the main thread.
-class HasDataStoreSupportRunnable final
-  : public workers::WorkerCheckAPIExposureOnMainThreadRunnable
-{
-public:
-  bool mResult;
-
-  explicit HasDataStoreSupportRunnable(workers::WorkerPrivate* aWorkerPrivate)
-    : workers::WorkerCheckAPIExposureOnMainThreadRunnable(aWorkerPrivate)
-    , mResult(false)
-  {
-    MOZ_ASSERT(aWorkerPrivate);
-    aWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-protected:
-  virtual bool
-  MainThreadRun() override
-  {
-    workers::AssertIsOnMainThread();
-
-    mResult = Navigator::HasDataStoreSupport(mWorkerPrivate->GetPrincipal());
-
-    return true;
-  }
-};
-
-/* static */
-bool
-Navigator::HasDataStoreSupport(JSContext* aCx, JSObject* aGlobal)
-{
-  // If the caller is on the worker thread, dispatch this to the main thread.
-  if (!NS_IsMainThread()) {
-    workers::WorkerPrivate* workerPrivate =
-      workers::GetWorkerPrivateFromContext(aCx);
-    workerPrivate->AssertIsOnWorkerThread();
-
-    RefPtr<HasDataStoreSupportRunnable> runnable =
-      new HasDataStoreSupportRunnable(workerPrivate);
-    return runnable->Dispatch() && runnable->mResult;
-  }
-
-  workers::AssertIsOnMainThread();
-
-  JS::Rooted<JSObject*> global(aCx, aGlobal);
-
-  nsCOMPtr<nsPIDOMWindowInner> win = GetWindowFromGlobal(global);
-  if (!win) {
-    return false;
-  }
-
-  nsIDocument* doc = win->GetExtantDoc();
-  if (!doc || !doc->NodePrincipal()) {
-    return false;
-  }
-
-  return HasDataStoreSupport(doc->NodePrincipal());
-}
-
 #ifdef MOZ_B2G
 /* static */
 bool
 Navigator::HasMobileIdSupport(JSContext* aCx, JSObject* aGlobal)
 {
   nsCOMPtr<nsPIDOMWindowInner> win = GetWindowFromGlobal(aGlobal);
   if (!win) {
     return false;
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -162,21 +162,16 @@ public:
   nsMimeTypeArray* GetMimeTypes(ErrorResult& aRv);
   nsPluginArray* GetPlugins(ErrorResult& aRv);
   Permissions* GetPermissions(ErrorResult& aRv);
   // The XPCOM GetDoNotTrack is ok
   Geolocation* GetGeolocation(ErrorResult& aRv);
   Promise* GetBattery(ErrorResult& aRv);
   battery::BatteryManager* GetDeprecatedBattery(ErrorResult& aRv);
 
-  static already_AddRefed<Promise> GetDataStores(nsPIDOMWindowInner* aWindow,
-                                                 const nsAString& aName,
-                                                 const nsAString& aOwner,
-                                                 ErrorResult& aRv);
-
   static void AppName(nsAString& aAppName, bool aUsePrefOverriddenValue);
 
   static nsresult GetPlatform(nsAString& aPlatform,
                               bool aUsePrefOverriddenValue);
 
   static nsresult GetAppVersion(nsAString& aAppVersion,
                                 bool aUsePrefOverriddenValue);
 
@@ -184,20 +179,16 @@ public:
                                nsIURI* aURI,
                                bool aIsCallerChrome,
                                nsAString& aUserAgent);
 
   // Clears the user agent cache by calling:
   // NavigatorBinding::ClearCachedUserAgentValue(this);
   void ClearUserAgentCache();
 
-  already_AddRefed<Promise> GetDataStores(const nsAString& aName,
-                                          const nsAString& aOwner,
-                                          ErrorResult& aRv);
-
   // Feature Detection API
   already_AddRefed<Promise> GetFeature(const nsAString& aName,
                                        ErrorResult& aRv);
 
   already_AddRefed<Promise> HasFeature(const nsAString &aName,
                                        ErrorResult& aRv);
 
   bool Vibrate(uint32_t aDuration);
@@ -324,20 +315,16 @@ public:
   static bool HasWifiManagerSupport(JSContext* /* unused */,
                                   JSObject* aGlobal);
 #ifdef MOZ_NFC
   static bool HasNFCSupport(JSContext* /* unused */, JSObject* aGlobal);
 #endif // MOZ_NFC
   static bool HasUserMediaSupport(JSContext* /* unused */,
                                   JSObject* /* unused */);
 
-  static bool HasDataStoreSupport(nsIPrincipal* aPrincipal);
-
-  static bool HasDataStoreSupport(JSContext* cx, JSObject* aGlobal);
-
 #ifdef MOZ_B2G
   static bool HasMobileIdSupport(JSContext* aCx, JSObject* aGlobal);
 #endif
 
   static bool HasPresentationSupport(JSContext* aCx, JSObject* aGlobal);
 
   static bool IsE10sEnabled(JSContext* aCx, JSObject* aGlobal);
 
--- a/dom/base/domerr.msg
+++ b/dom/base/domerr.msg
@@ -113,17 +113,16 @@ DOM4_MSG_DEF(BtParmInvalidError,  "Inval
 DOM4_MSG_DEF(BtUnhandledError,    "Unhandled",  NS_ERROR_DOM_BLUETOOTH_UNHANDLED)
 DOM4_MSG_DEF(BtAuthFailureError,  "Authentication failure",  NS_ERROR_DOM_BLUETOOTH_AUTH_FAILURE)
 DOM4_MSG_DEF(BtRmtDevDownError,   "Remote device down",  NS_ERROR_DOM_BLUETOOTH_RMT_DEV_DOWN)
 DOM4_MSG_DEF(BtAuthRejectedError, "Authentication rejected",  NS_ERROR_DOM_BLUETOOTH_AUTH_REJECTED)
 
 /* Web Animations errors */
 
 DOM4_MSG_DEF(NotSupportedError, "Animation to or from an underlying value is not yet supported.", NS_ERROR_DOM_ANIM_MISSING_PROPS_ERR)
-DOM4_MSG_DEF(NotSupportedError, "Animation with no target is not yet supported.", NS_ERROR_DOM_ANIM_NO_TARGET_ERR)
 DOM4_MSG_DEF(NotSupportedError, "Animation with no timeline is not yet supported.", NS_ERROR_DOM_ANIM_NO_TIMELINE_ERR)
 DOM4_MSG_DEF(NotSupportedError, "Animation with no effect is not yet supported.", NS_ERROR_DOM_ANIM_NO_EFFECT_ERR)
 
 /* common global codes (from nsError.h) */
 
 DOM_MSG_DEF(NS_OK                                  , "Success")
 DOM_MSG_DEF(NS_ERROR_NOT_INITIALIZED               , "Component not initialized")
 DOM_MSG_DEF(NS_ERROR_ALREADY_INITIALIZED           , "Component already initialized")
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -1387,17 +1387,17 @@ public:
    * @see nsLayoutUtils::GetFrameTextContent
    *
    * @param aNode Node to get textual contents of.
    * @param aDeep If true child elements of aNode are recursivly descended
    *              into to find text children.
    * @param aResult the result. Out param.
    * @return false on out of memory errors, true otherwise.
    */
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   static bool GetNodeTextContent(nsINode* aNode, bool aDeep,
                                  nsAString& aResult, const mozilla::fallible_t&);
 
   static void GetNodeTextContent(nsINode* aNode, bool aDeep,
                                  nsAString& aResult);
 
   /**
    * Same as GetNodeTextContents but appends the result rather than sets it.
@@ -1759,34 +1759,34 @@ public:
 
   /**
    * The method checks whether the caller can access native anonymous content.
    * If there is no JS in the stack or privileged JS is running, this
    * method returns true, otherwise false.
    */
   static bool CanAccessNativeAnon();
 
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   static nsresult WrapNative(JSContext *cx, nsISupports *native,
                              const nsIID* aIID, JS::MutableHandle<JS::Value> vp,
                              bool aAllowWrapping = true)
   {
     return WrapNative(cx, native, nullptr, aIID, vp, aAllowWrapping);
   }
 
   // Same as the WrapNative above, but use this one if aIID is nsISupports' IID.
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   static nsresult WrapNative(JSContext *cx, nsISupports *native,
                              JS::MutableHandle<JS::Value> vp,
                              bool aAllowWrapping = true)
   {
     return WrapNative(cx, native, nullptr, nullptr, vp, aAllowWrapping);
   }
 
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   static nsresult WrapNative(JSContext *cx, nsISupports *native,
                              nsWrapperCache *cache,
                              JS::MutableHandle<JS::Value> vp,
                              bool aAllowWrapping = true)
   {
     return WrapNative(cx, native, cache, nullptr, vp, aAllowWrapping);
   }
 
@@ -1809,17 +1809,17 @@ public:
    */
   static void RemoveNewlines(nsString &aString);
 
   /**
    * Convert Windows and Mac platform linebreaks to \n.
    * @param aString the string to convert the newlines inside [in/out]
    */
   static void PlatformToDOMLineBreaks(nsString &aString);
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   static bool PlatformToDOMLineBreaks(nsString &aString,
                                       const mozilla::fallible_t&);
 
   /**
    * Populates aResultString with the contents of the string-buffer aBuf, up
    * to aBuf's null-terminator.  aBuf must not be null. Ownership of the string
    * is not transferred.
    */
--- a/dom/base/nsGenericDOMDataNode.h
+++ b/dom/base/nsGenericDOMDataNode.h
@@ -133,17 +133,17 @@ public:
   {
     return SetText(aStr.BeginReading(), aStr.Length(), aNotify);
   }
   virtual nsresult AppendText(const char16_t* aBuffer, uint32_t aLength,
                               bool aNotify) override;
   virtual bool TextIsOnlyWhitespace() override;
   virtual bool HasTextForTranslation() override;
   virtual void AppendTextTo(nsAString& aResult) override;
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   virtual bool AppendTextTo(nsAString& aResult,
                             const mozilla::fallible_t&) override;
   virtual void SaveSubtreeState() override;
 
 #ifdef DEBUG
   virtual void List(FILE* out, int32_t aIndent) const override;
   virtual void DumpContent(FILE* out, int32_t aIndent, bool aDumpAll) const override;
 #endif
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -7715,24 +7715,16 @@ nsGlobalWindow::FirePopupBlockedEvent(ns
                                    init);
 
   event->SetTrusted(true);
 
   bool defaultActionEnabled;
   aDoc->DispatchEvent(event, &defaultActionEnabled);
 }
 
-static void FirePopupWindowEvent(nsIDocument* aDoc)
-{
-  // Fire a "PopupWindow" event
-  nsContentUtils::DispatchTrustedEvent(aDoc, aDoc,
-                                       NS_LITERAL_STRING("PopupWindow"),
-                                       true, true);
-}
-
 // static
 bool
 nsGlobalWindow::CanSetProperty(const char *aPrefName)
 {
   // Chrome can set any property.
   if (nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
     return true;
   }
@@ -7792,23 +7784,19 @@ nsGlobalWindow::RevisePopupAbuseLevel(Po
     int32_t popupMax = Preferences::GetInt("dom.popup_maximum", -1);
     if (popupMax >= 0 && gOpenPopupSpamCount >= popupMax)
       abuse = openOverridden;
   }
 
   return abuse;
 }
 
-/* If a window open is blocked, fire the appropriate DOM events.
-   aBlocked signifies we just blocked a popup.
-   aWindow signifies we just opened what is probably a popup.
-*/
-void
-nsGlobalWindow::FireAbuseEvents(bool aBlocked, bool aWindow,
-                                const nsAString &aPopupURL,
+/* If a window open is blocked, fire the appropriate DOM events. */
+void
+nsGlobalWindow::FireAbuseEvents(const nsAString &aPopupURL,
                                 const nsAString &aPopupWindowName,
                                 const nsAString &aPopupWindowFeatures)
 {
   // fetch the URI of the window requesting the opened window
 
   nsCOMPtr<nsPIDOMWindowOuter> window = GetTop();
   if (!window) {
     return;
@@ -7830,22 +7818,18 @@ nsGlobalWindow::FireAbuseEvents(bool aBl
 
   // use the base URI to build what would have been the popup's URI
   nsCOMPtr<nsIIOService> ios(do_GetService(NS_IOSERVICE_CONTRACTID));
   if (ios)
     ios->NewURI(NS_ConvertUTF16toUTF8(aPopupURL), 0, baseURL,
                 getter_AddRefs(popupURI));
 
   // fire an event chock full of informative URIs
-  if (aBlocked) {
-    FirePopupBlockedEvent(topDoc, popupURI, aPopupWindowName,
-                          aPopupWindowFeatures);
-  }
-  if (aWindow)
-    FirePopupWindowEvent(topDoc);
+  FirePopupBlockedEvent(topDoc, popupURI, aPopupWindowName,
+                        aPopupWindowFeatures);
 }
 
 already_AddRefed<nsPIDOMWindowOuter>
 nsGlobalWindow::OpenOuter(const nsAString& aUrl, const nsAString& aName,
                           const nsAString& aOptions, ErrorResult& aError)
 {
   MOZ_RELEASE_ASSERT(IsOuterWindow());
   nsCOMPtr<nsPIDOMWindowOuter> window;
@@ -11586,17 +11570,17 @@ nsGlobalWindow::OpenInternal(const nsASt
         // prevent this window from closing until after this script terminates
         // so that whatever popup blocker UI the app has will be visible.
         if (mContext == GetScriptContextFromJSContext(aJSCallerContext)) {
           mBlockScriptedClosingFlag = true;
           closeUnblocker.emplace(this);
         }
       }
 
-      FireAbuseEvents(true, false, aUrl, aName, aOptions);
+      FireAbuseEvents(aUrl, aName, aOptions);
       return aDoJSFixups ? NS_OK : NS_ERROR_FAILURE;
     }
   }
 
   nsCOMPtr<mozIDOMWindowProxy> domReturn;
 
   nsCOMPtr<nsIWindowWatcher> wwatch =
     do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
@@ -11668,25 +11652,25 @@ nsGlobalWindow::OpenInternal(const nsASt
       // XXXbz should this just use EnsureInnerWindow()?
 
       // Force document creation.
       nsCOMPtr<nsIDocument> doc = (*aReturn)->GetDoc();
     }
   }
 
   if (checkForPopup) {
+    MOZ_ASSERT(abuseLevel < openAbused, "Why didn't we take the early return?");
+
     if (abuseLevel >= openControlled) {
       nsGlobalWindow *opened = nsGlobalWindow::Cast(*aReturn);
       if (!opened->IsPopupSpamWindow()) {
         opened->SetPopupSpamWindow(true);
         ++gOpenPopupSpamCount;
       }
     }
-    if (abuseLevel >= openAbused)
-      FireAbuseEvents(false, true, aUrl, aName, aOptions);
   }
 
   return rv;
 }
 
 //*****************************************************************************
 // nsGlobalWindow: Timeout Functions
 //*****************************************************************************
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -1462,18 +1462,17 @@ public:
   already_AddRefed<nsIDocShellTreeOwner> GetTreeOwner();
   already_AddRefed<nsIBaseWindow> GetTreeOwnerWindow();
   already_AddRefed<nsIWebBrowserChrome> GetWebBrowserChrome();
   nsresult SecurityCheckURL(const char *aURL);
   bool IsPrivateBrowsing();
 
   bool PopupWhitelisted();
   PopupControlState RevisePopupAbuseLevel(PopupControlState);
-  void     FireAbuseEvents(bool aBlocked, bool aWindow,
-                           const nsAString &aPopupURL,
+  void     FireAbuseEvents(const nsAString &aPopupURL,
                            const nsAString &aPopupWindowName,
                            const nsAString &aPopupWindowFeatures);
   void FireOfflineStatusEventIfChanged();
 
   bool GetIsPrerendered();
 
   // Inner windows only.
   nsresult ScheduleNextIdleObserverCallback();
--- a/dom/base/nsHTMLContentSerializer.h
+++ b/dom/base/nsHTMLContentSerializer.h
@@ -32,26 +32,26 @@ class nsHTMLContentSerializer final : pu
 
   NS_IMETHOD AppendElementEnd(mozilla::dom::Element* aElement,
                               nsAString& aStr) override;
 
   NS_IMETHOD AppendDocumentStart(nsIDocument *aDocument,
                                  nsAString& aStr) override;
  protected:
 
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   virtual bool SerializeHTMLAttributes(nsIContent* aContent,
                                        nsIContent *aOriginalElement,
                                        nsAString& aTagPrefix,
                                        const nsAString& aTagNamespaceURI,
                                        nsIAtom* aTagName,
                                        int32_t aNamespace,
                                        nsAString& aStr);
 
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   virtual bool AppendAndTranslateEntities(const nsAString& aStr,
                                           nsAString& aOutputStr) override;
 
 };
 
 nsresult
 NS_NewHTMLContentSerializer(nsIContentSerializer** aSerializer);
 
--- a/dom/base/nsIContent.h
+++ b/dom/base/nsIContent.h
@@ -541,17 +541,17 @@ public:
    * NOTE: This asserts and returns for elements
    */
   virtual void AppendTextTo(nsAString& aResult) = 0;
 
   /**
    * Append the text content to aResult.
    * NOTE: This asserts and returns for elements
    */
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   virtual bool AppendTextTo(nsAString& aResult, const mozilla::fallible_t&) = 0;
 
   /**
    * Check if this content is focusable and in the current tab order.
    * Note: most callers should use nsIFrame::IsFocusable() instead as it 
    *       checks visibility and other layout factors as well.
    * Tabbable is indicated by a nonnegative tabindex & is a subset of focusable.
    * For example, only the selected radio button in a group is in the 
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -1042,16 +1042,27 @@ public:
                                             nsIURI* aSheetURI) = 0;
   virtual nsresult AddAdditionalStyleSheet(additionalSheetType aType,
                                            mozilla::StyleSheetHandle aSheet) = 0;
   virtual void RemoveAdditionalStyleSheet(additionalSheetType aType,
                                           nsIURI* sheetURI) = 0;
   virtual mozilla::StyleSheetHandle GetFirstAdditionalAuthorSheet() = 0;
 
   /**
+   * Assuming that aDocSheets is an array of document-level style
+   * sheets for this document, returns the index that aSheet should
+   * be inserted at to maintain document ordering.
+   *
+   * Defined in nsIDocumentInlines.h.
+   */
+  template<typename T>
+  size_t FindDocStyleSheetInsertionPoint(const nsTArray<RefPtr<T>>& aDocSheets,
+                                         T* aSheet);
+
+  /**
    * Get this document's CSSLoader.  This is guaranteed to not return null.
    */
   mozilla::css::Loader* CSSLoader() const {
     return mCSSLoader;
   }
 
   mozilla::StyleBackendType GetStyleBackendType() const;
 
--- a/dom/base/nsIDocumentInlines.h
+++ b/dom/base/nsIDocumentInlines.h
@@ -3,16 +3,58 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsIDocumentInlines_h
 #define nsIDocumentInlines_h
 
 #include "nsIDocument.h"
 #include "mozilla/dom/HTMLBodyElement.h"
+#include "nsStyleSheetService.h"
 
 inline mozilla::dom::HTMLBodyElement*
 nsIDocument::GetBodyElement()
 {
   return static_cast<mozilla::dom::HTMLBodyElement*>(GetHtmlChildElement(nsGkAtoms::body));
 }
 
+template<typename T>
+size_t
+nsIDocument::FindDocStyleSheetInsertionPoint(
+    const nsTArray<RefPtr<T>>& aDocSheets,
+    T* aSheet)
+{
+  nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance();
+
+  // lowest index first
+  int32_t newDocIndex = GetIndexOfStyleSheet(aSheet);
+
+  int32_t count = aDocSheets.Length();
+  int32_t index;
+  for (index = 0; index < count; index++) {
+    T* sheet = aDocSheets[index];
+    int32_t sheetDocIndex = GetIndexOfStyleSheet(sheet);
+    if (sheetDocIndex > newDocIndex)
+      break;
+
+    mozilla::StyleSheetHandle sheetHandle = sheet;
+
+    // If the sheet is not owned by the document it can be an author
+    // sheet registered at nsStyleSheetService or an additional author
+    // sheet on the document, which means the new
+    // doc sheet should end up before it.
+    if (sheetDocIndex < 0) {
+      if (sheetService) {
+        auto& authorSheets = *sheetService->AuthorStyleSheets();
+        if (authorSheets.IndexOf(sheetHandle) != authorSheets.NoIndex) {
+          break;
+        }
+      }
+      if (sheetHandle == GetFirstAdditionalAuthorSheet()) {
+        break;
+      }
+    }
+  }
+
+  return size_t(index);
+}
+
 #endif // nsIDocumentInlines_h
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -19,16 +19,17 @@
 #include "nsCOMArray.h"
 #include "nsPIDOMWindow.h"
 #include "nsDocument.h"
 #ifdef MOZ_XUL
 #include "nsXULElement.h"
 #endif
 #include "nsBindingManager.h"
 #include "nsGenericHTMLElement.h"
+#include "mozilla/AnimationTarget.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/dom/Animation.h"
 #include "mozilla/dom/HTMLImageElement.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/KeyframeEffect.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsObjectLoadingContent.h"
 #include "nsDOMMutationObserver.h"
--- a/dom/base/nsNodeUtils.h
+++ b/dom/base/nsNodeUtils.h
@@ -3,26 +3,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/. */
 
 #ifndef nsNodeUtils_h___
 #define nsNodeUtils_h___
 
 #include "mozilla/Maybe.h"
-#include "mozilla/NonOwningAnimationTarget.h"
 #include "nsIContent.h"          // for use in inline function (ParentChainChanged)
 #include "nsIMutationObserver.h" // for use in inline function (ParentChainChanged)
 #include "js/TypeDecls.h"
 #include "nsCOMArray.h"
 
 struct CharacterDataChangeInfo;
 template<class E> class nsCOMArray;
 class nsCycleCollectionTraversalCallback;
 namespace mozilla {
+struct NonOwningAnimationTarget;
 namespace dom {
 class Animation;
 } // namespace dom
 } // namespace mozilla
 
 class nsNodeUtils
 {
 public:
--- a/dom/base/nsScriptLoader.h
+++ b/dom/base/nsScriptLoader.h
@@ -174,24 +174,24 @@ public:
 
   void AppendElement(nsScriptLoadRequest* aElem)
   {
     MOZ_ASSERT(!aElem->isInList());
     NS_ADDREF(aElem);
     insertBack(aElem);
   }
 
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   already_AddRefed<nsScriptLoadRequest> Steal(nsScriptLoadRequest* aElem)
   {
     aElem->removeFrom(*this);
     return dont_AddRef(aElem);
   }
 
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   already_AddRefed<nsScriptLoadRequest> StealFirst()
   {
     MOZ_ASSERT(!isEmpty());
     return Steal(getFirst());
   }
 };
 
 //////////////////////////////////////////////////////////////
--- a/dom/base/nsTextFragment.h
+++ b/dom/base/nsTextFragment.h
@@ -130,17 +130,17 @@ public:
       aString.AllocFailed(aString.Length() + GetLength());
     }
   }
 
   /**
    * Append the contents of this string fragment to aString
    * @return false if an out of memory condition is detected, true otherwise
    */
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool AppendTo(nsAString& aString,
                 const mozilla::fallible_t& aFallible) const {
     if (mState.mIs2b) {
       bool ok = aString.Append(m2b, mState.mLength, aFallible);
       if (!ok) {
         return false;
       }
 
@@ -164,17 +164,17 @@ public:
 
   /**
    * Append a substring of the contents of this string fragment to aString.
    * @param aString the string in which to append
    * @param aOffset where to start the substring in this text fragment
    * @param aLength the length of the substring
    * @return false if an out of memory condition is detected, true otherwise
    */
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool AppendTo(nsAString& aString, int32_t aOffset, int32_t aLength,
                 const mozilla::fallible_t& aFallible) const
   {
     if (mState.mIs2b) {
       bool ok = aString.Append(m2b + aOffset, aLength, aFallible);
       if (!ok) {
         return false;
       }
--- a/dom/base/nsXHTMLContentSerializer.h
+++ b/dom/base/nsXHTMLContentSerializer.h
@@ -42,17 +42,17 @@ class nsXHTMLContentSerializer : public 
  protected:
 
 
   virtual bool CheckElementStart(nsIContent * aContent,
                           bool & aForceFormat,
                           nsAString& aStr,
                           nsresult& aResult) override;
 
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   virtual bool AfterElementStart(nsIContent* aContent,
                                  nsIContent* aOriginalElement,
                                  nsAString& aStr) override;
 
   virtual bool CheckElementEnd(mozilla::dom::Element* aContent,
                                bool& aForceFormat,
                                nsAString& aStr) override;
 
@@ -65,35 +65,35 @@ class nsXHTMLContentSerializer : public 
   virtual bool LineBreakAfterClose(int32_t aNamespaceID, nsIAtom* aName) override;
 
   bool HasLongLines(const nsString& text, int32_t& aLastNewlineOffset);
 
   // functions to check if we enter in or leave from a preformated content
   virtual void MaybeEnterInPreContent(nsIContent* aNode) override;
   virtual void MaybeLeaveFromPreContent(nsIContent* aNode) override;
 
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   virtual bool SerializeAttributes(nsIContent* aContent,
                            nsIContent *aOriginalElement,
                            nsAString& aTagPrefix,
                            const nsAString& aTagNamespaceURI,
                            nsIAtom* aTagName,
                            nsAString& aStr,
                            uint32_t aSkipAttr,
                            bool aAddNSAttr) override;
 
   bool IsFirstChildOfOL(nsIContent* aElement);
 
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool SerializeLIValueAttribute(nsIContent* aElement,
                                  nsAString& aStr);
   bool IsShorthandAttr(const nsIAtom* aAttrName,
                          const nsIAtom* aElementName);
 
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   virtual bool AppendAndTranslateEntities(const nsAString& aStr,
                                           nsAString& aOutputStr) override;
 
   nsresult EscapeURI(nsIContent* aContent,
                      const nsAString& aURI,
                      nsAString& aEscapedURI);
 
 private:
--- a/dom/base/nsXMLContentSerializer.h
+++ b/dom/base/nsXMLContentSerializer.h
@@ -67,92 +67,92 @@ class nsXMLContentSerializer : public ns
                                  nsAString& aStr) override;
 
  protected:
   virtual ~nsXMLContentSerializer();
 
   /**
    * Appends a char16_t character and increments the column position
    */
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool AppendToString(const char16_t aChar,
                       nsAString& aOutputStr);
 
   /**
    * Appends a nsAString string and increments the column position
    */
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool AppendToString(const nsAString& aStr,
                       nsAString& aOutputStr);
 
   /**
    * Appends a string by replacing all line-endings
    * by mLineBreak, except in the case of raw output.
    * It increments the column position.
    */
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool AppendToStringConvertLF(const nsAString& aStr,
                                nsAString& aOutputStr);
 
   /**
    * Appends a string by wrapping it when necessary.
    * It updates the column position.
    */
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool AppendToStringWrapped(const nsASingleFragmentString& aStr,
                              nsAString& aOutputStr);
 
   /**
    * Appends a string by formating and wrapping it when necessary
    * It updates the column position.
    */
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool AppendToStringFormatedWrapped(const nsASingleFragmentString& aStr,
                                      nsAString& aOutputStr);
 
   // used by AppendToStringWrapped
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool AppendWrapped_WhitespaceSequence(
           nsASingleFragmentString::const_char_iterator &aPos,
           const nsASingleFragmentString::const_char_iterator aEnd,
           const nsASingleFragmentString::const_char_iterator aSequenceStart,
           nsAString &aOutputStr);
 
   // used by AppendToStringFormatedWrapped
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool AppendFormatedWrapped_WhitespaceSequence(
           nsASingleFragmentString::const_char_iterator &aPos,
           const nsASingleFragmentString::const_char_iterator aEnd,
           const nsASingleFragmentString::const_char_iterator aSequenceStart,
           bool &aMayIgnoreStartOfLineWhitespaceSequence,
           nsAString &aOutputStr);
 
   // used by AppendToStringWrapped and AppendToStringFormatedWrapped
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool AppendWrapped_NonWhitespaceSequence(
           nsASingleFragmentString::const_char_iterator &aPos,
           const nsASingleFragmentString::const_char_iterator aEnd,
           const nsASingleFragmentString::const_char_iterator aSequenceStart,
           bool &aMayIgnoreStartOfLineWhitespaceSequence,
           bool &aSequenceStartAfterAWhiteSpace,
           nsAString &aOutputStr);
 
   /**
    * add mLineBreak to the string
    * It updates the column position and other flags.
    */
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool AppendNewLineToString(nsAString& aOutputStr);
 
 
   /**
    * Appends a string by translating entities
    * It doesn't increment the column position
    */
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   virtual bool AppendAndTranslateEntities(const nsAString& aStr,
                                           nsAString& aOutputStr);
 
   /**
    * retrieve the text content of the node and append it to the given string
    * It doesn't increment the column position
    */
   nsresult AppendTextData(nsIContent* aNode,
@@ -192,27 +192,27 @@ class nsXMLContentSerializer : public ns
    * GenerateNewPrefix generates a new prefix and writes it to aPrefix
    */
   void GenerateNewPrefix(nsAString& aPrefix);
 
   uint32_t ScanNamespaceDeclarations(nsIContent* aContent,
                                      nsIContent *aOriginalElement,
                                      const nsAString& aTagNamespaceURI);
 
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   virtual bool SerializeAttributes(nsIContent* aContent,
                                    nsIContent *aOriginalElement,
                                    nsAString& aTagPrefix,
                                    const nsAString& aTagNamespaceURI,
                                    nsIAtom* aTagName,
                                    nsAString& aStr,
                                    uint32_t aSkipAttr,
                                    bool aAddNSAttr);
 
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool SerializeAttr(const nsAString& aPrefix,
                      const nsAString& aName,
                      const nsAString& aValue,
                      nsAString& aStr,
                      bool aDoEscapeEntities);
 
   bool IsJavaScript(nsIContent * aContent,
                       nsIAtom* aAttrNameAtom,
@@ -234,27 +234,27 @@ class nsXMLContentSerializer : public ns
 
   /**
    * This method is responsible for appending the '>' at the end of the start
    * tag, possibly preceded by '/' and maybe a ' ' before that too.
    *
    * aElement and aOriginalElement are the same as the corresponding arguments
    * to AppendElementStart.
    */
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool AppendEndOfElementStart(mozilla::dom::Element* aEleemnt,
                                mozilla::dom::Element* aOriginalElement,
                                nsAString& aStr);
 
   /**
    * This method can be redefine to serialize additional things just after
    * after the serialization ot the start tag.
    * (called at the end of AppendElementStart)
    */
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   virtual bool AfterElementStart(nsIContent* aContent,
                                  nsIContent* aOriginalElement,
                                  nsAString& aStr) { return true; };
 
   /**
    * This method can be redefined to check if the element can be serialized.
    * It is called when the serialization of the end tag is asked 
    * (AppendElementEnd)
@@ -293,26 +293,26 @@ class nsXMLContentSerializer : public ns
    * Returns true if a line break should be inserted after an element close tag
    */
   virtual bool LineBreakAfterClose(int32_t aNamespaceID, nsIAtom* aName);
 
   /**
    * add intendation. Call only in the case of formating and if the current
    * position is at 0. It updates the column position.
    */
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool AppendIndentation(nsAString& aStr);
 
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool IncrIndentation(nsIAtom* aName);
   void DecrIndentation(nsIAtom* aName);
 
   // Functions to check for newlines that needs to be added between nodes in
   // the root of a document. See mAddNewlineForRootNode
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   bool MaybeAddNewlineForRootNode(nsAString& aStr);
   void MaybeFlagNewlineForRootNode(nsINode* aNode);
 
   // Functions to check if we enter in or leave from a preformated content
   virtual void MaybeEnterInPreContent(nsIContent* aNode);
   virtual void MaybeLeaveFromPreContent(nsIContent* aNode);
 
   bool ShouldMaintainPreLevel() const;
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -357,35 +357,16 @@ DOMInterfaces = {
 'CSSValueList': {
     'nativeType': 'nsDOMCSSValueList'
 },
 
 'DataChannel': {
     'nativeType': 'nsDOMDataChannel',
 },
 
-'DataStore': [{
-    'workers': False
-}, {
-    'workers': True,
-    'nativeType': 'mozilla::dom::workers::WorkerDataStore',
-    'implicitJSContext': ['name', 'owner', 'readOnly', 'get', 'remove',
-                          'clear', 'revisionId', 'getLength', 'sync']
-}],
-
-'DataStoreCursor': [{
-    'workers': False,
-    'wrapperCache': False
-}, {
-    'workers': True,
-    'nativeType': 'mozilla::dom::workers::WorkerDataStoreCursor',
-    'wrapperCache': False,
-    'implicitJSContext': ['store', 'next', 'close']
-}],
-
 'DedicatedWorkerGlobalScope': {
     'headerFile': 'mozilla/dom/WorkerScope.h',
     'workers': True,
 },
 
 'DeviceAcceleration': {
     'headerFile': 'mozilla/dom/DeviceMotionEvent.h',
 },
@@ -1607,20 +1588,16 @@ DOMInterfaces = {
     ],
     # Rename a few things so we don't have both classes and methods
     # with the same name
     'binaryNames': {
         'performance': 'getPerformance',
     },
 },
 
-'WorkerNavigator': {
-    'implicitJSContext': ['getDataStores'],
-},
-
 'XMLHttpRequest': [
 {
     'nativeType': 'nsXMLHttpRequest',
     'implicitJSContext': [ 'send'],
 },
 {
     'workers': True,
 }],
--- a/dom/bindings/MozMap.h
+++ b/dom/bindings/MozMap.h
@@ -99,17 +99,17 @@ public:
   typedef void (* Enumerator)(DataType* aValue, void* aClosure);
   void EnumerateValues(Enumerator aEnumerator, void *aClosure)
   {
     for (auto iter = this->Iter(); !iter.Done(); iter.Next()) {
       aEnumerator(&iter.Get()->mData, aClosure);
     }
   }
 
-  MOZ_WARN_UNUSED_RESULT
+  MOZ_MUST_USE
   DataType* AddEntry(const nsAString& aKey)
   {
     EntryType* ent = this->PutEntry(aKey, fallible);
     if (!ent) {
       return nullptr;
     }
     return &ent->mData;
   }
--- a/dom/bindings/ToJSValue.h
+++ b/dom/bindings/ToJSValue.h
@@ -20,28 +20,28 @@ namespace mozilla {
 namespace dom {
 
 class Promise;
 
 // If ToJSValue returns false, it must set an exception on the
 // JSContext.
 
 // Accept strings.
-MOZ_WARN_UNUSED_RESULT bool
+MOZ_MUST_USE bool
 ToJSValue(JSContext* aCx,
           const nsAString& aArgument,
           JS::MutableHandle<JS::Value> aValue);
 
 // Accept booleans.  But be careful here: if we just have a function that takes
 // a boolean argument, then any pointer that doesn't match one of our other
 // signatures/templates will get treated as a boolean, which is clearly not
 // desirable.  So make this a template that only gets used if the argument type
 // is actually boolean
 template<typename T>
-MOZ_WARN_UNUSED_RESULT
+MOZ_MUST_USE
 typename EnableIf<IsSame<T, bool>::value, bool>::Type
 ToJSValue(JSContext* aCx,
           T aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   // Make sure we're called in a compartment
   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
 
@@ -119,49 +119,49 @@ ToJSValue(JSContext* aCx,
   // Make sure we're called in a compartment
   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
 
   aValue.setNumber(aArgument);
   return true;
 }
 
 // Accept CallbackObjects
-MOZ_WARN_UNUSED_RESULT inline bool
+MOZ_MUST_USE inline bool
 ToJSValue(JSContext* aCx,
           CallbackObject& aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   // Make sure we're called in a compartment
   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
 
   aValue.setObject(*aArgument.Callback());
 
   return MaybeWrapValue(aCx, aValue);
 }
 
 // Accept objects that inherit from nsWrapperCache (e.g. most
 // DOM objects).
 template <class T>
-MOZ_WARN_UNUSED_RESULT
+MOZ_MUST_USE
 typename EnableIf<IsBaseOf<nsWrapperCache, T>::value, bool>::Type
 ToJSValue(JSContext* aCx,
           T& aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   // Make sure we're called in a compartment
   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
   // Make sure non-webidl objects don't sneak in here
   MOZ_ASSERT(aArgument.IsDOMBinding());
 
   return GetOrCreateDOMReflector(aCx, aArgument, aValue);
 }
 
 // Accept typed arrays built from appropriate nsTArray values
 template<typename T>
-MOZ_WARN_UNUSED_RESULT
+MOZ_MUST_USE
 typename EnableIf<IsBaseOf<AllTypedArraysBase, T>::value, bool>::Type
 ToJSValue(JSContext* aCx,
           const TypedArrayCreator<T>& aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   // Make sure we're called in a compartment
   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
 
@@ -171,17 +171,17 @@ ToJSValue(JSContext* aCx,
   }
   aValue.setObject(*obj);
   return true;
 }
 
 // Accept objects that inherit from nsISupports but not nsWrapperCache (e.g.
 // DOM File).
 template <class T>
-MOZ_WARN_UNUSED_RESULT
+MOZ_MUST_USE
 typename EnableIf<!IsBaseOf<nsWrapperCache, T>::value &&
                   !IsBaseOf<CallbackObject, T>::value &&
                   IsBaseOf<nsISupports, T>::value, bool>::Type
 ToJSValue(JSContext* aCx,
           T& aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   // Make sure we're called in a compartment
@@ -189,139 +189,139 @@ ToJSValue(JSContext* aCx,
 
   qsObjectHelper helper(ToSupports(&aArgument), nullptr);
   JS::Rooted<JSObject*> scope(aCx, JS::CurrentGlobalOrNull(aCx));
   return XPCOMObjectToJsval(aCx, scope, helper, nullptr, true, aValue);
 }
 
 // Accept nsRefPtr/nsCOMPtr
 template <typename T>
-MOZ_WARN_UNUSED_RESULT bool
+MOZ_MUST_USE bool
 ToJSValue(JSContext* aCx,
           const nsCOMPtr<T>& aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   return ToJSValue(aCx, *aArgument.get(), aValue);
 }
 
 template <typename T>
-MOZ_WARN_UNUSED_RESULT bool
+MOZ_MUST_USE bool
 ToJSValue(JSContext* aCx,
           const RefPtr<T>& aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   return ToJSValue(aCx, *aArgument.get(), aValue);
 }
 
 template <typename T>
-MOZ_WARN_UNUSED_RESULT bool
+MOZ_MUST_USE bool
 ToJSValue(JSContext* aCx,
           const NonNull<T>& aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   return ToJSValue(aCx, *aArgument.get(), aValue);
 }
 
 // Accept WebIDL dictionaries
 template <class T>
-MOZ_WARN_UNUSED_RESULT
+MOZ_MUST_USE
 typename EnableIf<IsBaseOf<DictionaryBase, T>::value, bool>::Type
 ToJSValue(JSContext* aCx,
           const T& aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   return aArgument.ToObjectInternal(aCx, aValue);
 }
 
 // Accept existing JS values (which may not be same-compartment with us
-MOZ_WARN_UNUSED_RESULT inline bool
+MOZ_MUST_USE inline bool
 ToJSValue(JSContext* aCx, JS::Handle<JS::Value> aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   aValue.set(aArgument);
   return MaybeWrapValue(aCx, aValue);
 }
 
 // Accept existing JS values on the Heap (which may not be same-compartment with us
-MOZ_WARN_UNUSED_RESULT inline bool
+MOZ_MUST_USE inline bool
 ToJSValue(JSContext* aCx, const JS::Heap<JS::Value>& aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   aValue.set(aArgument);
   return MaybeWrapValue(aCx, aValue);
 }
 
 // Accept existing rooted JS values (which may not be same-compartment with us
-MOZ_WARN_UNUSED_RESULT inline bool
+MOZ_MUST_USE inline bool
 ToJSValue(JSContext* aCx, const JS::Rooted<JS::Value>& aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   aValue.set(aArgument);
   return MaybeWrapValue(aCx, aValue);
 }
 
 // Accept existing rooted JS objects (which may not be same-compartment with
 // us).
-MOZ_WARN_UNUSED_RESULT inline bool
+MOZ_MUST_USE inline bool
 ToJSValue(JSContext* aCx, const JS::Rooted<JSObject*>& aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   aValue.setObjectOrNull(aArgument);
   return MaybeWrapObjectOrNullValue(aCx, aValue);
 }
 
 // Accept nsresult, for use in rejections, and create an XPCOM
 // exception object representing that nsresult.
-MOZ_WARN_UNUSED_RESULT bool
+MOZ_MUST_USE bool
 ToJSValue(JSContext* aCx,
           nsresult aArgument,
           JS::MutableHandle<JS::Value> aValue);
 
 // Accept ErrorResult, for use in rejections, and create an exception
 // representing the failure.  Note, the ErrorResult must indicate a failure
 // with aArgument.Failure() returning true.
-MOZ_WARN_UNUSED_RESULT bool
+MOZ_MUST_USE bool
 ToJSValue(JSContext* aCx,
           ErrorResult& aArgument,
           JS::MutableHandle<JS::Value> aValue);
 
 // Accept owning WebIDL unions.
 template <typename T>
-MOZ_WARN_UNUSED_RESULT
+MOZ_MUST_USE
 typename EnableIf<IsBaseOf<AllOwningUnionBase, T>::value, bool>::Type
 ToJSValue(JSContext* aCx,
           const T& aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
   return aArgument.ToJSVal(aCx, global, aValue);
 }
 
 // Accept pointers to other things we accept
 template <typename T>
-MOZ_WARN_UNUSED_RESULT
+MOZ_MUST_USE
 typename EnableIf<IsPointer<T>::value, bool>::Type
 ToJSValue(JSContext* aCx,
           T aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   return ToJSValue(aCx, *aArgument, aValue);
 }
 
 #ifdef SPIDERMONKEY_PROMISE
 // Accept Promise objects, which need special handling.
-MOZ_WARN_UNUSED_RESULT bool
+MOZ_MUST_USE bool
 ToJSValue(JSContext* aCx,
           Promise& aArgument,
           JS::MutableHandle<JS::Value> aValue);
 #endif // SPIDERMONKEY_PROMISE
 
 // Accept arrays of other things we accept
 template <typename T>
-MOZ_WARN_UNUSED_RESULT bool
+MOZ_MUST_USE bool
 ToJSValue(JSContext* aCx,
           T* aArguments,
           size_t aLength,
           JS::MutableHandle<JS::Value> aValue)
 {
   // Make sure we're called in a compartment
   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
 
@@ -338,37 +338,37 @@ ToJSValue(JSContext* aCx,
   if (!arrayObj) {
     return false;
   }
   aValue.setObject(*arrayObj);
   return true;
 }
 
 template <typename T>
-MOZ_WARN_UNUSED_RESULT bool
+MOZ_MUST_USE bool
 ToJSValue(JSContext* aCx,
           const nsTArray<T>& aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   return ToJSValue(aCx, aArgument.Elements(),
                    aArgument.Length(), aValue);
 }
 
 template <typename T>
-MOZ_WARN_UNUSED_RESULT bool
+MOZ_MUST_USE bool
 ToJSValue(JSContext* aCx,
           const FallibleTArray<T>& aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   return ToJSValue(aCx, aArgument.Elements(),
                    aArgument.Length(), aValue);
 }
 
 template <typename T, int N>
-MOZ_WARN_UNUSED_RESULT bool
+MOZ_MUST_USE bool
 ToJSValue(JSContext* aCx,
           const T(&aArgument)[N],
           JS::MutableHandle<JS::Value> aValue)
 {
   return ToJSValue(aCx, aArgument, N, aValue);
 }
 
 } // namespace dom
--- a/dom/canvas/ImageBitmap.cpp
+++ b/dom/canvas/ImageBitmap.cpp
@@ -466,56 +466,51 @@ ImageBitmap::PrepareForDrawTarget(gfx::D
                                              target->GetFormat());
 
     if (!target) {
       mSurface = nullptr;
       RefPtr<gfx::SourceSurface> surface(mSurface);
       return surface.forget();
     }
 
-    // We need to fall back to generic copying and cropping for the Windows8.1,
-    // D2D1 backend.
-    // In the Windows8.1 D2D1 backend, it might trigger "partial upload" from a
-    // non-SourceSurfaceD2D1 surface to a D2D1Image in the following
-    // CopySurface() step. However, the "partial upload" only supports uploading
-    // a rectangle starts from the upper-left point, which means it cannot
-    // upload an arbitrary part of the source surface and this causes problems
-    // if the mPictureRect is not starts from the upper-left point.
-    if (target->GetBackendType() == BackendType::DIRECT2D1_1 &&
-        mSurface->GetType() != SurfaceType::D2D1_1_IMAGE) {
-      RefPtr<DataSourceSurface> dataSurface = mSurface->GetDataSurface();
-      if (NS_WARN_IF(!dataSurface)) {
-        mSurface = nullptr;
-        RefPtr<gfx::SourceSurface> surface(mSurface);
-        return surface.forget();
-      }
-
-      mSurface = CropAndCopyDataSourceSurface(dataSurface, mPictureRect);
-    } else {
-      target->CopySurface(mSurface, surfPortion, dest);
-      mSurface = target->Snapshot();
-    }
+    target->CopySurface(mSurface, surfPortion, dest);
+    mSurface = target->Snapshot();
 
     // Make mCropRect match new surface we've cropped to
     mPictureRect.MoveTo(0, 0);
   }
 
   // Pre-multiply alpha here.
   // Apply pre-multiply alpha only if mIsPremultipliedAlpha is false.
   if (!mIsPremultipliedAlpha) {
     MOZ_ASSERT(mSurface->GetFormat() == SurfaceFormat::R8G8B8A8 ||
                mSurface->GetFormat() == SurfaceFormat::B8G8R8A8 ||
                mSurface->GetFormat() == SurfaceFormat::A8R8G8B8);
 
-    RefPtr<DataSourceSurface> dataSourceSurface = mSurface->GetDataSurface();
-    MOZ_ASSERT(dataSourceSurface);
+    RefPtr<DataSourceSurface> dstSurface = mSurface->GetDataSurface();
+    MOZ_ASSERT(dstSurface);
+
+    RefPtr<DataSourceSurface> srcSurface;
+    DataSourceSurface::MappedSurface srcMap;
+    DataSourceSurface::MappedSurface dstMap;
 
-    DataSourceSurface::ScopedMap map(dataSourceSurface, DataSourceSurface::READ_WRITE);
-    if (NS_WARN_IF(!map.IsMapped())) {
-      return nullptr;
+    if (!dstSurface->Map(DataSourceSurface::MapType::READ_WRITE, &dstMap)) {
+      srcSurface = dstSurface;
+      if (!srcSurface->Map(DataSourceSurface::READ, &srcMap)) {
+        gfxCriticalError() << "Failed to map source surface for premultiplying alpha.";
+        return nullptr;
+      }
+
+      dstSurface = Factory::CreateDataSourceSurface(srcSurface->GetSize(), srcSurface->GetFormat());
+
+      if (!dstSurface || !dstSurface->Map(DataSourceSurface::MapType::WRITE, &dstMap)) {
+        gfxCriticalError() << "Failed to map destination surface for premultiplying alpha.";
+        srcSurface->Unmap();
+        return nullptr;
+      }
     }
 
     uint8_t rIndex = 0;
     uint8_t gIndex = 0;
     uint8_t bIndex = 0;
     uint8_t aIndex = 0;
 
     if (mSurface->GetFormat() == SurfaceFormat::R8G8B8A8) {
@@ -530,34 +525,41 @@ ImageBitmap::PrepareForDrawTarget(gfx::D
       aIndex = 3;
     } else if (mSurface->GetFormat() == SurfaceFormat::A8R8G8B8) {
       rIndex = 1;
       gIndex = 2;
       bIndex = 3;
       aIndex = 0;
     }
 
-    for (int i = 0; i < dataSourceSurface->GetSize().height; ++i) {
-      uint8_t* bufferPtr = map.GetData() + map.GetStride() * i;
-      for (int i = 0; i < dataSourceSurface->GetSize().width; ++i) {
-        uint8_t r = *(bufferPtr+rIndex);
-        uint8_t g = *(bufferPtr+gIndex);
-        uint8_t b = *(bufferPtr+bIndex);
-        uint8_t a = *(bufferPtr+aIndex);
+    for (int i = 0; i < dstSurface->GetSize().height; ++i) {
+      uint8_t* bufferPtr = dstMap.mData + dstMap.mStride * i;
+      uint8_t* srcBufferPtr = srcSurface ? srcMap.mData + srcMap.mStride * i : bufferPtr;
+      for (int i = 0; i < dstSurface->GetSize().width; ++i) {
+        uint8_t r = *(srcBufferPtr+rIndex);
+        uint8_t g = *(srcBufferPtr+gIndex);
+        uint8_t b = *(srcBufferPtr+bIndex);
+        uint8_t a = *(srcBufferPtr+aIndex);
 
         *(bufferPtr+rIndex) = gfxUtils::sPremultiplyTable[a * 256 + r];
         *(bufferPtr+gIndex) = gfxUtils::sPremultiplyTable[a * 256 + g];
         *(bufferPtr+bIndex) = gfxUtils::sPremultiplyTable[a * 256 + b];
         *(bufferPtr+aIndex) = a;
 
         bufferPtr += 4;
+        srcBufferPtr += 4;
       }
     }
 
-    mSurface = dataSourceSurface;
+    dstSurface->Unmap();
+    if (srcSurface) {
+      srcSurface->Unmap();
+    }
+
+    mSurface = dstSurface;
   }
 
   // Replace our surface with one optimized for the target we're about to draw
   // to, under the assumption it'll likely be drawn again to that target.
   // This call should be a no-op for already-optimized surfaces
   mSurface = target->OptimizeSourceSurface(mSurface);
 
   RefPtr<gfx::SourceSurface> surface(mSurface);
@@ -878,17 +880,17 @@ ImageBitmap::CreateInternal(nsIGlobalObj
                             const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
 {
   if (!aImageBitmap.mData) {
     aRv.Throw(NS_ERROR_NOT_AVAILABLE);
     return nullptr;
   }
 
   RefPtr<layers::Image> data = aImageBitmap.mData;
-  RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
+  RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, aImageBitmap.mIsPremultipliedAlpha);
 
   // Set the picture rectangle.
   if (ret && aCropRect.isSome()) {
     ret->SetPictureRect(aCropRect.ref(), aRv);
   }
 
   return ret.forget();
 }
--- a/dom/canvas/WebGLProgram.cpp
+++ b/dom/canvas/WebGLProgram.cpp
@@ -950,17 +950,29 @@ WebGLProgram::LinkProgram()
         // This can't be done trivially, because we have to deal with mapped names too.
         mVertShader->ApplyTransformFeedbackVaryings(mGLName,
                                                     mTransformFeedbackVaryings,
                                                     mTransformFeedbackBufferMode,
                                                     &mTempMappedVaryings);
     }
 
     LinkAndUpdate();
-    if (IsLinked())
+    if (IsLinked()) {
+        // Check if the attrib name conflicting to uniform name
+        for (const auto& uniform : mMostRecentLinkInfo->uniformMap) {
+            if (mMostRecentLinkInfo->attribMap.find(uniform.first) != mMostRecentLinkInfo->attribMap.end()) {
+                mLinkLog = nsPrintfCString("The uniform name (%s) conflicts with attribute name.",
+                                           uniform.first.get());
+                mMostRecentLinkInfo = nullptr;
+                break;
+            }
+        }
+    }
+
+    if (mMostRecentLinkInfo)
         return;
 
     // Failed link.
     if (mContext->ShouldGenerateWarnings()) {
         // report shader/program infoLogs as warnings.
         // note that shader compilation errors can be deferred to linkProgram,
         // which is why we can't do anything in compileShader. In practice we could
         // report in compileShader the translation errors generated by ANGLE,
--- a/dom/canvas/test/reftest/reftest.list
+++ b/dom/canvas/test/reftest/reftest.list
@@ -153,12 +153,12 @@ skip-if(!winWidget) pref(webgl.disable-a
 
 # focus rings
 pref(canvas.focusring.enabled,true) skip-if(B2G) skip-if(cocoaWidget) skip-if(winWidget) needs-focus == drawFocusIfNeeded.html drawFocusIfNeeded-ref.html
 pref(canvas.customfocusring.enabled,true) skip-if(B2G) skip-if(cocoaWidget) skip-if(Android) skip-if(winWidget) fuzzy-if(gtkWidget,64,410) needs-focus == drawCustomFocusRing.html drawCustomFocusRing-ref.html
 
 # Check that captureStream() displays in a local video element
 == capturestream.html wrapper.html?green.png
 
-fuzzy-if(azureSkiaGL,1,2) fuzzy-if(Android,3,40) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),1,1) == 1177726-text-stroke-bounds.html 1177726-text-stroke-bounds-ref.html
+fuzzy-if(azureSkia,16,2) fuzzy-if(Android,3,40) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),1,1) == 1177726-text-stroke-bounds.html 1177726-text-stroke-bounds-ref.html
 
 # Canvas Filter Reftests
 include filters/reftest.list
--- a/dom/canvas/test/test_canvas.html
+++ b/dom/canvas/test/test_canvas.html
@@ -14305,21 +14305,17 @@ ctx.lineCap = 'round';
 ctx.lineJoin = 'round';
 
 ctx.beginPath();
 ctx.moveTo(50, 25);
 ctx.lineTo(50, 25);
 ctx.closePath();
 ctx.stroke();
 
-if (IsAzureSkia()) {
-  isPixel(ctx, 50,25, 0,255,0,255, 0);
-} else {
-  todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
-}
+todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
 
 }
 </script>
 
 <!-- [[[ test_2d.path.stroke.prune.corner.html ]]] -->
 
 <p>Canvas test: 2d.path.stroke.prune.corner</p>
 <!-- Testing: Zero-length line segments are removed before stroking with miters -->
@@ -14446,21 +14442,17 @@ ctx.lineCap = 'round';
 ctx.lineJoin = 'round';
 
 ctx.beginPath();
 ctx.rect(50, 25, 0, 0);
 ctx.stroke();
 
 ctx.strokeRect(50, 25, 0, 0);
 
-if (IsAzureSkia()) {
-  isPixel(ctx, 50,25, 0,255,0,255, 0);
-} else {
-  todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
-}
+todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
 
 }
 </script>
 
 <!-- [[[ test_2d.path.stroke.scale1.html ]]] -->
 
 <p>Canvas test: 2d.path.stroke.scale1</p>
 <!-- Testing: Stroke line widths are scaled by the current transformation matrix -->
--- a/dom/canvas/test/webgl-conf/generated-mochitest.ini
+++ b/dom/canvas/test/webgl-conf/generated-mochitest.ini
@@ -2738,17 +2738,16 @@ fail-if = (os == 'android')
 [generated/test_conformance__glsl__misc__shader-without-precision.frag.html]
 [generated/test_conformance__glsl__misc__shaders-with-constant-expression-loop-conditions.html]
 [generated/test_conformance__glsl__misc__shaders-with-invariance.html]
 fail-if = 1
 [generated/test_conformance__glsl__misc__shaders-with-mis-matching-uniforms.html]
 [generated/test_conformance__glsl__misc__shaders-with-mis-matching-varyings.html]
 [generated/test_conformance__glsl__misc__shaders-with-missing-varyings.html]
 [generated/test_conformance__glsl__misc__shaders-with-name-conflicts.html]
-fail-if = 1
 [generated/test_conformance__glsl__misc__shaders-with-uniform-structs.html]
 [generated/test_conformance__glsl__misc__shaders-with-varyings.html]
 [generated/test_conformance__glsl__misc__shared.html]
 [generated/test_conformance__glsl__misc__struct-equals.html]
 [generated/test_conformance__glsl__misc__struct-mixed-array-declarators.html]
 [generated/test_conformance__glsl__misc__struct-nesting-exceeds-maximum.html]
 [generated/test_conformance__glsl__misc__struct-nesting-of-variable-names.html]
 fail-if = (os == 'mac' && os_version == '10.10')
--- a/dom/canvas/test/webgl-conf/mochitest-errata.ini
+++ b/dom/canvas/test/webgl-conf/mochitest-errata.ini
@@ -32,17 +32,16 @@ skip-if = os == 'b2g' || ((os == 'linux'
 
 [generated/test_..__always-fail.html]
 fail-if = 1
 [generated/test_conformance__context__context-lost.html]
 fail-if = 1
 [generated/test_conformance__glsl__misc__shaders-with-invariance.html]
 fail-if = 1
 [generated/test_conformance__glsl__misc__shaders-with-name-conflicts.html]
-fail-if = 1
 [generated/test_conformance__renderbuffers__feedback-loop.html]
 fail-if = 1
 [generated/test_conformance__textures__texture-copying-feedback-loops.html]
 fail-if = 1
 
 ####################
 # Tests requesting non-local network connections.
 
deleted file mode 100644
--- a/dom/datastore/DataStore.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/dom/DataStore.h"
-#include "mozilla/dom/DataStoreCursor.h"
-#include "mozilla/dom/DataStoreBinding.h"
-#include "mozilla/dom/DataStoreImplBinding.h"
-#include "mozilla/dom/Navigator.h"
-#include "mozilla/dom/Promise.h"
-#include "mozilla/ErrorResult.h"
-#include "mozilla/Preferences.h"
-#include "AccessCheck.h"
-#include "nsContentUtils.h"
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_ADDREF_INHERITED(DataStore, DOMEventTargetHelper)
-NS_IMPL_RELEASE_INHERITED(DataStore, DOMEventTargetHelper)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DataStore)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
-
-NS_IMPL_CYCLE_COLLECTION_INHERITED(DataStore, DOMEventTargetHelper, mStore)
-
-DataStore::DataStore(nsPIDOMWindowInner* aWindow)
-  : DOMEventTargetHelper(aWindow)
-{
-}
-
-DataStore::~DataStore()
-{
-}
-
-already_AddRefed<DataStore>
-DataStore::Constructor(GlobalObject& aGlobal, ErrorResult& aRv)
-{
-  nsCOMPtr<nsPIDOMWindowInner> window =
-    do_QueryInterface(aGlobal.GetAsSupports());
-  if (!window) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  RefPtr<DataStore> store = new DataStore(window);
-  return store.forget();
-}
-
-JSObject*
-DataStore::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
-  return DataStoreBinding::Wrap(aCx, this, aGivenProto);
-}
-
-/*static*/ bool
-DataStore::EnabledForScope(JSContext* aCx, JS::Handle<JSObject*> aObj)
-{
-  // Only expose the interface when it is:
-  // 1. enabled by the preference and
-  // 2. accessed by the chrome codes in Gecko.
-  return (Navigator::HasDataStoreSupport(aCx, aObj) &&
-          nsContentUtils::ThreadsafeIsCallerChrome());
-}
-
-void
-DataStore::GetName(nsAString& aName, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mStore);
-
-  nsAutoString name;
-  mStore->GetName(name, aRv);
-  aName.Assign(name);
-}
-
-void
-DataStore::GetOwner(nsAString& aOwner, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mStore);
-
-  nsAutoString owner;
-  mStore->GetOwner(owner, aRv);
-  aOwner.Assign(owner);
-}
-
-bool
-DataStore::GetReadOnly(ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mStore);
-
-  return mStore->GetReadOnly(aRv);
-}
-
-already_AddRefed<Promise>
-DataStore::Get(const Sequence<OwningStringOrUnsignedLong>& aId,
-               ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mStore);
-
-  return mStore->Get(aId, aRv);
-}
-
-already_AddRefed<Promise>
-DataStore::Put(JSContext* aCx,
-               JS::Handle<JS::Value> aObj,
-               const StringOrUnsignedLong& aId,
-               const nsAString& aRevisionId,
-               ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mStore);
-
-  return mStore->Put(aObj, aId, aRevisionId, aRv);
-}
-
-already_AddRefed<Promise>
-DataStore::Add(JSContext* aCx,
-               JS::Handle<JS::Value> aObj,
-               const Optional<StringOrUnsignedLong>& aId,
-               const nsAString& aRevisionId,
-               ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mStore);
-
-  return mStore->Add(aObj, aId, aRevisionId, aRv);
-}
-
-already_AddRefed<Promise>
-DataStore::Remove(const StringOrUnsignedLong& aId,
-                  const nsAString& aRevisionId,
-                  ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mStore);
-
-  return mStore->Remove(aId, aRevisionId, aRv);
-}
-
-already_AddRefed<Promise>
-DataStore::Clear(const nsAString& aRevisionId, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mStore);
-
-  return mStore->Clear(aRevisionId, aRv);
-}
-
-void
-DataStore::GetRevisionId(nsAString& aRevisionId, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mStore);
-
-  nsAutoString revisionId;
-  mStore->GetRevisionId(revisionId, aRv);
-  aRevisionId.Assign(revisionId);
-}
-
-already_AddRefed<Promise>
-DataStore::GetLength(ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mStore);
-
-  return mStore->GetLength(aRv);
-}
-
-already_AddRefed<DataStoreCursor>
-DataStore::Sync(const nsAString& aRevisionId, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mStore);
-
-  return mStore->Sync(aRevisionId, aRv);
-}
-
-void
-DataStore::SetDataStoreImpl(DataStoreImpl& aStore, ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(!mStore);
-
-  mStore = &aStore;
-  mStore->SetEventTarget(*this, aRv);
-}
-
-} //namespace dom
-} //namespace mozilla
deleted file mode 100644
--- a/dom/datastore/DataStore.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_DataStore_h
-#define mozilla_dom_DataStore_h
-
-#include "mozilla/DOMEventTargetHelper.h"
-
-namespace mozilla {
-
-class ErrorResult;
-
-namespace dom {
-
-class Promise;
-class DataStoreCursor;
-class DataStoreImpl;
-class StringOrUnsignedLong;
-class OwningStringOrUnsignedLong;
-
-class DataStore final : public DOMEventTargetHelper
-{
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DataStore,
-                                           DOMEventTargetHelper)
-
-  explicit DataStore(nsPIDOMWindowInner* aWindow);
-
-  // WebIDL (internal functions)
-
-  static already_AddRefed<DataStore> Constructor(GlobalObject& aGlobal,
-                                                 ErrorResult& aRv);
-
-  virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
-
-  static bool EnabledForScope(JSContext* aCx, JS::Handle<JSObject*> aObj);
-
-  // WebIDL (public APIs)
-
-  void GetName(nsAString& aName, ErrorResult& aRv);
-
-  void GetOwner(nsAString& aOwner, ErrorResult& aRv);
-
-  bool GetReadOnly(ErrorResult& aRv);
-
-  already_AddRefed<Promise> Get(const Sequence<OwningStringOrUnsignedLong>& aId,
-                                ErrorResult& aRv);
-
-  already_AddRefed<Promise> Put(JSContext* aCx,
-                                JS::Handle<JS::Value> aObj,
-                                const StringOrUnsignedLong& aId,
-                                const nsAString& aRevisionId,
-                                ErrorResult& aRv);
-
-  already_AddRefed<Promise> Add(JSContext* aCx,
-                                JS::Handle<JS::Value> aObj,
-                                const Optional<StringOrUnsignedLong>& aId,
-                                const nsAString& aRevisionId,
-                                ErrorResult& aRv);
-
-  already_AddRefed<Promise> Remove(const StringOrUnsignedLong& aId,
-                                   const nsAString& aRevisionId,
-                                   ErrorResult& aRv);
-
-  already_AddRefed<Promise> Clear(const nsAString& aRevisionId,
-                                  ErrorResult& aRv);
-
-  void GetRevisionId(nsAString& aRevisionId, ErrorResult& aRv);
-
-  already_AddRefed<Promise> GetLength(ErrorResult& aRv);
-
-  already_AddRefed<DataStoreCursor> Sync(const nsAString& aRevisionId,
-                                         ErrorResult& aRv);
-
-  IMPL_EVENT_HANDLER(change)
-
-  // This internal function (ChromeOnly) is aimed to make the DataStore keep a
-  // reference to the DataStoreImpl which really implements the API's logic in
-  // JS. We also need to let the DataStoreImpl implementation keep the event
-  // target of DataStore, so that it can know where to fire the events.
-  void SetDataStoreImpl(DataStoreImpl& aStore, ErrorResult& aRv);
-
-private:
-  ~DataStore();
-
-  RefPtr<DataStoreImpl> mStore;
-};
-
-} //namespace dom
-} //namespace mozilla
-
-#endif
deleted file mode 100644
--- a/dom/datastore/DataStore.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-component {db5c9602-030f-4bff-a3de-881a8de370f2} DataStoreImpl.js
-contract @mozilla.org/dom/datastore;1 {db5c9602-030f-4bff-a3de-881a8de370f2}
deleted file mode 100644
--- a/dom/datastore/DataStoreCallbacks.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_DataStoreCallbacks_h
-#define mozilla_dom_DataStoreCallbacks_h
-
-#include "nsISupports.h"
-
-namespace mozilla {
-namespace dom {
-
-class DataStoreDB;
-
-class DataStoreDBCallback
-{
-public:
-  NS_IMETHOD_(MozExternalRefCountType) AddRef(void) = 0;
-  NS_IMETHOD_(MozExternalRefCountType) Release(void) = 0;
-
-  enum RunStatus {
-    Success,
-    CreatedSchema,
-    Error
-  };
-
-  virtual void Run(DataStoreDB* aDb, RunStatus aStatus) = 0;
-
-protected:
-  virtual ~DataStoreDBCallback()
-  {
-  }
-};
-
-class DataStoreRevisionCallback
-{
-public:
-  NS_IMETHOD_(MozExternalRefCountType) AddRef(void) = 0;
-  NS_IMETHOD_(MozExternalRefCountType) Release(void) = 0;
-
-  virtual void Run(const nsAString& aRevisionID) = 0;
-
-protected:
-  virtual ~DataStoreRevisionCallback()
-  {
-  }
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_DataStoreCallbacks_h
deleted file mode 100644
--- a/dom/datastore/DataStoreChangeNotifier.jsm
+++ /dev/null
@@ -1,223 +0,0 @@
-/* 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/. */
-
-"use strict"
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-this.EXPORTED_SYMBOLS = ["DataStoreChangeNotifier"];
-
-function debug(s) {
-  //dump('DEBUG DataStoreChangeNotifier: ' + s + '\n');
-}
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
-                                   "@mozilla.org/parentprocessmessagemanager;1",
-                                   "nsIMessageBroadcaster");
-
-XPCOMUtils.defineLazyServiceGetter(this, "dataStoreService",
-                                   "@mozilla.org/datastore-service;1",
-                                   "nsIDataStoreService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "systemMessenger",
-                                   "@mozilla.org/system-message-internal;1",
-                                   "nsISystemMessagesInternal");
-
-var kSysMsgOnChangeShortTimeoutSec =
-    Services.prefs.getIntPref("dom.datastore.sysMsgOnChangeShortTimeoutSec");
-var kSysMsgOnChangeLongTimeoutSec =
-    Services.prefs.getIntPref("dom.datastore.sysMsgOnChangeLongTimeoutSec");
-
-this.DataStoreChangeNotifier = {
-  children: [],
-  messages: [ "DataStore:Changed", "DataStore:RegisterForMessages",
-              "DataStore:UnregisterForMessages",
-              "child-process-shutdown" ],
-
-  // These hashes are used for storing the mapping between the datastore
-  // identifiers (name | owner manifest URL) and their correspondent timers. 
-  // The object literal is defined as below:
-  //
-  // {
-  //   "datastore name 1|owner manifest URL 1": timer1,
-  //   "datastore name 2|owner manifest URL 2": timer2,
-  //   ...
-  // }
-  sysMsgOnChangeShortTimers: {},
-  sysMsgOnChangeLongTimers: {},
-
-  init: function() {
-    debug("init");
-
-    this.messages.forEach((function(msgName) {
-      ppmm.addMessageListener(msgName, this);
-    }).bind(this));
-
-    Services.obs.addObserver(this, 'xpcom-shutdown', false);
-  },
-
-  observe: function(aSubject, aTopic, aData) {
-    debug("observe");
-
-    switch (aTopic) {
-      case 'xpcom-shutdown':
-        this.messages.forEach((function(msgName) {
-          ppmm.removeMessageListener(msgName, this);
-        }).bind(this));
-
-        Services.obs.removeObserver(this, 'xpcom-shutdown');
-        ppmm = null;
-        break;
-
-      default:
-        debug("Wrong observer topic: " + aTopic);
-        break;
-    }
-  },
-
-  broadcastMessage: function broadcastMessage(aData) {
-    debug("broadcast");
-
-    this.children.forEach(function(obj) {
-      if (obj.store == aData.store && obj.owner == aData.owner) {
-        obj.mm.sendAsyncMessage("DataStore:Changed:Return:OK", aData);
-      }
-    });
-  },
-
-  broadcastSystemMessage: function(aStore, aOwner) {
-    debug("broadcastSystemMessage");
-
-    // Clear relevant timers.
-    var storeKey = aStore + "|" + aOwner;
-    var shortTimer = this.sysMsgOnChangeShortTimers[storeKey];
-    if (shortTimer) {
-      shortTimer.cancel();
-      delete this.sysMsgOnChangeShortTimers[storeKey];
-    }
-    var longTimer = this.sysMsgOnChangeLongTimers[storeKey];
-    if (longTimer) {
-      longTimer.cancel();
-      delete this.sysMsgOnChangeLongTimers[storeKey];
-    }
-
-    systemMessenger.broadcastMessage("datastore-update-" + aStore,
-                                     { owner: aOwner });
-  },
-
-  // Use the following logic to broadcast system messages in a moderate pattern.
-  // 1. When an entry is changed, start a short timer and a long timer.
-  // 2. If an entry is changed while the short timer is running, reset it.
-  //    Do not reset the long timer.
-  // 3. Once either fires, broadcast the system message and cancel both timers.
-  setSystemMessageTimeout: function(aStore, aOwner) {
-    debug("setSystemMessageTimeout");
-
-    var storeKey = aStore + "|" + aOwner;
-
-    // Reset the short timer.
-    var shortTimer = this.sysMsgOnChangeShortTimers[storeKey];
-    if (!shortTimer) {
-      shortTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-      this.sysMsgOnChangeShortTimers[storeKey] = shortTimer;
-    } else {
-      shortTimer.cancel();
-    }
-    shortTimer.initWithCallback({ notify: this.broadcastSystemMessage.bind(this, aStore, aOwner) },
-                                kSysMsgOnChangeShortTimeoutSec * 1000,
-                                Ci.nsITimer.TYPE_ONE_SHOT);
-
-    // Set the long timer if necessary.
-    if (!this.sysMsgOnChangeLongTimers[storeKey]) {
-      var longTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-      this.sysMsgOnChangeLongTimers[storeKey] = longTimer;
-      longTimer.initWithCallback({ notify: this.broadcastSystemMessage.bind(this, aStore, aOwner) },
-                                 kSysMsgOnChangeLongTimeoutSec * 1000,
-                                 Ci.nsITimer.TYPE_ONE_SHOT);
-    }
-  },
-
-  receiveMessage: function(aMessage) {
-    debug("receiveMessage ");
-
-    // No check has to be done when the message is 'child-process-shutdown'.
-    if (aMessage.name != "child-process-shutdown") {
-      let principal = aMessage.principal;
-      if (!principal || !dataStoreService.checkPermission(principal)) {
-        return;
-      }
-    }
-
-    switch (aMessage.name) {
-      case "DataStore:Changed":
-        this.broadcastMessage(aMessage.data);
-        if (Services.prefs.getBoolPref("dom.sysmsg.enabled")) {
-          this.setSystemMessageTimeout(aMessage.data.store, aMessage.data.owner);
-        }
-        break;
-
-      case "DataStore:RegisterForMessages":
-        debug("Register!");
-
-        for (let i = 0; i < this.children.length; ++i) {
-          if (this.children[i].mm == aMessage.target &&
-              this.children[i].store == aMessage.data.store &&
-              this.children[i].owner == aMessage.data.owner) {
-            debug("Register on existing index: " + i);
-            this.children[i].windows.push(aMessage.data.innerWindowID);
-            return;
-          }
-        }
-
-        this.children.push({ mm: aMessage.target,
-                             store: aMessage.data.store,
-                             owner: aMessage.data.owner,
-                             windows: [ aMessage.data.innerWindowID ]});
-        break;
-
-      case "DataStore:UnregisterForMessages":
-        debug("Unregister");
-
-        for (let i = 0; i < this.children.length; ++i) {
-          if (this.children[i].mm == aMessage.target) {
-            debug("Unregister index: " + i);
-
-            var pos = this.children[i].windows.indexOf(aMessage.data.innerWindowID);
-            if (pos != -1) {
-              this.children[i].windows.splice(pos, 1);
-            }
-
-            if (this.children[i].windows.length) {
-              continue;
-            }
-
-            debug("Unregister delete index: " + i);
-            this.children.splice(i, 1);
-            --i;
-          }
-        }
-        break;
-
-      case "child-process-shutdown":
-        debug("Child process shutdown");
-
-        for (let i = 0; i < this.children.length; ++i) {
-          if (this.children[i].mm == aMessage.target) {
-            debug("Unregister index: " + i);
-            this.children.splice(i, 1);
-            --i;
-          }
-        }
-        break;
-
-      default:
-        debug("Wrong message: " + aMessage.name);
-    }
-  }
-}
-
-DataStoreChangeNotifier.init();
deleted file mode 100644
--- a/dom/datastore/DataStoreCursor.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/dom/DataStore.h"
-#include "mozilla/dom/DataStoreCursor.h"
-#include "mozilla/dom/DataStoreBinding.h"
-#include "mozilla/dom/DataStoreImplBinding.h"
-#include "mozilla/dom/Promise.h"
-#include "mozilla/ErrorResult.h"
-#include "nsPIDOMWindow.h"
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(DataStoreCursor)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(DataStoreCursor)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DataStoreCursor)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTION(DataStoreCursor, mCursor)
-
-already_AddRefed<DataStoreCursor>
-DataStoreCursor::Constructor(GlobalObject& aGlobal, ErrorResult& aRv)
-{
-  RefPtr<DataStoreCursor> cursor = new DataStoreCursor();
-  return cursor.forget();
-}
-
-bool
-DataStoreCursor::WrapObject(JSContext* aCx,
-                            JS::Handle<JSObject*> aGivenProto,
-                            JS::MutableHandle<JSObject*> aReflector)
-{
-  return DataStoreCursorBinding::Wrap(aCx, this, aGivenProto, aReflector);
-}
-
-already_AddRefed<DataStore>
-DataStoreCursor::GetStore(ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mCursor);
-
-  return mCursor->GetStore(aRv);
-}
-
-already_AddRefed<Promise>
-DataStoreCursor::Next(ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mCursor);
-
-  return mCursor->Next(aRv);
-}
-
-void
-DataStoreCursor::Close(ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mCursor);
-
-  mCursor->Close(aRv);
-}
-
-void
-DataStoreCursor::SetDataStoreCursorImpl(DataStoreCursorImpl& aCursor)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(!mCursor);
-
-  mCursor = &aCursor;
-}
-
-} //namespace dom
-} //namespace mozilla
deleted file mode 100644
--- a/dom/datastore/DataStoreCursor.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_DataStoreCursor_h
-#define mozilla_dom_DataStoreCursor_h
-
-#include "nsAutoPtr.h"
-#include "nsCOMPtr.h"
-#include "nsCycleCollectionParticipant.h"
-
-namespace mozilla {
-
-class ErrorResult;
-
-namespace dom {
-
-class Promise;
-class DataStore;
-class GlobalObject;
-class DataStoreCursorImpl;
-
-class DataStoreCursor final : public nsISupports
-{
-public:
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS(DataStoreCursor)
-
-  // WebIDL (internal functions)
-
-  static already_AddRefed<DataStoreCursor> Constructor(GlobalObject& aGlobal,
-                                                       ErrorResult& aRv);
-
-  bool WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
-
-  // WebIDL (public APIs)
-
-  already_AddRefed<DataStore> GetStore(ErrorResult& aRv);
-
-  already_AddRefed<Promise> Next(ErrorResult& aRv);
-
-  void Close(ErrorResult& aRv);
-
-  // This internal function (ChromeOnly) is aimed to make the DataStoreCursor
-  // keep a reference to the DataStoreCursorImpl which really implements the
-  // API's logic in JS.
-  void SetDataStoreCursorImpl(DataStoreCursorImpl& aCursor);
-
-private:
-  ~DataStoreCursor() {}
-  RefPtr<DataStoreCursorImpl> mCursor;
-};
-
-} //namespace dom
-} //namespace mozilla
-
-#endif
deleted file mode 100644
--- a/dom/datastore/DataStoreCursorImpl.jsm
+++ /dev/null
@@ -1,444 +0,0 @@
-/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict'
-
-this.EXPORTED_SYMBOLS = ['DataStoreCursor'];
-
-function debug(s) {
-  //dump('DEBUG DataStoreCursor: ' + s + '\n');
-}
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-const STATE_INIT = 0;
-const STATE_REVISION_INIT = 1;
-const STATE_REVISION_CHECK = 2;
-const STATE_SEND_ALL = 3;
-const STATE_REVISION_SEND = 4;
-const STATE_DONE = 5;
-
-const REVISION_ADDED = 'added';
-const REVISION_UPDATED = 'updated';
-const REVISION_REMOVED = 'removed';
-const REVISION_VOID = 'void';
-const REVISION_SKIP = 'skip'
-
-Cu.import('resource://gre/modules/Services.jsm');
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-
-/**
- * legend:
- * - RID = revision ID
- * - R = revision object (with the internalRevisionId that is a number)
- * - X = current object ID.
- * - L = the list of revisions that we have to send
- *
- * State: init: do you have RID ?
- *   YES: state->initRevision; loop
- *   NO: get R; X=0; state->sendAll; send a 'clear'
- *
- * State: initRevision. Get R from RID. Done?
- *   YES: state->revisionCheck; loop
- *   NO: RID = null; state->init; loop
- *
- * State: revisionCheck: get all the revisions between R and NOW. Done?
- *   YES and R == NOW: state->done; loop
- *   YES and R != NOW: Store this revisions in L; state->revisionSend; loop
- *   NO: R = NOW; X=0; state->sendAll; send a 'clear'
- *
- * State: sendAll: is R still the last revision?
- *   YES get the first object with id > X. Done?
- *     YES: X = object.id; send 'add'
- *     NO: state->revisionCheck; loop
- *   NO: R = NOW; X=0; send a 'clear'
- *
- * State: revisionSend: do you have something from L to send?
- *   YES and L[0] == 'removed': R=L[0]; send 'remove' with ID
- *   YES and L[0] == 'added': R=L[0]; get the object; found?
- *     NO: loop
- *     YES: send 'add' with ID and object
- *   YES and L[0] == 'updated': R=L[0]; get the object; found?
- *     NO: loop
- *     YES and object.R > R: continue
- *     YES and object.R <= R: send 'update' with ID and object
- *   YES L[0] == 'void': R=L[0]; state->init; loop
- *   NO: state->revisionCheck; loop
- *
- * State: done: send a 'done' with R
- */
-
-/* Helper functions */
-function createDOMError(aWindow, aEvent) {
-  return new aWindow.DOMError(aEvent);
-}
-
-/* DataStoreCursor object */
-this.DataStoreCursor = function(aWindow, aDataStore, aRevisionId) {
-  debug("DataStoreCursor created");
-  this.init(aWindow, aDataStore, aRevisionId);
-}
-
-this.DataStoreCursor.prototype = {
-  classDescription: 'DataStoreCursor XPCOM Component',
-  classID: Components.ID('{b6d14349-1eab-46b8-8513-584a7328a26b}'),
-  contractID: '@mozilla.org/dom/datastore-cursor-impl;1',
-  QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupports]),
-
-  _shuttingdown: false,
-
-  _window: null,
-  _dataStore: null,
-  _revisionId: null,
-  _revision: null,
-  _revisionsList: null,
-  _objectId: 0,
-
-  _state: STATE_INIT,
-
-  init: function(aWindow, aDataStore, aRevisionId) {
-    debug('DataStoreCursor init');
-
-    this._window = aWindow;
-    this._dataStore = aDataStore;
-    this._revisionId = aRevisionId;
-
-    Services.obs.addObserver(this, "inner-window-destroyed", false);
-
-    let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
-                      .getInterface(Ci.nsIDOMWindowUtils);
-    this._innerWindowID = util.currentInnerWindowID;
-  },
-
-  observe: function(aSubject, aTopic, aData) {
-    let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
-    if (wId == this._innerWindowID) {
-      Services.obs.removeObserver(this, "inner-window-destroyed");
-      this._shuttingdown = true;
-    }
-  },
-
-  // This is the implementation of the state machine.
-  // Read the comments at the top of this file in order to follow what it does.
-  stateMachine: function(aStore, aRevisionStore, aResolve, aReject) {
-    debug('StateMachine: ' + this._state);
-
-    // If the window has been destroyed we cannot create the Promise object.
-    if (this._shuttingdown) {
-      return;
-    }
-
-    switch (this._state) {
-      case STATE_INIT:
-        this.stateMachineInit(aStore, aRevisionStore, aResolve, aReject);
-        break;
-
-      case STATE_REVISION_INIT:
-        this.stateMachineRevisionInit(aStore, aRevisionStore, aResolve, aReject);
-        break;
-
-      case STATE_REVISION_CHECK:
-        this.stateMachineRevisionCheck(aStore, aRevisionStore, aResolve, aReject);
-        break;
-
-      case STATE_SEND_ALL:
-        this.stateMachineSendAll(aStore, aRevisionStore, aResolve, aReject);
-        break;
-
-      case STATE_REVISION_SEND:
-        this.stateMachineRevisionSend(aStore, aRevisionStore, aResolve, aReject);
-        break;
-
-      case STATE_DONE:
-        this.stateMachineDone(aStore, aRevisionStore, aResolve, aReject);
-        break;
-    }
-  },
-
-  stateMachineInit: function(aStore, aRevisionStore, aResolve, aReject) {
-    debug('StateMachineInit');
-
-    if (this._revisionId) {
-      this._state = STATE_REVISION_INIT;
-      this.stateMachine(aStore, aRevisionStore, aResolve, aReject);
-      return;
-    }
-
-    let self = this;
-    let request = aRevisionStore.openCursor(null, 'prev');
-    request.onsuccess = function(aEvent) {
-      if (aEvent.target.result === undefined) {
-        aReject(self._window.DOMError("InvalidRevision",
-                                      "The DataStore is corrupted"));
-        return;
-      }
-
-      self._revision = aEvent.target.result.value;
-      self._objectId = 0;
-      self._state = STATE_SEND_ALL;
-      aResolve(self.createTask('clear', null, '', null));
-    }
-  },
-
-  stateMachineRevisionInit: function(aStore, aRevisionStore, aResolve, aReject) {
-    debug('StateMachineRevisionInit');
-
-    let self = this;
-    let request = this._dataStore._db.getInternalRevisionId(
-      self._revisionId,
-      aRevisionStore,
-      function(aInternalRevisionId) {
-        // This revision doesn't exist.
-        if (aInternalRevisionId == undefined) {
-          self._revisionId = null;
-          self._objectId = 0;
-          self._state = STATE_INIT;
-          self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
-          return;
-        }
-
-        self._revision = { revisionId: self._revisionId,
-                           internalRevisionId: aInternalRevisionId };
-        self._state = STATE_REVISION_CHECK;
-        self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
-      }
-    );
-  },
-
-  stateMachineRevisionCheck: function(aStore, aRevisionStore, aResolve, aReject) {
-    debug('StateMachineRevisionCheck');
-
-    let changes = {
-      addedIds: {},
-      updatedIds: {},
-      removedIds: {}
-    };
-
-    let self = this;
-    let request = aRevisionStore.mozGetAll(
-      self._window.IDBKeyRange.lowerBound(this._revision.internalRevisionId, true));
-    request.onsuccess = function(aEvent) {
-
-      // Optimize the operations.
-      for (let i = 0; i < aEvent.target.result.length; ++i) {
-        let data = aEvent.target.result[i];
-
-        switch (data.operation) {
-          case REVISION_ADDED:
-            changes.addedIds[data.objectId] = data.internalRevisionId;
-            break;
-
-          case REVISION_UPDATED:
-            // We don't consider an update if this object has been added
-            // or if it has been already modified by a previous
-            // operation.
-            if (!(data.objectId in changes.addedIds) &&
-                !(data.objectId in changes.updatedIds)) {
-              changes.updatedIds[data.objectId] = data.internalRevisionId;
-            }
-            break;
-
-          case REVISION_REMOVED:
-            let id = data.objectId;
-
-            // If the object has been added in this range of revisions
-            // we can ignore it and remove it from the list.
-            if (id in changes.addedIds) {
-              delete changes.addedIds[id];
-            } else {
-              changes.removedIds[id] = data.internalRevisionId;
-            }
-
-            if (id in changes.updatedIds) {
-              delete changes.updatedIds[id];
-            }
-            break;
-
-          case REVISION_VOID:
-            if (i != 0) {
-              dump('Internal error: Revision "' + REVISION_VOID + '" should not be found!!!\n');
-              return;
-            }
-
-            self._revisionId = null;
-            self._objectId = 0;
-            self._state = STATE_INIT;
-            self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
-            return;
-        }
-      }
-
-      // From changes to a map of internalRevisionId.
-      let revisions = {};
-      function addRevisions(obj) {
-        for (let key in obj) {
-          revisions[obj[key]] = true;
-        }
-      }
-
-      addRevisions(changes.addedIds);
-      addRevisions(changes.updatedIds);
-      addRevisions(changes.removedIds);
-
-      // Create the list of revisions.
-      let list = [];
-      for (let i = 0; i < aEvent.target.result.length; ++i) {
-        let data = aEvent.target.result[i];
-
-        // If this revision doesn't contain useful data, we still need to keep
-        // it in the list because we need to update the internal revision ID.
-        if (!(data.internalRevisionId in revisions)) {
-          data.operation = REVISION_SKIP;
-        }
-
-        list.push(data);
-      }
-
-      if (list.length == 0) {
-        self._state = STATE_DONE;
-        self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
-        return;
-      }
-
-      // Some revision has to be sent.
-      self._revisionsList = list;
-      self._state = STATE_REVISION_SEND;
-      self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
-    };
-  },
-
-  stateMachineSendAll: function(aStore, aRevisionStore, aResolve, aReject) {
-    debug('StateMachineSendAll');
-
-    let self = this;
-    let request = aRevisionStore.openCursor(null, 'prev');
-    request.onsuccess = function(aEvent) {
-      if (self._revision.revisionId != aEvent.target.result.value.revisionId) {
-        self._revision = aEvent.target.result.value;
-        self._objectId = 0;
-        aResolve(self.createTask('clear', null, '', null));
-        return;
-      }
-
-      let request = aStore.openCursor(self._window.IDBKeyRange.lowerBound(self._objectId, true));
-      request.onsuccess = function(aEvent) {
-        let cursor = aEvent.target.result;
-        if (!cursor) {
-          self._state = STATE_REVISION_CHECK;
-          self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
-          return;
-        }
-
-        self._objectId = cursor.key;
-        aResolve(self.createTask('add', self._objectId, '', cursor.value));
-      };
-    };
-  },
-
-  stateMachineRevisionSend: function(aStore, aRevisionStore, aResolve, aReject) {
-    debug('StateMachineRevisionSend');
-
-    if (!this._revisionsList.length) {
-      this._state = STATE_REVISION_CHECK;
-      this.stateMachine(aStore, aRevisionStore, aResolve, aReject);
-      return;
-    }
-
-    this._revision = this._revisionsList.shift();
-
-    switch (this._revision.operation) {
-      case REVISION_REMOVED:
-        aResolve(this.createTask('remove', this._revision.objectId, '', null));
-        break;
-
-      case REVISION_ADDED: {
-        let request = aStore.get(this._revision.objectId);
-        let self = this;
-        request.onsuccess = function(aEvent) {
-          if (aEvent.target.result == undefined) {
-            self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
-            return;
-          }
-
-          aResolve(self.createTask('add', self._revision.objectId, '',
-                                   aEvent.target.result));
-        }
-        break;
-      }
-
-      case REVISION_UPDATED: {
-        let request = aStore.get(this._revision.objectId);
-        let self = this;
-        request.onsuccess = function(aEvent) {
-          if (aEvent.target.result == undefined) {
-            self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
-            return;
-          }
-
-          if (aEvent.target.result.revisionId >  self._revision.internalRevisionId) {
-            self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
-            return;
-          }
-
-          aResolve(self.createTask('update', self._revision.objectId, '',
-                                   aEvent.target.result));
-        }
-        break;
-      }
-
-      case REVISION_VOID:
-        // Internal error!
-        dump('Internal error: Revision "' + REVISION_VOID + '" should not be found!!!\n');
-        break;
-
-      case REVISION_SKIP:
-        // This revision contains data that has already been sent by another one.
-        this.stateMachine(aStore, aRevisionStore, aResolve, aReject);
-        break;
-    }
-  },
-
-  stateMachineDone: function(aStore, aRevisionStore, aResolve, aReject) {
-    this.close();
-    aResolve(this.createTask('done', null, this._revision.revisionId, null));
-  },
-
-  // public interface
-
-  get store() {
-    return this._dataStore.exposedObject;
-  },
-
-  next: function() {
-    debug('Next');
-
-    // If the window has been destroyed we cannot create the Promise object.
-    if (this._shuttingdown) {
-      throw Cr.NS_ERROR_FAILURE;
-    }
-
-    let self = this;
-    return new this._window.Promise(function(aResolve, aReject) {
-      self._dataStore._db.cursorTxn(
-        function(aTxn, aStore, aRevisionStore) {
-          self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
-        },
-        function(aEvent) {
-          aReject(createDOMError(self._window, aEvent));
-        }
-      );
-    });
-  },
-
-  close: function() {
-    this._dataStore.syncTerminated(this);
-  },
-
-  createTask: function(aOperation, aId, aRevisionId, aData) {
-    return Cu.cloneInto({ operation: aOperation, id: aId,
-                          revisionId: aRevisionId, data: aData }, this._window);
-  }
-};
deleted file mode 100644
--- a/dom/datastore/DataStoreDB.cpp
+++ /dev/null
@@ -1,439 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DataStoreDB.h"
-
-#include "DataStoreCallbacks.h"
-#include "jsapi.h"
-#include "mozilla/dom/IDBDatabaseBinding.h"
-#include "mozilla/dom/IDBDatabase.h"
-#include "mozilla/dom/IDBEvents.h"
-#include "mozilla/dom/IDBFactory.h"
-#include "mozilla/dom/IDBFactoryBinding.h"
-#include "mozilla/dom/IDBIndex.h"
-#include "mozilla/dom/IDBObjectStore.h"
-#include "mozilla/dom/IDBObjectStoreBinding.h"
-#include "mozilla/dom/IDBRequest.h"
-#include "mozilla/dom/IDBTransaction.h"
-#include "nsComponentManagerUtils.h"
-#include "nsContentUtils.h"
-#include "nsIDOMEvent.h"
-#include "nsIPrincipal.h"
-#include "nsIXPConnect.h"
-#include "nsNullPrincipal.h"
-
-#define DATASTOREDB_VERSION        1
-#define DATASTOREDB_NAME           "DataStoreDB"
-#define DATASTOREDB_REVISION_INDEX "revisionIndex"
-
-using namespace mozilla::dom::indexedDB;
-
-namespace mozilla {
-namespace dom {
-
-class VersionChangeListener final : public nsIDOMEventListener
-{
-public:
-  NS_DECL_ISUPPORTS
-
-  explicit VersionChangeListener(IDBDatabase* aDatabase)
-    : mDatabase(aDatabase)
-  {}
-
-  // nsIDOMEventListener
-  NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override
-  {
-    nsString type;
-    nsresult rv = aEvent->GetType(type);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    if (!type.EqualsASCII("versionchange")) {
-      MOZ_ASSERT_UNREACHABLE("Expected a versionchange event");
-      return NS_ERROR_FAILURE;
-    }
-
-    rv = mDatabase->RemoveEventListener(NS_LITERAL_STRING("versionchange"),
-                                        this, false);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-#ifdef DEBUG
-    nsCOMPtr<IDBVersionChangeEvent> event = do_QueryInterface(aEvent);
-    MOZ_ASSERT(event);
-
-    Nullable<uint64_t> version = event->GetNewVersion();
-    MOZ_ASSERT(version.IsNull());
-#endif
-
-    mDatabase->Close();
-
-    return NS_OK;
-  }
-
-private:
-  IDBDatabase* mDatabase;
-
-  ~VersionChangeListener() {}
-};
-
-NS_IMPL_ISUPPORTS(VersionChangeListener, nsIDOMEventListener)
-
-NS_IMPL_ISUPPORTS(DataStoreDB, nsIDOMEventListener)
-
-DataStoreDB::DataStoreDB(const nsAString& aManifestURL, const nsAString& aName)
-  : mState(Inactive)
-  , mCreatedSchema(false)
-{
-  mDatabaseName.Assign(aName);
-  mDatabaseName.Append('|');
-  mDatabaseName.Append(aManifestURL);
-}
-
-DataStoreDB::~DataStoreDB()
-{
-}
-
-nsresult
-DataStoreDB::CreateFactoryIfNeeded()
-{
-  if (!mFactory) {
-    nsresult rv;
-    nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::Create();
-
-    nsIXPConnect* xpc = nsContentUtils::XPConnect();
-    MOZ_ASSERT(xpc);
-
-    AutoJSAPI jsapi;
-    jsapi.Init();
-    JSContext* cx = jsapi.cx();
-    JS::Rooted<JSObject*> global(cx);
-    rv = xpc->CreateSandbox(cx, principal, global.address());
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    // The CreateSandbox call returns a proxy to the actual sandbox object. We
-    // don't need a proxy here.
-    global = js::UncheckedUnwrap(global);
-
-    JSAutoCompartment ac(cx, global);
-
-    rv = IDBFactory::CreateForDatastore(cx, global, getter_AddRefs(mFactory));
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-  }
-
-  return NS_OK;
-}
-
-nsresult
-DataStoreDB::Open(IDBTransactionMode aMode, const Sequence<nsString>& aDbs,
-                  DataStoreDBCallback* aCallback)
-{
-  MOZ_ASSERT(mState == Inactive);
-
-  nsresult rv = CreateFactoryIfNeeded();
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  // We only need a JSContext here to get a stack from, so just init our
-  // AutoJSAPI without a global.
-  AutoJSAPI jsapi;
-  jsapi.Init();
-  ErrorResult error;
-  mRequest = mFactory->Open(jsapi.cx(), mDatabaseName, DATASTOREDB_VERSION,
-                            error);
-  if (NS_WARN_IF(error.Failed())) {
-    return error.StealNSResult();
-  }
-
-  rv = AddEventListeners();
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  mState = Active;
-  mTransactionMode = aMode;
-  mObjectStores = aDbs;
-  mCallback = aCallback;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-DataStoreDB::HandleEvent(nsIDOMEvent* aEvent)
-{
-  nsString type;
-  nsresult rv = aEvent->GetType(type);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (type.EqualsASCII("success")) {
-    RemoveEventListeners();
-    mState = Inactive;
-
-    rv = DatabaseOpened();
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      mCallback->Run(this, DataStoreDBCallback::Error);
-    } else {
-      mCallback->Run(this, mCreatedSchema
-                      ? DataStoreDBCallback::CreatedSchema :
-                        DataStoreDBCallback::Success);
-    }
-
-    mRequest = nullptr;
-    return NS_OK;
-  }
-
-  if (type.EqualsASCII("upgradeneeded")) {
-    return UpgradeSchema(aEvent);
-  }
-
-  if (type.EqualsASCII("error") || type.EqualsASCII("blocked")) {
-    RemoveEventListeners();
-    mState = Inactive;
-    mCallback->Run(this, DataStoreDBCallback::Error);
-    mRequest = nullptr;
-    return NS_OK;
-  }
-
-  MOZ_CRASH("This should not happen");
-}
-
-nsresult
-DataStoreDB::UpgradeSchema(nsIDOMEvent* aEvent)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  // This DB has been just created and we have to inform the callback about
-  // this.
-  mCreatedSchema = true;
-
-#ifdef DEBUG
-  nsCOMPtr<IDBVersionChangeEvent> event = do_QueryInterface(aEvent);
-  MOZ_ASSERT(event);
-
-  Nullable<uint64_t> version = event->GetNewVersion();
-  MOZ_ASSERT(!version.IsNull());
-  MOZ_ASSERT(version.Value() == DATASTOREDB_VERSION);
-#endif
-
-  ErrorResult error;
-  JS::Rooted<JS::Value> result(nsContentUtils::RootingCx());
-  mRequest->GetResult(&result, error);
-  if (NS_WARN_IF(error.Failed())) {
-    return error.StealNSResult();
-  }
-
-  MOZ_ASSERT(result.isObject());
-
-  IDBDatabase* database = nullptr;
-  nsresult rv = UNWRAP_OBJECT(IDBDatabase, &result.toObject(), database);
-  if (NS_FAILED(rv)) {
-    NS_WARNING("Didn't get the object we expected!");
-    return rv;
-  }
-
-  {
-    IDBObjectStoreParameters params;
-    params.Init(NS_LITERAL_STRING("{ \"autoIncrement\": true }"));
-    RefPtr<IDBObjectStore> store =
-      database->CreateObjectStore(NS_LITERAL_STRING(DATASTOREDB_NAME),
-                                  params, error);
-    if (NS_WARN_IF(error.Failed())) {
-      return error.StealNSResult();
-    }
-  }
-
-  RefPtr<IDBObjectStore> store;
-
-  {
-    IDBObjectStoreParameters params;
-    params.Init(NS_LITERAL_STRING("{ \"autoIncrement\": true, \"keyPath\": \"internalRevisionId\" }"));
-
-    store =
-      database->CreateObjectStore(NS_LITERAL_STRING(DATASTOREDB_REVISION),
-                                  params, error);
-    if (NS_WARN_IF(error.Failed())) {
-      return error.StealNSResult();
-    }
-  }
-
-  {
-    IDBIndexParameters params;
-    params.Init(NS_LITERAL_STRING("{ \"unique\": true }"));
-    RefPtr<IDBIndex> index =
-      store->CreateIndex(NS_LITERAL_STRING(DATASTOREDB_REVISION_INDEX),
-                         NS_LITERAL_STRING("revisionId"), params, error);
-    if (NS_WARN_IF(error.Failed())) {
-      return error.StealNSResult();
-    }
-  }
-
-  return NS_OK;
-}
-
-nsresult
-DataStoreDB::DatabaseOpened()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  ErrorResult error;
-  JS::Rooted<JS::Value> result(nsContentUtils::RootingCx());
-  mRequest->GetResult(&result, error);
-  if (NS_WARN_IF(error.Failed())) {
-    return error.StealNSResult();
-  }
-
-  MOZ_ASSERT(result.isObject());
-
-  nsresult rv = UNWRAP_OBJECT(IDBDatabase, &result.toObject(), mDatabase);
-  if (NS_FAILED(rv)) {
-    NS_WARNING("Didn't get the object we expected!");
-    return rv;
-  }
-
-  RefPtr<VersionChangeListener> listener =
-    new VersionChangeListener(mDatabase);
-  rv = mDatabase->EventTarget::AddEventListener(
-    NS_LITERAL_STRING("versionchange"), listener, false);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  StringOrStringSequence objectStores;
-  if (!objectStores.RawSetAsStringSequence().AppendElements(mObjectStores,
-                                                            fallible)) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  // We init with the global of our result, just for consistency.
-  AutoJSAPI jsapi;
-  if (!jsapi.Init(&result.toObject())) {
-    return NS_ERROR_UNEXPECTED;
-  }
-  RefPtr<IDBTransaction> txn;
-  error = mDatabase->Transaction(jsapi.cx(),
-                                 objectStores,
-                                 mTransactionMode,
-                                 getter_AddRefs(txn));
-  if (NS_WARN_IF(error.Failed())) {
-    return error.StealNSResult();
-  }
-
-  mTransaction = txn.forget();
-  return NS_OK;
-}
-
-nsresult
-DataStoreDB::Delete()
-{
-  MOZ_ASSERT(mState == Inactive);
-
-  nsresult rv = CreateFactoryIfNeeded();
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  mTransaction = nullptr;
-
-  if (mDatabase) {
-    mDatabase->Close();
-    mDatabase = nullptr;
-  }
-
-  // We only need a JSContext here to get a stack from, so just init our
-  // AutoJSAPI without a global.
-  AutoJSAPI jsapi;
-  jsapi.Init();
-  ErrorResult error;
-  RefPtr<IDBOpenDBRequest> request =
-    mFactory->DeleteDatabase(jsapi.cx(), mDatabaseName, IDBOpenDBOptions(),
-                             error);
-  if (NS_WARN_IF(error.Failed())) {
-    return error.StealNSResult();
-  }
-
-  return NS_OK;
-}
-
-IDBTransaction*
-DataStoreDB::Transaction() const
-{
-  MOZ_ASSERT(mTransaction);
-  MOZ_ASSERT(mTransaction->IsOpen());
-  return mTransaction;
-}
-
-nsresult
-DataStoreDB::AddEventListeners()
-{
-  nsresult rv;
-  rv = mRequest->EventTarget::AddEventListener(NS_LITERAL_STRING("success"),
-                                               this, false);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  rv = mRequest->EventTarget::AddEventListener(NS_LITERAL_STRING("upgradeneeded"),
-                                               this, false);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  rv = mRequest->EventTarget::AddEventListener(NS_LITERAL_STRING("error"),
-                                               this, false);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  rv = mRequest->EventTarget::AddEventListener(NS_LITERAL_STRING("blocked"),
-                                               this, false);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  return NS_OK;
-}
-
-nsresult
-DataStoreDB::RemoveEventListeners()
-{
-  nsresult rv;
-  rv = mRequest->RemoveEventListener(NS_LITERAL_STRING("success"),
-                                     this, false);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  rv = mRequest->RemoveEventListener(NS_LITERAL_STRING("upgradeneeded"),
-                                     this, false);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  rv = mRequest->RemoveEventListener(NS_LITERAL_STRING("error"),
-                                     this, false);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  rv = mRequest->RemoveEventListener(NS_LITERAL_STRING("blocked"),
-                                     this, false);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  return NS_OK;
-}
-
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/datastore/DataStoreDB.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_DataStoreDB_h
-#define mozilla_dom_DataStoreDB_h
-
-#include "mozilla/dom/IDBTransactionBinding.h"
-#include "nsAutoPtr.h"
-#include "nsIDOMEventListener.h"
-#include "nsISupportsImpl.h"
-#include "nsString.h"
-
-#define DATASTOREDB_REVISION       "revision"
-
-namespace mozilla {
-namespace dom {
-
-class DataStoreDBCallback;
-class IDBDatabase;
-class IDBFactory;
-class IDBOpenDBRequest;
-class IDBTransaction;
-
-class DataStoreDB final : public nsIDOMEventListener
-{
-public:
-  NS_DECL_ISUPPORTS
-
-  DataStoreDB(const nsAString& aManifestURL, const nsAString& aName);
-
-  nsresult Open(IDBTransactionMode aMode, const Sequence<nsString>& aDb,
-                DataStoreDBCallback* aCallback);
-
-  nsresult Delete();
-
-  IDBTransaction* Transaction() const;
-
-  // nsIDOMEventListener
-  NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override;
-
-private:
-  ~DataStoreDB();
-
-  nsresult CreateFactoryIfNeeded();
-
-  nsresult UpgradeSchema(nsIDOMEvent* aEvent);
-
-  nsresult DatabaseOpened();
-
-  nsresult AddEventListeners();
-
-  nsresult RemoveEventListeners();
-
-  nsString mDatabaseName;
-
-  RefPtr<IDBFactory> mFactory;
-  RefPtr<IDBOpenDBRequest> mRequest;
-  RefPtr<IDBDatabase> mDatabase;
-  RefPtr<IDBTransaction> mTransaction;
-
-  RefPtr<DataStoreDBCallback> mCallback;
-
-  // Internal state to avoid strange use of this class.
-  enum StateType {
-    Inactive,
-    Active
-  } mState;
-
-  IDBTransactionMode mTransactionMode;
-  Sequence<nsString> mObjectStores;
-  bool mCreatedSchema;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_DataStoreDB_h
deleted file mode 100644
--- a/dom/datastore/DataStoreDB.jsm
+++ /dev/null
@@ -1,118 +0,0 @@
-/* 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/. */
-
-'use strict';
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-this.EXPORTED_SYMBOLS = ['DataStoreDB'];
-
-function debug(s) {
-  //dump('DEBUG DataStoreDB: ' + s + '\n');
-}
-
-const DATASTOREDB_VERSION = 1;
-const DATASTOREDB_OBJECTSTORE_NAME = 'DataStoreDB';
-const DATASTOREDB_REVISION = 'revision';
-const DATASTOREDB_REVISION_INDEX = 'revisionIndex';
-
-Cu.import('resource://gre/modules/IndexedDBHelper.jsm');
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.importGlobalProperties(["indexedDB"]);
-
-XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
-                                   "@mozilla.org/uuid-generator;1",
-                                   "nsIUUIDGenerator");
-
-this.DataStoreDB = function DataStoreDB() {}
-
-DataStoreDB.prototype = {
-
-  __proto__: IndexedDBHelper.prototype,
-
-  upgradeSchema: function(aTransaction, aDb, aOldVersion, aNewVersion) {
-    debug('updateSchema');
-    aDb.createObjectStore(DATASTOREDB_OBJECTSTORE_NAME, { autoIncrement: true });
-    let store = aDb.createObjectStore(DATASTOREDB_REVISION,
-                                      { autoIncrement: true,
-                                        keyPath: 'internalRevisionId' });
-    store.createIndex(DATASTOREDB_REVISION_INDEX, 'revisionId', { unique: true });
-  },
-
-  init: function(aOwner, aName) {
-    let dbName = aName + '|' + aOwner;
-    this.initDBHelper(dbName, DATASTOREDB_VERSION,
-                      [DATASTOREDB_OBJECTSTORE_NAME, DATASTOREDB_REVISION]);
-  },
-
-  txn: function(aType, aCallback, aErrorCb) {
-    debug('Transaction request');
-    this.newTxn(
-      aType,
-      aType == 'readonly'
-        ? [ DATASTOREDB_OBJECTSTORE_NAME ] : [ DATASTOREDB_OBJECTSTORE_NAME, DATASTOREDB_REVISION ],
-      function(aTxn, aStores) {
-        aType == 'readonly' ? aCallback(aTxn, aStores[0], null) : aCallback(aTxn, aStores[0], aStores[1]);
-      },
-      function() {},
-      aErrorCb
-    );
-  },
-
-  cursorTxn: function(aCallback, aErrorCb) {
-    debug('Cursor transaction request');
-    this.newTxn(
-      'readonly',
-       [ DATASTOREDB_OBJECTSTORE_NAME, DATASTOREDB_REVISION ],
-      function(aTxn, aStores) {
-        aCallback(aTxn, aStores[0], aStores[1]);
-      },
-      function() {},
-      aErrorCb
-    );
-  },
-
-  revisionTxn: function(aType, aCallback, aErrorCb) {
-    debug("Transaction request");
-    this.newTxn(
-      aType,
-      DATASTOREDB_REVISION,
-      aCallback,
-      function() {},
-      aErrorCb
-    );
-  },
-
-  addRevision: function(aStore, aKey, aType, aSuccessCb) {
-    debug("AddRevision: " + aKey + " - " + aType);
-    let revisionId =  uuidgen.generateUUID().toString();
-    let request = aStore.put({ revisionId: revisionId, objectId: aKey, operation: aType });
-    request.onsuccess = function() {
-      aSuccessCb(revisionId);
-    }
-  },
-
-  getInternalRevisionId: function(aRevisionId, aStore, aSuccessCb) {
-    debug('GetInternalRevisionId');
-    let request = aStore.index(DATASTOREDB_REVISION_INDEX).getKey(aRevisionId);
-    request.onsuccess = function(aEvent) {
-      aSuccessCb(aEvent.target.result);
-    }
-  },
-
-  clearRevisions: function(aStore, aSuccessCb) {
-    debug("ClearRevisions");
-    let request = aStore.clear();
-    request.onsuccess = function() {
-      aSuccessCb();
-    }
-  },
-
-  delete: function() {
-    debug('delete');
-    this.close();
-    indexedDB.deleteDatabase(this.dbName);
-    debug('database deleted');
-  }
-}
deleted file mode 100644
--- a/dom/datastore/DataStoreImpl.js
+++ /dev/null
@@ -1,549 +0,0 @@
-/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict'
-
-function debug(s) {
-  //dump('DEBUG DataStore: ' + s + '\n');
-}
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-const REVISION_ADDED = "added";
-const REVISION_UPDATED = "updated";
-const REVISION_REMOVED = "removed";
-const REVISION_VOID = "void";
-
-// This value has to be tuned a bit. Currently it's just a guess
-// and yet we don't know if it's too low or too high.
-const MAX_REQUESTS = 25;
-
-Cu.import("resource://gre/modules/DataStoreCursorImpl.jsm");
-Cu.import("resource://gre/modules/DataStoreDB.jsm");
-Cu.import('resource://gre/modules/Services.jsm');
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-Cu.importGlobalProperties(["indexedDB"]);
-
-XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
-                                   "@mozilla.org/childprocessmessagemanager;1",
-                                   "nsIMessageSender");
-
-/* Helper functions */
-function createDOMError(aWindow, aEvent) {
-  return new aWindow.DOMError(aEvent);
-}
-
-function throwInvalidArg(aWindow) {
-  return aWindow.Promise.reject(
-    new aWindow.DOMError("SyntaxError", "Non-numeric or invalid id"));
-}
-
-function throwReadOnly(aWindow) {
-  return aWindow.Promise.reject(
-    new aWindow.DOMError("ReadOnlyError", "DataStore in readonly mode"));
-}
-
-function validateId(aId) {
-  // If string, it cannot be empty.
-  if (typeof(aId) == 'string') {
-    return aId.length;
-  }
-
-  aId = parseInt(aId);
-  return (!isNaN(aId) && aId > 0);
-}
-
-/* DataStore object */
-function DataStore() {
-  debug("DataStore created");
-}
-
-DataStore.prototype = {
-  classDescription: "DataStore XPCOM Component",
-  classID: Components.ID("{db5c9602-030f-4bff-a3de-881a8de370f2}"),
-  contractID: "@mozilla.org/dom/datastore-impl;1",
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataStore, Ci.nsISupports,
-                                         Ci.nsIObserver]),
-
-  callbacks: [],
-
-  _window: null,
-  _name: null,
-  _owner: null,
-  _readOnly: null,
-  _revisionId: null,
-  _exposedObject: null,
-  _cursor: null,
-  _shuttingdown: false,
-  _eventTarget: null,
-
-  init: function(aWindow, aName, aOwner, aReadOnly) {
-    debug("DataStore init");
-
-    this._window = aWindow;
-    this._name = aName;
-    this._owner = aOwner;
-    this._readOnly = aReadOnly;
-
-    this._db = new DataStoreDB();
-    this._db.init(aOwner, aName);
-
-    Services.obs.addObserver(this, "inner-window-destroyed", false);
-
-    let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
-                      .getInterface(Ci.nsIDOMWindowUtils);
-    this._innerWindowID = util.currentInnerWindowID;
-
-    cpmm.addMessageListener("DataStore:Changed:Return:OK", this);
-    cpmm.sendAsyncMessage("DataStore:RegisterForMessages",
-                          { store: this._name, owner: this._owner,
-                            innerWindowID: this._innerWindowID },
-                          null,
-                          this._window.document.nodePrincipal);
-  },
-
-  observe: function(aSubject, aTopic, aData) {
-    let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
-    if (wId == this._innerWindowID) {
-      Services.obs.removeObserver(this, "inner-window-destroyed");
-
-      cpmm.removeMessageListener("DataStore:Changed:Return:OK", this);
-      cpmm.sendAsyncMessage("DataStore:UnregisterForMessages",
-                            { innerWindowID: this._innerWindowID },
-                            null,
-                            this._window.document.nodePrincipal);
-      this._shuttingdown = true;
-      this._db.close();
-    }
-  },
-
-  setEventTarget: function(aEventTarget) {
-    this._eventTarget = aEventTarget;
-  },
-
-  newDBPromise: function(aTxnType, aFunction) {
-    let self = this;
-    return new this._window.Promise(function(aResolve, aReject) {
-      debug("DBPromise started");
-      self._db.txn(
-        aTxnType,
-        function(aTxn, aStore, aRevisionStore) {
-          debug("DBPromise success");
-          aFunction(aResolve, aReject, aTxn, aStore, aRevisionStore);
-        },
-        function(aEvent) {
-          debug("DBPromise error");
-          aReject(createDOMError(self._window, aEvent));
-        }
-      );
-    });
-  },
-
-  checkRevision: function(aReject, aRevisionStore, aRevisionId, aCallback) {
-    if (!aRevisionId) {
-      aCallback();
-      return;
-    }
-
-    let self = this;
-
-    let request = aRevisionStore.openCursor(null, 'prev');
-    request.onsuccess = function(aEvent) {
-      let cursor = aEvent.target.result;
-      if (!cursor) {
-        dump("This cannot really happen.");
-        return;
-      }
-
-      if (cursor.value.revisionId != aRevisionId) {
-        aReject(new self._window.DOMError("ConstraintError",
-                                          "RevisionId is not up-to-date"));
-        return;
-      }
-
-      aCallback();
-    }
-  },
-
-  getInternal: function(aStore, aIds, aCallback) {
-    debug("GetInternal: " + aIds.toSource());
-
-    // Creation of the results array.
-    let results = new this._window.Array(aIds.length);
-
-    // We're going to create this amount of requests.
-    let pendingIds = aIds.length;
-    let indexPos = 0;
-
-    let self = this;
-
-    function getInternalSuccess(aEvent, aPos) {
-      debug("GetInternal success. Record: " + aEvent.target.result);
-      results[aPos] = Cu.cloneInto(aEvent.target.result, self._window);
-      if (!--pendingIds) {
-        aCallback(results);
-        return;
-      }
-
-      if (indexPos < aIds.length) {
-        // Just MAX_REQUESTS requests at the same time.
-        let count = 0;
-        while (indexPos < aIds.length && ++count < MAX_REQUESTS) {
-          getInternalRequest();
-        }
-      }
-    }
-
-    function getInternalRequest() {
-      let currentPos = indexPos++;
-      let request = aStore.get(aIds[currentPos]);
-      request.onsuccess = function(aEvent) {
-        getInternalSuccess(aEvent, currentPos);
-      }
-    }
-
-    getInternalRequest();
-  },
-
-  putInternal: function(aResolve, aStore, aRevisionStore, aObj, aId) {
-    debug("putInternal " + aId);
-
-    let self = this;
-    let request = aStore.put(aObj, aId);
-    request.onsuccess = function(aEvent) {
-      debug("putInternal success");
-
-      self.addRevision(aRevisionStore, aId, REVISION_UPDATED,
-        function() {
-          debug("putInternal - revisionId increased");
-          // No wrap here because the result is always a int.
-          aResolve(aEvent.target.result);
-        }
-      );
-    };
-  },
-
-  addInternal: function(aResolve, aStore, aRevisionStore, aObj, aId) {
-    debug("AddInternal");
-
-    let self = this;
-    let request = aStore.add(aObj, aId);
-    request.onsuccess = function(aEvent) {
-      debug("Request successful. Id: " + aEvent.target.result);
-      self.addRevision(aRevisionStore, aEvent.target.result, REVISION_ADDED,
-        function() {
-          debug("AddInternal - revisionId increased");
-          // No wrap here because the result is always a int.
-          aResolve(aEvent.target.result);
-        }
-      );
-    };
-  },
-
-  removeInternal: function(aResolve, aStore, aRevisionStore, aId) {
-    debug("RemoveInternal");
-
-    let self = this;
-    let request = aStore.get(aId);
-    request.onsuccess = function(aEvent) {
-      debug("RemoveInternal success. Record: " + aEvent.target.result);
-      if (aEvent.target.result === undefined) {
-        aResolve(false);
-        return;
-      }
-
-      let deleteRequest = aStore.delete(aId);
-      deleteRequest.onsuccess = function() {
-        debug("RemoveInternal success");
-        self.addRevision(aRevisionStore, aId, REVISION_REMOVED,
-          function() {
-            aResolve(true);
-          }
-        );
-      };
-    };
-  },
-
-  clearInternal: function(aResolve, aStore, aRevisionStore) {
-    debug("ClearInternal");
-
-    let self = this;
-    let request = aStore.clear();
-    request.onsuccess = function() {
-      debug("ClearInternal success");
-      self._db.clearRevisions(aRevisionStore,
-        function() {
-          debug("Revisions cleared");
-
-          self.addRevision(aRevisionStore, null, REVISION_VOID,
-            function() {
-              debug("ClearInternal - revisionId increased");
-              aResolve();
-            }
-          );
-        }
-      );
-    };
-  },
-
-  getLengthInternal: function(aResolve, aStore) {
-    debug("GetLengthInternal");
-
-    let request = aStore.count();
-    request.onsuccess = function(aEvent) {
-      debug("GetLengthInternal success: " + aEvent.target.result);
-      // No wrap here because the result is always a int.
-      aResolve(aEvent.target.result);
-    };
-  },
-
-  addRevision: function(aRevisionStore, aId, aType, aSuccessCb) {
-    let self = this;
-    this._db.addRevision(aRevisionStore, aId, aType,
-      function(aRevisionId) {
-        self._revisionId = aRevisionId;
-        self.sendNotification(aId, aType, aRevisionId);
-        aSuccessCb();
-      }
-    );
-  },
-
-  retrieveRevisionId: function(aSuccessCb) {
-    let self = this;
-    this._db.revisionTxn(
-      'readonly',
-      function(aTxn, aRevisionStore) {
-        debug("RetrieveRevisionId transaction success");
-
-        let request = aRevisionStore.openCursor(null, 'prev');
-        request.onsuccess = function(aEvent) {
-          let cursor = aEvent.target.result;
-          if (cursor) {
-            self._revisionId = cursor.value.revisionId;
-          }
-
-          aSuccessCb(self._revisionId);
-        };
-      }
-    );
-  },
-
-  sendNotification: function(aId, aOperation, aRevisionId) {
-    debug("SendNotification");
-    if (aOperation == REVISION_VOID) {
-      aOperation = "cleared";
-    }
-
-    cpmm.sendAsyncMessage("DataStore:Changed",
-                          { store: this.name, owner: this._owner,
-                            message: { revisionId: aRevisionId, id: aId,
-                                       operation: aOperation, owner: this._owner } },
-                          null,
-                          this._window.document.nodePrincipal);
-  },
-
-  receiveMessage: function(aMessage) {
-    debug("receiveMessage");
-
-    if (aMessage.name != "DataStore:Changed:Return:OK") {
-      debug("Wrong message: " + aMessage.name);
-      return;
-    }
-
-    // If this message is not for this DataStore, let's ignore it.
-    if (aMessage.data.owner != this._owner ||
-        aMessage.data.store != this._name) {
-      return;
-    }
-
-    let self = this;
-
-    this.retrieveRevisionId(
-      function() {
-        // If the window has been destroyed we don't emit the events.
-        if (self._shuttingdown) {
-          return;
-        }
-
-        // If we have an active cursor we don't emit events.
-        if (self._cursor) {
-          return;
-        }
-
-        let event = new self._window.DataStoreChangeEvent('change',
-                                                          aMessage.data.message);
-        self._eventTarget.dispatchEvent(event);
-      }
-    );
-  },
-
-  get exposedObject() {
-    debug("get exposedObject");
-    return this._exposedObject;
-  },
-
-  set exposedObject(aObject) {
-    debug("set exposedObject");
-    this._exposedObject = aObject;
-  },
-
-  syncTerminated: function(aCursor) {
-    // This checks is to avoid that an invalid cursor stops a sync.
-    if (this._cursor == aCursor) {
-      this._cursor = null;
-    }
-  },
-
-  // Public interface :
-
-  get name() {
-    return this._name;
-  },
-
-  get owner() {
-    return this._owner;
-  },
-
-  get readOnly() {
-    return this._readOnly;
-  },
-
-  get: function() {
-    let ids = Array.prototype.slice.call(arguments);
-    for (let i = 0; i < ids.length; ++i) {
-      if (!validateId(ids[i])) {
-        return throwInvalidArg(this._window);
-      }
-    }
-
-    if (ids.length == 0) {
-      return this._window.Promise.resolve(new this._window.Array());
-    }
-
-    let self = this;
-
-    // Promise<Object>
-    return this.newDBPromise("readonly",
-      function(aResolve, aReject, aTxn, aStore, aRevisionStore) {
-               self.getInternal(aStore, ids,
-                                function(aResults) {
-          aResolve(ids.length > 1 ? aResults : aResults[0]);
-        });
-      }
-    );
-  },
-
-  put: function(aObj, aId, aRevisionId) {
-    if (!validateId(aId)) {
-      return throwInvalidArg(this._window);
-    }
-
-    if (this._readOnly) {
-      return throwReadOnly(this._window);
-    }
-
-    let self = this;
-
-    // Promise<void>
-    return this.newDBPromise("readwrite",
-      function(aResolve, aReject, aTxn, aStore, aRevisionStore) {
-        self.checkRevision(aReject, aRevisionStore, aRevisionId, function() {
-          self.putInternal(aResolve, aStore, aRevisionStore, aObj, aId);
-        });
-      }
-    );
-  },
-
-  add: function(aObj, aId, aRevisionId) {
-    if (aId) {
-      if (!validateId(aId)) {
-        return throwInvalidArg(this._window);
-      }
-    }
-
-    if (this._readOnly) {
-      return throwReadOnly(this._window);
-    }
-
-    let self = this;
-
-    // Promise<int>
-    return this.newDBPromise("readwrite",
-      function(aResolve, aReject, aTxn, aStore, aRevisionStore) {
-        self.checkRevision(aReject, aRevisionStore, aRevisionId, function() {
-          self.addInternal(aResolve, aStore, aRevisionStore, aObj, aId);
-        });
-      }
-    );
-  },
-
-  remove: function(aId, aRevisionId) {
-    if (!validateId(aId)) {
-      return throwInvalidArg(this._window);
-    }
-
-    if (this._readOnly) {
-      return throwReadOnly(this._window);
-    }
-
-    let self = this;
-
-    // Promise<void>
-    return this.newDBPromise("readwrite",
-      function(aResolve, aReject, aTxn, aStore, aRevisionStore) {
-        self.checkRevision(aReject, aRevisionStore, aRevisionId, function() {
-          self.removeInternal(aResolve, aStore, aRevisionStore, aId);
-        });
-      }
-    );
-  },
-
-  clear: function(aRevisionId) {
-    if (this._readOnly) {
-      return throwReadOnly(this._window);
-    }
-
-    let self = this;
-
-    // Promise<void>
-    return this.newDBPromise("readwrite",
-      function(aResolve, aReject, aTxn, aStore, aRevisionStore) {
-        self.checkRevision(aReject, aRevisionStore, aRevisionId, function() {
-          self.clearInternal(aResolve, aStore, aRevisionStore);
-        });
-      }
-    );
-  },
-
-  get revisionId() {
-    return this._revisionId;
-  },
-
-  getLength: function() {
-    let self = this;
-
-    // Promise<int>
-    return this.newDBPromise("readonly",
-      function(aResolve, aReject, aTxn, aStore, aRevisionStore) {
-        self.getLengthInternal(aResolve, aStore);
-      }
-    );
-  },
-
-  sync: function(aRevisionId) {
-    debug("Sync");
-    this._cursor = new DataStoreCursor(this._window, this, aRevisionId);
-
-    let cursorImpl = this._window.DataStoreCursorImpl.
-                                  _create(this._window, this._cursor);
-
-    let exposedCursor = new this._window.DataStoreCursor();
-    exposedCursor.setDataStoreCursorImpl(cursorImpl);
-    return exposedCursor;
-  }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DataStore]);
deleted file mode 100644
--- a/dom/datastore/DataStoreRevision.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DataStoreRevision.h"
-
-#include "DataStoreCallbacks.h"
-#include "DataStoreService.h"
-#include "mozilla/dom/DataStoreBinding.h"
-#include "mozilla/dom/IDBObjectStore.h"
-#include "mozilla/dom/IDBRequest.h"
-#include "mozilla/dom/ToJSValue.h"
-#include "nsIDOMEvent.h"
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_ISUPPORTS(DataStoreRevision, nsIDOMEventListener)
-
-// Note: this code in it must not assume anything about the compartment cx is
-// in.
-nsresult
-DataStoreRevision::AddRevision(JSContext* aCx,
-                               IDBObjectStore* aStore,
-                               uint32_t aObjectId,
-                               RevisionType aRevisionType,
-                               DataStoreRevisionCallback* aCallback)
-{
-  MOZ_ASSERT(aStore);
-  MOZ_ASSERT(aCallback);
-
-  RefPtr<DataStoreService> service = DataStoreService::Get();
-  if (!service) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsString id;
-  nsresult rv = service->GenerateUUID(mRevisionID);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  DataStoreRevisionData data;
-  data.mRevisionId = mRevisionID;
-  data.mObjectId = aObjectId;
-
-  switch (aRevisionType) {
-    case RevisionVoid:
-      data.mOperation = NS_LITERAL_STRING("void");
-      break;
-
-    default:
-      MOZ_CRASH("This should not happen");
-  }
-
-  JS::Rooted<JS::Value> value(aCx);
-  if (!ToJSValue(aCx, data, &value)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  ErrorResult error;
-  mRequest = aStore->Put(aCx, value, JS::UndefinedHandleValue, error);
-  if (NS_WARN_IF(error.Failed())) {
-    return error.StealNSResult();
-  }
-
-  rv = mRequest->EventTarget::AddEventListener(NS_LITERAL_STRING("success"),
-                                               this, false);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  mCallback = aCallback;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-DataStoreRevision::HandleEvent(nsIDOMEvent* aEvent)
-{
-  nsString type;
-  nsresult rv = aEvent->GetType(type);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (!type.EqualsASCII("success")) {
-    MOZ_CRASH("This should not happen");
-  }
-
-  mRequest->RemoveEventListener(NS_LITERAL_STRING("success"), this, false);
-  mRequest = nullptr;
-
-  mCallback->Run(mRevisionID);
-  return NS_OK;
-}
-
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/datastore/DataStoreRevision.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_DataStoreRevision_h
-#define mozilla_dom_DataStoreRevision_h
-
-#include "jsapi.h"
-#include "nsAutoPtr.h"
-#include "nsIDOMEventListener.h"
-#include "nsString.h"
-
-namespace mozilla {
-namespace dom {
-
-class DataStoreRevisionCallback;
-class IDBObjectStore;
-class IDBRequest;
-
-class DataStoreRevision final : public nsIDOMEventListener
-{
-public:
-  NS_DECL_ISUPPORTS
-
-  enum RevisionType {
-    RevisionVoid
-  };
-
-  nsresult AddRevision(JSContext* aCx,
-                       IDBObjectStore* aStore,
-                       uint32_t aObjectId,
-                       RevisionType aRevisionType,
-                       DataStoreRevisionCallback* aCallback);
-
-  // nsIDOMEventListener
-  NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override;
-
-private:
-  ~DataStoreRevision() {}
-  RefPtr<DataStoreRevisionCallback> mCallback;
-  RefPtr<IDBRequest> mRequest;
-  nsString mRevisionID;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_DataStoreRevision_h
deleted file mode 100644
--- a/dom/datastore/DataStoreService.cpp
+++ /dev/null
@@ -1,1522 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DataStoreService.h"
-
-#include "DataStoreCallbacks.h"
-#include "DataStoreDB.h"
-#include "DataStoreRevision.h"
-#include "mozilla/dom/DataStore.h"
-#include "mozilla/dom/DataStoreBinding.h"
-#include "mozilla/dom/DataStoreImplBinding.h"
-#include "nsIDataStore.h"
-
-#include "mozilla/BasePrincipal.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/Services.h"
-#include "mozilla/StaticPtr.h"
-#include "mozilla/dom/ContentChild.h"
-#include "mozilla/dom/ContentParent.h"
-#include "mozilla/dom/DOMError.h"
-#include "mozilla/dom/IDBCursor.h"
-#include "mozilla/dom/IDBObjectStore.h"
-#include "mozilla/dom/IDBRequest.h"
-#include "mozilla/dom/IDBTransaction.h"
-#include "mozilla/dom/PermissionMessageUtils.h"
-#include "mozilla/dom/Promise.h"
-#include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/unused.h"
-
-#include "mozIApplication.h"
-#include "mozIApplicationClearPrivateDataParams.h"
-#include "nsIAppsService.h"
-#include "nsIDOMEvent.h"
-#include "nsIDocument.h"
-#include "nsIDOMGlobalPropertyInitializer.h"
-#include "nsIIOService.h"
-#include "nsIMutableArray.h"
-#include "nsIObserverService.h"
-#include "nsIPermissionManager.h"
-#include "nsIScriptSecurityManager.h"
-#include "nsISupportsPrimitives.h"
-#include "nsIUUIDGenerator.h"
-#include "nsPIDOMWindow.h"
-#include "nsIURI.h"
-
-#include "nsContentUtils.h"
-#include "nsNetCID.h"
-#include "nsServiceManagerUtils.h"
-#include "nsThreadUtils.h"
-#include "nsXULAppAPI.h"
-
-#define ASSERT_PARENT_PROCESS()                                             \
-  MOZ_ASSERT(XRE_IsParentProcess());                                        \
-  if (NS_WARN_IF(!XRE_IsParentProcess())) {                                 \
-    return NS_ERROR_FAILURE;                                                \
-  }
-
-using mozilla::BasePrincipal;
-using mozilla::PrincipalOriginAttributes;
-
-namespace mozilla {
-namespace dom {
-
-// This class contains all the information about a DataStore.
-class DataStoreInfo
-{
-public:
-  DataStoreInfo()
-    : mReadOnly(true)
-    , mEnabled(false)
-  {}
-
-  DataStoreInfo(const nsAString& aName,
-                const nsAString& aOriginURL,
-                const nsAString& aManifestURL,
-                bool aReadOnly,
-                bool aEnabled)
-    : mReadOnly(true)
-    , mEnabled(false)
-  {
-    Init(aName, aOriginURL, aManifestURL, aReadOnly, aEnabled);
-  }
-
-  void Init(const nsAString& aName,
-            const nsAString& aOriginURL,
-            const nsAString& aManifestURL,
-            bool aReadOnly,
-            bool aEnabled)
-  {
-    mName = aName;
-    mOriginURL = aOriginURL;
-    mManifestURL = aManifestURL;
-    mReadOnly = aReadOnly;
-    mEnabled = aEnabled;
-  }
-
-  void Update(const nsAString& aName,
-              const nsAString& aOriginURL,
-              const nsAString& aManifestURL,
-              bool aReadOnly)
-  {
-    mName = aName;
-    mOriginURL = aOriginURL;
-    mManifestURL = aManifestURL;
-    mReadOnly = aReadOnly;
-  }
-
-  void Enable()
-  {
-    mEnabled = true;
-  }
-
-  nsString mName;
-  nsString mOriginURL;
-  nsString mManifestURL;
-  bool mReadOnly;
-
-  // A DataStore is enabled when it has its first revision.
-  bool mEnabled;
-};
-
-namespace {
-
-// Singleton for DataStoreService.
-StaticRefPtr<DataStoreService> gDataStoreService;
-nsString gHomeScreenManifestURL;
-static uint64_t gCounterID = 0;
-
-typedef nsClassHashtable<nsUint32HashKey, DataStoreInfo> HashApp;
-
-void
-RejectPromise(nsPIDOMWindowInner* aWindow, Promise* aPromise, nsresult aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(NS_FAILED(aRv));
-
-  RefPtr<DOMError> error;
-  if (aRv == NS_ERROR_DOM_SECURITY_ERR) {
-    error = new DOMError(aWindow, NS_LITERAL_STRING("SecurityError"),
-                         NS_LITERAL_STRING("Access denied"));
-  } else {
-    error = new DOMError(aWindow, NS_LITERAL_STRING("InternalError"),
-                         NS_LITERAL_STRING("An error occurred"));
-  }
-
-  aPromise->MaybeRejectBrokenly(error);
-}
-
-void
-DeleteDatabase(const nsAString& aName,
-               const nsAString& aManifestURL)
-{
-  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-
-  RefPtr<DataStoreDB> db = new DataStoreDB(aManifestURL, aName);
-  db->Delete();
-}
-
-static void
-DeleteDataStoresHelper(nsClassHashtable<nsStringHashKey, HashApp>& aStores,
-                       uint32_t aAppId)
-{
-  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-
-  for (auto iter1 = aStores.Iter(); !iter1.Done(); iter1.Next()) {
-    nsAutoPtr<HashApp>& apps = iter1.Data();
-    for (auto iter2 = apps->Iter(); !iter2.Done(); iter2.Next()) {
-      if (aAppId == iter2.Key()) {
-        nsAutoPtr<DataStoreInfo>& info = iter2.Data();
-        DeleteDatabase(info->mName, info->mManifestURL);
-        iter2.Remove();
-      }
-    }
-
-    if (apps->Count() == 0) {
-      iter1.Remove();
-    }
-  }
-}
-
-void
-GeneratePermissionName(nsAString& aPermission,
-                       const nsAString& aName,
-                       const nsAString& aManifestURL)
-{
-  aPermission.AssignLiteral("indexedDB-chrome-");
-  aPermission.Append(aName);
-  aPermission.Append('|');
-  aPermission.Append(aManifestURL);
-}
-
-nsresult
-ResetPermission(uint32_t aAppId, const nsAString& aOriginURL,
-                const nsAString& aManifestURL,
-                const nsAString& aPermission,
-                bool aReadOnly)
-{
-  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-
-  nsresult rv;
-  nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  nsCOMPtr<nsIURI> uri;
-  rv = ioService->NewURI(NS_ConvertUTF16toUTF8(aOriginURL), nullptr, nullptr,
-                         getter_AddRefs(uri));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  PrincipalOriginAttributes attrs(aAppId, false);
-  nsCOMPtr<nsIPrincipal> principal =
-    BasePrincipal::CreateCodebasePrincipal(uri, attrs);
-  NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE);
-
-  nsCOMPtr<nsIPermissionManager> pm =
-    do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
-  if (!pm) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsCString basePermission;
-  basePermission.Append(NS_ConvertUTF16toUTF8(aPermission));
-
-  // Write permission
-  {
-    nsCString permission;
-    permission.Append(basePermission);
-    permission.AppendLiteral("-write");
-
-    uint32_t perm = nsIPermissionManager::UNKNOWN_ACTION;
-    rv = pm->TestExactPermissionFromPrincipal(principal, permission.get(),
-                                              &perm);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    if (aReadOnly && perm == nsIPermissionManager::ALLOW_ACTION) {
-      rv = pm->RemoveFromPrincipal(principal, permission.get());
-    }
-    else if (!aReadOnly && perm != nsIPermissionManager::ALLOW_ACTION) {
-      rv = pm->AddFromPrincipal(principal, permission.get(),
-                                nsIPermissionManager::ALLOW_ACTION,
-                                nsIPermissionManager::EXPIRE_NEVER, 0);
-    }
-
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-  }
-
-  // Read permission
-  {
-    nsCString permission;
-    permission.Append(basePermission);
-    permission.AppendLiteral("-read");
-
-    uint32_t perm = nsIPermissionManager::UNKNOWN_ACTION;
-    rv = pm->TestExactPermissionFromPrincipal(principal, permission.get(),
-                                              &perm);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    if (perm != nsIPermissionManager::ALLOW_ACTION) {
-      rv = pm->AddFromPrincipal(principal, permission.get(),
-                                nsIPermissionManager::ALLOW_ACTION,
-                                nsIPermissionManager::EXPIRE_NEVER, 0);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
-    }
-  }
-
-  // Generic permission
-  uint32_t perm = nsIPermissionManager::UNKNOWN_ACTION;
-  rv = pm->TestExactPermissionFromPrincipal(principal, basePermission.get(),
-                                            &perm);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (perm != nsIPermissionManager::ALLOW_ACTION) {
-    rv = pm->AddFromPrincipal(principal, basePermission.get(),
-                              nsIPermissionManager::ALLOW_ACTION,
-                              nsIPermissionManager::EXPIRE_NEVER, 0);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-  }
-
-  return NS_OK;
-}
-
-void
-HomeScreenPrefCallback(const char* aPrefName, void* /* aClosure */)
-{
-  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-  RefPtr<DataStoreService> service = DataStoreService::Get();
-  if (!service) {
-    return;
-  }
-
-  service->HomeScreenPrefChanged();
-}
-
-} /* anonymous namespace */
-
-// A PendingRequest is created when a content code wants a list of DataStores
-// but some of them are not enabled yet.
-class PendingRequest
-{
-public:
-  void Init(nsPIDOMWindowInner* aWindow, Promise* aPromise,
-            const nsTArray<DataStoreInfo>& aStores,
-            const nsTArray<nsString>& aPendingDataStores)
-  {
-    mWindow = aWindow;
-    mPromise = aPromise;
-    mStores = aStores;
-    mPendingDataStores = aPendingDataStores;
-  }
-
-  nsCOMPtr<nsPIDOMWindowInner> mWindow;
-  RefPtr<Promise> mPromise;
-  nsTArray<DataStoreInfo> mStores;
-
-  // This array contains the list of manifestURLs of the DataStores that are
-  // not enabled yet.
-  nsTArray<nsString> mPendingDataStores;
-};
-
-// This callback is used to enable a DataStore when its first revisionID is
-// created.
-class RevisionAddedEnableStoreCallback final :
-  public DataStoreRevisionCallback
-{
-private:
-  ~RevisionAddedEnableStoreCallback() {}
-public:
-  NS_INLINE_DECL_REFCOUNTING(RevisionAddedEnableStoreCallback);
-
-  RevisionAddedEnableStoreCallback(uint32_t aAppId,
-                                   const nsAString& aName,
-                                   const nsAString& aManifestURL)
-    : mAppId(aAppId)
-    , mName(aName)
-    , mManifestURL(aManifestURL)
-  {
-    MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-  }
-
-  void
-  Run(const nsAString& aRevisionId)
-  {
-    MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-
-    RefPtr<DataStoreService> service = DataStoreService::Get();
-    MOZ_ASSERT(service);
-
-    service->EnableDataStore(mAppId, mName, mManifestURL);
-  }
-
-private:
-  uint32_t mAppId;
-  nsString mName;
-  nsString mManifestURL;
-};
-
-// This DataStoreDBCallback is called when DataStoreDB opens the DataStore DB.
-// Then the first revision will be created if it's needed.
-class FirstRevisionIdCallback final : public DataStoreDBCallback
-                                    , public nsIDOMEventListener
-{
-public:
-  NS_DECL_ISUPPORTS
-
-  FirstRevisionIdCallback(uint32_t aAppId, const nsAString& aName,
-                          const nsAString& aManifestURL)
-    : mAppId(aAppId)
-    , mName(aName)
-    , mManifestURL(aManifestURL)
-  {
-    MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-  }
-
-  void
-  Run(DataStoreDB* aDb, RunStatus aStatus) override
-  {
-    MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-    MOZ_ASSERT(aDb);
-
-    if (aStatus == Error) {
-      NS_WARNING("Failed to create the first revision.");
-      return;
-    }
-
-    ErrorResult error;
-
-    if (aStatus == Success) {
-      mTxn = aDb->Transaction();
-
-      RefPtr<IDBObjectStore> store =
-      mTxn->ObjectStore(NS_LITERAL_STRING(DATASTOREDB_REVISION), error);
-      if (NS_WARN_IF(error.Failed())) {
-        return;
-      }
-
-      AutoJSAPI jsapi;
-      jsapi.Init();
-      mRequest = store->OpenCursor(jsapi.cx(), IDBCursorDirection::Prev, error);
-      if (NS_WARN_IF(error.Failed())) {
-        return;
-      }
-
-      nsresult rv;
-      rv = mRequest->EventTarget::AddEventListener(NS_LITERAL_STRING("success"),
-                                                   this, false);
-      if (NS_FAILED(rv)) {
-        NS_WARNING("Failed to add an EventListener.");
-        return;
-      }
-
-      return;
-    }
-
-    // The DB has just been created.
-
-    error = CreateFirstRevision(aDb->Transaction());
-    if (error.Failed()) {
-      NS_WARNING("Failed to add a revision to a DataStore.");
-    }
-  }
-
-  nsresult
-  CreateFirstRevision(IDBTransaction* aTxn)
-  {
-    MOZ_ASSERT(aTxn);
-
-    ErrorResult error;
-    RefPtr<IDBObjectStore> store =
-      aTxn->ObjectStore(NS_LITERAL_STRING(DATASTOREDB_REVISION), error);
-    if (NS_WARN_IF(error.Failed())) {
-      return error.StealNSResult();
-    }
-    MOZ_ASSERT(store);
-
-    RefPtr<RevisionAddedEnableStoreCallback> callback =
-      new RevisionAddedEnableStoreCallback(mAppId, mName, mManifestURL);
-
-    // Note: this cx is only used for rooting and AddRevision, neither of which
-    // actually care which compartment we're in.
-    AutoSafeJSContext cx;
-
-    // If the revision doesn't exist, let's create it.
-    RefPtr<DataStoreRevision> revision = new DataStoreRevision();
-    nsresult rv = revision->AddRevision(cx, store, 0,
-                                        DataStoreRevision::RevisionVoid,
-                                        callback);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    return NS_OK;
-  }
-
-  // nsIDOMEventListener
-  NS_IMETHOD
-  HandleEvent(nsIDOMEvent* aEvent) override
-  {
-    MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-
-    RefPtr<IDBRequest> request;
-    request.swap(mRequest);
-
-    RefPtr<IDBTransaction> txn;
-    txn.swap(mTxn);
-
-    request->RemoveEventListener(NS_LITERAL_STRING("success"), this, false);
-
-    nsString type;
-    nsresult rv = aEvent->GetType(type);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-#ifdef DEBUG
-    MOZ_ASSERT(type.EqualsASCII("success"));
-#endif
-
-    ErrorResult error;
-    JS::Rooted<JS::Value> result(nsContentUtils::RootingCx());
-    request->GetResult(&result, error);
-    if (NS_WARN_IF(error.Failed())) {
-      return error.StealNSResult();
-    }
-
-    // This means that the content is a IDBCursor, so the first revision already
-    // exists.
-    if (result.isObject()) {
-#ifdef DEBUG
-      IDBCursor* cursor = nullptr;
-      error = UNWRAP_OBJECT(IDBCursor, &result.toObject(), cursor);
-      MOZ_ASSERT(!error.Failed());
-#endif
-
-      RefPtr<DataStoreService> service = DataStoreService::Get();
-      MOZ_ASSERT(service);
-
-      return service->EnableDataStore(mAppId, mName, mManifestURL);
-    }
-
-    rv = CreateFirstRevision(txn);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    return NS_OK;
-  }
-
-private:
-  ~FirstRevisionIdCallback() {}
-
-  RefPtr<IDBRequest> mRequest;
-  RefPtr<IDBTransaction> mTxn;
-
-  uint32_t mAppId;
-  nsString mName;
-  nsString mManifestURL;
-};
-
-NS_IMPL_ISUPPORTS(FirstRevisionIdCallback, nsIDOMEventListener)
-
-// This class calls the 'retrieveRevisionId' method of the DataStore object for
-// any DataStore in the 'mResults' array. When all of them are called, the
-// promise is resolved with 'mResults'.
-// The reson why this has to be done is because DataStore are object that can be
-// created in any thread and in any process. The first revision has been
-// created, but they don't know its value yet.
-class RetrieveRevisionsCounter
-{
-private:
-  ~RetrieveRevisionsCounter() {}
-public:
-  NS_INLINE_DECL_REFCOUNTING(RetrieveRevisionsCounter);
-
-  RetrieveRevisionsCounter(uint32_t aId, Promise* aPromise, uint32_t aCount)
-    : mPromise(aPromise)
-    , mId(aId)
-    , mCount(aCount)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  void
-  AppendDataStore(JSContext* aCx, DataStore* aDataStore,
-                  nsIDataStore* aDataStoreIf)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    mResults.AppendElement(aDataStore);
-
-    // DataStore will run this callback when the revisionID is retrieved.
-    JSFunction* func = js::NewFunctionWithReserved(aCx, JSCallback,
-                                                   0 /* nargs */, 0 /* flags */,
-                                                   nullptr);
-    if (!func) {
-      return;
-    }
-
-    JS::Rooted<JSObject*> obj(aCx, JS_GetFunctionObject(func));
-    if (!obj) {
-      return;
-    }
-
-    // We use the ID to know which counter is this. The service keeps all of
-    // these counters alive with their own IDs in an hashtable.
-    js::SetFunctionNativeReserved(obj, 0, JS::Int32Value(mId));
-
-    JS::Rooted<JS::Value> value(aCx, JS::ObjectValue(*obj));
-    nsresult rv = aDataStoreIf->RetrieveRevisionId(value);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return;
-    }
-  }
-
-private:
-  static bool
-  JSCallback(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    JS::CallArgs args = CallArgsFromVp(aArgc, aVp);
-
-    JS::Rooted<JS::Value> value(aCx,
-                                js::GetFunctionNativeReserved(&args.callee(), 0));
-    uint32_t id = value.toInt32();
-
-    RefPtr<DataStoreService> service = DataStoreService::Get();
-    MOZ_ASSERT(service);
-
-    RefPtr<RetrieveRevisionsCounter> counter = service->GetCounter(id);
-    MOZ_ASSERT(counter);
-
-    // When all the callbacks are called, we can resolve the promise and remove
-    // the counter from the service.
-    --counter->mCount;
-    if (!counter->mCount) {
-      service->RemoveCounter(id);
-      counter->mPromise->MaybeResolve(counter->mResults);
-    }
-
-    return true;
-  }
-
-  RefPtr<Promise> mPromise;
-  nsTArray<RefPtr<DataStore>> mResults;
-
-  uint32_t mId;
-  uint32_t mCount;
-};
-
-/* static */ already_AddRefed<DataStoreService>
-DataStoreService::GetOrCreate()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (!gDataStoreService) {
-    RefPtr<DataStoreService> service = new DataStoreService();
-    if (NS_WARN_IF(NS_FAILED(service->Init()))) {
-      return nullptr;
-    }
-
-    gDataStoreService = service;
-  }
-
-  RefPtr<DataStoreService> service = gDataStoreService.get();
-  return service.forget();
-}
-
-/* static */ already_AddRefed<DataStoreService>
-DataStoreService::Get()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  RefPtr<DataStoreService> service = gDataStoreService.get();
-  return service.forget();
-}
-
-/* static */ void
-DataStoreService::Shutdown()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (gDataStoreService) {
-    if (XRE_IsParentProcess()) {
-      nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
-      if (obs) {
-        obs->RemoveObserver(gDataStoreService, "webapps-clear-data");
-      }
-
-      nsresult rv =
-        Preferences::UnregisterCallback(HomeScreenPrefCallback,
-                                        "dom.mozApps.homescreenURL",
-                                        nullptr);
-      NS_WARN_IF(NS_FAILED(rv));
-    }
-
-    gDataStoreService = nullptr;
-  }
-}
-
-NS_INTERFACE_MAP_BEGIN(DataStoreService)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDataStoreService)
-  NS_INTERFACE_MAP_ENTRY(nsIDataStoreService)
-  NS_INTERFACE_MAP_ENTRY(nsIObserver)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_ADDREF(DataStoreService)
-NS_IMPL_RELEASE(DataStoreService)
-
-DataStoreService::DataStoreService()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-}
-
-DataStoreService::~DataStoreService()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-}
-
-nsresult
-DataStoreService::Init()
-{
-  if (!XRE_IsParentProcess()) {
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
-  if (!obs) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsresult rv = obs->AddObserver(this, "webapps-clear-data", false);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  rv = Preferences::RegisterCallback(HomeScreenPrefCallback,
-                                     "dom.mozApps.homescreenURL",
-                                     nullptr);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-DataStoreService::InstallDataStore(uint32_t aAppId,
-                                   const nsAString& aName,
-                                   const nsAString& aOriginURL,
-                                   const nsAString& aManifestURL,
-                                   bool aReadOnly)
-{
-  ASSERT_PARENT_PROCESS()
-  MOZ_ASSERT(NS_IsMainThread());
-
-  HashApp* apps = nullptr;
-  if (!mStores.Get(aName, &apps)) {
-    apps = new HashApp();
-    mStores.Put(aName, apps);
-  }
-
-  DataStoreInfo* info = nullptr;
-  if (!apps->Get(aAppId, &info)) {
-    info = new DataStoreInfo(aName, aOriginURL, aManifestURL, aReadOnly, false);
-    apps->Put(aAppId, info);
-  } else {
-    info->Update(aName, aOriginURL, aManifestURL, aReadOnly);
-  }
-
-  nsresult rv = AddPermissions(aAppId, aName, aOriginURL, aManifestURL,
-                               aReadOnly);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  // Immediately create the first revision.
-  return CreateFirstRevisionId(aAppId, aName, aManifestURL);
-}
-
-NS_IMETHODIMP
-DataStoreService::InstallAccessDataStore(uint32_t aAppId,
-                                         const nsAString& aName,
-                                         const nsAString& aOriginURL,
-                                         const nsAString& aManifestURL,
-                                         bool aReadOnly)
-{
-  ASSERT_PARENT_PROCESS()
-  MOZ_ASSERT(NS_IsMainThread());
-
-  HashApp* apps = nullptr;
-  if (!mAccessStores.Get(aName, &apps)) {
-    apps = new HashApp();
-    mAccessStores.Put(aName, apps);
-  }
-
-  DataStoreInfo* info = nullptr;
-  if (!apps->Get(aAppId, &info)) {
-    info = new DataStoreInfo(aName, aOriginURL, aManifestURL, aReadOnly, false);
-    apps->Put(aAppId, info);
-  } else {
-    info->Update(aName, aOriginURL, aManifestURL, aReadOnly);
-  }
-
-  return AddAccessPermissions(aAppId, aName, aOriginURL, aManifestURL,
-                              aReadOnly);
-}
-
-NS_IMETHODIMP
-DataStoreService::GetDataStores(mozIDOMWindow* aWindow,
-                                const nsAString& aName,
-                                const nsAString& aOwner,
-                                nsISupports** aDataStores)
-{
-  // FIXME This will be a thread-safe method.
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsPIDOMWindowInner> window = nsPIDOMWindowInner::From(aWindow);
-  if (!window) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
-  ErrorResult rv;
-  RefPtr<Promise> promise = Promise::Create(global, rv);
-  if (rv.Failed()) {
-    return rv.StealNSResult();
-  }
-
-  nsCOMPtr<nsIDocument> document = window->GetDoc();
-  MOZ_ASSERT(document);
-
-  nsCOMPtr<nsIPrincipal> principal = document->NodePrincipal();
-  MOZ_ASSERT(principal);
-
-  nsTArray<DataStoreInfo> stores;
-
-  // If this request comes from the main process, we have access to the
-  // window, so we can skip the ipc communication.
-  if (XRE_IsParentProcess()) {
-    uint32_t appId;
-    rv = principal->GetAppId(&appId);
-    if (NS_WARN_IF(rv.Failed())) {
-      RejectPromise(window, promise, rv.StealNSResult());
-      promise.forget(aDataStores);
-      return NS_OK;
-    }
-
-    rv = GetDataStoreInfos(aName, aOwner, appId, principal, stores);
-    if (NS_WARN_IF(rv.Failed())) {
-      RejectPromise(window, promise, rv.StealNSResult());
-      promise.forget(aDataStores);
-      return NS_OK;
-    }
-  } else {
-    // This method can be called in the child so we need to send a request
-    // to the parent and create DataStore object here.
-    ContentChild* contentChild = ContentChild::GetSingleton();
-
-    nsTArray<DataStoreSetting> array;
-    if (!contentChild->SendDataStoreGetStores(nsAutoString(aName),
-                                              nsAutoString(aOwner),
-                                              IPC::Principal(principal),
-                                              &array)) {
-      RejectPromise(window, promise, NS_ERROR_FAILURE);
-      promise.forget(aDataStores);
-      return NS_OK;
-    }
-
-    for (uint32_t i = 0; i < array.Length(); ++i) {
-      DataStoreInfo* info = stores.AppendElement();
-      info->Init(array[i].name(), array[i].originURL(),
-                 array[i].manifestURL(), array[i].readOnly(),
-                 array[i].enabled());
-    }
-  }
-
-  GetDataStoresCreate(window, promise, stores);
-  promise.forget(aDataStores);
-  return NS_OK;
-}
-
-void
-DataStoreService::GetDataStoresCreate(nsPIDOMWindowInner* aWindow,
-                                      Promise* aPromise,
-                                      const nsTArray<DataStoreInfo>& aStores)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (!aStores.Length()) {
-    GetDataStoresResolve(aWindow, aPromise, aStores);
-    return;
-  }
-
-  nsTArray<nsString> pendingDataStores;
-  for (uint32_t i = 0; i < aStores.Length(); ++i) {
-    if (!aStores[i].mEnabled) {
-      pendingDataStores.AppendElement(aStores[i].mManifestURL);
-    }
-  }
-
-  if (!pendingDataStores.Length()) {
-    GetDataStoresResolve(aWindow, aPromise, aStores);
-    return;
-  }
-
-  PendingRequests* requests;
-  if (!mPendingRequests.Get(aStores[0].mName, &requests)) {
-    requests = new PendingRequests();
-    mPendingRequests.Put(aStores[0].mName, requests);
-  }
-
-  PendingRequest* request = requests->AppendElement();
-  request->Init(aWindow, aPromise, aStores, pendingDataStores);
-}
-
-void
-DataStoreService::GetDataStoresResolve(nsPIDOMWindowInner* aWindow,
-                                       Promise* aPromise,
-                                       const nsTArray<DataStoreInfo>& aStores)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (!aStores.Length()) {
-    nsTArray<RefPtr<DataStore>> results;
-    aPromise->MaybeResolve(results);
-    return;
-  }
-
-  AutoSafeJSContext cx;
-
-  // The counter will finish this task once all the DataStores will know their
-  // first revision Ids.
-  RefPtr<RetrieveRevisionsCounter> counter =
-    new RetrieveRevisionsCounter(++gCounterID, aPromise, aStores.Length());
-  mPendingCounters.Put(gCounterID, counter);
-
-  for (uint32_t i = 0; i < aStores.Length(); ++i) {
-    nsCOMPtr<nsIDataStore> dataStore =
-      do_CreateInstance("@mozilla.org/dom/datastore;1");
-    if (NS_WARN_IF(!dataStore)) {
-      return;
-    }
-
-    nsresult rv = dataStore->Init(aWindow, aStores[i].mName,
-                                  aStores[i].mManifestURL,
-                                  aStores[i].mReadOnly);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return;
-    }
-
-    nsCOMPtr<nsIXPConnectWrappedJS> xpcwrappedjs = do_QueryInterface(dataStore);
-    if (NS_WARN_IF(!xpcwrappedjs)) {
-      return;
-    }
-
-    JS::Rooted<JSObject*> dataStoreJS(cx, xpcwrappedjs->GetJSObject());
-    if (NS_WARN_IF(!dataStoreJS)) {
-      return;
-    }
-
-    nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aWindow);
-    MOZ_ASSERT(global);
-
-    JSAutoCompartment ac(cx, dataStoreJS);
-    RefPtr<DataStoreImpl> dataStoreObj = new DataStoreImpl(dataStoreJS,
-                                                             global);
-
-    RefPtr<DataStore> exposedStore = new DataStore(aWindow);
-
-    ErrorResult error;
-    exposedStore->SetDataStoreImpl(*dataStoreObj, error);
-    if (error.Failed()) {
-      return;
-    }
-
-    JS::Rooted<JS::Value> exposedObject(cx);
-    if (!GetOrCreateDOMReflector(cx, exposedStore, &exposedObject)) {
-      JS_ClearPendingException(cx);
-      return;
-    }
-
-    dataStore->SetExposedObject(exposedObject);
-
-    counter->AppendDataStore(cx, exposedStore, dataStore);
-  }
-}
-
-// This method populates 'aStores' with the list of DataStores with 'aName' as
-// name and available for this 'aAppId'.
-nsresult
-DataStoreService::GetDataStoreInfos(const nsAString& aName,
-                                    const nsAString& aOwner,
-                                    uint32_t aAppId,
-                                    nsIPrincipal* aPrincipal,
-                                    nsTArray<DataStoreInfo>& aStores)
-{
-  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-
-  nsCOMPtr<nsIAppsService> appsService =
-    do_GetService("@mozilla.org/AppsService;1");
-  if (NS_WARN_IF(!appsService)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsCOMPtr<mozIApplication> app;
-  nsresult rv = appsService->GetAppByLocalId(aAppId, getter_AddRefs(app));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (!app) {
-    return NS_ERROR_DOM_SECURITY_ERR;
-  }
-
-  if (!DataStoreService::CheckPermission(aPrincipal)) {
-    return NS_ERROR_DOM_SECURITY_ERR;
-  }
-
-  aStores.Clear();
-
-  HashApp* apps = nullptr;
-  if (!mStores.Get(aName, &apps)) {
-    return NS_OK;
-  }
-
-  DataStoreInfo* appsInfo = nullptr;
-  if (apps->Get(aAppId, &appsInfo) &&
-      (aOwner.IsEmpty() || aOwner.Equals(appsInfo->mManifestURL))) {
-    DataStoreInfo* owned = aStores.AppendElement();
-    owned->Init(appsInfo->mName, appsInfo->mOriginURL, appsInfo->mManifestURL,
-                false, appsInfo->mEnabled);
-  }
-
-  for (auto iter = apps->ConstIter(); !iter.Done(); iter.Next()) {
-    if (iter.Key() == aAppId) {
-      continue;
-    }
-
-    DataStoreInfo* appInfo = iter.UserData();
-    MOZ_ASSERT(appInfo);
-
-    HashApp* accessApp;
-    if (!mAccessStores.Get(aName, &accessApp)) {
-      continue;
-    }
-
-    if (!aOwner.IsEmpty() &&
-        !aOwner.Equals(appInfo->mManifestURL)) {
-      continue;
-    }
-
-    DataStoreInfo* accessInfo = nullptr;
-    if (!accessApp->Get(aAppId, &accessInfo)) {
-      continue;
-    }
-
-    bool readOnly = appInfo->mReadOnly || accessInfo->mReadOnly;
-    DataStoreInfo* accessStore = aStores.AppendElement();
-    accessStore->Init(aName, appInfo->mOriginURL,
-                      appInfo->mManifestURL, readOnly,
-                      appInfo->mEnabled);
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-DataStoreService::GetAppManifestURLsForDataStore(const nsAString& aName,
-                                                 nsIArray** aManifestURLs)
-{
-  ASSERT_PARENT_PROCESS()
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsIMutableArray> manifestURLs = do_CreateInstance(NS_ARRAY_CONTRACTID);
-  if (!manifestURLs) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  HashApp* apps = nullptr;
-  if (mStores.Get(aName, &apps)) {
-    for (auto iter = apps->ConstIter(); !iter.Done(); iter.Next()) {
-      nsCOMPtr<nsISupportsString> manifestURL(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
-      if (manifestURL) {
-        manifestURL->SetData(iter.UserData()->mManifestURL);
-        manifestURLs->AppendElement(manifestURL, false);
-      }
-    }
-  }
-  if (mAccessStores.Get(aName, &apps)) {
-    for (auto iter = apps->ConstIter(); !iter.Done(); iter.Next()) {
-      nsCOMPtr<nsISupportsString> manifestURL(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
-      if (manifestURL) {
-        manifestURL->SetData(iter.UserData()->mManifestURL);
-        manifestURLs->AppendElement(manifestURL, false);
-      }
-    }
-  }
-
-  manifestURLs.forget(aManifestURLs);
-  return NS_OK;
-}
-
-bool
-DataStoreService::CheckPermission(nsIPrincipal* aPrincipal)
-{
-  // First of all, the general pref has to be turned on.
-  bool enabled = false;
-  Preferences::GetBool("dom.datastore.enabled", &enabled);
-  if (!enabled) {
-    return false;
-  }
-
-  // Just for testing, we can enable DataStore for any kind of app.
-  if (Preferences::GetBool("dom.testing.datastore_enabled_for_hosted_apps", false)) {
-    return true;
-  }
-
-  if (!aPrincipal) {
-    return false;
-  }
-
-  uint16_t status;
-  if (NS_FAILED(aPrincipal->GetAppStatus(&status))) {
-    return false;
-  }
-
-  // Certified apps are always allowed.
-  if (status == nsIPrincipal::APP_STATUS_CERTIFIED) {
-    return true;
-  }
-
-  if (status != nsIPrincipal::APP_STATUS_PRIVILEGED) {
-    return false;
-  }
-
-  // Privileged apps are allowed if they are the homescreen.
-  nsAdoptingString homescreen =
-    Preferences::GetString("dom.mozApps.homescreenURL");
-  if (!homescreen) {
-    return false;
-  }
-
-  uint32_t appId;
-  nsresult rv = aPrincipal->GetAppId(&appId);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return false;
-  }
-
-  nsCOMPtr<nsIAppsService> appsService =
-    do_GetService("@mozilla.org/AppsService;1");
-  if (NS_WARN_IF(!appsService)) {
-    return false;
-  }
-
-  nsAutoString manifestURL;
-  rv = appsService->GetManifestURLByLocalId(appId, manifestURL);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return false;
-  }
-
-  return manifestURL.Equals(homescreen);
-}
-
-NS_IMETHODIMP
-DataStoreService::CheckPermission(nsIPrincipal* aPrincipal,
-                                  bool* aResult)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  *aResult = DataStoreService::CheckPermission(aPrincipal);
-
-  return NS_OK;
-}
-
-// This method is called when an app with DataStores is deleted.
-void
-DataStoreService::DeleteDataStores(uint32_t aAppId)
-{
-  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-
-  DeleteDataStoresHelper(mStores, aAppId);
-  DeleteDataStoresHelper(mAccessStores, aAppId);
-}
-
-NS_IMETHODIMP
-DataStoreService::Observe(nsISupports* aSubject,
-                          const char* aTopic,
-                          const char16_t* aData)
-{
-  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-
-  if (strcmp(aTopic, "webapps-clear-data")) {
-    return NS_OK;
-  }
-
-  nsCOMPtr<mozIApplicationClearPrivateDataParams> params =
-    do_QueryInterface(aSubject);
-  MOZ_ASSERT(params);
-
-  // DataStore is explosed to apps, not browser content.
-  bool browserOnly;
-  nsresult rv = params->GetBrowserOnly(&browserOnly);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (browserOnly) {
-    return NS_OK;
-  }
-
-  uint32_t appId;
-  rv = params->GetAppId(&appId);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  DeleteDataStores(appId);
-
-  return NS_OK;
-}
-
-nsresult
-DataStoreService::AddPermissions(uint32_t aAppId,
-                                 const nsAString& aName,
-                                 const nsAString& aOriginURL,
-                                 const nsAString& aManifestURL,
-                                 bool aReadOnly)
-{
-  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-
-  // This is the permission name.
-  nsString permission;
-  GeneratePermissionName(permission, aName, aManifestURL);
-
-  // When a new DataStore is installed, the permissions must be set for the
-  // owner app.
-  nsresult rv = ResetPermission(aAppId, aOriginURL, aManifestURL, permission,
-                                aReadOnly);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  // For any app that wants to have access to this DataStore we add the
-  // permissions.
-  HashApp* apps;
-  if (!mAccessStores.Get(aName, &apps)) {
-    return NS_OK;
-  }
-
-  for (auto iter = apps->ConstIter(); !iter.Done(); iter.Next()) {
-    DataStoreInfo* info = iter.UserData();
-    MOZ_ASSERT(info);
-
-    bool readOnly = aReadOnly || info->mReadOnly;
-
-    rv = ResetPermission(iter.Key(), info->mOriginURL,
-                         info->mManifestURL,
-                         permission, readOnly);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-  }
-
-  return NS_OK;
-}
-
-nsresult
-DataStoreService::AddAccessPermissions(uint32_t aAppId, const nsAString& aName,
-                                       const nsAString& aOriginURL,
-                                       const nsAString& aManifestURL,
-                                       bool aReadOnly)
-{
-  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-
-  // When an app wants to have access to a DataStore, the permissions must be
-  // set.
-  HashApp* apps = nullptr;
-  if (!mStores.Get(aName, &apps)) {
-    return NS_OK;
-  }
-
-  for (auto iter = apps->ConstIter(); !iter.Done(); iter.Next()) {
-    DataStoreInfo* info = iter.UserData();
-    MOZ_ASSERT(info);
-
-    nsAutoString permission;
-    GeneratePermissionName(permission, aName, info->mManifestURL);
-
-    // ReadOnly is decided by the owner first.
-    bool readOnly = info->mReadOnly || aReadOnly;
-
-    nsresult rv = ResetPermission(aAppId, aOriginURL,
-                                  info->mManifestURL,
-                                  permission, readOnly);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-  }
-
-  return NS_OK;
-}
-
-// This method starts the operation to create the first revision for a DataStore
-// if needed.
-nsresult
-DataStoreService::CreateFirstRevisionId(uint32_t aAppId,
-                                        const nsAString& aName,
-                                        const nsAString& aManifestURL)
-{
-  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-
-  RefPtr<DataStoreDB> db = new DataStoreDB(aManifestURL, aName);
-
-  RefPtr<FirstRevisionIdCallback> callback =
-    new FirstRevisionIdCallback(aAppId, aName, aManifestURL);
-
-  Sequence<nsString> dbs;
-  if (!dbs.AppendElement(NS_LITERAL_STRING(DATASTOREDB_REVISION), fallible)) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  return db->Open(IDBTransactionMode::Readwrite, dbs, callback);
-}
-
-nsresult
-DataStoreService::EnableDataStore(uint32_t aAppId, const nsAString& aName,
-                                  const nsAString& aManifestURL)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  {
-    HashApp* apps = nullptr;
-    DataStoreInfo* info = nullptr;
-    if (mStores.Get(aName, &apps) && apps->Get(aAppId, &info)) {
-      info->Enable();
-    }
-  }
-
-  // Notify the child processes.
-  if (XRE_IsParentProcess()) {
-    nsTArray<ContentParent*> children;
-    ContentParent::GetAll(children);
-    for (uint32_t i = 0; i < children.Length(); i++) {
-      if (children[i]->NeedsDataStoreInfos()) {
-        Unused << children[i]->SendDataStoreNotify(aAppId, nsAutoString(aName),
-                                                   nsAutoString(aManifestURL));
-      }
-    }
-  }
-
-  // Maybe we have some pending request waiting for this DataStore.
-  PendingRequests* requests;
-  if (!mPendingRequests.Get(aName, &requests)) {
-    return NS_OK;
-  }
-
-  for (uint32_t i = 0; i < requests->Length();) {
-    PendingRequest& request = requests->ElementAt(i);
-    nsTArray<nsString>::index_type pos =
-      request.mPendingDataStores.IndexOf(aManifestURL);
-    if (pos != request.mPendingDataStores.NoIndex) {
-      request.mPendingDataStores.RemoveElementAt(pos);
-
-      // No other pending dataStores.
-      if (request.mPendingDataStores.IsEmpty()) {
-        GetDataStoresResolve(request.mWindow, request.mPromise,
-                             request.mStores);
-        requests->RemoveElementAt(i);
-        continue;
-      }
-    }
-
-    ++i;
-  }
-
-  // No other pending requests for this name.
-  if (requests->IsEmpty()) {
-    mPendingRequests.Remove(aName);
-  }
-
-  return NS_OK;
-}
-
-already_AddRefed<RetrieveRevisionsCounter>
-DataStoreService::GetCounter(uint32_t aId) const
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  RefPtr<RetrieveRevisionsCounter> counter;
-  return mPendingCounters.Get(aId, getter_AddRefs(counter))
-           ? counter.forget() : nullptr;
-}
-
-void
-DataStoreService::RemoveCounter(uint32_t aId)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  mPendingCounters.Remove(aId);
-}
-
-nsresult
-DataStoreService::GetDataStoresFromIPC(const nsAString& aName,
-                                       const nsAString& aOwner,
-                                       nsIPrincipal* aPrincipal,
-                                       nsTArray<DataStoreSetting>* aValue)
-{
-  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-
-  uint32_t appId;
-  nsresult rv = aPrincipal->GetAppId(&appId);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  nsTArray<DataStoreInfo> stores;
-  rv = GetDataStoreInfos(aName, aOwner, appId, aPrincipal, stores);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  for (uint32_t i = 0; i < stores.Length(); ++i) {
-    DataStoreSetting* data = aValue->AppendElement();
-    data->name() = stores[i].mName;
-    data->originURL() = stores[i].mOriginURL;
-    data->manifestURL() = stores[i].mManifestURL;
-    data->readOnly() = stores[i].mReadOnly;
-    data->enabled() = stores[i].mEnabled;
-  }
-
-  return NS_OK;
-}
-
-nsresult
-DataStoreService::GenerateUUID(nsAString& aID)
-{
-  nsresult rv;
-
-  if (!mUUIDGenerator) {
-    mUUIDGenerator = do_GetService("@mozilla.org/uuid-generator;1", &rv);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-  }
-
-  nsID id;
-  rv = mUUIDGenerator->GenerateUUIDInPlace(&id);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  char chars[NSID_LENGTH];
-  id.ToProvidedString(chars);
-  CopyASCIItoUTF16(chars, aID);
-
-  return NS_OK;
-}
-
-void
-DataStoreService::HomeScreenPrefChanged()
-{
-  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
-
-  nsAdoptingString homescreen =
-    Preferences::GetString("dom.mozApps.homescreenURL");
-  if (homescreen == gHomeScreenManifestURL) {
-    return;
-  }
-
-  // Remove datastores of the old homescreen.
-  if (!gHomeScreenManifestURL.IsEmpty()) {
-    DeleteDataStoresIfNotAllowed(gHomeScreenManifestURL);
-  }
-
-  gHomeScreenManifestURL = homescreen;
-  if (gHomeScreenManifestURL.IsEmpty()) {
-    return;
-  }
-
-  // Add datastores for the new homescreen.
-  AddDataStoresIfAllowed(gHomeScreenManifestURL);
-}
-
-void
-DataStoreService::DeleteDataStoresIfNotAllowed(const nsAString& aManifestURL)
-{
-  nsCOMPtr<nsIAppsService> appsService =
-    do_GetService("@mozilla.org/AppsService;1");
-  if (NS_WARN_IF(!appsService)) {
-    return;
-  }
-
-  nsCOMPtr<mozIApplication> app;
-  nsresult rv = appsService->GetAppByManifestURL(aManifestURL,
-                                                 getter_AddRefs(app));
-  if (NS_WARN_IF(NS_FAILED(rv)) || !app) {
-    return;
-  }
-
-  uint32_t localId;
-  rv = app->GetLocalId(&localId);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  nsCOMPtr<nsIPrincipal> principal;
-  rv = app->GetPrincipal(getter_AddRefs(principal));
-
-  // We delete all the dataStores for this app here.
-  if (NS_WARN_IF(NS_FAILED(rv)) || !principal ||
-      !CheckPermission(principal)) {
-    DeleteDataStores(localId);
-  }
-}
-
-void
-DataStoreService::AddDataStoresIfAllowed(const nsAString& aManifestURL)
-{
-  nsCOMPtr<nsIAppsService> appsService =
-    do_GetService("@mozilla.org/AppsService;1");
-  if (NS_WARN_IF(!appsService)) {
-    return;
-  }
-
-  nsCOMPtr<mozIApplication> app;
-  nsresult rv = appsService->GetAppByManifestURL(aManifestURL,
-                                                 getter_AddRefs(app));
-  if (NS_WARN_IF(NS_FAILED(rv)) || !app) {
-    return;
-  }
-
-  uint32_t localId;
-  rv = app->GetLocalId(&localId);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  rv = appsService->UpdateDataStoreEntriesFromLocalId(localId);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-}
-
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/datastore/DataStoreService.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_DataStoreService_h
-#define mozilla_dom_DataStoreService_h
-
-#include "mozilla/dom/PContent.h"
-#include "nsClassHashtable.h"
-#include "nsIDataStoreService.h"
-#include "nsIObserver.h"
-#include "nsRefPtrHashtable.h"
-
-class nsIPrincipal;
-class nsIUUIDGenerator;
-class nsPIDOMWindowInner;
-
-namespace mozilla {
-namespace dom {
-
-class DataStoreInfo;
-class FirstRevisionIdCallback;
-class PendingRequest;
-class Promise;
-class RetrieveRevisionsCounter;
-class RevisionAddedEnableStoreCallback;
-
-class DataStoreService final : public nsIDataStoreService
-                             , public nsIObserver
-{
-  friend class ContentChild;
-  friend class FirstRevisionIdCallback;
-  friend class RetrieveRevisionsCounter;
-  friend class RevisionAddedEnableStoreCallback;
-
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIOBSERVER
-  NS_DECL_NSIDATASTORESERVICE
-
-  // Returns the DataStoreService singleton. Only to be called from main
-  // thread.
-  static already_AddRefed<DataStoreService> GetOrCreate();
-
-  static already_AddRefed<DataStoreService> Get();
-
-  static void Shutdown();
-
-  static bool CheckPermission(nsIPrincipal* principal);
-
-  nsresult GenerateUUID(nsAString& aID);
-
-  nsresult GetDataStoresFromIPC(const nsAString& aName,
-                                const nsAString& aOwner,
-                                nsIPrincipal* aPrincipal,
-                                nsTArray<DataStoreSetting>* aValue);
-
-  void HomeScreenPrefChanged();
-
-private:
-  DataStoreService();
-  ~DataStoreService();
-
-  nsresult Init();
-
-  typedef nsClassHashtable<nsUint32HashKey, DataStoreInfo> HashApp;
-
-  nsresult AddPermissions(uint32_t aAppId, const nsAString& aName,
-                          const nsAString& aOriginURL,
-                          const nsAString& aManifestURL,
-                          bool aReadOnly);
-
-  nsresult AddAccessPermissions(uint32_t aAppId, const nsAString& aName,
-                                const nsAString& aOriginURL,
-                                const nsAString& aManifestURL,
-                                bool aReadOnly);
-
-  nsresult CreateFirstRevisionId(uint32_t aAppId, const nsAString& aName,
-                                 const nsAString& aManifestURL);
-
-  void GetDataStoresCreate(nsPIDOMWindowInner* aWindow, Promise* aPromise,
-                           const nsTArray<DataStoreInfo>& aStores);
-
-  void GetDataStoresResolve(nsPIDOMWindowInner* aWindow, Promise* aPromise,
-                            const nsTArray<DataStoreInfo>& aStores);
-
-  nsresult GetDataStoreInfos(const nsAString& aName, const nsAString& aOwner,
-                             uint32_t aAppId, nsIPrincipal* aPrincipal,
-                             nsTArray<DataStoreInfo>& aStores);
-
-  void DeleteDataStores(uint32_t aAppId);
-
-  nsresult EnableDataStore(uint32_t aAppId, const nsAString& aName,
-                           const nsAString& aManifestURL);
-
-  already_AddRefed<RetrieveRevisionsCounter> GetCounter(uint32_t aId) const;
-
-  void RemoveCounter(uint32_t aId);
-
-  void DeleteDataStoresIfNotAllowed(const nsAString& aManifestURL);
-  void AddDataStoresIfAllowed(const nsAString& aManifestURL);
-
-  nsClassHashtable<nsStringHashKey, HashApp> mStores;
-  nsClassHashtable<nsStringHashKey, HashApp> mAccessStores;
-
-  typedef nsTArray<PendingRequest> PendingRequests;
-  nsClassHashtable<nsStringHashKey, PendingRequests> mPendingRequests;
-
-  nsRefPtrHashtable<nsUint32HashKey, RetrieveRevisionsCounter> mPendingCounters;
-
-  nsCOMPtr<nsIUUIDGenerator> mUUIDGenerator;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_DataStoreService_h
deleted file mode 100644
--- a/dom/datastore/moz.build
+++ /dev/null
@@ -1,50 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-XPIDL_SOURCES += [
-    'nsIDataStore.idl',
-    'nsIDataStoreService.idl',
-]
-
-XPIDL_MODULE = 'dom_datastore'
-
-EXPORTS.mozilla.dom += [
-    'DataStore.h',
-    'DataStoreCursor.h',
-    'DataStoreService.h',
-]
-
-UNIFIED_SOURCES += [
-    'DataStore.cpp',
-    'DataStoreCursor.cpp',
-    'DataStoreDB.cpp',
-    'DataStoreRevision.cpp',
-    'DataStoreService.cpp',
-]
-
-LOCAL_INCLUDES += [
-    '/js/xpconnect/wrappers',
-]
-
-EXTRA_COMPONENTS += [
-    'DataStore.manifest',
-    'DataStoreImpl.js',
-]
-
-EXTRA_JS_MODULES += [
-    'DataStoreChangeNotifier.jsm',
-    'DataStoreCursorImpl.jsm',
-    'DataStoreDB.jsm',
-]
-
-MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
-
-include('/ipc/chromium/chromium-config.mozbuild')
-
-FINAL_LIBRARY = 'xul'
-
-if CONFIG['GNU_CXX']:
-    CXXFLAGS += ['-Wshadow']
deleted file mode 100644
--- a/dom/datastore/nsIDataStore.idl
+++ /dev/null
@@ -1,23 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-interface mozIDOMWindow;
-
-// NOTE: This is a temporary interface.
-// It will be removed in the next patches for rewriting DataStore in C++.
-[scriptable, uuid(14f4bae7-dd01-4d1d-81e1-f8fd1e463b5f)]
-interface nsIDataStore : nsISupports
-{
-  void init(in mozIDOMWindow window,
-            in DOMString name,
-            in DOMString manifestURL,
-            in boolean readOnly);
-
-  attribute jsval exposedObject;
-
-  void retrieveRevisionId(in jsval cb);
-};
deleted file mode 100644
--- a/dom/datastore/nsIDataStoreService.idl
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-interface mozIDOMWindow;
-interface nsIPrincipal;
-interface nsIArray;
-
-[scriptable, uuid(44a8de94-d3dd-4a3a-a582-41027d36ceb5)]
-interface nsIDataStoreService : nsISupports
-{
-  void installDataStore(in unsigned long appId,
-                        in DOMString name,
-                        in DOMString originURL,
-                        in DOMString manifestURL,
-                        in boolean readOnly);
-
-  void installAccessDataStore(in unsigned long appId,
-                              in DOMString name,
-                              in DOMString originURL,
-                              in DOMString manifestURL,
-                              in boolean readOnly);
-
-  nsISupports getDataStores(in mozIDOMWindow window,
-                            in DOMString name,
-                            in DOMString owner);
-
-  nsIArray getAppManifestURLsForDataStore(in DOMString name);
-
-  boolean checkPermission(in nsIPrincipal principal);
-};
deleted file mode 100644
--- a/dom/datastore/tests/file_app.sjs
+++ /dev/null
@@ -1,55 +0,0 @@
-var gBasePath = "tests/dom/datastore/tests/";
-
-function handleRequest(request, response) {
-  var query = getQuery(request);
-
-  var testToken = '';
-  if ('testToken' in query) {
-    testToken = query.testToken;
-  }
-
-  var template = 'file_app.template.webapp';
-  if ('template' in query) {
-    template = query.template;
-  }
-  var template = gBasePath + template;
-  response.setHeader("Content-Type", "application/x-web-app-manifest+json", false);
-  response.write(readTemplate(template).replace(/TESTTOKEN/g, testToken));
-}
-
-// Copy-pasted incantations. There ought to be a better way to synchronously read
-// a file into a string, but I guess we're trying to discourage that.
-function readTemplate(path) {
-  var file = Components.classes["@mozilla.org/file/directory_service;1"].
-                        getService(Components.interfaces.nsIProperties).
-                        get("CurWorkD", Components.interfaces.nsILocalFile);
-  var fis  = Components.classes['@mozilla.org/network/file-input-stream;1'].
-                        createInstance(Components.interfaces.nsIFileInputStream);
-  var cis = Components.classes["@mozilla.org/intl/converter-input-stream;1"].
-                       createInstance(Components.interfaces.nsIConverterInputStream);
-  var split = path.split("/");
-  for(var i = 0; i < split.length; ++i) {
-    file.append(split[i]);
-  }
-  fis.init(file, -1, -1, false);
-  cis.init(fis, "UTF-8", 0, 0);
-
-  var data = "";
-  let str = {};
-  let read = 0;
-  do {
-    read = cis.readString(0xffffffff, str); // read as much as we can and put it in str.value
-    data += str.value;
-  } while (read != 0);
-  cis.close();
-  return data;
-}
-
-function getQuery(request) {
-  var query = {};
-  request.queryString.split('&').forEach(function (val) {
-    var [name, value] = val.split('=');
-    query[name] = unescape(value);
-  });
-  return query;
-}
deleted file mode 100644
--- a/dom/datastore/tests/file_app.template.webapp
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "name": "Really Rapid Release (hosted)",
-  "description": "Updated even faster than <a href='http://mozilla.org'>Firefox</a>, just to annoy slashdotters.",
-  "launch_path": "/tests/dom/datastore/tests/TESTTOKEN",