Merge inbound to mozilla-central. a=merge
authorCiure Andrei <aciure@mozilla.com>
Wed, 31 Oct 2018 00:06:53 +0200
changeset 443602 be32f4014f92d0ab717621997e0d36c9bc1c479b
parent 443601 a9bd3dd38b193be386f6f534d467b72c0d7b9a40 (current diff)
parent 443482 052cd2cda89aac684e448995407d0ddf342ca3d3 (diff)
child 443603 d751dd2cd3370f63087f7fa36d836b86a83506b7
child 443651 60da95af0316fed3a891735a41c16c87faa75d05
push id109412
push useraciure@mozilla.com
push dateTue, 30 Oct 2018 22:16:54 +0000
treeherdermozilla-inbound@d751dd2cd337 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone65.0a1
first release with
nightly linux32
be32f4014f92 / 65.0a1 / 20181030224027 / files
nightly linux64
be32f4014f92 / 65.0a1 / 20181030224027 / files
nightly mac
be32f4014f92 / 65.0a1 / 20181030224027 / files
nightly win32
be32f4014f92 / 65.0a1 / 20181030224027 / files
nightly win64
be32f4014f92 / 65.0a1 / 20181030224027 / 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 inbound to mozilla-central. a=merge
devtools/client/jar.mn
--- a/browser/components/aboutconfig/content/aboutconfig.css
+++ b/browser/components/aboutconfig/content/aboutconfig.css
@@ -1,5 +1,22 @@
 /* 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/. */
 
-/* aboutconfig.css */
+#list {
+  margin: 0;
+  padding: 2em;
+  overflow-wrap: break-word;
+}
+
+#list > li {
+  padding: 5px;
+  list-style: none;
+}
+
+#list > li:nth-child(even) {
+  background-color: rgba(0, 0, 0, .06);
+}
+
+#list > li:nth-child(odd) {
+  background-color: rgba(0, 0, 0, .03);
+}
--- a/browser/components/aboutconfig/content/aboutconfig.html
+++ b/browser/components/aboutconfig/content/aboutconfig.html
@@ -1,21 +1,22 @@
 <!-- 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/. -->
 
-<!DOCTYPE HTML>
+<!DOCTYPE html>
 <html>
   <head>
     <meta charset="utf-8">
     <link rel="stylesheet" media="screen, projection" type="text/css"
-          href="chrome://global/skin/in-content/common.css"/>
+          href="chrome://global/skin/in-content/common.css">
     <link rel="stylesheet" type="text/css"
-          href="chrome://browser/content/aboutconfig/aboutconfig.css"/>
+          href="chrome://browser/content/aboutconfig/aboutconfig.css">
     <link rel="localization" href="browser/aboutConfig.ftl">
     <script type="application/javascript"
             src="chrome://browser/content/aboutconfig/aboutconfig.js"></script>
     <title data-l10n-id="about-config-title"></title>
   </head>
 
-  <body>
+  <body onload="onLoad();">
+    <ul id="list"></ul>
   </body>
- </html>
+</html>
--- a/browser/components/aboutconfig/content/aboutconfig.js
+++ b/browser/components/aboutconfig/content/aboutconfig.js
@@ -1,5 +1,29 @@
 /* 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/. */
 
-/* aboutconfig.js */
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+ChromeUtils.import("resource://gre/modules/Preferences.jsm");
+
+let gPrefArray;
+
+function onLoad() {
+  gPrefArray = Services.prefs.getChildList("").map(name => ({
+    name,
+    value: Preferences.get(name),
+    hasUserValue: Services.prefs.prefHasUserValue(name),
+  }));
+
+  gPrefArray.sort((a, b) => a.name > b.name);
+
+  let fragment = document.createDocumentFragment();
+
+  for (let pref of gPrefArray) {
+    let listItem = document.createElement("li");
+    listItem.textContent = pref.name + " || " +
+      (pref.hasUserValue ? "Modified" : "Default") + " || " +
+      pref.value.constructor.name + " || " + pref.value;
+    fragment.appendChild(listItem);
+  }
+  document.getElementById("list").appendChild(fragment);
+}
--- a/browser/components/aboutconfig/test/browser/browser_basic.js
+++ b/browser/components/aboutconfig/test/browser/browser_basic.js
@@ -1,15 +1,35 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
+const PAGE_URL = "chrome://browser/content/aboutconfig/aboutconfig.html";
+
 add_task(async function test_load_title() {
   await BrowserTestUtils.withNewTab({
     gBrowser,
-    url: "chrome://browser/content/aboutconfig/aboutconfig.html",
+    url: PAGE_URL,
   }, browser => {
     info("about:config loaded");
     return ContentTask.spawn(browser, null, async () => {
       await content.document.l10n.ready;
       Assert.equal(content.document.title, "about:config");
     });
   });
 });
+
+add_task(async function test_load_settings() {
+  await BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: PAGE_URL,
+  }, browser => {
+    return ContentTask.spawn(browser, null, () => {
+      let list = [...content.document.getElementById("list")
+                                     .getElementsByTagName("li")];
+      function findPref(name) {
+        return list.some(e => e.textContent.trim().startsWith(name + " "));
+      }
+      Assert.ok(findPref("plugins.testmode"));
+      Assert.ok(findPref("dom.vr.enabled"));
+      Assert.ok(findPref("accessibility.AOM.enabled"));
+    });
+  });
+});
--- a/devtools/client/debugger/new/README.mozilla
+++ b/devtools/client/debugger/new/README.mozilla
@@ -1,13 +1,13 @@
 This is the debugger.html project output.
 See https://github.com/devtools-html/debugger.html
 
-Version 96
+Version 97
 
-Comparison: https://github.com/devtools-html/debugger.html/compare/release-95...release-96
+Comparison: https://github.com/devtools-html/debugger.html/compare/release-96...release-97
 
 Packages:
 - babel-plugin-transform-es2015-modules-commonjs @6.26.2
 - babel-preset-react @6.24.1
 - react @16.4.1
 - react-dom @16.4.1
 - webpack @3.12.0
--- a/devtools/client/debugger/new/dist/debugger.css
+++ b/devtools/client/debugger/new/dist/debugger.css
@@ -2661,59 +2661,64 @@ menuseparator {
   font-size: 14px;
   color: var(--theme-comment);
 }
 /* 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/>. */
 
 .call-site {
-  background: #f0f9ff;
   position: relative;
+  border-bottom: 2px solid lightgrey;
+  cursor: pointer;
 }
 
 .call-site::before {
   content: "";
-  position: absolute;
-  width: 100%;
-  height: calc(100% - 2px);
-  border-bottom: 2px solid #aed3ef;
+  mask: url("chrome://devtools/skin/images/debugger/column-marker.svg") no-repeat 100% 100%;
+  mask-size: contain;
+  display: inline-block;
+  background-color: var(--blue-55);
+  opacity: 0.5;
+  width: 9px;
+  height: 12px;
 }
 
 .call-site-bp {
   position: relative;
-}
-
-.debug-expression.call-site-bp,
-.call-site-bp {
-  background-color: #fce7e7;
+  border-bottom: 2px solid #aed3ef;
+  cursor: pointer;
 }
 
 .call-site-bp::before {
   content: "";
-  position: absolute;
-  width: 100%;
-  height: calc(100% - 2px);
-  border-bottom: 2px solid red;
+  mask: url("chrome://devtools/skin/images/debugger/column-marker.svg") no-repeat 100% 100%;
+  mask-size: contain;
+  display: inline-block;
+  background-color: var(--blue-55);
+  width: 9px;
+  height: 12px;
 }
 
 .theme-dark .call-site {
-  background-color: #4b5462;
+  border-bottom: none;
+}
+
+.theme-dark .call-site-bp {
+  border-bottom: none;
 }
 
 .theme-dark .call-site::before {
-  border-bottom-color: #5f78a4;
-}
-
-.theme-dark .call-site-bp {
-  background-color: #4b3f3f;
+  background-color: var(--blue-60);
+  opacity: 1;
 }
 
 .theme-dark .call-site-bp::before {
-  border-bottom-color: #dd4d4d;
+  background-color: var(--blue-50);
+  opacity: 0.5;
 }
 /* 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/>. */
 
 .conditional-breakpoint-panel {
   cursor: initial;
   margin: 1em 0;
@@ -3413,16 +3418,22 @@ html[dir="rtl"] .breakpoints-list .break
 /* 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/>. */
 
 .frames ul .frames-group .group,
 .frames ul .frames-group .group .location {
   font-weight: 500;
   cursor: default;
+  /*
+   * direction:rtl is set in Frames.css to overflow the location text from the
+   * start. Here we need to reset it in order to display the framework icon
+   * after the framework name.
+   */
+  direction: ltr;
 }
 
 .frames ul .frames-group.expanded .group,
 .frames ul .frames-group.expanded .group .location {
   color: var(--theme-highlight-blue);
 }
 
 .frames ul .frames-group.expanded .react path {
@@ -3495,58 +3506,63 @@ html[dir="rtl"] .breakpoints-list .break
 
 .frames ul {
   list-style: none;
   margin: 0;
   padding: 0;
 }
 
 .frames ul li {
-  padding: 0 10px 0 21px;
+  padding: 7px 10px 7px 21px;
   overflow: hidden;
   display: flex;
   justify-content: space-between;
+  column-gap: 0.5em;
   flex-direction: row;
   align-items: center;
   margin: 0;
+  max-width: 100%;
+  flex-wrap: wrap;
 }
 
 .frames ul li * {
   -moz-user-select: none;
   user-select: none;
 }
 
 .frames .badge {
   flex-shrink: 0;
   margin-right: 4px;
 }
 
 .frames .location {
   font-weight: normal;
-  display: flex;
-  justify-content: space-between;
-  flex-direction: row;
-  align-items: center;
   margin: 0;
-  flex-shrink: 0;
+  flex-grow: 1;
+  max-width: 100%;
+  overflow: hidden;
+  white-space: nowrap;
+  /* Trick to get the ellipsis at the start of the string */
+  text-overflow: ellipsis;
+  direction: rtl;
+  text-align: right;
 }
 
 .theme-light .frames .location {
   color: var(--theme-comment);
 }
 
 :root.theme-dark .frames .location {
   color: var(--theme-body-color);
   opacity: 0.6;
 }
 
 .frames .title {
   text-overflow: ellipsis;
   overflow: hidden;
-  margin: 7px 0.5em 7px 0;
 }
 
 .frames ul li:hover,
 .frames ul li:focus {
   background-color: var(--theme-toolbar-background-alt);
 }
 
 .theme-dark .frames ul li:focus {
@@ -3582,19 +3598,19 @@ html[dir="rtl"] .breakpoints-list .break
   color: inherit;
 }
 
 .show-more:hover {
   background-color: var(--theme-toolbar-background-hover);
 }
 
 .annotation-logo {
+  display: inline-block;
   width: 12px;
-  margin-left: 3px;
-  line-height: 8px;
+  margin-inline-start: 4px;
 }
 
 :root.theme-dark .annotation-logo svg path {
   fill: var(--theme-highlight-blue);
 }
 /* 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/>. */
--- a/devtools/client/debugger/new/dist/vendors.js
+++ b/devtools/client/debugger/new/dist/vendors.js
@@ -2196,16 +2196,17 @@ const svg = {
   angular: __webpack_require__(247),
   arrow: __webpack_require__(348),
   babel: __webpack_require__(3595),
   backbone: __webpack_require__(997),
   blackBox: __webpack_require__(349),
   breadcrumb: __webpack_require__(3603),
   breakpoint: __webpack_require__(350),
   "column-breakpoint": __webpack_require__(998),
+  "column-marker": __webpack_require__(3801),
   "case-match": __webpack_require__(351),
   choo: __webpack_require__(1290),
   close: __webpack_require__(352),
   coffeescript: __webpack_require__(2250),
   dojo: __webpack_require__(806),
   domain: __webpack_require__(353),
   extension: __webpack_require__(3632),
   file: __webpack_require__(354),
@@ -7523,16 +7524,23 @@ function createStructuredSelector(select
       composition[objectKeys[index]] = value;
       return composition;
     }, {});
   });
 }
 
 /***/ }),
 
+/***/ 3801:
+/***/ (function(module, exports) {
+
+module.exports = "<svg viewBox=\"0 0 9 12\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><g id=\"columnmarkergroup\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\"><polygon id=\"columnmarker\" fill=\"#1B1B1D\" points=\"0 0 4 0 9 6 4 12 0 12\"></polygon></g></svg>"
+
+/***/ }),
+
 /***/ 4:
 /***/ (function(module, exports) {
 
 module.exports = __WEBPACK_EXTERNAL_MODULE_4__;
 
 /***/ }),
 
 /***/ 52:
--- a/devtools/client/debugger/new/src/client/firefox/commands.js
+++ b/devtools/client/debugger/new/src/client/firefox/commands.js
@@ -250,17 +250,19 @@ function debuggeeCommand(script) {
   request.emit("json-reply", {});
 
   debuggerClient._activeRequests.delete(consoleActor);
 
   return Promise.resolve();
 }
 
 function navigate(url) {
-  return tabTarget.activeTab.navigateTo({ url });
+  return tabTarget.activeTab.navigateTo({
+    url
+  });
 }
 
 function reload() {
   return tabTarget.activeTab.reload();
 }
 
 function getProperties(grip) {
   const objClient = threadClient.pauseGrip(grip);
@@ -460,9 +462,9 @@ const clientCommands = {
   disablePrettyPrint,
   fetchSources,
   fetchWorkers,
   sendPacket,
   setPausePoints,
   setSkipPausing
 };
 exports.setupCommands = setupCommands;
-exports.clientCommands = clientCommands;
+exports.clientCommands = clientCommands;
\ No newline at end of file
--- a/devtools/client/debugger/new/src/client/firefox/events.js
+++ b/devtools/client/debugger/new/src/client/firefox/events.js
@@ -36,18 +36,18 @@ function setupEvents(dependencies) {
   });
 
   if (threadClient) {
     Object.keys(clientEvents).forEach(eventName => {
       threadClient.addListener(eventName, clientEvents[eventName]);
     });
 
     if (threadClient._parent) {
-      // Parent may be BrowsingContextTargetFront/WorkerTargetFront and be protocol.js.
-      // Or DebuggerClient and still be old fashion actor.
+      // Parent may be BrowsingContextTargetFront/WorkerTargetFront and
+      // be protocol.js.  Or DebuggerClient and still be old fashion actor.
       if (threadClient._parent.on) {
         threadClient._parent.on("workerListChanged", workerListChanged);
       } else {
         threadClient._parent.addListener("workerListChanged", workerListChanged);
       }
     }
   }
 }
@@ -114,9 +114,9 @@ function workerListChanged() {
 }
 
 const clientEvents = {
   paused,
   resumed,
   newSource
 };
 exports.setupEvents = setupEvents;
-exports.clientEvents = clientEvents;
+exports.clientEvents = clientEvents;
\ No newline at end of file
--- a/devtools/client/debugger/new/src/components/Editor/SearchBar.js
+++ b/devtools/client/debugger/new/src/components/Editor/SearchBar.js
@@ -218,20 +218,26 @@ class SearchBar extends _react.Component
         svgName,
         tooltip
       }) {
         const preppedClass = (0, _classnames2.default)(className, {
           active: modifiers && modifiers.get(modVal)
         });
         return _react2.default.createElement("button", {
           className: preppedClass,
-          onClick: () => {
+          onMouseDown: () => {
             toggleFileSearchModifier(modVal);
             doSearch(query);
           },
+          onKeyDown: e => {
+            if (e.key === "Enter") {
+              toggleFileSearchModifier(modVal);
+              doSearch(query);
+            }
+          },
           title: tooltip
         }, _react2.default.createElement(_Svg2.default, {
           name: svgName
         }));
       }
 
       return _react2.default.createElement("div", {
         className: "search-modifiers"
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/Frames/Frame.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/Frames/Frame.js
@@ -26,19 +26,21 @@ var _FrameMenu2 = _interopRequireDefault
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 /* 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/>. */
 function FrameTitle({
   frame,
-  options
+  options = {}
 }) {
-  const displayName = (0, _frames.formatDisplayName)(frame, options);
+  const displayName = (0, _frames.formatDisplayName)(frame, { ...options,
+    maxLength: null
+  });
   return _react2.default.createElement("div", {
     className: "title"
   }, displayName);
 }
 
 function FrameLocation({
   frame,
   displayFullUrl = false
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/Frames/Group.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/Frames/Group.js
@@ -120,17 +120,19 @@ class Group extends _react.Component {
       toggleFrameworkGrouping: toggleFrameworkGrouping,
       displayFullUrl: displayFullUrl,
       getFrameTitle: getFrameTitle
     })));
   }
 
   renderDescription() {
     const frame = this.props.group[0];
-    const displayName = (0, _frames.formatDisplayName)(frame);
+    const displayName = (0, _frames.formatDisplayName)(frame, {
+      maxLength: null
+    });
     return _react2.default.createElement("li", {
       key: frame.id,
       className: (0, _classnames2.default)("group"),
       onClick: this.toggleFrames,
       tabIndex: 0
     }, _react2.default.createElement("div", {
       className: "d-flex align-items-center min-width-0"
     }, _react2.default.createElement("div", {
--- a/devtools/client/debugger/new/src/utils/source-maps.js
+++ b/devtools/client/debugger/new/src/utils/source-maps.js
@@ -35,14 +35,18 @@ async function getGeneratedLocation(stat
     column: column === 0 ? undefined : column,
     sourceUrl: generatedSource.url
   };
 }
 
 async function getMappedLocation(state, sourceMaps, location) {
   const source = (0, _selectors.getSource)(state, location.sourceId);
 
+  if (!source) {
+    throw new Error("Unknown source for location");
+  }
+
   if ((0, _devtoolsSourceMap.isOriginalId)(location.sourceId)) {
     return getGeneratedLocation(state, source, location, sourceMaps);
   }
 
   return sourceMaps.getOriginalLocation(location, source);
 }
\ No newline at end of file
--- a/devtools/client/debugger/new/src/utils/text.js
+++ b/devtools/client/debugger/new/src/utils/text.js
@@ -55,13 +55,13 @@ function formatKeyShortcut(shortcut) {
  * @static
  */
 
 
 function truncateMiddleText(sourceText, maxLength) {
   let truncatedText = sourceText;
 
   if (sourceText.length > maxLength) {
-    truncatedText = `${sourceText.substring(0, Math.round(maxLength / 2) - 2)}...${sourceText.substring(sourceText.length - Math.round(maxLength / 2 - 1))}`;
+    truncatedText = `${sourceText.substring(0, Math.round(maxLength / 2) - 2)}…${sourceText.substring(sourceText.length - Math.round(maxLength / 2 - 1))}`;
   }
 
   return truncatedText;
 }
\ No newline at end of file
--- a/devtools/client/debugger/new/src/utils/utils.js
+++ b/devtools/client/debugger/new/src/utils/utils.js
@@ -45,17 +45,17 @@ function promisify(context, method, ...a
 /**
  * @memberof utils/utils
  * @static
  */
 
 
 function endTruncateStr(str, size) {
   if (str.length > size) {
-    return `...${str.slice(str.length - size)}`;
+    return `…${str.slice(str.length - size)}`;
   }
 
   return str;
 }
 
 function waitForMs(ms) {
   return new Promise(resolve => setTimeout(resolve, ms));
 }
\ No newline at end of file
--- a/devtools/client/jar.mn
+++ b/devtools/client/jar.mn
@@ -250,16 +250,17 @@ devtools.jar:
 
     # Debugger
     skin/images/debugger/angular.svg (themes/images/debugger/angular.svg)
     skin/images/debugger/arrow.svg (themes/images/debugger/arrow.svg)
     skin/images/debugger/blackBox.svg (themes/images/debugger/blackBox.svg)
     skin/images/debugger/breakpoint.svg (themes/images/debugger/breakpoint.svg)
     skin/images/debugger/close.svg (themes/images/debugger/close.svg)
     skin/images/debugger/coffeescript.svg (themes/images/debugger/coffeescript.svg)
+    skin/images/debugger/column-marker.svg (themes/images/debugger/column-marker.svg)
     skin/images/debugger/disable-pausing.svg (themes/images/debugger/disable-pausing.svg)
     skin/images/debugger/domain.svg (themes/images/debugger/domain.svg)
     skin/images/debugger/extension.svg (themes/images/debugger/extension.svg)
     skin/images/debugger/file.svg (themes/images/debugger/file.svg)
     skin/images/debugger/folder.svg (themes/images/debugger/folder.svg)
     skin/images/debugger/javascript.svg (themes/images/debugger/javascript.svg)
     skin/images/debugger/pause.svg (themes/images/debugger/pause.svg)
     skin/images/debugger/prettyPrint.svg (themes/images/debugger/prettyPrint.svg)
--- a/devtools/client/shared/components/reps/reps.js
+++ b/devtools/client/shared/components/reps/reps.js
@@ -1872,17 +1872,19 @@ const { span } = dom;
 const IGNORED_SOURCE_URLS = ["debugger eval code"];
 
 /**
  * Renders Error objects.
  */
 ErrorRep.propTypes = {
   object: PropTypes.object.isRequired,
   // @TODO Change this to Object.values when supported in Node's version of V8
-  mode: PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key]))
+  mode: PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])),
+  // An optional function that will be used to render the Error stacktrace.
+  renderStacktrace: PropTypes.func
 };
 
 function ErrorRep(props) {
   const object = props.object;
   const preview = object.preview;
 
   let name;
   if (preview && preview.name && preview.kind) {
@@ -1904,17 +1906,18 @@ function ErrorRep(props) {
 
   if (props.mode === MODE.TINY) {
     content.push(name);
   } else {
     content.push(`${name}: "${preview.message}"`);
   }
 
   if (preview.stack && props.mode !== MODE.TINY) {
-    content.push("\n", getStacktraceElements(props, preview));
+    const stacktrace = props.renderStacktrace ? props.renderStacktrace(parseStackString(preview.stack)) : getStacktraceElements(props, preview);
+    content.push("\n", stacktrace);
   }
 
   return span({
     "data-link-actor-id": object.actor,
     className: "objectBox-stackTrace"
   }, content);
 }
 
@@ -1935,18 +1938,75 @@ function ErrorRep(props) {
  *            (<anonymous>:11:1)
  */
 function getStacktraceElements(props, preview) {
   const stack = [];
   if (!preview.stack) {
     return stack;
   }
 
-  const isStacktraceALongString = isLongString(preview.stack);
-  const stackString = isStacktraceALongString ? preview.stack.initial : preview.stack;
+  parseStackString(preview.stack).forEach((frame, index, frames) => {
+    let onLocationClick;
+    const {
+      filename,
+      lineNumber,
+      columnNumber,
+      functionName,
+      location
+    } = frame;
+
+    if (props.onViewSourceInDebugger && !IGNORED_SOURCE_URLS.includes(filename)) {
+      onLocationClick = e => {
+        // Don't trigger ObjectInspector expand/collapse.
+        e.stopPropagation();
+        props.onViewSourceInDebugger({
+          url: filename,
+          line: lineNumber,
+          column: columnNumber
+        });
+      };
+    }
+
+    stack.push("\t", span({
+      key: `fn${index}`,
+      className: "objectBox-stackTrace-fn"
+    }, cleanFunctionName(functionName)), " ", span({
+      key: `location${index}`,
+      className: "objectBox-stackTrace-location",
+      onClick: onLocationClick,
+      title: onLocationClick ? `View source in debugger → ${location}` : undefined
+    }, location), "\n");
+  });
+
+  return span({
+    key: "stack",
+    className: "objectBox-stackTrace-grid"
+  }, stack);
+}
+
+/**
+ * Parse a string that should represent a stack trace and returns an array of
+ * the frames. The shape of the frames are extremely important as they can then
+ * be processed here or in the toolbox by other components.
+ * @param {String} stack
+ * @returns {Array} Array of frames, which are object with the following shape:
+ *                  - {String} filename
+ *                  - {String} functionName
+ *                  - {String} location
+ *                  - {Number} columnNumber
+ *                  - {Number} lineNumber
+ */
+function parseStackString(stack) {
+  const res = [];
+  if (!stack) {
+    return res;
+  }
+
+  const isStacktraceALongString = isLongString(stack);
+  const stackString = isStacktraceALongString ? stack.initial : stack;
 
   stackString.split("\n").forEach((frame, index, frames) => {
     if (!frame) {
       // Skip any blank lines
       return;
     }
 
     // If the stacktrace is a longString, don't include the last frame in the
@@ -1975,50 +2035,34 @@ function getStacktraceElements(props, pr
       // What's needed is only the last part after " -> ".
       location = result[2].split(" -> ").pop();
     }
 
     if (!functionName) {
       functionName = "<anonymous>";
     }
 
-    let onLocationClick;
     // Given the input: "scriptLocation:2:100"
     // Result:
     // ["scriptLocation:2:100", "scriptLocation", "2", "100"]
     const locationParts = location.match(/^(.*):(\d+):(\d+)$/);
 
-    if (props.onViewSourceInDebugger && location && locationParts && !IGNORED_SOURCE_URLS.includes(locationParts[1])) {
-      const [, url, line, column] = locationParts;
-      onLocationClick = e => {
-        // Don't trigger ObjectInspector expand/collapse.
-        e.stopPropagation();
-        props.onViewSourceInDebugger({
-          url,
-          line: Number(line),
-          column: Number(column)
-        });
-      };
+    if (location && locationParts) {
+      const [, filename, line, column] = locationParts;
+      res.push({
+        filename,
+        functionName,
+        location,
+        columnNumber: Number(column),
+        lineNumber: Number(line)
+      });
     }
-
-    stack.push("\t", span({
-      key: `fn${index}`,
-      className: "objectBox-stackTrace-fn"
-    }, cleanFunctionName(functionName)), " ", span({
-      key: `location${index}`,
-      className: "objectBox-stackTrace-location",
-      onClick: onLocationClick,
-      title: onLocationClick ? `View source in debugger → ${location}` : undefined
-    }, location), "\n");
   });
 
-  return span({
-    key: "stack",
-    className: "objectBox-stackTrace-grid"
-  }, stack);
+  return res;
 }
 
 // Registration
 function supportsObject(object, noGrip = false) {
   if (noGrip === true || !isGrip(object)) {
     return false;
   }
   return object.preview && getGripType(object, noGrip) === "Error" || object.class === "DOMException";
new file mode 100644
--- /dev/null
+++ b/devtools/client/themes/images/debugger/column-marker.svg
@@ -0,0 +1,5 @@
+<svg width="9px" height="12px" viewBox="0 0 9 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <g id="columnmarkergroup" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <polygon id="columnmarker" fill="#1B1B1D" points="0 0 4 0 9 6 4 12 0 12"></polygon>
+    </g>
+</svg>
\ No newline at end of file
--- a/dom/file/FileReader.cpp
+++ b/dom/file/FileReader.cpp
@@ -83,43 +83,16 @@ public:
   {}
 
   ~FileReaderDecreaseBusyCounter()
   {
     mFileReader->DecreaseBusyCounter();
   }
 };
 
-class FileReader::AsyncWaitRunnable final : public CancelableRunnable
-{
-public:
-  explicit AsyncWaitRunnable(FileReader* aReader)
-    : CancelableRunnable("FileReader::AsyncWaitRunnable")
-    , mReader(aReader)
-  {}
-
-  NS_IMETHOD
-  Run() override
-  {
-    if (mReader) {
-      mReader->InitialAsyncWait();
-    }
-    return NS_OK;
-  }
-
-  void
-  Abort()
-  {
-    mReader = nullptr;
-  }
-
-public:
-  RefPtr<FileReader> mReader;
-};
-
 void
 FileReader::RootResultArrayBuffer()
 {
   mozilla::HoldJSObjects(this);
 }
 
 //FileReader constructors/initializers
 
@@ -468,39 +441,24 @@ FileReader::ReadFileContent(Blob& aBlob,
 
     if (!mFileData) {
       NS_WARNING("Preallocation failed for ReadFileData");
       aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
       return;
     }
   }
 
-  mAsyncWaitRunnable = new AsyncWaitRunnable(this);
-  aRv = NS_DispatchToCurrentThread(mAsyncWaitRunnable);
+  aRv = DoAsyncWait();
   if (NS_WARN_IF(aRv.Failed())) {
     FreeFileData();
     return;
   }
 
   //FileReader should be in loading state here
   mReadyState = LOADING;
-}
-
-void
-FileReader::InitialAsyncWait()
-{
-  mAsyncWaitRunnable = nullptr;
-
-  nsresult rv = DoAsyncWait();
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    mReadyState = EMPTY;
-    FreeFileData();
-    return;
-  }
-
   DispatchProgressEvent(NS_LITERAL_STRING(LOADSTART_STR));
 }
 
 nsresult
 FileReader::GetAsText(Blob *aBlob,
                       const nsACString &aCharset,
                       const char *aFileData,
                       uint32_t aDataLen,
@@ -811,43 +769,26 @@ FileReader::Abort()
   if (mReadyState == EMPTY || mReadyState == DONE) {
     return;
   }
 
   MOZ_ASSERT(mReadyState == LOADING);
 
   ClearProgressEventTimer();
 
-  if (mAsyncWaitRunnable) {
-    mAsyncWaitRunnable->Abort();
-    mAsyncWaitRunnable = nullptr;
-  }
-
   mReadyState = DONE;
 
   // XXX The spec doesn't say this
   mError = DOMException::Create(NS_ERROR_DOM_ABORT_ERR);
 
   // Revert status and result attributes
   SetDOMStringToNull(mResult);
   mResultArrayBuffer = nullptr;
 
-  if (mAsyncStream) {
-    if (mBusyCount) {
-      // This will abort any pending reading. See nsIAsyncInputStream.idl.
-      mAsyncStream->AsyncWait(/* callback */ nullptr,
-                              /* aFlags*/ 0,
-                              /* aRequestedCount */ 0,
-                              mTarget);
-      DecreaseBusyCounter();
-      MOZ_ASSERT(mBusyCount == 0);
-    }
-    mAsyncStream = nullptr;
-  }
-
+  mAsyncStream = nullptr;
   mBlob = nullptr;
 
   //Clean up memory buffer
   FreeFileData();
 
   // Dispatch the events
   DispatchProgressEvent(NS_LITERAL_STRING(ABORT_STR));
   DispatchProgressEvent(NS_LITERAL_STRING(LOADEND_STR));
@@ -885,21 +826,16 @@ FileReader::DecreaseBusyCounter()
   }
 }
 
 void
 FileReader::Shutdown()
 {
   mReadyState = DONE;
 
-  if (mAsyncWaitRunnable) {
-    mAsyncWaitRunnable->Abort();
-    mAsyncWaitRunnable = nullptr;
-  }
-
   if (mAsyncStream) {
     mAsyncStream->Close();
     mAsyncStream = nullptr;
   }
 
   FreeFileData();
   mResultArrayBuffer = nullptr;
 
--- a/dom/file/FileReader.h
+++ b/dom/file/FileReader.h
@@ -123,18 +123,16 @@ public:
     FILE_AS_BINARY,
     FILE_AS_TEXT,
     FILE_AS_DATAURL
   };
 
   eDataFormat DataFormat() const { return mDataFormat; }
   const nsString& Result() const { return mResult; }
 
-  void InitialAsyncWait();
-
 private:
   virtual ~FileReader();
 
   // This must be in sync with dom/webidl/FileReader.webidl
   enum eReadyState {
     EMPTY = 0,
     LOADING = 1,
     DONE = 2
@@ -204,20 +202,16 @@ private:
   // This is set if FileReader is created on workers, but it is null if the
   // worker is shutting down. The null value is checked in ReadFileContent()
   // before starting any reading.
   RefPtr<WeakWorkerRef> mWeakWorkerRef;
 
   // This value is set when the reading starts in order to keep the worker alive
   // during the process.
   RefPtr<StrongWorkerRef> mStrongWorkerRef;
-
-  // Runnable to start the reading asynchronous.
-  class AsyncWaitRunnable;
-  RefPtr<AsyncWaitRunnable> mAsyncWaitRunnable;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(FileReader, FILEREADER_ID)
 
 } // dom namespace
 } // mozilla namespace
 
 #endif // mozilla_dom_FileReader_h
--- a/dom/file/tests/common_fileReader.js
+++ b/dom/file/tests/common_fileReader.js
@@ -252,17 +252,17 @@ function test_readAsText(blob, text) {
 
     r.addEventListener("load", () => { onloadHasRun = true });
     r.addEventListener("loadstart", () => { onloadStartHasRun = true });
 
     r.readAsText(blob);
 
     is(r.readyState, FileReader.LOADING, "correct loading text readyState");
     is(onloadHasRun, false, "text loading must be async");
-    is(onloadStartHasRun, false, "text loadstart should fire async");
+    is(onloadStartHasRun, true, "text loadstart should fire sync");
   });
 }
 
 function test_readAsBinaryString(blob, text) {
   return new Promise(resolve => {
     let onloadHasRun = false;
     let onloadStartHasRun = false;
 
@@ -275,17 +275,17 @@ function test_readAsBinaryString(blob, t
     r.readAsBinaryString(blob);
 
     r.onload = event => {
       loadEventHandler_string(event, resolve, r, text, text.length, "readAsBinaryString");
     }
 
     is(r.readyState, FileReader.LOADING, "correct loading binary readyState");
     is(onloadHasRun, false, "binary loading must be async");
-    is(onloadStartHasRun, false, "binary loadstart should fire async");
+    is(onloadStartHasRun, true, "binary loadstart should fire sync");
   });
 }
 
 function test_readAsArrayBuffer(blob, text) {
   return new Promise(resolve => {
     let onloadHasRun = false;
     let onloadStartHasRun = false;
 
@@ -298,17 +298,17 @@ function test_readAsArrayBuffer(blob, te
     r.readAsArrayBuffer(blob);
 
     r.onload = event => {
       loadEventHandler_arrayBuffer(event, resolve, r, text, "readAsArrayBuffer");
     }
 
     is(r.readyState, FileReader.LOADING, "correct loading arrayBuffer readyState");
     is(onloadHasRun, false, "arrayBuffer loading must be async");
-    is(onloadStartHasRun, false, "arrayBuffer loadstart should fire sync");
+    is(onloadStartHasRun, true, "arrayBuffer loadstart should fire sync");
   });
 }
 
 // Test a variety of encodings, and make sure they work properly
 function test_readAsTextWithEncoding(blob, text, length, charset) {
   return new Promise(resolve => {
     let r = new FileReader();
     r.onload = event => {
--- a/dom/security/nsCSPService.cpp
+++ b/dom/security/nsCSPService.cpp
@@ -86,27 +86,29 @@ subjectToCSP(nsIURI* aURI, nsContentPoli
     return false;
   }
 
   // Please note that it should be possible for websites to
   // whitelist their own protocol handlers with respect to CSP,
   // hence we use protocol flags to accomplish that, but we also
   // want resource:, chrome: and moz-icon to be subject to CSP
   // (which also use URI_IS_LOCAL_RESOURCE).
-  // Exception to the rule are images, styles, and localization DTDs
-  // using a scheme of resource: or chrome:
-  bool isImgOrStyleOrDTD = contentType == nsIContentPolicy::TYPE_IMAGE ||
-                      contentType == nsIContentPolicy::TYPE_STYLESHEET ||
-                      contentType == nsIContentPolicy::TYPE_DTD;
+  // Exception to the rule are images, styles, localization DTDs,
+  // and XBLs using a scheme of resource: or chrome:
+  bool isImgOrStyleOrDTDorXBL =
+    contentType == nsIContentPolicy::TYPE_IMAGE ||
+    contentType == nsIContentPolicy::TYPE_STYLESHEET ||
+    contentType == nsIContentPolicy::TYPE_DTD ||
+    contentType == nsIContentPolicy::TYPE_XBL;
   rv = aURI->SchemeIs("resource", &match);
-  if (NS_SUCCEEDED(rv) && match && !isImgOrStyleOrDTD) {
+  if (NS_SUCCEEDED(rv) && match && !isImgOrStyleOrDTDorXBL) {
     return true;
   }
   rv = aURI->SchemeIs("chrome", &match);
-  if (NS_SUCCEEDED(rv) && match && !isImgOrStyleOrDTD) {
+  if (NS_SUCCEEDED(rv) && match && !isImgOrStyleOrDTDorXBL) {
     return true;
   }
   rv = aURI->SchemeIs("moz-icon", &match);
   if (NS_SUCCEEDED(rv) && match) {
     return true;
   }
   rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_IS_LOCAL_RESOURCE, &match);
   if (NS_SUCCEEDED(rv) && match) {
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -4107,27 +4107,23 @@ AsyncPanZoomController::ReportCheckerboa
   UpdateCheckerboardEvent(lock, magnitude);
 }
 
 void
 AsyncPanZoomController::UpdateCheckerboardEvent(const MutexAutoLock& aProofOfLock,
                                                 uint32_t aMagnitude)
 {
   if (mCheckerboardEvent && mCheckerboardEvent->RecordFrameInfo(aMagnitude)) {
-    // This checkerboard event is done. Report some metrics to telemetry, but
-    // skip reporting if the sanity checker window is running, because we get
-    // checkerboarding reported on that window that we don't really care about.
-    if (!gfxPrefs::SanityTestRunning()) {
-      mozilla::Telemetry::Accumulate(mozilla::Telemetry::CHECKERBOARD_SEVERITY,
-        mCheckerboardEvent->GetSeverity());
-      mozilla::Telemetry::Accumulate(mozilla::Telemetry::CHECKERBOARD_PEAK,
-        mCheckerboardEvent->GetPeak());
-      mozilla::Telemetry::Accumulate(mozilla::Telemetry::CHECKERBOARD_DURATION,
-        (uint32_t)mCheckerboardEvent->GetDuration().ToMilliseconds());
-    }
+    // This checkerboard event is done. Report some metrics to telemetry.
+    mozilla::Telemetry::Accumulate(mozilla::Telemetry::CHECKERBOARD_SEVERITY,
+      mCheckerboardEvent->GetSeverity());
+    mozilla::Telemetry::Accumulate(mozilla::Telemetry::CHECKERBOARD_PEAK,
+      mCheckerboardEvent->GetPeak());
+    mozilla::Telemetry::Accumulate(mozilla::Telemetry::CHECKERBOARD_DURATION,
+      (uint32_t)mCheckerboardEvent->GetDuration().ToMilliseconds());
 
     mPotentialCheckerboardTracker.CheckerboardDone();
 
     if (gfxPrefs::APZRecordCheckerboarding()) {
       // if the pref is enabled, also send it to the storage class. it may be
       // chosen for public display on about:checkerboard, the hall of fame for
       // checkerboard events.
       uint32_t severity = mCheckerboardEvent->GetSeverity();
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -737,18 +737,16 @@ private:
                                                                MouseWheelRootScrollVerticalFactor, int32_t, 0);
   DECL_GFX_PREF(Live, "mousewheel.transaction.ignoremovedelay",MouseWheelIgnoreMoveDelayMs, int32_t, (int32_t)100);
   DECL_GFX_PREF(Live, "mousewheel.transaction.timeout",        MouseWheelTransactionTimeoutMs, int32_t, (int32_t)1500);
 
   DECL_GFX_PREF(Live, "nglayout.debug.widget_update_flashing", WidgetUpdateFlashing, bool, false);
 
   DECL_GFX_PREF(Live, "print.font-variations-as-paths",        PrintFontVariationsAsPaths, bool, true);
 
-  DECL_GFX_PREF(Live, "sanity-test.running",                   SanityTestRunning, bool, false);
-
   DECL_GFX_PREF(Once, "slider.snapMultiplier",                 SliderSnapMultiplier, int32_t, 0);
 
   DECL_GFX_PREF(Live, "test.events.async.enabled",             TestEventsAsyncEnabled, bool, false);
   DECL_GFX_PREF(Live, "test.mousescroll",                      MouseScrollTestingEnabled, bool, false);
 
   DECL_GFX_PREF(Live, "toolkit.scrollbox.horizontalScrollDistance", ToolkitHorizontalScrollDistance, int32_t, 5);
   DECL_GFX_PREF(Live, "toolkit.scrollbox.verticalScrollDistance",   ToolkitVerticalScrollDistance, int32_t, 3);
 
--- a/js/src/builtin/ModuleObject.cpp
+++ b/js/src/builtin/ModuleObject.cpp
@@ -1857,17 +1857,19 @@ js::StartDynamicModuleImport(JSContext* 
     if (!specifier) {
         if (!RejectPromiseWithPendingError(cx, promise)) {
             return nullptr;
         }
         return promise;
     }
 
     if (!importHook(cx, referencingPrivate, specifier, promise)) {
-        if (!RejectPromiseWithPendingError(cx, promise)) {
+        // If there's no exception pending then the script is terminating
+        // anyway, so just return nullptr.
+        if (!cx->isExceptionPending() || !RejectPromiseWithPendingError(cx, promise)) {
             return nullptr;
         }
         return promise;
     }
 
     return promise;
 }
 
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -6110,38 +6110,29 @@ GCRuntime::beginSweepingSweepGroup(FreeO
 
     sweepCache = nullptr;
     safeToYield = true;
 
     return Finished;
 }
 
 #ifdef JS_GC_ZEAL
-
 bool
 GCRuntime::shouldYieldForZeal(ZealMode mode)
 {
-    return useZeal && isIncremental && hasZealMode(mode);
-}
-
-IncrementalProgress
-GCRuntime::maybeYieldForSweepingZeal(FreeOp* fop, SliceBudget& budget)
-{
-    /*
-     * Check whether we need to yield for GC zeal. We always yield when running
-     * in incremental multi-slice zeal mode so RunDebugGC can reset the slice
-     * budget.
-     */
-    if (initialState != State::Sweep && shouldYieldForZeal(ZealMode::IncrementalMultipleSlices)) {
-        return NotFinished;
-    }
-
-    return Finished;
-}
-
+    bool yield = useZeal && isIncremental && hasZealMode(mode);
+
+    // Only yield on the first sweep slice for this mode.
+    bool firstSweepSlice = initialState != State::Sweep;
+    if (mode == ZealMode::IncrementalMultipleSlices && !firstSweepSlice) {
+        yield = false;
+    }
+
+    return yield;
+}
 #endif
 
 IncrementalProgress
 GCRuntime::endSweepingSweepGroup(FreeOp* fop, SliceBudget& budget)
 {
     {
         gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::FINALIZE_END);
         FreeOp fop(rt);
@@ -6684,64 +6675,72 @@ class SweepActionCall final : public Swe
   public:
     explicit SweepActionCall(Method m) : method(m) {}
     IncrementalProgress run(GCRuntime* gc, Args... args) override {
         return (gc->*method)(args...);
     }
     void assertFinished() const override { }
 };
 
-#ifdef JS_GC_ZEAL
 // Implementation of the SweepAction interface that yields in a specified zeal
-// mode and then calls another action.
+// mode.
 template <typename... Args>
 class SweepActionMaybeYield final : public SweepAction<GCRuntime*, Args...>
 {
-    using Action = SweepAction<GCRuntime*, Args...>;
-
     ZealMode mode;
-    UniquePtr<Action> action;
-    bool triggered;
+    bool isYielding;
 
   public:
-    SweepActionMaybeYield(UniquePtr<Action> action, ZealMode mode)
-      : mode(mode), action(std::move(action)), triggered(false) {}
+    explicit SweepActionMaybeYield(ZealMode mode)
+      : mode(mode), isYielding(false) {}
 
     IncrementalProgress run(GCRuntime* gc, Args... args) override {
-        if (!triggered && gc->shouldYieldForZeal(mode)) {
-            triggered = true;
+#ifdef JS_GC_ZEAL
+        if (!isYielding && gc->shouldYieldForZeal(mode)) {
+            isYielding = true;
             return NotFinished;
         }
 
-        triggered = false;
-        return action->run(gc, args...);
+        isYielding = false;
+#endif
+        return Finished;
     }
 
     void assertFinished() const override {
-        MOZ_ASSERT(!triggered);
-    }
+        MOZ_ASSERT(!isYielding);
+    }
+
+    // These actions should be skipped if GC zeal is not configured.
+#ifndef JS_GC_ZEAL
+    bool shouldSkip() override {
+        return true;
+    }
+#endif
 };
-#endif
 
 // Implementation of the SweepAction interface that calls a list of actions in
 // sequence.
 template <typename... Args>
 class SweepActionSequence final : public SweepAction<Args...>
 {
     using Action = SweepAction<Args...>;
     using ActionVector = Vector<UniquePtr<Action>, 0, SystemAllocPolicy>;
     using Iter = IncrementalIter<ContainerIter<ActionVector>>;
 
     ActionVector actions;
     typename Iter::State iterState;
 
   public:
     bool init(UniquePtr<Action>* acts, size_t count) {
         for (size_t i = 0; i < count; i++) {
-            if (!actions.emplaceBack(std::move(acts[i]))) {
+            auto& action = acts[i];
+            if (action->shouldSkip()) {
+                continue;
+            }
+            if (!actions.emplaceBack(std::move(action))) {
                 return false;
             }
         }
         return true;
     }
 
     IncrementalProgress run(Args... args) override {
         for (Iter iter(iterState, actions); !iter.done(); iter.next()) {
@@ -6860,24 +6859,24 @@ class RemoveLastTemplateParameter<Target
 };
 
 template <typename... Args>
 static UniquePtr<SweepAction<GCRuntime*, Args...>>
 Call(IncrementalProgress (GCRuntime::*method)(Args...)) {
    return MakeUnique<SweepActionCall<Args...>>(method);
 }
 
-template <typename... Args>
-static UniquePtr<SweepAction<GCRuntime*, Args...>>
-MaybeYield(ZealMode zealMode, UniquePtr<SweepAction<GCRuntime*, Args...>> action) {
-#ifdef JS_GC_ZEAL
-    return js::MakeUnique<SweepActionMaybeYield<Args...>>(std::move(action), zealMode);
-#else
-    return action;
-#endif
+static UniquePtr<SweepAction<GCRuntime*, FreeOp*, SliceBudget&>>
+MaybeYield(ZealMode zealMode) {
+    return js::MakeUnique<SweepActionMaybeYield<FreeOp*, SliceBudget&>>(zealMode);
+}
+
+static UniquePtr<SweepAction<GCRuntime*, FreeOp*, SliceBudget&, Zone*>>
+MaybeYieldInZoneLoop(ZealMode zealMode) {
+    return js::MakeUnique<SweepActionMaybeYield<FreeOp*, SliceBudget&, Zone*>>(zealMode);
 }
 
 template <typename... Args, typename... Rest>
 static UniquePtr<SweepAction<Args...>>
 Sequence(UniquePtr<SweepAction<Args...>> first, Rest... rest)
 {
     UniquePtr<SweepAction<Args...>> actions[] = { std::move(first), std::move(rest)... };
     auto seq = MakeUnique<SweepActionSequence<Args...>>();
@@ -6934,35 +6933,33 @@ GCRuntime::initSweepActions()
     using namespace sweepaction;
     using sweepaction::Call;
 
     sweepActions.ref() =
         RepeatForSweepGroup(rt,
             Sequence(
                 Call(&GCRuntime::endMarkingSweepGroup),
                 Call(&GCRuntime::beginSweepingSweepGroup),
-#ifdef JS_GC_ZEAL
-                Call(&GCRuntime::maybeYieldForSweepingZeal),
-#endif
-                MaybeYield(ZealMode::YieldBeforeSweepingAtoms,
-                           Call(&GCRuntime::sweepAtomsTable)),
-                MaybeYield(ZealMode::YieldBeforeSweepingCaches,
-                           Call(&GCRuntime::sweepWeakCaches)),
+                MaybeYield(ZealMode::IncrementalMultipleSlices),
+                MaybeYield(ZealMode::YieldBeforeSweepingAtoms),
+                Call(&GCRuntime::sweepAtomsTable),
+                MaybeYield(ZealMode::YieldBeforeSweepingCaches),
+                Call(&GCRuntime::sweepWeakCaches),
                 ForEachZoneInSweepGroup(rt,
                     Sequence(
-                        MaybeYield(ZealMode::YieldBeforeSweepingTypes,
-                                   Call(&GCRuntime::sweepTypeInformation)),
-                        MaybeYield(ZealMode::YieldBeforeSweepingObjects,
-                                   ForEachAllocKind(ForegroundObjectFinalizePhase.kinds,
-                                                    Call(&GCRuntime::finalizeAllocKind))),
-                        MaybeYield(ZealMode::YieldBeforeSweepingNonObjects,
-                                   ForEachAllocKind(ForegroundNonObjectFinalizePhase.kinds,
-                                                    Call(&GCRuntime::finalizeAllocKind))),
-                        MaybeYield(ZealMode::YieldBeforeSweepingShapeTrees,
-                                   Call(&GCRuntime::sweepShapeTree)),
+                        MaybeYieldInZoneLoop(ZealMode::YieldBeforeSweepingTypes),
+                        Call(&GCRuntime::sweepTypeInformation),
+                        MaybeYieldInZoneLoop(ZealMode::YieldBeforeSweepingObjects),
+                        ForEachAllocKind(ForegroundObjectFinalizePhase.kinds,
+                                         Call(&GCRuntime::finalizeAllocKind)),
+                        MaybeYieldInZoneLoop(ZealMode::YieldBeforeSweepingNonObjects),
+                        ForEachAllocKind(ForegroundNonObjectFinalizePhase.kinds,
+                                         Call(&GCRuntime::finalizeAllocKind)),
+                        MaybeYieldInZoneLoop(ZealMode::YieldBeforeSweepingShapeTrees),
+                        Call(&GCRuntime::sweepShapeTree),
                         Call(&GCRuntime::releaseSweptEmptyArenas))),
                 Call(&GCRuntime::endSweepingSweepGroup)));
 
     return sweepActions != nullptr;
 }
 
 IncrementalProgress
 GCRuntime::performSweepActions(SliceBudget& budget)
--- a/js/src/gc/GCRuntime.h
+++ b/js/src/gc/GCRuntime.h
@@ -59,16 +59,17 @@ enum IncrementalProgress
 // types are not deduced but come ultimately from the type of a function pointer
 // passed to SweepFunc.
 template <typename... Args>
 struct SweepAction
 {
     virtual ~SweepAction() {}
     virtual IncrementalProgress run(Args... args) = 0;
     virtual void assertFinished() const = 0;
+    virtual bool shouldSkip() { return false; }
 };
 
 class ChunkPool
 {
     Chunk* head_;
     size_t count_;
 
   public:
@@ -626,19 +627,16 @@ class GCRuntime
 
     void beginSweepPhase(JS::gcreason::Reason reason, AutoGCSession& session);
     void groupZonesForSweeping(JS::gcreason::Reason reason);
     MOZ_MUST_USE bool findInterZoneEdges();
     void getNextSweepGroup();
     IncrementalProgress endMarkingSweepGroup(FreeOp* fop, SliceBudget& budget);
     void markIncomingCrossCompartmentPointers(MarkColor color);
     IncrementalProgress beginSweepingSweepGroup(FreeOp* fop, SliceBudget& budget);
-#ifdef JS_GC_ZEAL
-    IncrementalProgress maybeYieldForSweepingZeal(FreeOp* fop, SliceBudget& budget);
-#endif
     bool shouldReleaseObservedTypes();
     void sweepDebuggerOnMainThread(FreeOp* fop);
     void sweepJitDataOnMainThread(FreeOp* fop);
     IncrementalProgress endSweepingSweepGroup(FreeOp* fop, SliceBudget& budget);
     IncrementalProgress performSweepActions(SliceBudget& sliceBudget);
     IncrementalProgress sweepTypeInformation(FreeOp* fop, SliceBudget& budget, Zone* zone);
     IncrementalProgress releaseSweptEmptyArenas(FreeOp* fop, SliceBudget& budget, Zone* zone);
     void startSweepingAtomsTable();
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/modules/bug-1502669.js
@@ -0,0 +1,5 @@
+// |jit-test| error: ReferenceError
+var g = newGlobal();
+g.parent = this;
+g.eval("new Debugger(parent).onExceptionUnwind = function () { hits++; };");
+import('')();
--- a/js/src/jit/JitOptions.cpp
+++ b/js/src/jit/JitOptions.cpp
@@ -229,22 +229,31 @@ DefaultJitOptions::DefaultJitOptions()
     const char* forcedRegisterAllocatorEnv = "JIT_OPTION_forcedRegisterAllocator";
     if (const char* env = getenv(forcedRegisterAllocatorEnv)) {
         forcedRegisterAllocator = LookupRegisterAllocator(env);
         if (!forcedRegisterAllocator.isSome()) {
             Warn(forcedRegisterAllocatorEnv, env);
         }
     }
 
+#if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
+    SET_DEFAULT(spectreIndexMasking, false);
+    SET_DEFAULT(spectreObjectMitigationsBarriers, false);
+    SET_DEFAULT(spectreObjectMitigationsMisc, false);
+    SET_DEFAULT(spectreStringMitigations, false);
+    SET_DEFAULT(spectreValueMasking, false);
+    SET_DEFAULT(spectreJitToCxxCalls, false);
+#else
     SET_DEFAULT(spectreIndexMasking, true);
     SET_DEFAULT(spectreObjectMitigationsBarriers, true);
     SET_DEFAULT(spectreObjectMitigationsMisc, true);
     SET_DEFAULT(spectreStringMitigations, true);
     SET_DEFAULT(spectreValueMasking, true);
     SET_DEFAULT(spectreJitToCxxCalls, true);
+#endif
 
     // Toggles whether unboxed plain objects can be created by the VM.
     SET_DEFAULT(disableUnboxedObjects, false);
 
     // Toggles the optimization whereby offsets are folded into loads and not
     // included in the bounds check.
     SET_DEFAULT(wasmFoldOffsets, true);
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -4981,21 +4981,17 @@ ShellModuleDynamicImportHook(JSContext* 
     MOZ_ASSERT(hookValue.toObject().is<JSFunction>());
 
     JS::AutoValueArray<3> args(cx);
     args[0].set(referencingPrivate);
     args[1].setString(specifier);
     args[2].setObject(*promise);
 
     RootedValue result(cx);
-    if (!JS_CallFunctionValue(cx, nullptr, hookValue, args, &result)) {
-        return false;
-    }
-
-    return true;
+    return JS_CallFunctionValue(cx, nullptr, hookValue, args, &result);
 }
 
 static bool
 GetModuleLoadPath(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     ShellContext* sc = GetShellContext(cx);
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3712,16 +3712,32 @@ nsLayoutUtils::PaintFrame(gfxContext* aR
           && !presShell->GetRootScrollFrame()) {
         // In cases where the root document is a XUL document, we want to take
         // the ViewID from the root element, as that will be the ViewID of the
         // root APZC in the tree. Skip doing this in cases where we know
         // nsGfxScrollFrame::BuilDisplayList will do it instead.
         if (dom::Element* element = presShell->GetDocument()->GetDocumentElement()) {
           id = nsLayoutUtils::FindOrCreateIDFor(element);
         }
+      // In some cases we get a root document here on an APZ-enabled window
+      // that doesn't have the root displayport initialized yet, even though
+      // the ChromeProcessController is supposed to do it when the widget is
+      // created. This can happen simply because the ChromeProcessController
+      // does it on the next spin of the event loop, and we can trigger a paint
+      // synchronously after window creation but before that runs. In that case
+      // we should initialize the root displayport here before we do the paint.
+      } else if (XRE_IsParentProcess() && presContext->IsRoot()
+          && presShell->GetDocument() != nullptr
+          && presShell->GetRootScrollFrame() != nullptr
+          && nsLayoutUtils::UsesAsyncScrolling(presShell->GetRootScrollFrame())) {
+        if (dom::Element* element = presShell->GetDocument()->GetDocumentElement()) {
+          if (!nsLayoutUtils::HasDisplayPort(element)) {
+            APZCCallbackHelper::InitializeRootDisplayport(presShell);
+          }
+        }
       }
 
       nsDisplayListBuilder::AutoCurrentScrollParentIdSetter idSetter(&builder, id);
 
       builder.SetVisibleRect(visibleRect);
       builder.SetIsBuilding(true);
       builder.SetAncestorHasApzAwareEventHandler(
           gfxPlatform::AsyncPanZoomEnabled() &&
--- a/media/libcubeb/README_MOZILLA
+++ b/media/libcubeb/README_MOZILLA
@@ -1,8 +1,8 @@
 The source from this directory was copied from the cubeb
 git repository using the update.sh script.  The only changes
 made were those applied by update.sh and the addition of
 Makefile.in build files for the Mozilla build system.
 
 The cubeb git repository is: git://github.com/kinetiknz/cubeb.git
 
-The git commit ID used was 04d58b66057171d25413498b3a4d0607fd500bb8 (2018-10-24 08:43:52 +1300)
+The git commit ID used was 9a7a55153e7f9b9e0036ab023909c7bc4a41688b (2018-10-30 09:05:26 +1300)
--- a/media/libcubeb/src/cubeb_audiounit.cpp
+++ b/media/libcubeb/src/cubeb_audiounit.cpp
@@ -3408,17 +3408,17 @@ audiounit_get_devices_of_type(cubeb_devi
                                    devices.data());
   if (ret != noErr) {
     return vector<AudioObjectID>();
   }
 
   // Remove the aggregate device from the list of devices (if any).
   for (auto it = devices.begin(); it != devices.end();) {
     CFStringRef name = get_device_name(*it);
-    if (CFStringFind(name, CFSTR("CubebAggregateDevice"), 0).location !=
+    if (name && CFStringFind(name, CFSTR("CubebAggregateDevice"), 0).location !=
         kCFNotFound) {
       it = devices.erase(it);
     } else {
       it++;
     }
   }
 
   /* Expected sorted but did not find anything in the docs. */
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1532,22 +1532,31 @@ pref("javascript.options.mem.gc_max_empt
 pref("javascript.options.showInConsole", false);
 
 pref("javascript.options.shared_memory", false);
 
 pref("javascript.options.throw_on_debuggee_would_run", false);
 pref("javascript.options.dump_stack_on_debuggee_would_run", false);
 
 // Spectre security vulnerability mitigations.
+#if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
+pref("javascript.options.spectre.index_masking", false);
+pref("javascript.options.spectre.object_mitigations.barriers", false);
+pref("javascript.options.spectre.object_mitigations.misc", false);
+pref("javascript.options.spectre.string_mitigations", false);
+pref("javascript.options.spectre.value_masking", false);
+pref("javascript.options.spectre.jit_to_C++_calls", false);
+#else
 pref("javascript.options.spectre.index_masking", true);
 pref("javascript.options.spectre.object_mitigations.barriers", true);
 pref("javascript.options.spectre.object_mitigations.misc", true);
 pref("javascript.options.spectre.string_mitigations", true);
 pref("javascript.options.spectre.value_masking", true);
 pref("javascript.options.spectre.jit_to_C++_calls", true);
+#endif
 
 // Streams API
 pref("javascript.options.streams", false);
 
 // advanced prefs
 pref("advanced.mailftp",                    false);
 pref("image.animation_mode",                "normal");
 
--- a/servo/components/style/properties/helpers/animated_properties.mako.rs
+++ b/servo/components/style/properties/helpers/animated_properties.mako.rs
@@ -2346,20 +2346,31 @@ impl Animate for ComputedRotate {
     fn animate(
         &self,
         other: &Self,
         procedure: Procedure,
     ) -> Result<Self, ()> {
         let from = ComputedRotate::resolve(self);
         let to = ComputedRotate::resolve(other);
 
-        let (fx, fy, fz, fa) =
+        let (mut fx, mut fy, mut fz, fa) =
             transform::get_normalized_vector_and_angle(from.0, from.1, from.2, from.3);
-        let (tx, ty, tz, ta) =
+        let (mut tx, mut ty, mut tz, ta) =
             transform::get_normalized_vector_and_angle(to.0, to.1, to.2, to.3);
+
+        if fa == Angle::from_degrees(0.) {
+            fx = tx;
+            fy = ty;
+            fz = tz;
+        } else if ta == Angle::from_degrees(0.) {
+            tx = fx;
+            ty = fy;
+            tz = fz;
+        }
+
         if (fx, fy, fz) == (tx, ty, tz) {
             return Ok(Rotate::Rotate3D(fx, fy, fz, fa.animate(&ta, procedure)?));
         }
 
         let fv = DirectionVector::new(fx, fy, fz);
         let tv = DirectionVector::new(tx, ty, tz);
         let fq = Quaternion::from_direction_and_angle(&fv, fa.radians64());
         let tq = Quaternion::from_direction_and_angle(&tv, ta.radians64());
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/FileAPI/reading-data-section/filereader_abort.html.ini
@@ -0,0 +1,4 @@
+[filereader_abort.html]
+  [Aborting after read]
+    expected: FAIL
+
--- a/testing/web-platform/meta/css/css-writing-modes/abs-pos-non-replaced-icb-vlr-021.xht.ini
+++ b/testing/web-platform/meta/css/css-writing-modes/abs-pos-non-replaced-icb-vlr-021.xht.ini
@@ -1,6 +1,3 @@
 [abs-pos-non-replaced-icb-vlr-021.xht]
-  expected:
-    if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
-    if debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
-    if not debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
+  disabled:
+    if (os == "win"): https://bugzilla.mozilla.org/show_bug.cgi?id=1500276
--- a/testing/web-platform/tests/css/css-transforms/animation/list-interpolation.html
+++ b/testing/web-platform/tests/css/css-transforms/animation/list-interpolation.html
@@ -6,115 +6,135 @@
 <link rel="help" href="https://drafts.csswg.org/css-transforms-1/#interpolation-of-transforms">
 <meta name="assert" content="Interpolation of transform function lists is performed as follows">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="resources/interpolation-testcommon.js"></script>
 </head>
 <body>
 <script>
-// none -> none
 test_interpolation(
   {
     property: 'transform',
     from: 'none',
     to: 'none',
   },
-  [{ at: 0.25, expect: 'none' }]
+  [{ at: 0.25, expect: 'none' }],
+  'none -> none'
 );
 
-// none -> something
 test_interpolation(
   {
     property: 'transform',
     from: 'none',
     to: 'translate(200px) rotate(720deg)',
   },
-  [{ at: 0.25, expect: 'translate(50px) rotate(180deg)' }]
+  [{ at: 0.25, expect: 'translate(50px) rotate(180deg)' }],
+  'none -> something'
 );
 
-// something -> none
 test_interpolation(
   {
     property: 'transform',
     from: 'translate(200px) rotate(720deg)',
     to: 'none',
   },
-  [{ at: 0.25, expect: 'translate(150px) rotate(540deg)' }]
+  [{ at: 0.25, expect: 'translate(150px) rotate(540deg)' }],
+  'something -> none'
 );
 
-// Mismatched lengths (from is shorter), common part matches
 test_interpolation(
   {
     property: 'transform',
     from: 'translate(100px)',
     to: 'translate(200px) rotate(720deg)',
   },
-  [{ at: 0.25, expect: 'translate(125px) rotate(180deg)' }]
+  [{ at: 0.25, expect: 'translate(125px) rotate(180deg)' }],
+  'Mismatched lengths (from is shorter), common part matches'
 );
 
-// Mismatched lengths (to is shorter), common part matches
 test_interpolation(
   {
     property: 'transform',
     from: 'translate(100px) rotate(720deg)',
     to: 'translate(200px)',
   },
-  [{ at: 0.25, expect: 'translate(125px) rotate(540deg)' }]
+  [{ at: 0.25, expect: 'translate(125px) rotate(540deg)' }],
+  'Mismatched lengths (to is shorter), common part matches'
 );
 
-// Perfect match
 test_interpolation(
   {
     property: 'transform',
     from: 'scale(2) rotate(360deg) translate(100px) matrix(1, 0, 0, 1, 100, 0) skew(0deg)',
     to: 'scale(3) rotate(1080deg) translate(200px) matrix(1, 0, 0, 1, 0, 200) skew(720deg)',
   },
   [
     {
       at: 0.25,
       expect: 'scale(2.25) rotate(540deg) translate(125px) matrix(1, 0, 0, 1, 75, 50) skew(180deg)',
     },
-  ]
+  ],
+  'Perfect match'
 );
 
-// Matches on primitives
 test_interpolation(
   {
     property: 'transform',
     from: 'translateX(100px) scaleX(3) translate(500px) scale(2)',
     to: 'translateY(200px) scale(5) translateX(100px) scaleY(3)',
   },
-  [{ at: 0.25, expect: 'translate(75px, 50px) scale(3.5, 2) translate(400px, 0px) scale(1.75, 2.25)' }]
+  [{ at: 0.25, expect: 'translate(75px, 50px) scale(3.5, 2) translate(400px, 0px) scale(1.75, 2.25)' }],
+  'Matches on primitives'
 );
 
-// Common prefix
+test_interpolation(
+  {
+    property: 'transform',
+    from: 'rotateX(90deg) translateX(100px)',
+    to: 'rotate3d(50, 0, 0, 180deg) translateY(200px)',
+  },
+  [{ at: 0.25, expect: 'rotateX(112.5deg) translate(75px, 50px)' }],
+  'Match on rotation vector'
+);
+
+test_interpolation(
+  {
+    property: 'transform',
+    from: 'rotateX(90deg) translateX(100px)',
+    to: 'rotateY(0deg) translateY(200px)',
+  },
+  [{ at: 0.25, expect: 'rotateX(67.5deg) translate(75px, 50px)' }],
+  'Match on rotation due to 0deg angle'
+);
+
 test_interpolation(
   {
     property: 'transform',
     from: 'rotate(0deg) translate(100px)',
     to: 'rotate(720deg) scale(2) translate(200px)',
   },
-  [{ at: 0.25, expect: 'rotate(180deg) matrix(1.25, 0, 0, 1.25, 175, 0)' }]
+  [{ at: 0.25, expect: 'rotate(180deg) matrix(1.25, 0, 0, 1.25, 175, 0)' }],
+  'Common prefix'
 );
 
-// Complete mismatch (except length)
 test_interpolation(
   {
     property: 'transform',
     from: 'scale(2) rotate(0deg) translate(100px)',
     to: 'rotate(720deg) scale(2) translate(200px)',
   },
-  [{ at: 0.25, expect: 'matrix(2, 0, 0, 2, 250, 0)' }]
+  [{ at: 0.25, expect: 'matrix(2, 0, 0, 2, 250, 0)' }],
+  'Complete mismatch (except length)'
 );
 
-// Complete mismatch including length
 test_interpolation(
   {
     property: 'transform',
     from: 'scale(2) rotate(0deg)',
     to: 'rotate(720deg) scale(2) translate(200px)',
   },
-  [{ at: 0.25, expect: 'matrix(2, 0, 0, 2, 100, 0)' }]
+  [{ at: 0.25, expect: 'matrix(2, 0, 0, 2, 100, 0)' }],
+  'Complete mismatch including length'
 );
 </script>
 </body>
 </html>
--- a/testing/web-platform/tests/css/css-transforms/animation/resources/interpolation-testcommon.js
+++ b/testing/web-platform/tests/css/css-transforms/animation/resources/interpolation-testcommon.js
@@ -1,24 +1,25 @@
 'use strict';
-function test_interpolation(settings, expectations) {
+function test_interpolation(settings, expectations, name) {
+  var message_prefix = name ? name + ': ' : '';
   // Returns a timing function that at 0.5 evaluates to progress.
   function timingFunction(progress) {
     if (progress === 0)
       return 'steps(1, end)';
     if (progress === 1)
       return 'steps(1, start)';
     var y = (8 * progress - 1) / 6;
     return 'cubic-bezier(0, ' + y + ', 1, ' + y + ')';
   }
 
   test(function(){
     assert_true(CSS.supports(settings.property, settings.from), 'Value "' + settings.from + '" is supported by ' + settings.property);
     assert_true(CSS.supports(settings.property, settings.to), 'Value "' + settings.to + '" is supported by ' + settings.property);
-  }, '"' + settings.from + '" and "' + settings.to + '" are valid ' + settings.property + ' values');
+  }, message_prefix + '"' + settings.from + '" and "' + settings.to + '" are valid ' + settings.property + ' values');
 
   for (var i = 0; i < expectations.length; ++i) {
     var progress = expectations[i].at;
     var expectation = expectations[i].expect;
     var animationId = 'anim' + i;
     var targetId = 'target' + i;
     var referenceId = 'reference' + i;
 
@@ -44,11 +45,11 @@ function test_interpolation(settings, ex
       document.body.appendChild(target);
 
       var reference = document.createElement('div');
       reference.id = referenceId;
       document.body.appendChild(reference);
       reference.style = '';
 
       assert_equals(getComputedStyle(target)[settings.property], getComputedStyle(reference)[settings.property]);
-    }, 'Animation between "' + settings.from + '" and "' + settings.to + '" at progress ' + progress);
+    }, message_prefix + 'Animation between "' + settings.from + '" and "' + settings.to + '" at progress ' + progress);
   }
 }