Merge mozilla-central to autoland. a=merge
authorCosmin Sabou <csabou@mozilla.com>
Tue, 16 Oct 2018 19:27:54 +0300
changeset 499953 6fa9b4e512fa5fadcf300634e5da2ae8b1d12ed2
parent 499951 8eaeb557ba9f438afb0d6a7bd3bfc19f7b6df098 (current diff)
parent 499952 31724aea10cae55f30b825ade226c4d25e11a899 (diff)
child 499954 7413b2c7cdb4f45da50d2130a9403978977a36ed
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone64.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 mozilla-central to autoland. a=merge
security/sandbox/chromium-shim/patches/with_update/mingw_noexports_casts.patch
--- a/browser/base/content/browser-pageActions.js
+++ b/browser/base/content/browser-pageActions.js
@@ -1198,16 +1198,22 @@ BrowserPageActions.addSearchEngine = {
         prompt.alert(title, text);
       },
     });
   },
 };
 
 // share URL
 BrowserPageActions.shareURL = {
+  onCommand(event, buttonNode) {
+    let browser = gBrowser.selectedBrowser;
+    let currentURI = gURLBar.makeURIReadable(browser.currentURI).displaySpec;
+    this._windowsUIUtils.shareUrl(currentURI, browser.contentTitle);
+  },
+
   onShowingInPanel(buttonNode) {
     this._cached = false;
   },
 
   onBeforePlacedInWindow(browserWindow) {
     let action = PageActions.actionForID("shareURL");
     BrowserPageActions.takeActionTitleFromPanel(action);
   },
@@ -1259,12 +1265,12 @@ BrowserPageActions.shareURL = {
       bodyNode.firstChild.remove();
     }
     bodyNode.appendChild(fragment);
     this._cached = true;
   },
 };
 
 // Attach sharingService here so tests can override the implementation
-XPCOMUtils.defineLazyServiceGetter(BrowserPageActions.shareURL,
-                                   "_sharingService",
-                                   "@mozilla.org/widget/macsharingservice;1",
-                                   "nsIMacSharingService");
+XPCOMUtils.defineLazyServiceGetters(BrowserPageActions.shareURL, {
+  _sharingService: ["@mozilla.org/widget/macsharingservice;1", "nsIMacSharingService"],
+  _windowsUIUtils: ["@mozilla.org/windows-ui-utils;1", "nsIWindowsUIUtils"],
+});
--- a/browser/base/content/test/general/browser_homeDrop.js
+++ b/browser/base/content/test/general/browser_homeDrop.js
@@ -14,16 +14,18 @@ add_task(async function() {
   ok(dragSrcElement, "Downloads button exists");
   let homeButton = document.getElementById("home-button");
   ok(homeButton, "home button present");
 
   async function drop(dragData, homepage) {
     let setHomepageDialogPromise = BrowserTestUtils.domWindowOpened();
 
     EventUtils.synthesizeDrop(dragSrcElement, homeButton, dragData, "copy", window);
+    // Ensure dnd suppression is cleared.
+    EventUtils.synthesizeMouseAtCenter(homeButton, { type: "mouseup" }, window);
 
     let setHomepageDialog = await setHomepageDialogPromise;
     ok(true, "dialog appeared in response to home button drop");
     await BrowserTestUtils.waitForEvent(setHomepageDialog, "load", false);
 
     let setHomepagePromise = new Promise(function(resolve) {
       let observer = {
         QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
@@ -63,16 +65,18 @@ add_task(async function() {
       });
 
       executeSoon(function() {
         info("Attempting second drop, of a javascript: URI");
         // The drop handler throws an exception when dragging URIs that inherit
         // principal, e.g. javascript:
         expectUncaughtException();
         EventUtils.synthesizeDrop(dragSrcElement, homeButton, [[{type: "text/plain", data: "javascript:8888"}]], "copy", window);
+        // Ensure dnd suppression is cleared.
+        EventUtils.synthesizeMouseAtCenter(homeButton, { type: "mouseup" }, window);
       });
     });
   }
 
   await drop([[{type: "text/plain",
                  data: "http://mochi.test:8888/"}]],
               "http://mochi.test:8888/");
   await drop([[{type: "text/plain",
--- a/browser/base/content/test/tabs/head.js
+++ b/browser/base/content/test/tabs/head.js
@@ -169,16 +169,18 @@ async function dragAndDrop(tab1, tab2, c
   if (destWindow != window) {
     // Make sure that both tab1 and tab2 are visible
     window.focus();
     window.moveTo(rect.left, rect.top + rect.height * 3);
   }
 
   let originalTPos = tab1._tPos;
   EventUtils.synthesizeDrop(tab1, tab2, null, copy ? "copy" : "move", window, destWindow, event);
+  // Ensure dnd suppression is cleared.
+  EventUtils.synthesizeMouseAtCenter(tab2, { type: "mouseup" }, destWindow);
   if (!copy && destWindow == window) {
     await BrowserTestUtils.waitForCondition(() => tab1._tPos != originalTPos,
       "Waiting for tab position to be updated");
   } else if (destWindow != window) {
     await BrowserTestUtils.waitForCondition(() => tab1.closing,
       "Waiting for tab closing");
   }
 }
--- a/browser/base/content/test/urlbar/browser.ini
+++ b/browser/base/content/test/urlbar/browser.ini
@@ -52,16 +52,20 @@ support-files =
   page_action_menu_add_search_engine_same_names.html
   page_action_menu_add_search_engine_0.xml
   page_action_menu_add_search_engine_1.xml
   page_action_menu_add_search_engine_2.xml
 [browser_page_action_menu_clipboard.js]
 subsuite = clipboard
 [browser_page_action_menu_share_mac.js]
 skip-if = os != "mac" # Mac only feature
+[browser_page_action_menu_share_win.js]
+support-files =
+  browser_page_action_menu_share_win.html
+skip-if = os != "win" # Windows only feature
 [browser_pasteAndGo.js]
 subsuite = clipboard
 [browser_populateAfterPushState.js]
 [browser_removeUnsafeProtocolsFromURLBarPaste.js]
 subsuite = clipboard
 [browser_search_favicon.js]
 [browser_tabMatchesInAwesomebar.js]
 support-files =
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/urlbar/browser_page_action_menu_share_win.html
@@ -0,0 +1,2 @@
+<!doctype html>
+<title>Windows Sharing</title>
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/urlbar/browser_page_action_menu_share_win.js
@@ -0,0 +1,49 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/* global sinon */
+Services.scriptloader.loadSubScript("resource://testing-common/sinon-2.3.2.js");
+
+const TEST_URL = getRootDirectory(gTestPath) + "browser_page_action_menu_share_win.html";
+
+// Keep track of site details we are sharing
+let sharedUrl, sharedTitle;
+
+let stub = sinon.stub(BrowserPageActions.shareURL, "_windowsUIUtils").get(() => {
+  return {
+    shareUrl(url, title) {
+      sharedUrl = url;
+      sharedTitle = title;
+    },
+  };
+});
+
+registerCleanupFunction(async function() {
+  stub.restore();
+  delete window.sinon;
+});
+
+add_task(async function shareURL() {
+
+  if (!AppConstants.isPlatformAndVersionAtLeast("win", "6.4")) {
+    Assert.ok(true, "We only expose share on windows 10 and above");
+    return;
+  }
+
+  await BrowserTestUtils.withNewTab(TEST_URL, async () => {
+    // Open the panel.
+    await promisePageActionPanelOpen();
+
+    // Click Share URL.
+    let shareURLButton = document.getElementById("pageAction-panel-shareURL");
+    let hiddenPromise = promisePageActionPanelHidden();
+    EventUtils.synthesizeMouseAtCenter(shareURLButton, {});
+
+    await hiddenPromise;
+
+    Assert.equal(sharedUrl, TEST_URL, "Shared correct URL");
+    Assert.equal(sharedTitle, "Windows Sharing", "Shared with the correct title");
+  });
+});
--- a/browser/components/customizableui/test/head.js
+++ b/browser/components/customizableui/test/head.js
@@ -18,17 +18,17 @@ Services.scriptloader.loadSubScript("chr
 /**
  * Instance of CustomizableUITestUtils for the current browser window.
  */
 var gCUITestUtils = new CustomizableUITestUtils(window);
 
 Services.prefs.setBoolPref("browser.uiCustomization.skipSourceNodeCheck", true);
 registerCleanupFunction(() => Services.prefs.clearUserPref("browser.uiCustomization.skipSourceNodeCheck"));
 
-var {synthesizeDragStart, synthesizeDrop} = EventUtils;
+var {synthesizeDragStart, synthesizeDrop, synthesizeMouseAtCenter} = EventUtils;
 
 const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
 const kForceOverflowWidthPx = 300;
 
 function createDummyXULButton(id, label, win = window) {
   let btn = document.createElementNS(kNSXUL, "toolbarbutton");
   btn.id = id;
@@ -184,16 +184,18 @@ function simulateItemDrag(aToDrag, aTarg
       ev = {clientX: bounds.right - 2, clientY: bounds.bottom - 2};
     } else {
       ev = {clientX: bounds.left + 2, clientY: bounds.top + 2};
     }
   }
   ev._domDispatchOnly = true;
   synthesizeDrop(aToDrag.parentNode, aTarget, null, null,
                  aToDrag.ownerGlobal, aTarget.ownerGlobal, ev);
+  // Ensure dnd suppression is cleared.
+  synthesizeMouseAtCenter(aTarget, { type: "mouseup" }, aTarget.ownerGlobal);
 }
 
 function endCustomizing(aWindow = window) {
   if (aWindow.document.documentElement.getAttribute("customizing") != "true") {
     return true;
   }
   return new Promise(resolve => {
     function onCustomizationEnds() {
--- a/browser/modules/PageActions.jsm
+++ b/browser/modules/PageActions.jsm
@@ -1180,16 +1180,31 @@ if (AppConstants.platform == "macosx") {
     wantsSubview: true,
     onSubviewShowing(panelViewNode) {
         browserPageActions(panelViewNode).shareURL
           .onShowingSubview(panelViewNode);
     },
   });
 }
 
+if (AppConstants.isPlatformAndVersionAtLeast("win", "6.4")) {
+  gBuiltInActions.push(
+  // Share URL
+  {
+    id: "shareURL",
+    title: "shareURL-title",
+    onBeforePlacedInWindow(buttonNode) {
+      browserPageActions(buttonNode).shareURL.onBeforePlacedInWindow(buttonNode);
+    },
+    onCommand(event, buttonNode) {
+      browserPageActions(buttonNode).shareURL.onCommand(event, buttonNode);
+    },
+  });
+}
+
 /**
  * Gets a BrowserPageActions object in a browser window.
  *
  * @param  obj
  *         Either a DOM node or a browser window.
  * @return The BrowserPageActions object in the browser window related to the
  *         given object.
  */
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -592,16 +592,20 @@ html|*.urlbar-input:-moz-lwtheme::placeh
 
 .urlbar-display {
   margin-top: 0;
   margin-bottom: 0;
   margin-inline-start: 0;
   color: GrayText;
 }
 
+#pageAction-panel-shareURL {
+  list-style-image: url("chrome://browser/skin/share.svg");
+}
+
 %include ../shared/urlbarSearchSuggestionsNotification.inc.css
 
 #search-container {
   min-width: calc(54px + 11ch);
 }
 
 /* identity box */
 
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -33,16 +33,17 @@ browser.jar:
   skin/classic/browser/places/livemark-item.png                (places/livemark-item.png)
   skin/classic/browser/preferences/alwaysAsk.png               (preferences/alwaysAsk.png)
   skin/classic/browser/preferences/application.png             (preferences/application.png)
   skin/classic/browser/preferences/saveFile.png                (preferences/saveFile.png)
   skin/classic/browser/preferences/preferences.css             (preferences/preferences.css)
 * skin/classic/browser/preferences/in-content/preferences.css  (preferences/in-content/preferences.css)
 * skin/classic/browser/preferences/in-content/dialog.css       (preferences/in-content/dialog.css)
   skin/classic/browser/preferences/applications.css            (preferences/applications.css)
+  skin/classic/browser/share.svg                               (share.svg)
   skin/classic/browser/tabbrowser/tabDragIndicator.png         (tabbrowser/tabDragIndicator.png)
   skin/classic/browser/window-controls/close.svg                 (window-controls/close.svg)
   skin/classic/browser/window-controls/close-highcontrast.svg    (window-controls/close-highcontrast.svg)
   skin/classic/browser/window-controls/close-themes.svg          (window-controls/close-themes.svg)
   skin/classic/browser/window-controls/maximize.svg              (window-controls/maximize.svg)
   skin/classic/browser/window-controls/maximize-highcontrast.svg (window-controls/maximize-highcontrast.svg)
   skin/classic/browser/window-controls/maximize-themes.svg       (window-controls/maximize-themes.svg)
   skin/classic/browser/window-controls/minimize.svg              (window-controls/minimize.svg)
new file mode 100644
--- /dev/null
+++ b/browser/themes/windows/share.svg
@@ -0,0 +1,7 @@
+<!-- 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/. -->
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
+  <path fill="context-fill" d="M 15.707 4.293 l -4 -4 a 1 1 0 0 0 -1.414 1.414 L 12.585 4 H 11 a 7.008 7.008 0 0 0 -7 7 a 1 1 0 0 0 2 0 a 5.006 5.006 0 0 1 5 -5 h 1.585 l -2.293 2.293 a 1 1 0 1 0 1.414 1.414 l 4 -4 a 1 1 0 0 0 0.001 -1.414 Z" />
+  <path fill="context-fill" d="M 13 11 a 1 1 0 0 0 -1 1 v 1 a 1 1 0 0 1 -1 1 H 3 a 1 1 0 0 1 -1 -1 V 6 a 1 1 0 0 1 1 -1 h 1 a 1 1 0 0 0 0 -2 H 3 a 3 3 0 0 0 -3 3 v 7 a 3 3 0 0 0 3 3 h 8 a 3 3 0 0 0 3 -3 v -1 a 1 1 0 0 0 -1 -1 Z" />
+</svg>
--- a/dom/base/EventSource.cpp
+++ b/dom/base/EventSource.cpp
@@ -144,17 +144,17 @@ public:
   void AddRefObject();
   void ReleaseObject();
 
   bool CreateWorkerRef(WorkerPrivate* aWorkerPrivate);
   void ReleaseWorkerRef();
 
   void AssertIsOnTargetThread() const
   {
-    MOZ_ASSERT(IsTargetThread());
+    MOZ_DIAGNOSTIC_ASSERT(IsTargetThread());
   }
 
   bool IsTargetThread() const
   {
     return NS_GetCurrentThread() == mTargetThread;
   }
 
   uint16_t ReadyState()
--- a/dom/quota/ActorsParent.cpp
+++ b/dom/quota/ActorsParent.cpp
@@ -24,16 +24,17 @@
 #include "nsIURI.h"
 #include "nsPIDOMWindow.h"
 
 #include <algorithm>
 #include "GeckoProfiler.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/CondVar.h"
+#include "mozilla/Telemetry.h"
 #include "mozilla/dom/PContent.h"
 #include "mozilla/dom/asmjscache/AsmJSCache.h"
 #include "mozilla/dom/cache/QuotaClient.h"
 #include "mozilla/dom/indexedDB/ActorsParent.h"
 #include "mozilla/dom/quota/PQuotaParent.h"
 #include "mozilla/dom/quota/PQuotaRequestParent.h"
 #include "mozilla/dom/quota/PQuotaUsageRequestParent.h"
 #include "mozilla/dom/simpledb/ActorsParent.h"
@@ -5409,32 +5410,38 @@ QuotaManager::EnsureTemporaryStorageIsIn
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(mStorageInitialized);
 
   if (mTemporaryStorageInitialized) {
     return NS_OK;
   }
 
+  TimeStamp startTime = TimeStamp::Now();
+
   nsresult rv = InitializeRepository(PERSISTENCE_TYPE_DEFAULT);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     // We have to cleanup partially initialized quota.
     RemoveQuota();
 
     return rv;
   }
 
   rv = InitializeRepository(PERSISTENCE_TYPE_TEMPORARY);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     // We have to cleanup partially initialized quota.
     RemoveQuota();
 
     return rv;
   }
 
+  Telemetry::AccumulateTimeDelta(Telemetry::QM_REPOSITORIES_INITIALIZATION_TIME,
+                                 startTime,
+                                 TimeStamp::Now());
+
   if (gFixedLimitKB >= 0) {
     mTemporaryStorageLimit = static_cast<uint64_t>(gFixedLimitKB) * 1024;
   } else {
     nsCOMPtr<nsIFile> storageDir =
       do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
--- a/dom/script/ModuleScript.cpp
+++ b/dom/script/ModuleScript.cpp
@@ -51,19 +51,18 @@ ModuleScript::ModuleScript(ScriptLoader*
   MOZ_ASSERT(!HasErrorToRethrow());
 }
 
 void
 ModuleScript::UnlinkModuleRecord()
 {
   // Remove module's back reference to this object request if present.
   if (mModuleRecord) {
-    MOZ_ASSERT(JS::GetModuleHostDefinedField(mModuleRecord).toPrivate() ==
-               this);
-    JS::SetModuleHostDefinedField(mModuleRecord, JS::UndefinedValue());
+    MOZ_ASSERT(JS::GetModulePrivate(mModuleRecord).toPrivate() == this);
+    JS::SetModulePrivate(mModuleRecord, JS::UndefinedValue());
     mModuleRecord = nullptr;
   }
 }
 
 ModuleScript::~ModuleScript()
 {
   // The object may be destroyed without being unlinked first.
   UnlinkModuleRecord();
@@ -76,17 +75,17 @@ ModuleScript::SetModuleRecord(JS::Handle
   MOZ_ASSERT(!mModuleRecord);
   MOZ_ASSERT(!HasParseError());
   MOZ_ASSERT(!HasErrorToRethrow());
 
   mModuleRecord = aModuleRecord;
 
   // Make module's host defined field point to this module script object.
   // This is cleared in the UnlinkModuleRecord().
-  JS::SetModuleHostDefinedField(mModuleRecord, JS::PrivateValue(this));
+  JS::SetModulePrivate(mModuleRecord, JS::PrivateValue(this));
   HoldJSObjects(this);
 }
 
 void
 ModuleScript::SetParseError(const JS::Value& aError)
 {
   MOZ_ASSERT(!aError.isUndefined());
   MOZ_ASSERT(!HasParseError());
--- a/dom/script/ScriptLoader.cpp
+++ b/dom/script/ScriptLoader.cpp
@@ -754,23 +754,23 @@ ScriptLoader::StartFetchingModuleAndDepe
     return ready;
   }
 
   return ready;
 }
 
 // 8.1.3.8.1 HostResolveImportedModule(referencingModule, specifier)
 JSObject*
-HostResolveImportedModule(JSContext* aCx, JS::Handle<JSObject*> aModule,
+HostResolveImportedModule(JSContext* aCx,
+                          JS::Handle<JS::Value> aReferencingPrivate,
                           JS::Handle<JSString*> aSpecifier)
 {
   // Let referencing module script be referencingModule.[[HostDefined]].
-  JS::Value value = JS::GetModuleHostDefinedField(aModule);
-  auto script = static_cast<ModuleScript*>(value.toPrivate());
-  MOZ_ASSERT(script->ModuleRecord() == aModule);
+  auto script = static_cast<ModuleScript*>(aReferencingPrivate.toPrivate());
+  MOZ_ASSERT(JS::GetModulePrivate(script->ModuleRecord()) == aReferencingPrivate);
 
   // Let url be the result of resolving a module specifier given referencing
   // module script and specifier.
   nsAutoJSString string;
   if (!string.init(aCx, aSpecifier)) {
     return nullptr;
   }
 
@@ -787,29 +787,22 @@ HostResolveImportedModule(JSContext* aCx
 
   MOZ_ASSERT(!ms->HasParseError());
   MOZ_ASSERT(ms->ModuleRecord());
 
   return ms->ModuleRecord();
 }
 
 bool
-HostPopulateImportMeta(JSContext* aCx, JS::Handle<JSObject*> aModule,
+HostPopulateImportMeta(JSContext* aCx,
+                       JS::Handle<JS::Value> aReferencingPrivate,
                        JS::Handle<JSObject*> aMetaObject)
 {
-  MOZ_DIAGNOSTIC_ASSERT(aModule);
-
-  JS::Value value = JS::GetModuleHostDefinedField(aModule);
-  if (value.isUndefined()) {
-    JS_ReportErrorASCII(aCx, "Module script not found");
-    return false;
-  }
-
-  auto script = static_cast<ModuleScript*>(value.toPrivate());
-  MOZ_DIAGNOSTIC_ASSERT(script->ModuleRecord() == aModule);
+  auto script = static_cast<ModuleScript*>(aReferencingPrivate.toPrivate());
+  MOZ_ASSERT(JS::GetModulePrivate(script->ModuleRecord()) == aReferencingPrivate);
 
   nsAutoCString url;
   MOZ_DIAGNOSTIC_ASSERT(script->BaseURL());
   MOZ_ALWAYS_SUCCEEDS(script->BaseURL()->GetAsciiSpec(url));
 
   JS::Rooted<JSString*> urlString(aCx, JS_NewStringCopyZ(aCx, url.get()));
   if (!urlString) {
     JS_ReportOutOfMemory(aCx);
--- a/dom/script/ScriptLoader.h
+++ b/dom/script/ScriptLoader.h
@@ -516,18 +516,19 @@ private:
 
   bool IsFetchingModule(ModuleLoadRequest* aRequest) const;
 
   bool ModuleMapContainsURL(nsIURI* aURL) const;
   RefPtr<mozilla::GenericPromise> WaitForModuleFetch(nsIURI* aURL);
   ModuleScript* GetFetchedModule(nsIURI* aURL) const;
 
   friend JSObject*
-  HostResolveImportedModule(JSContext* aCx, JS::Handle<JSObject*> aModule,
-                          JS::Handle<JSString*> aSpecifier);
+  HostResolveImportedModule(JSContext* aCx,
+                            JS::Handle<JS::Value> aReferencingPrivate,
+                            JS::Handle<JSString*> aSpecifier);
 
   // Returns wether we should save the bytecode of this script after the
   // execution of the script.
   static bool
   ShouldCacheBytecode(ScriptLoadRequest* aRequest);
 
   nsresult CreateModuleScript(ModuleLoadRequest* aRequest);
   nsresult ProcessFetchedModuleSource(ModuleLoadRequest* aRequest);
--- a/dom/svg/SVGFEImageElement.cpp
+++ b/dom/svg/SVGFEImageElement.cpp
@@ -46,16 +46,17 @@ nsSVGElement::StringInfo SVGFEImageEleme
 NS_IMPL_ISUPPORTS_INHERITED(SVGFEImageElement, SVGFEImageElementBase,
                             imgINotificationObserver, nsIImageLoadingContent)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGFEImageElement::SVGFEImageElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
   : SVGFEImageElementBase(std::move(aNodeInfo))
+  , mImageAnimationMode(0)
 {
   // We start out broken
   AddStatesSilently(NS_EVENT_STATE_BROKEN);
 }
 
 SVGFEImageElement::~SVGFEImageElement()
 {
   DestroyImageLoadingContent();
@@ -334,29 +335,61 @@ SVGFEImageElement::GetPreserveAspectRati
 nsSVGElement::StringAttributesInfo
 SVGFEImageElement::GetStringInfo()
 {
   return StringAttributesInfo(mStringAttributes, sStringInfo,
                               ArrayLength(sStringInfo));
 }
 
 //----------------------------------------------------------------------
+// nsIImageLoadingContent methods
+NS_IMETHODIMP_(void)
+SVGFEImageElement::FrameCreated(nsIFrame* aFrame)
+{
+  nsImageLoadingContent::FrameCreated(aFrame);
+
+  uint64_t mode = aFrame->PresContext()->ImageAnimationMode();
+  if (mode == mImageAnimationMode) {
+    return;
+  }
+
+  mImageAnimationMode = mode;
+
+  if (mPendingRequest) {
+    nsCOMPtr<imgIContainer> container;
+    mPendingRequest->GetImage(getter_AddRefs(container));
+    if (container) {
+      container->SetAnimationMode(mode);
+    }
+  }
+
+  if (mCurrentRequest) {
+    nsCOMPtr<imgIContainer> container;
+    mCurrentRequest->GetImage(getter_AddRefs(container));
+    if (container) {
+      container->SetAnimationMode(mode);
+    }
+  }
+}
+
+//----------------------------------------------------------------------
 // imgINotificationObserver methods
 
 NS_IMETHODIMP
 SVGFEImageElement::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aData)
 {
   nsresult rv = nsImageLoadingContent::Notify(aRequest, aType, aData);
 
   if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
     // Request a decode
     nsCOMPtr<imgIContainer> container;
     aRequest->GetImage(getter_AddRefs(container));
     MOZ_ASSERT(container, "who sent the notification then?");
     container->StartDecoding(imgIContainer::FLAG_NONE);
+    container->SetAnimationMode(mImageAnimationMode);
   }
 
   if (aType == imgINotificationObserver::LOAD_COMPLETE ||
       aType == imgINotificationObserver::FRAME_UPDATE ||
       aType == imgINotificationObserver::SIZE_AVAILABLE) {
     if (GetParent() && GetParent()->IsSVGElement(nsGkAtoms::filter)) {
       SVGObserverUtils::InvalidateDirectRenderingObservers(
         static_cast<SVGFilterElement*>(GetParent()));
--- a/dom/svg/SVGFEImageElement.h
+++ b/dom/svg/SVGFEImageElement.h
@@ -64,16 +64,19 @@ public:
                                 bool aNotify) override;
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent) override;
   virtual void UnbindFromTree(bool aDeep, bool aNullParent) override;
   virtual EventStates IntrinsicState() const override;
 
   NS_IMETHOD Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) override;
 
+  // Override for nsIImageLoadingContent.
+  NS_IMETHOD_(void) FrameCreated(nsIFrame* aFrame) override;
+
   void MaybeLoadSVGImage();
 
   // WebIDL
   already_AddRefed<SVGAnimatedString> Href();
   already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
 
 private:
   nsresult LoadSVGImage(bool aForce, bool aNotify);
@@ -87,14 +90,15 @@ protected:
   // Override for nsImageLoadingContent.
   nsIContent* AsContent() override { return this; }
 
   enum { RESULT, HREF, XLINK_HREF };
   nsSVGString mStringAttributes[3];
   static StringInfo sStringInfo[3];
 
   SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
+  uint16_t mImageAnimationMode;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif
--- a/js/src/builtin/ModuleObject.cpp
+++ b/js/src/builtin/ModuleObject.cpp
@@ -868,32 +868,40 @@ ModuleObject::namespace_()
 {
     Value value = getReservedSlot(NamespaceSlot);
     if (value.isUndefined()) {
         return nullptr;
     }
     return &value.toObject().as<ModuleNamespaceObject>();
 }
 
+ScriptSourceObject*
+ModuleObject::scriptSourceObject() const
+{
+    return &getReservedSlot(ScriptSourceObjectSlot).toObject().as<ScriptSourceObject>();
+}
+
 FunctionDeclarationVector*
 ModuleObject::functionDeclarations()
 {
     Value value = getReservedSlot(FunctionDeclarationsSlot);
     if (value.isUndefined()) {
         return nullptr;
     }
 
     return static_cast<FunctionDeclarationVector*>(value.toPrivate());
 }
 
 void
 ModuleObject::init(HandleScript script)
 {
+    MOZ_ASSERT(script);
     initReservedSlot(ScriptSlot, PrivateGCThingValue(script));
     initReservedSlot(StatusSlot, Int32Value(MODULE_STATUS_UNINSTANTIATED));
+    initReservedSlot(ScriptSourceObjectSlot, ObjectValue(script->scriptSourceUnwrap()));
 }
 
 void
 ModuleObject::setInitialEnvironment(HandleModuleEnvironmentObject initialEnvironment)
 {
     initReservedSlot(EnvironmentSlot, ObjectValue(*initialEnvironment));
 }
 
@@ -1050,28 +1058,16 @@ ModuleObject::metaObject() const
 void
 ModuleObject::setMetaObject(JSObject* obj)
 {
     MOZ_ASSERT(obj);
     MOZ_ASSERT(!metaObject());
     setReservedSlot(MetaObjectSlot, ObjectValue(*obj));
 }
 
-Value
-ModuleObject::hostDefinedField() const
-{
-    return getReservedSlot(HostDefinedSlot);
-}
-
-void
-ModuleObject::setHostDefinedField(const JS::Value& value)
-{
-    setReservedSlot(HostDefinedSlot, value);
-}
-
 Scope*
 ModuleObject::enclosingScope() const
 {
     return script()->enclosingScope();
 }
 
 /* static */ void
 ModuleObject::trace(JSTracer* trc, JSObject* obj)
@@ -1795,16 +1791,17 @@ js::GetOrCreateModuleMetaObject(JSContex
     }
 
     JS::ModuleMetadataHook func = cx->runtime()->moduleMetadataHook;
     if (!func) {
         JS_ReportErrorASCII(cx, "Module metadata hook not set");
         return nullptr;
     }
 
-    if (!func(cx, module, metaObject)) {
+    RootedValue modulePrivate(cx, JS::GetModulePrivate(module));
+    if (!func(cx, modulePrivate, metaObject)) {
         return nullptr;
     }
 
     module->setMetaObject(metaObject);
 
     return metaObject;
 }
--- a/js/src/builtin/ModuleObject.h
+++ b/js/src/builtin/ModuleObject.h
@@ -255,17 +255,17 @@ class ModuleObject : public NativeObject
     enum ModuleSlot
     {
         ScriptSlot = 0,
         EnvironmentSlot,
         NamespaceSlot,
         StatusSlot,
         EvaluationErrorSlot,
         MetaObjectSlot,
-        HostDefinedSlot,
+        ScriptSourceObjectSlot,
         RequestedModulesSlot,
         ImportEntriesSlot,
         LocalExportEntriesSlot,
         IndirectExportEntriesSlot,
         StarExportEntriesSlot,
         ImportBindingsSlot,
         FunctionDeclarationsSlot,
         DFSIndexSlot,
@@ -307,34 +307,32 @@ class ModuleObject : public NativeObject
     Scope* enclosingScope() const;
     ModuleEnvironmentObject& initialEnvironment() const;
     ModuleEnvironmentObject* environment() const;
     ModuleNamespaceObject* namespace_();
     ModuleStatus status() const;
     bool hadEvaluationError() const;
     Value evaluationError() const;
     JSObject* metaObject() const;
-    Value hostDefinedField() const;
+    ScriptSourceObject* scriptSourceObject() const;
     ArrayObject& requestedModules() const;
     ArrayObject& importEntries() const;
     ArrayObject& localExportEntries() const;
     ArrayObject& indirectExportEntries() const;
     ArrayObject& starExportEntries() const;
     IndirectBindingMap& importBindings();
 
     static bool Instantiate(JSContext* cx, HandleModuleObject self);
     static bool Evaluate(JSContext* cx, HandleModuleObject self);
 
     static ModuleNamespaceObject* GetOrCreateModuleNamespace(JSContext* cx,
                                                              HandleModuleObject self);
 
     void setMetaObject(JSObject* obj);
 
-    void setHostDefinedField(const JS::Value& value);
-
     // For BytecodeEmitter.
     bool noteFunctionDeclaration(JSContext* cx, HandleAtom name, HandleFunction fun);
 
     // For intrinsic_InstantiateModuleFunctionDeclarations.
     static bool instantiateFunctionDeclarations(JSContext* cx, HandleModuleObject self);
 
     // For intrinsic_ExecuteModule.
     static bool execute(JSContext* cx, HandleModuleObject self, MutableHandleValue rval);
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -2356,16 +2356,17 @@ GetPropIRGenerator::tryAttachGenericElem
     // To allow other types to attach in the non-megamorphic case we test the specific
     // matching native reciever; however, once megamorphic we can attach for any native
     if (mode_ == ICState::Mode::Megamorphic) {
         writer.guardIsNativeObject(objId);
     } else {
         NativeObject* nobj = &obj->as<NativeObject>();
         TestMatchingNativeReceiver(writer, nobj, objId);
     }
+    writer.guardIndexGreaterThanDenseInitLength(objId, indexId);
     writer.callNativeGetElementResult(objId, indexId);
     writer.typeMonitorResult();
 
     trackAttached(mode_ == ICState::Mode::Megamorphic
                   ? "GenericElementMegamorphic": "GenericElement");
     return true;
 }
 
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -217,16 +217,17 @@ extern const char* const CacheKindNames[
     _(GuardNoUnboxedExpando)              \
     _(GuardAndLoadUnboxedExpando)         \
     _(GuardAndGetIndexFromString)         \
     _(GuardAndGetNumberFromString)        \
     _(GuardAndGetIterator)                \
     _(GuardHasGetterSetter)               \
     _(GuardGroupHasUnanalyzedNewScript)   \
     _(GuardIndexIsNonNegative)            \
+    _(GuardIndexGreaterThanDenseInitLength) \
     _(GuardTagNotEqual)                   \
     _(GuardXrayExpandoShapeAndDefaultProto) \
     _(GuardFunctionPrototype)             \
     _(GuardNoAllocationMetadataBuilder)   \
     _(GuardObjectGroupNotPretenured)      \
     _(LoadStackValue)                     \
     _(LoadObject)                         \
     _(LoadProto)                          \
@@ -801,16 +802,20 @@ class MOZ_RAII CacheIRWriter : public JS
     void guardGroupHasUnanalyzedNewScript(ObjectGroup* group) {
         writeOp(CacheOp::GuardGroupHasUnanalyzedNewScript);
         addStubField(uintptr_t(group), StubField::Type::ObjectGroup);
     }
 
     void guardIndexIsNonNegative(Int32OperandId index) {
         writeOpWithOperandId(CacheOp::GuardIndexIsNonNegative, index);
     }
+    void guardIndexGreaterThanDenseInitLength(ObjOperandId obj, Int32OperandId index) {
+        writeOpWithOperandId(CacheOp::GuardIndexGreaterThanDenseInitLength, obj);
+        writeOperandId(index);
+    }
     void guardTagNotEqual(ValueTagOperandId lhs, ValueTagOperandId rhs) {
         writeOpWithOperandId(CacheOp::GuardTagNotEqual, lhs);
         writeOperandId(rhs);
     }
 
     void loadFrameCalleeResult() {
         writeOp(CacheOp::LoadFrameCalleeResult);
     }
--- a/js/src/jit/CacheIRCompiler.cpp
+++ b/js/src/jit/CacheIRCompiler.cpp
@@ -2816,16 +2816,42 @@ CacheIRCompiler::emitGuardIndexIsNonNega
         return false;
     }
 
     masm.branch32(Assembler::LessThan, index, Imm32(0), failure->label());
     return true;
 }
 
 bool
+CacheIRCompiler::emitGuardIndexGreaterThanDenseInitLength()
+{
+    Register obj = allocator.useRegister(masm, reader.objOperandId());
+    Register index = allocator.useRegister(masm, reader.int32OperandId());
+    AutoScratchRegister scratch(allocator, masm);
+    AutoScratchRegister scratch2(allocator, masm);
+
+    FailurePath* failure;
+    if (!addFailurePath(&failure)) {
+        return false;
+    }
+
+    // Load obj->elements.
+    masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch);
+
+    // Ensure index >= capacity.
+    Label outOfBounds;
+    Address capacity(scratch, ObjectElements::offsetOfInitializedLength());
+    masm.spectreBoundsCheck32(index, capacity, scratch2, &outOfBounds);
+    masm.jump(failure->label());
+    masm.bind(&outOfBounds);
+
+    return true;
+}
+
+bool
 CacheIRCompiler::emitGuardTagNotEqual()
 {
     Register lhs = allocator.useRegister(masm, reader.valueTagOperandId());
     Register rhs = allocator.useRegister(masm, reader.valueTagOperandId());
 
     FailurePath* failure;
     if (!addFailurePath(&failure)) {
         return false;
--- a/js/src/jit/CacheIRCompiler.h
+++ b/js/src/jit/CacheIRCompiler.h
@@ -41,16 +41,17 @@ namespace jit {
     _(GuardMagicValue)                    \
     _(GuardNoUnboxedExpando)              \
     _(GuardAndLoadUnboxedExpando)         \
     _(GuardNoDetachedTypedObjects)        \
     _(GuardNoDenseElements)               \
     _(GuardAndGetNumberFromString)        \
     _(GuardAndGetIndexFromString)         \
     _(GuardIndexIsNonNegative)            \
+    _(GuardIndexGreaterThanDenseInitLength) \
     _(GuardTagNotEqual)                   \
     _(GuardXrayExpandoShapeAndDefaultProto)\
     _(GuardNoAllocationMetadataBuilder)   \
     _(GuardObjectGroupNotPretenured)      \
     _(LoadObject)                         \
     _(LoadProto)                          \
     _(LoadEnclosingEnvironment)           \
     _(LoadWrapperTarget)                  \
--- a/js/src/jit/CacheIRSpewer.cpp
+++ b/js/src/jit/CacheIRSpewer.cpp
@@ -151,30 +151,39 @@ CacheIRSpewer::valueProperty(const char*
         JSString* str = v.isString() ? v.toString() : v.toSymbol()->description();
         if (str && str->isLinear()) {
             j.beginStringProperty("value");
             QuoteString(output, &str->asLinear());
             j.endStringProperty();
         }
     } else if (v.isObject()) {
         JSObject& object = v.toObject();
-        bool indexed = object.isNative() && object.as<NativeObject>().isIndexed();
-        j.formatProperty("value", "%p (shape: %p)%s", &object, object.maybeShape(),
-                         indexed ? " indexed" : "");
-        if (indexed) {
-            NativeObject& native = object.as<NativeObject>();
-            j.beginObjectProperty("indexed");
+        j.formatProperty("value", "%p (shape: %p)", &object, object.maybeShape());
+        if (NativeObject* nobj = object.isNative() ? &object.as<NativeObject>() : nullptr) {
+            j.beginListProperty("flags");
             {
-                j.property("denseInitializedLength",native.getDenseInitializedLength());
-                j.property("denseCapacity",native.getDenseCapacity());
-                j.property("denseElementsAreSealed", native.denseElementsAreSealed());
-                j.property("denseElementsAreCopyOnWrite", native.denseElementsAreCopyOnWrite());
-                j.property("denseElementsAreFrozen", native.denseElementsAreFrozen());
+                if (nobj->isIndexed()) {
+                    j.value("indexed");
+                }
+                if (nobj->inDictionaryMode()) {
+                    j.value("dictionaryMode");
+                }
             }
-            j.endObject();
+            j.endList();
+            if (nobj->isIndexed()) {
+                j.beginObjectProperty("indexed");
+                {
+                    j.property("denseInitializedLength", nobj->getDenseInitializedLength());
+                    j.property("denseCapacity", nobj->getDenseCapacity());
+                    j.property("denseElementsAreSealed", nobj->denseElementsAreSealed());
+                    j.property("denseElementsAreCopyOnWrite", nobj->denseElementsAreCopyOnWrite());
+                    j.property("denseElementsAreFrozen", nobj->denseElementsAreFrozen());
+                }
+                j.endObject();
+            }
         }
     }
 
     j.endObject();
 }
 
 void
 CacheIRSpewer::opcodeProperty(const char* name, const JSOp op)
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4147,25 +4147,37 @@ JS::CompileModule(JSContext* cx, const R
     AssertHeapIsIdle();
     CHECK_THREAD(cx);
 
     module.set(frontend::CompileModule(cx, options, srcBuf));
     return !!module;
 }
 
 JS_PUBLIC_API(void)
-JS::SetModuleHostDefinedField(JSObject* module, const JS::Value& value)
-{
-    module->as<ModuleObject>().setHostDefinedField(value);
+JS::SetModulePrivate(JSObject* module, const JS::Value& value)
+{
+    module->as<ModuleObject>().scriptSourceObject()->setPrivate(value);
 }
 
 JS_PUBLIC_API(JS::Value)
-JS::GetModuleHostDefinedField(JSObject* module)
-{
-    return module->as<ModuleObject>().hostDefinedField();
+JS::GetModulePrivate(JSObject* module)
+{
+    return module->as<ModuleObject>().scriptSourceObject()->getPrivate();
+}
+
+JS_PUBLIC_API(void)
+JS::SetScriptPrivate(JSScript* script, const JS::Value& value)
+{
+    script->scriptSourceUnwrap().setPrivate(value);
+}
+
+JS_PUBLIC_API(JS::Value)
+JS::GetScriptPrivate(JSScript* script)
+{
+    return script->scriptSourceUnwrap().getPrivate();
 }
 
 JS_PUBLIC_API(bool)
 JS::ModuleInstantiate(JSContext* cx, JS::HandleObject moduleArg)
 {
     AssertHeapIsIdle();
     CHECK_THREAD(cx);
     cx->check(moduleArg);
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3016,31 +3016,31 @@ extern JS_PUBLIC_API(JSString*)
 JS_DecompileScript(JSContext* cx, JS::Handle<JSScript*> script);
 
 extern JS_PUBLIC_API(JSString*)
 JS_DecompileFunction(JSContext* cx, JS::Handle<JSFunction*> fun);
 
 
 namespace JS {
 
-using ModuleResolveHook = JSObject* (*)(JSContext*, HandleObject, HandleString);
+using ModuleResolveHook = JSObject* (*)(JSContext*, HandleValue, HandleString);
 
 /**
  * Get the HostResolveImportedModule hook for the runtime.
  */
 extern JS_PUBLIC_API(ModuleResolveHook)
 GetModuleResolveHook(JSRuntime* rt);
 
 /**
  * Set the HostResolveImportedModule hook for the runtime to the given function.
  */
 extern JS_PUBLIC_API(void)
 SetModuleResolveHook(JSRuntime* rt, ModuleResolveHook func);
 
-using ModuleMetadataHook = bool (*)(JSContext*, HandleObject, HandleObject);
+using ModuleMetadataHook = bool (*)(JSContext*, HandleValue, HandleObject);
 
 /**
  * Get the hook for populating the import.meta metadata object.
  */
 extern JS_PUBLIC_API(ModuleMetadataHook)
 GetModuleMetadataHook(JSRuntime* rt);
 
 /**
@@ -3054,27 +3054,40 @@ SetModuleMetadataHook(JSRuntime* rt, Mod
  * Parse the given source buffer as a module in the scope of the current global
  * of cx and return a source text module record.
  */
 extern JS_PUBLIC_API(bool)
 CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
               SourceBufferHolder& srcBuf, JS::MutableHandleObject moduleRecord);
 
 /**
- * Set the [[HostDefined]] field of a source text module record to the given
- * value.
+ * Set a private value associated with a source text module record.
  */
 extern JS_PUBLIC_API(void)
-SetModuleHostDefinedField(JSObject* module, const JS::Value& value);
+SetModulePrivate(JSObject* module, const JS::Value& value);
+
+/**
+ * Get the private value associated with a source text module record.
+ */
+extern JS_PUBLIC_API(JS::Value)
+GetModulePrivate(JSObject* module);
 
 /**
- * Get the [[HostDefined]] field of a source text module record.
+ * Set a private value associated with a script. Note that this value is shared
+ * by all nested scripts compiled from a single source file.
+ */
+extern JS_PUBLIC_API(void)
+SetScriptPrivate(JSScript* script, const JS::Value& value);
+
+/**
+ * Get the private value associated with a script. Note that this value is
+ * shared by all nested scripts compiled from a single source file.
  */
 extern JS_PUBLIC_API(JS::Value)
-GetModuleHostDefinedField(JSObject* module);
+GetScriptPrivate(JSScript* script);
 
 /*
  * Perform the ModuleInstantiate operation on the given source text module
  * record.
  *
  * This transitively resolves all module dependencies (calling the
  * HostResolveImportedModule hook) and initializes the environment record for
  * the module.
--- a/js/src/shell/ModuleLoader.js
+++ b/js/src/shell/ModuleLoader.js
@@ -1,66 +1,71 @@
 /* -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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/. */
 
 /* global getModuleLoadPath setModuleLoadHook setModuleResolveHook setModuleMetadataHook */
-/* global parseModule os */
+/* global getModulePrivate setModulePrivate parseModule os */
 
 // A basic synchronous module loader for testing the shell.
 {
 // Save standard built-ins before scripts can modify them.
 const ArrayPrototypeJoin = Array.prototype.join;
 const MapPrototypeGet = Map.prototype.get;
 const MapPrototypeHas = Map.prototype.has;
 const MapPrototypeSet = Map.prototype.set;
 const ObjectDefineProperty = Object.defineProperty;
 const ReflectApply = Reflect.apply;
 const StringPrototypeIndexOf = String.prototype.indexOf;
 const StringPrototypeLastIndexOf = String.prototype.lastIndexOf;
 const StringPrototypeStartsWith = String.prototype.startsWith;
 const StringPrototypeSubstring = String.prototype.substring;
+const ErrorClass = Error;
 
 const ReflectLoader = new class {
     constructor() {
         this.registry = new Map();
         this.modulePaths = new Map();
         this.loadPath = getModuleLoadPath();
     }
 
-    resolve(name, module) {
+    resolve(name, referencingInfo) {
         if (os.path.isAbsolute(name))
             return name;
 
         let loadPath = this.loadPath;
-        if (module) {
-            // Treat |name| as a relative path if it starts with either "./"
-            // or "../".
-            let isRelative = ReflectApply(StringPrototypeStartsWith, name, ["./"])
-                          || ReflectApply(StringPrototypeStartsWith, name, ["../"])
+
+        // Treat |name| as a relative path if it starts with either "./"
+        // or "../".
+        let isRelative = ReflectApply(StringPrototypeStartsWith, name, ["./"])
+                      || ReflectApply(StringPrototypeStartsWith, name, ["../"])
 #ifdef XP_WIN
-                          || ReflectApply(StringPrototypeStartsWith, name, [".\\"])
-                          || ReflectApply(StringPrototypeStartsWith, name, ["..\\"])
+                      || ReflectApply(StringPrototypeStartsWith, name, [".\\"])
+                      || ReflectApply(StringPrototypeStartsWith, name, ["..\\"])
 #endif
-                             ;
+                         ;
 
-            // If |name| is a relative path and |module|'s path is available,
-            // load |name| relative to the referring module.
-            if (isRelative && ReflectApply(MapPrototypeHas, this.modulePaths, [module])) {
-                let modulePath = ReflectApply(MapPrototypeGet, this.modulePaths, [module]);
-                let sepIndex = ReflectApply(StringPrototypeLastIndexOf, modulePath, ["/"]);
+        // If |name| is a relative path and the referencing module's path is
+        // available, load |name| relative to the that path.
+        if (isRelative) {
+            if (!referencingInfo) {
+                throw new ErrorClass("No referencing module for relative import");
+            }
+
+            let path = referencingInfo.path;
+
+            let sepIndex = ReflectApply(StringPrototypeLastIndexOf, path, ["/"]);
 #ifdef XP_WIN
-                let otherSepIndex = ReflectApply(StringPrototypeLastIndexOf, modulePath, ["\\"]);
-                if (otherSepIndex > sepIndex)
-                    sepIndex = otherSepIndex;
+            let otherSepIndex = ReflectApply(StringPrototypeLastIndexOf, path, ["\\"]);
+            if (otherSepIndex > sepIndex)
+                sepIndex = otherSepIndex;
 #endif
-                if (sepIndex >= 0)
-                    loadPath = ReflectApply(StringPrototypeSubstring, modulePath, [0, sepIndex]);
-            }
+            if (sepIndex >= 0)
+                loadPath = ReflectApply(StringPrototypeSubstring, path, [0, sepIndex]);
         }
 
         return os.path.join(loadPath, name);
     }
 
     normalize(path) {
 #ifdef XP_WIN
         // Replace all forward slashes with backward slashes.
@@ -150,18 +155,19 @@ const ReflectLoader = new class {
 
     loadAndParse(path) {
         let normalized = this.normalize(path);
         if (ReflectApply(MapPrototypeHas, this.registry, [normalized]))
             return ReflectApply(MapPrototypeGet, this.registry, [normalized]);
 
         let source = this.fetch(path);
         let module = parseModule(source, path);
+        let moduleInfo = { path: normalized };
+        setModulePrivate(module, moduleInfo);
         ReflectApply(MapPrototypeSet, this.registry, [normalized, module]);
-        ReflectApply(MapPrototypeSet, this.modulePaths, [module, path]);
         return module;
     }
 
     loadAndExecute(path) {
         let module = this.loadAndParse(path);
         module.declarationInstantiation();
         return module.evaluation();
     }
@@ -170,22 +176,22 @@ const ReflectLoader = new class {
         return this.loadAndExecute(path);
     }
 
     ["import"](name, referrer) {
         let path = this.resolve(name, null);
         return this.loadAndExecute(path);
     }
 
-    populateImportMeta(module, metaObject) {
-        // For the shell, use the script's filename as the base URL.
+    populateImportMeta(moduleInfo, metaObject) {
+        // For the shell, use the module's normalized path as the base URL.
 
         let path;
-        if (ReflectApply(MapPrototypeHas, this.modulePaths, [module])) {
-            path = ReflectApply(MapPrototypeGet, this.modulePaths, [module]);
+        if (moduleInfo) {
+            path = moduleInfo.path;
         } else {
             path = "(unknown)";
         }
         metaObject.url = path;
     }
 };
 
 setModuleLoadHook((path) => ReflectLoader.importRoot(path));
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -4718,28 +4718,28 @@ SetModuleResolveHook(JSContext* cx, unsi
     Handle<GlobalObject*> global = cx->global();
     global->setReservedSlot(GlobalAppSlotModuleResolveHook, args[0]);
 
     args.rval().setUndefined();
     return true;
 }
 
 static JSObject*
-CallModuleResolveHook(JSContext* cx, HandleObject module, HandleString specifier)
+CallModuleResolveHook(JSContext* cx, HandleValue referencingPrivate, HandleString specifier)
 {
     Handle<GlobalObject*> global = cx->global();
     RootedValue hookValue(cx, global->getReservedSlot(GlobalAppSlotModuleResolveHook));
     if (hookValue.isUndefined()) {
         JS_ReportErrorASCII(cx, "Module resolve hook not set");
         return nullptr;
     }
     MOZ_ASSERT(hookValue.toObject().is<JSFunction>());
 
     JS::AutoValueArray<2> args(cx);
-    args[0].setObject(*module);
+    args[0].set(referencingPrivate);
     args[1].setString(specifier);
 
     RootedValue result(cx);
     if (!JS_CallFunctionValue(cx, nullptr, hookValue, args, &result)) {
         return nullptr;
     }
 
     if (!result.isObject() || !result.toObject().is<ModuleObject>()) {
@@ -4769,35 +4769,82 @@ SetModuleMetadataHook(JSContext* cx, uns
     Handle<GlobalObject*> global = cx->global();
     global->setReservedSlot(GlobalAppSlotModuleMetadataHook, args[0]);
 
     args.rval().setUndefined();
     return true;
 }
 
 static bool
-CallModuleMetadataHook(JSContext* cx, HandleObject module, HandleObject metaObject)
+CallModuleMetadataHook(JSContext* cx, HandleValue modulePrivate, HandleObject metaObject)
 {
     Handle<GlobalObject*> global = cx->global();
     RootedValue hookValue(cx, global->getReservedSlot(GlobalAppSlotModuleMetadataHook));
     if (hookValue.isUndefined()) {
         JS_ReportErrorASCII(cx, "Module metadata hook not set");
         return false;
     }
     MOZ_ASSERT(hookValue.toObject().is<JSFunction>());
 
     JS::AutoValueArray<2> args(cx);
-    args[0].setObject(*module);
+    args[0].set(modulePrivate);
     args[1].setObject(*metaObject);
 
     RootedValue dummy(cx);
     return JS_CallFunctionValue(cx, nullptr, hookValue, args, &dummy);
 }
 
 static bool
+ReportArgumentTypeError(JSContext* cx, HandleValue value, const char* expected)
+{
+    const char* typeName = InformalValueTypeName(value);
+    JS_ReportErrorASCII(cx, "Expected %s, got %s", expected, typeName);
+    return false;
+}
+
+static bool
+ShellSetModulePrivate(JSContext* cx, unsigned argc, Value* vp)
+{
+    CallArgs args = CallArgsFromVp(argc, vp);
+
+    if (args.length() != 2) {
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
+                                  "setModulePrivate", "0", "s");
+        return false;
+    }
+
+    if (!args[0].isObject() || !args[0].toObject().is<ModuleObject>()) {
+        return ReportArgumentTypeError(cx, args[0], "module object");
+    }
+
+    JS::SetModulePrivate(&args[0].toObject(), args[1]);
+    args.rval().setUndefined();
+    return true;
+}
+
+static bool
+ShellGetModulePrivate(JSContext* cx, unsigned argc, Value* vp)
+{
+    CallArgs args = CallArgsFromVp(argc, vp);
+
+    if (args.length() != 1) {
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
+                                  "getModulePrivate", "0", "s");
+        return false;
+    }
+
+    if (!args[0].isObject() || !args[0].toObject().is<ModuleObject>()) {
+        return ReportArgumentTypeError(cx, args[0], "module object");
+    }
+
+    args.rval().set(JS::GetModulePrivate(&args[0].toObject()));
+    return true;
+}
+
+static bool
 GetModuleLoadPath(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     ShellContext* sc = GetShellContext(cx);
     if (sc->moduleLoadPath) {
         JSString* str = JS_NewStringCopyZ(cx, sc->moduleLoadPath.get());
         if (!str) {
@@ -8006,16 +8053,24 @@ static const JSFunctionSpecWithHelp shel
 "  be implemented by the module loader."),
 
     JS_FN_HELP("setModuleMetadataHook", SetModuleMetadataHook, 1, 0,
 "setModuleMetadataHook(function(module) {})",
 "  Set the HostPopulateImportMeta hook to |function|.\n"
 "  This hook is used to create the metadata object returned by import.meta for\n"
 "  a module.  It should be implemented by the module loader."),
 
+    JS_FN_HELP("setModulePrivate", ShellSetModulePrivate, 2, 0,
+"setModulePrivate(scriptObject, privateValue)",
+"  Associate a private value with a module object.\n"),
+
+    JS_FN_HELP("getModulePrivate", ShellGetModulePrivate, 2, 0,
+"getModulePrivate(scriptObject)",
+"  Get the private value associated with a module object.\n"),
+
     JS_FN_HELP("getModuleLoadPath", GetModuleLoadPath, 0, 0,
 "getModuleLoadPath()",
 "  Return any --module-load-path argument passed to the shell.  Used by the\n"
 "  module loader.\n"),
 
 #if defined(JS_BUILD_BINAST)
 
 JS_FN_HELP("parseBin", BinParse, 1, 0,
--- a/js/src/vm/JSScript.h
+++ b/js/src/vm/JSScript.h
@@ -1216,22 +1216,32 @@ class ScriptSourceObject : public Native
     JSScript* introductionScript() const {
         Value value = getReservedSlot(INTRODUCTION_SCRIPT_SLOT);
         if (value.isUndefined()) {
             return nullptr;
         }
         return value.toGCThing()->as<JSScript>();
     }
 
+    void setPrivate(const Value& value) {
+        setReservedSlot(PRIVATE_SLOT, value);
+    }
+    Value getPrivate() const {
+        return getReservedSlot(PRIVATE_SLOT);
+    }
+
   private:
-    static const uint32_t SOURCE_SLOT = 0;
-    static const uint32_t ELEMENT_SLOT = 1;
-    static const uint32_t ELEMENT_PROPERTY_SLOT = 2;
-    static const uint32_t INTRODUCTION_SCRIPT_SLOT = 3;
-    static const uint32_t RESERVED_SLOTS = 4;
+    enum {
+        SOURCE_SLOT = 0,
+        ELEMENT_SLOT,
+        ELEMENT_PROPERTY_SLOT,
+        INTRODUCTION_SCRIPT_SLOT,
+        PRIVATE_SLOT,
+        RESERVED_SLOTS
+    };
 };
 
 enum class GeneratorKind : bool { NotGenerator, Generator };
 enum class FunctionAsyncKind : bool { SyncFunction, AsyncFunction };
 
 /*
  * NB: after a successful XDR_DECODE, XDRScript callers must do any required
  * subsequent set-up of owning function or script object and then call
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -2185,17 +2185,18 @@ intrinsic_HostResolveImportedModule(JSCo
 
     JS::ModuleResolveHook moduleResolveHook = cx->runtime()->moduleResolveHook;
     if (!moduleResolveHook) {
         JS_ReportErrorASCII(cx, "Module resolve hook not set");
         return false;
     }
 
     RootedObject result(cx);
-    result = moduleResolveHook(cx, module, specifier);
+    RootedValue referencingPrivate(cx, JS::GetModulePrivate(module));
+    result = moduleResolveHook(cx, referencingPrivate, specifier);
     if (!result) {
         return false;
     }
 
     if (!result->is<ModuleObject>()) {
         JS_ReportErrorASCII(cx, "Module resolve hook did not return Module object");
         return false;
     }
--- a/layout/svg/nsSVGImageFrame.cpp
+++ b/layout/svg/nsSVGImageFrame.cpp
@@ -564,17 +564,22 @@ nsSVGImageListener::Notify(imgIRequest *
     nsLayoutUtils::PostRestyleEvent(
       mFrame->GetContent()->AsElement(), nsRestyleHint(0),
       nsChangeHint_InvalidateRenderingObservers);
     mFrame->InvalidateFrame();
   }
 
   if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
     // Called once the resource's dimensions have been obtained.
-    aRequest->GetImage(getter_AddRefs(mFrame->mImageContainer));
+    nsCOMPtr<imgIContainer> image;
+    aRequest->GetImage(getter_AddRefs(image));
+    if (image) {
+      image->SetAnimationMode(mFrame->PresContext()->ImageAnimationMode());
+      mFrame->mImageContainer = image.forget();
+    }
     mFrame->InvalidateFrame();
     nsLayoutUtils::PostRestyleEvent(
       mFrame->GetContent()->AsElement(), nsRestyleHint(0),
       nsChangeHint_InvalidateRenderingObservers);
     nsSVGUtils::ScheduleReflowSVG(mFrame);
   }
 
   return NS_OK;
--- a/layout/xul/nsImageBoxFrame.cpp
+++ b/layout/xul/nsImageBoxFrame.cpp
@@ -846,16 +846,18 @@ nsImageBoxFrame::OnSizeAvailable(imgIReq
 {
   NS_ENSURE_ARG_POINTER(aImage);
 
   // Ensure the animation (if any) is started. Note: There is no
   // corresponding call to Decrement for this. This Increment will be
   // 'cleaned up' by the Request when it is destroyed, but only then.
   aRequest->IncrementAnimationConsumers();
 
+  aImage->SetAnimationMode(PresContext()->ImageAnimationMode());
+
   nscoord w, h;
   aImage->GetWidth(&w);
   aImage->GetHeight(&h);
 
   mIntrinsicSize.SizeTo(nsPresContext::CSSPixelsToAppUnits(w),
                         nsPresContext::CSSPixelsToAppUnits(h));
 
   if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
--- a/layout/xul/tree/nsTreeImageListener.cpp
+++ b/layout/xul/tree/nsTreeImageListener.cpp
@@ -32,16 +32,25 @@ nsTreeImageListener::Notify(imgIRequest 
     return mTreeFrame ? mTreeFrame->OnImageIsAnimated(aRequest) : NS_OK;
   }
 
   if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
     // Ensure the animation (if any) is started. Note: There is no
     // corresponding call to Decrement for this. This Increment will be
     // 'cleaned up' by the Request when it is destroyed, but only then.
     aRequest->IncrementAnimationConsumers();
+
+    if (mTreeFrame) {
+      nsCOMPtr<imgIContainer> image;
+      aRequest->GetImage(getter_AddRefs(image));
+      if (image) {
+        nsPresContext* presContext = mTreeFrame->PresContext();
+        image->SetAnimationMode(presContext->ImageAnimationMode());
+      }
+    }
   }
 
   if (aType == imgINotificationObserver::FRAME_UPDATE) {
     Invalidate();
   }
 
   return NS_OK;
 }
deleted file mode 100644
--- a/security/sandbox/chromium-shim/patches/with_update/mingw_noexports_casts.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-# HG changeset patch
-# User Tom Ritter <tom@mozilla.com>
-# Date 1526498300 18000
-#      Wed May 16 14:18:20 2018 -0500
-# Node ID dd3f4940aeb0c4e00e8bcf1c238f2355ad793489
-# Parent  cf646c80b9545db7ab548f88a482378734ee2f78
-Bug 1462100 Cast to void* to avoid conversion errors on MinGW, which does not do the automatic conversion like msvc r?bobowen
-
-MozReview-Commit-ID: 8fO9Nu9gaxh
-
-diff --git a/security/sandbox/chromium/sandbox/win/src/interception.h b/security/sandbox/chromium/sandbox/win/src/interception.h
---- a/security/sandbox/chromium/sandbox/win/src/interception.h
-+++ b/security/sandbox/chromium/sandbox/win/src/interception.h
-@@ -264,25 +264,25 @@ class InterceptionManager {
- #define MAKE_SERVICE_NAME(service) &Target##service##64
- #else
- #define MAKE_SERVICE_NAME(service) &Target##service
- #endif
- 
- #define ADD_NT_INTERCEPTION(service, id, num_params) \
-   AddToPatchedFunctions(kNtdllName, #service, \
-                         sandbox::INTERCEPTION_SERVICE_CALL, \
--                        MAKE_SERVICE_NAME(service), id)
-+                        (void*)MAKE_SERVICE_NAME(service), id)
- 
- #define INTERCEPT_NT(manager, service, id, num_params) \
-   manager->ADD_NT_INTERCEPTION(service, id, num_params)
- 
- // When intercepting the EAT it is important that the patched version of the
- // function not call any functions imported from system libraries unless
- // |TargetServices::InitCalled()| returns true, because it is only then that
- // we are guaranteed that our IAT has been initialized.
- #define INTERCEPT_EAT(manager, dll, function, id, num_params) \
-   manager->AddToPatchedFunctions(dll, #function, sandbox::INTERCEPTION_EAT, \
--                                 MAKE_SERVICE_NAME(function), id)
-+                                 (void*)MAKE_SERVICE_NAME(function), id)
- #endif  // SANDBOX_EXPORTS
- 
- }  // namespace sandbox
- 
- #endif  // SANDBOX_SRC_INTERCEPTION_H_
--- a/security/sandbox/chromium-shim/patches/with_update/patch_order.txt
+++ b/security/sandbox/chromium-shim/patches/with_update/patch_order.txt
@@ -12,10 +12,9 @@ fix_Wcomma_warning_in_time_cc.patch
 allow_read_only_all_paths_rule.patch
 revert_TargetNtSetInformationThread_change.patch
 mingw_base_win_get_caller.patch
 mingw_duplicate_instatinations.patch
 mingw_copy_s.patch
 mingw_operator_new.patch
 mingw_cast_getprocaddress.patch
 mingw_capitalization.patch
-mingw_noexports_casts.patch
 mingw_offsetof.patch
--- a/security/sandbox/chromium/sandbox/win/src/interception.h
+++ b/security/sandbox/chromium/sandbox/win/src/interception.h
@@ -264,25 +264,25 @@ class InterceptionManager {
 #define MAKE_SERVICE_NAME(service) &Target##service##64
 #else
 #define MAKE_SERVICE_NAME(service) &Target##service
 #endif
 
 #define ADD_NT_INTERCEPTION(service, id, num_params) \
   AddToPatchedFunctions(kNtdllName, #service, \
                         sandbox::INTERCEPTION_SERVICE_CALL, \
-                        (void*)MAKE_SERVICE_NAME(service), id)
+                        MAKE_SERVICE_NAME(service), id)
 
 #define INTERCEPT_NT(manager, service, id, num_params) \
   manager->ADD_NT_INTERCEPTION(service, id, num_params)
 
 // When intercepting the EAT it is important that the patched version of the
 // function not call any functions imported from system libraries unless
 // |TargetServices::InitCalled()| returns true, because it is only then that
 // we are guaranteed that our IAT has been initialized.
 #define INTERCEPT_EAT(manager, dll, function, id, num_params) \
   manager->AddToPatchedFunctions(dll, #function, sandbox::INTERCEPTION_EAT, \
-                                 (void*)MAKE_SERVICE_NAME(function), id)
+                                 MAKE_SERVICE_NAME(function), id)
 #endif  // SANDBOX_EXPORTS
 
 }  // namespace sandbox
 
 #endif  // SANDBOX_SRC_INTERCEPTION_H_
--- a/testing/mochitest/tests/SimpleTest/EventUtils.js
+++ b/testing/mochitest/tests/SimpleTest/EventUtils.js
@@ -2330,18 +2330,16 @@ function synthesizeDropAfterDragOver(aRe
   if (aResult) {
     effect = "none";
   } else if (effect != "none") {
     event = createDragEventObject("drop", aDestElement, aDestWindow,
                                   aDataTransfer, aDragEvent);
     sendDragEvent(event, aDestElement, aDestWindow);
   }
 
-  synthesizeMouseAtCenter(aDestElement, { type: "mouseup" }, aDestWindow);
-
   return effect;
 }
 
 /**
  * Emulate a drag and drop by emulating a dragstart and firing events dragenter,
  * dragover, and drop.
  *
  * @param aSrcElement   The element to use to start the drag.
@@ -2460,17 +2458,16 @@ async function synthesizePlainDragAndDro
     await new Promise(r => setTimeout(r, 0));
 
     event = createDragEventObject("drop", destElement, destWindow,
                                   dataTransfer, {});
     sendDragEvent(event, destElement, destWindow);
 
     await new Promise(r => setTimeout(r, 0));
 
-    synthesizeMouseAtCenter(destElement, { type: "mouseup" }, destWindow);
   } finally {
     ds.endDragSession(true, 0);
   }
 }
 
 var PluginUtils =
 {
   withTestPlugin : function(callback)
--- a/testing/web-platform/tests/webdriver/tests/element_clear/clear.py
+++ b/testing/web-platform/tests/webdriver/tests/element_clear/clear.py
@@ -1,11 +1,12 @@
 # META: timeout=long
 
 import pytest
+import time
 
 from webdriver import Element
 
 from tests.support.asserts import (
     assert_element_has_focus,
     assert_error,
     assert_events_equal,
     assert_in_events,
@@ -42,17 +43,17 @@ def test_null_response_value(session):
     element = session.find.css("input", all=False)
 
     response = element_clear(session, element)
     value = assert_success(response)
     assert value is None
 
 
 def test_no_browsing_context(session, closed_window):
-    element = Element("foo", session)
+    element = Element("foo" + str(time.time()), session)
 
     response = element_clear(session, element)
     assert_error(response, "no such window")
 
 
 def test_connected_element(session):
     session.url = inline("<input>")
     element = session.find.css("input", all=False)
--- a/toolkit/components/printing/content/printProgress.js
+++ b/toolkit/components/printing/content/printProgress.js
@@ -41,29 +41,27 @@ function ellipseString(aStr, doFront) {
   return aStr;
 }
 
 // all progress notifications are done through the nsIWebProgressListener implementation...
 var progressListener = {
     onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
       if (aStateFlags & Ci.nsIWebProgressListener.STATE_START) {
         // Put progress meter in undetermined mode.
-        // dialog.progress.setAttribute( "value", 0 );
-        dialog.progress.setAttribute( "mode", "undetermined" );
+        dialog.progress.removeAttribute("value");
       }
 
       if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
         // we are done printing
         // Indicate completion in title area.
         var msg = getString( "printComplete" );
         dialog.title.setAttribute("value", msg);
 
         // Put progress meter at 100%.
         dialog.progress.setAttribute( "value", 100 );
-        dialog.progress.setAttribute( "mode", "normal" );
         var percentPrint = getString( "progressText" );
         percentPrint = replaceInsert( percentPrint, 1, 100 );
         dialog.progressText.setAttribute("value", percentPrint);
 
         if (Services.focus.activeWindow == window) {
           // This progress dialog is the currently active window. In
           // this case we need to make sure that some other window
           // gets focus before we close this dialog to work around the
@@ -82,17 +80,17 @@ var progressListener = {
 
         window.close();
       }
     },
 
     onProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) {
       if (switchUI) {
         dialog.tempLabel.setAttribute("hidden", "true");
-        dialog.progress.setAttribute("hidden", "false");
+        dialog.progressBox.removeAttribute("hidden");
 
         var progressLabel = getString("progress");
         if (progressLabel == "") {
           progressLabel = "Progress:"; // better than nothing
         }
         switchUI = false;
       }
 
@@ -113,28 +111,26 @@ var progressListener = {
 
       // Calculate percentage.
       var percent;
       if ( aMaxTotalProgress > 0 ) {
         percent = Math.round( (aCurTotalProgress * 100) / aMaxTotalProgress );
         if ( percent > 100 )
           percent = 100;
 
-        dialog.progress.removeAttribute( "mode");
-
         // Advance progress meter.
         dialog.progress.setAttribute( "value", percent );
 
         // Update percentage label on progress meter.
         var percentPrint = getString( "progressText" );
         percentPrint = replaceInsert( percentPrint, 1, percent );
         dialog.progressText.setAttribute("value", percentPrint);
       } else {
         // Progress meter should be barber-pole in this case.
-        dialog.progress.setAttribute( "mode", "undetermined" );
+        dialog.progress.removeAttribute("value");
         // Update percentage label on progress meter.
         dialog.progressText.setAttribute("value", "");
       }
     },
 
     onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {
       // we can ignore this notification
     },
@@ -204,21 +200,22 @@ function onLoad() {
         return;
     }
 
     dialog = {};
     dialog.strings = [];
     dialog.title        = document.getElementById("dialog.title");
     dialog.titleLabel   = document.getElementById("dialog.titleLabel");
     dialog.progress     = document.getElementById("dialog.progress");
+    dialog.progressBox     = document.getElementById("dialog.progressBox");
     dialog.progressText = document.getElementById("dialog.progressText");
     dialog.progressLabel = document.getElementById("dialog.progressLabel");
     dialog.tempLabel    = document.getElementById("dialog.tempLabel");
 
-    dialog.progress.setAttribute("hidden", "true");
+    dialog.progressBox.setAttribute("hidden", "true");
 
     var progressLabel = getString("preparing");
     if (progressLabel == "") {
       progressLabel = "Preparing..."; // better than nothing
     }
     dialog.tempLabel.value = progressLabel;
 
     dialog.title.value = docTitle;
--- a/toolkit/components/printing/content/printProgress.xul
+++ b/toolkit/components/printing/content/printProgress.xul
@@ -4,16 +4,17 @@
    - 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/. -->
 
 <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
 
 <!DOCTYPE window SYSTEM "chrome://global/locale/printProgress.dtd">
 
 <dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        xmlns:html="http://www.w3.org/1999/xhtml"
         buttons="cancel"
         title="&printWindow.title;"
         style="width: 36em;"
         ondialogcancel="onCancel()"
         onload="onLoad()"
         onunload="onUnload()">
 
   <script type="application/javascript" src="chrome://global/content/printProgress.js"/>
@@ -42,19 +43,22 @@
         <row>
           <hbox pack="end">
             <label id="dialog.titleLabel" value="&title;"/>
           </hbox>
             <label id="dialog.title"/>
         </row>
         <row class="thin-separator">             
           <hbox pack="end">
-            <label id="dialog.progressLabel" control="dialog.progress" value="&progress;"/>
+            <html:label id="dialog.progressLabel" for="dialog.progress"
+                        style="margin-right: 1em;">&progress;</html:label>
           </hbox>
-            <label id="dialog.tempLabel" value="&preparing;"/>
-            <progressmeter id="dialog.progress" mode="normal" value="0"/>
+          <label id="dialog.tempLabel" value="&preparing;"/>
+          <vbox pack="center" id="dialog.progressBox">
+            <html:progress id="dialog.progress" value="0" max="100"></html:progress>
+          </vbox>
           <hbox pack="end" style="min-width: 2.5em;">
             <label id="dialog.progressText"/>
           </hbox>
         </row>
       </rows>
     </grid>
 </dialog>
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -14146,10 +14146,21 @@
     ],
     "expires_in_version": "69",
     "kind": "linear",
     "high": 60,
     "n_buckets": 10,
     "bug_numbers": [1490074],
     "description": "How long the AudioContext would become audible since it was created, time unit is seconds.",
     "releaseChannelCollection": "opt-out"
+  },
+  "QM_REPOSITORIES_INITIALIZATION_TIME": {
+    "record_in_processes": ["main"],
+    "expires_in_version": "68",
+    "bug_numbers": [1481716],
+    "kind": "exponential",
+    "high": 30000,
+    "n_buckets": 30,
+    "releaseChannelCollection": "opt-out",
+    "alert_emails": ["ttung@mozilla.com"],
+    "description": "Time (ms) for the QuotaManager to initialize repositories."
   }
 }
--- a/toolkit/content/widgets/progressmeter.js
+++ b/toolkit/content/widgets/progressmeter.js
@@ -70,87 +70,36 @@ class MozProgressmeter extends MozXULEle
 
   connectedCallback() {
     if (this.delayConnectedCallback()) {
       return;
     }
     this._initUI();
   }
 
-  disconnectedCallback() {
-    this.runAnimation = false;
-  }
-
   static get observedAttributes() {
     return [ "mode" ];
   }
 
   attributeChangedCallback(name, oldValue, newValue) {
     if (!this.isConnectedAndReady) {
       return;
     }
 
     if (name === "mode" && oldValue != newValue) {
       this._initUI();
     }
   }
 
   _initUI() {
-    let isUndetermined = this.isUndetermined();
-    let content = isUndetermined ?
-      `
-        <stack class="progress-remainder" flex="1" style="overflow: -moz-hidden-unscrollable;">
-          <spacer class="progress-bar" top="0" style="margin-right: -1000px;"/>
-        </stack>
-      ` :
-      `
-        <spacer class="progress-bar"/>
-        <spacer class="progress-remainder"/>
-      `;
-
-    this._stack = null;
-    this._spacer = null;
-    this._runAnimation = isUndetermined;
+    let content = `
+      <spacer class="progress-bar"/>
+      <spacer class="progress-remainder"/>
+    `;
 
     this.textContent = "";
     this.appendChild(MozXULElement.parseXULToFragment(content));
-
-    if (!isUndetermined) {
-      return;
-    }
-
-    this._stack = this.querySelector(".progress-remainder");
-    this._spacer = this.querySelector(".progress-bar");
-    this._isLTR = document.defaultView.getComputedStyle(this).direction == "ltr";
-    this._startTime = window.performance.now();
-
-    let nextStep = (t) => {
-      if (!this._runAnimation) {
-        return;
-      }
-
-      let width = this._stack.boxObject.width;
-      if (width) {
-        let elapsedTime = t - this._startTime;
-
-        // Width of chunk is 1/5 (determined by the ratio 2000:400) of the
-        // total width of the progress bar. The left edge of the chunk
-        // starts at -1 and moves all the way to 4. It covers the distance
-        // in 2 seconds.
-        let position = this._isLTR ? ((elapsedTime % 2000) / 400) - 1 :
-                                     ((elapsedTime % 2000) / -400) + 4;
-
-        width = width >> 2;
-        this._spacer.height = this._stack.boxObject.height;
-        this._spacer.width = width;
-        this._spacer.left = width * position;
-      }
-
-      window.requestAnimationFrame(nextStep);
-    };
-
-    window.requestAnimationFrame(nextStep);
   }
 }
 
 customElements.define("progressmeter", MozProgressmeter);
 
 }
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -3726,22 +3726,28 @@ nsWindow::Create(nsIWidget* aParent,
 
         bool isSetVisual = false;
 #ifdef MOZ_X11
         // Ensure gfxPlatform is initialized, since that is what initializes
         // gfxVars, used below.
         Unused << gfxPlatform::GetPlatform();
 
         bool useWebRender = gfx::gfxVars::UseWebRender() &&
-            AllowWebRenderForThisWindow();
+             AllowWebRenderForThisWindow();
+
+        bool shouldAccelerate = ComputeShouldAccelerate();
+        MOZ_ASSERT(shouldAccelerate | !useWebRender);
 
         // If using WebRender on X11, we need to select a visual with a depth buffer,
         // as well as an alpha channel if transparency is requested. This must be done
         // before the widget is realized.
-        if (mIsX11Display) {
+
+        // Use GL/WebRender compatible visual only when it is necessary, since
+        // the visual consumes more memory.
+        if (mIsX11Display && shouldAccelerate) {
             auto display =
                 GDK_DISPLAY_XDISPLAY(gtk_widget_get_display(mShell));
             auto screen = gtk_widget_get_screen(mShell);
             int screenNumber = GDK_SCREEN_XNUMBER(screen);
             int visualId = 0;
             if (GLContextGLX::FindVisual(display, screenNumber,
                                          useWebRender, needsAlphaVisual,
                                          &visualId)) {
--- a/widget/nsIWindowsUIUtils.idl
+++ b/widget/nsIWindowsUIUtils.idl
@@ -15,10 +15,14 @@ interface nsIWindowsUIUtils : nsISupport
    * non-Windows and on versions of Windows before win10
    */
   readonly attribute boolean inTabletMode;
 
   /**
    * Update the tablet mode state
    */
   void updateTabletModeState();
+
+  /**
+   * Share URL
+   */
+  void shareUrl(in AString shareTitle, in AString urlToShare);
 };
-
--- a/widget/windows/WindowsUIUtils.cpp
+++ b/widget/windows/WindowsUIUtils.cpp
@@ -30,16 +30,17 @@
 #pragma comment(lib, "runtimeobject.lib")
 
 using namespace mozilla;
 using namespace ABI::Windows::UI;
 using namespace ABI::Windows::UI::ViewManagement;
 using namespace Microsoft::WRL;
 using namespace Microsoft::WRL::Wrappers;
 using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::ApplicationModel::DataTransfer;
 
 /* All of this is win10 stuff and we're compiling against win81 headers
  * for now, so we may need to do some legwork: */
 #if WINVER_MAXVER < 0x0A00
 namespace ABI {
   namespace Windows {
     namespace UI {
       namespace ViewManagement {
@@ -85,16 +86,31 @@ typedef interface IUIViewSettingsInterop
 MIDL_INTERFACE("3694dbf9-8f68-44be-8ff5-195c98ede8a6")
 IUIViewSettingsInterop : public IInspectable
 {
 public:
   virtual HRESULT STDMETHODCALLTYPE GetForWindow(HWND hwnd, REFIID riid, void **ppv) = 0;
 };
 #endif
 
+#ifndef __IDataTransferManagerInterop_INTERFACE_DEFINED__
+#define __IDataTransferManagerInterop_INTERFACE_DEFINED__
+
+typedef interface IDataTransferManagerInterop IDataTransferManagerInterop;
+
+MIDL_INTERFACE("3A3DCD6C-3EAB-43DC-BCDE-45671CE800C8")
+IDataTransferManagerInterop : public IUnknown
+{
+public:
+    virtual HRESULT STDMETHODCALLTYPE GetForWindow(HWND appWindow, REFIID riid, void **dataTransferManager) = 0;
+    virtual HRESULT STDMETHODCALLTYPE ShowShareUIForWindow(HWND appWindow) = 0;
+};
+
+#endif
+
 #endif
 
 WindowsUIUtils::WindowsUIUtils() :
   mInTabletMode(eTabletModeUnknown)
 {
 }
 
 WindowsUIUtils::~WindowsUIUtils()
@@ -173,8 +189,129 @@ WindowsUIUtils::UpdateTabletModeState()
         }
       }
     }
   }
 #endif
 
   return NS_OK;
 }
+
+struct HStringDeleter
+{
+  typedef HSTRING pointer;
+  void operator()(pointer aString)
+  {
+      WindowsDeleteString(aString);
+  }
+};
+
+typedef mozilla::UniquePtr<HSTRING, HStringDeleter> HStringUniquePtr;
+
+NS_IMETHODIMP
+WindowsUIUtils::ShareUrl(const nsAString& aUrlToShare,
+                         const nsAString& aShareTitle)
+{
+#ifndef __MINGW32__
+  if (!IsWin10OrLater()) {
+    return NS_OK;
+  }
+
+  HSTRING rawTitle;
+  HRESULT hr = WindowsCreateString(PromiseFlatString(aShareTitle).get(), aShareTitle.Length(), &rawTitle);
+  if (FAILED(hr)) {
+    return NS_OK;
+  }
+  HStringUniquePtr title(rawTitle);
+
+  HSTRING rawUrl;
+  hr = WindowsCreateString(PromiseFlatString(aUrlToShare).get(), aUrlToShare.Length(), &rawUrl);
+  if (FAILED(hr)) {
+    return NS_OK;
+  }
+  HStringUniquePtr url(rawUrl);
+
+  ComPtr<IUriRuntimeClassFactory> uriFactory;
+  hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_Uri).Get(), &uriFactory);
+  if (FAILED(hr)) {
+    return NS_OK;
+  }
+
+  ComPtr<IUriRuntimeClass> uri;
+  hr = uriFactory->CreateUri(url.get(), &uri);
+  if (FAILED(hr)) {
+    return NS_OK;
+  }
+
+  HWND hwnd = GetForegroundWindow();
+  if (!hwnd) {
+    return NS_OK;
+  }
+
+  ComPtr<IDataTransferManagerInterop> dtmInterop;
+  hr = RoGetActivationFactory(HStringReference(
+    RuntimeClass_Windows_ApplicationModel_DataTransfer_DataTransferManager)
+                         .Get(), IID_PPV_ARGS(&dtmInterop));
+  if (FAILED(hr)) {
+    return NS_OK;
+  }
+
+  ComPtr<IDataTransferManager> dtm;
+  hr = dtmInterop->GetForWindow(hwnd, IID_PPV_ARGS(&dtm));
+  if (FAILED(hr)) {
+    return NS_OK;
+  }
+
+  auto callback = Callback < ITypedEventHandler<DataTransferManager*, DataRequestedEventArgs* >> (
+          [uri = std::move(uri), title = std::move(title)](IDataTransferManager*, IDataRequestedEventArgs* pArgs) -> HRESULT
+    {
+      ComPtr<IDataRequest> spDataRequest;
+      HRESULT hr = pArgs->get_Request(&spDataRequest);
+      if (FAILED(hr)) {
+        return hr;
+      }
+
+      ComPtr<IDataPackage> spDataPackage;
+      hr = spDataRequest->get_Data(&spDataPackage);
+      if (FAILED(hr)) {
+        return hr;
+      }
+
+      ComPtr<IDataPackage2> spDataPackage2;
+      hr = spDataPackage->QueryInterface(IID_PPV_ARGS(&spDataPackage2));
+      if (FAILED(hr)) {
+        return hr;
+      }
+
+      ComPtr<IDataPackagePropertySet> spDataPackageProperties;
+      hr = spDataPackage->get_Properties(&spDataPackageProperties);
+      if (FAILED(hr)) {
+        return hr;
+      }
+
+      hr = spDataPackageProperties->put_Title(title.get());
+      if (FAILED(hr)) {
+        return hr;
+      }
+
+      hr = spDataPackage2->SetWebLink(uri.Get());
+      if (FAILED(hr)) {
+        return hr;
+      }
+
+      return S_OK;
+    });
+
+  EventRegistrationToken dataRequestedToken;
+  hr = dtm->add_DataRequested(callback.Get(), &dataRequestedToken);
+  if (FAILED(hr)) {
+    return NS_OK;
+  }
+
+  hr = dtmInterop->ShowShareUIForWindow(hwnd);
+  if (FAILED(hr)) {
+    return NS_OK;
+  }
+
+#endif
+
+  return NS_OK;
+}