Merge mozilla-inbound to mozilla-central. a=merge
authorCosmin Sabou <csabou@mozilla.com>
Tue, 16 Oct 2018 19:24:57 +0300
changeset 497241 31724aea10ca
parent 497205 f2e35ed6a692 (current diff)
parent 497217 237c50cb98bc (diff)
child 497242 6fa9b4e512fa
child 497254 1403652ca901
push id9996
push userarchaeopteryx@coole-files.de
push dateThu, 18 Oct 2018 18:37:15 +0000
treeherdermozilla-beta@8efe26839243 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone64.0a1
first release with
nightly linux32
31724aea10ca / 64.0a1 / 20181016220050 / files
nightly linux64
31724aea10ca / 64.0a1 / 20181016220050 / files
nightly mac
31724aea10ca / 64.0a1 / 20181016220050 / files
nightly win32
31724aea10ca / 64.0a1 / 20181016220050 / files
nightly win64
31724aea10ca / 64.0a1 / 20181016220050 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-inbound to mozilla-central. a=merge
browser/themes/windows/browser.css
browser/themes/windows/jar.mn
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;
+}