Merge mozilla-central to autoland. a=merge CLOSED TREE
authorshindli <shindli@mozilla.com>
Wed, 21 Nov 2018 06:35:33 +0200
changeset 503856 2ab57f102c2964112b52922f4df3024557ab2b83
parent 503855 156f5b9586a6f0ea81d9bf4f07c8b84f7e5f19f3 (current diff)
parent 503851 50785e9ffd05cad4eaa1ced6485534fb1f099892 (diff)
child 503857 3a2396b6972e19316f4830cd5071ee10b33e8409
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to autoland. a=merge CLOSED TREE
accessible/tests/mochitest/value/test_progress.xul
dom/base/crashtests/398088-1.xul
layout/reftests/bugs/474336-1-ref.xul
layout/reftests/bugs/474336-1.xul
layout/xul/crashtests/472189.xul
layout/xul/crashtests/475133.html
testing/mozharness/configs/android/androidx86.py
toolkit/content/tests/chrome/test_progressmeter.xul
toolkit/content/tests/reftests/bug-442419-progressmeter-max-ref.xul
toolkit/content/tests/reftests/bug-442419-progressmeter-max.xul
toolkit/content/widgets/progressmeter.js
toolkit/themes/osx/global/progressmeter.css
toolkit/themes/windows/global/progressmeter.css
--- a/accessible/base/MarkupMap.h
+++ b/accessible/base/MarkupMap.h
@@ -425,17 +425,17 @@ MARKUPMAP(
 
 MARKUPMAP(p,
           nullptr,
           roles::PARAGRAPH)
 
 MARKUPMAP(
   progress,
   [](Element* aElement, Accessible* aContext) -> Accessible* {
-     return new HTMLProgressMeterAccessible(aElement, aContext->Document());
+     return new HTMLProgressAccessible(aElement, aContext->Document());
   },
   0
 )
 
 MARKUPMAP(q,
           New_HyperText,
           0)
 
--- a/accessible/base/Role.h
+++ b/accessible/base/Role.h
@@ -314,17 +314,17 @@ enum Role {
 
   /**
    * Represents the calendar control.
    */
   DROPLIST = 47,
 
   /**
    * Represents a progress bar, dynamically showing the user the percent
-   * complete of an operation in progress. It is used for xul:progressmeter,
+   * complete of an operation in progress. It is used for html:progress,
    * role="progressbar".
    */
   PROGRESSBAR = 48,
 
   /**
    * Represents a dial or knob whose purpose is to allow a user to set a value.
    */
   DIAL = 49,
--- a/accessible/base/XULMap.h
+++ b/accessible/base/XULMap.h
@@ -14,17 +14,16 @@ XULMAP_TYPE(iframe, OuterDocAccessible)
 XULMAP_TYPE(listheader, XULColumAccessible)
 XULMAP_TYPE(menu, XULMenuitemAccessibleWrap)
 XULMAP_TYPE(menubar, XULMenubarAccessible)
 XULMAP_TYPE(menucaption, XULMenuitemAccessibleWrap)
 XULMAP_TYPE(menuitem, XULMenuitemAccessibleWrap)
 XULMAP_TYPE(menulist, XULComboboxAccessible)
 XULMAP_TYPE(menuseparator, XULMenuSeparatorAccessible)
 XULMAP_TYPE(notification, XULAlertAccessible)
-XULMAP_TYPE(progressmeter, XULProgressMeterAccessible)
 XULMAP_TYPE(radio, XULRadioButtonAccessible)
 XULMAP_TYPE(radiogroup, XULRadioGroupAccessible)
 XULMAP_TYPE(richlistbox, XULListboxAccessibleWrap)
 XULMAP_TYPE(richlistitem, XULListitemAccessible)
 XULMAP_TYPE(statusbar, XULStatusBarAccessible)
 XULMAP_TYPE(tab, XULTabAccessible)
 XULMAP_TYPE(tabpanels, XULTabpanelsAccessible)
 XULMAP_TYPE(tabs, XULTabsAccessible)
--- a/accessible/generic/FormControlAccessible.cpp
+++ b/accessible/generic/FormControlAccessible.cpp
@@ -9,146 +9,16 @@
 
 #include "mozilla/dom/HTMLInputElement.h"
 #include "mozilla/FloatingPoint.h"
 #include "Role.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
-// ProgressMeterAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-template class mozilla::a11y::ProgressMeterAccessible<1>;
-template class mozilla::a11y::ProgressMeterAccessible<100>;
-
-////////////////////////////////////////////////////////////////////////////////
-// Accessible
-
-template<int Max>
-role
-ProgressMeterAccessible<Max>::NativeRole() const
-{
-  return roles::PROGRESSBAR;
-}
-
-template<int Max>
-uint64_t
-ProgressMeterAccessible<Max>::NativeState() const
-{
-  uint64_t state = LeafAccessible::NativeState();
-
-  // An undetermined progressbar (i.e. without a value) has a mixed state.
-  nsAutoString attrValue;
-  mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue);
-
-  if (attrValue.IsEmpty())
-    state |= states::MIXED;
-
-  return state;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ProgressMeterAccessible<Max>: Widgets
-
-template<int Max>
-bool
-ProgressMeterAccessible<Max>::IsWidget() const
-{
-  return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ProgressMeterAccessible<Max>: Value
-
-template<int Max>
-void
-ProgressMeterAccessible<Max>::Value(nsString& aValue) const
-{
-  LeafAccessible::Value(aValue);
-  if (!aValue.IsEmpty())
-    return;
-
-  double maxValue = MaxValue();
-  if (IsNaN(maxValue) || maxValue == 0)
-    return;
-
-  double curValue = CurValue();
-  if (IsNaN(curValue))
-    return;
-
-  // Treat the current value bigger than maximum as 100%.
-  double percentValue = (curValue < maxValue) ?
-    (curValue / maxValue) * 100 : 100;
-
-  aValue.AppendFloat(percentValue);
-  aValue.Append('%');
-}
-
-template<int Max>
-double
-ProgressMeterAccessible<Max>::MaxValue() const
-{
-  double value = LeafAccessible::MaxValue();
-  if (!IsNaN(value))
-    return value;
-
-  nsAutoString strValue;
-  if (mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::max, strValue)) {
-    nsresult result = NS_OK;
-    value = strValue.ToDouble(&result);
-    if (NS_SUCCEEDED(result))
-      return value;
-  }
-
-  return Max;
-}
-
-template<int Max>
-double
-ProgressMeterAccessible<Max>::MinValue() const
-{
-  double value = LeafAccessible::MinValue();
-  return IsNaN(value) ? 0 : value;
-}
-
-template<int Max>
-double
-ProgressMeterAccessible<Max>::Step() const
-{
-  double value = LeafAccessible::Step();
-  return IsNaN(value) ? 0 : value;
-}
-
-template<int Max>
-double
-ProgressMeterAccessible<Max>::CurValue() const
-{
-  double value = LeafAccessible::CurValue();
-  if (!IsNaN(value))
-    return value;
-
-  nsAutoString attrValue;
-  if (!mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue))
-    return UnspecifiedNaN<double>();
-
-  nsresult error = NS_OK;
-  value = attrValue.ToDouble(&error);
-  return NS_FAILED(error) ? UnspecifiedNaN<double>() : value;
-}
-
-template<int Max>
-bool
-ProgressMeterAccessible<Max>::SetCurValue(double aValue)
-{
-  return false; // progress meters are readonly.
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
 // CheckboxAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 role
 CheckboxAccessible::NativeRole() const
 {
   return roles::CHECKBUTTON;
 }
--- a/accessible/generic/FormControlAccessible.h
+++ b/accessible/generic/FormControlAccessible.h
@@ -7,51 +7,16 @@
 #define MOZILLA_A11Y_FormControlAccessible_H_
 
 #include "BaseAccessibles.h"
 
 namespace mozilla {
 namespace a11y {
 
 /**
-  * Generic class used for progress meters.
-  */
-template<int Max>
-class ProgressMeterAccessible : public LeafAccessible
-{
-public:
-  ProgressMeterAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-    LeafAccessible(aContent, aDoc)
-  {
-    // Ignore 'ValueChange' DOM event in lieu of @value attribute change
-    // notifications.
-    mStateFlags |= eHasNumericValue | eIgnoreDOMUIEvent;
-    mType = eProgressType;
-  }
-
-  // Accessible
-  virtual void Value(nsString& aValue) const override;
-  virtual mozilla::a11y::role NativeRole() const override;
-  virtual uint64_t NativeState() const override;
-
-  // Value
-  virtual double MaxValue() const override;
-  virtual double MinValue() const override;
-  virtual double CurValue() const override;
-  virtual double Step() const override;
-  virtual bool SetCurValue(double aValue) override;
-
-  // Widgets
-  virtual bool IsWidget() const override;
-
-protected:
-  virtual ~ProgressMeterAccessible() {}
-};
-
-/**
  * Checkbox accessible.
  */
 class CheckboxAccessible : public LeafAccessible
 {
 
 public:
   enum { eAction_Click = 0 };
 
--- a/accessible/html/HTMLFormControlAccessible.cpp
+++ b/accessible/html/HTMLFormControlAccessible.cpp
@@ -800,8 +800,126 @@ HTMLFigcaptionAccessible::RelationByType
   if (figure &&
       figure->GetContent()->NodeInfo()->Equals(nsGkAtoms::figure,
                                                mContent->GetNameSpaceID())) {
     rel.AppendTarget(figure);
   }
 
   return rel;
 }
+
+////////////////////////////////////////////////////////////////////////////////
+// HTMLProgressAccessible
+////////////////////////////////////////////////////////////////////////////////
+
+role
+HTMLProgressAccessible::NativeRole() const
+{
+  return roles::PROGRESSBAR;
+}
+
+uint64_t
+HTMLProgressAccessible::NativeState() const
+{
+  uint64_t state = LeafAccessible::NativeState();
+
+  // An undetermined progressbar (i.e. without a value) has a mixed state.
+  nsAutoString attrValue;
+  mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::value,
+                                 attrValue);
+  if (attrValue.IsEmpty()) {
+    state |= states::MIXED;
+  }
+
+  return state;
+}
+
+bool
+HTMLProgressAccessible::IsWidget() const
+{
+  return true;
+}
+
+void
+HTMLProgressAccessible::Value(nsString& aValue) const
+{
+  LeafAccessible::Value(aValue);
+  if (!aValue.IsEmpty()) {
+    return;
+  }
+
+  double maxValue = MaxValue();
+  if (IsNaN(maxValue) || maxValue == 0) {
+    return;
+  }
+
+  double curValue = CurValue();
+  if (IsNaN(curValue)) {
+    return;
+  }
+
+  // Treat the current value bigger than maximum as 100%.
+  double percentValue = (curValue < maxValue) ? (curValue / maxValue) * 100
+                                              : 100;
+
+  aValue.AppendFloat(percentValue);
+  aValue.Append('%');
+}
+
+double
+HTMLProgressAccessible::MaxValue() const
+{
+  double value = LeafAccessible::MaxValue();
+  if (!IsNaN(value)) {
+    return value;
+  }
+
+  nsAutoString strValue;
+  if (mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::max,
+                                     strValue)) {
+    nsresult result = NS_OK;
+    value = strValue.ToDouble(&result);
+    if (NS_SUCCEEDED(result)) {
+      return value;
+    }
+  }
+
+  return 1;
+}
+
+double
+HTMLProgressAccessible::MinValue() const
+{
+  double value = LeafAccessible::MinValue();
+  return IsNaN(value) ? 0 : value;
+}
+
+double
+HTMLProgressAccessible::Step() const
+{
+  double value = LeafAccessible::Step();
+  return IsNaN(value) ? 0 : value;
+}
+
+double
+HTMLProgressAccessible::CurValue() const
+{
+  double value = LeafAccessible::CurValue();
+  if (!IsNaN(value)) {
+    return value;
+  }
+
+  nsAutoString attrValue;
+  if (!mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::value,
+                                      attrValue)) {
+    return UnspecifiedNaN<double>();
+  }
+
+  nsresult error = NS_OK;
+  value = attrValue.ToDouble(&error);
+  return NS_FAILED(error) ? UnspecifiedNaN<double>() : value;
+}
+
+bool
+HTMLProgressAccessible::SetCurValue(double aValue)
+{
+  return false; // progress meters are readonly.
+}
--- a/accessible/html/HTMLFormControlAccessible.h
+++ b/accessible/html/HTMLFormControlAccessible.h
@@ -9,21 +9,16 @@
 #include "FormControlAccessible.h"
 #include "HyperTextAccessibleWrap.h"
 
 namespace mozilla {
 class TextEditor;
 namespace a11y {
 
 /**
- * Accessible for HTML progress element.
- */
-typedef ProgressMeterAccessible<1> HTMLProgressMeterAccessible;
-
-/**
  * Accessible for HTML input@type="radio" element.
  */
 class HTMLRadioButtonAccessible : public RadioButtonAccessible
 {
 
 public:
   HTMLRadioButtonAccessible(nsIContent* aContent, DocAccessible* aDoc) :
     RadioButtonAccessible(aContent, aDoc)
@@ -265,12 +260,47 @@ public:
   // Accessible
   virtual nsAtom* LandmarkRole() const override;
   virtual a11y::role NativeRole() const override;
 
 protected:
   virtual ~HTMLFormAccessible() = default;
 };
 
+/**
+ * Accessible for HTML progress element.
+ */
+
+class HTMLProgressAccessible : public LeafAccessible
+{
+public:
+  HTMLProgressAccessible(nsIContent* aContent, DocAccessible* aDoc) :
+    LeafAccessible(aContent, aDoc)
+  {
+    // Ignore 'ValueChange' DOM event in lieu of @value attribute change
+    // notifications.
+    mStateFlags |= eHasNumericValue | eIgnoreDOMUIEvent;
+    mType = eProgressType;
+  }
+
+  // Accessible
+  virtual void Value(nsString& aValue) const override;
+  virtual mozilla::a11y::role NativeRole() const override;
+  virtual uint64_t NativeState() const override;
+
+  // Value
+  virtual double MaxValue() const override;
+  virtual double MinValue() const override;
+  virtual double CurValue() const override;
+  virtual double Step() const override;
+  virtual bool SetCurValue(double aValue) override;
+
+  // Widgets
+  virtual bool IsWidget() const override;
+
+protected:
+  virtual ~HTMLProgressAccessible() {}
+};
+
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/interfaces/nsIAccessibleRole.idl
+++ b/accessible/interfaces/nsIAccessibleRole.idl
@@ -307,17 +307,17 @@ interface nsIAccessibleRole : nsISupport
 
   /**
    * Represents the calendar control.
    */
   const unsigned long ROLE_DROPLIST = 47;
 
   /**
    * Represents a progress bar, dynamically showing the user the percent
-   * complete of an operation in progress. It is used for xul:progressmeter,
+   * complete of an operation in progress. It is used for html:progress,
    * role="progressbar".
    */
   const unsigned long ROLE_PROGRESSBAR = 48;
 
   /**
    * Represents a dial or knob whose purpose is to allow a user to set a value.
    */
   const unsigned long ROLE_DIAL = 49;
--- a/accessible/tests/mochitest/name/test_general.xul
+++ b/accessible/tests/mochitest/name/test_general.xul
@@ -169,17 +169,17 @@
       testName("lb_opt1_children_hidden", "i am visible");
 
 
       //////////////////////////////////////////////////////////////////////////
       // Name from aria-labelledby: menuitem label+ listitem label
       testName("li_labelledby", "Show an Alert The moment the event starts");
 
       //////////////////////////////////////////////////////////////////////////
-      // groupbox labeling from caption sub tree
+      // groupbox labeling from first label
       testName("groupbox", "Some caption");
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   ]]>
@@ -343,17 +343,17 @@
   <vbox role="listbox" tabindex="0">
     <hbox id="lb_opt1_children_hidden" role="option" tabindex="0">
       <description>i am visible</description>
       <description style="display:none">i am hidden</description>
     </hbox>
 
     <!-- Name from caption sub tree -->
     <groupbox id="groupbox">
-      <caption><label>Some caption</label></caption>
+      <label>Some caption</label>
       <checkbox label="some checkbox label" />
     </groupbox>
   </vbox>
 
   <!-- bug 441991; create name from other menuitem label listitem's own label -->
   <hbox>
     <richlistbox>
       <richlistitem id="li_labelledby"
--- a/accessible/tests/mochitest/relations/test_general.xul
+++ b/accessible/tests/mochitest/relations/test_general.xul
@@ -98,18 +98,17 @@
       // aria-flowto, multiple relations
       testRelation("flowto1", RELATION_FLOWS_TO, ["flowfrom1", "flowfrom2"]);
       testRelation("flowfrom1", RELATION_FLOWS_FROM, "flowto1");
       testRelation("flowfrom2", RELATION_FLOWS_FROM, "flowto1");
 
       // 'default button' relation
       testRelation("textbox", RELATION_DEFAULT_BUTTON, "submit");
 
-      // 'labelled by'/'label for' relation for xul:goupbox and xul:label of
-      // xul:caption
+      // 'labelled by'/'label for' relation for xul:groupbox and xul:label
       var groupboxAcc = getAccessible("groupbox");
       var labelAcc = groupboxAcc.firstChild;
       testRelation(labelAcc, RELATION_LABEL_FOR, groupboxAcc);
       testRelation(groupboxAcc, RELATION_LABELLED_BY, labelAcc);
 
       // 'labelled by'/'label for' relations for xul:tab and xul:tabpanel
       // (fixed in bug 366527)
       testRelation("tabpanel1", RELATION_LABELLED_BY, "tab1");
@@ -206,17 +205,17 @@
 
     <description id="flowto" aria-flowto="flowfrom">flow to</description>
     <description id="flowfrom">flow from</description>
 
     <textbox id="textbox"/>
     <button id="submit" default="true" label="Default"/>
 
     <groupbox id="groupbox">
-      <caption><label id="groupboxlabel" value="caption"/></caption>
+      <label value="caption"/>
     </groupbox>
 
     <tabbox>
       <tabs>
         <tab label="tab1" id="tab1"/>
         <tab label="tab2" id="tab2" linkedpanel="tabpanel2"/>
         <tab label="tab3" id="tab3" linkedpanel="tabpanel3"/>
       </tabs>
--- a/accessible/tests/mochitest/tree/test_groupbox.xul
+++ b/accessible/tests/mochitest/tree/test_groupbox.xul
@@ -49,16 +49,16 @@
       <div id="content" style="display: none">
       </div>
       <pre id="test">
       </pre>
     </body>
 
     <vbox flex="1">
       <groupbox id="groupbox">
-        <caption><label value="Some caption"/></caption>
+        <label value="Some caption"/>
         <checkbox label="some checkbox label" />
     </groupbox>
     </vbox>
   </hbox>
 
 </window>
 
--- a/accessible/tests/mochitest/value/a11y.ini
+++ b/accessible/tests/mochitest/value/a11y.ini
@@ -1,9 +1,8 @@
 [DEFAULT]
 support-files =
   !/accessible/tests/mochitest/*.js
 
 [test_general.html]
 [test_number.html]
 [test_progress.html]
-[test_progress.xul]
 [test_range.html]
deleted file mode 100644
--- a/accessible/tests/mochitest/value/test_progress.xul
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
-                 type="text/css"?>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        title="XUL progressmeter tests">
-
-  <script type="application/javascript"
-          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
-
-  <script type="application/javascript"
-          src="../common.js" />
-  <script type="application/javascript"
-          src="../value.js" />
-
-  <script type="application/javascript">
-  <![CDATA[
-    function doTest()
-    {
-      // progressmeter
-      testValue("pm1", "50%", 50, 0, 100, 0);
-      testValue("pm2", "50%", 500, 0, 1000, 0);
-      testValue("pm3", "", 0, 0, 100, 0);
-      testValue("pm4", "", 0, 0, 100, 0);
-
-      // aria progressbar
-      testValue("ariapb1", "500", 500, 0, 1000, 0);
-      testValue("ariapb2", "", 0, 0, 0, 0);
-
-      SimpleTest.finish();
-    }
-
-    SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
-  ]]>
-  </script>
-
-  <hbox flex="1" style="overflow: auto;">
-    <body xmlns="http://www.w3.org/1999/xhtml">
-      <a target="_blank"
-         href="https://bugzilla.mozilla.org/show_bug.cgi?id=489551"
-         title="Values of sliders and progress bars in HTML 5 audio and video element's control sets are not percentages">
-        Mozilla Bug 489551
-      </a><br/>
-      <p id="display"></p>
-      <div id="content" style="display: none">
-      </div>
-      <pre id="test">
-      </pre>
-    </body>
-
-    <!-- progressmeter -->
-    <vbox>
-      <progressmeter id="pm1" value="50"/>
-      <progressmeter id="pm2" value="500" max="1000"/>
-      <progressmeter id="pm3"/>
-      <progressmeter id="pm4" mode="undetermined"/>
-    </vbox>
-
-    <!-- aria -->
-    <description id="ariapb1" role="progressbar"
-                 aria-valuenow="500" aria-valuemin="0" aria-valuemax="1000"/>
-    <description id="ariapb2" role="progressbar"/>
-  </hbox>
-
-</window>
-
--- a/accessible/xul/XULElementAccessibles.cpp
+++ b/accessible/xul/XULElementAccessibles.cpp
@@ -84,23 +84,24 @@ XULLabelAccessible::NativeState() const
   // They are not focusable or selectable
   return HyperTextAccessibleWrap::NativeState() | states::READONLY;
 }
 
 Relation
 XULLabelAccessible::RelationByType(RelationType aType) const
 {
   Relation rel = HyperTextAccessibleWrap::RelationByType(aType);
+
+  // The label for xul:groupbox is generated from the first xul:label
   if (aType == RelationType::LABEL_FOR) {
-    // Caption is the label for groupbox
-    nsIContent* parent = mContent->GetFlattenedTreeParent();
-    if (parent && parent->IsXULElement(nsGkAtoms::caption)) {
-      Accessible* parent = Parent();
-      if (parent && parent->Role() == roles::GROUPING)
-        rel.AppendTarget(parent);
+    Accessible* parent = Parent();
+    if (parent && parent->Role() == roles::GROUPING &&
+        parent->GetContent()->IsXULElement(nsGkAtoms::groupbox) &&
+        parent->GetChildAt(0) == this) {
+      rel.AppendTarget(parent);
     }
   }
 
   return rel;
 }
 
 void
 XULLabelAccessible::UpdateLabelValue(const nsString& aValue)
--- a/accessible/xul/XULFormControlAccessible.cpp
+++ b/accessible/xul/XULFormControlAccessible.cpp
@@ -281,34 +281,23 @@ XULGroupboxAccessible::NativeName(nsStri
 
   return eNameOK;
 }
 
 Relation
 XULGroupboxAccessible::RelationByType(RelationType aType) const
 {
   Relation rel = AccessibleWrap::RelationByType(aType);
-  if (aType != RelationType::LABELLED_BY)
-    return rel;
 
-  // The label for xul:groupbox is generated from xul:label that is
-  // inside the anonymous content of the xul:caption.
-  // The xul:label has an accessible object but the xul:caption does not
-  uint32_t childCount = ChildCount();
-  for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
-    Accessible* childAcc = GetChildAt(childIdx);
-    if (childAcc->Role() == roles::LABEL) {
-      // Ensure that it's our label
-      Relation reverseRel = childAcc->RelationByType(RelationType::LABEL_FOR);
-      Accessible* testGroupbox = nullptr;
-      while ((testGroupbox = reverseRel.Next()))
-        if (testGroupbox == this) {
-          // The <label> points back to this groupbox
-          rel.AppendTarget(childAcc);
-        }
+  // The label for xul:groupbox is generated from the first xul:label
+  if (aType == RelationType::LABELLED_BY && ChildCount() > 0) {
+    Accessible* childAcc = GetChildAt(0);
+    if (childAcc->Role() == roles::LABEL &&
+        childAcc->GetContent()->IsXULElement(nsGkAtoms::label)) {
+      rel.AppendTarget(childAcc);
     }
   }
 
   return rel;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULRadioButtonAccessible
--- a/accessible/xul/XULFormControlAccessible.h
+++ b/accessible/xul/XULFormControlAccessible.h
@@ -11,21 +11,16 @@
 #include "FormControlAccessible.h"
 #include "HyperTextAccessibleWrap.h"
 #include "XULSelectControlAccessible.h"
 
 namespace mozilla {
 namespace a11y {
 
 /**
- * Used for XUL progressmeter element.
- */
-typedef ProgressMeterAccessible<100> XULProgressMeterAccessible;
-
-/**
  * Used for XUL button.
  *
  * @note  Don't inherit from LeafAccessible - it doesn't allow children
  *         and a button can have a dropmarker child.
  */
 class XULButtonAccessible : public AccessibleWrap
 {
 public:
--- a/browser/base/content/pageinfo/pageInfo.xul
+++ b/browser/base/content/pageinfo/pageInfo.xul
@@ -274,19 +274,17 @@
         <button command="cmd_help" label="&helpButton.label;" dlgtype="help"/>
       </hbox>
     </vbox>
 
     <!-- Security & Privacy -->
     <vbox id="securityPanel">
       <!-- Identity Section -->
       <groupbox>
-        <caption>
-          <label class="header" value="&securityView.identity.header;"/>
-        </caption>
+        <label class="header" value="&securityView.identity.header;"/>
         <grid>
           <columns>
             <column/>
             <column flex="1"/>
           </columns>
           <rows>
             <!-- Domain -->
             <row>
@@ -321,19 +319,17 @@
               <textbox id="security-identity-validity-value" readonly="true"/>
             </row>
           </rows>
         </grid>
       </groupbox>
 
       <!-- Privacy & History section -->
       <groupbox>
-        <caption>
-          <label class="header" value="&securityView.privacy.header;"/>
-        </caption>
+        <label class="header" value="&securityView.privacy.header;"/>
         <grid>
           <columns>
             <column flex="1"/>
             <column flex="1"/>
           </columns>
           <rows>
             <!-- History -->
             <row>
@@ -368,19 +364,17 @@
               </hbox>
             </row>
           </rows>
         </grid>
       </groupbox>
 
       <!-- Technical Details section -->
       <groupbox>
-        <caption>
-          <label class="header" value="&securityView.technical.header;"/>
-        </caption>
+        <label class="header" value="&securityView.technical.header;"/>
         <label id="security-technical-shortform"/>
         <description id="security-technical-longform1"/>
         <description id="security-technical-longform2"/>
         <description id="security-technical-certificate-transparency"/>
       </groupbox>
 
       <hbox pack="end">
         <button command="cmd_help" label="&helpButton.label;" dlgtype="help"/>
--- a/browser/base/content/sanitize.xul
+++ b/browser/base/content/sanitize.xul
@@ -11,16 +11,17 @@
 
 
 <?xml-stylesheet href="chrome://browser/content/sanitizeDialog.css"?>
 
 <!DOCTYPE dialog>
 
 <dialog id="SanitizeDialog" type="child"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        xmlns:html="http://www.w3.org/1999/xhtml"
         buttons="accept,cancel"
         persist="lastSelected screenX screenY"
         role="dialog"
         data-l10n-id="dialog-title"
         data-l10n-attrs="style"
         onload="gSanitizePromptDialog.init();"
         ondialogaccept="return gSanitizePromptDialog.sanitize();">
 
@@ -66,17 +67,17 @@
       </vbox>
     </hbox>
     <spacer flex="1"/>
   </vbox>
 
   <separator class="thin"/>
 
   <groupbox>
-    <caption><label data-l10n-id="history-section-label"></label></caption>
+    <label><html:h2 data-l10n-id="history-section-label"/></label>
     <grid flex="1">
       <columns>
         <column data-l10n-id="sanitize-prefs-style" data-l10n-attrs="style"/>
         <column flex="1"/>
       </columns>
       <rows>
         <row>
           <checkbox data-l10n-id="item-history-and-downloads"
@@ -98,17 +99,17 @@
           <checkbox data-l10n-id="item-form-search-history"
                     preference="privacy.cpd.formdata"
                     onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
         </row>
       </rows>
     </grid>
   </groupbox>
   <groupbox>
-    <caption><label data-l10n-id="data-section-label"></label></caption>
+    <label><html:h2 data-l10n-id="data-section-label"/></label>
     <grid flex="1">
       <columns>
         <column data-l10n-id="sanitize-prefs-style" data-l10n-attrs="style"/>
         <column flex="1"/>
       </columns>
       <rows>
         <row>
           <checkbox data-l10n-id="item-site-preferences"
--- a/browser/components/newtab/lib/AboutPreferences.jsm
+++ b/browser/components/newtab/lib/AboutPreferences.jsm
@@ -5,16 +5,18 @@
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "PluralForm", "resource://gre/modules/PluralForm.jsm");
 const {actionTypes: at} = ChromeUtils.import("resource://activity-stream/common/Actions.jsm", {});
 
 XPCOMUtils.defineLazyGlobalGetters(this, ["fetch"]);
 
+const HTML_NS = "http://www.w3.org/1999/xhtml";
+
 const PREFERENCES_LOADED_EVENT = "home-pane-loaded";
 
 // These "section" objects are formatted in a way to be similar to the ones from
 // SectionsManager to construct the preferences view.
 const PREFS_BEFORE_SECTIONS = [
   {
     id: "search",
     pref: {
@@ -157,21 +159,21 @@ this.AboutPreferences = class AboutPrefe
       `href="data:text/css,${encodeURIComponent(CUSTOM_CSS)}" type="text/css"`),
       document.documentElement);
 
     // Insert a new group immediately after the homepage one
     const homeGroup = document.getElementById("homepageGroup");
     const contentsGroup = homeGroup.insertAdjacentElement("afterend", homeGroup.cloneNode());
     contentsGroup.id = "homeContentsGroup";
     contentsGroup.setAttribute("data-subcategory", "contents");
-    const caption = createAppend("caption", contentsGroup);
-    const captionLabel = createAppend("label", caption);
-    captionLabel.setAttribute("value", formatString("prefs_home_header"));
-    const description = createAppend("description", contentsGroup);
-    description.textContent = formatString("prefs_home_description");
+    createAppend("label", contentsGroup)
+      .appendChild(document.createElementNS(HTML_NS, "h2"))
+      .textContent = formatString("prefs_home_header");
+    createAppend("description", contentsGroup)
+      .textContent = formatString("prefs_home_description");
 
     // Add preferences for each section
     prefStructure.forEach(sectionData => {
       const {
         id,
         pref: prefData,
         icon = "webextension",
         maxRows,
--- a/browser/components/preferences/colors.xul
+++ b/browser/components/preferences/colors.xul
@@ -27,17 +27,17 @@
   <script type="application/javascript" src="chrome://global/content/preferencesBindings.js"/>
 
   <keyset>
     <key data-l10n-id="colors-close-key" modifiers="accel" oncommand="Preferences.close(event)"/>
   </keyset>
 
   <hbox>
     <groupbox flex="1">
-      <caption><label data-l10n-id="colors-text-and-background"/></caption>
+      <label><html:h2 data-l10n-id="colors-text-and-background"/></label>
       <hbox align="center">
         <label data-l10n-id="colors-text-header" control="foregroundtextmenu"/>
         <spacer flex="1"/>
         <html:input type="color" id="foregroundtextmenu"
                     preference="browser.display.foreground_color"/>
       </hbox>
       <hbox align="center" style="margin-top: 5px">
         <label data-l10n-id="colors-background" control="backgroundmenu" />
@@ -48,17 +48,17 @@
       <separator class="thin"/>
       <hbox align="center">
         <checkbox id="browserUseSystemColors" data-l10n-id="colors-use-system"
                   preference="browser.display.use_system_colors"/>
       </hbox>
     </groupbox>
 
     <groupbox flex="1">
-      <caption><label data-l10n-id="colors-links-header"/></caption>
+      <label><html:h2 data-l10n-id="colors-links-header"/></label>
       <hbox align="center">
         <label data-l10n-id="colors-unvisited-links" control="unvisitedlinkmenu" />
         <spacer flex="1"/>
         <html:input type="color" id="unvisitedlinkmenu"
                     preference="browser.anchor_color"/>
       </hbox>
       <hbox align="center" style="margin-top: 5px">
         <label data-l10n-id="colors-visited-links" control="visitedlinkmenu" />
--- a/browser/components/preferences/connection.xul
+++ b/browser/components/preferences/connection.xul
@@ -4,16 +4,17 @@
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <?xml-stylesheet href="chrome://global/skin/"?>
 <?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css"?>
 
 <dialog id="ConnectionsDialog" type="child"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        xmlns:html="http://www.w3.org/1999/xhtml"
         data-l10n-id="connection-window"
         data-l10n-attrs="title, style"
         buttons="accept,cancel,help"
         persist="lastSelected screenX screenY"
         role="dialog"
         onbeforeaccept="return gConnectionsDialog.beforeAccept();"
         onload="gConnectionsDialog.checkForSystemProxy();"
         helpTopic="prefs-connection-settings"
@@ -40,17 +41,17 @@
         align="top" hidden="true" class="extension-controlled">
     <description control="disableProxyExtension" flex="1" />
     <button id="disableProxyExtension"
             class="extension-controlled-button accessory-button"
             data-l10n-id="connection-disable-extension" />
   </hbox>
 
   <groupbox>
-    <caption><label data-l10n-id="connection-proxy-configure" /></caption>
+    <label><html:h2 data-l10n-id="connection-proxy-configure"/></label>
 
     <radiogroup id="networkProxyType" preference="network.proxy.type"
                 onsyncfrompreference="return gConnectionsDialog.readProxyType();">
       <radio value="0" data-l10n-id="connection-proxy-option-no" />
       <radio value="4" data-l10n-id="connection-proxy-option-auto" />
       <radio value="5" data-l10n-id="connection-proxy-option-system" id="systemPref" hidden="true" />
       <radio value="1" data-l10n-id="connection-proxy-option-manual"/>
       <grid class="indent" flex="1">
--- a/browser/components/preferences/fonts.xul
+++ b/browser/components/preferences/fonts.xul
@@ -5,16 +5,17 @@
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css"?>
 
 <dialog id="FontsDialog" type="child"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        xmlns:html="http://www.w3.org/1999/xhtml"
         data-l10n-id="fonts-window"
         data-l10n-attrs="title"
         buttons="accept,cancel,help"
         persist="lastSelected screenX screenY"
         role="dialog"
         helpTopic="prefs-fonts-and-colors"
         ondialoghelp="openPrefsHelp()">
 
@@ -26,58 +27,56 @@
   <script type="application/javascript" src="chrome://global/content/preferencesBindings.js"/>
 
   <keyset>
     <key data-l10n-id="fonts-window-close" modifiers="accel" oncommand="Preferences.close(event)"/>
   </keyset>
 
   <!-- Fonts for: [ Language ] -->
   <groupbox>
-    <caption>
-      <hbox align="center">
-        <label data-l10n-id="fonts-langgroup-header" control="selectLangs"/>
-      </hbox>
-      <!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
-      <hbox>
-        <menulist id="selectLangs" preference="font.language.group"
-                  onsyncfrompreference="return gFontsDialog.readFontLanguageGroup();">
-          <menupopup>
-            <menuitem value="ar"              data-l10n-id="fonts-langgroup-arabic"/>
-            <menuitem value="x-armn"          data-l10n-id="fonts-langgroup-armenian"/>
-            <menuitem value="x-beng"          data-l10n-id="fonts-langgroup-bengali"/>
-            <menuitem value="zh-CN"           data-l10n-id="fonts-langgroup-simpl-chinese"/>
-            <menuitem value="zh-HK"           data-l10n-id="fonts-langgroup-trad-chinese-hk"/>
-            <menuitem value="zh-TW"           data-l10n-id="fonts-langgroup-trad-chinese"/>
-            <menuitem value="x-cyrillic"      data-l10n-id="fonts-langgroup-cyrillic"/>
-            <menuitem value="x-devanagari"    data-l10n-id="fonts-langgroup-devanagari"/>
-            <menuitem value="x-ethi"          data-l10n-id="fonts-langgroup-ethiopic"/>
-            <menuitem value="x-geor"          data-l10n-id="fonts-langgroup-georgian"/>
-            <menuitem value="el"              data-l10n-id="fonts-langgroup-el"/>
-            <menuitem value="x-gujr"          data-l10n-id="fonts-langgroup-gujarati"/>
-            <menuitem value="x-guru"          data-l10n-id="fonts-langgroup-gurmukhi"/>
-            <menuitem value="he"              data-l10n-id="fonts-langgroup-hebrew"/>
-            <menuitem value="ja"              data-l10n-id="fonts-langgroup-japanese"/>
-            <menuitem value="x-knda"          data-l10n-id="fonts-langgroup-kannada"/>
-            <menuitem value="x-khmr"          data-l10n-id="fonts-langgroup-khmer"/>
-            <menuitem value="ko"              data-l10n-id="fonts-langgroup-korean"/>
-            <menuitem value="x-western"       data-l10n-id="fonts-langgroup-latin"/>
-            <menuitem value="x-mlym"          data-l10n-id="fonts-langgroup-malayalam"/>
-            <menuitem value="x-math"          data-l10n-id="fonts-langgroup-math"/>
-            <menuitem value="x-orya"          data-l10n-id="fonts-langgroup-odia"/>
-            <menuitem value="x-sinh"          data-l10n-id="fonts-langgroup-sinhala"/>
-            <menuitem value="x-tamil"         data-l10n-id="fonts-langgroup-tamil"/>
-            <menuitem value="x-telu"          data-l10n-id="fonts-langgroup-telugu"/>
-            <menuitem value="th"              data-l10n-id="fonts-langgroup-thai"/>
-            <menuitem value="x-tibt"          data-l10n-id="fonts-langgroup-tibetan"/>
-            <menuitem value="x-cans"          data-l10n-id="fonts-langgroup-canadian"/>
-            <menuitem value="x-unicode"       data-l10n-id="fonts-langgroup-other"/>
-          </menupopup>
-        </menulist>
-      </hbox>
-    </caption>
+    <hbox align="center">
+      <label control="selectLangs"><html:h2 data-l10n-id="fonts-langgroup-header"/></label>
+    </hbox>
+    <!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
+    <hbox>
+      <menulist id="selectLangs" preference="font.language.group"
+                onsyncfrompreference="return gFontsDialog.readFontLanguageGroup();">
+        <menupopup>
+          <menuitem value="ar"              data-l10n-id="fonts-langgroup-arabic"/>
+          <menuitem value="x-armn"          data-l10n-id="fonts-langgroup-armenian"/>
+          <menuitem value="x-beng"          data-l10n-id="fonts-langgroup-bengali"/>
+          <menuitem value="zh-CN"           data-l10n-id="fonts-langgroup-simpl-chinese"/>
+          <menuitem value="zh-HK"           data-l10n-id="fonts-langgroup-trad-chinese-hk"/>
+          <menuitem value="zh-TW"           data-l10n-id="fonts-langgroup-trad-chinese"/>
+          <menuitem value="x-cyrillic"      data-l10n-id="fonts-langgroup-cyrillic"/>
+          <menuitem value="x-devanagari"    data-l10n-id="fonts-langgroup-devanagari"/>
+          <menuitem value="x-ethi"          data-l10n-id="fonts-langgroup-ethiopic"/>
+          <menuitem value="x-geor"          data-l10n-id="fonts-langgroup-georgian"/>
+          <menuitem value="el"              data-l10n-id="fonts-langgroup-el"/>
+          <menuitem value="x-gujr"          data-l10n-id="fonts-langgroup-gujarati"/>
+          <menuitem value="x-guru"          data-l10n-id="fonts-langgroup-gurmukhi"/>
+          <menuitem value="he"              data-l10n-id="fonts-langgroup-hebrew"/>
+          <menuitem value="ja"              data-l10n-id="fonts-langgroup-japanese"/>
+          <menuitem value="x-knda"          data-l10n-id="fonts-langgroup-kannada"/>
+          <menuitem value="x-khmr"          data-l10n-id="fonts-langgroup-khmer"/>
+          <menuitem value="ko"              data-l10n-id="fonts-langgroup-korean"/>
+          <menuitem value="x-western"       data-l10n-id="fonts-langgroup-latin"/>
+          <menuitem value="x-mlym"          data-l10n-id="fonts-langgroup-malayalam"/>
+          <menuitem value="x-math"          data-l10n-id="fonts-langgroup-math"/>
+          <menuitem value="x-orya"          data-l10n-id="fonts-langgroup-odia"/>
+          <menuitem value="x-sinh"          data-l10n-id="fonts-langgroup-sinhala"/>
+          <menuitem value="x-tamil"         data-l10n-id="fonts-langgroup-tamil"/>
+          <menuitem value="x-telu"          data-l10n-id="fonts-langgroup-telugu"/>
+          <menuitem value="th"              data-l10n-id="fonts-langgroup-thai"/>
+          <menuitem value="x-tibt"          data-l10n-id="fonts-langgroup-tibetan"/>
+          <menuitem value="x-cans"          data-l10n-id="fonts-langgroup-canadian"/>
+          <menuitem value="x-unicode"       data-l10n-id="fonts-langgroup-other"/>
+        </menupopup>
+      </menulist>
+    </hbox>
 
     <grid>
       <columns>
         <column/>
         <column flex="1"/>
         <column/>
         <column/>
       </columns>
@@ -249,17 +248,17 @@
                 preference="browser.display.use_document_fonts"
                 onsyncfrompreference="return gFontsDialog.readUseDocumentFonts();"
                 onsynctopreference="return gFontsDialog.writeUseDocumentFonts();"/>
     </hbox>
   </groupbox>
 
   <!-- Text Encoding -->
   <groupbox>
-    <caption><label data-l10n-id="fonts-languages-fallback-header"/></caption>
+    <label><html:h2 data-l10n-id="fonts-languages-fallback-header"/></label>
     <description data-l10n-id="fonts-languages-fallback-desc"/>
     <hbox align="center">
       <label data-l10n-id="fonts-languages-fallback-label" control="DefaultCharsetList"/>
       <!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
       <hbox>
         <menulist id="DefaultCharsetList" preference="intl.charset.fallback.override">
           <menupopup>
             <menuitem data-l10n-id="fonts-languages-fallback-name-auto"        value=""/>
--- a/browser/components/preferences/in-content/findInPage.js
+++ b/browser/components/preferences/in-content/findInPage.js
@@ -305,17 +305,17 @@ var gSearchResultsPane = {
       }
     } else {
       noResultsEl.hidden = true;
       document.getElementById("sorry-message-query").textContent = "";
       // Going back to General when cleared
       gotoPref("paneGeneral");
 
       // Hide some special second level headers in normal view
-      for (let element of document.querySelectorAll("caption.search-header")) {
+      for (let element of document.querySelectorAll(".search-header")) {
         element.hidden = true;
       }
     }
 
     window.dispatchEvent(new CustomEvent("PreferencesSearchCompleted", { detail: query }));
   },
 
   /**
--- a/browser/components/preferences/in-content/home.xul
+++ b/browser/components/preferences/in-content/home.xul
@@ -17,17 +17,17 @@
           data-preference-related="browser.startup.homepage"
           data-l10n-id="home-restore-defaults"
           preference="pref.browser.homepage.disable_button.restore_default"/>
 </hbox>
 
 <groupbox id="homepageGroup"
           data-category="paneHome"
           hidden="true">
-  <caption><label data-l10n-id="home-new-windows-tabs-header"/></caption>
+  <label><html:h2 data-l10n-id="home-new-windows-tabs-header"/></label>
   <description data-l10n-id="home-new-windows-tabs-description2" />
 
   <hbox id="homepageAndNewWindowsOption">
     <label control="homeMode" data-l10n-id="home-homepage-mode-label" flex="1" />
 
     <vbox class="homepageMenuItemContainer" flex="1">
       <textbox id="homePrefHidden"
               preference="browser.startup.homepage"
--- a/browser/components/preferences/in-content/main.xul
+++ b/browser/components/preferences/in-content/main.xul
@@ -22,17 +22,17 @@
       data-category="paneGeneral">
       <label class="header-name" flex="1" data-l10n-id="pane-general-title"/>
 </hbox>
 
 <!-- Startup -->
 <groupbox id="startupGroup"
           data-category="paneGeneral"
           hidden="true">
-  <caption><label data-l10n-id="startup-header"/></caption>
+  <label><html:h2 data-l10n-id="startup-header"/></label>
 
 #ifdef MOZ_DEV_EDITION
   <vbox id="separateProfileBox">
     <checkbox id="separateProfileMode"
               data-l10n-id="separate-profile-mode"/>
     <hbox id="sync-dev-edition-root" lign="center" class="indent" hidden="true">
       <label id="useFirefoxSync" data-l10n-id="use-firefox-sync"/>
       <deck id="getStarted">
@@ -69,17 +69,17 @@
   </vbox>
 #endif
 
 </groupbox>
 
 <!-- Tab preferences -->
 <groupbox data-category="paneGeneral"
           hidden="true">
-    <caption><label data-l10n-id="tabs-group-header"/></caption>
+    <label><html:h2 data-l10n-id="tabs-group-header"/></label>
 
     <checkbox id="ctrlTabRecentlyUsedOrder" data-l10n-id="ctrl-tab-recently-used-order"
               preference="browser.ctrlTab.recentlyUsedOrder"
               oncommand="Services.prefs.clearUserPref('browser.ctrlTab.migrated');"/>
 
     <checkbox id="linkTargeting" data-l10n-id="open-new-link-as-tabs"
               preference="browser.link.open_newwindow"
               onsyncfrompreference="return gMainPane.readLinkTarget();"
@@ -133,17 +133,17 @@
       class="subcategory"
       hidden="true"
       data-category="paneGeneral">
   <label class="header-name" flex="1" data-l10n-id="language-and-appearance-header"/>
 </hbox>
 
 <!-- Fonts and Colors -->
 <groupbox id="fontsGroup" data-category="paneGeneral" hidden="true">
-  <caption><label data-l10n-id="fonts-and-colors-header"/></caption>
+  <label><html:h2 data-l10n-id="fonts-and-colors-header"/></label>
 
   <hbox id="fontSettings">
     <hbox align="center" flex="1">
       <label control="defaultFont" data-l10n-id="default-font"/>
       <!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
       <hbox flex="1">
         <menulist id="defaultFont" flex="1" delayprefsave="true" onsyncfrompreference="return FontBuilder.readFontSelection(this);"/>
       </hbox>
@@ -275,17 +275,17 @@
                 colors-visited-links
               "/>
     </hbox>
   </hbox>
 </groupbox>
 
 <!-- Languages -->
 <groupbox id="languagesGroup" data-category="paneGeneral" hidden="true">
-  <caption><label data-l10n-id="language-header"/></caption>
+  <label><html:h2 data-l10n-id="language-header"/></label>
 
   <vbox id="browserLanguagesBox" align="start" hidden="true">
     <description flex="1" controls="chooseBrowserLanguage" data-l10n-id="choose-browser-language-description"/>
     <hbox>
       <menulist id="defaultBrowserLanguage" oncommand="gMainPane.onBrowserLanguageChange(event)">
         <menupopup/>
       </menulist>
       <button id="manageBrowserLanguagesButton"
@@ -348,17 +348,17 @@
       class="subcategory"
       hidden="true"
       data-category="paneGeneral">
   <label class="header-name" flex="1" data-l10n-id="files-and-applications-title"/>
 </hbox>
 
 <!--Downloads-->
 <groupbox id="downloadsGroup" data-category="paneGeneral" hidden="true">
-  <caption><label data-l10n-id="download-header"/></caption>
+  <label><html:h2 data-l10n-id="download-header"/></label>
 
   <radiogroup id="saveWhere"
               preference="browser.download.useDownloadDir"
               onsyncfrompreference="return gMainPane.readUseDownloadDir();">
     <hbox>
       <radio id="saveTo"
              value="true"
              data-l10n-id="download-save-to"/>
@@ -375,17 +375,17 @@
            hidden="true"/>
     <radio id="alwaysAsk"
            value="false"
            data-l10n-id="download-always-ask-where"/>
   </radiogroup>
 </groupbox>
 
 <groupbox id="applicationsGroup" data-category="paneGeneral" hidden="true">
-  <caption><label data-l10n-id="applications-header"/></caption>
+  <label><html:h2 data-l10n-id="applications-header"/></label>
   <description data-l10n-id="applications-description"/>
   <textbox id="filter" flex="1"
            type="search"
            data-l10n-id="applications-filter"
            aria-controls="handlersView"/>
 
   <richlistbox id="handlersView"
                preference="pref.downloads.disable_button.edit_actions">
@@ -398,17 +398,17 @@
                  flex="1"/>
     </listheader>
   </richlistbox>
 </groupbox>
 
 
 <!-- DRM Content -->
 <groupbox id="drmGroup" data-category="paneGeneral" data-subcategory="drm" hidden="true">
-  <caption><label data-l10n-id="drm-content-header"/></caption>
+  <label><html:h2 data-l10n-id="drm-content-header"/></label>
   <grid id="contentGrid2">
     <columns>
       <column flex="1"/>
       <column/>
     </columns>
     <rows id="contentRows-2">
       <row id="playDRMContentRow">
         <hbox align="center">
@@ -430,17 +430,17 @@
       class="subcategory"
       hidden="true"
       data-category="paneGeneral">
   <label class="header-name" flex="1" data-l10n-id="update-application-title"/>
 </hbox>
 
 <!-- Update -->
 <groupbox id="updateApp" data-category="paneGeneral" hidden="true">
-  <caption class="search-header" hidden="true"><label data-l10n-id="update-application-title"/></caption>
+  <label class="search-header" hidden="true"><html:h2 data-l10n-id="update-application-title"/></label>
 
   <label data-l10n-id="update-application-description"/>
   <hbox align="center">
     <vbox flex="1">
       <description id="updateAppInfo">
         <html:a id="releasenotes" target="_blank" data-l10n-name="learn-more" class="learnMore text-link" hidden="true"/>
       </description>
       <description id="distribution" class="text-blurb" hidden="true"/>
@@ -576,17 +576,17 @@
       class="subcategory"
       hidden="true"
       data-category="paneGeneral">
   <label class="header-name" flex="1" data-l10n-id="performance-title"/>
 </hbox>
 
 <!-- Performance -->
 <groupbox id="performanceGroup" data-category="paneGeneral" hidden="true">
-  <caption class="search-header" hidden="true"><label data-l10n-id="performance-title"/></caption>
+  <label class="search-header" hidden="true"><html:h2 data-l10n-id="performance-title"/></label>
 
   <hbox align="center">
     <checkbox id="useRecommendedPerformanceSettings"
               class="tail-with-learn-more"
               data-l10n-id="performance-use-recommended-settings-checkbox"
               preference="browser.preferences.defaultPerformanceSettings.enabled"/>
     <label id="performanceSettingsLearnMore" class="learnMore text-link" data-l10n-id="performance-settings-learn-more"/>
   </hbox>
@@ -622,17 +622,17 @@
       class="subcategory"
       hidden="true"
       data-category="paneGeneral">
   <label class="header-name" flex="1" data-l10n-id="browsing-title"/>
 </hbox>
 
 <!-- Browsing -->
 <groupbox id="browsingGroup" data-category="paneGeneral" hidden="true">
-  <caption class="search-header" hidden="true"><label data-l10n-id="browsing-title"/></caption>
+  <label class="search-header" hidden="true"><html:h2 data-l10n-id="browsing-title"/></label>
 
   <checkbox id="useAutoScroll"
             data-l10n-id="browsing-use-autoscroll"
             preference="general.autoScroll"/>
   <checkbox id="useSmoothScrolling"
             data-l10n-id="browsing-use-smooth-scrolling"
             preference="general.smoothScroll"/>
 
@@ -661,17 +661,17 @@
       class="subcategory"
       hidden="true"
       data-category="paneGeneral">
   <label class="header-name" flex="1" data-l10n-id="network-settings-title"/>
 </hbox>
 
 <!-- Network Settings-->
 <groupbox id="connectionGroup" data-category="paneGeneral" hidden="true">
-  <caption class="search-header" hidden="true"><label data-l10n-id="network-settings-title"/></caption>
+  <label class="search-header" hidden="true"><html:h2 data-l10n-id="network-settings-title"/></label>
 
   <hbox align="center">
     <hbox align="center" flex="1">
       <description id="connectionSettingsDescription" control="connectionSettings"/>
       <spacer width="5"/>
       <label id="connectionSettingsLearnMore" class="learnMore text-link"
         data-l10n-id="network-proxy-connection-learn-more">
       </label>
--- a/browser/components/preferences/in-content/preferences.js
+++ b/browser/components/preferences/in-content/preferences.js
@@ -298,17 +298,17 @@ function scrollAndHighlight(subcategory)
 
 /**
  * If there is no visible second level header it will return first level header,
  * otherwise return second level header.
  * @returns {Element} - The closest displayed header.
  */
 function getClosestDisplayedHeader(element) {
   let header = element.closest("groupbox");
-  let searchHeader = header.querySelector("caption.search-header");
+  let searchHeader = header.querySelector(".search-header");
   if (searchHeader && searchHeader.hidden &&
       header.previousSibling.classList.contains("subcategory")) {
     header = header.previousSibling;
   }
   return header;
 }
 
 function scrollContentTo(element) {
--- a/browser/components/preferences/in-content/preferences.xul
+++ b/browser/components/preferences/in-content/preferences.xul
@@ -20,16 +20,17 @@
 <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
 <!ENTITY % certManagerDTD SYSTEM "chrome://pippki/locale/certManager.dtd">
 %brandDTD;
 %certManagerDTD;
 ]>
 
 <page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
       xmlns:html="http://www.w3.org/1999/xhtml"
+      role="document"
       data-l10n-id="pref-page"
       data-l10n-attrs="title">
 
   <linkset>
     <link rel="localization" href="branding/brand.ftl"/>
     <link rel="localization" href="browser/branding/sync-brand.ftl"/>
     <link rel="localization" href="browser/preferences/preferences.ftl"/>
     <!-- Used by fontbuilder.js -->
--- a/browser/components/preferences/in-content/privacy.xul
+++ b/browser/components/preferences/in-content/privacy.xul
@@ -13,19 +13,17 @@
       class="subcategory"
       hidden="true"
       data-category="panePrivacy">
   <label class="header-name" flex="1" data-l10n-id="privacy-header"/>
 </hbox>
 
 <!-- Tracking / Content Blocking -->
 <groupbox id="trackingGroup" data-category="panePrivacy" hidden="true" aria-describedby="contentBlockingDescription">
-  <caption>
-    <label id="contentBlockingHeader" data-l10n-id="content-blocking-header"/>
-  </caption>
+  <label id="contentBlockingHeader"><html:h2 data-l10n-id="content-blocking-header"/></label>
   <vbox data-subcategory="trackingprotection">
     <hbox align="start">
       <image id="trackingProtectionShield"/>
       <vbox flex="1">
         <description class="description-with-side-element">
           <html:span id="contentBlockingDescription" class="tail-with-learn-more" data-l10n-id="content-blocking-description"></html:span>
           <label id="contentBlockingLearnMore" class="learnMore text-link" data-l10n-id="content-blocking-learn-more"/>
         </description>
@@ -200,17 +198,17 @@
         <radio value="false" data-l10n-id="do-not-track-option-default-content-blocking"/>
       </radiogroup>
     </vbox>
   </vbox>
 </groupbox>
 
 <!-- Site Data -->
 <groupbox id="siteDataGroup" data-category="panePrivacy" hidden="true" aria-describedby="totalSiteDataSize">
-  <caption><label data-l10n-id="sitedata-header"/></caption>
+  <label><html:h2 data-l10n-id="sitedata-header"/></label>
 
   <hbox data-subcategory="sitedata" align="baseline">
     <vbox flex="1">
       <description class="description-with-side-element" flex="1">
         <html:span id="totalSiteDataSize" class="tail-with-learn-more"></html:span>
         <label id="siteDataLearnMoreLink"
           class="learnMore text-link" data-l10n-id="sitedata-learn-more"/>
       </description>
@@ -263,17 +261,17 @@
                 " />
       </hbox>
     </vbox>
   </hbox>
 </groupbox>
 
 <!-- Passwords -->
 <groupbox id="passwordsGroup" orient="vertical" data-category="panePrivacy" hidden="true">
-  <caption><label data-l10n-id="logins-header"/></caption>
+  <label><html:h2 data-l10n-id="logins-header"/></label>
 
   <vbox id="passwordSettings">
     <hbox id="savePasswordsBox">
       <checkbox id="savePasswords"
                 data-l10n-id="forms-ask-to-save-logins"
                 preference="signon.rememberSignons"
                 onsyncfrompreference="return gPrivacyPane.readSavePasswords();"
                 flex="1" />
@@ -317,17 +315,17 @@
 <!-- The form autofill section is inserted in to this box
      after the form autofill extension has initialized. -->
 <groupbox id="formAutofillGroupBox"
           data-category="panePrivacy"
           data-subcategory="form-autofill"></groupbox>
 
 <!-- History -->
 <groupbox id="historyGroup" data-category="panePrivacy" hidden="true">
-  <caption><label data-l10n-id="history-header"/></caption>
+  <label><html:h2 data-l10n-id="history-header"/></label>
   <hbox align="center">
     <label id="historyModeLabel"
            control="historyMode"
            data-l10n-id="history-remember-label"/>
     <!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
     <hbox>
       <menulist id="historyMode">
         <menupopup>
@@ -418,17 +416,17 @@
     </vbox>
   </hbox>
 </groupbox>
 
 <!-- Address Bar -->
 <groupbox id="locationBarGroup"
           data-category="panePrivacy"
           hidden="true">
-  <caption><label data-l10n-id="addressbar-header"/></caption>
+  <label><html:h2 data-l10n-id="addressbar-header"/></label>
   <label id="locationBarSuggestionLabel" data-l10n-id="addressbar-suggest"/>
   <checkbox id="historySuggestion" data-l10n-id="addressbar-locbar-history-option"
             preference="browser.urlbar.suggest.history"/>
   <checkbox id="bookmarkSuggestion" data-l10n-id="addressbar-locbar-bookmarks-option"
             preference="browser.urlbar.suggest.bookmark"/>
   <checkbox id="openpageSuggestion" data-l10n-id="addressbar-locbar-openpage-option"
             preference="browser.urlbar.suggest.openpage"/>
   <label class="text-link" id="openSearchEnginePreferences"
@@ -438,18 +436,18 @@
 <hbox id="permissionsCategory"
       class="subcategory"
       hidden="true"
       data-category="panePrivacy">
   <label class="header-name" flex="1" data-l10n-id="permissions-header"/>
 </hbox>
 
 <!-- Permissions -->
-<groupbox id="permissionsGroup" data-category="panePrivacy" hidden="true" data-subcategory="permissions" aria-labelledby="permissionsGroupLabel">
-  <caption class="search-header" hidden="true"><label data-l10n-id="permissions-header" id="permissionsGroupLabel"/></caption>
+<groupbox id="permissionsGroup" data-category="panePrivacy" hidden="true" data-subcategory="permissions">
+  <label class="search-header" hidden="true"><html:h2 data-l10n-id="permissions-header"/></label>
 
   <grid>
     <columns>
       <column flex="1"/>
       <column/>
     </columns>
     <rows>
       <row id="locationSettingsRow" align="center" role="group" aria-labelledby="locationPermissionsLabel">
@@ -668,18 +666,18 @@
 #ifdef MOZ_DATA_REPORTING
 <hbox id="dataCollectionCategory"
       class="subcategory"
       hidden="true"
       data-category="panePrivacy">
   <label class="header-name" flex="1" data-l10n-id="collection-header"/>
 </hbox>
 
-<groupbox id="dataCollectionGroup" data-category="panePrivacy" hidden="true" aria-labelledby="dataCollectionGroupLabel">
-  <caption class="search-header" hidden="true"><label data-l10n-id="collection-header" id="dataCollectionGroupLabel"/></caption>
+<groupbox id="dataCollectionGroup" data-category="panePrivacy" hidden="true">
+  <label class="search-header" hidden="true"><html:h2 data-l10n-id="collection-header"/></label>
 
   <description>
     <label class="tail-with-learn-more" data-l10n-id="collection-description"/>
     <label id="dataCollectionPrivacyNotice"
            class="learnMore text-link"
            data-l10n-id="collection-privacy-notice"/>
   </description>
   <vbox data-subcategory="reports">
@@ -740,17 +738,17 @@
       class="subcategory"
       hidden="true"
       data-category="panePrivacy">
   <label class="header-name" flex="1" data-l10n-id="security-header"/>
 </hbox>
 
 <!-- addons, forgery (phishing) UI Security -->
 <groupbox id="browsingProtectionGroup" data-category="panePrivacy" hidden="true">
-  <caption><label data-l10n-id="security-browsing-protection"/></caption>
+  <label><html:h2 data-l10n-id="security-browsing-protection"/></label>
   <hbox align = "center">
     <checkbox id="enableSafeBrowsing"
               data-l10n-id="security-enable-safe-browsing"
               class="tail-with-learn-more"/>
     <label id="enableSafeBrowsingLearnMore"
            class="learnMore text-link" data-l10n-id="security-enable-safe-browsing-link"/>
   </hbox>
   <vbox class="indent">
@@ -758,17 +756,17 @@
               data-l10n-id="security-block-downloads"/>
     <checkbox id="blockUncommonUnwanted"
               data-l10n-id="security-block-uncommon-software"/>
   </vbox>
 </groupbox>
 
 <!-- Certificates -->
 <groupbox id="certSelection" data-category="panePrivacy" hidden="true">
-  <caption><label data-l10n-id="certs-header"/></caption>
+  <label><html:h2 data-l10n-id="certs-header"/></label>
   <description id="CertSelectionDesc" control="certSelection" data-l10n-id="certs-personal-label"/>
 
   <!--
     The values on these radio buttons may look like l10n issues, but
     they're not - this preference uses *those strings* as its values.
     I KID YOU NOT.
   -->
   <radiogroup id="certSelection"
--- a/browser/components/preferences/in-content/search.xul
+++ b/browser/components/preferences/in-content/search.xul
@@ -4,28 +4,28 @@
     <hbox id="searchCategory"
           class="subcategory"
           hidden="true"
           data-category="paneSearch">
       <label class="header-name" flex="1" data-l10n-id="pane-search-title" />
     </hbox>
 
     <groupbox id="searchbarGroup" data-category="paneSearch">
-      <caption><label id="searchbarLabel" data-l10n-id="search-bar-header" /></caption>
-      <radiogroup id="searchBarVisibleGroup" aria-labelledby="searchbarLabel" preference="browser.search.widget.inNavBar">
+      <label control="searchBarVisibleGroup"><html:h2 data-l10n-id="search-bar-header"/></label>
+      <radiogroup id="searchBarVisibleGroup" preference="browser.search.widget.inNavBar">
         <radio id="searchBarHiddenRadio" value="false" data-l10n-id="search-bar-hidden"/>
         <image class="searchBarImage searchBarHiddenImage" role="presentation"/>
         <radio id="searchBarShownRadio" value="true" data-l10n-id="search-bar-shown"/>
         <image class="searchBarImage searchBarShownImage" role="presentation"/>
       </radiogroup>
     </groupbox>
 
     <!-- Default Search Engine -->
     <groupbox id="defaultEngineGroup" data-category="paneSearch">
-      <caption><label data-l10n-id="search-engine-default-header" /></caption>
+      <label><html:h2 data-l10n-id="search-engine-default-header" /></label>
       <description data-l10n-id="search-engine-default-desc" />
 
       <hbox id="browserDefaultSearchExtensionContent"
             align="center" hidden="true" class="extension-controlled">
         <description control="disableDefaultSearchExtension" flex="1"/>
       </hbox>
 
       <hbox>
@@ -47,17 +47,17 @@
         <hbox id="urlBarSuggestionPermanentPBLabel"
               align="center" class="indent">
           <label flex="1" data-l10n-id="search-suggestions-cant-show" />
         </hbox>
       </vbox>
     </groupbox>
 
     <groupbox id="oneClickSearchProvidersGroup" data-category="paneSearch">
-      <caption><label data-l10n-id="search-one-click-header" /></caption>
+      <label><html:h2 data-l10n-id="search-one-click-header" /></label>
       <description data-l10n-id="search-one-click-desc" />
 
       <tree id="engineList" flex="1" rows="8" hidecolumnpicker="true" editable="true"
             seltype="single" allowunderflowscroll="true">
         <treechildren id="engineChildren" flex="1"/>
         <treecols>
           <treecol id="engineShown" type="checkbox" editable="true" sortable="false"/>
           <treecol id="engineName" flex="4" data-l10n-id="search-choose-engine-column" sortable="false"/>
--- a/browser/components/preferences/in-content/sync.js
+++ b/browser/components/preferences/in-content/sync.js
@@ -303,17 +303,18 @@ var gSyncPane = {
     document.getElementById("fxaChangeDeviceName").disabled = !syncReady;
 
     // Clear the profile image (if any) of the previously logged in account.
     document.querySelector("#fxaLoginVerified > .fxaProfileImage").style.removeProperty("list-style-image");
 
     if (state.displayName) {
       fxaLoginStatus.setAttribute("hasName", true);
       displayNameLabel.hidden = false;
-      displayNameLabel.textContent = state.displayName;
+      document.getElementById("fxaDisplayNameHeading").textContent =
+        state.displayName;
     } else {
       fxaLoginStatus.removeAttribute("hasName");
     }
     if (state.avatarURL) {
       let bgImage = "url(\"" + state.avatarURL + "\")";
       let profileImageElement = document.querySelector("#fxaLoginVerified > .fxaProfileImage");
       profileImageElement.style.listStyleImage = bgImage;
 
--- a/browser/components/preferences/in-content/sync.xul
+++ b/browser/components/preferences/in-content/sync.xul
@@ -14,31 +14,31 @@
   <label class="header-name" flex="1" data-l10n-id="pane-sync-title" />
 </hbox>
 
 <deck id="weavePrefsDeck" data-category="paneSync" hidden="true"
       data-hidden-from-search="true">
   <groupbox id="noFxaAccount">
     <hbox>
       <vbox flex="1">
-        <caption><label id="noFxaCaption" data-l10n-id="sync-signedout-caption"/></caption>
+        <label id="noFxaCaption"><html:h2 data-l10n-id="sync-signedout-caption"/></label>
         <description id="noFxaDescription" flex="1" data-l10n-id="sync-signedout-description"/>
       </vbox>
       <vbox>
         <image class="fxaSyncIllustration"/>
       </vbox>
     </hbox>
     <hbox id="fxaNoLoginStatus" align="center" flex="1">
       <vbox>
         <image class="fxaProfileImage"/>
       </vbox>
       <vbox flex="1">
         <hbox align="center" flex="1">
           <hbox align="center" flex="1">
-            <caption><label id="signedOutAccountBoxTitle" data-l10n-id="sync-signedout-account-title"/></caption>
+            <label id="signedOutAccountBoxTitle"><html:h2 data-l10n-id="sync-signedout-account-title"/></label>
           </hbox>
           <button id="noFxaSignIn"
                   class="accessory-button"
                   data-l10n-id="sync-signedout-account-signin"/>
         </hbox>
         <hbox align="center" flex="1">
           <html:a id="noFxaSignUp"
                   class="openLink"
@@ -65,30 +65,32 @@
         class="text-link" target="_blank"/>
     </label>
   </groupbox>
 
   <vbox id="hasFxaAccount">
     <hbox>
       <vbox id="fxaContentWrapper" flex="1">
         <groupbox id="fxaGroup">
-          <caption class="search-header" hidden="true"><label data-l10n-id="pane-sync-title"/></caption>
+          <label class="search-header" hidden="true"><html:h2 data-l10n-id="pane-sync-title"/></label>
 
           <deck id="fxaLoginStatus" flex="1">
 
             <!-- logged in and verified and all is good -->
             <hbox id="fxaLoginVerified" align="center" flex="1">
               <image class="fxaProfileImage actionable"
                      role="button"
                      onclick="gSyncPane.openChangeProfileImage(event);"
                      onkeypress="gSyncPane.openChangeProfileImage(event);"
                      data-l10n-id="sync-profile-picture"/>
               <vbox flex="1" pack="center">
                 <hbox flex="1" align="baseline">
-                  <caption><label id="fxaDisplayName" hidden="true"/></caption>
+                  <label id="fxaDisplayName" hidden="true">
+                    <html:h2 id="fxaDisplayNameHeading"/>
+                  </label>
                   <label id="fxaEmailAddress" flex="1" crop="end"/>
                   <button id="fxaUnlinkButton"
                           class="accessory-button"
                           data-l10n-id="sync-disconnect"/>
                 </hbox>
                 <hbox>
                   <html:a id="verifiedManage" class="openLink"
                           data-l10n-id="sync-manage-account"
@@ -134,17 +136,17 @@
                   <button id="rejectReSignIn" data-l10n-id="sync-sign-in"/>
                   <button id="rejectUnlinkFxaAccount" data-l10n-id="sync-remove-account"/>
                 </hbox>
               </vbox>
             </hbox>
           </deck>
         </groupbox>
         <groupbox id="syncOptions">
-          <caption><label data-l10n-id="sync-signedin-settings-header"/></caption>
+          <label><html:h2 data-l10n-id="sync-signedin-settings-header"/></label>
           <description data-l10n-id="sync-signedin-settings-desc"/>
           <hbox id="fxaSyncEngines">
             <vbox flex="1">
               <!-- by design, no tooltip for bookmarks or history -->
               <checkbox data-l10n-id="sync-engine-bookmarks"
                         preference="engine.bookmarks"/>
               <checkbox data-l10n-id="sync-engine-history"
                         preference="engine.history"/>
@@ -164,19 +166,17 @@
                         preference="engine.prefs"/>
             </vbox>
             <spacer/>
           </hbox>
         </groupbox>
       </vbox>
     </hbox>
     <groupbox>
-      <caption>
-        <label control="fxaSyncComputerName" data-l10n-id="sync-device-name-header"/>
-      </caption>
+      <label control="fxaSyncComputerName"><html:h2 data-l10n-id="sync-device-name-header"/></label>
       <hbox id="fxaDeviceName">
         <textbox id="fxaSyncComputerName" flex="1" disabled="true"/>
         <button id="fxaChangeDeviceName"
                 data-l10n-id="sync-device-name-change"/>
         <button id="fxaCancelChangeDeviceName"
                 data-l10n-id="sync-device-name-cancel"
                 hidden="true"/>
         <button id="fxaSaveChangeDeviceName"
--- a/browser/components/preferences/sanitize.xul
+++ b/browser/components/preferences/sanitize.xul
@@ -7,16 +7,17 @@
 
 <?xml-stylesheet href="chrome://global/skin/"?>
 <?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css"?>
 
 <!DOCTYPE dialog>
 
 <dialog id="SanitizeDialog" type="child"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        xmlns:html="http://www.w3.org/1999/xhtml"
         buttons="accept,cancel,help"
         persist="lastSelected screenX screenY"
         role="dialog"
         ondialoghelp="openPrefsHelp()"
         data-l10n-id="sanitize-prefs"
         data-l10n-attrs="style"
         helpTopic="prefs-clear-private-data"
         onload="gSanitizeDialog.init();">
@@ -33,17 +34,17 @@
     <key data-l10n-id="window-close" modifiers="accel" oncommand="Preferences.close(event)"/>
   </keyset>
 
   <script type="application/javascript" src="chrome://browser/content/preferences/sanitize.js"/>
 
   <description data-l10n-id="clear-data-settings-label"></description>
 
   <groupbox>
-    <caption><label data-l10n-id="history-section-label"></label></caption>
+    <label><html:h2 data-l10n-id="history-section-label"/></label>
     <grid flex="1">
       <columns>
         <column data-l10n-id="sanitize-prefs-style" data-l10n-attrs="style"/>
         <column flex="1"/>
       </columns>
       <rows>
         <row>
           <checkbox data-l10n-id="item-history-and-downloads"
@@ -60,17 +61,17 @@
         <row>
           <checkbox data-l10n-id="item-form-search-history"
                     preference="privacy.clearOnShutdown.formdata"/>
         </row>
       </rows>
     </grid>
   </groupbox>
   <groupbox>
-    <caption><label data-l10n-id="data-section-label"></label></caption>
+    <label><html:h2 data-l10n-id="data-section-label"/></label>
     <grid flex="1">
       <columns>
         <column data-l10n-id="sanitize-prefs-style" data-l10n-attrs="style"/>
         <column flex="1"/>
       </columns>
       <rows>
         <row>
           <checkbox data-l10n-id="item-site-preferences"
new file mode 100644
--- /dev/null
+++ b/browser/config/mozconfigs/win64-aarch64/common-opt
@@ -0,0 +1,29 @@
+# This file is sourced by the nightly, beta, and release mozconfigs.
+
+. "$topsrcdir/build/mozconfig.stylo"
+
+. "$topsrcdir/browser/config/mozconfigs/common"
+
+ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
+ac_add_options --enable-jemalloc
+if [ -f /c/builds/gapi.data ]; then
+  _gapi_keyfile=c:/builds/gapi.data
+else
+  _gapi_keyfile=e:/builds/gapi.data
+fi
+ac_add_options --with-google-api-keyfile=${_gapi_keyfile}
+
+ac_add_options --with-mozilla-api-keyfile=c:/builds/mozilla-desktop-geoloc-api.key
+
+# Needed to enable breakpad in application.ini
+export MOZILLA_OFFICIAL=1
+
+export MOZ_TELEMETRY_REPORTING=1
+
+. $topsrcdir/build/win64-aarch64/mozconfig.vs-latest
+
+# Package js shell.
+export MOZ_PACKAGE_JSSHELL=1
+
+# Crashreporter does peculiar things.
+ac_add_options --disable-crashreporter
new file mode 100644
--- /dev/null
+++ b/browser/config/mozconfigs/win64-aarch64/common-win64
@@ -0,0 +1,10 @@
+# This file is used by all AArch64 Win64 builds
+
+ac_add_options --target=aarch64-windows-mingw32
+ac_add_options --host=x86_64-pc-mingw32
+
+# WebRTC is busted in various ways.
+ac_add_options --disable-webrtc
+
+# Accessibility doesn't work.
+ac_add_options --disable-accessibility
new file mode 100644
--- /dev/null
+++ b/browser/config/mozconfigs/win64-aarch64/debug
@@ -0,0 +1,29 @@
+. "$topsrcdir/build/mozconfig.win-common"
+MOZ_AUTOMATION_L10N_CHECK=0
+. "$topsrcdir/browser/config/mozconfigs/common"
+
+ac_add_options --disable-crashreporter
+
+. "$topsrcdir/browser/config/mozconfigs/win64-aarch64/common-win64"
+
+. "$topsrcdir/build/mozconfig.stylo"
+
+ac_add_options --enable-debug
+ac_add_options --enable-dmd
+ac_add_options --enable-profiling  # needed for --enable-dmd to work on Windows
+ac_add_options --enable-verify-mar
+
+# Needed to enable breakpad in application.ini
+export MOZILLA_OFFICIAL=1
+
+# Enable Telemetry
+export MOZ_TELEMETRY_REPORTING=1
+
+# Package js shell.
+export MOZ_PACKAGE_JSSHELL=1
+
+ac_add_options --with-branding=browser/branding/nightly
+
+. $topsrcdir/build/win64-aarch64/mozconfig.vs-latest
+
+. "$topsrcdir/build/mozconfig.common.override"
new file mode 100644
--- /dev/null
+++ b/browser/config/mozconfigs/win64-aarch64/debug-msvc
@@ -0,0 +1,3 @@
+. "$topsrcdir/browser/config/mozconfigs/win64-aarch64/debug"
+
+unset ENABLE_CLANG_PLUGIN
new file mode 100644
--- /dev/null
+++ b/browser/config/mozconfigs/win64-aarch64/nightly
@@ -0,0 +1,10 @@
+. "$topsrcdir/build/mozconfig.win-common"
+. "$topsrcdir/browser/config/mozconfigs/win64-aarch64/common-win64"
+. "$topsrcdir/browser/config/mozconfigs/win64-aarch64/common-opt"
+
+ac_add_options --enable-verify-mar
+ac_add_options --enable-dmd
+
+ac_add_options --with-branding=browser/branding/nightly
+
+. "$topsrcdir/build/mozconfig.common.override"
new file mode 100644
--- /dev/null
+++ b/browser/config/mozconfigs/win64-aarch64/opt-msvc
@@ -0,0 +1,3 @@
+. "$topsrcdir/browser/config/mozconfigs/win64-aarch64/nightly"
+
+unset ENABLE_CLANG_PLUGIN
new file mode 100644
--- /dev/null
+++ b/browser/config/tooltool-manifests/win64/aarch64.manifest
@@ -0,0 +1,33 @@
+[
+  {
+    "size": 266240,
+    "digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
+    "algorithm": "sha512",
+    "filename": "mozmake.exe"
+  },
+  {
+    "version": "Visual Studio 15.9 preview release 5",
+    "size": 621847510,
+    "visibility": "internal",
+    "digest": "eba775d85c32d3d0acab72804ba82f0d0180b419c6f01774bc520b7b5f74efd384a2569cb255866053d30e71c94363afee2042f1fad510c02525d5b282cbb3cf",
+    "algorithm": "sha512",
+    "filename": "vs2017_15.9.0p5.zip",
+    "unpack": true
+  },
+  {
+    "version": "makecab rev d2bc6797648b7a834782714a55d339d2fd4e58c8",
+    "algorithm": "sha512",
+    "visibility": "public",
+    "filename": "makecab.tar.bz2",
+    "unpack": true,
+    "digest": "196ac6a567c85559957dfe511c3d8654d23c94d5603259e19ccafe9d71e0e4ccee63ccc9a778f2699654b786cda54266108b7d4db543d01bb0b42545b4e6ec75",
+    "size": 297118
+  },
+  {
+    "size": 1516544,
+    "visibility": "public",
+    "digest": "cf84f9592059f1e0756370f44e0ad289b71569c235d2ec8c5958695cc57352d3b99b584fd119e73fc9593d1c4cca414985e71f567f777162471b6040ebc59d13",
+    "algorithm": "sha512",
+    "filename": "win32-minidump_stackwalk.exe"
+  }
+]
--- a/browser/extensions/formautofill/FormAutofillPreferences.jsm
+++ b/browser/extensions/formautofill/FormAutofillPreferences.jsm
@@ -31,16 +31,18 @@ const {
   EDIT_CREDITCARD_KEYWORDS,
 } = FormAutofillUtils;
 // Add credit card enabled flag in telemetry environment for recording the number of
 // users who disable/enable the credit card autofill feature.
 
 this.log = null;
 FormAutofill.defineLazyLogGetter(this, EXPORTED_SYMBOLS[0]);
 
+const HTML_NS = "http://www.w3.org/1999/xhtml";
+
 function FormAutofillPreferences() {
   this.bundle = Services.strings.createBundle(BUNDLE_URI);
 }
 
 FormAutofillPreferences.prototype = {
   /**
    * Create the Form Autofill preference group.
    *
@@ -65,18 +67,18 @@ FormAutofillPreferences.prototype = {
   /**
    * Create Form Autofill preference group
    *
    * @param  {XULDocument} document
    */
   createPreferenceGroup(document) {
     let learnMoreURL = Services.urlFormatter.formatURLPref("app.support.baseURL") + "autofill-card-address";
     let formAutofillFragment = document.createDocumentFragment();
-    let formAutofillGroupBoxCaption = document.createXULElement("caption");
-    let formAutofillGroupBoxCaptionLabel = document.createXULElement("label");
+    let formAutofillGroupBoxLabel = document.createXULElement("label");
+    let formAutofillGroupBoxLabelHeading = document.createElementNS(HTML_NS, "h2");
     let formAutofillGroupBoxDescription = document.createXULElement("description");
     let formAutofillGroup = document.createXULElement("vbox");
     let addressAutofill = document.createXULElement("hbox");
     let addressAutofillCheckboxGroup = document.createXULElement("hbox");
     let addressAutofillCheckbox = document.createXULElement("checkbox");
     let addressAutofillLearnMore = document.createXULElement("label");
     let savedAddressesBtn = document.createXULElement("button");
     // Wrappers are used to properly compute the search tooltip positions
@@ -86,17 +88,17 @@ FormAutofillPreferences.prototype = {
     savedAddressesBtn.className = "accessory-button";
     addressAutofillCheckbox.className = "tail-with-learn-more";
     addressAutofillLearnMore.className = "learnMore text-link";
 
     formAutofillGroup.id = "formAutofillGroup";
     addressAutofill.id = "addressAutofill";
     addressAutofillLearnMore.id = "addressAutofillLearnMore";
 
-    formAutofillGroupBoxCaptionLabel.textContent = this.bundle.GetStringFromName("autofillHeader");
+    formAutofillGroupBoxLabelHeading.textContent = this.bundle.GetStringFromName("autofillHeader");
     formAutofillGroupBoxDescription.textContent =
       this.bundle.formatStringFromName("autofillDescription",
                                        [FormAutofillUtils.brandBundle.GetStringFromName("brandShortName")],
                                        1);
 
     addressAutofill.setAttribute("data-subcategory", "address-autofill");
     addressAutofillCheckbox.setAttribute("label", this.bundle.GetStringFromName("autofillAddressesCheckbox"));
     addressAutofillLearnMore.textContent = this.bundle.GetStringFromName("learnMoreLabel");
@@ -114,18 +116,18 @@ FormAutofillPreferences.prototype = {
     // Manually set the checked state
     if (FormAutofill.isAutofillAddressesEnabled) {
       addressAutofillCheckbox.setAttribute("checked", true);
     }
 
     addressAutofillCheckboxGroup.align = "center";
     addressAutofillCheckboxGroup.flex = 1;
 
-    formAutofillGroupBoxCaption.appendChild(formAutofillGroupBoxCaptionLabel);
-    formAutofillFragment.appendChild(formAutofillGroupBoxCaption);
+    formAutofillGroupBoxLabel.appendChild(formAutofillGroupBoxLabelHeading);
+    formAutofillFragment.appendChild(formAutofillGroupBoxLabel);
     formAutofillFragment.appendChild(formAutofillGroupBoxDescription);
     formAutofillFragment.appendChild(formAutofillGroup);
     formAutofillGroup.appendChild(addressAutofill);
     addressAutofill.appendChild(addressAutofillCheckboxGroup);
     addressAutofillCheckboxGroup.appendChild(addressAutofillCheckbox);
     addressAutofillCheckboxGroup.appendChild(addressAutofillLearnMore);
     addressAutofill.appendChild(savedAddressesBtnWrapper);
     savedAddressesBtnWrapper.appendChild(savedAddressesBtn);
--- a/browser/installer/allowed-dupes.mn
+++ b/browser/installer/allowed-dupes.mn
@@ -93,17 +93,16 @@ chrome/toolkit/skin/classic/global/dialo
 chrome/toolkit/skin/classic/global/dropmarker.css
 chrome/toolkit/skin/classic/global/global.css
 chrome/toolkit/skin/classic/global/icons/close-win7.png
 chrome/toolkit/skin/classic/global/menu.css
 chrome/toolkit/skin/classic/global/menulist.css
 chrome/toolkit/skin/classic/global/numberbox.css
 chrome/toolkit/skin/classic/global/popup.css
 chrome/toolkit/skin/classic/global/preferences.css
-chrome/toolkit/skin/classic/global/progressmeter.css
 chrome/toolkit/skin/classic/global/radio.css
 chrome/toolkit/skin/classic/global/richlistbox.css
 chrome/toolkit/skin/classic/global/scrollbars.css
 chrome/toolkit/skin/classic/global/scrollbox.css
 chrome/toolkit/skin/classic/global/splitter.css
 chrome/toolkit/skin/classic/global/tabbox.css
 chrome/toolkit/skin/classic/global/textbox.css
 chrome/toolkit/skin/classic/global/toolbar.css
--- a/browser/themes/shared/incontentprefs/preferences.inc.css
+++ b/browser/themes/shared/incontentprefs/preferences.inc.css
@@ -23,20 +23,20 @@
   width: 100%;
   padding: 0;
 }
 
 groupbox[data-category] {
   margin: 0 0 32px;
 }
 
-caption {
+html|h2 {
   margin: 16px 0 4px;
   font-size: 1.14em;
-  font-weight: 600;
+  line-height: normal;
 }
 
 .header-name {
   margin-bottom: 8px;
 }
 
 description.indent,
 .indent > description {
--- a/build/moz.configure/init.configure
+++ b/build/moz.configure/init.configure
@@ -1149,39 +1149,23 @@ set_config('MOZILLA_SYMBOLVERSION', mile
 # JS configure still wants to look at these.
 add_old_configure_assignment('MOZILLA_VERSION', milestone.version)
 add_old_configure_assignment('MOZILLA_SYMBOLVERSION', milestone.symbolversion)
 
 set_config('MOZ_APP_VERSION', milestone.app_version)
 set_config('MOZ_APP_VERSION_DISPLAY', milestone.app_version_display)
 add_old_configure_assignment('MOZ_APP_VERSION', milestone.app_version)
 
-
-# The app update channel is 'default' when not supplied, and MOZILLA_OFFICIAL
-# is not set. When MOZILLA_OFFICIAL is set, the default is derived from
-# the application display version.
-@depends(milestone, mozilla_official)
-def default_update_channel(milestone, mozilla_official):
-    if not mozilla_official:
-        return 'default'
-    if milestone.is_release_or_beta:
-        if 'esr' in milestone.app_version_display:
-            return 'esr'
-        if 'b' in milestone.app_version_display:
-            return 'beta'
-        return 'release'
-    if milestone.is_nightly:
-        return 'nightly'
-    return 'default'
-
-
+# The app update channel is 'default' when not supplied. The value is used in
+# the application's confvars.sh (and is made available to a project specific
+# moz.configure).
 option('--enable-update-channel',
        nargs=1,
        help='Select application update channel',
-       default=default_update_channel)
+       default='default')
 
 
 @depends('--enable-update-channel')
 def update_channel(channel):
     if channel[0] == '':
         return 'default'
     return channel[0].lower()
 
--- a/build/moz.configure/rust.configure
+++ b/build/moz.configure/rust.configure
@@ -325,17 +325,18 @@ set_config('WIN64_LIB', depends('WIN64_L
 
 
 @depends(target, rustc_info, c_compiler, 'WIN64_LINK', 'WIN64_LIB')
 def win64_cargo_linker(target, rustc_info, compiler_info, link, lib):
     # When we're building a 32-bit Windows build with a 64-bit rustc, we
     # need to configure the linker it will use for host binaries (build scripts)
     # specially because the compiler configuration we use for the build is for
     # MSVC targeting 32-bit binaries.
-    if target.kernel == 'WINNT' and target.cpu == 'x86' and \
+    if target.kernel == 'WINNT' and \
+       target.cpu in ('x86', 'aarch64') and \
        compiler_info.type in ('msvc', 'clang-cl') and \
        rustc_info.host == 'x86_64-pc-windows-msvc' and link and lib:
         return True
 
 
 set_config('WIN64_CARGO_LINKER', win64_cargo_linker)
 
 
new file mode 100644
--- /dev/null
+++ b/build/win64-aarch64/mozconfig.vs-latest
@@ -0,0 +1,1 @@
+. $topsrcdir/build/win64-aarch64/mozconfig.vs2017
new file mode 100644
--- /dev/null
+++ b/build/win64-aarch64/mozconfig.vs2017
@@ -0,0 +1,47 @@
+if [ -z "${VSPATH}" ]; then
+    TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir}
+    VSPATH="$(cd ${TOOLTOOL_DIR} && pwd)/vs2017_15.9.0p5"
+fi
+
+if [ -d "${VSPATH}" ]; then
+    VSWINPATH="$(cd ${VSPATH} && pwd -W)"
+
+    export WINDOWSSDKDIR="${VSWINPATH}/SDK"
+    export WIN32_REDIST_DIR=${VSPATH}/VC/redist/onecore/arm64/Microsoft.VC141.CRT
+    export WIN_DIA_SDK_BIN_DIR="${VSPATH}/DIA SDK/bin/amd64"
+
+    win_sdk_version="10.0.17134.0"
+
+    # Need to run x86-64 host binaries.
+    export PATH="${VSPATH}/VC/bin/Hostx64/x64:${VSPATH}/SDK/bin/${win_sdk_version}/x64:${VSPATH}/VC/redist/x64/Microsoft.VC141.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x64:${WIN_DIA_SDK_BIN_DIR}:${PATH}"
+
+    export INCLUDE="${VSPATH}/VC/include:${VSPATH}/VC/atlmfc/include:${VSPATH}/SDK/Include/${win_sdk_version}/ucrt:${VSPATH}/SDK/Include/${win_sdk_version}/shared:${VSPATH}/SDK/Include/${win_sdk_version}/um:${VSPATH}/SDK/Include/${win_sdk_version}/winrt"
+    export LIB="${VSPATH}/VC/lib/arm64:${VSPATH}/VC/atlmfc/lib/arm64:${VSPATH}/SDK/Lib/${win_sdk_version}/ucrt/arm64:${VSPATH}/SDK/Lib/${win_sdk_version}/um/arm64:${VSPATH}/DIA SDK/lib/amd64"
+
+    # We need to declare host and target tools separately.
+    arm_bin="${VSPATH}/VC/bin/Hostx64/arm64"
+    export CC="${arm_bin}/cl.exe"
+    export CXX="${arm_bin}/cl.exe"
+    export AS="${arm_bin}/armasm64.exe"
+    export LINKER="${arm_bin}/link.exe"
+
+    x64_bin="${VSPATH}/VC/bin/Hostx64/x64"
+    export HOST_CC="${x64_bin}/cl.exe"
+    export HOST_CXX="${x64_bin}/cl.exe"
+    export HOST_LINKER="${x64_bin}/link.exe"
+
+    # We provided LIB, above, but we also need to provide HOST_LDFLAGS so host
+    # links are not completely confused.  LIBPATH wants its argument with
+    # Windows-style drives.
+    libs=""
+    libs="${libs} -LIBPATH:${VSWINPATH}/VC/lib/x64"
+    libs="${libs} -LIBPATH:${VSWINPATH}/VC/atlmfc/lib/x64"
+    libs="${libs} -LIBPATH:${VSWINPATH}/SDK/Lib/${win_sdk_version}/um/x64"
+    libs="${libs} -LIBPATH:${VSWINPATH}/SDK/Lib/${win_sdk_version}/ucrt/x64"
+    export HOST_LDFLAGS="${libs}"
+
+    export WIN64_LINK="${VSPATH}/VC/bin/Hostx64/x64/link.exe"
+    export WIN64_LIB="${VSPATH}/VC/lib/x64:${VSPATH}/VC/atlmfc/lib/x64:${VSPATH}/SDK/Lib/${win_sdk_version}/ucrt/x64:${VSPATH}/SDK/Lib/${win_sdk_version}/um/x64:${VSPATH}/DIA SDK/lib/amd64"
+fi
+
+. $topsrcdir/build/mozconfig.vs-common
--- a/devtools/client/debugger/new/src/actions/sources/newSources.js
+++ b/devtools/client/debugger/new/src/actions/sources/newSources.js
@@ -20,16 +20,18 @@ import { selectLocation } from "../sourc
 import { getRawSourceURL, isPrettyURL, isOriginal } from "../../utils/source";
 import {
   getBlackBoxList,
   getSource,
   getPendingSelectedLocation,
   getPendingBreakpointsForSource
 } from "../../selectors";
 
+import { prefs } from "../../utils/prefs";
+
 import type { Source, SourceId } from "../../types";
 import type { Action, ThunkArgs } from "../types";
 
 function createOriginalSource(
   originalUrl,
   generatedSource,
   sourceMaps
 ): Source {
@@ -41,17 +43,17 @@ function createOriginalSource(
     isWasm: false,
     isBlackBoxed: false,
     loadedState: "unloaded"
   };
 }
 
 function loadSourceMaps(sources) {
   return async function({ dispatch, sourceMaps }: ThunkArgs) {
-    if (!sourceMaps) {
+    if (!prefs.clientSourceMapsEnabled) {
       return;
     }
 
     let originalSources = await Promise.all(
       sources.map(({ id }) => dispatch(loadSourceMap(id)))
     );
 
     originalSources = flatten(originalSources).filter(Boolean);
--- a/devtools/client/debugger/new/src/utils/source.js
+++ b/devtools/client/debugger/new/src/utils/source.js
@@ -56,18 +56,17 @@ function trimUrlQuery(url: string): stri
 }
 
 export function shouldPrettyPrint(source: Source) {
   if (
     !source ||
     isPretty(source) ||
     !isJavaScript(source) ||
     isOriginal(source) ||
-    source.sourceMapURL ||
-    !prefs.clientSourceMapsEnabled
+    (prefs.clientSourceMapsEnabled && source.sourceMapURL)
   ) {
     return false;
   }
 
   return true;
 }
 
 /**
--- a/devtools/client/debugger/new/test/mochitest/browser.ini
+++ b/devtools/client/debugger/new/test/mochitest/browser.ini
@@ -725,16 +725,17 @@ skip-if = true
 [browser_dbg-pause-points.js]
 [browser_dbg-scopes-mutations.js]
 [browser_dbg-search-file.js]
 skip-if = os == "win" # Bug 1393121
 [browser_dbg-quick-open.js]
 skip-if = os == "win"
 [browser_dbg-search-project.js]
 [browser_dbg-sourcemaps.js]
+[browser_dbg-sourcemaps-disabled.js]
 [browser_dbg-sourcemaps-reload.js]
 skip-if = os == "win" || (verify) # Bug 1434792
 [browser_dbg-sourcemaps-reloading.js]
 [browser_dbg-sourcemaps2.js]
 [browser_dbg-sourcemaps3.js]
 [browser_dbg-sourcemaps-bogus.js]
 skip-if = os == 'linux' && !asan # bug 1447118
 [browser_dbg-sources.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps-disabled.js
@@ -0,0 +1,19 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Tests loading and pretty printing bundles with sourcemaps disabled
+requestLongerTimeout(2);
+
+add_task(async function() {
+  await pushPref("devtools.source-map.client-service.enabled", false);
+  const dbg = await initDebugger("doc-sourcemaps.html");
+
+  await waitForSources(dbg, "bundle.js");
+  const bundleSrc = findSource(dbg, "bundle.js");
+
+  info('Pretty print the bundle');
+  await selectSource(dbg, bundleSrc);
+  clickElement(dbg, "prettyPrintButton");
+  await waitForSelectedSource(dbg, "bundle.js:formatted");
+  ok(true, 'everything finished');
+});
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -685,19 +685,16 @@ Toolbox.prototype = {
   },
 
   /**
    * A common access point for the client-side mapping service for source maps that
    * any panel can use.  This is a "low-level" API that connects to
    * the source map worker.
    */
   get sourceMapService() {
-    if (!Services.prefs.getBoolPref("devtools.source-map.client-service.enabled")) {
-      return null;
-    }
     return this._createSourceMapService();
   },
 
   /**
    * Clients wishing to use source maps but that want the toolbox to
    * track the source and style sheet actor mapping can use this
    * source map service.  This is a higher-level service than the one
    * returned by |sourceMapService|, in that it automatically tracks
--- a/devtools/client/styleeditor/StyleEditorUI.jsm
+++ b/devtools/client/styleeditor/StyleEditorUI.jsm
@@ -309,17 +309,18 @@ StyleEditorUI.prototype = {
     }
 
     if (!this._seenSheets.has(styleSheet)) {
       const promise = (async () => {
         let editor = await this._addStyleSheetEditor(styleSheet, isNew);
 
         const toolbox = gDevTools.getToolbox(this._target);
         const sourceMapService = toolbox.sourceMapService;
-        if (!sourceMapService) {
+
+        if (!sourceMapService || !Services.prefs.getBoolPref(PREF_ORIG_SOURCES)) {
           return editor;
         }
 
         const {href, nodeHref, actorID: id, sourceMapURL} = styleSheet;
         const url = href || nodeHref;
         const sources = await sourceMapService.getOriginalURLs({
           id,
           url,
deleted file mode 100644
--- a/dom/base/crashtests/398088-1.xul
+++ /dev/null
@@ -1,23 +0,0 @@
-<window onload="boom();" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<script>
-
-function boom()
-{
-  var p = document.getElementById("p");
-  
-  document.addEventListener("DOMAttrModified", removeP, true); 
-  
-  p.removeAttribute("mode");
-  
-  function removeP()
-  {
-    document.documentElement.removeChild(p);
-  }
-}
-
-</script>
-
-<progressmeter id="p" mode="determined" />
-
-</window>
--- a/dom/base/crashtests/crashtests.list
+++ b/dom/base/crashtests/crashtests.list
@@ -46,17 +46,16 @@ load 377360-1.xhtml
 load 377960-1.html
 load 377960-2.html
 load 384663-1.html
 load 386000-1.html
 load 386794-1.html
 load 387460-1.html
 load 395469-1.xhtml
 load 395469-2.xhtml
-load 398088-1.xul
 skip load 399712-1.html # sporadically times out (bug 473680)
 load 400763-1.html
 load 401993-1.html
 load 404869-1.xul
 load 407818.html
 load 410860-1.xml
 load 411882-1.xhtml
 load 416734-1.html
--- a/gfx/skia/skia/src/ports/SkGlobalInitialization_default.cpp
+++ b/gfx/skia/skia/src/ports/SkGlobalInitialization_default.cpp
@@ -1,26 +1,30 @@
 /*
  * Copyright 2011 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
 
 #include "SkFlattenablePriv.h"
+#include "SkMaskFilter.h"
 #include "../../src/effects/SkDashImpl.h"
 #include "SkGradientShader.h"
 
 /*
  *  None of these are strictly "required" for Skia to operate.
  *
  *  These are the bulk of our "effects" -- subclasses of various effects on SkPaint.
  *
  *  Clients should feel free to dup this file and modify it as needed. This function "InitEffects"
  *  will automatically be called before any of skia's effects are asked to be deserialized.
  */
 void SkFlattenable::PrivateInitializer::InitEffects() {
     // Shader
     SkGradientShader::InitializeFlattenables();
 
+    // Mask filters.
+    SkMaskFilter::InitializeFlattenables();
+
     // PathEffect
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDashImpl)
 }
new file mode 100644
--- /dev/null
+++ b/gfx/tests/crashtests/1505426-1.html
@@ -0,0 +1,23 @@
+<html>
+
+<head>
+  <script>
+    function start() {
+      canvas = document.getElementById('canvas')
+      context = canvas.getContext('2d')
+      canvas.setAttribute('x', 800)
+      setTimeout(function() {
+        context.fillText('i', 158, 156, 206)
+      }, 0)
+      context.setTransform(0, 1, 19, 1, 0.0989504886744, 0)
+    }
+    document.addEventListener('DOMContentLoaded', start)
+  </script>
+
+</head>
+
+<body>
+  <canvas id='canvas'></canvas>
+</body>
+
+</html>
\ No newline at end of file
--- a/gfx/tests/crashtests/crashtests.list
+++ b/gfx/tests/crashtests/crashtests.list
@@ -168,8 +168,9 @@ load 1464243.html
 load 1467847-1.html
 load 1468020.html
 load 1470437.html
 load 1470440.html
 load 1478035.html
 load 1490704-1.html
 load 1501518.html
 load 1503986-1.html
+load 1505426-1.html
--- a/js/public/CompilationAndEvaluation.h
+++ b/js/public/CompilationAndEvaluation.h
@@ -3,16 +3,18 @@
  * 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/. */
 
 /* Functions for compiling and evaluating scripts. */
 
 #ifndef js_CompilationAndEvaluation_h
 #define js_CompilationAndEvaluation_h
 
+#include "mozilla/Utf8.h" // mozilla::Utf8Unit
+
 #include <stddef.h> // size_t
 #include <stdio.h> // FILE
 
 #include "jstypes.h" // JS_PUBLIC_API
 
 #include "js/CompileOptions.h" // JS::CompileOptions, JS::ReadOnlyCompileOptions
 #include "js/RootingAPI.h" // JS::Handle, JS::MutableHandle
 #include "js/Value.h" // JS::Value and specializations of JS::*Handle-related types
@@ -152,16 +154,32 @@ EvaluateUtf8Path(JSContext* cx, const Re
 /**
  * |script| will always be set. On failure, it will be set to nullptr.
  */
 extern JS_PUBLIC_API bool
 Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
         SourceText<char16_t>& srcBuf, MutableHandle<JSScript*> script);
 
 /**
+ * Identical to |JS::Compile|, but compiles UTF-8.
+ *
+ * The "DontInflate" suffix is temporary while bugs in UTF-8 compilation are
+ * ironed out.  In the long term this function and |JS::Compile| will follow
+ * the same naming scheme.
+ *
+ * NOTE: This function DOES NOT INFLATE the UTF-8 bytes to UTF-16 before
+ *       compiling them.  UTF-8 compilation is currently experimental and has
+ *       known bugs.  Use only if you're willing to tolerate unspecified bugs!
+ */
+extern JS_PUBLIC_API bool
+CompileDontInflate(JSContext* cx, const ReadOnlyCompileOptions& options,
+                   SourceText<mozilla::Utf8Unit>& srcBuf,
+                   MutableHandle<JSScript*> script);
+
+/**
  * Compile the provided UTF-8 data into a script.  If the data contains invalid
  * UTF-8, an error is reported.
  *
  * |script| is always set to the compiled script or to null in case of error.
  */
 extern JS_PUBLIC_API bool
 CompileUtf8(JSContext* cx, const ReadOnlyCompileOptions& options,
             const char* bytes, size_t length, MutableHandle<JSScript*> script);
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -1409,58 +1409,161 @@ template<typename Unit, class AnyCharsAc
 void
 TokenStreamSpecific<Unit, AnyCharsAccess>::currentLineAndColumn(uint32_t* line, uint32_t* column) const
 {
     const TokenStreamAnyChars& anyChars = anyCharsAccess();
     uint32_t offset = anyChars.currentToken().pos.begin;
     anyChars.srcCoords.lineNumAndColumnIndex(offset, line, column);
 }
 
+template<>
+inline void
+SourceUnits<char16_t>::computeWindowOffsetAndLength(const char16_t* encodedWindow,
+                                                    size_t encodedTokenOffset,
+                                                    size_t* utf16TokenOffset,
+                                                    size_t encodedWindowLength,
+                                                    size_t* utf16WindowLength)
+{
+    MOZ_ASSERT_UNREACHABLE("shouldn't need to recompute for UTF-16");
+}
+
+template<>
+inline void
+SourceUnits<Utf8Unit>::computeWindowOffsetAndLength(const Utf8Unit* encodedWindow,
+                                                    size_t encodedTokenOffset,
+                                                    size_t* utf16TokenOffset,
+                                                    size_t encodedWindowLength,
+                                                    size_t* utf16WindowLength)
+{
+    MOZ_ASSERT(encodedTokenOffset <= encodedWindowLength,
+               "token offset must be within the window, and the two lambda "
+               "calls below presume this ordering of values");
+
+    const Utf8Unit* const encodedWindowEnd = encodedWindow + encodedWindowLength;
+
+    size_t i = 0;
+    auto ComputeUtf16Count = [&i, &encodedWindow](const Utf8Unit* limit) {
+        while (encodedWindow < limit) {
+            Utf8Unit lead = *encodedWindow++;
+            if (MOZ_LIKELY(IsAscii(lead))) {
+                // ASCII contributes a single UTF-16 code unit.
+                i++;
+                continue;
+            }
+
+            Maybe<char32_t> cp = DecodeOneUtf8CodePoint(lead, &encodedWindow, limit);
+            MOZ_ASSERT(cp.isSome(),
+                       "computed window should only contain valid UTF-8");
+
+            i += unicode::IsSupplementary(cp.value()) ? 2 : 1;
+        }
+
+        return i;
+    };
+
+    // Compute the token offset from |i == 0| and the initial |encodedWindow|.
+    const Utf8Unit* token = encodedWindow + encodedTokenOffset;
+    MOZ_ASSERT(token <= encodedWindowEnd);
+    *utf16TokenOffset = ComputeUtf16Count(token);
+
+    // Compute the window length, picking up from |i| and |encodedWindow| that,
+    // in general, were modified just above.
+    *utf16WindowLength = ComputeUtf16Count(encodedWindowEnd);
+}
+
 template<typename Unit>
 bool
 TokenStreamCharsBase<Unit>::addLineOfContext(ErrorMetadata* err, uint32_t offset)
 {
-    size_t windowStart = sourceUnits.findWindowStart(offset);
-    size_t windowEnd = sourceUnits.findWindowEnd(offset);
-
-    size_t windowLength = windowEnd - windowStart;
-    MOZ_ASSERT(windowLength <= SourceUnits::WindowRadius * 2);
+    // Rename the variable to make meaning clearer: an offset into source units
+    // in Unit encoding.
+    size_t encodedOffset = offset;
+
+    // These are also offsets into source units in Unit encoding.
+    size_t encodedWindowStart = sourceUnits.findWindowStart(encodedOffset);
+    size_t encodedWindowEnd = sourceUnits.findWindowEnd(encodedOffset);
+
+    size_t encodedWindowLength = encodedWindowEnd - encodedWindowStart;
+    MOZ_ASSERT(encodedWindowLength <= SourceUnits::WindowRadius * 2);
 
     // Don't add a useless "line" of context when the window ends up empty
     // because of an invalid encoding at the start of a line.
-    if (windowLength == 0) {
+    if (encodedWindowLength == 0) {
         MOZ_ASSERT(err->lineOfContext == nullptr,
                    "ErrorMetadata::lineOfContext must be null so we don't "
                    "have to set the lineLength/tokenOffset fields");
         return true;
     }
 
     // We might have hit an error while processing some source code feature
     // that's accumulating text into |this->charBuffer| -- e.g. we could be
     // halfway into a regular expression literal, then encounter invalid UTF-8.
     // Thus we must clear |this->charBuffer| of prior work.
     this->charBuffer.clear();
 
-    const Unit* start = sourceUnits.codeUnitPtrAt(windowStart);
-    if (!fillCharBufferFromSourceNormalizingAsciiLineBreaks(start, start + windowLength)) {
+    const Unit* encodedWindow = sourceUnits.codeUnitPtrAt(encodedWindowStart);
+    if (!fillCharBufferFromSourceNormalizingAsciiLineBreaks(encodedWindow,
+                                                            encodedWindow + encodedWindowLength))
+    {
         return false;
     }
 
+    size_t utf16WindowLength = this->charBuffer.length();
+
     // The windowed string is null-terminated.
     if (!this->charBuffer.append('\0')) {
         return false;
     }
 
     err->lineOfContext.reset(this->charBuffer.extractOrCopyRawBuffer());
     if (!err->lineOfContext) {
         return false;
     }
 
-    err->lineLength = windowLength;
-    err->tokenOffset = offset - windowStart;
+    size_t encodedTokenOffset = encodedOffset - encodedWindowStart;
+
+    MOZ_ASSERT(encodedTokenOffset <= encodedWindowLength,
+               "token offset must be inside the window");
+
+    // The length in UTF-8 code units of a code point is always greater than or
+    // equal to the same code point's length in UTF-16 code points.  ASCII code
+    // points are 1 unit in either encoding.  Code points in [U+0080, U+10000)
+    // are 2-3 UTF-8 code units to 1 UTF-16 code unit.  And code points in
+    // [U+10000, U+10FFFF] are 4 UTF-8 code units to 2 UTF-16 code units.
+    //
+    // Therefore, if encoded window length equals the length in UTF-16 (this is
+    // always the case for Unit=char16_t), the UTF-16 offsets are exactly the
+    // encoded offsets.  Otherwise we must convert offset/length from UTF-8 to
+    // UTF-16.
+    if (std::is_same<Unit, char16_t>::value) {
+        MOZ_ASSERT(utf16WindowLength == encodedWindowLength,
+                   "UTF-16 to UTF-16 shouldn't change window length");
+        err->tokenOffset = encodedTokenOffset;
+        err->lineLength = encodedWindowLength;
+    } else {
+        MOZ_ASSERT((std::is_same<Unit, Utf8Unit>::value),
+                   "should only see UTF-8 here");
+
+        bool simple = utf16WindowLength == encodedWindowLength;
+        MOZ_ASSERT(std::all_of(encodedWindow, encodedWindow + encodedWindowLength,
+                               IsAscii<Unit>) ==
+                   simple,
+                   "equal window lengths in UTF-8 should correspond only to "
+                   "wholly-ASCII text");
+
+        if (simple) {
+            err->tokenOffset = encodedTokenOffset;
+            err->lineLength = encodedWindowLength;
+        } else {
+            sourceUnits.computeWindowOffsetAndLength(encodedWindow,
+                                                     encodedTokenOffset, &err->tokenOffset,
+                                                     encodedWindowLength, &err->lineLength);
+        }
+    }
+
     return true;
 }
 
 template<typename Unit, class AnyCharsAccess>
 bool
 TokenStreamSpecific<Unit, AnyCharsAccess>::computeErrorMetadata(ErrorMetadata* err,
                                                                 uint32_t offset)
 {
@@ -3183,17 +3286,17 @@ TokenStreamSpecific<Unit, AnyCharsAccess
                     return false;
                 }
 
                 // If we consumed U+2028 LINE SEPARATOR or U+2029 PARAGRAPH
                 // SEPARATOR, they'll be normalized to '\n'.  '\' followed by
                 // LineContinuation represents no code points, so don't append
                 // in this case.
                 if (codePoint != '\n') {
-                    if (!this->charBuffer.append(unit)) {
+                    if (!appendCodePointToCharBuffer(AssertedCast<char32_t>(codePoint))) {
                         return false;
                     }
                 }
 
                 continue;
             }
 
             // The block above eliminated all non-ASCII, so cast to the
--- a/js/src/frontend/TokenStream.h
+++ b/js/src/frontend/TokenStream.h
@@ -1418,16 +1418,45 @@ class SourceUnits
     /**
      * From absolute offset |offset|, find an absolute offset within source
      * text, no further than |WindowRadius| code units away from |offset|, such
      * that all code units from |offset| to that offset are valid,
      * non-LineTerminator code points.
      */
     size_t findWindowEnd(size_t offset) const;
 
+    /**
+     * Given a |window| of |encodingSpecificWindowLength| units encoding valid
+     * Unicode text, with index |encodingSpecificTokenOffset| indicating a
+     * particular code point boundary in |window|, compute the corresponding
+     * token offset and length if |window| were encoded in UTF-16.  For
+     * example:
+     *
+     *   // U+03C0 GREEK SMALL LETTER PI is encoded as 0xCF 0x80.
+     *   const Utf8Unit* encodedWindow =
+     *     reinterpret_cast<const Utf8Unit*>(u8"ππππ = @ FAIL");
+     *   size_t encodedTokenOffset = 11; // 2 * 4 + ' = '.length
+     *   size_t encodedWindowLength = 17; // 2 * 4 + ' = @ FAIL'.length
+     *   size_t utf16Offset, utf16Length;
+     *   computeWindowOffsetAndLength(encodedWindow,
+     *                                encodedTokenOffset, &utf16Offset,
+     *                                encodedWindowLength, &utf16Length);
+     *   MOZ_ASSERT(utf16Offset == 7);
+     *   MOZ_ASSERT(utf16Length = 13);
+     *
+     * This function asserts if called for UTF-16: the sole caller can avoid
+     * computing UTF-16 offsets when they're definitely the same as the encoded
+     * offsets.
+     */
+    inline void computeWindowOffsetAndLength(const Unit* encodeWindow,
+                                             size_t encodingSpecificTokenOffset,
+                                             size_t* utf16TokenOffset,
+                                             size_t encodingSpecificWindowLength,
+                                             size_t* utf16WindowLength);
+
   private:
     /** Base of buffer. */
     const Unit* base_;
 
     /** Offset of base_[0]. */
     uint32_t startOffset_;
 
     /** Limit for quick bounds check. */
--- a/js/src/jsapi-tests/moz.build
+++ b/js/src/jsapi-tests/moz.build
@@ -26,16 +26,17 @@ UNIFIED_SOURCES += [
     'testDateToLocaleString.cpp',
     'testDebugger.cpp',
     'testDeepFreeze.cpp',
     'testDefineGetterSetterNonEnumerable.cpp',
     'testDefineProperty.cpp',
     'testDefinePropertyIgnoredAttributes.cpp',
     'testDeflateStringToUTF8Buffer.cpp',
     'testDifferentNewTargetInvokeConstructor.cpp',
+    'testEmptyWindowIsOmitted.cpp',
     'testErrorCopying.cpp',
     'testErrorLineOfContext.cpp',
     'testException.cpp',
     'testExecuteInJSMEnvironment.cpp',
     'testExternalArrayBuffer.cpp',
     'testExternalStrings.cpp',
     'testFindSCCs.cpp',
     'testForceLexicalInitialization.cpp',
--- a/js/src/jsapi-tests/testCompileUtf8.cpp
+++ b/js/src/jsapi-tests/testCompileUtf8.cpp
@@ -11,16 +11,17 @@
 #include "jsfriendapi.h"
 
 #include "js/CharacterEncoding.h"
 #include "js/CompilationAndEvaluation.h"
 #include "js/SourceText.h"
 #include "jsapi-tests/tests.h"
 #include "vm/ErrorReporting.h"
 
+using mozilla::ArrayEqual;
 using mozilla::ArrayLength;
 using mozilla::IsAsciiHexDigit;
 using mozilla::Utf8Unit;
 
 BEGIN_TEST(testUtf8BadBytes)
 {
     static const char badLeadingUnit[] = "var x = \x80";
     CHECK(testBadUtf8(badLeadingUnit,
@@ -200,37 +201,26 @@ isTooBigMessage(const char* str)
 
 static bool
 isNotShortestFormMessage(const char* str)
 {
     return isForbiddenCodePointMessage(str) &&
            contains(str, "it wasn't encoded in shortest possible form");
 }
 
-bool
-compileUtf8(const char* chars, size_t len, JS::MutableHandleScript script)
-{
-    JS::RealmOptions globalOptions;
-    JS::RootedObject global(cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr,
-						   JS::FireOnNewGlobalHook, globalOptions));
-    CHECK(global);
-
-    JSAutoRealm ar(cx, global);
-
-    JS::CompileOptions options(cx);
-    return JS::CompileUtf8DontInflate(cx, options, chars, len, script);
-}
-
 template<size_t N, typename TestMessage>
 bool
 testBadUtf8(const char (&chars)[N], unsigned errorNumber,
             TestMessage testMessage, const char* badBytes)
 {
     JS::Rooted<JSScript*> script(cx);
-    CHECK(!compileUtf8(chars, N - 1, &script));
+    {
+        JS::CompileOptions options(cx);
+        CHECK(!JS::CompileUtf8DontInflate(cx, options, chars, N - 1, &script));
+    }
 
     JS::RootedValue exn(cx);
     CHECK(JS_GetPendingException(cx, &exn));
     JS_ClearPendingException(cx);
 
     js::ErrorReport report(cx);
     CHECK(report.init(cx, exn, js::ErrorReport::WithSideEffects));
 
@@ -272,8 +262,66 @@ testBadUtf8(const char (&chars)[N], unsi
     CHECK(lineOfContext[lineOfContextLength] == '\0');
     CHECK(lineOfContextLength == expectedContextLen);
 
     CHECK(std::memcmp(lineOfContext, expectedContext, expectedContextLen * sizeof(char16_t)) == 0);
 
     return true;
 }
 END_TEST(testUtf8BadBytes)
+
+BEGIN_TEST(testMultiUnitUtf8InWindow)
+{
+    static const char firstInWindowIsMultiUnit[] =
+      "\xCF\x80\xCF\x80 = 6.283185307; @ bad starts HERE:\x80\xFF\xFF";
+    CHECK(testContext(firstInWindowIsMultiUnit,
+                      u"ππ = 6.283185307; @ bad starts HERE:"));
+
+    static const char atTokenOffsetIsMulti[] =
+      "var z = 💯";
+    CHECK(testContext(atTokenOffsetIsMulti,
+                      u"var z = 💯"));
+
+    static const char afterTokenOffsetIsMulti[] =
+      "var z = @💯💯💯X";
+    CHECK(testContext(afterTokenOffsetIsMulti,
+                      u"var z = @💯💯💯X"));
+
+    static const char atEndIsMulti[] =
+      "var z = @@💯💯💯";
+    CHECK(testContext(atEndIsMulti,
+                      u"var z = @@💯💯💯"));
+
+    return true;
+}
+
+template<size_t N, size_t ContextLenWithNull>
+bool
+testContext(const char (&chars)[N], const char16_t (&expectedContext)[ContextLenWithNull])
+{
+    JS::Rooted<JSScript*> script(cx);
+    {
+        JS::CompileOptions options(cx);
+        CHECK(!JS::CompileUtf8DontInflate(cx, options, chars, N - 1, &script));
+    }
+
+    JS::RootedValue exn(cx);
+    CHECK(JS_GetPendingException(cx, &exn));
+    JS_ClearPendingException(cx);
+
+    js::ErrorReport report(cx);
+    CHECK(report.init(cx, exn, js::ErrorReport::WithSideEffects));
+
+    const auto* errorReport = report.report();
+
+    CHECK(errorReport->errorNumber == JSMSG_ILLEGAL_CHARACTER);
+
+    const char16_t* lineOfContext = errorReport->linebuf();
+    size_t lineOfContextLength = errorReport->linebufLength();
+
+    CHECK(lineOfContext[lineOfContextLength] == '\0');
+    CHECK(lineOfContextLength == ContextLenWithNull - 1);
+
+    CHECK(ArrayEqual(lineOfContext, expectedContext, ContextLenWithNull));
+
+    return true;
+}
+END_TEST(testMultiUnitUtf8InWindow)
new file mode 100644
--- /dev/null
+++ b/js/src/jsapi-tests/testEmptyWindowIsOmitted.cpp
@@ -0,0 +1,165 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/TextUtils.h"
+#include "mozilla/Utf8.h"
+
+#include <cstring>
+
+#include "jsfriendapi.h"
+
+#include "js/CharacterEncoding.h"
+#include "js/CompilationAndEvaluation.h"
+#include "js/SourceText.h"
+#include "jsapi-tests/tests.h"
+#include "vm/ErrorReporting.h"
+
+using mozilla::ArrayLength;
+using mozilla::IsAsciiHexDigit;
+using mozilla::Utf8Unit;
+
+BEGIN_TEST(testEmptyWindow)
+{
+    return testUtf8() && testUtf16();
+}
+
+bool
+testUtf8()
+{
+    // Bad unit with nothing before it.
+    static const char badLeadingUnit[] = "\x80";
+    CHECK(testOmittedWindow(badLeadingUnit, JSMSG_BAD_LEADING_UTF8_UNIT, "0x80"));
+
+    // Bad unit at start of a fresh line.
+    static const char badStartingFreshLine[] = "var x = 5;\n\x98";
+    CHECK(testOmittedWindow(badStartingFreshLine, JSMSG_BAD_LEADING_UTF8_UNIT, "0x98"));
+
+    // Bad trailing unit in initial code point.
+    static const char badTrailingUnit[] = "\xD8\x20";
+    CHECK(testOmittedWindow(badTrailingUnit, JSMSG_BAD_TRAILING_UTF8_UNIT, "0xD8 0x20"));
+
+    // Bad trailing unit at start of a fresh line.
+    static const char badTrailingUnitFreshLine[] = "var x = 5;\n\xD8\x20";
+    CHECK(testOmittedWindow(badTrailingUnitFreshLine, JSMSG_BAD_TRAILING_UTF8_UNIT, "0xD8 0x20"));
+
+    // Overlong in initial code point.
+    static const char overlongInitial[] = "\xC0\x80";
+    CHECK(testOmittedWindow(overlongInitial, JSMSG_FORBIDDEN_UTF8_CODE_POINT, "0xC0 0x80"));
+
+    // Overlong at start of a fresh line.
+    static const char overlongFreshLine[] = "var x = 5;\n\xC0\x81";
+    CHECK(testOmittedWindow(overlongFreshLine, JSMSG_FORBIDDEN_UTF8_CODE_POINT, "0xC0 0x81"));
+
+    // Not-enough in initial code point.
+    static const char notEnoughInitial[] = "\xF0";
+    CHECK(testOmittedWindow(notEnoughInitial, JSMSG_NOT_ENOUGH_CODE_UNITS, "0xF0"));
+
+    // Not-enough at start of a fresh line.
+    static const char notEnoughFreshLine[] = "var x = 5;\n\xF0";
+    CHECK(testOmittedWindow(notEnoughFreshLine, JSMSG_NOT_ENOUGH_CODE_UNITS, "0xF0"));
+
+    return true;
+}
+
+bool
+testUtf16()
+{
+    // Bad unit with nothing before it.
+    static const char16_t badLeadingUnit[] = u"\xDFFF";
+    CHECK(testOmittedWindow(badLeadingUnit, JSMSG_ILLEGAL_CHARACTER));
+
+    // Bad unit at start of a fresh line.
+    static const char16_t badStartingFreshLine[] = u"var x = 5;\n\xDFFF";
+    CHECK(testOmittedWindow(badStartingFreshLine, JSMSG_ILLEGAL_CHARACTER));
+
+    return true;
+}
+
+static bool
+startsWith(const char* str, const char* prefix)
+{
+    return std::strncmp(prefix, str, strlen(prefix)) == 0;
+}
+
+static bool
+equals(const char* str, const char* expected)
+{
+    return std::strcmp(str, expected) == 0;
+}
+
+bool
+compile(const char16_t* chars, size_t len, JS::MutableHandle<JSScript*> script)
+{
+    JS::SourceText<char16_t> source;
+    CHECK(source.init(cx, chars, len, JS::SourceOwnership::Borrowed));
+
+    JS::CompileOptions options(cx);
+    return JS::Compile(cx, options, source, script);
+}
+
+bool
+compile(const char* chars, size_t len, JS::MutableHandle<JSScript*> script)
+{
+    JS::SourceText<Utf8Unit> source;
+    CHECK(source.init(cx, chars, len, JS::SourceOwnership::Borrowed));
+
+    JS::CompileOptions options(cx);
+    return JS::CompileDontInflate(cx, options, source, script);
+}
+
+template<typename CharT, size_t N>
+bool
+testOmittedWindow(const CharT (&chars)[N], unsigned expectedErrorNumber,
+                  const char* badCodeUnits = nullptr)
+{
+    JS::Rooted<JSScript*> script(cx);
+    CHECK(!compile(chars, N - 1, &script));
+
+    JS::RootedValue exn(cx);
+    CHECK(JS_GetPendingException(cx, &exn));
+    JS_ClearPendingException(cx);
+
+    js::ErrorReport report(cx);
+    CHECK(report.init(cx, exn, js::ErrorReport::WithSideEffects));
+
+    const auto* errorReport = report.report();
+
+    CHECK(errorReport->errorNumber == expectedErrorNumber);
+
+    if (const auto& notes = errorReport->notes) {
+        CHECK(sizeof(CharT) == 1);
+        CHECK(badCodeUnits != nullptr);
+
+        auto iter = notes->begin();
+        CHECK(iter != notes->end());
+
+        const char* noteMessage = (*iter)->message().c_str();
+
+        // The prefix ought always be the same.
+        static const char expectedPrefix[] =
+            "the code units comprising this invalid code point were: ";
+        constexpr size_t expectedPrefixLen = ArrayLength(expectedPrefix) - 1;
+
+        CHECK(startsWith(noteMessage, expectedPrefix));
+
+        // The end of the prefix is the bad code units.
+        CHECK(equals(noteMessage + expectedPrefixLen, badCodeUnits));
+
+        ++iter;
+        CHECK(iter == notes->end());
+    } else {
+        CHECK(sizeof(CharT) == 2);
+
+        // UTF-16 encoding "errors" are not categorical errors, so the errors
+        // are just of the invalid-character sort, without an accompanying note
+        // spelling out a series of invalid code units.
+        CHECK(!badCodeUnits);
+    }
+
+    CHECK(!errorReport->linebuf());
+
+    return true;
+}
+END_TEST(testEmptyWindow)
--- a/js/src/vm/CompilationAndEvaluation.cpp
+++ b/js/src/vm/CompilationAndEvaluation.cpp
@@ -121,16 +121,23 @@ CompileUtf8DontInflate(JSContext* cx, co
 bool
 JS::Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
             SourceText<char16_t>& srcBuf, JS::MutableHandleScript script)
 {
     return CompileSourceBuffer(cx, options, srcBuf, script);
 }
 
 bool
+JS::CompileDontInflate(JSContext* cx, const ReadOnlyCompileOptions& options,
+                       SourceText<Utf8Unit>& srcBuf, JS::MutableHandleScript script)
+{
+    return CompileSourceBuffer(cx, options, srcBuf, script);
+}
+
+bool
 JS::CompileLatin1(JSContext* cx, const ReadOnlyCompileOptions& options,
                   const char* bytes, size_t length, JS::MutableHandleScript script)
 {
     return ::CompileLatin1(cx, options, bytes, length, script);
 }
 
 bool
 JS::CompileUtf8(JSContext* cx, const ReadOnlyCompileOptions& options,
deleted file mode 100644
--- a/layout/reftests/bugs/474336-1-ref.xul
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-
-<window xmlns:html="http://www.w3.org/1999/xhtml"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        >
-
-<html:style>
-    #prog {
-        -moz-appearance: none;
-        background-color: blue;
-    }
-    #prog .progress-bar {
-        -moz-appearance: none;
-        border-radius: 3px 3px;
-        background-color: red;
-    }
-</html:style>
-
-<progressmeter id="prog" value="50" max="200"/>
-
-</window>
deleted file mode 100644
--- a/layout/reftests/bugs/474336-1.xul
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-
-<window xmlns:html="http://www.w3.org/1999/xhtml"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        class="reftest-wait">
-
-<html:style>
-    #prog {
-        -moz-appearance: none;
-        background-color: blue;
-    }
-    #prog .progress-bar {
-        -moz-appearance: none;
-        border-radius: 3px 3px;
-        background-color: red;
-    }
-</html:style>
-
-<progressmeter id="prog" value="50"/>
-
-<script>
-<![CDATA[
-
-function load(event) {
-  setTimeout(function() {
-    document.getElementById("prog").max = 200;
-    document.documentElement.removeAttribute("class");
-  }, 0);
-}
-window.addEventListener("load", load, false);
-
-]]>
-</script>
-
-</window>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1255,17 +1255,16 @@ fuzzy(0-255,0-15) == 472020-1a.xul 47202
 fails == 472020-1b.xul 472020-1-ref.xul
 fails == 472020-2.xul 472020-2-ref.xul
 == 472500-1.xul 472500-1-ref.xul
 == 472769-1a.html 472769-1-ref.html
 == 472769-1b.html 472769-1-ref.html
 == 472769-2.html 472769-2-ref.html
 == 472769-3.html 472769-3-ref.html
 == 473847-1.xul 473847-1-ref.xul
-fuzzy-if(skiaContent,0-1,0-16) == 474336-1.xul 474336-1-ref.xul
 == 474417-1.html 474417-1-ref.html
 fuzzy-if(skiaContent,0-1,0-5) == 474472-1.html 474472-1-ref.html
 == 475986-1a.html 475986-1-ref.html
 == 475986-1b.html 475986-1-ref.html
 == 475986-1c.html 475986-1-ref.html
 == 475986-1d.html 475986-1-ref.html
 == 475986-1e.html 475986-1-ref.html
 == 475986-1f.html 475986-1-ref.html
deleted file mode 100644
--- a/layout/xul/crashtests/472189.xul
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<window id="yourwindow" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-<script type="text/javascript">
-<![CDATA[
-function onload() {
-  document.addEventListener("DOMAttrModified", function() {}, true);
-  document.getElementById("test").setAttribute("value", "50");
-}
-]]>
-</script>
-<progressmeter id="test"/>
-</window>
\ No newline at end of file
deleted file mode 100644
--- a/layout/xul/crashtests/475133.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script type="text/javascript">
-function x()
-{
-  document.removeEventListener("DOMAttrModified", x);
-  document.removeChild(document.documentElement);
-}
-
-function boom()
-{
-  var p = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "progressmeter");
-  document.addEventListener("DOMAttrModified", x);
-  document.documentElement.appendChild(p);
-}
-</script>
-</head>
-<body onload="boom();"></body>
-</html>
--- a/layout/xul/crashtests/crashtests.list
+++ b/layout/xul/crashtests/crashtests.list
@@ -54,18 +54,16 @@ load 408904-1.xul
 load 412479-1.xhtml
 load 417509.xul
 load 430356-1.xhtml
 load 452185.html
 asserts(0-1) load 464407-1.xhtml # Bugs 450974, 1267054, 718883
 load 467080.xul
 load 470063-1.html
 load 470272.html
-load 472189.xul
-load 475133.html
 load 538308-1.xul
 load 557174-1.xml
 load 564705-1.xul
 load 583957-1.html
 load 617089.html
 load menulist-focused.xhtml
 load 716503.html
 load 1379332-1.xul
--- a/mfbt/Utf8.h
+++ b/mfbt/Utf8.h
@@ -228,18 +228,19 @@ Utf8AsUnsignedChars(const Utf8Unit* aUni
   // compiler does this, and there's a C++ proposal to standardize it.
   // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0907r0.html   So
   // *technically* this is implementation-defined -- but everyone does it and
   // this behavior is being standardized.
   return reinterpret_cast<const unsigned char*>(aUnits);
 }
 
 /** Returns true iff |aUnit| is an ASCII value. */
+template<>
 inline bool
-IsAscii(Utf8Unit aUnit)
+IsAscii<Utf8Unit>(Utf8Unit aUnit)
 {
   return IsAscii(aUnit.toUint8());
 }
 
 /**
  * Returns true if the given length-delimited memory consists of a valid UTF-8
  * string, false otherwise.
  *
--- a/mobile/android/installer/allowed-dupes.mn
+++ b/mobile/android/installer/allowed-dupes.mn
@@ -12,17 +12,16 @@ chrome/toolkit/skin/classic/global/dialo
 chrome/toolkit/skin/classic/global/dropmarker.css
 chrome/toolkit/skin/classic/global/global.css
 chrome/toolkit/skin/classic/global/listbox.css
 chrome/toolkit/skin/classic/global/menu.css
 chrome/toolkit/skin/classic/global/menulist.css
 chrome/toolkit/skin/classic/global/numberbox.css
 chrome/toolkit/skin/classic/global/popup.css
 chrome/toolkit/skin/classic/global/preferences.css
-chrome/toolkit/skin/classic/global/progressmeter.css
 chrome/toolkit/skin/classic/global/radio.css
 chrome/toolkit/skin/classic/global/richlistbox.css
 chrome/toolkit/skin/classic/global/scrollbars.css
 chrome/toolkit/skin/classic/global/scrollbox.css
 chrome/toolkit/skin/classic/global/splitter.css
 chrome/toolkit/skin/classic/global/tabbox.css
 chrome/toolkit/skin/classic/global/textbox.css
 chrome/toolkit/skin/classic/global/toolbar.css
--- a/taskcluster/ci/build/windows.yml
+++ b/taskcluster/ci/build/windows.yml
@@ -992,16 +992,86 @@ win64-msvc/opt:
         mozconfig-variant: opt-msvc
     toolchains:
         - win64-clang-cl
         - win64-rust
         - win64-cbindgen
         - win64-sccache
         - win64-node
 
+win64-aarch64-msvc/debug:
+    description: "AArch64 Win64 MSVC Debug"
+    index:
+        product: firefox
+        job-name: win64-aarch64-msvc-debug
+    treeherder:
+        platform: windows2012-aarch64/debug
+        symbol: Bmsvc
+        tier: 1
+    worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
+    worker:
+        max-run-time: 7200
+        env:
+            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/aarch64.manifest"
+            PERFHERDER_EXTRA_OPTIONS: msvc-aarch64
+    run:
+        using: mozharness
+        actions: [get-secrets, build]
+        options: [append-env-variables-from-configs]
+        script: mozharness/scripts/fx_desktop_build.py
+        config:
+            - builds/releng_base_firefox.py
+            - builds/taskcluster_base_windows.py
+            - builds/taskcluster_sub_win64/debug.py
+        extra-config:
+            mozconfig_platform: win64-aarch64
+        mozconfig-variant: debug-msvc
+    run-on-projects: ['mozilla-central', 'trunk', 'try']
+    toolchains:
+        - win64-clang-cl
+        - win64-aarch64-rust-nightly
+        - win64-cbindgen
+        - win64-sccache
+        - win64-node
+
+win64-aarch64-msvc/opt:
+    description: "AArch64 Win64 MSVC Opt"
+    index:
+        product: firefox
+        job-name: win64-aarch64-msvc-opt
+    treeherder:
+        platform: windows2012-aarch64/opt
+        symbol: Bmsvc
+        tier: 1
+    worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
+    worker:
+        max-run-time: 7200
+        env:
+            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/aarch64.manifest"
+            PERFHERDER_EXTRA_OPTIONS: msvc-aarch64
+    run:
+        using: mozharness
+        actions: [get-secrets, build]
+        options: [append-env-variables-from-configs]
+        script: mozharness/scripts/fx_desktop_build.py
+        config:
+            - builds/releng_base_firefox.py
+            - builds/taskcluster_base_windows.py
+        extra-config:
+            stage_platform: win64
+            mozconfig_platform: win64-aarch64
+        mozconfig-variant: opt-msvc
+    run-on-projects: ['mozilla-central', 'trunk', 'try']
+    toolchains:
+        - win64-clang-cl
+        - win64-aarch64-rust-nightly
+        - win64-cbindgen
+        - win64-sccache
+        - win64-node
+
 win32-mingwclang/opt:
     description: "Win32 MinGW-Clang Opt"
     index:
         product: firefox
         job-name: win32-mingwclang-opt
     treeherder:
         platform: windows-mingw32/all
         symbol: WMC32(Bo)
--- a/taskcluster/ci/test/misc.yml
+++ b/taskcluster/ci/test/misc.yml
@@ -16,19 +16,16 @@ geckoview-junit:
             android-em-4.3-arm7-api-16-ccov/debug: 6
             android-em-4.3-arm7-api-16/debug: 6
             android-em-4.3-arm7-api-16/opt: 2
             default: 1
     mozharness:
         script: android_emulator_unittest.py
         config:
             by-test-platform:
-                android-em-4.2-x86/opt:
-                    - android/android_common.py
-                    - android/androidx86.py
                 android-em-7.0-x86/opt:
                     - android/android_common.py
                     - android/androidx86_7_0.py
                 android-em.*:
                     - android/android_common.py
                     - android/androidarm_4_3_junit.py
         extra-options:
             - --test-suite=geckoview-junit
--- a/taskcluster/ci/test/mochitest.yml
+++ b/taskcluster/ci/test/mochitest.yml
@@ -10,19 +10,16 @@ job-defaults:
     mozharness:
         script:
             by-test-platform:
                 android-em.*: android_emulator_unittest.py
                 android-hw.*: android_hardware_unittest.py
                 default: desktop_unittest.py
         config:
             by-test-platform:
-                android-em-4.2-x86/opt:
-                    - android/android_common.py
-                    - android/androidx86.py
                 android-em-7.0-x86/opt:
                     - android/android_common.py
                     - android/androidx86_7_0.py
                 android-em.*:
                     - android/android_common.py
                     - android/androidarm_4_3.py
                 android-hw.*:
                     - android/android_common.py
--- a/taskcluster/ci/test/test-platforms.yml
+++ b/taskcluster/ci/test/test-platforms.yml
@@ -299,21 +299,16 @@ android-em-4.3-arm7-api-16-ccov/debug:
         - android-ccov-tests
 
 android-em-4.3-arm7-api-16/opt:
     build-platform: android-api-16/opt
     test-sets:
         - android-common-tests
         - android-opt-tests
 
-android-em-4.2-x86/opt:
-    build-platform: android-x86/opt
-    test-sets:
-        - android-x86-tests
-
 android-em-7.0-x86/opt:
     build-platform: android-x86/opt
     test-sets:
         - android-x86-kvm-tests
 
 # android-hw test platforms execute on real devices attached to Autophone hosts.
 
 # android-hw-g5-7-0 Motorola Moto G5 Android 7.0
--- a/taskcluster/ci/test/test-sets.yml
+++ b/taskcluster/ci/test/test-sets.yml
@@ -329,20 +329,16 @@ android-common-tests:
     - reftest
     - test-verify
     - xpcshell
 
 android-opt-tests:
     # Robocop tests often fail on Debug builds
     - robocop
 
-android-x86-tests:
-    - mochitest-chrome
-    - xpcshell
-
 android-x86-kvm-tests:
     - crashtest
     - geckoview-junit
     - jsreftest
     # - mochitest
     # - mochitest-chrome
     - mochitest-clipboard
     - mochitest-gpu
--- a/taskcluster/ci/test/xpcshell.yml
+++ b/taskcluster/ci/test/xpcshell.yml
@@ -5,19 +5,16 @@ job-defaults:
             default: false
     mozharness:
         script:
             by-test-platform:
                 android-em.*: android_emulator_unittest.py
                 default: desktop_unittest.py
         config:
             by-test-platform:
-                android-em-4.2-x86/opt:
-                    - android/android_common.py
-                    - android/androidx86.py
                 android-em.*:
                     - android/android_common.py
                     - android/androidarm_4_3.py
                 linux.*:
                     - unittests/linux_unittest.py
                     - remove_executables.py
                 macosx.*:
                     - unittests/mac_unittest.py
@@ -36,17 +33,16 @@ xpcshell:
     run-on-projects:
         by-test-platform:
             windows10-64-asan/opt: []  # No XPCShell on ASAN yet
             default: built-projects
     chunks:
         by-test-platform:
             linux32/debug: 12
             linux64/debug: 10
-            android-em-4.2-x86/opt: 6
             android-em-4.3-arm7-api-16/debug: 12
             macosx.*: 1
             windows.*: 1
             windows10-64-ccov/debug: 8
             macosx64-ccov/debug: 8
             default: 8
     instance-size:
         by-test-platform:
--- a/taskcluster/ci/toolchain/windows.yml
+++ b/taskcluster/ci/toolchain/windows.yml
@@ -144,16 +144,41 @@ win64-rust-nightly:
         arguments: [
             '--channel', 'nightly-2018-10-05',
             '--host', 'x86_64-pc-windows-msvc',
             '--target', 'x86_64-pc-windows-msvc',
             '--target', 'i686-pc-windows-msvc',
         ]
         toolchain-artifact: public/build/rustc.tar.bz2
 
+win64-aarch64-rust-nightly:
+    description: "rust nightly repack with aarch64 support"
+    treeherder:
+        kind: build
+        platform: toolchains/opt
+        symbol: TW64(rust-aarch64-nightly)
+        tier: 1
+    worker-type: aws-provisioner-v1/gecko-{level}-b-linux
+    worker:
+        docker-image: {in-tree: toolchain-build}
+        max-run-time: 7200
+        env:
+            UPLOAD_DIR: artifacts
+    run:
+        using: toolchain-script
+        script: repack_rust.py
+        arguments: [
+            '--channel', 'nightly-2018-11-08',
+            '--host', 'x86_64-pc-windows-msvc',
+            '--target', 'x86_64-pc-windows-msvc',
+            '--target', 'aarch64-pc-windows-msvc',
+            '--target', 'i686-pc-windows-msvc',
+        ]
+        toolchain-artifact: public/build/rustc.tar.bz2
+
 win64-node:
     description: "Node repack toolchain build"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TW64(node)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
deleted file mode 100644
--- a/testing/mozharness/configs/android/androidx86.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# mozharness configuration for Android x86 unit tests
-#
-# This configuration should be combined with suite definitions and other
-# mozharness configuration from android_common.py, or similar.
-
-config = {
-    "deprecated_sdk_path": True,
-    "tooltool_manifest_path": "testing/config/tooltool-manifests/androidx86/releng.manifest",
-    "emulator_manifest": """
-        [
-        {
-        "size": 193383673,
-        "digest": "6609e8b95db59c6a3ad60fc3dcfc358b2c8ec8b4dda4c2780eb439e1c5dcc5d550f2e47ce56ba14309363070078d09b5287e372f6e95686110ff8a2ef1838221",
-        "algorithm": "sha512",
-        "filename": "android-sdk18_0.r18moz1.orig.tar.gz",
-        "unpack": "True"
-        }
-        ] """,
-    "emulator_avd_name": "test-1",
-    "emulator_process_name": "emulator64-x86",
-    "emulator_extra_args": "-show-kernel -debug init,console,gles,memcheck,adbserver,adbclient,adb,avd_config,socket -qemu -m 1024",
-    "exes": {
-        'adb': '%(abs_work_dir)s/android-sdk18/platform-tools/adb',
-    },
-    "env": {
-        "DISPLAY": ":0.0",
-        "PATH": "%(PATH)s:%(abs_work_dir)s/android-sdk18/tools:%(abs_work_dir)s/android-sdk18/platform-tools",
-        "MINIDUMP_SAVEPATH": "%(abs_work_dir)s/../minidumps"
-    },
-}
--- a/toolkit/content/customElements.js
+++ b/toolkit/content/customElements.js
@@ -291,17 +291,16 @@ window.MozElements = MozElements;
 
 // For now, don't load any elements in the extension dummy document.
 // We will want to load <browser> when that's migrated (bug 1441935).
 const isDummyDocument = document.documentURI == "chrome://extensions/content/dummy.xul";
 if (!isDummyDocument) {
   for (let script of [
     "chrome://global/content/elements/general.js",
     "chrome://global/content/elements/notificationbox.js",
-    "chrome://global/content/elements/progressmeter.js",
     "chrome://global/content/elements/radio.js",
     "chrome://global/content/elements/textbox.js",
     "chrome://global/content/elements/tabbox.js",
     "chrome://global/content/elements/tree.js",
   ]) {
     Services.scriptloader.loadSubScript(script, window);
   }
 
--- a/toolkit/content/jar.mn
+++ b/toolkit/content/jar.mn
@@ -92,17 +92,16 @@ toolkit.jar:
    content/global/bindings/tree.xml            (widgets/tree.xml)
    content/global/bindings/videocontrols.xml   (widgets/videocontrols.xml)
 *  content/global/bindings/wizard.xml          (widgets/wizard.xml)
    content/global/elements/datetimebox.js      (widgets/datetimebox.js)
    content/global/elements/findbar.js          (widgets/findbar.js)
    content/global/elements/editor.js          (widgets/editor.js)
    content/global/elements/general.js          (widgets/general.js)
    content/global/elements/notificationbox.js  (widgets/notificationbox.js)
-   content/global/elements/progressmeter.js    (widgets/progressmeter.js)
    content/global/elements/radio.js            (widgets/radio.js)
    content/global/elements/marquee.css         (widgets/marquee.css)
    content/global/elements/marquee.js          (widgets/marquee.js)
    content/global/elements/stringbundle.js     (widgets/stringbundle.js)
    content/global/elements/tabbox.js           (widgets/tabbox.js)
    content/global/elements/textbox.js          (widgets/textbox.js)
    content/global/elements/videocontrols.js    (widgets/videocontrols.js)
    content/global/elements/tree.js             (widgets/tree.js)
--- a/toolkit/content/moz.build
+++ b/toolkit/content/moz.build
@@ -164,19 +164,16 @@ with Files('tests/chrome/test_preference
     BUG_COMPONENT = ('Toolkit', 'Preferences')
 
 with Files('tests/mochitest/*autocomplete*'):
     BUG_COMPONENT = ('Toolkit', 'Autocomplete')
 
 with Files('tests/mochitest/*mousecapture*'):
     BUG_COMPONENT = ('Core', 'Event Handling')
 
-with Files('tests/reftests/*progress*'):
-    BUG_COMPONENT = ('Toolkit', 'XUL Widgets')
-
 with Files('tests/reftests/*multiline*'):
     BUG_COMPONENT = ('Core', 'XBL')
 
 with Files('tests/reftests/*videocontrols*'):
     BUG_COMPONENT = ('Toolkit', 'Video/Audio Controls')
 
 with Files('tests/unit/**'):
     BUG_COMPONENT = ('Toolkit', 'General')
--- a/toolkit/content/tests/chrome/chrome.ini
+++ b/toolkit/content/tests/chrome/chrome.ini
@@ -165,17 +165,16 @@ skip-if = (verify && (os == 'win'))
 [test_popupremoving.xul]
 [test_popupremoving_frame.xul]
 [test_position.xul]
 [test_preferences.xul]
 [test_preferences_beforeaccept.xul]
 support-files = window_preferences_beforeaccept.xul
 [test_preferences_onsyncfrompreference.xul]
 support-files = window_preferences_onsyncfrompreference.xul
-[test_progressmeter.xul]
 [test_props.xul]
 [test_radio.xul]
 [test_richlist_direction.xul]
 [test_righttoleft.xul]
 [test_screenPersistence.xul]
 [test_scrollbar.xul]
 [test_showcaret.xul]
 [test_subframe_origin.xul]
deleted file mode 100644
--- a/toolkit/content/tests/chrome/test_progressmeter.xul
+++ /dev/null
@@ -1,74 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<!--
-  XUL Widget Test for progressmeter
-  -->
-<window title="Progressmeter" width="500" height="600"
-        onload="doTests()"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>  
-
-  <progressmeter id="n1"/>
-  <progressmeter id="n2" mode="undetermined"/>
-
-  <!-- test results are displayed in the html:body -->
-  <body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
-
-  <!-- test code goes here -->
-  <script type="application/javascript"><![CDATA[
-SimpleTest.waitForExplicitFinish();
-
-function doTests() {
-  var n1 = document.getElementById("n1");
-  var n2 = document.getElementById("n2");
-
-  SimpleTest.is(n1.mode, "", "mode determined");
-  SimpleTest.is(n2.mode, "undetermined", "mode undetermined");
-
-  SimpleTest.is(n1.value, "0", "determined value");
-  SimpleTest.is(n2.value, "0", "undetermined value");
-
-  // values can only be incremented in multiples of 4
-  n1.value = 2;
-  SimpleTest.is(n1.value, "0", "determined value set 2");
-  n1.value = -1;
-  SimpleTest.is(n1.value, "0", "determined value set -1");
-  n1.value = 125;
-  SimpleTest.is(n1.value, "100", "determined value set 125");
-  n1.value = 7;
-  SimpleTest.is(n1.value, "7", "determined value set 7");
-  n1.value = "17";
-  SimpleTest.is(n1.value, "17", "determined value set 17 string");
-  n1.value = 18;
-  SimpleTest.is(n1.value, "17", "determined value set 18");
-  n1.value = "Cat";
-  SimpleTest.is(n1.value, "17", "determined value set invalid");
-
-  n1.max = 200;
-  is(n1.max, "200", "max changed");
-  n1.value = 150;
-  n1.max = 120;
-  is(n1.value, "120", "max lowered below value");
-
-  n2.value = 2;
-  SimpleTest.is(n2.value, "0", "undetermined value set 2");
-  n2.value = -1;
-  SimpleTest.is(n2.value, "0", "undetermined value set -1");
-  n2.value = 125;
-  SimpleTest.is(n2.value, "100", "undetermined value set 125");
-  n2.value = 7;
-  SimpleTest.is(n2.value, "7", "undetermined value set 7");
-  n2.value = "17";
-  SimpleTest.is(n2.value, "17", "undetermined value set 17 string");
-  n2.value = 18;
-  SimpleTest.is(n2.value, "17", "undetermined value set 18");
-  n2.value = "Cat";
-  SimpleTest.is(n2.value, "17", "determined value set invalid");
-
-  SimpleTest.finish();
-}
-
-]]></script>
-
-</window>
deleted file mode 100644
--- a/toolkit/content/tests/reftests/bug-442419-progressmeter-max-ref.xul
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-  <progressmeter value="100"/> <!-- default is max = 100 -->
-</window>
-
deleted file mode 100644
--- a/toolkit/content/tests/reftests/bug-442419-progressmeter-max.xul
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-  <progressmeter  max="198" value="198"/> <!-- 100% -->
-</window>
-
--- a/toolkit/content/tests/reftests/reftest.list
+++ b/toolkit/content/tests/reftests/reftest.list
@@ -1,6 +1,5 @@
-== bug-442419-progressmeter-max.xul bug-442419-progressmeter-max-ref.xul
 != textbox-multiline-default-value.xul textbox-multiline-empty.xul
 == videocontrols-dynamically-add-cc.html videocontrols-dynamically-add-cc-ref.html
 == audio-with-bogus-url.html audio-with-bogus-url-ref.html
 == audio-dynamically-change-small-width.html audio-dynamically-change-small-width-ref.html
 == audio-with-padding.html audio-with-padding-ref.html
--- a/toolkit/content/widgets.css
+++ b/toolkit/content/widgets.css
@@ -12,17 +12,16 @@
 @import url("chrome://global/skin/checkbox.css");
 @import url("chrome://global/skin/dialog.css");
 @import url("chrome://global/skin/dropmarker.css");
 @import url("chrome://global/skin/findBar.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/progressmeter.css");
 @import url("chrome://global/skin/radio.css");
 @import url("chrome://global/skin/richlistbox.css");
 @import url("chrome://global/skin/scrollbox.css");
 @import url("chrome://global/skin/splitter.css");
 @import url("chrome://global/skin/tabbox.css");
 
 /* numberbox.css needs to be loaded after textbox.css since it overrides it */
 @import url("chrome://global/skin/textbox.css");
deleted file mode 100644
--- a/toolkit/content/widgets/progressmeter.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// This is loaded into chrome windows with the subscript loader. Wrap in
-// a block to prevent accidentally leaking globals onto `window`.
-{
-
-/**
- * XUL progressmeter element.
- */
-class MozProgressmeter extends MozXULElement {
-  get mode() {
-    return this.getAttribute("mode");
-  }
-
-  set mode(val) {
-    if (this.mode != val) {
-      this.setAttribute("mode", val);
-    }
-    return val;
-  }
-
-  get value() {
-    return this.getAttribute("value") || "0";
-  }
-
-  set value(val) {
-    let p = Math.round(val);
-    let max = Math.round(this.max);
-    if (p < 0) {
-      p = 0;
-    } else if (p > max) {
-      p = max;
-    }
-
-    let c = this.value;
-    if (p != c) {
-      let delta = p - c;
-      if (delta < 0) {
-        delta = -delta;
-      }
-      if (delta > 3 || p == 0 || p == max) {
-        this.setAttribute("value", p);
-        // Fire DOM event so that accessible value change events occur
-        let event = document.createEvent("Events");
-        event.initEvent("ValueChange", true, true);
-        this.dispatchEvent(event);
-      }
-    }
-
-    return val;
-  }
-
-  get max() {
-    return this.getAttribute("max") || "100";
-  }
-
-  set max(val) {
-    this.setAttribute("max", isNaN(val) ? 100 : Math.max(val, 1));
-    this.value = this.value;
-    return val;
-  }
-
-  isUndetermined() {
-    return this.getAttribute("mode") == "undetermined";
-  }
-
-  connectedCallback() {
-    if (this.delayConnectedCallback()) {
-      return;
-    }
-    this._initUI();
-  }
-
-  static get observedAttributes() {
-    return [ "mode" ];
-  }
-
-  attributeChangedCallback(name, oldValue, newValue) {
-    if (!this.isConnectedAndReady) {
-      return;
-    }
-
-    if (name === "mode" && oldValue != newValue) {
-      this._initUI();
-    }
-  }
-
-  _initUI() {
-    let content = `
-      <spacer class="progress-bar"/>
-      <spacer class="progress-remainder"/>
-    `;
-
-    this.textContent = "";
-    this.appendChild(MozXULElement.parseXULToFragment(content));
-  }
-}
-
-customElements.define("progressmeter", MozProgressmeter);
-
-}
--- a/toolkit/locales/en-US/toolkit/preferences/preferences.ftl
+++ b/toolkit/locales/en-US/toolkit/preferences/preferences.ftl
@@ -27,13 +27,13 @@ set-password-reenter-password = Re-enter
 set-password-meter = Password quality meter
 set-password-meter-loading = Loading
 master-password-description = A Master Password is used to protect sensitive information like site passwords. If you create a Master Password you will be asked to enter it once per session when { -brand-short-name } retrieves saved information protected by the password.
 master-password-warning = Please make sure you remember the Master Password you have set. If you forget your Master Password, you will be unable to access any of the information protected by it.
 
 remove-password =
     .title = Remove Master Password
 remove-info =
-    .label = You must enter your current password to proceed:
+    .value = You must enter your current password to proceed:
 remove-warning1 = Your Master Password is used to protect sensitive information like site passwords.
 remove-warning2 = If you remove your Master Password your information will not be protected if your computer is compromised.
 remove-password-old-password =
-    .label = Current password:
+    .value = Current password:
--- a/toolkit/mozapps/extensions/content/extensions.xml
+++ b/toolkit/mozapps/extensions/content/extensions.xml
@@ -9,17 +9,18 @@
 %extensionsDTD;
 ]>
 
 <!-- import-globals-from extensions.js -->
 
 <bindings id="addonBindings"
           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">
+          xmlns:xbl="http://www.mozilla.org/xbl"
+          xmlns:html="http://www.w3.org/1999/xhtml">
 
 
   <!-- Rating - displays current/average rating, allows setting user rating -->
   <binding id="rating">
     <content>
       <xul:image class="star"
                  onmouseover="document.getBindingParent(this)._hover(1);"
                  onclick="document.getBindingParent(this).userRating = 1;"/>
@@ -124,18 +125,17 @@
 
   <!-- Download progress - shows graphical progress of download and any
        related status message. -->
   <binding id="download-progress">
     <content>
       <xul:stack flex="1">
         <xul:hbox flex="1">
           <xul:hbox class="start-cap"/>
-          <xul:progressmeter anonid="progress" class="progress" flex="1"
-                             min="0" max="100"/>
+          <html:progress anonid="progress" class="progress" max="100"/>
           <xul:hbox class="end-cap"/>
         </xul:hbox>
         <xul:hbox class="status-container">
           <xul:spacer flex="1"/>
           <xul:label anonid="status" class="status"/>
           <xul:spacer flex="1"/>
           <xul:button anonid="cancel-btn" class="cancel"
                       tooltiptext="&progress.cancel.tooltip;"
@@ -158,40 +158,37 @@
       <field name="_cancel">
         document.getAnonymousElementByAttribute(this, "anonid", "cancel-btn");
       </field>
       <field name="_status">
         document.getAnonymousElementByAttribute(this, "anonid", "status");
       </field>
 
       <property name="progress">
-        <getter><![CDATA[
-          return this._progress.value;
-        ]]></getter>
         <setter><![CDATA[
-          this._progress.value = val;
+          // This property is always updated after maxProgress.
+          if (this.getAttribute("mode") == "determined") {
+            this._progress.value = val;
+          }
           if (val == this._progress.max)
             this.setAttribute("complete", true);
           else
             this.removeAttribute("complete");
         ]]></setter>
       </property>
 
       <property name="maxProgress">
-        <getter><![CDATA[
-          return this._progress.max;
-        ]]></getter>
         <setter><![CDATA[
           if (val == -1) {
-            this._progress.mode = "undetermined";
+            this.setAttribute("mode", "undetermined");
+            this._progress.removeAttribute("value");
           } else {
-            this._progress.mode = "determined";
-            this._progress.max = val;
+            this.setAttribute("mode", "determined");
+            this._progress.setAttribute("max", val);
           }
-          this.setAttribute("mode", this._progress.mode);
         ]]></setter>
       </property>
 
       <property name="status">
         <getter><![CDATA[
           return this._status.value;
         ]]></getter>
         <setter><![CDATA[
--- a/toolkit/mozapps/preferences/removemp.xul
+++ b/toolkit/mozapps/preferences/removemp.xul
@@ -22,17 +22,17 @@
   <vbox id="warnings">
     <description data-l10n-id="remove-warning1"></description>
     <description class="header" data-l10n-id="remove-warning2"></description>
   </vbox>
 
   <separator class="thin"/>
 
   <groupbox>
-    <caption  data-l10n-id="remove-info"/>
+    <label data-l10n-id="remove-info"/>
 
     <hbox align="center">
       <label control="password" data-l10n-id="remove-password-old-password"/> 
       <textbox id="password" type="password"
                oninput="gRemovePasswordDialog.validateInput();"
                aria-describedby="warnings"/>
     </hbox>
   </groupbox>
--- a/toolkit/themes/mobile/jar.mn
+++ b/toolkit/themes/mobile/jar.mn
@@ -10,17 +10,16 @@ toolkit.jar:
    skin/classic/global/checkbox.css                        (global/empty.css)
    skin/classic/global/dialog.css                          (global/empty.css)
    skin/classic/global/dropmarker.css                      (global/empty.css)
    skin/classic/global/global.css                          (global/empty.css)
    skin/classic/global/menu.css                            (global/empty.css)
    skin/classic/global/menulist.css                        (global/empty.css)
    skin/classic/global/numberbox.css                       (global/empty.css)
    skin/classic/global/popup.css                           (global/empty.css)
-   skin/classic/global/progressmeter.css                   (global/empty.css)
    skin/classic/global/radio.css                           (global/empty.css)
    skin/classic/global/richlistbox.css                     (global/empty.css)
    skin/classic/global/scrollbox.css                       (global/empty.css)
    skin/classic/global/splitter.css                        (global/empty.css)
    skin/classic/global/tabbox.css                          (global/empty.css)
    skin/classic/global/textbox.css                         (global/empty.css)
    skin/classic/global/toolbar.css                         (global/empty.css)
    skin/classic/global/toolbarbutton.css                   (global/empty.css)
--- a/toolkit/themes/osx/global/jar.mn
+++ b/toolkit/themes/osx/global/jar.mn
@@ -13,17 +13,16 @@ toolkit.jar:
   skin/classic/global/dropmarker.css
 * skin/classic/global/findBar.css
 * skin/classic/global/global.css
   skin/classic/global/menu.css
   skin/classic/global/menulist.css
 * skin/classic/global/notification.css
   skin/classic/global/netError.css
   skin/classic/global/popup.css
-  skin/classic/global/progressmeter.css
   skin/classic/global/radio.css
   skin/classic/global/richlistbox.css
   skin/classic/global/scrollbars.css                                 (nativescrollbars.css)
   skin/classic/global/scrollbox.css
   skin/classic/global/splitter.css
   skin/classic/global/tabprompts.css
   skin/classic/global/tabbox.css
   skin/classic/global/textbox.css
deleted file mode 100644
--- a/toolkit/themes/osx/global/progressmeter.css
+++ /dev/null
@@ -1,18 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
-
-progressmeter {
-  -moz-appearance: progressbar;
-  margin: 2px 4px;
-  min-width: 128px;
-  height: 12px;
-}
-
-.progress-remainder[flex="100"],
-.progress-remainder[flex="0"] {
-  background-image: none !important;
-  -moz-appearance: none;
-}
--- a/toolkit/themes/shared/extensions/extensions.inc.css
+++ b/toolkit/themes/shared/extensions/extensions.inc.css
@@ -829,16 +829,17 @@ button.warning {
   background-color: var(--in-content-border-highlight);
 }
 
 .download-progress .progress .progress-bar  {
   min-height: 28px;
 }
 
 .download-progress .progress {
+  -moz-box-flex: 1;
   -moz-appearance: none;
   background-color: transparent;
   padding: 0;
   margin: 0;
   border: none;
 }
 
 .download-progress .start-cap,
--- a/toolkit/themes/shared/non-mac.jar.inc.mn
+++ b/toolkit/themes/shared/non-mac.jar.inc.mn
@@ -6,17 +6,16 @@
 # by the shared jar manifest, which in turn is included by the os-specific
 # manifests.
 # As a result, the source file paths are relative to the location of the
 # actual manifests.
 
 #include jar.inc.mn
 
   skin/classic/global/dialog.css                           (../../windows/global/dialog.css)
-  skin/classic/global/progressmeter.css                    (../../windows/global/progressmeter.css)
   skin/classic/global/scrollbars.css                       (../../windows/global/xulscrollbars.css)
   skin/classic/global/tabprompts.css                       (../../windows/global/tabprompts.css)
   skin/classic/global/wizard.css                           (../../windows/global/wizard.css)
 
   skin/classic/global/arrow/arrow-dn.gif                   (../../windows/global/arrow/arrow-dn.gif)
   skin/classic/global/arrow/arrow-up.gif                   (../../windows/global/arrow/arrow-up.gif)
   skin/classic/global/arrow/panelarrow-horizontal.svg      (../../windows/global/arrow/panelarrow-horizontal.svg)
   skin/classic/global/arrow/panelarrow-vertical.svg        (../../windows/global/arrow/panelarrow-vertical.svg)
deleted file mode 100644
--- a/toolkit/themes/windows/global/progressmeter.css
+++ /dev/null
@@ -1,26 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* ===== progressmeter.css ==============================================
-  == Styles used by the XUL progressmeter element.
-  ======================================================================= */
-
-@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
-
-/* ::::: progressmeter ::::: */
-
-progressmeter {
-  -moz-appearance: progressbar;
-  margin: 2px 4px;
-  border: 1px solid ThreeDShadow;
-  background-color: -moz-Dialog;
-  min-width: 128px;
-  min-height: 15px;
-}
-
-.progress-bar {
-  -moz-appearance: progresschunk;
-  min-width: 0;
-  background-color: ThreeDShadow;
-}
--- a/widget/nsNativeTheme.cpp
+++ b/widget/nsNativeTheme.cpp
@@ -171,36 +171,32 @@ nsNativeTheme::CheckIntAttr(nsIFrame* aF
 
   return value;
 }
 
 /* static */
 double
 nsNativeTheme::GetProgressValue(nsIFrame* aFrame)
 {
-  // When we are using the HTML progress element,
-  // we can get the value from the IDL property.
-  if (aFrame && aFrame->GetContent()->IsHTMLElement(nsGkAtoms::progress)) {
-    return static_cast<HTMLProgressElement*>(aFrame->GetContent())->Value();
+  if (!aFrame || !aFrame->GetContent()->IsHTMLElement(nsGkAtoms::progress)) {
+    return 0;
   }
 
-  return (double)nsNativeTheme::CheckIntAttr(aFrame, nsGkAtoms::value, 0);
+  return static_cast<HTMLProgressElement*>(aFrame->GetContent())->Value();
 }
 
 /* static */
 double
 nsNativeTheme::GetProgressMaxValue(nsIFrame* aFrame)
 {
-  // When we are using the HTML progress element,
-  // we can get the max from the IDL property.
-  if (aFrame && aFrame->GetContent()->IsHTMLElement(nsGkAtoms::progress)) {
-    return static_cast<HTMLProgressElement*>(aFrame->GetContent())->Max();
+  if (!aFrame || !aFrame->GetContent()->IsHTMLElement(nsGkAtoms::progress)) {
+    return 100;
   }
 
-  return (double)std::max(nsNativeTheme::CheckIntAttr(aFrame, nsGkAtoms::max, 100), 1);
+  return static_cast<HTMLProgressElement*>(aFrame->GetContent())->Max();
 }
 
 bool
 nsNativeTheme::GetCheckedOrSelected(nsIFrame* aFrame, bool aCheckSelected)
 {
   if (!aFrame)
     return false;
 
@@ -560,32 +556,26 @@ nsNativeTheme::IsNextToSelectedTab(nsIFr
   }
 
   if (thisTabIndex == -1 || selectedTabIndex == -1)
     return false;
 
   return (thisTabIndex - selectedTabIndex == aOffset);
 }
 
-// progressbar:
 bool
 nsNativeTheme::IsIndeterminateProgress(nsIFrame* aFrame,
                                        EventStates aEventStates)
 {
-  if (!aFrame || !aFrame->GetContent()|| !aFrame->GetContent()->IsElement())
+  if (!aFrame || !aFrame->GetContent() ||
+      !aFrame->GetContent()->IsHTMLElement(nsGkAtoms::progress)) {
     return false;
-
-  if (aFrame->GetContent()->IsHTMLElement(nsGkAtoms::progress)) {
-    return aEventStates.HasState(NS_EVENT_STATE_INDETERMINATE);
   }
 
-  return aFrame->GetContent()->AsElement()->AttrValueIs(kNameSpaceID_None,
-                                                        nsGkAtoms::mode,
-                                                        NS_LITERAL_STRING("undetermined"),
-                                                        eCaseMatters);
+  return aEventStates.HasState(NS_EVENT_STATE_INDETERMINATE);
 }
 
 bool
 nsNativeTheme::IsVerticalProgress(nsIFrame* aFrame)
 {
   if (!aFrame) {
     return false;
   }
--- a/xpcom/ds/StaticAtoms.py
+++ b/xpcom/ds/StaticAtoms.py
@@ -977,17 +977,16 @@ STATIC_ATOMS = [
     Atom("preventdefault", "preventdefault"),
     Atom("previewDiv", "preview-div"),
     Atom("primary", "primary"),
     Atom("print", "print"),
     Atom("priority", "priority"),
     Atom("processingInstruction", "processing-instruction"),
     Atom("profile", "profile"),
     Atom("progress", "progress"),
-    Atom("progressmeter", "progressmeter"),
     Atom("prompt", "prompt"),
     Atom("properties", "properties"),
     Atom("property", "property"),
     Atom("pubdate", "pubdate"),
     Atom("q", "q"),
     Atom("radio", "radio"),
     Atom("radioLabel", "radio-label"),
     Atom("radiogroup", "radiogroup"),
@@ -1212,17 +1211,16 @@ STATIC_ATOMS = [
     Atom("treeseparator", "treeseparator"),
     Atom("_true", "true"),
     Atom("truespeed", "truespeed"),
     Atom("tt", "tt"),
     Atom("type", "type"),
     Atom("typemustmatch", "typemustmatch"),
     Atom("u", "u"),
     Atom("ul", "ul"),
-    Atom("undetermined", "undetermined"),
     Atom("unparsedEntityUri", "unparsed-entity-uri"),
     Atom("up", "up"),
     Atom("upperAlpha", "upper-alpha"),
     Atom("upperFirst", "upper-first"),
     Atom("upperRoman", "upper-roman"),
     Atom("use", "use"),
     Atom("useAttributeSets", "use-attribute-sets"),
     Atom("usemap", "usemap"),