Merge inbound to mozilla-central. a=merge
authorCiure Andrei <aciure@mozilla.com>
Tue, 10 Jul 2018 00:59:02 +0300
changeset 425523 19edc7c22303a37b7b5fea326171288eba17d788
parent 425509 8e3c84df8f675600be2c39f73d962f1419a4b9c2 (current diff)
parent 425522 e711420b85f70b765c7c69c80a478250bc886229 (diff)
child 425524 9f03501341bf35bc502f69f870746ffac73992ae
child 425544 771645fe5b4c9c1c2e00d7bff661d22b289d54aa
child 425565 4511c613a7539920e5b224124f8f1d14ac6084a0
push id34256
push useraciure@mozilla.com
push dateMon, 09 Jul 2018 21:59:26 +0000
treeherdermozilla-central@19edc7c22303 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone63.0a1
first release with
nightly linux32
19edc7c22303 / 63.0a1 / 20180709221247 / files
nightly linux64
19edc7c22303 / 63.0a1 / 20180709221247 / files
nightly mac
19edc7c22303 / 63.0a1 / 20180709221247 / files
nightly win32
19edc7c22303 / 63.0a1 / 20180709221247 / files
nightly win64
19edc7c22303 / 63.0a1 / 20180709221247 / 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
toolkit/components/telemetry/Histograms.json
toolkit/themes/linux/global/arrow/arrow-dn-hov.gif
toolkit/themes/linux/global/arrow/arrow-up-hov.gif
--- a/browser/base/content/sanitize.xul
+++ b/browser/base/content/sanitize.xul
@@ -78,29 +78,16 @@
           </vbox>
         </hbox>
         <spacer flex="1"/>
       </vbox>
 
 
     <separator class="thin"/>
 
-    <hbox id="detailsExpanderWrapper" align="center">
-      <button type="image"
-              id="detailsExpander"
-              class="expander-down"
-              persist="class"
-              oncommand="gSanitizePromptDialog.toggleItemList();"/>
-      <label id="detailsExpanderLabel"
-             value="&detailsProgressiveDisclosure.label;"
-             accesskey="&detailsProgressiveDisclosure.accesskey;"
-             control="detailsExpander"/>
-    </hbox>
-
-    <vbox id="itemList" collapsed="true" persist="collapsed">
     <groupbox orient="horizontal">
       <caption><label>&historySection.label;</label></caption>
       <grid flex="1">
         <columns>
           <column style="width: &sanitizePrefs2.column.width;"/>
           <column flex="1"/>
         </columns>
         <rows>
@@ -149,11 +136,10 @@
             <checkbox label="&itemOfflineApps.label;"
                       accesskey="&itemOfflineApps.accesskey;"
                       preference="privacy.cpd.offlineApps"
                       onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
           </row>
         </rows>
       </grid>
     </groupbox>
-    </vbox>
   </vbox>
 </dialog>
--- a/browser/base/content/sanitizeDialog.js
+++ b/browser/base/content/sanitizeDialog.js
@@ -111,31 +111,25 @@ var gSanitizePromptDialog = {
       Cu.reportError("Exception during sanitize: " + er);
       return true; // We *do* want to close immediately on error.
     }
   },
 
   /**
    * If the panel that displays a warning when the duration is "Everything" is
    * not set up, sets it up.  Otherwise does nothing.
-   *
-   * @param aDontShowItemList Whether only the warning message should be updated.
-   *                          True means the item list visibility status should not
-   *                          be changed.
    */
-  prepareWarning(aDontShowItemList) {
+  prepareWarning() {
     // If the date and time-aware locale warning string is ever used again,
     // initialize it here.  Currently we use the no-visits warning string,
     // which does not include date and time.  See bug 480169 comment 48.
 
     var warningStringID;
     if (this.hasNonSelectedItems()) {
       warningStringID = "sanitizeSelectedWarning";
-      if (!aDontShowItemList)
-        this.showItemList();
     } else {
       warningStringID = "sanitizeEverythingWarning2";
     }
 
     var warningDesc = document.getElementById("sanitizeEverythingWarning");
     warningDesc.textContent =
       this.bundleBrowser.getString(warningStringID);
   },
@@ -157,17 +151,17 @@ var gSanitizePromptDialog = {
     // privacy.sanitize.timeSpan, which doesn't affect the button's status).
     var found = this._getItemPrefs().some(pref => !!pref.value && !pref.disabled);
 
     try {
       document.documentElement.getButton("accept").disabled = !found;
     } catch (e) { }
 
     // Update the warning prompt if needed
-    this.prepareWarning(true);
+    this.prepareWarning();
 
     return undefined;
   },
 
   /**
    * Sanitizer.prototype.sanitize() requires the prefs to be up-to-date.
    * Because the type of this prefwindow is "child" -- and that's needed because
    * without it the dialog has no OK and Cancel buttons -- the prefs are not
@@ -197,52 +191,9 @@ var gSanitizePromptDialog = {
     let checkboxes = document.querySelectorAll("checkbox[preference]");
     for (let i = 0; i < checkboxes.length; ++i) {
       let pref = Preferences.get(checkboxes[i].getAttribute("preference"));
       if (!pref.value)
         return true;
     }
     return false;
   },
-
-  /**
-   * Show the history items list.
-   */
-  showItemList() {
-    var itemList = document.getElementById("itemList");
-    var expanderButton = document.getElementById("detailsExpander");
-
-    if (itemList.collapsed) {
-      expanderButton.className = "expander-up";
-      itemList.setAttribute("collapsed", "false");
-      if (document.documentElement.boxObject.height)
-        window.resizeBy(0, itemList.boxObject.height);
-    }
-  },
-
-  /**
-   * Hide the history items list.
-   */
-  hideItemList() {
-    var itemList = document.getElementById("itemList");
-    var expanderButton = document.getElementById("detailsExpander");
-
-    if (!itemList.collapsed) {
-      expanderButton.className = "expander-down";
-      window.resizeBy(0, -itemList.boxObject.height);
-      itemList.setAttribute("collapsed", "true");
-    }
-  },
-
-  /**
-   * Called by the item list expander button to toggle the list's visibility.
-   */
-  toggleItemList() {
-    var itemList = document.getElementById("itemList");
-
-    if (itemList.collapsed)
-      this.showItemList();
-    else
-      this.hideItemList();
-  }
-
-
 };
--- a/browser/base/content/test/sanitize/browser_sanitizeDialog.js
+++ b/browser/base/content/test/sanitize/browser_sanitizeDialog.js
@@ -54,19 +54,16 @@ add_task(async function init() {
 /**
  * Initializes the dialog to its default state.
  */
 add_task(async function default_state() {
   let wh = new WindowHelper();
   wh.onload = function() {
     // Select "Last Hour"
     this.selectDuration(Sanitizer.TIMESPAN_HOUR);
-    // Hide details
-    if (!this.getItemList().collapsed)
-      this.toggleDetails();
     this.acceptDialog();
   };
   wh.open();
   await wh.promiseClosed;
 });
 
 /**
  * Cancels the dialog, makes sure history not cleared.
@@ -82,25 +79,16 @@ add_task(async function test_cancel() {
     uris.push(pURI);
   }
   await PlacesTestUtils.addVisits(places);
 
   let wh = new WindowHelper();
   wh.onload = function() {
     this.selectDuration(Sanitizer.TIMESPAN_HOUR);
     this.checkPrefCheckbox("history", false);
-    this.checkDetails(false);
-
-    // Show details
-    this.toggleDetails();
-    this.checkDetails(true);
-
-    // Hide details
-    this.toggleDetails();
-    this.checkDetails(false);
     this.cancelDialog();
   };
   wh.onunload = async function() {
     await promiseHistoryClearedState(uris, false);
     await blankSlate();
     await promiseHistoryClearedState(uris, true);
   };
   wh.open();
@@ -271,26 +259,16 @@ add_task(async function test_everything(
   await PlacesTestUtils.addVisits(places);
   let wh = new WindowHelper();
   wh.onload = function() {
     is(this.isWarningPanelVisible(), false,
        "Warning panel should be hidden after previously accepting dialog " +
        "with a predefined timespan");
     this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
     this.checkPrefCheckbox("history", true);
-    this.checkDetails(true);
-
-    // Hide details
-    this.toggleDetails();
-    this.checkDetails(false);
-
-    // Show details
-    this.toggleDetails();
-    this.checkDetails(true);
-
     this.acceptDialog();
   };
   wh.onunload = async function() {
     await promiseSanitized;
     intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_EVERYTHING,
               "timeSpan pref should be everything after accepting dialog " +
               "with everything selected");
 
@@ -435,121 +413,16 @@ add_task(async function test_form_entrie
     await promiseSanitized;
     let exists = await formNameExists(formEntry);
     is(exists, false, "form entry " + formEntry + " should no longer exist");
   };
   wh.open();
   await wh.promiseClosed;
 });
 
-
-/**
- * Ensure that toggling details persists
- * across dialog openings.
- */
-add_task(async function test_toggling_details_persists() {
-  {
-    let wh = new WindowHelper();
-    wh.onload = function() {
-      // Check all items and select "Everything"
-      this.checkAllCheckboxes();
-      this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
-
-      // Hide details
-      this.toggleDetails();
-      this.checkDetails(false);
-      this.acceptDialog();
-    };
-    wh.open();
-    await wh.promiseClosed;
-  }
-  {
-    let wh = new WindowHelper();
-    wh.onload = function() {
-      // Details should remain closed because all items are checked.
-      this.checkDetails(false);
-
-      // Uncheck history.
-      this.checkPrefCheckbox("history", false);
-      this.acceptDialog();
-    };
-    wh.open();
-    await wh.promiseClosed;
-  }
-  {
-    let wh = new WindowHelper();
-    wh.onload = function() {
-      // Details should be open because not all items are checked.
-      this.checkDetails(true);
-
-      // Modify the Site Preferences item state (bug 527820)
-      this.checkAllCheckboxes();
-      this.checkPrefCheckbox("siteSettings", false);
-      this.acceptDialog();
-    };
-    wh.open();
-    await wh.promiseClosed;
-  }
-  {
-    let wh = new WindowHelper();
-    wh.onload = function() {
-      // Details should be open because not all items are checked.
-      this.checkDetails(true);
-
-      // Hide details
-      this.toggleDetails();
-      this.checkDetails(false);
-      this.cancelDialog();
-    };
-    wh.open();
-    await wh.promiseClosed;
-  }
-  {
-    let wh = new WindowHelper();
-    wh.onload = function() {
-      // Details should be open because not all items are checked.
-      this.checkDetails(true);
-
-      // Select another duration
-      this.selectDuration(Sanitizer.TIMESPAN_HOUR);
-      // Hide details
-      this.toggleDetails();
-      this.checkDetails(false);
-      this.acceptDialog();
-    };
-    wh.open();
-    await wh.promiseClosed;
-  }
-  {
-    let wh = new WindowHelper();
-    wh.onload = function() {
-      // Details should not be open because "Last Hour" is selected
-      this.checkDetails(false);
-
-      this.cancelDialog();
-    };
-    wh.open();
-    await wh.promiseClosed;
-  }
-  {
-    let wh = new WindowHelper();
-    wh.onload = function() {
-      // Details should have remained closed
-      this.checkDetails(false);
-
-      // Show details
-      this.toggleDetails();
-      this.checkDetails(true);
-      this.cancelDialog();
-    };
-    wh.open();
-    await wh.promiseClosed;
-  }
-});
-
 // Test for offline cache deletion
 add_task(async function test_offline_cache() {
   // Prepare stuff, we will work with www.example.com
   var URL = "http://www.example.com";
   var URI = makeURI(URL);
   var principal = Services.scriptSecurityManager.createCodebasePrincipal(URI, {});
 
   // Give www.example.com privileges to store offline data
@@ -562,18 +435,16 @@ add_task(async function test_offline_cac
   var appcachegroupid = appcacheserv.buildGroupIDForInfo(makeURI(URL + "/manifest"), Services.loadContextInfo.default);
   var appcache = appcacheserv.createApplicationCache(appcachegroupid);
   var storage = Services.cache2.appCacheStorage(Services.loadContextInfo.default, appcache);
 
   // Open the dialog
   let wh = new WindowHelper();
   wh.onload = function() {
     this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
-    // Show details
-    this.toggleDetails();
     // Clear only offlineApps
     this.uncheckAllCheckboxes();
     this.checkPrefCheckbox("offlineApps", true);
     this.acceptDialog();
   };
   wh.onunload = function() {
     // Check if the cache has been deleted
     var size = -1;
@@ -612,18 +483,16 @@ add_task(async function test_offline_app
   var principal = Services.scriptSecurityManager.createCodebasePrincipal(URI, {});
 
   let promiseSanitized = promiseSanitizationComplete();
 
   // Open the dialog
   let wh = new WindowHelper();
   wh.onload = function() {
     this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
-    // Show details
-    this.toggleDetails();
     // Clear only offlineApps
     this.uncheckAllCheckboxes();
     this.checkPrefCheckbox("siteSettings", true);
     this.acceptDialog();
   };
   wh.onunload = async function() {
     await promiseSanitized;
 
@@ -662,46 +531,16 @@ WindowHelper.prototype = {
   /**
    * "Presses" the dialog's Cancel button.
    */
   cancelDialog() {
     this.win.document.documentElement.cancelDialog();
   },
 
   /**
-   * Ensures that the details progressive disclosure button and the item list
-   * hidden by it match up.  Also makes sure the height of the dialog is
-   * sufficient for the item list and warning panel.
-   *
-   * @param aShouldBeShown
-   *        True if you expect the details to be shown and false if hidden
-   */
-  checkDetails(aShouldBeShown) {
-    let button = this.getDetailsButton();
-    let list = this.getItemList();
-    let hidden = list.hidden || list.collapsed;
-    is(hidden, !aShouldBeShown,
-       "Details should be " + (aShouldBeShown ? "shown" : "hidden") +
-       " but were actually " + (hidden ? "hidden" : "shown"));
-    let dir = hidden ? "down" : "up";
-    is(button.className, "expander-" + dir,
-       "Details button should be " + dir + " because item list is " +
-       (hidden ? "" : "not ") + "hidden");
-    let height = 0;
-    if (!hidden) {
-      ok(list.boxObject.height > 30, "listbox has sufficient size");
-      height += list.boxObject.height;
-    }
-    if (this.isWarningPanelVisible())
-      height += this.getWarningPanel().boxObject.height;
-    ok(height < this.win.innerHeight,
-       "Window should be tall enough to fit warning panel and item list");
-  },
-
-  /**
    * (Un)checks a history scope checkbox (browser & download history,
    * form history, etc.).
    *
    * @param aPrefName
    *        The final portion of the checkbox's privacy.cpd.* preference name
    * @param aCheckState
    *        True if the checkbox should be checked, false otherwise
    */
@@ -731,37 +570,23 @@ WindowHelper.prototype = {
     this._checkAllCheckboxesCustom(true);
   },
 
   uncheckAllCheckboxes() {
     this._checkAllCheckboxesCustom(false);
   },
 
   /**
-   * @return The details progressive disclosure button
-   */
-  getDetailsButton() {
-    return this.win.document.getElementById("detailsExpander");
-  },
-
-  /**
    * @return The dialog's duration dropdown
    */
   getDurationDropdown() {
     return this.win.document.getElementById("sanitizeDurationChoice");
   },
 
   /**
-   * @return The item list hidden by the details progressive disclosure button
-   */
-  getItemList() {
-    return this.win.document.getElementById("itemList");
-  },
-
-  /**
    * @return The clear-everything warning box
    */
   getWarningPanel() {
     return this.win.document.getElementById("sanitizeEverythingWarningBox");
   },
 
   /**
    * @return True if the "Everything" warning panel is visible (as opposed to
@@ -852,23 +677,16 @@ WindowHelper.prototype = {
     if (aDurVal === Sanitizer.TIMESPAN_EVERYTHING) {
       is(this.isWarningPanelVisible(), true,
          "Warning panel should be visible for TIMESPAN_EVERYTHING");
     } else {
       is(this.isWarningPanelVisible(), false,
          "Warning panel should not be visible for non-TIMESPAN_EVERYTHING");
     }
   },
-
-  /**
-   * Toggles the details progressive disclosure button.
-   */
-  toggleDetails() {
-    this.getDetailsButton().click();
-  }
 };
 
 function promiseSanitizationComplete() {
   return TestUtils.topicObserved("sanitizer-sanitization-complete");
 }
 
 /**
  * Adds a download to history.
--- a/browser/locales/en-US/chrome/browser/sanitize.dtd
+++ b/browser/locales/en-US/chrome/browser/sanitize.dtd
@@ -24,22 +24,16 @@
 <!ENTITY clearTimeDuration.last2Hours     "Last Two Hours">
 <!ENTITY clearTimeDuration.last4Hours     "Last Four Hours">
 <!ENTITY clearTimeDuration.today          "Today">
 <!ENTITY clearTimeDuration.everything     "Everything">
 <!-- Localization note (clearTimeDuration.suffix) - trailing entity for languages
 that require it.  -->
 <!ENTITY clearTimeDuration.suffix         "">
 
-<!-- LOCALIZATION NOTE (detailsProgressiveDisclosure.*): Labels and accesskeys
-     of the "Details" progressive disclosure button.  See UI mockup at bug
-     480169 -->
-<!ENTITY detailsProgressiveDisclosure.label     "Details">
-<!ENTITY detailsProgressiveDisclosure.accesskey "e">
-
 <!ENTITY historySection.label         "History">
 <!ENTITY dataSection.label            "Data">
 
 <!ENTITY itemHistoryAndDownloads.label     "Browsing &amp; Download History">
 <!ENTITY itemHistoryAndDownloads.accesskey "B">
 <!ENTITY itemFormSearchHistory.label       "Form &amp; Search History">
 <!ENTITY itemFormSearchHistory.accesskey   "F">
 <!ENTITY itemCookies.label                 "Cookies">
--- a/browser/themes/linux/sanitizeDialog.css
+++ b/browser/themes/linux/sanitizeDialog.css
@@ -35,62 +35,15 @@
 }
 
 #sanitizeEverythingWarningDescBox {
   padding: 0 16px;
   margin: 0;
 }
 
 
-/* Progressive disclosure button */
-#detailsExpanderWrapper {
-  padding: 0;
-  margin-top: 6px;
-  margin-bottom: 6px;
-  margin-inline-start: -4px;
-  margin-inline-end: 0;
-}
-
-.expander-up,
-.expander-down {
-  min-width: 0;
-  padding: 2px 0;
-  padding-inline-start: 2px;
-}
-
-.expander-up {
-  list-style-image: url("chrome://global/skin/arrow/arrow-up.gif");
-}
-
-.expander-down {
-  list-style-image: url("chrome://global/skin/arrow/arrow-dn.gif");
-}
-
-.expander-down:hover:active {
-  list-style-image: url("chrome://global/skin/arrow/arrow-dn-hov.gif");
-}
-
-.expander-up:hover:active {
-  list-style-image: url("chrome://global/skin/arrow/arrow-up-hov.gif");
-}
-
-
-/* Make the item list the same width as the warning box */
-#itemList {
-  margin-inline-start: 0;
-  margin-inline-end: 0;
-}
-
-/* Without this a useless scrollbar appears in the listbox when its rows
-   attribute is set to the total number of listitems, as it is currently.  See
-   bug 489958 comment 14 and bug 491788. */
-#itemList > listitem {
-  padding: 1px 0;
-}
-
-
 /* Align the last dialog button with the end of the warning box */
 .dialog-button-box {
   margin-inline-end: 0;
 }
 .dialog-button[dlgtype="accept"] {
   margin-inline-end: 0;
 }
--- a/browser/themes/osx/sanitizeDialog.css
+++ b/browser/themes/osx/sanitizeDialog.css
@@ -31,50 +31,15 @@
 }
 
 #sanitizeEverythingWarningDescBox {
   padding: 0 16px;
   margin: 0;
 }
 
 
-/* Progressive disclosure button */
-#detailsExpanderWrapper {
-  padding: 0;
-  margin-top: 6px;
-  margin-bottom: 6px;
-}
-
-.expander-up,
-.expander-down {
-  padding: 0;
-  margin: 0;
-}
-
-.expander-up {
-  -moz-appearance: -moz-mac-disclosure-button-open;
-}
-
-.expander-down {
-  -moz-appearance: -moz-mac-disclosure-button-closed;
-}
-
-/* Make the item list the same width as the warning box */
-#itemList {
-  margin-inline-start: 0;
-  margin-inline-end: 0;
-}
-
-/* Without this a useless scrollbar appears in the listbox when its rows
-   attribute is set to the total number of listitems, as it is currently.  See
-   bug 489958 comment 14 and bug 491788. */
-#itemList > listitem {
-  padding: 1px 0;
-}
-
-
 /* Align the last dialog button with the end of the warning box */
 .dialog-button-box {
   margin-inline-end: 0;
 }
 .dialog-button[dlgtype="accept"] {
   margin-inline-end: 0;
 }
--- a/browser/themes/windows/sanitizeDialog.css
+++ b/browser/themes/windows/sanitizeDialog.css
@@ -35,48 +35,15 @@
 }
 
 #sanitizeEverythingWarningDescBox {
   padding: 0 16px;
   margin: 0;
 }
 
 
-/* Progressive disclosure button */
-#detailsExpanderWrapper {
-  padding: 0;
-  margin: 6px 0;
-}
-
-.expander-up,
-.expander-down {
-  min-width: 0;
-  margin: 0;
-}
-
-.expander-up > .button-box,
-.expander-down > .button-box {
-  padding: 0;
-}
-
-.expander-up {
-  list-style-image: url("chrome://global/skin/icons/collapse.png");
-}
-
-.expander-down {
-  list-style-image: url("chrome://global/skin/icons/expand.png");
-}
-
-
-/* Make the item list the same width as the warning box */
-#itemList {
-  margin-inline-start: 0;
-  margin-inline-end: 0;
-}
-
-
 /* Align the last dialog button with the end of the warning box */
 .dialog-button-box {
   margin-inline-end: 0;
 }
 .dialog-button[dlgtype="cancel"] {
   margin-inline-end: 0;
 }
--- a/build/virtualenv_packages.txt
+++ b/build/virtualenv_packages.txt
@@ -52,16 +52,18 @@ mozilla.pth:testing/marionette/client
 mozilla.pth:testing/marionette/harness
 mozilla.pth:testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py
 mozilla.pth:testing/marionette/puppeteer/firefox
 mozilla.pth:testing/raptor
 mozilla.pth:testing/talos
 packages.txt:testing/mozbase/packages.txt
 mozilla.pth:tools
 mozilla.pth:testing/web-platform
+mozilla.pth:testing/web-platform/tests/tools/third_party/html5lib
+mozilla.pth:testing/web-platform/tests/tools/third_party/webencodings
 mozilla.pth:testing/web-platform/tests/tools/wptrunner
 mozilla.pth:testing/web-platform/tests/tools/wptserve
 mozilla.pth:testing/web-platform/tests/tools/six
 mozilla.pth:testing/xpcshell
 mozilla.pth:third_party/python/mock-1.0.0
 mozilla.pth:xpcom/typelib/xpt/tools
 mozilla.pth:tools/docs
 mozilla.pth:media/webrtc/trunk/tools/gyp/pylib
--- a/devtools/client/themes/tooltips.css
+++ b/devtools/client/themes/tooltips.css
@@ -167,17 +167,17 @@
 
 .tooltip-flexible-height .tooltip-filler {
   /* In flexible mode the filler should grow as much as possible. */
   flex-grow: 1;
 }
 
 /* type="arrow" overrides: remove arrow decorations for the xul <panel> wrapper */
 
-.tooltip-xul-wrapper[type="arrow"] {
+.tooltip-xul-wrapper[type="arrow"][side] {
   margin: 0;
 }
 
 /* The arrow image is hidden because the panel is opened using openPopupAtScreen(). */
 
 /* Remove all decorations on .panel-arrowcontent is the tooltip content container. */
 .tooltip-xul-wrapper[type="arrow"] .panel-arrowcontent {
   margin: 0;
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -1513,18 +1513,17 @@ Navigator::HasUserMediaSupport(JSContext
   return Preferences::GetBool("media.navigator.enabled", false) ||
          Preferences::GetBool("media.peerconnection.enabled", false);
 }
 
 /* static */
 already_AddRefed<nsPIDOMWindowInner>
 Navigator::GetWindowFromGlobal(JSObject* aGlobal)
 {
-  nsCOMPtr<nsPIDOMWindowInner> win =
-    do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(aGlobal));
+  nsCOMPtr<nsPIDOMWindowInner> win = xpc::WindowOrNull(aGlobal);
   return win.forget();
 }
 
 nsresult
 Navigator::GetPlatform(nsAString& aPlatform, bool aUsePrefOverriddenValue)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -2226,30 +2226,16 @@ nsContentUtils::InProlog(nsINode *aNode)
   }
 
   nsIDocument* doc = parent->AsDocument();
   nsIContent* root = doc->GetRootElement();
 
   return !root || doc->ComputeIndexOf(aNode) < doc->ComputeIndexOf(root);
 }
 
-nsIDocument*
-nsContentUtils::GetDocumentFromCaller()
-{
-  AutoJSContext cx;
-
-  nsCOMPtr<nsPIDOMWindowInner> win =
-    do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(JS::CurrentGlobalOrNull(cx)));
-  if (!win) {
-    return nullptr;
-  }
-
-  return win->GetExtantDoc();
-}
-
 bool
 nsContentUtils::IsCallerChrome()
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (SubjectPrincipal() == sSystemPrincipal) {
     return true;
   }
 
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -625,28 +625,16 @@ public:
    * which is known to the IO service, and has the URI_NORELATIVE flag.
    *
    * If the URL may be treated as absolute in some cases, but relative in others
    * (for instance, "http:foo", which can be either an absolute or relative URL,
    * depending on the context), this function returns false.
    */
   static bool IsAbsoluteURL(const nsACString& aURL);
 
-  /**
-   * GetDocumentFromCaller gets its document by looking at the last called
-   * function and finding the document that the function itself relates to.
-   * For example, consider two windows A and B in the same origin. B has a
-   * function which does something that ends up needing the current document.
-   * If a script in window A were to call B's function, GetDocumentFromCaller
-   * would find that function (in B) and return B's document.
-   *
-   * @return The document or null if no JS Context.
-   */
-  static nsIDocument* GetDocumentFromCaller();
-
   // Check if a node is in the document prolog, i.e. before the document
   // element.
   static bool InProlog(nsINode *aNode);
 
   static nsNameSpaceManager* NameSpaceManager()
   {
     return sNameSpaceManager;
   }
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -57,34 +57,16 @@ nsJSUtils::GetCallingLocation(JSContext*
   if (!JS::DescribeScriptedCaller(aContext, &filename, aLineno, aColumn)) {
     return false;
   }
 
   aFilename.Assign(NS_ConvertUTF8toUTF16(filename.get()));
   return true;
 }
 
-nsIScriptGlobalObject *
-nsJSUtils::GetStaticScriptGlobal(JSObject* aObj)
-{
-  if (!aObj)
-    return nullptr;
-  return xpc::WindowGlobalOrNull(aObj);
-}
-
-nsIScriptContext *
-nsJSUtils::GetStaticScriptContext(JSObject* aObj)
-{
-  nsIScriptGlobalObject *nativeGlobal = GetStaticScriptGlobal(aObj);
-  if (!nativeGlobal)
-    return nullptr;
-
-  return nativeGlobal->GetScriptContext();
-}
-
 uint64_t
 nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(JSContext *aContext)
 {
   if (!aContext)
     return 0;
 
   nsGlobalWindowInner* win = xpc::CurrentWindowOrNull(aContext);
   return win ? win->WindowID() : 0;
--- a/dom/base/nsJSUtils.h
+++ b/dom/base/nsJSUtils.h
@@ -39,20 +39,16 @@ class nsJSUtils
 public:
   static bool GetCallingLocation(JSContext* aContext, nsACString& aFilename,
                                  uint32_t* aLineno = nullptr,
                                  uint32_t* aColumn = nullptr);
   static bool GetCallingLocation(JSContext* aContext, nsAString& aFilename,
                                  uint32_t* aLineno = nullptr,
                                  uint32_t* aColumn = nullptr);
 
-  static nsIScriptGlobalObject *GetStaticScriptGlobal(JSObject* aObj);
-
-  static nsIScriptContext *GetStaticScriptContext(JSObject* aObj);
-
   /**
    * Retrieve the inner window ID based on the given JSContext.
    *
    * @param JSContext aContext
    *        The JSContext from which you want to find the inner window ID.
    *
    * @returns uint64_t the inner window ID.
    */
--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -174,17 +174,17 @@ private:
   nsCOMPtr<nsIThread> mThread;
 };
 
 ThreadedDriver::~ThreadedDriver()
 {
   if (mThread) {
     nsCOMPtr<nsIRunnable> event =
       new MediaStreamGraphShutdownThreadRunnable(mThread.forget());
-    GraphImpl()->Dispatch(event.forget());
+    SystemGroup::Dispatch(TaskCategory::Other, event.forget());
   }
 }
 
 class MediaStreamGraphInitThreadRunnable : public Runnable {
 public:
   explicit MediaStreamGraphInitThreadRunnable(ThreadedDriver* aDriver)
     : Runnable("MediaStreamGraphInitThreadRunnable")
     , mDriver(aDriver)
--- a/dom/workers/WorkerError.cpp
+++ b/dom/workers/WorkerError.cpp
@@ -9,16 +9,17 @@
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/dom/ErrorEvent.h"
 #include "mozilla/dom/ErrorEventBinding.h"
 #include "mozilla/dom/ServiceWorkerManager.h"
 #include "mozilla/dom/SimpleGlobalObject.h"
 #include "mozilla/dom/WorkerDebuggerGlobalScopeBinding.h"
 #include "mozilla/dom/WorkerGlobalScopeBinding.h"
 #include "mozilla/EventDispatcher.h"
+#include "nsGlobalWindowInner.h"
 #include "nsIConsoleService.h"
 #include "nsScriptError.h"
 #include "WorkerRunnable.h"
 #include "WorkerPrivate.h"
 #include "WorkerScope.h"
 
 namespace mozilla {
 namespace dom {
@@ -83,17 +84,16 @@ public:
       // https://bugzilla.mozilla.org/show_bug.cgi?id=1271441 tracks making this
       // better.
       if (aFireAtScope &&
           (aTarget || aReport.mErrorNumber != JSMSG_OVER_RECURSED)) {
         JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
         NS_ASSERTION(global, "This should never be null!");
 
         nsEventStatus status = nsEventStatus_eIgnore;
-        nsIScriptGlobalObject* sgo;
 
         if (aWorkerPrivate) {
           WorkerGlobalScope* globalScope = nullptr;
           UNWRAP_OBJECT(WorkerGlobalScope, &global, globalScope);
 
           if (!globalScope) {
             WorkerDebuggerGlobalScope* globalScope = nullptr;
             UNWRAP_OBJECT(WorkerDebuggerGlobalScope, &global, globalScope);
@@ -124,20 +124,20 @@ public:
           if (NS_FAILED(EventDispatcher::DispatchDOMEvent(ToSupports(globalScope),
                                                           nullptr,
                                                           event, nullptr,
                                                           &status))) {
             NS_WARNING("Failed to dispatch worker thread error event!");
             status = nsEventStatus_eIgnore;
           }
         }
-        else if ((sgo = nsJSUtils::GetStaticScriptGlobal(global))) {
+        else if (nsGlobalWindowInner* win = xpc::WindowOrNull(global)) {
           MOZ_ASSERT(NS_IsMainThread());
 
-          if (NS_FAILED(sgo->HandleScriptError(init, &status))) {
+          if (NS_FAILED(win->HandleScriptError(init, &status))) {
             NS_WARNING("Failed to dispatch main thread error event!");
             status = nsEventStatus_eIgnore;
           }
         }
 
         // Was preventDefault() called?
         if (status == nsEventStatus_eConsumeNoDefault) {
           return;
@@ -337,17 +337,16 @@ WorkerErrorReport::ReportError(JSContext
     // https://bugzilla.mozilla.org/show_bug.cgi?id=1271441 tracks making this
     // better.
     if (aFireAtScope &&
         (aTarget || aReport.mErrorNumber != JSMSG_OVER_RECURSED)) {
       JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
       NS_ASSERTION(global, "This should never be null!");
 
       nsEventStatus status = nsEventStatus_eIgnore;
-      nsIScriptGlobalObject* sgo;
 
       if (aWorkerPrivate) {
         WorkerGlobalScope* globalScope = nullptr;
         UNWRAP_OBJECT(WorkerGlobalScope, &global, globalScope);
 
         if (!globalScope) {
           WorkerDebuggerGlobalScope* globalScope = nullptr;
           UNWRAP_OBJECT(WorkerDebuggerGlobalScope, &global, globalScope);
@@ -378,20 +377,20 @@ WorkerErrorReport::ReportError(JSContext
         if (NS_FAILED(EventDispatcher::DispatchDOMEvent(ToSupports(globalScope),
                                                         nullptr,
                                                         event, nullptr,
                                                         &status))) {
           NS_WARNING("Failed to dispatch worker thread error event!");
           status = nsEventStatus_eIgnore;
         }
       }
-      else if ((sgo = nsJSUtils::GetStaticScriptGlobal(global))) {
+      else if (nsGlobalWindowInner* win = xpc::WindowOrNull(global)) {
         MOZ_ASSERT(NS_IsMainThread());
 
-        if (NS_FAILED(sgo->HandleScriptError(init, &status))) {
+        if (NS_FAILED(win->HandleScriptError(init, &status))) {
           NS_WARNING("Failed to dispatch main thread error event!");
           status = nsEventStatus_eIgnore;
         }
       }
 
       // Was preventDefault() called?
       if (status == nsEventStatus_eConsumeNoDefault) {
         return;
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -30,16 +30,17 @@
 #include "mozilla/dom/PerformanceStorageWorker.h"
 #include "mozilla/dom/PromiseDebugging.h"
 #include "mozilla/dom/WorkerBinding.h"
 #include "mozilla/ThreadEventQueue.h"
 #include "mozilla/ThrottledEventQueue.h"
 #include "mozilla/TimelineConsumers.h"
 #include "mozilla/WorkerTimelineMarker.h"
 #include "nsCycleCollector.h"
+#include "nsGlobalWindowInner.h"
 #include "nsNetUtil.h"
 #include "nsIMemoryReporter.h"
 #include "nsIPermissionManager.h"
 #include "nsIRandomGenerator.h"
 #include "nsIScriptError.h"
 #include "nsIScriptTimeoutHandler.h"
 #include "nsIURI.h"
 #include "nsIURL.h"
@@ -2977,22 +2978,17 @@ WorkerPrivate::GetLoadInfo(JSContext* aC
       NS_ENSURE_SUCCESS(rv, rv);
 
       loadInfo.mPrincipalIsSystem = true;
     }
 
     // See if we're being called from a window.
     nsCOMPtr<nsPIDOMWindowInner> globalWindow = aWindow;
     if (!globalWindow) {
-      nsCOMPtr<nsIScriptGlobalObject> scriptGlobal =
-        nsJSUtils::GetStaticScriptGlobal(JS::CurrentGlobalOrNull(aCx));
-      if (scriptGlobal) {
-        globalWindow = do_QueryInterface(scriptGlobal);
-        MOZ_ASSERT(globalWindow);
-      }
+      globalWindow = xpc::CurrentWindowOrNull(aCx);
     }
 
     nsCOMPtr<nsIDocument> document;
     Maybe<ClientInfo> clientInfo;
 
     if (globalWindow) {
       // Only use the current inner window, and only use it if the caller can
       // access it.
--- a/js/src/tests/jstests.py
+++ b/js/src/tests/jstests.py
@@ -13,28 +13,31 @@ from __future__ import print_function
 
 import os
 import sys
 import textwrap
 import platform
 from os.path import abspath, dirname, isfile, realpath
 from contextlib import contextmanager
 from copy import copy
+from itertools import chain
 from subprocess import list2cmdline, call
 
 from lib.tests import RefTestCase, get_jitflags, get_cpu_count, \
     get_environment_overlay, change_env
 from lib.results import ResultsSink
 from lib.progressbar import ProgressBar
 
 if sys.platform.startswith('linux') or sys.platform.startswith('darwin'):
     from lib.tasks_unix import run_all_tests
 else:
     from lib.tasks_win import run_all_tests
 
+here = dirname(abspath(__file__))
+
 
 @contextmanager
 def changedir(dirname):
     pwd = os.getcwd()
     os.chdir(dirname)
     try:
         yield
     finally:
@@ -287,16 +290,96 @@ def parse_args():
     # Hide the progress bar if it will get in the way of other output.
     options.hide_progress = (options.format == 'automation' or
                              not ProgressBar.conservative_isatty() or
                              options.hide_progress)
 
     return (options, prefix, requested_paths, excluded_paths)
 
 
+def load_wpt_tests(requested_paths, excluded_paths, debug):
+    """Return a list of `RefTestCase` objects for the jsshell testharness.js
+    tests filtered by the given paths and debug-ness."""
+    repo_root = abspath(os.path.join(here, "..", "..", ".."))
+    wp = os.path.join(repo_root, "testing", "web-platform")
+    wpt = os.path.join(wp, "tests")
+
+    sys_paths = [
+        "python/mozterm",
+        "testing/mozbase/mozcrash",
+        "testing/mozbase/mozdevice",
+        "testing/mozbase/mozfile",
+        "testing/mozbase/mozinfo",
+        "testing/mozbase/mozleak",
+        "testing/mozbase/mozlog",
+        "testing/mozbase/mozprocess",
+        "testing/mozbase/mozprofile",
+        "testing/mozbase/mozrunner",
+        "testing/web-platform/tests/tools",
+        "testing/web-platform/tests/tools/third_party/html5lib",
+        "testing/web-platform/tests/tools/third_party/webencodings",
+        "testing/web-platform/tests/tools/wptrunner",
+        "testing/web-platform/tests/tools/wptserve",
+    ]
+    abs_sys_paths = [os.path.join(repo_root, path) for path in sys_paths]
+
+    failed = False
+    for path in abs_sys_paths:
+        if not os.path.isdir(path):
+            failed = True
+            print("Could not add '%s' to the path")
+    if failed:
+        return []
+
+    sys.path[0:0] = abs_sys_paths
+
+    from wptrunner import products, testloader, wptcommandline, wpttest, wptlogging
+
+    wptlogging.setup({}, {})
+    kwargs = {
+        "config": None,
+        "tests_root": wpt,
+        "metadata_root": os.path.join(wp, "meta"),
+        "gecko_e10s": False,
+        "verify": False,
+    }
+    wptcommandline.set_from_config(kwargs)
+    test_paths = kwargs["test_paths"]
+
+    def filter_jsshell_tests(it):
+        for test in it:
+            if test[1].get("jsshell"):
+                yield test
+
+    test_manifests = testloader.ManifestLoader(test_paths, types=["testharness"],
+                                               meta_filters=[filter_jsshell_tests]).load()
+
+    run_info_extras = products.load_product(kwargs["config"], "firefox")[-1](**kwargs)
+    run_info = wpttest.get_run_info(kwargs["metadata_root"], "firefox",
+                                    debug=debug, extras=run_info_extras)
+
+    path_filter = testloader.TestFilter(test_manifests,
+                                        include=requested_paths,
+                                        exclude=excluded_paths)
+    loader = testloader.TestLoader(test_manifests,
+                                   ["testharness"],
+                                   run_info,
+                                   manifest_filters=[path_filter])
+
+    extra_helper_paths = [
+        os.path.join(wpt, "resources", "testharness.js"),
+        os.path.join(here, "testharnessreport.js"),
+    ]
+
+    return [
+        RefTestCase(wpt, test_path, extra_helper_paths=extra_helper_paths, wpt=test)
+        for test_path, test_type, test in loader.iter_tests()
+    ]
+
+
 def load_tests(options, requested_paths, excluded_paths):
     """
     Returns a tuple: (test_count, test_gen)
         test_count: [int] Number of tests that will be in test_gen
         test_gen: [iterable<Test>] Tests found that should be run.
     """
     import lib.manifest as manifest
 
@@ -311,16 +394,21 @@ def load_tests(options, requested_paths,
             xul_info = manifest.XULInfo(xul_abi, xul_os, xul_debug)
         xul_tester = manifest.XULInfoTester(xul_info, options.js_shell)
 
     test_dir = dirname(abspath(__file__))
     path_options = PathOptions(test_dir, requested_paths, excluded_paths)
     test_count = manifest.count_tests(test_dir, path_options)
     test_gen = manifest.load_reftests(test_dir, path_options, xul_tester)
 
+    wpt_tests = load_wpt_tests(requested_paths, excluded_paths,
+                               debug=xul_tester.test("isDebugBuild"))
+    test_count += len(wpt_tests)
+    test_gen = chain(test_gen, wpt_tests)
+
     if options.test_reflect_stringify is not None:
         def trs_gen(tests):
             for test in tests:
                 test.test_reflect_stringify = options.test_reflect_stringify
                 # Even if the test is not normally expected to pass, we still
                 # expect reflect-stringify to be able to handle it.
                 test.expect = True
                 test.random = False
--- a/js/src/tests/lib/manifest.py
+++ b/js/src/tests/lib/manifest.py
@@ -323,16 +323,19 @@ def _parse_test_header(fullpath, testcas
 def _parse_external_manifest(filename, relpath):
     """
     Reads an external manifest file for test suites whose individual test cases
     can't be decorated with reftest comments.
     filename - str: name of the manifest file
     relpath - str: relative path of the directory containing the manifest
                    within the test suite
     """
+    if not os.path.exists(filename):
+        return []
+
     entries = []
 
     with open(filename, 'r') as fp:
         manifest_re = re.compile(r'^\s*(.*)\s+(include|script)\s+(\S+)$')
         for line in fp:
             line, _, comment = line.partition('#')
             line = line.strip()
             if not line:
@@ -422,13 +425,13 @@ def load_reftests(location, path_options
         # Get the full path and relative location of the file.
         filename = os.path.join(root, basename)
         if not _is_test_file(root, basename, filename, path_options):
             continue
 
         # Skip empty files.
         fullpath = os.path.join(location, filename)
 
-        testcase = RefTestCase(filename)
+        testcase = RefTestCase(location, filename)
         _apply_external_manifests(filename, testcase, externalManifestEntries,
                                   xul_tester)
         _parse_test_header(fullpath, testcase, xul_tester)
         yield testcase
--- a/js/src/tests/lib/results.py
+++ b/js/src/tests/lib/results.py
@@ -1,10 +1,11 @@
 from __future__ import print_function
 
+import json
 import pipes
 import re
 
 from progressbar import NullProgressBar, ProgressBar
 from structuredlog import TestLogger
 
 # subprocess.list2cmdline does not properly escape for sh-like shells
 
@@ -57,21 +58,68 @@ class TestResult:
     """Classified result from a test run."""
 
     def __init__(self, test, result, results):
         self.test = test
         self.result = result
         self.results = results
 
     @classmethod
+    def from_wpt_output(cls, output):
+        """Parse the output from a web-platform test that uses testharness.js.
+        (The output is written to stdout in js/src/tests/testharnessreport.js.)
+        """
+        from wptrunner.executors.base import testharness_result_converter
+
+        rc = output.rc
+        if rc != 0:
+            if rc == 3:
+                harness_status = "ERROR"
+            else:
+                harness_status = "CRASH"
+            tests = []
+        else:
+            for line in output.out.split("\n"):
+                if line.startswith("WPT OUTPUT: "):
+                    msg = line[len("WPT OUTPUT: "):]
+                    data = [output.test.wpt.url] + json.loads(msg)
+                    harness_status_obj, tests = testharness_result_converter(output.test.wpt, data)
+                    harness_status = harness_status_obj.status
+                    break
+            else:
+                harness_status = "ERROR"
+                tests = []
+
+        result = cls.PASS
+        results = []
+        if harness_status != output.test.wpt.expected():
+            if harness_status == "CRASH":
+                result = cls.CRASH
+            else:
+                result = cls.FAIL
+        else:
+            for test in tests:
+                if test.status == output.test.wpt.expected(test.name):
+                    test_result = (cls.PASS, "")
+                else:
+                    test_result = (cls.FAIL, test.message)
+                    result = cls.FAIL
+                results.append(test_result)
+
+        return cls(output.test, result, results)
+
+    @classmethod
     def from_output(cls, output):
         test = output.test
         result = None          # str:      overall result, see class-level variables
         results = []           # (str,str) list: subtest results (pass/fail, message)
 
+        if test.wpt:
+            return cls.from_wpt_output(output)
+
         out, err, rc = output.out, output.err, output.rc
 
         failures = 0
         passes = 0
 
         expected_rcs = []
         if test.path.endswith('-n.js'):
             expected_rcs.append(3)
--- a/js/src/tests/lib/tests.py
+++ b/js/src/tests/lib/tests.py
@@ -140,17 +140,19 @@ def get_cpu_count():
         pass
 
     return 1
 
 
 class RefTestCase(object):
     """A test case consisting of a test and an expected result."""
 
-    def __init__(self, path):
+    def __init__(self, root, path, extra_helper_paths=None, wpt=None):
+        # str:  path of the tests root dir
+        self.root = root
         # str:  path of JS file relative to tests root dir
         self.path = path
         # [str]: Extra options to pass to the shell
         self.options = []
         # [str]: JIT flags to pass to the shell
         self.jitflags = []
         # str or None: path to reflect-stringify.js file to test
         # instead of actually running tests
@@ -172,40 +174,49 @@ class RefTestCase(object):
         self.terms = None
 
         # The tag between |...| in the test header.
         self.tag = None
 
         # Anything occuring after -- in the test header.
         self.comment = None
 
-    @staticmethod
-    def prefix_command(path):
-        """Return the '-f shell.js' options needed to run a test with the given
-        path."""
+        self.extra_helper_paths = extra_helper_paths or []
+        self.wpt = wpt
+
+    def prefix_command(self):
+        """Return the '-f' options needed to run a test with the given path."""
+        path = self.path
         prefix = []
         while path != '':
             assert path != '/'
             path = os.path.dirname(path)
-            shell_path = os.path.join(path, 'shell.js')
-            prefix.append(shell_path)
+            shell_path = os.path.join(self.root, path, 'shell.js')
+            if os.path.exists(shell_path):
+                prefix.append(shell_path)
+                prefix.append('-f')
+        prefix.reverse()
+
+        for extra_path in self.extra_helper_paths:
             prefix.append('-f')
+            prefix.append(extra_path)
 
-        prefix.reverse()
         return prefix
 
+    def abs_path(self):
+        return os.path.join(self.root, self.path)
+
     def get_command(self, prefix):
-        cmd = prefix + self.jitflags + self.options \
-            + RefTestCase.prefix_command(self.path)
+        cmd = prefix + self.jitflags + self.options + self.prefix_command()
         if self.test_reflect_stringify is not None:
-            cmd += [self.test_reflect_stringify, "--check", self.path]
+            cmd += [self.test_reflect_stringify, "--check", self.abs_path()]
         elif self.is_module:
-            cmd += ["--module", self.path]
+            cmd += ["--module", self.abs_path()]
         else:
-            cmd += ["-f", self.path]
+            cmd += ["-f", self.abs_path()]
         return cmd
 
     def __str__(self):
         ans = self.path
         if not self.enable:
             ans += ', skip'
         if self.error is not None:
             ans += ', error=' + self.error
--- a/js/src/tests/non262/extensions/regress-50447-1.js
+++ b/js/src/tests/non262/extensions/regress-50447-1.js
@@ -94,29 +94,28 @@ function test2()
 {
   /* generate an error with only msg property */
 
 
   /* note this test incorporates the path to the
      test file and assumes the path to the test case
      is a subdirectory of the directory containing jsDriver.pl
   */
-  var expectedLine = 109;
+  var expectedLine = 106;
   var expectedFileName = 'non262/extensions/regress-50447-1.js';
-  if (typeof document != "undefined") {
-    expectedFileName = document.location.href.
-      replace(/[^\/]*(\?.*)$/, '') +
-      expectedFileName;
-  }
+  var expectedSource = /\(new InternalError\("msg", "([^"]+)", ([0-9]+)\)\)/;
+
   var e = new InternalError ("msg");
-  reportCompare ("(new InternalError(\"msg\", \"" +
-		 expectedFileName + "\", " + expectedLine + "))",
-		 normalize(e.toSource()),
-		 "toSource() returned unexpected result.");
-  reportCompare (expectedFileName, normalize(e.fileName),
+
+  var actual = expectedSource.exec(e.toSource());
+  reportCompare (normalize(actual[1]).endsWith(expectedFileName), true,
+		 "toSource() returned unexpected result (filename).");
+  reportCompare (actual[2], String(expectedLine),
+		 "toSource() returned unexpected result (line).");
+  reportCompare (normalize(e.fileName).endsWith(expectedFileName), true,
 		 "fileName property returned unexpected value.");
   reportCompare (expectedLine, e.lineNumber,
 		 "lineNumber property returned unexpected value.");
 
 
 }
 
 
@@ -126,44 +125,43 @@ function test3()
 
   /* note this test incorporates the path to the
      test file and assumes the path to the test case
      is a subdirectory of the directory containing jsDriver.pl
   */
 
 
 
+  var expectedLine = 10;
   var expectedFileName = 'non262/extensions/regress-50447-1.js';
-  if (typeof document != "undefined") {
-    expectedFileName = document.location.href.
-      replace(/[^\/]*(\?.*)$/, '') +
-      expectedFileName;
-  }
+  var expectedSource = /\(new InternalError\("msg", "([^"]+)", ([0-9]+)\)\)/;
 
   var e = new InternalError ("msg");
-  e.lineNumber = 10;
-  reportCompare ("(new InternalError(\"msg\", \"" +
-		 expectedFileName + "\", 10))",
-		 normalize(e.toSource()),
-		 "toSource() returned unexpected result.");
-  reportCompare (expectedFileName, normalize(e.fileName),
+  e.lineNumber = expectedLine;
+
+  var actual = expectedSource.exec(e.toSource());
+  reportCompare (normalize(actual[1]).endsWith(expectedFileName), true,
+		 "toSource() returned unexpected result (filename).");
+  reportCompare (actual[2], String(expectedLine),
+		 "toSource() returned unexpected result (line).");
+  reportCompare (normalize(e.fileName).endsWith(expectedFileName), true,
 		 "fileName property returned unexpected value.");
-  reportCompare (10, e.lineNumber,
+  reportCompare (expectedLine, e.lineNumber,
 		 "lineNumber property returned unexpected value.");
 
 
 }
 
 
 function test4()
 {
   /* generate an error with only msg and filename properties */
 
 
-  var expectedLine = 163;
+  var expectedLine = 161;
 
   var e = new InternalError ("msg", "file");
   reportCompare ("(new InternalError(\"msg\", \"file\", " + expectedLine + "))",
 		 e.toSource(),
 		 "toSource() returned unexpected result.");
   reportCompare ("file", e.fileName,
 		 "fileName property returned unexpected value.");
   reportCompare (expectedLine, e.lineNumber,
new file mode 100644
--- /dev/null
+++ b/js/src/tests/testharnessreport.js
@@ -0,0 +1,15 @@
+/* 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/. */
+
+add_completion_callback(function(tests, harness_status) {
+    // This output is parsed in TestResult.from_wpt_output.
+    print("WPT OUTPUT: " + JSON.stringify([
+        harness_status.status,
+        harness_status.message,
+        harness_status.stack,
+        tests.map(function(t) {
+            return [t.name, t.status, t.message, t.stack];
+        }),
+    ]));
+});
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -6874,16 +6874,19 @@ nsHttpChannel::OnStartRequest(nsIRequest
         nsresult status;
         request->GetStatus(&status);
         mStatus = status;
     }
 
     LOG(("nsHttpChannel::OnStartRequest [this=%p request=%p status=%" PRIx32 "]\n",
          this, request, static_cast<uint32_t>(static_cast<nsresult>(mStatus))));
 
+    Telemetry::Accumulate(Telemetry::HTTP_CHANNEL_ONSTART_SUCCESS,
+                          NS_SUCCEEDED(mStatus));
+
     if (mRaceCacheWithNetwork) {
         LOG(("  racingNetAndCache - mFirstResponseSource:%d fromCache:%d fromNet:%d\n",
              static_cast<int32_t>(mFirstResponseSource), request == mCachePump, request == mTransactionPump));
         if (mFirstResponseSource == RESPONSE_PENDING) {
             // When the cache wins mFirstResponseSource is set to RESPONSE_FROM_CACHE
             // earlier in ReadFromCache, so this must be a response from the network.
             MOZ_ASSERT(request == mTransactionPump);
             LOG(("  First response from network\n"));
--- a/testing/config/tooltool-manifests/linux64/ccov.manifest
+++ b/testing/config/tooltool-manifests/linux64/ccov.manifest
@@ -1,9 +1,9 @@
 [
   {
-    "size": 1831125,
-    "digest": "ddde7b2bfc64f40487b7d068e43a857e35ff183d9e60400da4e20c11c58295f35162f23c976fe1d435f26559ab89a7b12153bcef76990bc55844dce53cb91b1e",
+    "size": 1858593,
+    "digest": "a2f53ed683fc5bbab5b4c935b0ea345cf553f2e71bbadba7f64bc074c4c945c7254e4d97c47d3e18c2b47c71d5d01eced25cf8afd8470019c7401731a65984b9",
     "algorithm": "sha512",
     "filename": "grcov-linux-x86_64.tar.bz2",
     "unpack": false
   }
 ]
--- a/testing/config/tooltool-manifests/macosx64/ccov.manifest
+++ b/testing/config/tooltool-manifests/macosx64/ccov.manifest
@@ -1,9 +1,9 @@
 [
   {
-    "size": 874832,
+    "size": 919638,
     "visibility": "public",
-    "digest": "6e7c495eaed9e30e202f611614e611ee85878be72bffce59d8408fec7be459f86ac6ac00c84787f5d24ad4c30f91819575a6890be0d44add9c4dd526a3059ab4",
+    "digest": "c90e75f664daf05506e703b54a1afa0d065f06a90625fef35ed8aa3623dc15ca7efc3ab905e4db2245c9540a72647792de3d700f728eada8d2b068d8f2f6d9e1",
     "algorithm": "sha512",
     "filename": "grcov-osx-x86_64.tar.bz2"
   }
 ]
--- a/testing/config/tooltool-manifests/win32/ccov.manifest
+++ b/testing/config/tooltool-manifests/win32/ccov.manifest
@@ -1,9 +1,9 @@
 [
   {
-    "size": 884442,
-    "digest": "ec18befaf6cf0f0e3ba5a5e9acdc92442f42004b586ba2621b52163c4aaeedbae93c1cca09d14bd464b7d854daf232b210ca02f8a6643ee43d121ee8c4fe0af9",
+    "size": 919079,
+    "digest": "80144fb0d626be56ec0c12536c59097d473f74e05bf97515f8754bb39851e9e4260096a1852d6c57f60dc64a1970be4ca851bff094502f2658bfd2eec5667747",
     "algorithm": "sha512",
     "filename": "grcov-win-i686.tar.bz2",
     "unpack": false
   }
 ]
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -2460,16 +2460,24 @@
     "bug_numbers": [1440701],
     "expires_in_version": "70",
     "kind": "categorical",
     "keyed": true,
     "releaseChannelCollection": "opt-out",
     "description": "Upgrading display content Channel Disposition",
     "labels": ["cancel", "disk", "netOk", "netEarlyFail", "netLateFail"]
   },
+  "HTTP_CHANNEL_ONSTART_SUCCESS" : {
+    "record_in_processes": ["main"],
+    "expires_in_version": "never",
+    "kind": "boolean",
+    "description": "Successfully started HTTP channels",
+    "bug_numbers": [1473333],
+    "alert_emails": ["necko@mozilla.com", "dstenberg@mozilla.com"]
+  },
   "HTTP_CONNECTION_ENTRY_CACHE_HIT_1" : {
     "record_in_processes": ["main", "content"],
     "expires_in_version": "never",
     "kind": "boolean",
     "description": "Fraction of sockets that used a nsConnectionEntry with history - size 300."
   },
   "HTTP_CACHE_DISPOSITION_2_V2": {
     "record_in_processes": ["main", "content"],
--- a/toolkit/content/widgets.css
+++ b/toolkit/content/widgets.css
@@ -10,11 +10,12 @@
 @import url("chrome://global/skin/autocomplete.css");
 @import url("chrome://formautofill-shared/skin/autocomplete-item.css");
 @import url("chrome://formautofill/skin/autocomplete-item.css");
 @import url("chrome://global/skin/dropmarker.css");
 @import url("chrome://global/skin/groupbox.css");
 @import url("chrome://global/skin/menu.css");
 @import url("chrome://global/skin/menulist.css");
 @import url("chrome://global/skin/notification.css");
+@import url("chrome://global/skin/popup.css");
 @import url("chrome://global/skin/richlistbox.css");
 @import url("chrome://global/skin/splitter.css");
 @import url("chrome://global/skin/toolbar.css");
--- a/toolkit/content/widgets/popup.xml
+++ b/toolkit/content/widgets/popup.xml
@@ -6,25 +6,17 @@
 <!-- This files relies on these specific Chrome/XBL globals -->
 <!-- globals PopupBoxObject -->
 
 <bindings id="popupBindings"
    xmlns="http://www.mozilla.org/xbl"
    xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    xmlns:xbl="http://www.mozilla.org/xbl">
 
-  <binding id="popup-base">
-    <resources>
-      <stylesheet src="chrome://global/skin/popup.css"/>
-    </resources>
-  </binding>
-
-  <binding id="popup"
-           extends="chrome://global/content/bindings/popup.xml#popup-base">
-
+  <binding id="popup">
     <content>
       <xul:arrowscrollbox class="popup-internal-box" flex="1" orient="vertical"
                           smoothscroll="false">
         <children/>
       </xul:arrowscrollbox>
     </content>
 
     <implementation>
@@ -50,18 +42,17 @@
           }
           for (var i = 0; i < array.length; i++)
             array[i].width = width;
         ]]>
       </handler>
     </handlers>
   </binding>
 
-  <binding id="panel"
-           extends="chrome://global/content/bindings/popup.xml#popup-base">
+  <binding id="panel">
     <implementation>
       <field name="_prevFocus">0</field>
     </implementation>
 
     <handlers>
       <handler event="popupshowing"><![CDATA[
         // Capture the previous focus before has a chance to get set inside the panel
         try {
@@ -134,16 +125,21 @@
             currentFocus = currentFocus.parentNode;
           }
         }
       ]]></handler>
     </handlers>
   </binding>
 
   <binding id="arrowpanel" extends="chrome://global/content/bindings/popup.xml#panel">
+    <resources>
+      <!-- Fixes an issue with the "test_arrowpanel.xul" animation on Mac, see bug 1470880. -->
+      <stylesheet src="data:text/css,"/>
+    </resources>
+
     <content flip="both" side="top" position="bottomcenter topleft" consumeoutsideclicks="false">
       <xul:vbox anonid="container" class="panel-arrowcontainer" flex="1"
                xbl:inherits="side,panelopen">
         <xul:box anonid="arrowbox" class="panel-arrowbox">
           <xul:image anonid="arrow" class="panel-arrow" xbl:inherits="side"/>
         </xul:box>
         <xul:box class="panel-arrowcontent" xbl:inherits="side,align,dir,orient,pack" flex="1">
           <children/>
@@ -262,18 +258,17 @@
         }
       </handler>
       <handler event="popuppositioned" phase="target">
         this.adjustArrowPosition();
       </handler>
     </handlers>
   </binding>
 
-  <binding id="tooltip"
-           extends="chrome://global/content/bindings/popup.xml#popup-base">
+  <binding id="tooltip">
     <content>
       <children>
         <xul:label class="tooltip-label" xbl:inherits="xbl:text=label" flex="1"/>
       </children>
     </content>
 
     <implementation>
       <field name="_mouseOutCount">0</field>
deleted file mode 100644
index b07a6d2a85bf9799d5c9924b7042963f4c624a02..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index b8bd0f519805de3a810bfb0f71a538a16eaf0107..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/toolkit/themes/linux/global/jar.mn
+++ b/toolkit/themes/linux/global/jar.mn
@@ -25,18 +25,16 @@ toolkit.jar:
    skin/classic/global/scrollbox.css
    skin/classic/global/splitter.css
    skin/classic/global/tabbox.css
    skin/classic/global/textbox.css
    skin/classic/global/toolbar.css
    skin/classic/global/toolbarbutton.css
    skin/classic/global/tree.css
 *  skin/classic/global/alerts/alert.css                        (alerts/alert.css)
-   skin/classic/global/arrow/arrow-dn-hov.gif                  (arrow/arrow-dn-hov.gif)
-   skin/classic/global/arrow/arrow-up-hov.gif                  (arrow/arrow-up-hov.gif)
 
    skin/classic/global/icons/Authentication.png                (icons/Authentication.png)
    skin/classic/global/icons/blacklist_favicon.png             (icons/blacklist_favicon.png)
    skin/classic/global/icons/blacklist_large.png               (icons/blacklist_large.png)
    skin/classic/global/icons/Close.gif                         (icons/Close.gif)
    skin/classic/global/icons/Minimize.gif                      (icons/Minimize.gif)
    skin/classic/global/icons/Restore.gif                       (icons/Restore.gif)
    skin/classic/global/icons/sslWarning.png                    (icons/sslWarning.png)
--- a/toolkit/themes/shared/extensions/extensions.inc.css
+++ b/toolkit/themes/shared/extensions/extensions.inc.css
@@ -154,26 +154,26 @@ button.warning {
 /*** category selector ***/
 
 #categories {
   /* With photon this should be 70px but there are some hidden forward/back
      buttons that are 39px tall above this. */
   padding-top: 31px;
 }
 
-.category[disabled] {
+#categories > .category[disabled] {
   overflow: hidden;
   height: 0;
   min-height: 0;
   opacity: 0;
   transition-property: min-height, opacity;
   transition-duration: 1s, 0.8s;
 }
 
-.category:not([disabled]) {
+#categories > .category:not([disabled]) {
   transition-property: min-height, opacity;
   transition-duration: 1s, 0.8s;
 }
 
 /* Maximize the size of the viewport when the window is small */
 @media (max-width: 800px) {
   .category-name {
     display: none;
@@ -332,17 +332,17 @@ button.warning {
 .list > scrollbox > .scrollbox-innerbox {
   border: 1px dotted transparent;
 }
 
 .list:-moz-focusring > scrollbox > .scrollbox-innerbox {
   border-color: var(--in-content-border-focus);
 }
 
-.addon {
+richlistbox.list > richlistitem.addon {
   color: var(--in-content-text-color);
   border-bottom: 1px solid var(--in-content-box-border-color);
   padding: 5px;
   background-origin: border-box;
 }
 
 .addon:not(:only-child):last-child {
   border-bottom-width: 0;
@@ -559,17 +559,17 @@ button.warning {
   --view-highlight-color: #EFFAF2;
 }
 
 .addon-view[pending="disable"],
 .addon-view[pending="uninstall"] {
   --view-highlight-color: #F2F2F2;
 }
 
-.addon[selected] {
+.list > .addon[selected] {
   background-color: var(--in-content-page-background);
   color: var(--in-content-page-color);
   padding-inline-start: 1px; /* compensate the 4px border */
   border-inline-start: solid 4px var(--in-content-border-focus);
 }
 
 #addon-list .addon[active="false"] > .content-container > .content-inner-container {
   color: #999;
@@ -577,17 +577,17 @@ button.warning {
 
 #addon-list .addon[active="false"][selected] > .content-container > .content-inner-container {
   color: #777;
 }
 
 
 /*** item - uninstalled ***/
 
-.addon[status="uninstalled"] {
+.list > .addon[status="uninstalled"] {
   border: none;
 }
 
 .addon[status="uninstalled"] > .container {
   -moz-box-align: center;
   padding: 4px 20px;
   background-color: #FDFFA8;
   border-radius: 8px;
--- a/toolkit/themes/shared/in-content/common.inc.css
+++ b/toolkit/themes/shared/in-content/common.inc.css
@@ -639,48 +639,48 @@ xul|*.radio-label-box {
   -moz-appearance: none;
   background-color: initial; /* override the background-color set on all richlistboxes in common.inc.css */
   padding-top: 70px;
   margin: 0;
   border-width: 0;
   width: 240px;
 }
 
-*|*.category {
+*|*#categories > *|*.category {
   min-height: 48px;
   -moz-appearance: none;
   color: var(--in-content-category-text);
   margin-inline-start: 34px;
   padding-inline-end: 10px;
   padding-inline-start: 10px;
   transition: background-color 150ms;
 }
 
-*|*.category:hover {
+*|*#categories > *|*.category:hover {
   background-color: var(--in-content-category-background-hover);
   border-radius: 2px;
 }
 
-*|*.category:hover:active {
+*|*#categories > *|*.category:hover:active {
   background-color: var(--in-content-category-background-active);
 }
 
-*|*.category[selected],
-*|*.category.selected {
+*|*#categories > *|*.category[selected],
+*|*#categories > *|*.category.selected {
   color: var(--in-content-category-text-selected);
   background: none;
 }
 
-*|*.category[selected]:hover,
-*|*.category.selected:hover {
+*|*#categories > *|*.category[selected]:hover,
+*|*#categories > *|*.category.selected:hover {
   background-color: var(--in-content-category-background-selected-hover);
 }
 
-*|*.category[selected]:hover:active,
-*|*.category.selected:hover:active {
+*|*#categories > *|*.category[selected]:hover:active,
+*|*#categories > *|*.category.selected:hover:active {
   color: var(--in-content-category-text-selected-active);
   background-color: var(--in-content-category-background-selected-active);
 }
 
 *|*#categories[keyboard-navigation="true"]:-moz-focusring > *|*.category[current] {
   outline: var(--in-content-category-outline-focus);
 }
 
@@ -709,17 +709,17 @@ xul|*.radio-label-box {
   #categories {
     width: 118px;
   }
 
   .category-icon + .category-name {
     display: none;
   }
 
-  .category {
+  #categories > .category {
     padding-inline-start: 13px; /* make category icons align center */
     margin-inline-end: 33px;
   }
 
   .main-content {
     padding-left: 0;
     padding-right: 0;
   }