merge mozilla-inbound to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 03 Feb 2016 11:59:20 +0100
changeset 321060 f2f8fc172f4c62334e9a92bcf10e00fe877387d5
parent 320941 ce6b2fdabc3ecd709abf5de6dbe963edd44d18fb (current diff)
parent 321059 94c27b21c934f0cc178e896587532d7cc0b4c60c (diff)
child 321065 e47aaf341c14d2de51bd2ddfb48f76f05ebea298
child 321106 75773f2f6eae1ae3c45f1d4114981e34061cefbe
push id1128
push userjlund@mozilla.com
push dateWed, 01 Jun 2016 01:31:59 +0000
treeherdermozilla-release@fe0d30de989d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone47.0a1
first release with
nightly linux32
f2f8fc172f4c / 47.0a1 / 20160203030249 / files
nightly linux64
f2f8fc172f4c / 47.0a1 / 20160203030249 / files
nightly mac
f2f8fc172f4c / 47.0a1 / 20160203030249 / files
nightly win32
f2f8fc172f4c / 47.0a1 / 20160203030249 / files
nightly win64
f2f8fc172f4c / 47.0a1 / 20160203030249 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge mozilla-inbound to mozilla-central a=merge
build/macosx/mozconfig.rust
build/stlport/Makefile.in
dom/workers/test/serviceworkers/download_window.html
dom/workers/test/serviceworkers/download_worker.js
gfx/skia/Makefile.in
media/omx-plugin/lib/ics/libvideoeditorplayer/Makefile.in
mobile/android/app/mobile.js
testing/marionette/transport/marionette_transport/__init__.py
testing/marionette/transport/marionette_transport/transport.py
testing/marionette/transport/setup.py
toolkit/crashreporter/google-breakpad/src/client/linux/handler/Makefile.in
--- a/accessible/atk/AccessibleWrap.cpp
+++ b/accessible/atk/AccessibleWrap.cpp
@@ -754,17 +754,17 @@ getAttributesCB(AtkObject *aAtkObj)
   AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
   if (accWrap)
     return GetAttributeSet(accWrap);
 
   ProxyAccessible* proxy = GetProxy(aAtkObj);
   if (!proxy)
     return nullptr;
 
-  nsAutoTArray<Attribute, 10> attrs;
+  AutoTArray<Attribute, 10> attrs;
   proxy->Attributes(&attrs);
   if (attrs.IsEmpty())
     return nullptr;
 
   AtkAttributeSet* objAttributeSet = nullptr;
   for (uint32_t i = 0; i < attrs.Length(); i++) {
     AtkAttribute *objAttr = (AtkAttribute *)g_malloc(sizeof(AtkAttribute));
     objAttr->name = g_strdup(attrs[i].Name().get());
@@ -1014,17 +1014,17 @@ refRelationSetCB(AtkObject *aAtkObj)
     proxy->Relations(&types, &targetSets);
 
     size_t relationCount = types.Length();
     for (size_t i = 0; i < relationCount; i++) {
       if (typeMap[static_cast<uint32_t>(types[i])] == ATK_RELATION_NULL)
         continue;
 
       size_t targetCount = targetSets[i].Length();
-      nsAutoTArray<AtkObject*, 5> wrappers;
+      AutoTArray<AtkObject*, 5> wrappers;
       for (size_t j = 0; j < targetCount; j++)
         wrappers.AppendElement(GetWrapperFor(targetSets[i][j]));
 
       AtkRelationType atkType = typeMap[static_cast<uint32_t>(types[i])];
       AtkRelation* atkRelation =
         atk_relation_set_get_relation_by_type(relation_set, atkType);
       if (atkRelation)
         atk_relation_set_remove(relation_set, atkRelation);
@@ -1659,17 +1659,17 @@ AccessibleWrap::GetColumnHeader(TableAcc
   }
 
   // otherwise get column header for the data cell at the first row.
   TableCellAccessible* tableCell = cell->AsTableCell();
   if (!tableCell) {
     return nullptr;
   }
 
-  nsAutoTArray<Accessible*, 10> headerCells;
+  AutoTArray<Accessible*, 10> headerCells;
   tableCell->ColHeaderCells(&headerCells);
   if (headerCells.IsEmpty()) {
     return nullptr;
   }
 
   return headerCells[0];
 }
 
@@ -1693,16 +1693,16 @@ AccessibleWrap::GetRowHeader(TableAccess
   }
 
   // otherwise get row header for the data cell at the first column.
   TableCellAccessible* tableCell = cell->AsTableCell();
   if (!tableCell) {
     return nullptr;
   }
 
-  nsAutoTArray<Accessible*, 10> headerCells;
+  AutoTArray<Accessible*, 10> headerCells;
   tableCell->RowHeaderCells(&headerCells);
   if (headerCells.IsEmpty()) {
     return nullptr;
   }
 
   return headerCells[0];
 }
--- a/accessible/atk/nsMaiInterfaceTable.cpp
+++ b/accessible/atk/nsMaiInterfaceTable.cpp
@@ -268,17 +268,17 @@ getSummaryCB(AtkTable *aTable)
   return nullptr;
 }
 
 static gint
 getSelectedColumnsCB(AtkTable *aTable, gint** aSelected)
 {
   *aSelected = nullptr;
 
-  nsAutoTArray<uint32_t, 10> cols;
+  AutoTArray<uint32_t, 10> cols;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
   if (accWrap) {
     accWrap->AsTable()->SelectedColIndices(&cols);
    } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
     proxy->TableSelectedColumnIndices(&cols);
   } else {
     return 0;
   }
@@ -295,17 +295,17 @@ getSelectedColumnsCB(AtkTable *aTable, g
   memcpy(atkColumns, cols.Elements(), cols.Length() * sizeof(uint32_t));
   *aSelected = atkColumns;
   return cols.Length();
 }
 
 static gint
 getSelectedRowsCB(AtkTable *aTable, gint **aSelected)
 {
-  nsAutoTArray<uint32_t, 10> rows;
+  AutoTArray<uint32_t, 10> rows;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
   if (accWrap) {
     accWrap->AsTable()->SelectedRowIndices(&rows);
   } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
     proxy->TableSelectedRowIndices(&rows);
   } else {
     return 0;
   }
--- a/accessible/atk/nsMaiInterfaceText.cpp
+++ b/accessible/atk/nsMaiInterfaceText.cpp
@@ -306,17 +306,17 @@ getRunAttributesCB(AtkText *aText, gint 
     return ConvertToAtkTextAttributeSet(attributes);
   }
 
   ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText));
   if (!proxy) {
     return nullptr;
   }
 
-  nsAutoTArray<Attribute, 10> attrs;
+  AutoTArray<Attribute, 10> attrs;
   proxy->TextAttributes(false, aOffset, &attrs, &startOffset, &endOffset);
   *aStartOffset = startOffset;
   *aEndOffset = endOffset;
   return ConvertToAtkTextAttributeSet(attrs);
 }
 
 static AtkAttributeSet*
 getDefaultAttributesCB(AtkText *aText)
@@ -332,17 +332,17 @@ getDefaultAttributesCB(AtkText *aText)
     return ConvertToAtkTextAttributeSet(attributes);
   }
 
   ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText));
   if (!proxy) {
     return nullptr;
   }
 
-  nsAutoTArray<Attribute, 10> attrs;
+  AutoTArray<Attribute, 10> attrs;
   proxy->DefaultTextAttributes(&attrs);
   return ConvertToAtkTextAttributeSet(attrs);
 }
 
 static void
 getCharacterExtentsCB(AtkText *aText, gint aOffset,
                       gint *aX, gint *aY,
                       gint *aWidth, gint *aHeight,
--- a/accessible/base/EventQueue.h
+++ b/accessible/base/EventQueue.h
@@ -71,17 +71,17 @@ private:
 protected:
 
   /**
    * The document accessible reference owning this queue.
    */
   DocAccessible* mDocument;
 
   /**
-   * Pending events array. Don't make this an nsAutoTArray; we use
+   * Pending events array. Don't make this an AutoTArray; we use
    * SwapElements() on it.
    */
   nsTArray<RefPtr<AccEvent> > mEvents;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
--- a/accessible/base/NotificationController.h
+++ b/accessible/base/NotificationController.h
@@ -277,17 +277,17 @@ private:
     RefPtr<Accessible> mContainer;
 
     // Array of inserted contents.
     nsTArray<nsCOMPtr<nsIContent> > mInsertedContent;
   };
 
   /**
    * A pending accessible tree update notifications for content insertions.
-   * Don't make this an nsAutoTArray; we use SwapElements() on it.
+   * Don't make this an AutoTArray; we use SwapElements() on it.
    */
   nsTArray<RefPtr<ContentInsertion> > mContentInsertions;
 
   template<class T>
   class nsCOMPtrHashKey : public PLDHashEntryHdr
   {
   public:
     typedef T* KeyType;
@@ -311,17 +311,17 @@ private:
   };
 
   /**
    * A pending accessible tree update notifications for rendered text changes.
    */
   nsTHashtable<nsCOMPtrHashKey<nsIContent> > mTextHash;
 
   /**
-   * Other notifications like DOM events. Don't make this an nsAutoTArray; we
+   * Other notifications like DOM events. Don't make this an AutoTArray; we
    * use SwapElements() on it.
    */
   nsTArray<RefPtr<Notification> > mNotifications;
 
   /**
    * Holds all scheduled relocations.
    */
   nsTArray<RefPtr<Accessible> > mRelocations;
--- a/accessible/base/TextRange-inl.h
+++ b/accessible/base/TextRange-inl.h
@@ -12,17 +12,17 @@
 
 namespace mozilla {
 namespace a11y {
 
 inline Accessible*
 TextRange::Container() const
 {
   uint32_t pos1 = 0, pos2 = 0;
-  nsAutoTArray<Accessible*, 30> parents1, parents2;
+  AutoTArray<Accessible*, 30> parents1, parents2;
   return CommonParent(mStartContainer, mEndContainer,
                       &parents1, &pos1, &parents2, &pos2);
 }
 
 
 } // namespace a11y
 } // namespace mozilla
 
--- a/accessible/base/TextRange.cpp
+++ b/accessible/base/TextRange.cpp
@@ -19,17 +19,17 @@ bool
 TextPoint::operator <(const TextPoint& aPoint) const
 {
   if (mContainer == aPoint.mContainer)
     return mOffset < aPoint.mOffset;
 
   // Build the chain of parents
   Accessible* p1 = mContainer;
   Accessible* p2 = aPoint.mContainer;
-  nsAutoTArray<Accessible*, 30> parents1, parents2;
+  AutoTArray<Accessible*, 30> parents1, parents2;
   do {
     parents1.AppendElement(p1);
     p1 = p1->Parent();
   } while (p1);
   do {
     parents2.AppendElement(p2);
     p2 = p2->Parent();
   } while (p2);
@@ -71,17 +71,17 @@ TextRange::EmbeddedChildren(nsTArray<Acc
     }
     return;
   }
 
   Accessible* p1 = mStartContainer->GetChildAtOffset(mStartOffset);
   Accessible* p2 = mEndContainer->GetChildAtOffset(mEndOffset);
 
   uint32_t pos1 = 0, pos2 = 0;
-  nsAutoTArray<Accessible*, 30> parents1, parents2;
+  AutoTArray<Accessible*, 30> parents1, parents2;
   Accessible* container =
     CommonParent(p1, p2, &parents1, &pos1, &parents2, &pos2);
 
   // Traverse the tree up to the container and collect embedded objects.
   for (uint32_t idx = 0; idx < pos1 - 1; idx++) {
     Accessible* parent = parents1[idx + 1];
     Accessible* child = parents1[idx];
     uint32_t childCount = parent->ChildCount();
@@ -141,17 +141,17 @@ TextRange::Normalize(ETextUnit aUnit)
 {
 
 }
 
 bool
 TextRange::Crop(Accessible* aContainer)
 {
   uint32_t boundaryPos = 0, containerPos = 0;
-  nsAutoTArray<Accessible*, 30> boundaryParents, containerParents;
+  AutoTArray<Accessible*, 30> boundaryParents, containerParents;
 
   // Crop the start boundary.
   Accessible* container = nullptr;
   Accessible* boundary = mStartContainer->GetChildAtOffset(mStartOffset);
   if (boundary != aContainer) {
     CommonParent(boundary, aContainer, &boundaryParents, &boundaryPos,
                  &containerParents, &containerPos);
 
--- a/accessible/base/TreeWalker.h
+++ b/accessible/base/TreeWalker.h
@@ -82,17 +82,17 @@ private:
   /**
    * Pop state from stack.
    */
   ChildrenIterator* PopState();
 
   DocAccessible* mDoc;
   Accessible* mContext;
   nsIContent* mAnchorNode;
-  nsAutoTArray<ChildrenIterator, 20> mStateStack;
+  AutoTArray<ChildrenIterator, 20> mStateStack;
   int32_t mChildFilter;
   uint32_t mFlags;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif // mozilla_a11y_TreeWalker_h_
--- a/accessible/ipc/DocAccessibleChild.cpp
+++ b/accessible/ipc/DocAccessibleChild.cpp
@@ -1043,17 +1043,17 @@ DocAccessibleChild::RecvRowExtent(const 
 }
 
 bool
 DocAccessibleChild::RecvColHeaderCells(const uint64_t& aID,
                                        nsTArray<uint64_t>* aCells)
 {
   TableCellAccessible* acc = IdToTableCellAccessible(aID);
   if (acc) {
-    nsAutoTArray<Accessible*, 10> headerCells;
+    AutoTArray<Accessible*, 10> headerCells;
     acc->ColHeaderCells(&headerCells);
     aCells->SetCapacity(headerCells.Length());
     for (uint32_t i = 0; i < headerCells.Length(); ++i) {
       aCells->AppendElement(
         reinterpret_cast<uint64_t>(headerCells[i]->UniqueID()));
     }
   }
 
@@ -1061,17 +1061,17 @@ DocAccessibleChild::RecvColHeaderCells(c
 }
 
 bool
 DocAccessibleChild::RecvRowHeaderCells(const uint64_t& aID,
                                        nsTArray<uint64_t>* aCells)
 {
   TableCellAccessible* acc = IdToTableCellAccessible(aID);
   if (acc) {
-    nsAutoTArray<Accessible*, 10> headerCells;
+    AutoTArray<Accessible*, 10> headerCells;
     acc->RowHeaderCells(&headerCells);
     aCells->SetCapacity(headerCells.Length());
     for (uint32_t i = 0; i < headerCells.Length(); ++i) {
       aCells->AppendElement(
         reinterpret_cast<uint64_t>(headerCells[i]->UniqueID()));
     }
   }
 
@@ -1363,17 +1363,17 @@ DocAccessibleChild::RecvTableSelectedRow
 }
 
 bool
 DocAccessibleChild::RecvTableSelectedCells(const uint64_t& aID,
                                            nsTArray<uint64_t>* aCellIDs)
 {
   TableAccessible* acc = IdToTableAccessible(aID);
   if (acc) {
-    nsAutoTArray<Accessible*, 30> cells;
+    AutoTArray<Accessible*, 30> cells;
     acc->SelectedCells(&cells);
     aCellIDs->SetCapacity(cells.Length());
     for (uint32_t i = 0; i < cells.Length(); ++i) {
       aCellIDs->AppendElement(
         reinterpret_cast<uint64_t>(cells[i]->UniqueID()));
     }
   }
 
@@ -1524,17 +1524,17 @@ DocAccessibleChild::RecvAtkTableRowHeade
 }
 
 bool
 DocAccessibleChild::RecvSelectedItems(const uint64_t& aID,
                                       nsTArray<uint64_t>* aSelectedItemIDs)
 {
   Accessible* acc = IdToAccessibleSelect(aID);
   if (acc) {
-    nsAutoTArray<Accessible*, 10> selectedItems;
+    AutoTArray<Accessible*, 10> selectedItems;
     acc->SelectedItems(&selectedItems);
     aSelectedItemIDs->SetCapacity(selectedItems.Length());
     for (size_t i = 0; i < selectedItems.Length(); ++i) {
       aSelectedItemIDs->AppendElement(
         reinterpret_cast<uint64_t>(selectedItems[i]->UniqueID()));
     }
   }
 
--- a/accessible/ipc/ProxyAccessible.cpp
+++ b/accessible/ipc/ProxyAccessible.cpp
@@ -773,17 +773,17 @@ ProxyAccessible::TableSelectedRowCount()
   uint32_t count = 0;
   Unused << mDoc->SendTableSelectedRowCount(mID, &count);
   return count;
 }
 
 void
 ProxyAccessible::TableSelectedCells(nsTArray<ProxyAccessible*>* aCellIDs)
 {
-  nsAutoTArray<uint64_t, 30> cellIDs;
+  AutoTArray<uint64_t, 30> cellIDs;
   Unused << mDoc->SendTableSelectedCells(mID, &cellIDs);
   aCellIDs->SetCapacity(cellIDs.Length());
   for (uint32_t i = 0; i < cellIDs.Length(); ++i) {
     aCellIDs->AppendElement(mDoc->GetAccessible(cellIDs[i]));
   }
 }
 
 void
@@ -852,17 +852,17 @@ ProxyAccessible::AtkTableRowHeader(int32
   bool ok = false;
   Unused << mDoc->SendAtkTableRowHeader(mID, aRow, &headerID, &ok);
   return ok ? mDoc->GetAccessible(headerID) : nullptr;
 }
 
 void
 ProxyAccessible::SelectedItems(nsTArray<ProxyAccessible*>* aSelectedItems)
 {
-  nsAutoTArray<uint64_t, 10> itemIDs;
+  AutoTArray<uint64_t, 10> itemIDs;
   Unused << mDoc->SendSelectedItems(mID, &itemIDs);
   aSelectedItems->SetCapacity(itemIDs.Length());
   for (size_t i = 0; i < itemIDs.Length(); ++i) {
     aSelectedItems->AppendElement(mDoc->GetAccessible(itemIDs[i]));
   }
 }
 
 uint32_t
--- a/accessible/mac/mozAccessible.mm
+++ b/accessible/mac/mozAccessible.mm
@@ -415,17 +415,17 @@ ConvertToNSArray(nsTArray<ProxyAccessibl
       // Per the MathML 3 spec, the latter happens iff the linethickness
       // attribute is of the form [zero-float][optional-unit]. In that case we
       // set line thickness to zero and in the other cases we set it to one.
       nsAutoString thickness;
       if (accWrap) {
         nsCOMPtr<nsIPersistentProperties> attributes = accWrap->Attributes();
         nsAccUtils::GetAccAttr(attributes, nsGkAtoms::linethickness_, thickness);
       } else {
-        nsAutoTArray<Attribute, 10> attrs;
+        AutoTArray<Attribute, 10> attrs;
         proxy->Attributes(&attrs);
         for (size_t i = 0 ; i < attrs.Length() ; i++) {
           if (attrs.ElementAt(i).Name() == "thickness") {
             thickness = attrs.ElementAt(i).Value();
             break;
           }
         }
       }
@@ -679,21 +679,21 @@ ConvertToNSArray(nsTArray<ProxyAccessibl
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   AccessibleWrap* accWrap = [self getGeckoAccessible];
   if (mChildren || (accWrap && !accWrap->AreChildrenCached()))
     return mChildren;
 
   // get the array of children.
   if (accWrap) {
-    nsAutoTArray<Accessible*, 10> childrenArray;
+    AutoTArray<Accessible*, 10> childrenArray;
     accWrap->GetUnignoredChildren(&childrenArray);
     mChildren = ConvertToNSArray(childrenArray);
   } else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
-    nsAutoTArray<ProxyAccessible*, 10> childrenArray;
+    AutoTArray<ProxyAccessible*, 10> childrenArray;
     GetProxyUnignoredChildren(proxy, &childrenArray);
     mChildren = ConvertToNSArray(childrenArray);
   }
 
 #ifdef DEBUG_hakan
   // make sure we're not returning any ignored accessibles.
   NSEnumerator *e = [mChildren objectEnumerator];
   mozAccessible *m = nil;
--- a/accessible/mac/mozTableAccessible.mm
+++ b/accessible/mac/mozTableAccessible.mm
@@ -202,22 +202,22 @@
     TableCellAccessible* cell = accWrap->AsTableCell();
     if ([attribute isEqualToString:NSAccessibilityRowIndexRangeAttribute])
       return [NSValue valueWithRange:NSMakeRange(cell->RowIdx(),
                                                  cell->RowExtent())];
     if ([attribute isEqualToString:NSAccessibilityColumnIndexRangeAttribute])
       return [NSValue valueWithRange:NSMakeRange(cell->ColIdx(),
                                                  cell->ColExtent())];
     if ([attribute isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
-      nsAutoTArray<Accessible*, 10> headerCells;
+      AutoTArray<Accessible*, 10> headerCells;
       cell->RowHeaderCells(&headerCells);
       return ConvertToNSArray(headerCells);
     }
     if ([attribute isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
-      nsAutoTArray<Accessible*, 10> headerCells;
+      AutoTArray<Accessible*, 10> headerCells;
       cell->ColHeaderCells(&headerCells);
       return ConvertToNSArray(headerCells);
     }
   } else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
     if ([attribute isEqualToString:NSAccessibilityRowIndexRangeAttribute])
       return [NSValue valueWithRange:NSMakeRange(proxy->RowIdx(),
                                                  proxy->RowExtent())];
     if ([attribute isEqualToString:NSAccessibilityColumnIndexRangeAttribute])
--- a/accessible/windows/ia2/ia2Accessible.cpp
+++ b/accessible/windows/ia2/ia2Accessible.cpp
@@ -763,17 +763,17 @@ ia2Accessible::get_selectionRanges(IA2Ra
     return E_INVALIDARG;
 
   *aNRanges = 0;
 
   AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
   if (acc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
-  nsAutoTArray<TextRange, 1> ranges;
+  AutoTArray<TextRange, 1> ranges;
   acc->Document()->SelectionRanges(&ranges);
   uint32_t len = ranges.Length();
   for (uint32_t idx = 0; idx < len; idx++) {
     if (!ranges[idx].Crop(acc)) {
       ranges.RemoveElementAt(idx);
     }
   }
 
--- a/accessible/windows/ia2/ia2AccessibleTable.cpp
+++ b/accessible/windows/ia2/ia2AccessibleTable.cpp
@@ -366,17 +366,17 @@ ia2AccessibleTable::get_selectedChildren
   if (!aChildren || !aNChildren)
     return E_INVALIDARG;
 
   *aChildren = nullptr;
   *aNChildren = 0;
   if (!mTable)
     return CO_E_OBJNOTCONNECTED;
 
-  nsAutoTArray<uint32_t, 30> cellIndices;
+  AutoTArray<uint32_t, 30> cellIndices;
   mTable->SelectedCellIndices(&cellIndices);
 
   uint32_t maxCells = cellIndices.Length();
   if (maxCells == 0)
     return S_FALSE;
 
   *aChildren = static_cast<LONG*>(moz_xmalloc(sizeof(LONG) * maxCells));
   *aNChildren = maxCells;
@@ -658,17 +658,17 @@ ia2AccessibleTable::get_selectedCells(IU
   if (!aCells || !aNSelectedCells)
     return E_INVALIDARG;
 
   *aCells = nullptr;
   *aNSelectedCells = 0;
   if (!mTable)
     return CO_E_OBJNOTCONNECTED;
 
-  nsAutoTArray<Accessible*, 30> cells;
+  AutoTArray<Accessible*, 30> cells;
   mTable->SelectedCells(&cells);
   if (cells.IsEmpty())
     return S_FALSE;
 
   *aCells =
     static_cast<IUnknown**>(::CoTaskMemAlloc(sizeof(IUnknown*) *
                                              cells.Length()));
   if (!*aCells)
@@ -694,17 +694,17 @@ ia2AccessibleTable::get_selectedColumns(
   if (!aColumns || !aNColumns)
     return E_INVALIDARG;
 
   *aColumns = nullptr;
   *aNColumns = 0;
   if (!mTable)
     return CO_E_OBJNOTCONNECTED;
 
-  nsAutoTArray<uint32_t, 30> colIndices;
+  AutoTArray<uint32_t, 30> colIndices;
   mTable->SelectedColIndices(&colIndices);
 
   uint32_t maxCols = colIndices.Length();
   if (maxCols == 0)
     return S_FALSE;
 
   *aColumns = static_cast<LONG*>(moz_xmalloc(sizeof(LONG) * maxCols));
   *aNColumns = maxCols;
@@ -724,17 +724,17 @@ ia2AccessibleTable::get_selectedRows(lon
   if (!aRows || !aNRows)
     return E_INVALIDARG;
 
   *aRows = nullptr;
   *aNRows = 0;
   if (!mTable)
     return CO_E_OBJNOTCONNECTED;
 
-  nsAutoTArray<uint32_t, 30> rowIndices;
+  AutoTArray<uint32_t, 30> rowIndices;
   mTable->SelectedRowIndices(&rowIndices);
 
   uint32_t maxRows = rowIndices.Length();
   if (maxRows == 0)
     return S_FALSE;
 
   *aRows = static_cast<LONG*>(moz_xmalloc(sizeof(LONG) * maxRows));
   *aNRows = maxRows;
--- a/accessible/windows/ia2/ia2AccessibleTableCell.cpp
+++ b/accessible/windows/ia2/ia2AccessibleTableCell.cpp
@@ -95,17 +95,17 @@ ia2AccessibleTableCell::get_columnHeader
   if (!aCellAccessibles || !aNColumnHeaderCells)
     return E_INVALIDARG;
 
   *aCellAccessibles = nullptr;
   *aNColumnHeaderCells = 0;
   if (!mTableCell)
     return CO_E_OBJNOTCONNECTED;
 
-  nsAutoTArray<Accessible*, 10> cells;
+  AutoTArray<Accessible*, 10> cells;
   mTableCell->ColHeaderCells(&cells);
 
   *aNColumnHeaderCells = cells.Length();
   *aCellAccessibles =
     static_cast<IUnknown**>(::CoTaskMemAlloc(sizeof(IUnknown*) *
                                              cells.Length()));
 
   if (!*aCellAccessibles)
@@ -167,17 +167,17 @@ ia2AccessibleTableCell::get_rowHeaderCel
   if (!aCellAccessibles || !aNRowHeaderCells)
     return E_INVALIDARG;
 
   *aCellAccessibles = nullptr;
   *aNRowHeaderCells = 0;
   if (!mTableCell)
     return CO_E_OBJNOTCONNECTED;
 
-  nsAutoTArray<Accessible*, 10> cells;
+  AutoTArray<Accessible*, 10> cells;
   mTableCell->RowHeaderCells(&cells);
 
   *aNRowHeaderCells = cells.Length();
   *aCellAccessibles =
     static_cast<IUnknown**>(::CoTaskMemAlloc(sizeof(IUnknown*) *
                                              cells.Length()));
   if (!*aCellAccessibles)
     return E_OUTOFMEMORY;
--- a/accessible/windows/ia2/ia2AccessibleText.cpp
+++ b/accessible/windows/ia2/ia2AccessibleText.cpp
@@ -56,17 +56,17 @@ ia2AccessibleText::get_attributes(long a
 
   *aStartOffset = 0;
   *aEndOffset = 0;
   *aTextAttributes = nullptr;
 
   int32_t startOffset = 0, endOffset = 0;
   HRESULT hr;
   if (ProxyAccessible* proxy = HyperTextProxyFor(this)) {
-    nsAutoTArray<Attribute, 10> attrs;
+    AutoTArray<Attribute, 10> attrs;
     proxy->TextAttributes(true, aOffset, &attrs, &startOffset, &endOffset);
     hr = AccessibleWrap::ConvertToIA2Attributes(&attrs, aTextAttributes);
   } else {
     HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
     if (textAcc->IsDefunct())
       return CO_E_OBJNOTCONNECTED;
 
     nsCOMPtr<nsIPersistentProperties> attributes =
--- a/accessible/windows/msaa/AccessibleWrap.cpp
+++ b/accessible/windows/msaa/AccessibleWrap.cpp
@@ -829,17 +829,17 @@ AccessibleWrap::get_accSelection(VARIANT
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   // TODO make this work with proxies.
   if (IsProxy())
     return E_NOTIMPL;
 
   if (IsSelect()) {
-    nsAutoTArray<Accessible*, 10> selectedItems;
+    AutoTArray<Accessible*, 10> selectedItems;
     if (IsProxy()) {
       nsTArray<ProxyAccessible*> proxies;
       Proxy()->SelectedItems(&proxies);
 
       uint32_t selectedCount = proxies.Length();
       for (uint32_t i = 0; i < selectedCount; i++) {
         selectedItems.AppendElement(WrapperFor(proxies[i]));
       }
--- a/accessible/xpcom/xpcAccessibleHyperText.cpp
+++ b/accessible/xpcom/xpcAccessibleHyperText.cpp
@@ -366,17 +366,17 @@ xpcAccessibleHyperText::GetSelectionRang
   if (!Intl())
     return NS_ERROR_FAILURE;
 
   nsresult rv = NS_OK;
   nsCOMPtr<nsIMutableArray> xpcRanges =
     do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsAutoTArray<TextRange, 1> ranges;
+  AutoTArray<TextRange, 1> ranges;
   Intl()->SelectionRanges(&ranges);
   uint32_t len = ranges.Length();
   for (uint32_t idx = 0; idx < len; idx++)
     xpcRanges->AppendElement(new xpcAccessibleTextRange(Move(ranges[idx])),
                              false);
 
   xpcRanges.forget(aRanges);
   return NS_OK;
--- a/accessible/xpcom/xpcAccessibleSelectable.cpp
+++ b/accessible/xpcom/xpcAccessibleSelectable.cpp
@@ -16,17 +16,17 @@ xpcAccessibleSelectable::GetSelectedItem
 {
   NS_ENSURE_ARG_POINTER(aSelectedItems);
   *aSelectedItems = nullptr;
 
   if (!Intl())
     return NS_ERROR_FAILURE;
   NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
 
-  nsAutoTArray<Accessible*, 10> items;
+  AutoTArray<Accessible*, 10> items;
   Intl()->SelectedItems(&items);
 
   uint32_t itemCount = items.Length();
   if (itemCount == 0)
     return NS_OK;
 
   nsresult rv = NS_OK;
   nsCOMPtr<nsIMutableArray> xpcItems =
--- a/accessible/xpcom/xpcAccessibleTable.cpp
+++ b/accessible/xpcom/xpcAccessibleTable.cpp
@@ -268,17 +268,17 @@ xpcAccessibleTable::GetSelectedCells(nsI
   if (!Intl())
     return NS_ERROR_FAILURE;
 
   nsresult rv = NS_OK;
   nsCOMPtr<nsIMutableArray> selCells =
     do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsAutoTArray<Accessible*, XPC_TABLE_DEFAULT_SIZE> cellsArray;
+  AutoTArray<Accessible*, XPC_TABLE_DEFAULT_SIZE> cellsArray;
   Intl()->SelectedCells(&cellsArray);
 
   uint32_t totalCount = cellsArray.Length();
   for (uint32_t idx = 0; idx < totalCount; idx++) {
     Accessible* cell = cellsArray.ElementAt(idx);
     selCells->AppendElement(static_cast<nsIAccessible*>(ToXPC(cell)), false);
   }
 
@@ -294,17 +294,17 @@ xpcAccessibleTable::GetSelectedCellIndic
   *aCellsArraySize = 0;
 
   NS_ENSURE_ARG_POINTER(aCellsArray);
   *aCellsArray = 0;
 
   if (!Intl())
     return NS_ERROR_FAILURE;
 
-  nsAutoTArray<uint32_t, XPC_TABLE_DEFAULT_SIZE> cellsArray;
+  AutoTArray<uint32_t, XPC_TABLE_DEFAULT_SIZE> cellsArray;
   Intl()->SelectedCellIndices(&cellsArray);
 
   *aCellsArraySize = cellsArray.Length();
   *aCellsArray = static_cast<int32_t*>
     (moz_xmalloc(*aCellsArraySize * sizeof(int32_t)));
   memcpy(*aCellsArray, cellsArray.Elements(),
     *aCellsArraySize * sizeof(int32_t));
 
@@ -319,17 +319,17 @@ xpcAccessibleTable::GetSelectedColumnInd
   *aColsArraySize = 0;
 
   NS_ENSURE_ARG_POINTER(aColsArray);
   *aColsArray = 0;
 
   if (!Intl())
     return NS_ERROR_FAILURE;
 
-  nsAutoTArray<uint32_t, XPC_TABLE_DEFAULT_SIZE> colsArray;
+  AutoTArray<uint32_t, XPC_TABLE_DEFAULT_SIZE> colsArray;
   Intl()->SelectedColIndices(&colsArray);
 
   *aColsArraySize = colsArray.Length();
   *aColsArray = static_cast<int32_t*>
     (moz_xmalloc(*aColsArraySize * sizeof(int32_t)));
   memcpy(*aColsArray, colsArray.Elements(),
     *aColsArraySize * sizeof(int32_t));
 
@@ -344,17 +344,17 @@ xpcAccessibleTable::GetSelectedRowIndice
   *aRowsArraySize = 0;
 
   NS_ENSURE_ARG_POINTER(aRowsArray);
   *aRowsArray = 0;
 
   if (!Intl())
     return NS_ERROR_FAILURE;
 
-  nsAutoTArray<uint32_t, XPC_TABLE_DEFAULT_SIZE> rowsArray;
+  AutoTArray<uint32_t, XPC_TABLE_DEFAULT_SIZE> rowsArray;
   Intl()->SelectedRowIndices(&rowsArray);
 
   *aRowsArraySize = rowsArray.Length();
   *aRowsArray = static_cast<int32_t*>
     (moz_xmalloc(*aRowsArraySize * sizeof(int32_t)));
   memcpy(*aRowsArray, rowsArray.Elements(),
     *aRowsArraySize * sizeof(int32_t));
 
--- a/accessible/xpcom/xpcAccessibleTableCell.cpp
+++ b/accessible/xpcom/xpcAccessibleTableCell.cpp
@@ -103,17 +103,17 @@ NS_IMETHODIMP
 xpcAccessibleTableCell::GetColumnHeaderCells(nsIArray** aHeaderCells)
 {
   NS_ENSURE_ARG_POINTER(aHeaderCells);
   *aHeaderCells = nullptr;
 
   if (!Intl())
     return NS_ERROR_FAILURE;
 
-  nsAutoTArray<Accessible*, 10> headerCells;
+  AutoTArray<Accessible*, 10> headerCells;
   Intl()->ColHeaderCells(&headerCells);
 
   nsCOMPtr<nsIMutableArray> cells = do_CreateInstance(NS_ARRAY_CONTRACTID);
   NS_ENSURE_TRUE(cells, NS_ERROR_FAILURE);
 
   for (uint32_t idx = 0; idx < headerCells.Length(); idx++) {
     cells->AppendElement(static_cast<nsIAccessible*>(ToXPC(headerCells[idx])),
                          false);
@@ -127,17 +127,17 @@ NS_IMETHODIMP
 xpcAccessibleTableCell::GetRowHeaderCells(nsIArray** aHeaderCells)
 {
   NS_ENSURE_ARG_POINTER(aHeaderCells);
   *aHeaderCells = nullptr;
 
   if (!Intl())
     return NS_ERROR_FAILURE;
 
-  nsAutoTArray<Accessible*, 10> headerCells;
+  AutoTArray<Accessible*, 10> headerCells;
   Intl()->RowHeaderCells(&headerCells);
 
   nsCOMPtr<nsIMutableArray> cells = do_CreateInstance(NS_ARRAY_CONTRACTID);
   NS_ENSURE_TRUE(cells, NS_ERROR_FAILURE);
 
   for (uint32_t idx = 0; idx < headerCells.Length(); idx++) {
     cells->AppendElement(static_cast<nsIAccessible*>(ToXPC(headerCells[idx])),
                          false);
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -350,16 +350,20 @@ pref("dom.w3c_touch_events.safetyY", 120
 #ifdef MOZ_SAFE_BROWSING
 pref("browser.safebrowsing.enabled", true);
 // Prevent loading of pages identified as malware
 pref("browser.safebrowsing.malware.enabled", true);
 pref("browser.safebrowsing.downloads.enabled", true);
 pref("browser.safebrowsing.downloads.remote.enabled", true);
 pref("browser.safebrowsing.downloads.remote.timeout_ms", 10000);
 pref("browser.safebrowsing.downloads.remote.url", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
+pref("browser.safebrowsing.downloads.remote.block_dangerous",            true);
+pref("browser.safebrowsing.downloads.remote.block_dangerous_host",       true);
+pref("browser.safebrowsing.downloads.remote.block_potentially_unwanted", false);
+pref("browser.safebrowsing.downloads.remote.block_uncommon",             false);
 pref("browser.safebrowsing.debug", false);
 
 pref("browser.safebrowsing.provider.google.lists", "goog-badbinurl-shavar,goog-downloadwhite-digest256,goog-phish-shavar,goog-malware-shavar,goog-unwanted-shavar");
 pref("browser.safebrowsing.provider.google.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");
 pref("browser.safebrowsing.provider.google.gethashURL", "https://safebrowsing.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2");
 pref("browser.safebrowsing.provider.google.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
 
 pref("browser.safebrowsing.reportPhishMistakeURL", "https://%LOCALE%.phish-error.mozilla.com/?hl=%LOCALE%&url=");
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -20,16 +20,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!--
     B2G repositories for all targets
     -->
   <project name="gaia" path="gaia" remote="mozillaorg" revision="4f0e2a1a42a2d049b6fe8f4f095cdcdf0fd5465c"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4eb8f37d2239ea7746462aa603f585116a9eaa92"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
+  <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
   <project name="platform_system_libpdu" path="system/libpdu" remote="b2g" revision="ac4e539dbd73522c466ebffba53edea61702082f"/>
   <project name="platform_system_sensorsd" path="system/sensorsd" remote="b2g" revision="3799a1cb57f08e9468d1cec6c74f8abe93ddae36"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk-specific things and forks -->
   <project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
   <project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -20,16 +20,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!--
     B2G repositories for all targets
     -->
   <project name="gaia" path="gaia" remote="mozillaorg" revision="4f0e2a1a42a2d049b6fe8f4f095cdcdf0fd5465c"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4eb8f37d2239ea7746462aa603f585116a9eaa92"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
+  <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
   <project name="platform_system_libpdu" path="system/libpdu" remote="b2g" revision="ac4e539dbd73522c466ebffba53edea61702082f"/>
   <project name="platform_system_sensorsd" path="system/sensorsd" remote="b2g" revision="3799a1cb57f08e9468d1cec6c74f8abe93ddae36"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk-specific things and forks -->
   <project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
   <project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
--- a/b2g/installer/Makefile.in
+++ b/b2g/installer/Makefile.in
@@ -21,27 +21,24 @@ DEFINES += \
 	-DPREF_DIR=$(PREF_DIR) \
 	$(NULL)
 
 DEFINES += -DJAREXT=
 
 DEFINES += -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME)
 
 # Set MSVC dlls version to package, if any.
+ifdef MOZ_NO_DEBUG_RTL
 ifdef WIN32_REDIST_DIR
-ifdef MOZ_NO_DEBUG_RTL
 DEFINES += -DMOZ_PACKAGE_MSVC_DLLS=1
 DEFINES += -DMSVC_C_RUNTIME_DLL=$(MSVC_C_RUNTIME_DLL)
 DEFINES += -DMSVC_CXX_RUNTIME_DLL=$(MSVC_CXX_RUNTIME_DLL)
-ifdef MSVC_APPCRT_DLL
-DEFINES += -DMSVC_APPCRT_DLL=$(MSVC_APPCRT_DLL)
 endif
-ifdef MSVC_DESKTOPCRT_DLL
-DEFINES += -DMSVC_DESKTOPCRT_DLL=$(MSVC_DESKTOPCRT_DLL)
-endif
+ifdef WIN_UCRT_REDIST_DIR
+DEFINES += -DMOZ_PACKAGE_WIN_UCRT_DLLS=1
 endif
 endif
 
 ifdef MOZ_DEBUG
 DEFINES += -DMOZ_DEBUG=1
 endif
 
 ifdef ENABLE_MARIONETTE
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -60,22 +60,20 @@
 @BINPATH@/@MOZ_CHILD_PROCESS_NAME@.app/
 #else
 @BINPATH@/@MOZ_CHILD_PROCESS_NAME@
 #endif
 #ifdef XP_WIN32
 #if MOZ_PACKAGE_MSVC_DLLS
 @BINPATH@/@MSVC_C_RUNTIME_DLL@
 @BINPATH@/@MSVC_CXX_RUNTIME_DLL@
-#ifdef MSVC_APPCRT_DLL
-@BINPATH@/@MSVC_APPCRT_DLL@
 #endif
-#ifdef MSVC_DESKTOPCRT_DLL
-@BINPATH@/@MSVC_DESKTOPCRT_DLL@
-#endif
+#if MOZ_PACKAGE_WIN_UCRT_DLLS
+@BINPATH@/api-ms-win-*.dll
+@BINPATH@/ucrtbase.dll
 #endif
 #endif
 #ifndef MOZ_NATIVE_ICU
 #ifdef MOZ_SHARED_ICU
 #ifdef XP_WIN
 @BINPATH@/icudt@MOZ_ICU_DBG_SUFFIX@@MOZ_ICU_VERSION@.dll
 @BINPATH@/icuin@MOZ_ICU_DBG_SUFFIX@@MOZ_ICU_VERSION@.dll
 @BINPATH@/icuuc@MOZ_ICU_DBG_SUFFIX@@MOZ_ICU_VERSION@.dll
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -2,24 +2,16 @@
 # 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/.
 
 dist_dest   = $(DIST)/$(MOZ_MACBUNDLE_NAME)
 
 # hardcode en-US for the moment
 AB_CD = en-US
 
-DEFINES += \
-  -DFIREFOX_ICO='"$(DIST)/branding/firefox.ico"' \
-  -DDOCUMENT_ICO='"$(DIST)/branding/document.ico"' \
-  -DNEWWINDOW_ICO='"$(DIST)/branding/newwindow.ico"' \
-  -DNEWTAB_ICO='"$(DIST)/branding/newtab.ico"' \
-  -DPBMODE_ICO='"$(DIST)/branding/pbmode.ico"' \
-  $(NULL)
-
 # Build a binary bootstrapping with XRE_main
 
 ifndef MOZ_WINCONSOLE
 ifneq (,$(MOZ_DEBUG)$(MOZ_ASAN))
 MOZ_WINCONSOLE = 1
 else
 MOZ_WINCONSOLE = 0
 endif
--- a/browser/app/moz.build
+++ b/browser/app/moz.build
@@ -68,8 +68,12 @@ DISABLE_STL_WRAPPING = True
 if CONFIG['MOZ_LINKER']:
     OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
 
 if CONFIG['HAVE_CLOCK_MONOTONIC']:
     OS_LIBS += CONFIG['REALTIME_LIBS']
 
 if CONFIG['GNU_CXX']:
     CXXFLAGS += ['-Wshadow']
+
+for icon in ('firefox', 'document', 'newwindow', 'newtab', 'pbmode'):
+    DEFINES[icon.upper() + '_ICO'] = '"%s/dist/branding/%s.ico"' % (
+        TOPOBJDIR, icon)
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -948,16 +948,20 @@ pref("gecko.handlerService.allowRegister
 
 #ifdef MOZ_SAFE_BROWSING
 pref("browser.safebrowsing.enabled", true);
 pref("browser.safebrowsing.malware.enabled", true);
 pref("browser.safebrowsing.downloads.enabled", true);
 pref("browser.safebrowsing.downloads.remote.enabled", true);
 pref("browser.safebrowsing.downloads.remote.timeout_ms", 10000);
 pref("browser.safebrowsing.downloads.remote.url", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
+pref("browser.safebrowsing.downloads.remote.block_dangerous",            true);
+pref("browser.safebrowsing.downloads.remote.block_dangerous_host",       true);
+pref("browser.safebrowsing.downloads.remote.block_potentially_unwanted", false);
+pref("browser.safebrowsing.downloads.remote.block_uncommon",             false);
 pref("browser.safebrowsing.debug", false);
 
 pref("browser.safebrowsing.provider.google.lists", "goog-badbinurl-shavar,goog-downloadwhite-digest256,goog-phish-shavar,goog-malware-shavar,goog-unwanted-shavar");
 pref("browser.safebrowsing.provider.google.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");
 pref("browser.safebrowsing.provider.google.gethashURL", "https://safebrowsing.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2");
 pref("browser.safebrowsing.provider.google.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
 
 pref("browser.safebrowsing.reportPhishMistakeURL", "https://%LOCALE%.phish-error.mozilla.com/?hl=%LOCALE%&url=");
--- a/browser/base/content/test/general/browser_bug724239.js
+++ b/browser/base/content/test/general/browser_bug724239.js
@@ -1,33 +1,11 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-function test() {
-  waitForExplicitFinish();
-  BrowserOpenTab();
-
-  let tab = gBrowser.selectedTab;
-  let browser = tab.linkedBrowser;
-
-  registerCleanupFunction(function () { gBrowser.removeTab(tab); });
-
-  whenBrowserLoaded(browser, function () {
-    browser.loadURI("http://example.com/");
-
-    whenBrowserLoaded(browser, function () {
-      ok(!gBrowser.canGoBack, "about:newtab wasn't added to the session history");
-      finish();
-    });
+add_task(function* test() {
+  yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" },
+                                    function* (browser) {
+    BrowserTestUtils.loadURI(browser, "http://example.com");
+    yield BrowserTestUtils.browserLoaded(browser);
+    ok(!gBrowser.canGoBack, "about:newtab wasn't added to the session history");
   });
-}
-
-function whenBrowserLoaded(aBrowser, aCallback) {
-  if (aBrowser.contentDocument.readyState == "complete") {
-    executeSoon(aCallback);
-    return;
-  }
-
-  aBrowser.addEventListener("load", function onLoad() {
-    aBrowser.removeEventListener("load", onLoad, true);
-    executeSoon(aCallback);
-  }, true);
-}
+});
--- a/browser/components/privatebrowsing/test/browser/browser.ini
+++ b/browser/components/privatebrowsing/test/browser/browser.ini
@@ -37,14 +37,11 @@ tags = trackingprotection
 [browser_privatebrowsing_placestitle.js]
 [browser_privatebrowsing_popupblocker.js]
 [browser_privatebrowsing_protocolhandler.js]
 [browser_privatebrowsing_sidebar.js]
 [browser_privatebrowsing_theming.js]
 [browser_privatebrowsing_ui.js]
 [browser_privatebrowsing_urlbarfocus.js]
 [browser_privatebrowsing_windowtitle.js]
-skip-if = e10s
 [browser_privatebrowsing_zoom.js]
-skip-if = e10s
 [browser_privatebrowsing_zoomrestore.js]
-skip-if = e10s
 [browser_privatebrowsing_newtab_from_popup.js]
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle.js
@@ -1,19 +1,18 @@
 /* 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/. */
 
 // This test makes sure that the window title changes correctly while switching
 // from and to private browsing mode.
 
-function test() {
+add_task(function test() {
   const testPageURL = "http://mochi.test:8888/browser/" +
     "browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle_page.html";
-  waitForExplicitFinish();
   requestLongerTimeout(2);
 
   // initialization of expected titles
   let test_title = "Test title";
   let app_name = document.documentElement.getAttribute("title");
   const isOSX = ("nsILocalFileMac" in Ci);
   let page_with_title;
   let page_without_title;
@@ -33,74 +32,46 @@ function test() {
     page_with_title = test_title + " - " + app_name;
     page_without_title = app_name;
     about_pb_title = "Open a private window?" + " - " + app_name;
     pb_page_with_title = test_title + " - " + app_name + " (Private Browsing)";
     pb_page_without_title = app_name + " (Private Browsing)";
     pb_about_pb_title = "You're browsing privately - " + app_name + " (Private Browsing)";
   }
 
-  function testTabTitle(aWindow, url, insidePB, expected_title, funcNext) {
-    executeSoon(function () {
-      let tab = aWindow.gBrowser.selectedTab = aWindow.gBrowser.addTab();
-      let browser = aWindow.gBrowser.selectedBrowser;
-      browser.stop();
-      // ensure that the test is run after the titlebar has been updated
-      browser.addEventListener("load", function () {
-        browser.removeEventListener("load", arguments.callee, true);
-        executeSoon(function () {
-          if (aWindow.document.title != expected_title) {
-            executeSoon(arguments.callee);
-            return;
-          }
-          is(aWindow.document.title, expected_title, "The window title for " + url +
-             " is correct (" + (insidePB ? "inside" : "outside") +
-             " private browsing mode)");
+  function* testTabTitle(aWindow, url, insidePB, expected_title) {
+    let tab = (yield BrowserTestUtils.openNewForegroundTab(aWindow.gBrowser));
+    yield BrowserTestUtils.loadURI(tab.linkedBrowser, url);
+    yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+
+    yield BrowserTestUtils.waitForCondition(() => {
+      return aWindow.document.title === expected_title;
+    });
+
+    is(aWindow.document.title, expected_title, "The window title for " + url +
+       " is correct (" + (insidePB ? "inside" : "outside") +
+       " private browsing mode)");
 
-          let win = aWindow.gBrowser.replaceTabWithWindow(tab);
-          win.addEventListener("load", function() {
-            win.removeEventListener("load", arguments.callee, false);
-            executeSoon(function() {
-              if (win.document.title != expected_title) {
-                executeSoon(arguments.callee);
-                return;
-              }
-              is(win.document.title, expected_title, "The window title for " + url +
-                 " detached tab is correct (" + (insidePB ? "inside" : "outside") +
-                 " private browsing mode)");
-              win.close();
-              aWindow.close();
+    let win = aWindow.gBrowser.replaceTabWithWindow(tab);
+    yield BrowserTestUtils.waitForEvent(win, "load", false);
+
+    yield BrowserTestUtils.waitForCondition(() => {
+      return win.document.title === expected_title;
+    });
 
-              setTimeout(funcNext, 0);
-            });
-          }, false);
-        });
-      }, true);
+    is(win.document.title, expected_title, "The window title for " + url +
+       " detached tab is correct (" + (insidePB ? "inside" : "outside") +
+       " private browsing mode)");
 
-      browser.loadURI(url);
-    });
+    yield Promise.all([ BrowserTestUtils.closeWindow(win),
+                        BrowserTestUtils.closeWindow(aWindow) ]);
   }
 
-  whenNewWindowLoaded({private: false}, function(win) {
-    testTabTitle(win, "about:blank", false, page_without_title, function() {
-      whenNewWindowLoaded({private: false}, function(win) {
-        testTabTitle(win, testPageURL, false, page_with_title, function() {
-          whenNewWindowLoaded({private: false}, function(win) {
-            testTabTitle(win, "about:privatebrowsing", false, about_pb_title, function() {
-              whenNewWindowLoaded({private: true}, function(win) {
-                testTabTitle(win, "about:blank", true, pb_page_without_title, function() {
-                  whenNewWindowLoaded({private: true}, function(win) {
-                    testTabTitle(win, testPageURL, true, pb_page_with_title, function() {
-                      whenNewWindowLoaded({private: true}, function(win) {
-                        testTabTitle(win, "about:privatebrowsing", true, pb_about_pb_title, finish);
-                      });
-                    });
-                  });
-                });
-              });
-            });
-          });
-        });
-      });
-    });
-  });
-  return;
-}
+  function openWin(private) {
+    return BrowserTestUtils.openNewBrowserWindow({ private });
+  }
+  yield Task.spawn(testTabTitle((yield openWin(false)), "about:blank", false, page_without_title));
+  yield Task.spawn(testTabTitle((yield openWin(false)), testPageURL, false, page_with_title));
+  yield Task.spawn(testTabTitle((yield openWin(false)), "about:privatebrowsing", false, about_pb_title));
+  yield Task.spawn(testTabTitle((yield openWin(true)), "about:blank", true, pb_page_without_title));
+  yield Task.spawn(testTabTitle((yield openWin(true)), testPageURL, true, pb_page_with_title));
+  yield Task.spawn(testTabTitle((yield openWin(true)), "about:privatebrowsing", true, pb_about_pb_title));
+});
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoom.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoom.js
@@ -1,60 +1,37 @@
 /* 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/. */
 
 // This test makes sure that private browsing turns off doesn't cause zoom
 // settings to be reset on tab switch (bug 464962)
 
-function test() {
-  waitForExplicitFinish();
-
-  function testZoom(aWindow, aCallback) {
-    executeSoon(function() {
-      let tabAbout = aWindow.gBrowser.addTab();
-      aWindow.gBrowser.selectedTab = tabAbout;
+add_task(function* test() {
+  let win = (yield BrowserTestUtils.openNewBrowserWindow({ private: true }));
+  let tabAbout = (yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:"));
+  let tabMozilla = (yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:"));
 
-      let aboutBrowser = aWindow.gBrowser.getBrowserForTab(tabAbout);
-      aboutBrowser.addEventListener("load", function onAboutBrowserLoad() {
-        aboutBrowser.removeEventListener("load", onAboutBrowserLoad, true);
-        let tabMozilla = aWindow.gBrowser.addTab();
-        aWindow.gBrowser.selectedTab = tabMozilla;
+  let mozillaZoom = win.ZoomManager.zoom;
 
-        let mozillaBrowser = aWindow.gBrowser.getBrowserForTab(tabMozilla);
-        mozillaBrowser.addEventListener("load", function onMozillaBrowserLoad() {
-          mozillaBrowser.removeEventListener("load", onMozillaBrowserLoad, true);
-          let mozillaZoom = aWindow.ZoomManager.zoom;
-
-          // change the zoom on the mozilla page
-          aWindow.FullZoom.enlarge();
-          // make sure the zoom level has been changed
-          isnot(aWindow.ZoomManager.zoom, mozillaZoom, "Zoom level can be changed");
-          mozillaZoom = aWindow.ZoomManager.zoom;
+  // change the zoom on the mozilla page
+  win.FullZoom.enlarge();
+  // make sure the zoom level has been changed
+  isnot(win.ZoomManager.zoom, mozillaZoom, "Zoom level can be changed");
+  mozillaZoom = win.ZoomManager.zoom;
 
-          // switch to about: tab
-          aWindow.gBrowser.selectedTab = tabAbout;
+  // switch to about: tab
+  yield BrowserTestUtils.switchTab(win.gBrowser, tabAbout);
 
-          // switch back to mozilla tab
-          aWindow.gBrowser.selectedTab = tabMozilla;
-
-          // make sure the zoom level has not changed
-          is(aWindow.ZoomManager.zoom, mozillaZoom,
-            "Entering private browsing should not reset the zoom on a tab");
+  // switch back to mozilla tab
+  yield BrowserTestUtils.switchTab(win.gBrowser, tabMozilla);
 
-          // cleanup
-          aWindow.FullZoom.reset();
-          aWindow.gBrowser.removeTab(tabMozilla);
-          aWindow.gBrowser.removeTab(tabAbout);
-          aWindow.close();
-          aCallback();
+  // make sure the zoom level has not changed
+  is(win.ZoomManager.zoom, mozillaZoom,
+     "Entering private browsing should not reset the zoom on a tab");
 
-        }, true);
-        mozillaBrowser.contentWindow.location = "about:mozilla";
-      }, true);
-      aboutBrowser.contentWindow.location = "about:";
-    });
-  }
+  // cleanup
+  win.FullZoom.reset();
+  yield Promise.all([ BrowserTestUtils.removeTab(tabMozilla),
+                      BrowserTestUtils.removeTab(tabAbout) ]);
 
-  whenNewWindowLoaded({private: true}, function(privateWindow) {
-    testZoom(privateWindow, finish);
-  });
-}
+  yield BrowserTestUtils.closeWindow(win);
+});
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoomrestore.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoomrestore.js
@@ -1,80 +1,64 @@
 /* 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/. */
 
 // This test makes sure that about:privatebrowsing does not appear zoomed in
 // if there is already a zoom site pref for about:blank (bug 487656).
 
-function test() {
+add_task(function* test() {
   // initialization
-  waitForExplicitFinish();
   let windowsToClose = [];
   let windowsToReset = [];
 
-  function doTestWhenReady(aIsZoomedWindow, aWindow, aCallback) {
+  function promiseLocationChange() {
+    return new Promise(resolve => {
+      Services.obs.addObserver(function onLocationChange(subj, topic, data) {
+        Services.obs.removeObserver(onLocationChange, topic);
+        resolve();
+      }, "browser-fullZoom:location-change", false);
+    });
+  }
+
+  function promiseTestReady(aIsZoomedWindow, aWindow) {
     // Need to wait on two things, the ordering of which is not guaranteed:
     // (1) the page load, and (2) FullZoom's update to the new page's zoom
     // level.  FullZoom broadcasts "browser-fullZoom:location-change" when its
     // update is done.  (See bug 856366 for details.)
 
-    let n = 0;
 
     let browser = aWindow.gBrowser.selectedBrowser;
-    browser.addEventListener("load", function onLoad() {
-      browser.removeEventListener("load", onLoad, true);
-      if (++n == 2)
-        doTest(aIsZoomedWindow, aWindow, aCallback);
-    }, true);
-
-    Services.obs.addObserver(function onLocationChange(subj, topic, data) {
-      Services.obs.removeObserver(onLocationChange, topic);
-      if (++n == 2)
-        doTest(aIsZoomedWindow, aWindow, aCallback);
-    }, "browser-fullZoom:location-change", false);
-
-    browser.loadURI("about:blank");
+    return BrowserTestUtils.loadURI(browser, "about:blank").then(() => {
+      return Promise.all([ BrowserTestUtils.browserLoaded(browser),
+                           promiseLocationChange() ]);
+    }).then(() => doTest(aIsZoomedWindow, aWindow));
   }
 
-  function doTest(aIsZoomedWindow, aWindow, aCallback) {
+  function doTest(aIsZoomedWindow, aWindow) {
     if (aIsZoomedWindow) {
       is(aWindow.ZoomManager.zoom, 1,
          "Zoom level for freshly loaded about:blank should be 1");
       // change the zoom on the blank page
       aWindow.FullZoom.enlarge();
       isnot(aWindow.ZoomManager.zoom, 1, "Zoom level for about:blank should be changed");
-      aCallback();
       return;
     }
+
     // make sure the zoom level is set to 1
     is(aWindow.ZoomManager.zoom, 1, "Zoom level for about:privatebrowsing should be reset");
-    aCallback();
-  }
-
-  function finishTest() {
-    // cleanup
-    windowsToReset.forEach(function(win) {
-      win.FullZoom.reset();
-    });
-    windowsToClose.forEach(function(win) {
-      win.close();
-    });
-    finish();
   }
 
   function testOnWindow(options, callback) {
-    let win = whenNewWindowLoaded(options,
-      function(win) {
-        windowsToClose.push(win);
-        windowsToReset.push(win);
-        executeSoon(function() { callback(win); });
-      });
-  };
+    return BrowserTestUtils.openNewBrowserWindow(options).then((win) => {
+      windowsToClose.push(win);
+      windowsToReset.push(win);
+      return win;
+    });
+  }
 
-  testOnWindow({}, function(win) {
-    doTestWhenReady(true, win, function() {
-      testOnWindow({private: true}, function(win) {
-        doTestWhenReady(false, win, finishTest);
-      });
-    });
-  });
-}
+  yield testOnWindow({}).then(win => promiseTestReady(true, win));
+  yield testOnWindow({private: true}).then(win => promiseTestReady(false, win));
+
+  // cleanup
+  windowsToReset.forEach((win) => win.FullZoom.reset());
+  yield Promise.all(windowsToClose.map(win => BrowserTestUtils.closeWindow(win)));
+});
--- a/browser/config/mozconfigs/macosx-universal/nightly
+++ b/browser/config/mozconfigs/macosx-universal/nightly
@@ -7,11 +7,11 @@ ac_add_options --enable-instruments
 ac_add_options --enable-dtrace
 
 if test "${MOZ_UPDATE_CHANNEL}" = "nightly"; then
 ac_add_options --with-macbundlename-prefix=Firefox
 fi
 
 ac_add_options --with-branding=browser/branding/nightly
 
-. "$topsrcdir/build/macosx/mozconfig.rust"
+. "$topsrcdir/build/mozconfig.rust"
 . "$topsrcdir/build/mozconfig.common.override"
 . "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/macosx64/debug
+++ b/browser/config/mozconfigs/macosx64/debug
@@ -15,11 +15,11 @@ fi
 # Treat warnings as errors (modulo ALLOW_COMPILER_WARNINGS).
 ac_add_options --enable-warnings-as-errors
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 ac_add_options --with-branding=browser/branding/nightly
 
-. "$topsrcdir/build/macosx/mozconfig.rust"
+. "$topsrcdir/build/mozconfig.rust"
 . "$topsrcdir/build/mozconfig.common.override"
 . "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/macosx64/nightly
+++ b/browser/config/mozconfigs/macosx64/nightly
@@ -13,11 +13,11 @@ fi
 # Treat warnings as errors (modulo ALLOW_COMPILER_WARNINGS).
 ac_add_options --enable-warnings-as-errors
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 ac_add_options --with-branding=browser/branding/nightly
 
-. "$topsrcdir/build/macosx/mozconfig.rust"
+. "$topsrcdir/build/mozconfig.rust"
 . "$topsrcdir/build/mozconfig.common.override"
 . "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/macosx64/opt-static-analysis
+++ b/browser/config/mozconfigs/macosx64/opt-static-analysis
@@ -8,12 +8,12 @@ ac_add_options --disable-debug
 ac_add_options --enable-optimize
 ac_add_options --enable-dmd
 
 # Treat warnings as errors (modulo ALLOW_COMPILER_WARNINGS).
 ac_add_options --enable-warnings-as-errors
 
 ac_add_options --enable-clang-plugin
 
-. "$topsrcdir/build/macosx/mozconfig.rust"
+. "$topsrcdir/build/mozconfig.rust"
 . "$topsrcdir/build/mozconfig.common.override"
 . "$topsrcdir/build/mozconfig.cache"
 
--- a/browser/config/mozconfigs/whitelist
+++ b/browser/config/mozconfigs/whitelist
@@ -48,17 +48,17 @@ whitelist['nightly']['macosx-universal']
     'ac_add_options --with-macbundlename-prefix=Firefox',
     'fi',
     'mk_add_options MOZ_MAKE_FLAGS="-j12"',
     'ac_add_options --with-ccache',
     '. "$topsrcdir/build/mozconfig.cache"',
     'ac_add_options --disable-install-strip',
     'ac_add_options --enable-instruments',
     'ac_add_options --enable-dtrace',
-    '. "$topsrcdir/build/macosx/mozconfig.rust"',
+    '. "$topsrcdir/build/mozconfig.rust"',
 ]
 
 whitelist['nightly']['win32'] += [
     '. $topsrcdir/configs/mozilla2/win32/include/choose-make-flags',
     'mk_add_options MOZ_MAKE_FLAGS=-j1',
     '. "$topsrcdir/build/mozconfig.cache"',
     'if test "$IS_NIGHTLY" != ""; then',
     'ac_add_options --disable-auto-deps',
--- a/browser/config/tooltool-manifests/macosx64/cross-releng.manifest
+++ b/browser/config/tooltool-manifests/macosx64/cross-releng.manifest
@@ -42,10 +42,26 @@
 },
 {
 "size": 188880, 
 "visibility": "public", 
 "digest": "1ffddd43efb03aed897ee42035d9d8d758a8d66ab6c867599ef755e1a586768fc22011ce03698af61454920b00fe8bed08c9a681e7bd324d7f8f78c026c83943", 
 "algorithm": "sha512", 
 "unpack": true,
 "filename": "genisoimage.tar.xz"
+},
+{
+"size": 60778437,
+"visibility": "public",
+"digest": "2d5d300dd0d829012953ca0dd70b0abfda4e848ff03450326cf0c10eac2a71e37275b824597641f0f536b97b754bc81b10f9dbbb73ff725412858a7c2b9df6a7",
+"algorithm": "sha512",
+"filename": "rust-std-lib.tar.bz2",
+"unpack": true
+},
+{
+"size": 36038146,
+"visibility": "public",
+"digest": "b967ba81cb08ce4c3a18e3f8411365ee775861df1ba7f60bcaccd03f940732ee9c4c622cd3163198abb36b2124cde550c61b5d153f1ae8a9107b382ddf660895",
+"algorithm": "sha512",
+"filename": "rustc-linux64.tar.bz2",
+"unpack": true
 }
 ]
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -53,27 +53,24 @@ endif
 ifdef MOZ_D3DCOMPILER_XP_DLL
 DEFINES += -DMOZ_D3DCOMPILER_XP_DLL=$(MOZ_D3DCOMPILER_XP_DLL)
 endif
 endif
 
 DEFINES += -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME)
 
 # Set MSVC dlls version to package, if any.
+ifdef MOZ_NO_DEBUG_RTL
 ifdef WIN32_REDIST_DIR
-ifdef MOZ_NO_DEBUG_RTL
 DEFINES += -DMOZ_PACKAGE_MSVC_DLLS=1
 DEFINES += -DMSVC_C_RUNTIME_DLL=$(MSVC_C_RUNTIME_DLL)
 DEFINES += -DMSVC_CXX_RUNTIME_DLL=$(MSVC_CXX_RUNTIME_DLL)
-ifdef MSVC_APPCRT_DLL
-DEFINES += -DMSVC_APPCRT_DLL=$(MSVC_APPCRT_DLL)
 endif
-ifdef MSVC_DESKTOPCRT_DLL
-DEFINES += -DMSVC_DESKTOPCRT_DLL=$(MSVC_DESKTOPCRT_DLL)
-endif
+ifdef WIN_UCRT_REDIST_DIR
+DEFINES += -DMOZ_PACKAGE_WIN_UCRT_DLLS=1
 endif
 endif
 
 ifneq (,$(filter WINNT Darwin Android,$(OS_TARGET)))
 DEFINES += -DMOZ_SHARED_MOZGLUE=1
 endif
 
 ifdef NECKO_WIFI
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -86,22 +86,20 @@
 #else
 @BINPATH@/@MOZ_CHILD_PROCESS_NAME@
 #endif
 #ifdef XP_WIN32
 @BINPATH@/plugin-hang-ui@BIN_SUFFIX@
 #if MOZ_PACKAGE_MSVC_DLLS
 @BINPATH@/@MSVC_C_RUNTIME_DLL@
 @BINPATH@/@MSVC_CXX_RUNTIME_DLL@
-#ifdef MSVC_APPCRT_DLL
-@BINPATH@/@MSVC_APPCRT_DLL@
 #endif
-#ifdef MSVC_DESKTOPCRT_DLL
-@BINPATH@/@MSVC_DESKTOPCRT_DLL@
-#endif
+#if MOZ_PACKAGE_WIN_UCRT_DLLS
+@BINPATH@/api-ms-win-*.dll
+@BINPATH@/ucrtbase.dll
 #endif
 #endif
 #ifndef MOZ_NATIVE_ICU
 #ifdef MOZ_SHARED_ICU
 #ifdef XP_WIN
 @BINPATH@/icudt@MOZ_ICU_DBG_SUFFIX@@MOZ_ICU_VERSION@.dll
 @BINPATH@/icuin@MOZ_ICU_DBG_SUFFIX@@MOZ_ICU_VERSION@.dll
 @BINPATH@/icuuc@MOZ_ICU_DBG_SUFFIX@@MOZ_ICU_VERSION@.dll
--- a/browser/modules/UserContextUI.jsm
+++ b/browser/modules/UserContextUI.jsm
@@ -10,23 +10,23 @@ Cu.import("resource://gre/modules/XPCOMU
 Cu.import("resource://gre/modules/Services.jsm")
 
 XPCOMUtils.defineLazyGetter(this, "gBrowserBundle", function() {
   return Services.strings.createBundle("chrome://browser/locale/browser.properties");
 });
 
 this.UserContextUI = {
   getUserContextLabel(userContextId) {
-    switch (userContextId) {
+    switch (parseInt(userContextId)) {
       // No UserContext:
       case 0: return "";
 
       case 1: return gBrowserBundle.GetStringFromName("usercontext.personal.label");
       case 2: return gBrowserBundle.GetStringFromName("usercontext.work.label");
-      case 3: return gBrowserBundle.GetStringFromName("usercontext.shopping.label");
-      case 4: return gBrowserBundle.GetStringFromName("usercontext.banking.label");
+      case 3: return gBrowserBundle.GetStringFromName("usercontext.banking.label");
+      case 4: return gBrowserBundle.GetStringFromName("usercontext.shopping.label");
 
       // Display the context IDs for values outside the pre-defined range.
       // Used for debugging, no localization necessary.
       default: return "Context " + userContextId;
     }
   }
 }
--- a/build/autoconf/rust.m4
+++ b/build/autoconf/rust.m4
@@ -27,10 +27,92 @@ AC_DEFUN([MOZ_RUST_SUPPORT], [
     "$_RUSTC_MAJOR_VERSION" -lt 1 -o \
     \( "$_RUSTC_MAJOR_VERSION" -eq 1 -a "$_RUSTC_MINOR_VERSION" -lt 5 \); then
     AC_MSG_ERROR([Rust compiler ${RUSTC_VERSION} is too old.
       To compile Rust language sources please install at least
       version 1.5 of the 'rustc' toolchain and make sure it is
       first in your path.
       You can verify this by typing 'rustc --version'.])
   fi
+
+  if test -n "$RUSTC" -a -n "$MOZ_RUST"; then
+    # Rust's --target options are similar to, but not exactly the same
+    # as, the autoconf-derived targets we use.  An example would be that
+    # Rust uses distinct target triples for targetting the GNU C++ ABI
+    # and the MSVC C++ ABI on Win32, whereas autoconf has a single
+    # triple and relies on the user to ensure that everything is
+    # compiled for the appropriate ABI.  We need to perform appropriate
+    # munging to get the correct option to rustc.
+    #
+    # The canonical list of targets supported can be derived from:
+    #
+    # https://github.com/rust-lang/rust/tree/master/mk/cfg
+    rust_target=
+    case "$target" in
+      # Linux
+      i*86*linux-gnu)
+          rust_target=i686-unknown-linux-gnu
+          ;;
+      x86_64*linux-gnu)
+          rust_target=x86_64-unknown-linux-gnu
+          ;;
+
+      # OS X and iOS
+      i*86-apple-darwin*)
+          rust_target=i686-apple-darwin
+          ;;
+      i*86-apple-ios*)
+          rust_target=i386-apple-ios
+          ;;
+      x86_64-apple-darwin*)
+          rust_target=x86_64-apple-darwin
+          ;;
+
+      # Android
+      i*86*linux-android)
+          rust_target=i686-linux-android
+          ;;
+      arm*linux-android*)
+          rust_target=arm-linux-androideabi
+          ;;
+
+      # Windows
+      i*86-pc-mingw32)
+          # XXX better detection of CXX needed here, to figure out whether
+          # we need i686-pc-windows-gnu instead, since mingw32 builds work.
+          rust_target=i686-pc-windows-msvc
+          ;;
+      x86_64-pc-mingw32)
+          # XXX and here as well
+          rust_target=x86_64-pc-windows-msvc
+          ;;
+      *)
+          AC_ERROR([don't know how to translate $target for rustc])
+    esac
+
+    # Check to see whether we need to pass --target to RUSTC.  This can
+    # happen when building Firefox on Windows: js's configure will receive
+    # a RUSTC from the toplevel configure that already has --target added to
+    # it.
+    rustc_target_arg=
+    case "$RUSTC" in
+      *--target=${rust_target}*)
+        ;;
+      *)
+        rustc_target_arg=--target=${rust_target}
+        ;;
+    esac
+
+    # Check to see whether our rustc has a reasonably functional stdlib
+    # for our chosen target.
+    echo 'pub extern fn hello() { println!("Hello world"); }' > conftest.rs
+    if AC_TRY_COMMAND(${RUSTC} --crate-type staticlib ${rustc_target_arg} -o conftest.rlib conftest.rs > /dev/null) && test -s conftest.rlib; then
+      RUSTC="${RUSTC} ${rustc_target_arg}"
+    else
+      AC_ERROR([cannot compile for ${rust_target} with ${RUSTC}])
+    fi
+    rm -f conftest.rs conftest.rlib
+  fi
+
+  # TODO: separate HOST_RUSTC and RUSTC variables
+
   AC_SUBST(MOZ_RUST)
 ])
--- a/build/mach_bootstrap.py
+++ b/build/mach_bootstrap.py
@@ -67,17 +67,16 @@ SEARCH_PATHS = [
     'layout/tools/reftest',
     'other-licenses/ply',
     'testing',
     'testing/firefox-ui/harness',
     'testing/firefox-ui/tests',
     'testing/luciddream',
     'testing/marionette/client',
     'testing/marionette/client/marionette/runner/mixins/browsermob-proxy-py',
-    'testing/marionette/transport',
     'testing/marionette/driver',
     'testing/mozbase/mozcrash',
     'testing/mozbase/mozdebug',
     'testing/mozbase/mozdevice',
     'testing/mozbase/mozfile',
     'testing/mozbase/mozhttpd',
     'testing/mozbase/mozinfo',
     'testing/mozbase/mozinstall',
deleted file mode 100644
--- a/build/macosx/mozconfig.rust
+++ /dev/null
@@ -1,6 +0,0 @@
-# Options to enable rust in automation builds.
-
-if test `uname -s` != Linux; then
-RUSTC="$topsrcdir/rustc/bin/rustc"
-ac_add_options --enable-rust
-fi
deleted file mode 100644
--- a/build/stlport/Makefile.in
+++ /dev/null
@@ -1,9 +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/.
-
-MODULES = stlport
-
-include $(topsrcdir)/config/rules.mk
-
-CXXFLAGS += -fuse-cxa-atexit
--- a/build/stlport/moz.build
+++ b/build/stlport/moz.build
@@ -67,8 +67,12 @@ if CONFIG['GNU_CXX']:
     ]
 
 # Force to build a static library, instead of a fake library, without
 # installing it in dist/lib.
 NO_EXPAND_LIBS = True
 
 # We allow warnings for third-party code that can be updated from upstream.
 ALLOW_COMPILER_WARNINGS = True
+
+CXXFLAGS += [
+    '-fuse-cxa-atexit',
+]
--- a/build/virtualenv_packages.txt
+++ b/build/virtualenv_packages.txt
@@ -1,9 +1,8 @@
-marionette_transport.pth:testing/marionette/transport
 marionette_driver.pth:testing/marionette/driver
 browsermobproxy.pth:testing/marionette/client/marionette/runner/mixins/browsermob-proxy-py
 wptserve.pth:testing/web-platform/tests/tools/wptserve
 marionette.pth:testing/marionette/client
 blessings.pth:python/blessings
 configobj.pth:python/configobj
 jsmin.pth:python/jsmin
 mach.pth:python/mach
--- a/build/win32/Makefile.in
+++ b/build/win32/Makefile.in
@@ -1,29 +1,32 @@
 # 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 $(topsrcdir)/config/rules.mk
 
+REDIST_FILES =
+
 ifdef WIN32_REDIST_DIR
+REDIST_FILES += '$(WIN32_REDIST_DIR)'/$(MSVC_C_RUNTIME_DLL)
+REDIST_FILES += '$(WIN32_REDIST_DIR)'/$(MSVC_CXX_RUNTIME_DLL)
+endif
 
-REDIST_FILES = \
-  $(MSVC_C_RUNTIME_DLL) \
-  $(MSVC_CXX_RUNTIME_DLL) \
-  $(MSVC_APPCRT_DLL) \
-  $(MSVC_DESKTOPCRT_DLL) \
-  $(NULL)
+ifdef WIN_UCRT_REDIST_DIR
+REDIST_FILES += $(wildcard $(WIN_UCRT_REDIST_DIR)/api-ms-win-*.dll)
+REDIST_FILES += '$(WIN_UCRT_REDIST_DIR)'/ucrtbase.dll
+endif
 
+ifdef REDIST_FILES
 libs-preqs = \
-  $(call mkdir_deps,$(FINAL_TARGET)) \
-  $(NULL)
+	$(call mkdir_deps,$(FINAL_TARGET)) \
+	$(NULL)
 
 libs:: $(libs-preqs)
-	install --preserve-timestamps $(foreach f,$(REDIST_FILES),'$(WIN32_REDIST_DIR)'/$(f)) $(FINAL_TARGET)
-
-endif # WIN32_REDIST_DIR
+	install --preserve-timestamps $(REDIST_FILES) $(FINAL_TARGET)
+endif
 
 # run the binscope tool to make sure the binary and all libraries
 # are using all available Windows OS-level security mechanisms
 check::
 	$(PYTHON) $(srcdir)/autobinscope.py $(DIST)/bin/$(MOZ_APP_NAME)$(BIN_SUFFIX) $(DIST)/crashreporter-symbols/
 	$(PYTHON) $(srcdir)/autobinscope.py $(DIST)/bin/plugin-container.exe $(DIST)/crashreporter-symbols/
--- a/build/win32/autobinscope.py
+++ b/build/win32/autobinscope.py
@@ -42,17 +42,17 @@ try:
 except KeyError:
   print "BINSCOPE environment variable is not set, can't check DEP/ASLR etc. status."
   sys.exit(0)
   
 try:    
   proc = subprocess.Popen([binscope_path, "/target", binary_path,
     "/output", log_file_path, "/sympath", symbol_path,
     "/c", "ATLVersionCheck", "/c", "ATLVulnCheck", "/c", "SharedSectionCheck", "/c", "APTCACheck", "/c", "NXCheck",
-    "/c", "GSCheck", "/c", "GSFunctionSafeBuffersCheck", "/c", "GSFriendlyInitCheck",
+    "/c", "GSCheck", "/c", "GSFriendlyInitCheck",
     "/c", "CompilerVersionCheck", "/c", "SafeSEHCheck", "/c", "SNCheck",
     "/c", "DBCheck"], stdout=subprocess.PIPE)
 
 except WindowsError, (errno, strerror): 
   if errno != 2 and errno != 3:
     print "Unexpected error ! \nError " + str(errno) + " : " + strerror + "\nExiting !\n"
     sys.exit(0)
   else:
--- a/config/config.mk
+++ b/config/config.mk
@@ -391,29 +391,16 @@ RTL_FLAGS=-MD          # Dynamically lin
 ifdef MOZ_DEBUG
 ifndef MOZ_NO_DEBUG_RTL
 RTL_FLAGS=-MDd         # Dynamically linked, multithreaded MSVC4.0 debug RTL
 endif
 endif # MOZ_DEBUG
 endif # USE_STATIC_LIBS
 endif # WINNT && !GNU_CC
 
-ifeq ($(OS_ARCH),Darwin)
-# Compiling ObjC requires an Apple compiler anyway, so it's ok to set
-# host CMFLAGS here.
-HOST_CMFLAGS += -fobjc-exceptions
-HOST_CMMFLAGS += -fobjc-exceptions
-OS_COMPILE_CMFLAGS += -fobjc-exceptions
-OS_COMPILE_CMMFLAGS += -fobjc-exceptions
-ifeq ($(MOZ_WIDGET_TOOLKIT),uikit)
-OS_COMPILE_CMFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch
-OS_COMPILE_CMMFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch
-endif
-endif
-
 COMPILE_CFLAGS	= $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CFLAGS) $(_DEPEND_CFLAGS) $(CFLAGS) $(MOZBUILD_CFLAGS)
 COMPILE_CXXFLAGS = $(if $(DISABLE_STL_WRAPPING),,$(STL_FLAGS)) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CXXFLAGS) $(_DEPEND_CFLAGS) $(CXXFLAGS) $(MOZBUILD_CXXFLAGS)
 COMPILE_CMFLAGS = $(OS_COMPILE_CMFLAGS) $(MOZBUILD_CMFLAGS)
 COMPILE_CMMFLAGS = $(OS_COMPILE_CMMFLAGS) $(MOZBUILD_CMMFLAGS)
 ASFLAGS += $(MOZBUILD_ASFLAGS)
 
 ifndef CROSS_COMPILE
 HOST_CFLAGS += $(RTL_FLAGS)
--- a/configure.in
+++ b/configure.in
@@ -530,18 +530,16 @@ case "$target" in
             MSVS_VERSION=2013
             MSVC_C_RUNTIME_DLL=msvcr120.dll
             MSVC_CXX_RUNTIME_DLL=msvcp120.dll
         elif test "$_CC_MAJOR_VERSION" = "19" -a "$_CC_BUILD_VERSION" -ge "23506"; then
             _CC_SUITE=14
             MSVS_VERSION=2015
             MSVC_C_RUNTIME_DLL=vcruntime140.dll
             MSVC_CXX_RUNTIME_DLL=msvcp140.dll
-            MSVC_APPCRT_DLL=appcrt140.dll
-            MSVC_DESKTOPCRT_DLL=desktopcrt140.dll
 
             # -Wv:18 disables all warnings introduced after VS2013
             # See http://blogs.msdn.com/b/vcblog/archive/2014/11/12/improvements-to-warnings-in-the-c-compiler.aspx
             CFLAGS="$CFLAGS -Wv:18"
             CXXFLAGS="$CXXFLAGS -Wv:18"
 
             # -Zc:sizedDealloc- disables C++14 global sized deallocation (see bug 1160146)
             CXXFLAGS="$CXXFLAGS -Zc:sizedDealloc-"
@@ -550,26 +548,31 @@ case "$target" in
             # See https://connect.microsoft.com/VisualStudio/feedback/details/1789709/visual-c-2015-runtime-broken-on-windows-server-2003-c-11-magic-statics
             CXXFLAGS="$CXXFLAGS -Zc:threadSafeInit-"
 
             # https://connect.microsoft.com/VisualStudio/feedback/details/888527/warnings-on-dbghelp-h
             # for dbghelp.h, imagehlp.h, and shobj.h
             # C4091: 'typedef ': ignored on left of '' when no variable is declared
             CFLAGS="$CFLAGS -wd4091"
             CXXFLAGS="$CXXFLAGS -wd4091"
+
+            if test -n "$WIN_UCRT_REDIST_DIR"; then
+              if test ! -d "$WIN_UCRT_REDIST_DIR"; then
+                AC_MSG_ERROR([Invalid Windows UCRT Redist directory: ${WIN_UCRT_REDIST_DIR}])
+              fi
+              WIN_UCRT_REDIST_DIR=`cd "$WIN_UCRT_REDIST_DIR" && pwd`
+            fi
         else
             AC_MSG_ERROR([This version (${_CC_MAJOR_VERSION}.${_CC_MINOR_VERSION}.${_CC_BUILD_VERSION}) of the MSVC compiler is unsupported.
 You must install Visual C++ 2013 Update 3, Visual C++ 2015 Update 1, or newer in order to build.
 See https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
         fi
         AC_SUBST(MSVS_VERSION)
         AC_SUBST(MSVC_C_RUNTIME_DLL)
         AC_SUBST(MSVC_CXX_RUNTIME_DLL)
-        AC_SUBST(MSVC_APPCRT_DLL)
-        AC_SUBST(MSVC_DESKTOPCRT_DLL)
 
         # Disable SEH on clang-cl because it doesn't implement them yet.
         if test -z "$CLANG_CL"; then
             AC_DEFINE(HAVE_SEH_EXCEPTIONS)
         else
             # Send our CFLAGS to NSS
             MOZ_CFLAGS_NSS=1
             AC_DEFINE_UNQUOTED(GTEST_HAS_SEH, 0)
@@ -1629,17 +1632,16 @@ fi # COMPILE_ENVIRONMENT
 
 dnl ========================================================
 dnl Special rust checks
 dnl ========================================================
 
 if test -n "$MACOSX_DEPLOYMENT_TARGET" -a -n "$MOZ_RUST"; then
   AC_MSG_CHECKING([if we're targeting 32-bit])
   if test -z "$HAVE_64BIT_BUILD"; then
-    RUSTC="$RUSTC --target=i686-apple-darwin"
     AC_MSG_RESULT([using $RUSTC])
   else
     AC_MSG_RESULT([no])
   fi
   AC_MSG_CHECKING([rustc compatibility with MacOS X])
   # Stock rustc doesn't support MacOS X 10.6 or earlier.
   # https://github.com/rust-lang/rust/issues/25342
   _MACOSX_TARGET_MINOR=`echo "$MACOSX_DEPLOYMENT_TARGET" | cut -d. -f2`
@@ -2211,16 +2213,18 @@ ia64*-hpux*)
             WIN32_SUBSYSTEM_VERSION=6.01
         fi
         WIN32_CONSOLE_EXE_LDFLAGS=-SUBSYSTEM:CONSOLE,$WIN32_SUBSYSTEM_VERSION
         WIN32_GUI_EXE_LDFLAGS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
         DSO_LDOPTS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
         _USE_CPP_INCLUDE_FLAG=1
         _DEFINES_CFLAGS='-FI $(topobjdir)/mozilla-config.h -DMOZILLA_CLIENT'
         _DEFINES_CXXFLAGS='-FI $(topobjdir)/mozilla-config.h -DMOZILLA_CLIENT'
+        SSE_FLAGS="-arch:SSE"
+        SSE2_FLAGS="-arch:SSE2"
         CFLAGS="$CFLAGS -W3 -Gy"
         CXXFLAGS="$CXXFLAGS -W3 -Gy"
         if test "$CPU_ARCH" = "x86"; then
             dnl VS2012+ defaults to -arch:SSE2.
             CFLAGS="$CFLAGS -arch:IA32"
             CXXFLAGS="$CXXFLAGS -arch:IA32"
         fi
         dnl VS2013+ requires -FS when parallel building by make -jN.
@@ -7211,24 +7215,26 @@ else
     AC_DEFINE(MOZ_MEMORY_BSD)
     ;;
   *-solaris*)
     AC_DEFINE(MOZ_MEMORY_SOLARIS)
     ;;
   *-mingw*)
     AC_DEFINE(MOZ_MEMORY_WINDOWS)
     export MOZ_NO_DEBUG_RTL=1
-    WIN32_CRT_LIBS="msvcrt.lib msvcprt.lib"
-    dnl Look for a broken crtdll.obj
-    WIN32_CRTDLL_FULLPATH=`lib -nologo -list $WIN32_CRT_LIBS | grep crtdll\\.obj`
-    lib -NOLOGO -OUT:crtdll.obj $WIN32_CRT_LIBS -EXTRACT:$WIN32_CRTDLL_FULLPATH
-    if grep -q '__imp__\{0,1\}free' crtdll.obj; then
-      MOZ_CRT=1
-    fi
-    rm crtdll.obj
+    if test "$MSVS_VERSION" != "2015"; then
+        WIN32_CRT_LIBS="msvcrt.lib msvcprt.lib"
+        dnl Look for a broken crtdll.obj
+        WIN32_CRTDLL_FULLPATH=`lib -nologo -list $WIN32_CRT_LIBS | grep crtdll\\.obj`
+        lib -NOLOGO -OUT:crtdll.obj $WIN32_CRT_LIBS -EXTRACT:$WIN32_CRTDLL_FULLPATH
+        if grep -q '__imp__\{0,1\}free' crtdll.obj; then
+          MOZ_CRT=1
+        fi
+        rm crtdll.obj
+    fi
     ;;
   *)
     AC_MSG_ERROR([--enable-jemalloc not supported on ${target}])
     ;;
   esac
 fi # MOZ_MEMORY
 AC_SUBST(MOZ_MEMORY)
 AC_SUBST(MOZ_JEMALLOC4)
@@ -8795,16 +8801,29 @@ if test "$MOZ_WIDGET_TOOLKIT" = gonk -a 
 fi
 AC_SUBST(MOZ_B2G_LOADER)
 
 AC_SUBST(MOZ_NATIVE_NSPR)
 
 AC_SUBST(MOZ_NATIVE_NSS)
 AC_SUBST(NSS_DISABLE_DBM)
 
+HOST_CMFLAGS=-fobjc-exceptions
+HOST_CMMFLAGS=-fobjc-exceptions
+OS_COMPILE_CMFLAGS=-fobjc-exceptions
+OS_COMPILE_CMMFLAGS=-fobjc-exceptions
+if test "$MOZ_WIDGET_TOOLKIT" = uikit; then
+  OS_COMPILE_CMFLAGS="$OS_COMPILE_CMFLAGS -fobjc-abi-version=2 -fobjc-legacy-dispatch"
+  OS_COMPILE_CMMFLAGS="$OS_COMPILE_CMMFLAGS -fobjc-abi-version=2 -fobjc-legacy-dispatch"
+fi
+AC_SUBST(HOST_CMFLAGS)
+AC_SUBST(HOST_CMMFLAGS)
+AC_SUBST(OS_COMPILE_CMFLAGS)
+AC_SUBST(OS_COMPILE_CMMFLAGS)
+
 OS_CFLAGS="$CFLAGS"
 OS_CXXFLAGS="$CXXFLAGS"
 OS_CPPFLAGS="$CPPFLAGS"
 OS_COMPILE_CFLAGS="$COMPILE_CFLAGS"
 OS_COMPILE_CXXFLAGS="$COMPILE_CXXFLAGS"
 OS_LDFLAGS="$LDFLAGS"
 OS_LIBS="$LIBS"
 AC_SUBST(OS_CFLAGS)
--- a/devtools/client/inspector/shared/test/browser_styleinspector_csslogic-content-stylesheets.js
+++ b/devtools/client/inspector/shared/test/browser_styleinspector_csslogic-content-stylesheets.js
@@ -16,16 +16,18 @@ const TEST_URI_XUL = TEST_URL_ROOT + "do
 const XUL_URI = Cc["@mozilla.org/network/io-service;1"]
                 .getService(Ci.nsIIOService)
                 .newURI(TEST_URI_XUL, null, null);
 var ssm = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
                             .getService(Ci.nsIScriptSecurityManager);
 const XUL_PRINCIPAL = ssm.createCodebasePrincipal(XUL_URI, {});
 
 add_task(function*() {
+  requestLongerTimeout(2);
+
   info("Checking stylesheets on HTML document");
   yield addTab(TEST_URI_HTML);
   let target = getNode("#target");
 
   let {inspector} = yield openRuleView();
   yield selectNode("#target", inspector);
 
   info("Checking stylesheets");
--- a/devtools/shared/security/LocalCertService.cpp
+++ b/devtools/shared/security/LocalCertService.cpp
@@ -253,17 +253,17 @@ private:
   {
     nsCOMPtr<nsIX509CertDB> certDB = do_GetService(NS_X509CERTDB_CONTRACTID);
     if (!certDB) {
       return NS_ERROR_FAILURE;
     }
 
     nsCOMPtr<nsIX509Cert> certFromDB;
     nsresult rv;
-    rv = certDB->FindCertByNickname(nullptr, NS_ConvertASCIItoUTF16(mNickname),
+    rv = certDB->FindCertByNickname(NS_ConvertASCIItoUTF16(mNickname),
                                     getter_AddRefs(certFromDB));
     if (NS_FAILED(rv)) {
       return rv;
     }
     mCert = certFromDB;
     return NS_OK;
   }
 
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1683,17 +1683,17 @@ nsDocShell::FirePageHideNotification(boo
     }
 
     mContentViewer->PageHide(aIsUnload);
 
     if (mTiming) {
       mTiming->NotifyUnloadEventEnd();
     }
 
-    nsAutoTArray<nsCOMPtr<nsIDocShell>, 8> kids;
+    AutoTArray<nsCOMPtr<nsIDocShell>, 8> kids;
     uint32_t n = mChildList.Length();
     kids.SetCapacity(n);
     for (uint32_t i = 0; i < n; i++) {
       kids.AppendElement(do_QueryInterface(ChildAt(i)));
     }
 
     n = kids.Length();
     for (uint32_t i = 0; i < n; ++i) {
@@ -4391,17 +4391,17 @@ nsDocShell::RemoveFromSessionHistory()
     }
   }
   if (!internalHistory) {
     return NS_OK;
   }
 
   int32_t index = 0;
   sessionHistory->GetIndex(&index);
-  nsAutoTArray<uint64_t, 16> ids;
+  AutoTArray<uint64_t, 16> ids;
   ids.AppendElement(mHistoryID);
   internalHistory->RemoveEntries(ids, index);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::SetCreatedDynamically(bool aDynamic)
 {
@@ -4482,17 +4482,17 @@ nsDocShell::ClearFrameHistory(nsISHEntry
   GetRootSessionHistory(getter_AddRefs(rootSH));
   nsCOMPtr<nsISHistoryInternal> history = do_QueryInterface(rootSH);
   if (!history || !shcontainer) {
     return;
   }
 
   int32_t count = 0;
   shcontainer->GetChildCount(&count);
-  nsAutoTArray<uint64_t, 16> ids;
+  AutoTArray<uint64_t, 16> ids;
   for (int32_t i = 0; i < count; ++i) {
     nsCOMPtr<nsISHEntry> child;
     shcontainer->GetChildAt(i, getter_AddRefs(child));
     if (child) {
       uint64_t id = 0;
       child->GetDocshellID(&id);
       ids.AppendElement(id);
     }
@@ -14308,14 +14308,16 @@ nsDocShell::InFrameSwap()
     shell = shell->GetParentDocshell();
   } while (shell);
   return false;
 }
 
 NS_IMETHODIMP
 nsDocShell::IssueWarning(uint32_t aWarning, bool aAsError)
 {
-  nsCOMPtr<nsIDocument> doc = mContentViewer->GetDocument();
-  if (doc) {
-    doc->WarnOnceAbout(nsIDocument::DeprecatedOperations(aWarning), aAsError);
-  }
-  return NS_OK;
-}
+  if (mContentViewer) {
+    nsCOMPtr<nsIDocument> doc = mContentViewer->GetDocument();
+    if (doc) {
+      doc->WarnOnceAbout(nsIDocument::DeprecatedOperations(aWarning), aAsError);
+    }
+  }
+  return NS_OK;
+}
--- a/docshell/shistory/nsSHistory.cpp
+++ b/docshell/shistory/nsSHistory.cpp
@@ -1400,17 +1400,17 @@ nsSHistory::RemoveEntries(nsTArray<uint6
 void
 nsSHistory::RemoveDynEntries(int32_t aOldIndex, int32_t aNewIndex)
 {
   // Search for the entries which are in the current index,
   // but not in the new one.
   nsCOMPtr<nsISHEntry> originalSH;
   GetEntryAtIndex(aOldIndex, false, getter_AddRefs(originalSH));
   nsCOMPtr<nsISHContainer> originalContainer = do_QueryInterface(originalSH);
-  nsAutoTArray<uint64_t, 16> toBeRemovedEntries;
+  AutoTArray<uint64_t, 16> toBeRemovedEntries;
   if (originalContainer) {
     nsTArray<uint64_t> originalDynDocShellIDs;
     GetDynamicChildren(originalContainer, originalDynDocShellIDs, true);
     if (originalDynDocShellIDs.Length()) {
       nsCOMPtr<nsISHEntry> currentSH;
       GetEntryAtIndex(aNewIndex, false, getter_AddRefs(currentSH));
       nsCOMPtr<nsISHContainer> newContainer = do_QueryInterface(currentSH);
       if (newContainer) {
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -573,17 +573,17 @@ EffectCompositor::ComposeAnimationRule(d
 }
 
 /* static */ void
 EffectCompositor::GetOverriddenProperties(nsStyleContext* aStyleContext,
                                           EffectSet& aEffectSet,
                                           nsCSSPropertySet&
                                             aPropertiesOverridden)
 {
-  nsAutoTArray<nsCSSProperty, LayerAnimationInfo::kRecords> propertiesToTrack;
+  AutoTArray<nsCSSProperty, LayerAnimationInfo::kRecords> propertiesToTrack;
   {
     nsCSSPropertySet propertiesToTrackAsSet;
     for (KeyframeEffectReadOnly* effect : aEffectSet) {
       for (const AnimationProperty& property : effect->Properties()) {
         if (nsCSSProps::PropHasFlags(property.mProperty,
                                      CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR) &&
             !propertiesToTrackAsSet.HasProperty(property.mProperty)) {
           propertiesToTrackAsSet.AddProperty(property.mProperty);
--- a/dom/animation/KeyframeEffect.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -1350,17 +1350,17 @@ BuildAnimationPropertyListFromKeyframeSe
     JSContext* aCx,
     Element* aTarget,
     JS::ForOfIterator& aIterator,
     nsTArray<AnimationProperty>& aResult,
     ErrorResult& aRv)
 {
   // Convert the object in aIterator to sequence<Keyframe>, producing
   // an array of OffsetIndexedKeyframe objects.
-  nsAutoTArray<OffsetIndexedKeyframe,4> keyframes;
+  AutoTArray<OffsetIndexedKeyframe,4> keyframes;
   if (!ConvertKeyframeSequence(aCx, aIterator, keyframes)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   // If the sequence<> had zero elements, we won't generate any
   // keyframes.
   if (keyframes.IsEmpty()) {
--- a/dom/animation/test/chrome/test_restyles.html
+++ b/dom/animation/test/chrome/test_restyles.html
@@ -76,66 +76,66 @@ waitForAllPaints(function() {
 
     yield animation.ready;
     ok(animation.isRunningOnCompositor);
 
     var markers = yield observeStyling(5);
     is(markers.length, 0,
        'CSS animations running on the compositor should not update style ' +
        'on the main thread');
-    div.remove(div);
+    div.remove();
   });
 
   add_task_if_omta_enabled(function* no_restyling_for_compositor_transitions() {
     var div = addDiv(null, { style: 'transition: opacity 100s; opacity: 0' });
     getComputedStyle(div).opacity;
     div.style.opacity = 1;
 
     var animation = div.getAnimations()[0];
 
     yield animation.ready;
     ok(animation.isRunningOnCompositor);
 
     var markers = yield observeStyling(5);
     is(markers.length, 0,
        'CSS transitions running on the compositor should not update style ' +
        'on the main thread');
-    div.remove(div);
+    div.remove();
   });
 
   add_task_if_omta_enabled(function* no_restyling_when_animation_duration_is_changed() {
     var div = addDiv(null, { style: 'animation: opacity 100s' });
     var animation = div.getAnimations()[0];
 
     yield animation.ready;
     ok(animation.isRunningOnCompositor);
 
     div.animationDuration = '200s';
 
     var markers = yield observeStyling(5);
     is(markers.length, 0,
        'Animations running on the compositor should not update style ' +
        'on the main thread');
-    div.remove(div);
+    div.remove();
   });
 
   add_task_if_omta_enabled(function* only_one_restyling_after_finish_is_called() {
     var div = addDiv(null, { style: 'animation: opacity 100s' });
     var animation = div.getAnimations()[0];
 
     yield animation.ready;
     ok(animation.isRunningOnCompositor);
 
     animation.finish();
 
     var markers = yield observeStyling(5);
     is(markers.length, 1,
        'Animations running on the compositor should only update style ' +
        'once after finish() is called');
-    div.remove(div);
+    div.remove();
   });
 
   add_task(function* no_restyling_mouse_movement_on_finished_transition() {
     var div = addDiv(null, { style: 'transition: opacity 1ms; opacity: 0' });
     getComputedStyle(div).opacity;
     div.style.opacity = 1;
 
     var animation = div.getAnimations()[0];
@@ -150,17 +150,17 @@ waitForAllPaints(function() {
       // layout flush.
       synthesizeMouseAtPoint(mouseX++, mouseY++,
                              { type: 'mousemove' }, window);
     });
 
     is(markers.length, 0,
        'Bug 1219236: Finished transitions should never cause restyles ' +
        'when mouse is moved on the animations');
-    div.remove(div);
+    div.remove();
   });
 
   add_task(function* no_restyling_mouse_movement_on_finished_animation() {
     var div = addDiv(null, { style: 'animation: opacity 1ms' });
     var animation = div.getAnimations()[0];
 
     var initialRect = div.getBoundingClientRect();
 
@@ -173,47 +173,47 @@ waitForAllPaints(function() {
       // layout flush.
       synthesizeMouseAtPoint(mouseX++, mouseY++,
                              { type: 'mousemove' }, window);
     });
 
     is(markers.length, 0,
        'Bug 1219236: Finished animations should never cause restyles ' +
        'when mouse is moved on the animations');
-    div.remove(div);
+    div.remove();
   });
 
   add_task_if_omta_enabled(function* no_restyling_compositor_animations_out_of_view_element() {
     var div = addDiv(null,
       { style: 'animation: opacity 100s; transform: translateY(-400px);' });
     var animation = div.getAnimations()[0];
 
     yield animation.ready;
     ok(!animation.isRunningOnCompositor);
 
     var markers = yield observeStyling(5);
 
     todo_is(markers.length, 0,
             'Bug 1166500: Animations running on the compositor in out of ' +
             'view element should never cause restyles');
-    div.remove(div);
+    div.remove();
   });
 
   add_task(function* no_restyling_main_thread_animations_out_of_view_element() {
     var div = addDiv(null,
       { style: 'animation: background-color 100s; transform: translateY(-400px);' });
     var animation = div.getAnimations()[0];
 
     yield animation.ready;
     var markers = yield observeStyling(5);
 
     todo_is(markers.length, 0,
             'Bug 1166500: Animations running on the main-thread in out of ' +
             'view element should never cause restyles');
-    div.remove(div);
+    div.remove();
   });
 
   /*
    Disabled for now since, on Android, the opacity animation runs on the
    compositor even if it is scrolled out of view.
    We will fix this in bug 1166500 or a follow-up bug
   add_task_if_omta_enabled(function* no_restyling_compositor_animations_in_scrolled_out_element() {
     var parentElement = addDiv(null,
@@ -244,17 +244,17 @@ waitForAllPaints(function() {
     var animation = div.getAnimations()[0];
 
     yield animation.ready;
     var markers = yield observeStyling(5);
 
     todo_is(markers.length, 0,
             'Bug 1166500: Animations running on the main-thread in elements ' +
             'which are scrolled out should never cause restyles');
-    parentElement.remove(div);
+    parentElement.remove();
   });
 
   /*
    Disabled for now since, on Android and B2G, the opacity animation runs on the
    compositor even if the associated element has visibility:hidden.
    We will fix this in bug 1237454 or a follow-up bug.
   add_task_if_omta_enabled(function* no_restyling_compositor_animations_in_visiblily_hidden_element() {
     var div = addDiv(null,
@@ -264,32 +264,32 @@ waitForAllPaints(function() {
     yield animation.ready;
     ok(!animation.isRunningOnCompositor);
 
     var markers = yield observeStyling(5);
 
     todo_is(markers.length, 0,
             'Bug 1237454: Animations running on the compositor in ' +
             'visibility hidden element should never cause restyles');
-    div.remove(div);
+    div.remove();
   });
   */
 
   add_task(function* no_restyling_main_thread_animations_in_visiblily_hidden_element() {
     var div = addDiv(null,
      { style: 'animation: background-color 100s; visibility: hidden' });
     var animation = div.getAnimations()[0];
 
     yield animation.ready;
     var markers = yield observeStyling(5);
 
     todo_is(markers.length, 0,
             'Bug 1237454: Animations running on the main-thread in ' +
             'visibility hidden element should never cause restyles');
-    div.remove(div);
+    div.remove();
   });
 
   add_task_if_omta_enabled(function* no_restyling_compositor_animations_after_pause_is_called() {
     var div = addDiv(null, { style: 'animation: opacity 100s' });
     var animation = div.getAnimations()[0];
 
     yield animation.ready;
     ok(animation.isRunningOnCompositor);
@@ -297,32 +297,47 @@ waitForAllPaints(function() {
     animation.pause();
 
     yield animation.ready;
 
     var markers = yield observeStyling(5);
     is(markers.length, 0,
        'Bug 1232563: Paused animations running on the compositor should ' +
        'never cause restyles once after pause() is called');
-    div.remove(div);
+    div.remove();
   });
 
-  add_task(function* no_restyling_matn_thread_animations_after_pause_is_called() {
+  add_task(function* no_restyling_main_thread_animations_after_pause_is_called() {
     var div = addDiv(null, { style: 'animation: background-color 100s' });
     var animation = div.getAnimations()[0];
 
     yield animation.ready;
 
     animation.pause();
 
     yield animation.ready;
 
     var markers = yield observeStyling(5);
     is(markers.length, 0,
        'Bug 1232563: Paused animations running on the main-thread should ' +
        'never cause restyles after pause() is called');
-    div.remove(div);
+    div.remove();
+  });
+
+  add_task_if_omta_enabled(function* only_one_restyling_when_current_time_is_set_to_middle_of_duration() {
+    var div = addDiv(null, { style: 'animation: opacity 100s' });
+    var animation = div.getAnimations()[0];
+
+    yield animation.ready;
+
+    animation.currentTime = 50000; // 50s
+
+    var markers = yield observeStyling(5);
+    is(markers.length, 1,
+       'Bug 1235478: Animations running on the compositor should only once ' +
+       'update style when currentTime is set to middle of duration time');
+    div.remove();
   });
 
 });
 
 </script>
 </body>
--- a/dom/base/DOMMatrix.cpp
+++ b/dom/base/DOMMatrix.cpp
@@ -262,31 +262,31 @@ template <typename T> void GetDataFromMa
   aData[13] = static_cast<T>(aMatrix->M42());
   aData[14] = static_cast<T>(aMatrix->M43());
   aData[15] = static_cast<T>(aMatrix->M44());
 }
 
 void
 DOMMatrixReadOnly::ToFloat32Array(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv) const
 {
-  nsAutoTArray<float, 16> arr;
+  AutoTArray<float, 16> arr;
   arr.SetLength(16);
   GetDataFromMatrix(this, arr.Elements());
   JS::Rooted<JS::Value> value(aCx);
   if (!ToJSValue(aCx, TypedArrayCreator<Float32Array>(arr), &value)) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
   aResult.set(&value.toObject());
 }
 
 void
 DOMMatrixReadOnly::ToFloat64Array(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv) const
 {
-  nsAutoTArray<double, 16> arr;
+  AutoTArray<double, 16> arr;
   arr.SetLength(16);
   GetDataFromMatrix(this, arr.Elements());
   JS::Rooted<JS::Value> value(aCx);
   if (!ToJSValue(aCx, TypedArrayCreator<Float64Array>(arr), &value)) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
   aResult.set(&value.toObject());
--- a/dom/base/File.cpp
+++ b/dom/base/File.cpp
@@ -254,17 +254,17 @@ Blob::ToFile()
   }
 
   return file.forget();
 }
 
 already_AddRefed<File>
 Blob::ToFile(const nsAString& aName, ErrorResult& aRv) const
 {
-  nsAutoTArray<RefPtr<BlobImpl>, 1> blobImpls;
+  AutoTArray<RefPtr<BlobImpl>, 1> blobImpls;
   blobImpls.AppendElement(mImpl);
 
   nsAutoString contentType;
   mImpl->GetType(contentType);
 
   RefPtr<MultipartBlobImpl> impl =
     MultipartBlobImpl::Create(blobImpls, aName, contentType, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -303,17 +303,17 @@ nsIContent::GetBaseURI(bool aTryUseXHRDo
   // Start with document base
   nsCOMPtr<nsIURI> base = doc->GetBaseURI(aTryUseXHRDocBaseURI);
 
   // Collect array of xml:base attribute values up the parent chain. This
   // is slightly slower for the case when there are xml:base attributes, but
   // faster for the far more common case of there not being any such
   // attributes.
   // Also check for SVG elements which require special handling
-  nsAutoTArray<nsString, 5> baseAttrs;
+  AutoTArray<nsString, 5> baseAttrs;
   nsString attr;
   const nsIContent *elem = this;
   do {
     // First check for SVG specialness (why is this SVG specific?)
     if (elem->IsSVGElement()) {
       nsIContent* bindingParent = elem->GetBindingParent();
       if (bindingParent) {
         nsXBLBinding* binding = bindingParent->GetXBLBinding();
@@ -1323,17 +1323,17 @@ public:
         SUBTREE_UNBINDINGS_PER_RUNNABLE) {
       sContentUnbinder->mLast->mNext = new ContentUnbinder();
       sContentUnbinder->mLast = sContentUnbinder->mLast->mNext;
     }
     sContentUnbinder->mLast->mSubtreeRoots.AppendElement(aSubtreeRoot);
   }
 
 private:
-  nsAutoTArray<nsCOMPtr<nsIContent>,
+  AutoTArray<nsCOMPtr<nsIContent>,
                SUBTREE_UNBINDINGS_PER_RUNNABLE> mSubtreeRoots;
   RefPtr<ContentUnbinder>                     mNext;
   ContentUnbinder*                              mLast;
   static ContentUnbinder*                       sContentUnbinder;
 };
 
 ContentUnbinder* ContentUnbinder::sContentUnbinder = nullptr;
 
@@ -1523,21 +1523,21 @@ FragmentOrElement::CanSkipInCC(nsINode* 
   }
 
   if (!gCCBlackMarkedNodes) {
     gCCBlackMarkedNodes = new nsTHashtable<nsPtrHashKey<nsINode> >(1020);
   }
 
   // nodesToUnpurple contains nodes which will be removed
   // from the purple buffer if the DOM tree is black.
-  nsAutoTArray<nsIContent*, 1020> nodesToUnpurple;
+  AutoTArray<nsIContent*, 1020> nodesToUnpurple;
   // grayNodes need script traverse, so they aren't removed from
   // the purple buffer, but are marked to be in black subtree so that
   // traverse is faster.
-  nsAutoTArray<nsINode*, 1020> grayNodes;
+  AutoTArray<nsINode*, 1020> grayNodes;
 
   bool foundBlack = root->IsBlack();
   if (root != currentDoc) {
     currentDoc = nullptr;
     if (NeedsScriptTraverse(root)) {
       grayNodes.AppendElement(root);
     } else if (static_cast<nsIContent*>(root)->IsPurple()) {
       nodesToUnpurple.AppendElement(static_cast<nsIContent*>(root));
@@ -1593,18 +1593,18 @@ FragmentOrElement::CanSkipInCC(nsINode* 
     // Can't remove currently handled purple node.
     if (purple != aNode) {
       purple->RemovePurple();
     }
   }
   return !NeedsScriptTraverse(aNode);
 }
 
-nsAutoTArray<nsINode*, 1020>* gPurpleRoots = nullptr;
-nsAutoTArray<nsIContent*, 1020>* gNodesToUnbind = nullptr;
+AutoTArray<nsINode*, 1020>* gPurpleRoots = nullptr;
+AutoTArray<nsIContent*, 1020>* gNodesToUnbind = nullptr;
 
 void ClearCycleCollectorCleanupData()
 {
   if (gPurpleRoots) {
     uint32_t len = gPurpleRoots->Length();
     for (uint32_t i = 0; i < len; ++i) {
       nsINode* n = gPurpleRoots->ElementAt(i);
       n->SetIsPurpleRoot(false);
@@ -1697,17 +1697,17 @@ FragmentOrElement::CanSkip(nsINode* aNod
   // Subtree has been traversed already, and aNode has
   // been handled in a way that doesn't require revisiting it.
   if (root->IsPurpleRoot()) {
     return false;
   }
 
   // nodesToClear contains nodes which are either purple or
   // gray.
-  nsAutoTArray<nsIContent*, 1020> nodesToClear;
+  AutoTArray<nsIContent*, 1020> nodesToClear;
 
   bool foundBlack = root->IsBlack();
   bool domOnlyCycle = false;
   if (root != currentDoc) {
     currentDoc = nullptr;
     if (!foundBlack) {
       domOnlyCycle = static_cast<nsIContent*>(root)->OwnedOnlyByTheDOMTree();
     }
@@ -1746,29 +1746,29 @@ FragmentOrElement::CanSkip(nsINode* aNod
       }
     }
   }
 
   if (!currentDoc || !foundBlack) {
     root->SetIsPurpleRoot(true);
     if (domOnlyCycle) {
       if (!gNodesToUnbind) {
-        gNodesToUnbind = new nsAutoTArray<nsIContent*, 1020>();
+        gNodesToUnbind = new AutoTArray<nsIContent*, 1020>();
       }
       gNodesToUnbind->AppendElement(static_cast<nsIContent*>(root));
       for (uint32_t i = 0; i < nodesToClear.Length(); ++i) {
         nsIContent* n = nodesToClear[i];
         if ((n != aNode || aRemovingAllowed) && n->IsPurple()) {
           n->RemovePurple();
         }
       }
       return true;
     } else {
       if (!gPurpleRoots) {
-        gPurpleRoots = new nsAutoTArray<nsINode*, 1020>();
+        gPurpleRoots = new AutoTArray<nsINode*, 1020>();
       }
       gPurpleRoots->AppendElement(root);
     }
   }
 
   if (!foundBlack) {
     return false;
   }
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -866,17 +866,17 @@ Navigator::RemoveIdleObserver(MozIdleObs
   if (NS_FAILED(mWindow->UnregisterIdleObserver(obs))) {
     NS_WARNING("Failed to remove idle observer.");
   }
 }
 
 bool
 Navigator::Vibrate(uint32_t aDuration)
 {
-  nsAutoTArray<uint32_t, 1> pattern;
+  AutoTArray<uint32_t, 1> pattern;
   pattern.AppendElement(aDuration);
   return Vibrate(pattern);
 }
 
 bool
 Navigator::Vibrate(const nsTArray<uint32_t>& aPattern)
 {
   if (!mWindow) {
--- a/dom/base/nsContentIterator.cpp
+++ b/dom/base/nsContentIterator.cpp
@@ -150,17 +150,17 @@ protected:
   virtual void LastRelease();
 
   nsCOMPtr<nsINode> mCurNode;
   nsCOMPtr<nsINode> mFirst;
   nsCOMPtr<nsINode> mLast;
   nsCOMPtr<nsINode> mCommonParent;
 
   // used by nsContentIterator to cache indices
-  nsAutoTArray<int32_t, 8> mIndexes;
+  AutoTArray<int32_t, 8> mIndexes;
 
   // used by nsSubtreeIterator to cache indices.  Why put them in the base
   // class?  Because otherwise I have to duplicate the routines GetNextSibling
   // etc across both classes, with slight variations for caching.  Or
   // alternately, create a base class for the cache itself and have all the
   // cache manipulation go through a vptr.  I think this is the best space and
   // speed combo, even though it's ugly.
   int32_t mCachedIndex;
@@ -1053,18 +1053,18 @@ nsContentIterator::PositionAt(nsINode* a
                                           firstNode, firstOffset,
                                           lastNode, lastOffset)))) {
     mIsDone = true;
     return NS_ERROR_FAILURE;
   }
 
   // We can be at ANY node in the sequence.  Need to regenerate the array of
   // indexes back to the root or common parent!
-  nsAutoTArray<nsINode*, 8>     oldParentStack;
-  nsAutoTArray<int32_t, 8>      newIndexes;
+  AutoTArray<nsINode*, 8>     oldParentStack;
+  AutoTArray<int32_t, 8>      newIndexes;
 
   // Get a list of the parents up to the root, then compare the new node with
   // entries in that array until we find a match (lowest common ancestor).  If
   // no match, use IndexOf, take the parent, and repeat.  This avoids using
   // IndexOf() N times on possibly large arrays.  We still end up doing it a
   // fair bit.  It's better to use Clone() if possible.
 
   // we know the depth we're down (though we may not have started at the top).
@@ -1208,18 +1208,18 @@ protected:
   nsContentSubtreeIterator(const nsContentSubtreeIterator&);
   nsContentSubtreeIterator& operator=(const nsContentSubtreeIterator&);
 
   virtual void LastRelease() override;
 
   RefPtr<nsRange> mRange;
 
   // these arrays all typically are used and have elements
-  nsAutoTArray<nsIContent*, 8> mEndNodes;
-  nsAutoTArray<int32_t, 8>     mEndOffsets;
+  AutoTArray<nsIContent*, 8> mEndNodes;
+  AutoTArray<int32_t, 8>     mEndOffsets;
 };
 
 NS_IMPL_ADDREF_INHERITED(nsContentSubtreeIterator, nsContentIterator)
 NS_IMPL_RELEASE_INHERITED(nsContentSubtreeIterator, nsContentIterator)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsContentSubtreeIterator)
 NS_INTERFACE_MAP_END_INHERITING(nsContentIterator)
 
--- a/dom/base/nsContentList.cpp
+++ b/dom/base/nsContentList.cpp
@@ -543,17 +543,17 @@ void
 nsContentList::GetSupportedNames(unsigned aFlags, nsTArray<nsString>& aNames)
 {
   if (!(aFlags & JSITER_HIDDEN)) {
     return;
   }
 
   BringSelfUpToDate(true);
 
-  nsAutoTArray<nsIAtom*, 8> atoms;
+  AutoTArray<nsIAtom*, 8> atoms;
   for (uint32_t i = 0; i < mElements.Length(); ++i) {
     nsIContent *content = mElements.ElementAt(i);
     if (content->HasID()) {
       nsIAtom* id = content->GetID();
       MOZ_ASSERT(id != nsGkAtoms::_empty,
                  "Empty ids don't get atomized");
       if (!atoms.Contains(id)) {
         atoms.AppendElement(id);
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -2281,17 +2281,17 @@ nsINode*
 nsContentUtils::GetCommonAncestor(nsINode* aNode1,
                                   nsINode* aNode2)
 {
   if (aNode1 == aNode2) {
     return aNode1;
   }
 
   // Build the chain of parents
-  nsAutoTArray<nsINode*, 30> parents1, parents2;
+  AutoTArray<nsINode*, 30> parents1, parents2;
   do {
     parents1.AppendElement(aNode1);
     aNode1 = aNode1->GetParentNode();
   } while (aNode1);
   do {
     parents2.AppendElement(aNode2);
     aNode2 = aNode2->GetParentNode();
   } while (aNode2);
@@ -2330,17 +2330,17 @@ nsContentUtils::ComparePoints(nsINode* a
                               bool* aDisconnected)
 {
   if (aParent1 == aParent2) {
     return aOffset1 < aOffset2 ? -1 :
            aOffset1 > aOffset2 ? 1 :
            0;
   }
 
-  nsAutoTArray<nsINode*, 32> parents1, parents2;
+  AutoTArray<nsINode*, 32> parents1, parents2;
   nsINode* node1 = aParent1;
   nsINode* node2 = aParent2;
   do {
     parents1.AppendElement(node1);
     node1 = node1->GetParentNode();
   } while (node1);
   do {
     parents2.AppendElement(node2);
@@ -4282,17 +4282,17 @@ nsContentUtils::CreateContextualFragment
                               (document->GetCompatibilityMode() ==
                                eCompatibility_NavQuirks),
                               aPreventScriptExecution);
     }
 
     return frag.forget();
   }
 
-  nsAutoTArray<nsString, 32> tagStack;
+  AutoTArray<nsString, 32> tagStack;
   nsAutoString uriStr, nameStr;
   nsCOMPtr<nsIContent> content = do_QueryInterface(aContextNode);
   // just in case we have a text node
   if (content && !content->IsElement())
     content = content->GetParent();
 
   while (content && content->IsElement()) {
     nsString& tagName = *tagStack.AppendElement();
@@ -6848,17 +6848,17 @@ void
 nsContentUtils::FireMutationEventsForDirectParsing(nsIDocument* aDoc,
                                                    nsIContent* aDest,
                                                    int32_t aOldChildCount)
 {
   // Fire mutation events. Optimize for the case when there are no listeners
   int32_t newChildCount = aDest->GetChildCount();
   if (newChildCount && nsContentUtils::
         HasMutationListeners(aDoc, NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
-    nsAutoTArray<nsCOMPtr<nsIContent>, 50> childNodes;
+    AutoTArray<nsCOMPtr<nsIContent>, 50> childNodes;
     NS_ASSERTION(newChildCount - aOldChildCount >= 0,
                  "What, some unexpected dom mutation has happened?");
     childNodes.SetCapacity(newChildCount - aOldChildCount);
     for (nsIContent* child = aDest->GetFirstChild();
          child;
          child = child->GetNextSibling()) {
       childNodes.AppendElement(child);
     }
@@ -7915,17 +7915,17 @@ nsContentUtils::FirePageHideEvent(nsIDoc
                                   EventTarget* aChromeEventHandler)
 {
   nsCOMPtr<nsIDocument> doc = aItem->GetDocument();
   NS_ASSERTION(doc, "What happened here?");
   doc->OnPageHide(true, aChromeEventHandler);
 
   int32_t childCount = 0;
   aItem->GetChildCount(&childCount);
-  nsAutoTArray<nsCOMPtr<nsIDocShellTreeItem>, 8> kids;
+  AutoTArray<nsCOMPtr<nsIDocShellTreeItem>, 8> kids;
   kids.AppendElements(childCount);
   for (int32_t i = 0; i < childCount; ++i) {
     aItem->GetChildAt(i, getter_AddRefs(kids[i]));
   }
 
   for (uint32_t i = 0; i < kids.Length(); ++i) {
     if (kids[i]) {
       FirePageHideEvent(kids[i], aChromeEventHandler);
@@ -7940,17 +7940,17 @@ nsContentUtils::FirePageHideEvent(nsIDoc
 /* static */
 void
 nsContentUtils::FirePageShowEvent(nsIDocShellTreeItem* aItem,
                                   EventTarget* aChromeEventHandler,
                                   bool aFireIfShowing)
 {
   int32_t childCount = 0;
   aItem->GetChildCount(&childCount);
-  nsAutoTArray<nsCOMPtr<nsIDocShellTreeItem>, 8> kids;
+  AutoTArray<nsCOMPtr<nsIDocShellTreeItem>, 8> kids;
   kids.AppendElements(childCount);
   for (int32_t i = 0; i < childCount; ++i) {
     aItem->GetChildAt(i, getter_AddRefs(kids[i]));
   }
 
   for (uint32_t i = 0; i < kids.Length(); ++i) {
     if (kids[i]) {
       FirePageShowEvent(kids[i], aChromeEventHandler, aFireIfShowing);
@@ -8529,17 +8529,17 @@ private:
           default:
             aOut.Append(c);
             break;
         }
       }
     }
   }
 
-  nsAutoTArray<Unit, STRING_BUFFER_UNITS> mUnits;
+  AutoTArray<Unit, STRING_BUFFER_UNITS> mUnits;
   nsAutoPtr<StringBuilder>                mNext;
   StringBuilder*                          mLast;
   // mLength is used only in the first StringBuilder object in the linked list.
   uint32_t                                mLength;
 };
 
 } // namespace
 
--- a/dom/base/nsDOMMutationObserver.cpp
+++ b/dom/base/nsDOMMutationObserver.cpp
@@ -17,25 +17,25 @@
 #include "nsIScriptGlobalObject.h"
 #include "nsServiceManagerUtils.h"
 #include "nsTextFragment.h"
 #include "nsThreadUtils.h"
 
 using mozilla::dom::TreeOrderComparator;
 using mozilla::dom::Animation;
 
-nsAutoTArray<RefPtr<nsDOMMutationObserver>, 4>*
+AutoTArray<RefPtr<nsDOMMutationObserver>, 4>*
   nsDOMMutationObserver::sScheduledMutationObservers = nullptr;
 
 nsDOMMutationObserver* nsDOMMutationObserver::sCurrentObserver = nullptr;
 
 uint32_t nsDOMMutationObserver::sMutationLevel = 0;
 uint64_t nsDOMMutationObserver::sCount = 0;
 
-nsAutoTArray<nsAutoTArray<RefPtr<nsDOMMutationObserver>, 4>, 4>*
+AutoTArray<AutoTArray<RefPtr<nsDOMMutationObserver>, 4>, 4>*
 nsDOMMutationObserver::sCurrentlyHandlingObservers = nullptr;
 
 nsINodeList*
 nsDOMMutationRecord::AddedNodes()
 {
   if (!mAddedNodes) {
     mAddedNodes = new nsSimpleContentList(mTarget);
   }
@@ -580,17 +580,17 @@ nsDOMMutationObserver::ScheduleForRun()
   mWaitingForRun = true;
   RescheduleForRun();
 }
 
 void
 nsDOMMutationObserver::RescheduleForRun()
 {
   if (!sScheduledMutationObservers) {
-    sScheduledMutationObservers = new nsAutoTArray<RefPtr<nsDOMMutationObserver>, 4>;
+    sScheduledMutationObservers = new AutoTArray<RefPtr<nsDOMMutationObserver>, 4>;
   }
 
   bool didInsert = false;
   for (uint32_t i = 0; i < sScheduledMutationObservers->Length(); ++i) {
     if (static_cast<nsDOMMutationObserver*>((*sScheduledMutationObservers)[i])
           ->mId > mId) {
       sScheduledMutationObservers->InsertElementAt(i, this);
       didInsert = true;
@@ -877,17 +877,17 @@ nsDOMMutationObserver::HandleMutationsIn
     // This does *not* catch all cases, but should work for stuff running
     // in separate tabs.
     return;
   }
 
   nsTArray<RefPtr<nsDOMMutationObserver> >* suppressedObservers = nullptr;
 
   while (sScheduledMutationObservers) {
-    nsAutoTArray<RefPtr<nsDOMMutationObserver>, 4>* observers =
+    AutoTArray<RefPtr<nsDOMMutationObserver>, 4>* observers =
       sScheduledMutationObservers;
     sScheduledMutationObservers = nullptr;
     for (uint32_t i = 0; i < observers->Length(); ++i) {
       sCurrentObserver = static_cast<nsDOMMutationObserver*>((*observers)[i]);
       if (!sCurrentObserver->Suppressed()) {
         sCurrentObserver->HandleMutation();
       } else {
         if (!suppressedObservers) {
@@ -990,17 +990,17 @@ nsDOMMutationObserver::AddCurrentlyHandl
   if (aMutationLevel > 1) {
     // MutationObserver must be in the currently handling observer list
     // in all the nested levels.
     AddCurrentlyHandlingObserver(aObserver, aMutationLevel - 1);
   }
 
   if (!sCurrentlyHandlingObservers) {
     sCurrentlyHandlingObservers =
-      new nsAutoTArray<nsAutoTArray<RefPtr<nsDOMMutationObserver>, 4>, 4>;
+      new AutoTArray<AutoTArray<RefPtr<nsDOMMutationObserver>, 4>, 4>;
   }
 
   while (sCurrentlyHandlingObservers->Length() < aMutationLevel) {
     sCurrentlyHandlingObservers->InsertElementAt(
       sCurrentlyHandlingObservers->Length());
   }
 
   uint32_t index = aMutationLevel - 1;
--- a/dom/base/nsDOMMutationObserver.h
+++ b/dom/base/nsDOMMutationObserver.h
@@ -600,37 +600,37 @@ protected:
                                            uint32_t aMutationLevel);
 
   nsCOMPtr<nsPIDOMWindowInner>                       mOwner;
 
   nsCOMArray<nsMutationReceiver>                     mReceivers;
   nsClassHashtable<nsISupportsHashKey,
                    nsCOMArray<nsMutationReceiver> >  mTransientReceivers;
   // MutationRecords which are being constructed.
-  nsAutoTArray<nsDOMMutationRecord*, 4>              mCurrentMutations;
+  AutoTArray<nsDOMMutationRecord*, 4>              mCurrentMutations;
   // MutationRecords which will be handed to the callback at the end of
   // the microtask.
   RefPtr<nsDOMMutationRecord>                      mFirstPendingMutation;
   nsDOMMutationRecord*                               mLastPendingMutation;
   uint32_t                                           mPendingMutationCount;
 
   RefPtr<mozilla::dom::MutationCallback>           mCallback;
 
   bool                                               mWaitingForRun;
   bool                                               mIsChrome;
   bool                                               mMergeAttributeRecords;
 
   uint64_t                                           mId;
 
   static uint64_t                                    sCount;
-  static nsAutoTArray<RefPtr<nsDOMMutationObserver>, 4>* sScheduledMutationObservers;
+  static AutoTArray<RefPtr<nsDOMMutationObserver>, 4>* sScheduledMutationObservers;
   static nsDOMMutationObserver*                      sCurrentObserver;
 
   static uint32_t                                    sMutationLevel;
-  static nsAutoTArray<nsAutoTArray<RefPtr<nsDOMMutationObserver>, 4>, 4>*
+  static AutoTArray<AutoTArray<RefPtr<nsDOMMutationObserver>, 4>, 4>*
                                                      sCurrentlyHandlingObservers;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsDOMMutationObserver, NS_DOM_MUTATION_OBSERVER_IID)
 
 class nsAutoMutationBatch
 {
 public:
@@ -735,17 +735,17 @@ private:
   struct BatchObserver
   {
     nsDOMMutationObserver* mObserver;
     bool                   mWantsChildList;
   };
   
   static nsAutoMutationBatch* sCurrentBatch;
   nsAutoMutationBatch* mPreviousBatch;
-  nsAutoTArray<BatchObserver, 2> mObservers;
+  AutoTArray<BatchObserver, 2> mObservers;
   nsTArray<nsCOMPtr<nsIContent> > mRemovedNodes;
   nsTArray<nsCOMPtr<nsIContent> > mAddedNodes;
   nsINode* mBatchTarget;
   bool mRemovalDone;
   bool mFromFirstToLast;
   bool mAllowNestedBatches;
   nsCOMPtr<nsINode> mPrevSibling;
   nsCOMPtr<nsINode> mNextSibling;
@@ -902,17 +902,17 @@ private:
   struct Entry
   {
     RefPtr<mozilla::dom::Animation> mAnimation;
     State mState;
     bool mChanged;
   };
 
   static nsAutoAnimationMutationBatch* sCurrentBatch;
-  nsAutoTArray<nsDOMMutationObserver*, 2> mObservers;
+  AutoTArray<nsDOMMutationObserver*, 2> mObservers;
   typedef nsTArray<Entry> EntryArray;
   nsClassHashtable<nsPtrHashKey<nsINode>, EntryArray> mEntryTable;
   // List of nodes referred to by mEntryTable so we can sort them
   nsTArray<nsINode*> mBatchTargets;
 };
 
 inline
 nsDOMMutationObserver*
--- a/dom/base/nsDOMTokenList.cpp
+++ b/dom/base/nsDOMTokenList.cpp
@@ -129,17 +129,17 @@ nsDOMTokenList::AddInternal(const nsAttr
 
   nsAutoString resultStr;
 
   if (aAttr) {
     aAttr->ToString(resultStr);
   }
 
   bool oneWasAdded = false;
-  nsAutoTArray<nsString, 10> addedClasses;
+  AutoTArray<nsString, 10> addedClasses;
 
   for (uint32_t i = 0, l = aTokens.Length(); i < l; ++i) {
     const nsString& aToken = aTokens[i];
 
     if ((aAttr && aAttr->Contains(aToken)) ||
         addedClasses.Contains(aToken)) {
       continue;
     }
@@ -170,17 +170,17 @@ nsDOMTokenList::Add(const nsTArray<nsStr
 
   const nsAttrValue* attr = GetParsedAttr();
   AddInternal(attr, aTokens);
 }
 
 void
 nsDOMTokenList::Add(const nsAString& aToken, mozilla::ErrorResult& aError)
 {
-  nsAutoTArray<nsString, 1> tokens;
+  AutoTArray<nsString, 1> tokens;
   tokens.AppendElement(aToken);
   Add(tokens, aError);
 }
 
 void
 nsDOMTokenList::RemoveInternal(const nsAttrValue* aAttr,
                                const nsTArray<nsString>& aTokens)
 {
@@ -256,17 +256,17 @@ nsDOMTokenList::Remove(const nsTArray<ns
   }
 
   RemoveInternal(attr, aTokens);
 }
 
 void
 nsDOMTokenList::Remove(const nsAString& aToken, mozilla::ErrorResult& aError)
 {
-  nsAutoTArray<nsString, 1> tokens;
+  AutoTArray<nsString, 1> tokens;
   tokens.AppendElement(aToken);
   Remove(tokens, aError);
 }
 
 bool
 nsDOMTokenList::Toggle(const nsAString& aToken,
                        const Optional<bool>& aForce,
                        ErrorResult& aError)
@@ -276,17 +276,17 @@ nsDOMTokenList::Toggle(const nsAString& 
     return false;
   }
 
   const nsAttrValue* attr = GetParsedAttr();
   const bool forceOn = aForce.WasPassed() && aForce.Value();
   const bool forceOff = aForce.WasPassed() && !aForce.Value();
 
   bool isPresent = attr && attr->Contains(aToken);
-  nsAutoTArray<nsString, 1> tokens;
+  AutoTArray<nsString, 1> tokens;
   (*tokens.AppendElement()).Rebind(aToken.Data(), aToken.Length());
 
   if (isPresent) {
     if (!forceOn) {
       RemoveInternal(attr, tokens);
       isPresent = false;
     }
   } else {
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -3289,17 +3289,17 @@ nsIDocument::ElementsFromPoint(float aX,
   ElementsFromPointHelper(aX, aY, nsIDocument::FLUSH_LAYOUT, aElements);
 }
 
 Element*
 nsDocument::ElementFromPointHelper(float aX, float aY,
                                    bool aIgnoreRootScrollFrame,
                                    bool aFlushLayout)
 {
-  nsAutoTArray<RefPtr<Element>, 1> elementArray;
+  AutoTArray<RefPtr<Element>, 1> elementArray;
   ElementsFromPointHelper(aX, aY,
                           ((aIgnoreRootScrollFrame ? nsIDocument::IGNORE_ROOT_SCROLL_FRAME : 0) |
                            (aFlushLayout ? nsIDocument::FLUSH_LAYOUT : 0) |
                            nsIDocument::IS_ELEMENT_FROM_POINT),
                           elementArray);
   if (elementArray.IsEmpty()) {
     return nullptr;
   }
@@ -3411,17 +3411,17 @@ nsDocument::NodesFromRectHelper(float aX
   nsIPresShell *ps = GetShell();
   NS_ENSURE_STATE(ps);
   nsIFrame *rootFrame = ps->GetRootFrame();
 
   // XUL docs, unlike HTML, have no frame tree until everything's done loading
   if (!rootFrame)
     return NS_OK; // return nothing to premature XUL callers as a reminder to wait
 
-  nsAutoTArray<nsIFrame*,8> outFrames;
+  AutoTArray<nsIFrame*,8> outFrames;
   nsLayoutUtils::GetFramesForArea(rootFrame, rect, outFrames,
     nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC |
     (aIgnoreRootScrollFrame ? nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME : 0));
 
   // Used to filter out repeated elements in sequence.
   nsIContent* lastAdded = nullptr;
 
   for (uint32_t i = 0; i < outFrames.Length(); i++) {
@@ -8802,19 +8802,21 @@ nsDocument::CanSavePresentation(nsIReque
       bool canCache = subdoc ? subdoc->CanSavePresentation(nullptr) : false;
       if (!canCache) {
         return false;
       }
     }
   }
 
 #ifdef MOZ_WEBSPEECH
-  auto* globalWindow = nsGlobalWindow::Cast(win);
-  if (globalWindow->HasActiveSpeechSynthesis()) {
-    return false;
+  if (win) {
+    auto* globalWindow = nsGlobalWindow::Cast(win);
+    if (globalWindow->HasActiveSpeechSynthesis()) {
+      return false;
+    }
   }
 #endif
 
   return true;
 }
 
 void
 nsDocument::Destroy()
@@ -11233,17 +11235,17 @@ nsDocument::RestorePreviousFullScreenSta
   NS_ASSERTION(!IsFullScreenDoc() || !FullscreenRoots::IsEmpty(),
     "Should have at least 1 fullscreen root when fullscreen!");
 
   if (!IsFullScreenDoc() || !GetWindow() || FullscreenRoots::IsEmpty()) {
     return;
   }
 
   nsCOMPtr<nsIDocument> fullScreenDoc = GetFullscreenLeaf(this);
-  nsAutoTArray<nsDocument*, 8> exitDocs;
+  AutoTArray<nsDocument*, 8> exitDocs;
 
   nsIDocument* doc = fullScreenDoc;
   // Collect all subdocuments.
   for (; doc != this; doc = doc->GetParentDocument()) {
     exitDocs.AppendElement(static_cast<nsDocument*>(doc));
   }
   MOZ_ASSERT(doc == this, "Must have reached this doc");
   // Collect all ancestor documents which we are going to change.
@@ -11850,17 +11852,17 @@ nsDocument::ApplyFullscreen(const Fullsc
   // to detect if the origin which is fullscreen has changed.
   nsCOMPtr<nsIDocument> previousFullscreenDoc = GetFullscreenLeaf(this);
 
   // Stores a list of documents which we must dispatch "mozfullscreenchange"
   // too. We're required by the spec to dispatch the events in root-to-leaf
   // order, but we traverse the doctree in a leaf-to-root order, so we save
   // references to the documents we must dispatch to so that we get the order
   // as specified.
-  nsAutoTArray<nsIDocument*, 8> changed;
+  AutoTArray<nsIDocument*, 8> changed;
 
   // Remember the root document, so that if a full-screen document is hidden
   // we can reset full-screen state in the remaining visible full-screen documents.
   nsIDocument* fullScreenRootDoc = nsContentUtils::GetRootDocument(this);
 
   // If a document is already in fullscreen, then unlock the mouse pointer
   // before setting a new document to fullscreen
   UnlockPointer();
--- a/dom/base/nsDocumentEncoder.cpp
+++ b/dom/base/nsDocumentEncoder.cpp
@@ -157,21 +157,21 @@ protected:
   nsString          mMimeType;
   nsCString         mCharset;
   uint32_t          mFlags;
   uint32_t          mWrapColumn;
   uint32_t          mStartDepth;
   uint32_t          mEndDepth;
   int32_t           mStartRootIndex;
   int32_t           mEndRootIndex;
-  nsAutoTArray<nsINode*, 8>    mCommonAncestors;
-  nsAutoTArray<nsIContent*, 8> mStartNodes;
-  nsAutoTArray<int32_t, 8>     mStartOffsets;
-  nsAutoTArray<nsIContent*, 8> mEndNodes;
-  nsAutoTArray<int32_t, 8>     mEndOffsets;
+  AutoTArray<nsINode*, 8>    mCommonAncestors;
+  AutoTArray<nsIContent*, 8> mStartNodes;
+  AutoTArray<int32_t, 8>     mStartOffsets;
+  AutoTArray<nsIContent*, 8> mEndNodes;
+  AutoTArray<int32_t, 8>     mEndOffsets;
   bool              mHaltRangeHint;  
   // Used when context has already been serialized for
   // table cell selections (where parent is <tr>)
   bool              mDisableContextSerialize;
   bool              mIsCopying;  // Set to true only while copying
   bool              mNodeIsContainer;
   nsStringBuffer*   mCachedBuffer;
 };
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -1365,17 +1365,17 @@ nsFocusManager::GetCommonAncestor(nsPIDO
   NS_ENSURE_TRUE(aWindow1 && aWindow2, nullptr);
 
   nsCOMPtr<nsIDocShellTreeItem> dsti1 = aWindow1->GetDocShell();
   NS_ENSURE_TRUE(dsti1, nullptr);
 
   nsCOMPtr<nsIDocShellTreeItem> dsti2 = aWindow2->GetDocShell();
   NS_ENSURE_TRUE(dsti2, nullptr);
 
-  nsAutoTArray<nsIDocShellTreeItem*, 30> parents1, parents2;
+  AutoTArray<nsIDocShellTreeItem*, 30> parents1, parents2;
   do {
     parents1.AppendElement(dsti1);
     nsCOMPtr<nsIDocShellTreeItem> parentDsti1;
     dsti1->GetParent(getter_AddRefs(parentDsti1));
     dsti1.swap(parentDsti1);
   } while (dsti1);
   do {
     parents2.AppendElement(dsti2);
--- a/dom/base/nsFrameMessageManager.h
+++ b/dom/base/nsFrameMessageManager.h
@@ -394,17 +394,17 @@ protected:
                                     bool aRunInGlobalScope,
                                     bool aShouldCache,
                                     JS::MutableHandle<JSScript*> aScriptp);
   void TryCacheLoadAndCompileScript(const nsAString& aURL,
                                     bool aRunInGlobalScope);
   bool InitChildGlobalInternal(nsISupports* aScope, const nsACString& aID);
   nsCOMPtr<nsIXPConnectJSObjectHolder> mGlobal;
   nsCOMPtr<nsIPrincipal> mPrincipal;
-  nsAutoTArray<JS::Heap<JSObject*>, 2> mAnonymousGlobalScopes;
+  AutoTArray<JS::Heap<JSObject*>, 2> mAnonymousGlobalScopes;
 
   static nsDataHashtable<nsStringHashKey, nsMessageManagerScriptHolder*>* sCachedScripts;
   static nsScriptCacheCleaner* sScriptCacheCleaner;
 };
 
 class nsScriptCacheCleaner final : public nsIObserver
 {
   ~nsScriptCacheCleaner() {}
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -926,16 +926,20 @@ GK_ATOM(ontransitionend, "ontransitionen
 GK_ATOM(onunderflow, "onunderflow")
 GK_ATOM(onunload, "onunload")
 GK_ATOM(onupdatefound, "onupdatefound")
 GK_ATOM(onupdateready, "onupdateready")
 GK_ATOM(onupgradeneeded, "onupgradeneeded")
 GK_ATOM(onussdreceived, "onussdreceived")
 GK_ATOM(onversionchange, "onversionchange")
 GK_ATOM(onvoicechange, "onvoicechange")
+GK_ATOM(onwebkitAnimationEnd, "onwebkitAnimationEnd")
+GK_ATOM(onwebkitAnimationIteration, "onwebkitAnimationIteration")
+GK_ATOM(onwebkitAnimationStart, "onwebkitAnimationStart")
+GK_ATOM(onwebkitTransitionEnd, "onwebkitTransitionEnd")
 GK_ATOM(onwheel, "onwheel")
 GK_ATOM(open, "open")
 GK_ATOM(optgroup, "optgroup")
 GK_ATOM(optimum, "optimum")
 GK_ATOM(option, "option")
 GK_ATOM(_or, "or")
 GK_ATOM(order, "order")
 GK_ATOM(ordinal, "ordinal")
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -1825,17 +1825,17 @@ public:
       MOZ_ASSERT(aObserver, "Must have observer");
       mObservers.AppendElement(aObserver);
     }
 
     const nsTArray< nsCOMPtr<nsIObserver> > & Observers() {
       return mObservers;
     }
   protected:
-    nsAutoTArray< nsCOMPtr<nsIObserver>, 8 > mObservers;
+    AutoTArray< nsCOMPtr<nsIObserver>, 8 > mObservers;
   };
 
   /**
    * Request an external resource document for aURI.  This will return the
    * resource document if available.  If one is not available yet, it will
    * start loading as needed, and the pending load object will be returned in
    * aPendingLoad so that the caller can register an observer to wait for the
    * load.  If this function returns null and doesn't return a pending load,
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -590,17 +590,17 @@ nsINode::RemoveChild(nsIDOMNode* aOldChi
   }
   return rv.StealNSResult();
 }
 
 void
 nsINode::Normalize()
 {
   // First collect list of nodes to be removed
-  nsAutoTArray<nsCOMPtr<nsIContent>, 50> nodes;
+  AutoTArray<nsCOMPtr<nsIContent>, 50> nodes;
 
   bool canMerge = false;
   for (nsIContent* node = this->GetFirstChild();
        node;
        node = node->GetNextNode(this)) {
     if (node->NodeType() != nsIDOMNode::TEXT_NODE) {
       canMerge = false;
       continue;
@@ -859,17 +859,17 @@ nsINode::CompareDocumentPosition(nsINode
     MOZ_ASSERT(GetParentNode() == aOtherNode.GetParentNode());
     return static_cast<uint16_t>(nsIDOMNode::DOCUMENT_POSITION_PRECEDING);
   }
   if (GetNextSibling() == &aOtherNode) {
     MOZ_ASSERT(GetParentNode() == aOtherNode.GetParentNode());
     return static_cast<uint16_t>(nsIDOMNode::DOCUMENT_POSITION_FOLLOWING);
   }
 
-  nsAutoTArray<const nsINode*, 32> parents1, parents2;
+  AutoTArray<const nsINode*, 32> parents1, parents2;
 
   const nsINode *node1 = &aOtherNode, *node2 = this;
 
   // Check if either node is an attribute
   const Attr* attr1 = nullptr;
   if (node1->IsNodeOfType(nsINode::eATTRIBUTE)) {
     attr1 = static_cast<const Attr*>(node1);
     const Element* elem = attr1->GetElement();
@@ -1987,17 +1987,17 @@ nsINode::ReplaceOrInsertBefore(bool aRep
     nodeToInsertBefore = aRefChild;
   }
   if (nodeToInsertBefore == aNewChild) {
     // We're going to remove aNewChild from its parent, so use its next sibling
     // as the node to insert before.
     nodeToInsertBefore = nodeToInsertBefore->GetNextSibling();
   }
 
-  Maybe<nsAutoTArray<nsCOMPtr<nsIContent>, 50> > fragChildren;
+  Maybe<AutoTArray<nsCOMPtr<nsIContent>, 50> > fragChildren;
 
   // Remove the new child from the old parent if one exists
   nsIContent* newContent = aNewChild->AsContent();
   nsCOMPtr<nsINode> oldParent = newContent->GetParentNode();
   if (oldParent) {
     int32_t removeIndex = oldParent->IndexOf(newContent);
     if (removeIndex < 0) {
       // newContent is anonymous.  We can't deal with this, so just bail
@@ -2697,17 +2697,17 @@ nsINode::QuerySelector(const nsAString& 
 
 already_AddRefed<nsINodeList>
 nsINode::QuerySelectorAll(const nsAString& aSelector, ErrorResult& aResult)
 {
   RefPtr<nsSimpleContentList> contentList = new nsSimpleContentList(this);
 
   nsCSSSelectorList* selectorList = ParseSelectorList(aSelector, aResult);
   if (selectorList) {
-    FindMatchingElements<false, nsAutoTArray<Element*, 128>>(this,
+    FindMatchingElements<false, AutoTArray<Element*, 128>>(this,
                                                              selectorList,
                                                              *contentList,
                                                              aResult);
   } else {
     // Either we failed (and aResult already has the exception), or this
     // is a pseudo-element-only selector that matches nothing.
   }
 
--- a/dom/base/nsLineBreaker.cpp
+++ b/dom/base/nsLineBreaker.cpp
@@ -54,17 +54,17 @@ SetupCapitalization(const char16_t* aWor
     }
   }
 }
 
 nsresult
 nsLineBreaker::FlushCurrentWord()
 {
   uint32_t length = mCurrentWord.Length();
-  nsAutoTArray<uint8_t,4000> breakState;
+  AutoTArray<uint8_t,4000> breakState;
   if (!breakState.AppendElements(length))
     return NS_ERROR_OUT_OF_MEMORY;
   
   nsTArray<bool> capitalizationState;
 
   if (!mCurrentWordContainsComplexChar) {
     // For break-strict set everything internal to "break", otherwise
     // to "no break"!
@@ -182,17 +182,17 @@ nsLineBreaker::AppendText(nsIAtom* aHyph
       return NS_OK;
 
     // We encountered whitespace, so we're done with this word
     nsresult rv = FlushCurrentWord();
     if (NS_FAILED(rv))
       return rv;
   }
 
-  nsAutoTArray<uint8_t,4000> breakState;
+  AutoTArray<uint8_t,4000> breakState;
   if (aSink) {
     if (!breakState.AppendElements(aLength))
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   bool noCapitalizationNeeded = true;
   nsTArray<bool> capitalizationState;
   if (aSink && (aFlags & BREAK_NEED_CAPITALIZATION)) {
@@ -308,17 +308,17 @@ nsLineBreaker::AppendText(nsIAtom* aHyph
 
 void
 nsLineBreaker::FindHyphenationPoints(nsHyphenator *aHyphenator,
                                      const char16_t *aTextStart,
                                      const char16_t *aTextLimit,
                                      uint8_t *aBreakState)
 {
   nsDependentSubstring string(aTextStart, aTextLimit);
-  AutoFallibleTArray<bool,200> hyphens;
+  AutoTArray<bool,200> hyphens;
   if (NS_SUCCEEDED(aHyphenator->Hyphenate(string, hyphens))) {
     for (uint32_t i = 0; i + 1 < string.Length(); ++i) {
       if (hyphens[i]) {
         aBreakState[i + 1] =
           gfxTextRun::CompressedGlyph::FLAG_BREAK_TYPE_HYPHEN;
       }
     }
   }
@@ -363,17 +363,17 @@ nsLineBreaker::AppendText(nsIAtom* aHyph
     }
 
     // We encountered whitespace, so we're done with this word
     nsresult rv = FlushCurrentWord();
     if (NS_FAILED(rv))
       return rv;
   }
 
-  nsAutoTArray<uint8_t,4000> breakState;
+  AutoTArray<uint8_t,4000> breakState;
   if (aSink) {
     if (!breakState.AppendElements(aLength))
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   uint32_t start = offset;
   bool noBreaksNeeded = !aSink ||
     ((aFlags & NO_BREAKS_NEEDED_FLAGS) == NO_BREAKS_NEEDED_FLAGS &&
--- a/dom/base/nsLineBreaker.h
+++ b/dom/base/nsLineBreaker.h
@@ -201,19 +201,19 @@ private:
 
   void UpdateCurrentWordLanguage(nsIAtom *aHyphenationLanguage);
 
   void FindHyphenationPoints(nsHyphenator *aHyphenator,
                              const char16_t *aTextStart,
                              const char16_t *aTextLimit,
                              uint8_t *aBreakState);
 
-  nsAutoTArray<char16_t,100> mCurrentWord;
+  AutoTArray<char16_t,100> mCurrentWord;
   // All the items that contribute to mCurrentWord
-  nsAutoTArray<TextItem,2>    mTextItems;
+  AutoTArray<TextItem,2>    mTextItems;
   nsIAtom*                    mCurrentWordLanguage;
   bool                        mCurrentWordContainsMixedLang;
   bool                        mCurrentWordContainsComplexChar;
 
   // True if the previous character was breakable whitespace
   bool                        mAfterBreakableSpace;
   // True if a break must be allowed at the current position because
   // a run of breakable whitespace ends here
--- a/dom/base/nsPIDOMWindowInlines.h
+++ b/dom/base/nsPIDOMWindowInlines.h
@@ -120,13 +120,13 @@ nsPIDOMWindow<T>::GetDocShell() const
   return mDocShell;
 }
 
 template <class T>
 nsIContent*
 nsPIDOMWindow<T>::GetFocusedNode() const
 {
   if (IsOuterWindow()) {
-    return mInnerWindow->GetFocusedNode();
+    return mInnerWindow ? mInnerWindow->GetFocusedNode() : nullptr;
   }
 
   return mFocusedNode;
 }
--- a/dom/base/nsPerformance.cpp
+++ b/dom/base/nsPerformance.cpp
@@ -953,17 +953,17 @@ PerformanceBase::ClearMarks(const Option
 {
   ClearUserEntries(aName, NS_LITERAL_STRING("mark"));
 }
 
 DOMHighResTimeStamp
 PerformanceBase::ResolveTimestampFromName(const nsAString& aName,
                                           ErrorResult& aRv)
 {
-  nsAutoTArray<RefPtr<PerformanceEntry>, 1> arr;
+  AutoTArray<RefPtr<PerformanceEntry>, 1> arr;
   DOMHighResTimeStamp ts;
   Optional<nsAString> typeParam;
   nsAutoString str;
   str.AssignLiteral("mark");
   typeParam = &str;
   GetEntriesByName(aName, typeParam, arr);
   if (!arr.IsEmpty()) {
     return arr.LastElement()->StartTime();
--- a/dom/base/nsPlainTextSerializer.h
+++ b/dom/base/nsPlainTextSerializer.h
@@ -194,20 +194,20 @@ private:
                                           Number of previous headers of
                                           the same depth and in the same
                                           section.
                                           mHeaderCounter[1] for <h1> etc. */
 
   RefPtr<mozilla::dom::Element> mElement;
 
   // For handling table rows
-  nsAutoTArray<bool, 8> mHasWrittenCellsForRow;
+  AutoTArray<bool, 8> mHasWrittenCellsForRow;
   
   // Values gotten in OpenContainer that is (also) needed in CloseContainer
-  nsAutoTArray<bool, 8> mIsInCiteBlockquote;
+  AutoTArray<bool, 8> mIsInCiteBlockquote;
 
   // The output data
   nsAString*            mOutputString;
 
   // The tag stack: the stack of tags we're operating on, so we can nest.
   // The stack only ever points to static atoms, so they don't need to be
   // refcounted.
   nsIAtom**        mTagStack;
--- a/dom/base/nsXHTMLContentSerializer.h
+++ b/dom/base/nsXHTMLContentSerializer.h
@@ -147,17 +147,17 @@ protected:
     int32_t startVal;
 
     // is true only before the serialization of the first li of an ol
     // should be false for other li in the list
     bool isFirstListItem;
   };
 
   // Stack to store one olState struct per <OL>.
-  nsAutoTArray<olState, 8> mOLStateStack;
+  AutoTArray<olState, 8> mOLStateStack;
 
   bool HasNoChildren(nsIContent* aContent);
 };
 
 nsresult
 NS_NewXHTMLContentSerializer(nsIContentSerializer** aSerializer);
 
 #endif
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -2065,20 +2065,20 @@ template<typename T>
 void DoTraceSequence(JSTracer* trc, FallibleTArray<T>& seq);
 template<typename T>
 void DoTraceSequence(JSTracer* trc, InfallibleTArray<T>& seq);
 
 // Class for simple sequence arguments, only used internally by codegen.
 namespace binding_detail {
 
 template<typename T>
-class AutoSequence : public AutoFallibleTArray<T, 16>
+class AutoSequence : public AutoTArray<T, 16>
 {
 public:
-  AutoSequence() : AutoFallibleTArray<T, 16>()
+  AutoSequence() : AutoTArray<T, 16>()
   {}
 
   // Allow converting to const sequences as needed
   operator const Sequence<T>&() const {
     return *reinterpret_cast<const Sequence<T>*>(this);
   }
 };
 
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -4469,18 +4469,18 @@ def getJSToNativeConversionInfo(type, de
             elementType = type.inner.inner
         else:
             elementType = type.inner
 
         # We want to use auto arrays if we can, but we have to be careful with
         # reallocation behavior for arrays.  In particular, if we use auto
         # arrays for sequences and have a sequence of elements which are
         # themselves sequences or have sequences as members, we have a problem.
-        # In that case, resizing the outermost nsAutoTarray to the right size
-        # will memmove its elements, but nsAutoTArrays are not memmovable and
+        # In that case, resizing the outermost AutoTArray to the right size
+        # will memmove its elements, but AutoTArrays are not memmovable and
         # hence will end up with pointers to bogus memory, which is bad.  To
         # deal with this, we typically map WebIDL sequences to our Sequence
         # type, which is in fact memmovable.  The one exception is when we're
         # passing in a sequence directly as an argument without any sort of
         # optional or nullable complexity going on.  In that situation, we can
         # use an AutoSequence instead.  We have to keep using Sequence in the
         # nullable and optional cases because we don't want to leak the
         # AutoSequence type to consumers, which would be unavoidable with
@@ -8384,17 +8384,17 @@ class CGEnumerateHook(CGAbstractBindingM
                 Argument('JS::Handle<JSObject*>', 'obj')]
         # Our "self" is actually the "obj" argument in this case, not the thisval.
         CGAbstractBindingMethod.__init__(
             self, descriptor, ENUMERATE_HOOK_NAME,
             args, getThisObj="", callArgs="")
 
     def generate_code(self):
         return CGGeneric(dedent("""
-            nsAutoTArray<nsString, 8> names;
+            AutoTArray<nsString, 8> names;
             ErrorResult rv;
             self->GetOwnPropertyNames(cx, names, rv);
             if (rv.MaybeSetPendingException(cx)) {
               return false;
             }
             bool dummy;
             for (uint32_t i = 0; i < names.Length(); ++i) {
               if (!JS_HasUCProperty(cx, obj, names[i].get(), names[i].Length(), &dummy)) {
@@ -10451,17 +10451,17 @@ class CGEnumerateOwnPropertiesViaGetOwnP
                 Argument('JS::AutoIdVector&', 'props')]
         CGAbstractBindingMethod.__init__(self, descriptor,
                                          "EnumerateOwnPropertiesViaGetOwnPropertyNames",
                                          args, getThisObj="",
                                          callArgs="")
 
     def generate_code(self):
         return CGGeneric(dedent("""
-            nsAutoTArray<nsString, 8> names;
+            AutoTArray<nsString, 8> names;
             ErrorResult rv;
             self->GetOwnPropertyNames(cx, names, rv);
             if (rv.MaybeSetPendingException(cx)) {
               return false;
             }
             // OK to pass null as "proxy" because it's ignored if
             // shadowPrototypeProperties is true
             return AppendNamedPropertyIds(cx, nullptr, names, true, props);
--- a/dom/bluetooth/common/BluetoothService.cpp
+++ b/dom/bluetooth/common/BluetoothService.cpp
@@ -89,25 +89,25 @@ ShutdownTimeExceeded(nsITimer* aTimer, v
 }
 
 void
 GetAllBluetoothActors(InfallibleTArray<BluetoothParent*>& aActors)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aActors.IsEmpty());
 
-  nsAutoTArray<ContentParent*, 20> contentActors;
+  AutoTArray<ContentParent*, 20> contentActors;
   ContentParent::GetAll(contentActors);
 
   for (uint32_t contentIndex = 0;
        contentIndex < contentActors.Length();
        contentIndex++) {
     MOZ_ASSERT(contentActors[contentIndex]);
 
-    AutoInfallibleTArray<PBluetoothParent*, 5> bluetoothActors;
+    AutoTArray<PBluetoothParent*, 5> bluetoothActors;
     contentActors[contentIndex]->ManagedPBluetoothParent(bluetoothActors);
 
     for (uint32_t bluetoothIndex = 0;
          bluetoothIndex < bluetoothActors.Length();
          bluetoothIndex++) {
       MOZ_ASSERT(bluetoothActors[bluetoothIndex]);
 
       BluetoothParent* actor =
@@ -482,17 +482,17 @@ BluetoothService::StartStopBluetooth(boo
   return rv;
 }
 
 void
 BluetoothService::SetEnabled(bool aEnabled)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  AutoInfallibleTArray<BluetoothParent*, 10> childActors;
+  AutoTArray<BluetoothParent*, 10> childActors;
   GetAllBluetoothActors(childActors);
 
   for (uint32_t index = 0; index < childActors.Length(); index++) {
     Unused << childActors[index]->SendEnabled(aEnabled);
   }
 
   /**
    * mEnabled: real status of bluetooth
@@ -566,17 +566,17 @@ BluetoothService::HandleShutdown()
   MOZ_ASSERT(NS_IsMainThread());
 
   // This is a two phase shutdown. First we notify all child processes that
   // bluetooth is going away, and then we wait for them to acknowledge. Then we
   // close down all the bluetooth machinery.
 
   Cleanup();
 
-  AutoInfallibleTArray<BluetoothParent*, 10> childActors;
+  AutoTArray<BluetoothParent*, 10> childActors;
   GetAllBluetoothActors(childActors);
 
   if (!childActors.IsEmpty()) {
     // Notify child processes that they should stop using bluetooth now.
     for (uint32_t index = 0; index < childActors.Length(); index++) {
       childActors[index]->BeginShutdown();
     }
 
--- a/dom/browser-element/BrowserElementChildPreload.js
+++ b/dom/browser-element/BrowserElementChildPreload.js
@@ -1882,16 +1882,17 @@ BrowserElementChild.prototype = {
         } catch (e) {}
         sendAsyncMsg('loadend', {backgroundColor: bgColor});
 
         switch (status) {
           case Cr.NS_OK :
           case Cr.NS_BINDING_ABORTED :
             // Ignoring NS_BINDING_ABORTED, which is set when loading page is
             // stopped.
+          case Cr.NS_ERROR_PARSED_DATA_CACHED:
             return;
 
           // TODO See nsDocShell::DisplayLoadError to see what extra
           // information we should be annotating this first block of errors
           // with. Bug 1107091.
           case Cr.NS_ERROR_UNKNOWN_PROTOCOL :
             sendAsyncMsg('error', { type: 'unknownProtocolFound' });
             return;
--- a/dom/cache/AutoUtils.cpp
+++ b/dom/cache/AutoUtils.cpp
@@ -42,17 +42,17 @@ enum CleanupAction
 void
 CleanupChildFds(CacheReadStream& aReadStream, CleanupAction aAction)
 {
   if (aReadStream.fds().type() !=
       OptionalFileDescriptorSet::TPFileDescriptorSetChild) {
     return;
   }
 
-  nsAutoTArray<FileDescriptor, 4> fds;
+  AutoTArray<FileDescriptor, 4> fds;
 
   FileDescriptorSetChild* fdSetActor =
     static_cast<FileDescriptorSetChild*>(aReadStream.fds().get_PFileDescriptorSetChild());
   MOZ_ASSERT(fdSetActor);
 
   if (aAction == Delete) {
     Unused << fdSetActor->Send__delete__(fdSetActor);
   }
@@ -102,17 +102,17 @@ CleanupChild(CacheReadStreamOrVoid& aRea
 void
 CleanupParentFds(CacheReadStream& aReadStream, CleanupAction aAction)
 {
   if (aReadStream.fds().type() !=
       OptionalFileDescriptorSet::TPFileDescriptorSetParent) {
     return;
   }
 
-  nsAutoTArray<FileDescriptor, 4> fds;
+  AutoTArray<FileDescriptor, 4> fds;
 
   FileDescriptorSetParent* fdSetActor =
     static_cast<FileDescriptorSetParent*>(aReadStream.fds().get_PFileDescriptorSetParent());
   MOZ_ASSERT(fdSetActor);
 
   if (aAction == Delete) {
     Unused << fdSetActor->Send__delete__(fdSetActor);
   }
@@ -301,17 +301,17 @@ MatchInPutList(InternalRequest* aRequest
     }
 
     RefPtr<InternalHeaders> cachedRequestHeaders =
       TypeUtils::ToInternalHeaders(cachedRequest.headers());
 
     RefPtr<InternalHeaders> cachedResponseHeaders =
       TypeUtils::ToInternalHeaders(cachedResponse.headers());
 
-    nsAutoTArray<nsCString, 16> varyHeaders;
+    AutoTArray<nsCString, 16> varyHeaders;
     ErrorResult rv;
     cachedResponseHeaders->GetAll(NS_LITERAL_CSTRING("vary"), varyHeaders, rv);
     MOZ_ALWAYS_TRUE(!rv.Failed());
 
     // Assume the vary headers match until we find a conflict
     bool varyHeadersMatch = true;
 
     for (uint32_t j = 0; j < varyHeaders.Length(); ++j) {
--- a/dom/cache/Cache.cpp
+++ b/dom/cache/Cache.cpp
@@ -109,17 +109,17 @@ public:
     // Stop holding the worker alive when we leave this method.
     RefPtr<Feature> feature;
     feature.swap(mFeature);
 
     // Promise::All() passed an array of fetch() Promises should give us
     // an Array of Response objects.  The following code unwraps these
     // JS values back to an nsTArray<RefPtr<Response>>.
 
-    nsAutoTArray<RefPtr<Response>, 256> responseList;
+    AutoTArray<RefPtr<Response>, 256> responseList;
     responseList.SetCapacity(mRequestList.Length());
 
     bool isArray;
     if (NS_WARN_IF(!JS_IsArrayObject(aCx, aValue, &isArray) || !isArray)) {
       Fail();
       return;
     }
 
@@ -566,17 +566,17 @@ Cache::AddAll(const GlobalObject& aGloba
     if (NS_WARN_IF(!promise)) {
       return nullptr;
     }
 
     promise->MaybeResolve(JS::UndefinedHandleValue);
     return promise.forget();
   }
 
-  nsAutoTArray<RefPtr<Promise>, 256> fetchList;
+  AutoTArray<RefPtr<Promise>, 256> fetchList;
   fetchList.SetCapacity(aRequestList.Length());
 
   // Begin fetching each request in parallel.  For now, if an error occurs just
   // abandon our previous fetch calls.  In theory we could cancel them in the
   // future once fetch supports it.
 
   for (uint32_t i = 0; i < aRequestList.Length(); ++i) {
     RequestOrUSVString requestOrString;
--- a/dom/cache/CacheOpChild.cpp
+++ b/dom/cache/CacheOpChild.cpp
@@ -214,31 +214,31 @@ CacheOpChild::HandleResponse(const Cache
   RefPtr<Response> response = ToResponse(cacheResponse);
 
   mPromise->MaybeResolve(response);
 }
 
 void
 CacheOpChild::HandleResponseList(const nsTArray<CacheResponse>& aResponseList)
 {
-  nsAutoTArray<RefPtr<Response>, 256> responses;
+  AutoTArray<RefPtr<Response>, 256> responses;
   responses.SetCapacity(aResponseList.Length());
 
   for (uint32_t i = 0; i < aResponseList.Length(); ++i) {
     AddFeatureToStreamChild(aResponseList[i], GetFeature());
     responses.AppendElement(ToResponse(aResponseList[i]));
   }
 
   mPromise->MaybeResolve(responses);
 }
 
 void
 CacheOpChild::HandleRequestList(const nsTArray<CacheRequest>& aRequestList)
 {
-  nsAutoTArray<RefPtr<Request>, 256> requests;
+  AutoTArray<RefPtr<Request>, 256> requests;
   requests.SetCapacity(aRequestList.Length());
 
   for (uint32_t i = 0; i < aRequestList.Length(); ++i) {
     AddFeatureToStreamChild(aRequestList[i], GetFeature());
     requests.AppendElement(ToRequest(aRequestList[i]));
   }
 
   mPromise->MaybeResolve(requests);
--- a/dom/cache/CacheOpParent.cpp
+++ b/dom/cache/CacheOpParent.cpp
@@ -74,18 +74,18 @@ CacheOpParent::Execute(Manager* aManager
 
   // Handle put op
   if (mOpArgs.type() == CacheOpArgs::TCachePutAllArgs) {
     MOZ_ASSERT(mCacheId != INVALID_CACHE_ID);
 
     const CachePutAllArgs& args = mOpArgs.get_CachePutAllArgs();
     const nsTArray<CacheRequestResponse>& list = args.requestResponseList();
 
-    nsAutoTArray<nsCOMPtr<nsIInputStream>, 256> requestStreamList;
-    nsAutoTArray<nsCOMPtr<nsIInputStream>, 256> responseStreamList;
+    AutoTArray<nsCOMPtr<nsIInputStream>, 256> requestStreamList;
+    AutoTArray<nsCOMPtr<nsIInputStream>, 256> responseStreamList;
 
     for (uint32_t i = 0; i < list.Length(); ++i) {
       requestStreamList.AppendElement(
         DeserializeCacheStream(list[i].request().body()));
       responseStreamList.AppendElement(
         DeserializeCacheStream(list[i].response().body()));
     }
 
@@ -216,17 +216,17 @@ CacheOpParent::DeserializeCacheStream(co
   // Option 2: One of our own ReadStreams was passed back to us with a stream
   //           control actor.
   stream = ReadStream::Create(readStream);
   if (stream) {
     return stream.forget();
   }
 
   // Option 3: A stream was serialized using normal methods.
-  nsAutoTArray<FileDescriptor, 4> fds;
+  AutoTArray<FileDescriptor, 4> fds;
   if (readStream.fds().type() ==
       OptionalFileDescriptorSet::TPFileDescriptorSetChild) {
 
     FileDescriptorSetParent* fdSetActor =
       static_cast<FileDescriptorSetParent*>(readStream.fds().get_PFileDescriptorSetParent());
     MOZ_ASSERT(fdSetActor);
 
     fdSetActor->ForgetFileDescriptors(fds);
--- a/dom/cache/DBSchema.cpp
+++ b/dom/cache/DBSchema.cpp
@@ -583,21 +583,21 @@ DeleteCacheId(mozIStorageConnection* aCo
               nsTArray<nsID>& aDeletedBodyIdListOut)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(aConn);
 
   // Delete the bodies explicitly as we need to read out the body IDs
   // anyway.  These body IDs must be deleted one-by-one as content may
   // still be referencing them invidivually.
-  nsAutoTArray<EntryId, 256> matches;
+  AutoTArray<EntryId, 256> matches;
   nsresult rv = QueryAll(aConn, aCacheId, matches);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
-  nsAutoTArray<IdCount, 16> deletedSecurityIdList;
+  AutoTArray<IdCount, 16> deletedSecurityIdList;
   rv = DeleteEntries(aConn, matches, aDeletedBodyIdListOut,
                      deletedSecurityIdList);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = DeleteSecurityInfoList(aConn, deletedSecurityIdList);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   // Delete the remainder of the cache using cascade semantics.
@@ -715,17 +715,17 @@ CacheMatch(mozIStorageConnection* aConn,
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(aConn);
   MOZ_ASSERT(aFoundResponseOut);
   MOZ_ASSERT(aSavedResponseOut);
 
   *aFoundResponseOut = false;
 
-  nsAutoTArray<EntryId, 1> matches;
+  AutoTArray<EntryId, 1> matches;
   nsresult rv = QueryCache(aConn, aCacheId, aRequest, aParams, matches, 1);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   if (matches.IsEmpty()) {
     return rv;
   }
 
   rv = ReadResponse(aConn, matches[0], aSavedResponseOut);
@@ -742,17 +742,17 @@ CacheMatchAll(mozIStorageConnection* aCo
               const CacheRequestOrVoid& aRequestOrVoid,
               const CacheQueryParams& aParams,
               nsTArray<SavedResponse>& aSavedResponsesOut)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(aConn);
   nsresult rv;
 
-  nsAutoTArray<EntryId, 256> matches;
+  AutoTArray<EntryId, 256> matches;
   if (aRequestOrVoid.type() == CacheRequestOrVoid::Tvoid_t) {
     rv = QueryAll(aConn, aCacheId, matches);
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
   } else {
     rv = QueryCache(aConn, aCacheId, aRequestOrVoid, aParams, matches);
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
   }
 
@@ -776,21 +776,21 @@ CachePut(mozIStorageConnection* aConn, C
          const nsID* aResponseBodyId,
          nsTArray<nsID>& aDeletedBodyIdListOut)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(aConn);
 
   CacheQueryParams params(false, false, false, false,
                            NS_LITERAL_STRING(""));
-  nsAutoTArray<EntryId, 256> matches;
+  AutoTArray<EntryId, 256> matches;
   nsresult rv = QueryCache(aConn, aCacheId, aRequest, params, matches);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
-  nsAutoTArray<IdCount, 16> deletedSecurityIdList;
+  AutoTArray<IdCount, 16> deletedSecurityIdList;
   rv = DeleteEntries(aConn, matches, aDeletedBodyIdListOut,
                      deletedSecurityIdList);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = InsertEntry(aConn, aCacheId, aRequest, aRequestBodyId, aResponse,
                    aResponseBodyId);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
@@ -809,25 +809,25 @@ CacheDelete(mozIStorageConnection* aConn
             nsTArray<nsID>& aDeletedBodyIdListOut, bool* aSuccessOut)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(aConn);
   MOZ_ASSERT(aSuccessOut);
 
   *aSuccessOut = false;
 
-  nsAutoTArray<EntryId, 256> matches;
+  AutoTArray<EntryId, 256> matches;
   nsresult rv = QueryCache(aConn, aCacheId, aRequest, aParams, matches);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   if (matches.IsEmpty()) {
     return rv;
   }
 
-  nsAutoTArray<IdCount, 16> deletedSecurityIdList;
+  AutoTArray<IdCount, 16> deletedSecurityIdList;
   rv = DeleteEntries(aConn, matches, aDeletedBodyIdListOut,
                      deletedSecurityIdList);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = DeleteSecurityInfoList(aConn, deletedSecurityIdList);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   *aSuccessOut = true;
@@ -840,17 +840,17 @@ CacheKeys(mozIStorageConnection* aConn, 
           const CacheRequestOrVoid& aRequestOrVoid,
           const CacheQueryParams& aParams,
           nsTArray<SavedRequest>& aSavedRequestsOut)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(aConn);
   nsresult rv;
 
-  nsAutoTArray<EntryId, 256> matches;
+  AutoTArray<EntryId, 256> matches;
   if (aRequestOrVoid.type() == CacheRequestOrVoid::Tvoid_t) {
     rv = QueryAll(aConn, aCacheId, matches);
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
   } else {
     rv = QueryCache(aConn, aCacheId, aRequestOrVoid, aParams, matches);
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
   }
 
@@ -907,17 +907,17 @@ StorageMatch(mozIStorageConnection* aCon
   rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
     "SELECT cache_id FROM storage WHERE namespace=:namespace ORDER BY rowid;"
   ), getter_AddRefs(state));
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = state->BindInt32ByName(NS_LITERAL_CSTRING("namespace"), aNamespace);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
-  nsAutoTArray<CacheId, 32> cacheIdList;
+  AutoTArray<CacheId, 32> cacheIdList;
 
   bool hasMoreData = false;
   while (NS_SUCCEEDED(state->ExecuteStep(&hasMoreData)) && hasMoreData) {
     CacheId cacheId = INVALID_CACHE_ID;
     rv = state->GetInt64(0, &cacheId);
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     cacheIdList.AppendElement(cacheId);
   }
@@ -1213,17 +1213,17 @@ MatchByVaryHeader(mozIStorageConnection*
     "SELECT value FROM response_headers "
     "WHERE name='vary' AND entry_id=:entry_id;"
   ), getter_AddRefs(state));
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = state->BindInt32ByName(NS_LITERAL_CSTRING("entry_id"), entryId);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
-  nsAutoTArray<nsCString, 8> varyValues;
+  AutoTArray<nsCString, 8> varyValues;
 
   bool hasMoreData = false;
   while (NS_SUCCEEDED(state->ExecuteStep(&hasMoreData)) && hasMoreData) {
     nsAutoCString value;
     rv = state->GetUTF8String(0, value);
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     varyValues.AppendElement(value);
   }
--- a/dom/cache/Manager.cpp
+++ b/dom/cache/Manager.cpp
@@ -69,31 +69,31 @@ public:
     // Note, this must be done after any schema version updates to
     // ensure our DBSchema methods work correctly.
     if (MarkerFileExists(aQuotaInfo)) {
       NS_WARNING("Cache not shutdown cleanly! Cleaning up stale data...");
       mozStorageTransaction trans(aConn, false,
                                   mozIStorageConnection::TRANSACTION_IMMEDIATE);
 
       // Clean up orphaned Cache objects
-      nsAutoTArray<CacheId, 8> orphanedCacheIdList;
+      AutoTArray<CacheId, 8> orphanedCacheIdList;
       nsresult rv = db::FindOrphanedCacheIds(aConn, orphanedCacheIdList);
       if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
       for (uint32_t i = 0; i < orphanedCacheIdList.Length(); ++i) {
-        nsAutoTArray<nsID, 16> deletedBodyIdList;
+        AutoTArray<nsID, 16> deletedBodyIdList;
         rv = db::DeleteCacheId(aConn, orphanedCacheIdList[i], deletedBodyIdList);
         if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
         rv = BodyDeleteFiles(aDBDir, deletedBodyIdList);
         if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
       }
 
       // Clean up orphaned body objects
-      nsAutoTArray<nsID, 64> knownBodyIdList;
+      AutoTArray<nsID, 64> knownBodyIdList;
       rv = db::GetKnownBodyIds(aConn, knownBodyIdList);
 
       rv = BodyDeleteOrphanedFiles(aDBDir, knownBodyIdList);
       if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     }
 
     return rv;
   }
@@ -1368,17 +1368,17 @@ Manager::Listener::OnOpComplete(ErrorRes
                nsTArray<SavedRequest>(), nullptr);
 }
 
 void
 Manager::Listener::OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
                                 const SavedResponse& aSavedResponse,
                                 StreamList* aStreamList)
 {
-  nsAutoTArray<SavedResponse, 1> responseList;
+  AutoTArray<SavedResponse, 1> responseList;
   responseList.AppendElement(aSavedResponse);
   OnOpComplete(Move(aRv), aResult, INVALID_CACHE_ID, responseList,
                nsTArray<SavedRequest>(), aStreamList);
 }
 
 void
 Manager::Listener::OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
                                 const nsTArray<SavedResponse>& aSavedResponseList,
@@ -1897,17 +1897,17 @@ Manager::SetBodyIdOrphanedIfRefed(const 
   return false;
 }
 
 void
 Manager::NoteOrphanedBodyIdList(const nsTArray<nsID>& aDeletedBodyIdList)
 {
   NS_ASSERT_OWNINGTHREAD(Manager);
 
-  nsAutoTArray<nsID, 64> deleteNowList;
+  AutoTArray<nsID, 64> deleteNowList;
   deleteNowList.SetCapacity(aDeletedBodyIdList.Length());
 
   for (uint32_t i = 0; i < aDeletedBodyIdList.Length(); ++i) {
     if (!SetBodyIdOrphanedIfRefed(aDeletedBodyIdList[i])) {
       deleteNowList.AppendElement(aDeletedBodyIdList[i]);
     }
   }
 
--- a/dom/cache/ReadStream.cpp
+++ b/dom/cache/ReadStream.cpp
@@ -217,17 +217,17 @@ ReadStream::Inner::Serialize(CacheReadSt
   // If we are sending a ReadStream, then we never want to set the
   // pushStream actors at the same time.
   aReadStreamOut->pushStreamChild() = nullptr;
   aReadStreamOut->pushStreamParent() = nullptr;
 
   aReadStreamOut->id() = mId;
   mControl->SerializeControl(aReadStreamOut);
 
-  nsAutoTArray<FileDescriptor, 4> fds;
+  AutoTArray<FileDescriptor, 4> fds;
   SerializeInputStream(mStream, aReadStreamOut->params(), fds);
 
   mControl->SerializeFds(aReadStreamOut, fds);
 
   // We're passing ownership across the IPC barrier with the control, so
   // do not signal that the stream is closed here.
   Forget();
 }
@@ -446,17 +446,17 @@ ReadStream::Create(const CacheReadStream
     auto actor = static_cast<CacheStreamControlChild*>(aReadStream.controlChild());
     control = actor;
   } else {
     auto actor = static_cast<CacheStreamControlParent*>(aReadStream.controlParent());
     control = actor;
   }
   MOZ_ASSERT(control);
 
-  nsAutoTArray<FileDescriptor, 4> fds;
+  AutoTArray<FileDescriptor, 4> fds;
   control->DeserializeFds(aReadStream, fds);
 
   nsCOMPtr<nsIInputStream> stream =
     DeserializeInputStream(aReadStream.params(), fds);
   MOZ_ASSERT(stream);
 
   // Currently we expect all cache read streams to be blocking file streams.
 #ifdef DEBUG
--- a/dom/cache/TypeUtils.cpp
+++ b/dom/cache/TypeUtils.cpp
@@ -39,17 +39,17 @@ using mozilla::ipc::FileDescriptor;
 using mozilla::ipc::PBackgroundChild;
 using mozilla::ipc::PFileDescriptorSetChild;
 
 namespace {
 
 static bool
 HasVaryStar(mozilla::dom::InternalHeaders* aHeaders)
 {
-  nsAutoTArray<nsCString, 16> varyHeaders;
+  AutoTArray<nsCString, 16> varyHeaders;
   ErrorResult rv;
   aHeaders->GetAll(NS_LITERAL_CSTRING("vary"), varyHeaders, rv);
   MOZ_ALWAYS_TRUE(!rv.Failed());
 
   for (uint32_t i = 0; i < varyHeaders.Length(); ++i) {
     nsAutoCString varyValue(varyHeaders[i]);
     char* rawBuffer = varyValue.BeginWriting();
     char* token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer);
@@ -62,17 +62,17 @@ HasVaryStar(mozilla::dom::InternalHeader
     }
   }
   return false;
 }
 
 void
 SerializeNormalStream(nsIInputStream* aStream, CacheReadStream& aReadStreamOut)
 {
-  nsAutoTArray<FileDescriptor, 4> fds;
+  AutoTArray<FileDescriptor, 4> fds;
   SerializeInputStream(aStream, aReadStreamOut.params(), fds);
 
   PFileDescriptorSetChild* fdSet = nullptr;
   if (!fds.IsEmpty()) {
     // We should not be serializing until we have an actor ready
     PBackgroundChild* manager = BackgroundChild::GetForCurrentThread();
     MOZ_ASSERT(manager);
 
@@ -89,17 +89,17 @@ SerializeNormalStream(nsIInputStream* aS
   }
 }
 
 void
 ToHeadersEntryList(nsTArray<HeadersEntry>& aOut, InternalHeaders* aHeaders)
 {
   MOZ_ASSERT(aHeaders);
 
-  nsAutoTArray<InternalHeaders::Entry, 16> entryList;
+  AutoTArray<InternalHeaders::Entry, 16> entryList;
   aHeaders->GetEntries(entryList);
 
   for (uint32_t i = 0; i < entryList.Length(); ++i) {
     InternalHeaders::Entry& entry = entryList[i];
     aOut.AppendElement(HeadersEntry(entry.mName, entry.mValue));
   }
 }
 
--- a/dom/camera/GonkCameraControl.cpp
+++ b/dom/camera/GonkCameraControl.cpp
@@ -242,34 +242,34 @@ nsGonkCameraControl::Initialize()
     mLuminanceSupported ? "" : "NOT ");
   if (mFlashSupported) {
     DOM_CAMERA_LOGI(" - flash:                         supported, default mode '%s'\n",
       NS_ConvertUTF16toUTF8(flashMode).get());
   } else {
     DOM_CAMERA_LOGI(" - flash:                         NOT supported\n");
   }
 
-  nsAutoTArray<Size, 16> sizes;
+  AutoTArray<Size, 16> sizes;
   mParams.Get(CAMERA_PARAM_SUPPORTED_VIDEOSIZES, sizes);
   if (sizes.Length() > 0) {
     mSeparateVideoAndPreviewSizesSupported = true;
     DOM_CAMERA_LOGI(" - support for separate preview and video sizes\n");
     mParams.Get(CAMERA_PARAM_VIDEOSIZE, mLastRecorderSize);
     DOM_CAMERA_LOGI(" - default video recorder size:   %u x %u\n",
       mLastRecorderSize.width, mLastRecorderSize.height);
 
     Size preferred;
     mParams.Get(CAMERA_PARAM_PREFERRED_PREVIEWSIZE_FOR_VIDEO, preferred);
     DOM_CAMERA_LOGI(" - preferred video preview size:  %u x %u\n",
       preferred.width, preferred.height);
   } else {
     mLastRecorderSize = mCurrentConfiguration.mPreviewSize;
   }
 
-  nsAutoTArray<nsString, 8> modes;
+  AutoTArray<nsString, 8> modes;
   mParams.Get(CAMERA_PARAM_SUPPORTED_METERINGMODES, modes);
   if (!modes.IsEmpty()) {
     nsString mode;
     const char* kCenterWeighted = "center-weighted";
 
     mParams.Get(CAMERA_PARAM_METERINGMODE, mode);
     if (!mode.EqualsASCII(kCenterWeighted)) {
       nsTArray<nsString>::index_type i = modes.Length();
@@ -297,17 +297,17 @@ nsGonkCameraControl::~nsGonkCameraContro
 
   StopImpl();
   DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
 }
 
 nsresult
 nsGonkCameraControl::ValidateConfiguration(const Configuration& aConfig, Configuration& aValidatedConfig)
 {
-  nsAutoTArray<Size, 16> supportedSizes;
+  AutoTArray<Size, 16> supportedSizes;
   Get(CAMERA_PARAM_SUPPORTED_PICTURESIZES, supportedSizes);
 
   nsresult rv = GetSupportedSize(aConfig.mPictureSize, supportedSizes,
                                  aValidatedConfig.mPictureSize);
   if (NS_FAILED(rv)) {
     DOM_CAMERA_LOGW("Unable to find a picture size close to %ux%u\n",
       aConfig.mPictureSize.width, aConfig.mPictureSize.height);
     return NS_ERROR_INVALID_ARG;
@@ -918,17 +918,17 @@ nsGonkCameraControl::SetThumbnailSizeImp
    * Some drivers will fail to take a picture if the thumbnail does not have
    * the same aspect ratio as the set picture size, so we need to enforce that
    * too.
    */
   int smallestDelta = INT_MAX;
   uint32_t smallestDeltaIndex = UINT32_MAX;
   int targetArea = aSize.width * aSize.height;
 
-  nsAutoTArray<Size, 8> supportedSizes;
+  AutoTArray<Size, 8> supportedSizes;
   Get(CAMERA_PARAM_SUPPORTED_JPEG_THUMBNAIL_SIZES, supportedSizes);
 
   for (uint32_t i = 0; i < supportedSizes.Length(); ++i) {
     int area = supportedSizes[i].width * supportedSizes[i].height;
     int delta = abs(area - targetArea);
 
     if (area != 0 &&
         delta < smallestDelta &&
@@ -1023,17 +1023,17 @@ nsGonkCameraControl::SetPictureSizeImpl(
   }
 
   if (aSize.width == mCurrentConfiguration.mPictureSize.width &&
       aSize.height == mCurrentConfiguration.mPictureSize.height) {
     DOM_CAMERA_LOGI("Requested picture size %ux%u unchanged\n", aSize.width, aSize.height);
     return NS_OK;
   }
 
-  nsAutoTArray<Size, 8> supportedSizes;
+  AutoTArray<Size, 8> supportedSizes;
   Get(CAMERA_PARAM_SUPPORTED_PICTURESIZES, supportedSizes);
 
   Size best;
   nsresult rv = GetSupportedSize(aSize, supportedSizes, best);
   if (NS_FAILED(rv)) {
     DOM_CAMERA_LOGW("Unable to find a picture size close to %ux%u\n",
       aSize.width, aSize.height);
     return NS_ERROR_INVALID_ARG;
@@ -1722,17 +1722,17 @@ nsGonkCameraControl::SelectCaptureAndPre
 
   // At this point, we know the capture size has been validated and replaced
   // if necessary with the best matching supported value.
   DOM_CAMERA_LOGI("Select capture size %ux%u, preview size %ux%u, maximum size %ux%u\n",
                   aCaptureSize.width, aCaptureSize.height,
                   aPreviewSize.width, aPreviewSize.height,
                   aMaxSize.width, aMaxSize.height);
 
-  nsAutoTArray<Size, 16> sizes;
+  AutoTArray<Size, 16> sizes;
   nsresult rv = Get(CAMERA_PARAM_SUPPORTED_PREVIEWSIZES, sizes);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   // May optionally apply a ceiling to the preview size. Any supported preview
   // size with an area larger than the maximum will be ignored regardless of
   // aspect ratio or delta to requested preview size.
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -1029,17 +1029,17 @@ protected:
     RefPtr<nsSVGFilterChainObserver> filterChainObserver;
     mozilla::gfx::FilterDescription filter;
     nsTArray<RefPtr<mozilla::gfx::SourceSurface>> filterAdditionalImages;
 
     bool imageSmoothingEnabled;
     bool fontExplicitLanguage;
   };
 
-  nsAutoTArray<ContextState, 3> mStyleStack;
+  AutoTArray<ContextState, 3> mStyleStack;
 
   inline ContextState& CurrentState() {
     return mStyleStack[mStyleStack.Length() - 1];
   }
 
   inline const ContextState& CurrentState() const {
     return mStyleStack[mStyleStack.Length() - 1];
   }
--- a/dom/canvas/ImageBitmapRenderingContext.cpp
+++ b/dom/canvas/ImageBitmapRenderingContext.cpp
@@ -234,17 +234,17 @@ ImageBitmapRenderingContext::GetCanvasLa
   }
 
   RefPtr<ImageContainer> imageContainer = imageLayer->GetContainer();
   if (!imageContainer) {
     imageContainer = aManager->CreateImageContainer();
     imageLayer->SetContainer(imageContainer);
   }
 
-  nsAutoTArray<ImageContainer::NonOwningImage, 1> imageList;
+  AutoTArray<ImageContainer::NonOwningImage, 1> imageList;
   RefPtr<layers::Image> image = ClipToIntrinsicSize();
   imageList.AppendElement(ImageContainer::NonOwningImage(image));
   imageContainer->SetCurrentImages(imageList);
 
   return imageLayer.forget();
 }
 
 void
--- a/dom/events/Event.h
+++ b/dom/events/Event.h
@@ -25,16 +25,17 @@
 class nsIContent;
 class nsIDOMEventTarget;
 class nsPresContext;
 
 namespace mozilla {
 namespace dom {
 
 class EventTarget;
+class EventMessageAutoOverride;
 class WantsPopupControlCheck;
 #define GENERATED_EVENT(EventClass_) class EventClass_;
 #include "mozilla/dom/GeneratedEventList.h"
 #undef GENERATED_EVENT
 // ExtendableEvent is a ServiceWorker event that is not
 // autogenerated since it has some extra methods.
 namespace workers {
 class ExtendableEvent;
@@ -234,16 +235,17 @@ public:
                                             nsIContent* aRelatedTarget);
 
 protected:
 
   // Internal helper functions
   void SetEventType(const nsAString& aEventTypeArg);
   already_AddRefed<nsIContent> GetTargetFromFrame();
 
+  friend class EventMessageAutoOverride;
   friend class WantsPopupControlCheck;
   void SetWantsPopupControlCheck(bool aCheck)
   {
     mWantsPopupControlCheck = aCheck;
   }
 
   bool GetWantsPopupControlCheck()
   {
@@ -263,16 +265,58 @@ protected:
   bool                        mEventIsInternal;
   bool                        mPrivateDataDuplicated;
   bool                        mIsMainThreadEvent;
   // True when popup control check should rely on event.type, not
   // WidgetEvent.mMessage.
   bool                        mWantsPopupControlCheck;
 };
 
+/**
+ * RAII helper-class to override an event's message (i.e. its DOM-exposed
+ * type), for as long as the object is alive.  Restores the original
+ * EventMessage when destructed.
+ *
+ * Notable requirements:
+ *  - The original & overriding messages must be known (not eUnidentifiedEvent).
+ *  - The original & overriding messages must be different.
+ *  - The passed-in nsIDOMEvent must outlive this RAII helper.
+ */
+class MOZ_RAII EventMessageAutoOverride
+{
+public:
+  explicit EventMessageAutoOverride(nsIDOMEvent* aEvent,
+                                    EventMessage aOverridingMessage)
+    : mEvent(aEvent->InternalDOMEvent()),
+      mOrigMessage(mEvent->mEvent->mMessage)
+  {
+    MOZ_ASSERT(aOverridingMessage != mOrigMessage,
+               "Don't use this class if you're not actually overriding");
+    MOZ_ASSERT(aOverridingMessage != eUnidentifiedEvent,
+               "Only use this class with a valid overriding EventMessage");
+    MOZ_ASSERT(mOrigMessage != eUnidentifiedEvent &&
+               mEvent->mEvent->typeString.IsEmpty(),
+               "Only use this class on events whose overridden type is "
+               "known (so we can restore it properly)");
+
+    mEvent->mEvent->mMessage = aOverridingMessage;
+  }
+
+  ~EventMessageAutoOverride()
+  {
+    mEvent->mEvent->mMessage = mOrigMessage;
+  }
+
+protected:
+  // Non-owning ref, which should be safe since we're a stack-allocated object
+  // with limited lifetime. Whoever creates us should keep mEvent alive.
+  Event* const MOZ_NON_OWNING_REF mEvent;
+  const EventMessage mOrigMessage;
+};
+
 class MOZ_STACK_CLASS WantsPopupControlCheck
 {
 public:
   explicit WantsPopupControlCheck(nsIDOMEvent* aEvent) :
     mEvent(aEvent->InternalDOMEvent())
   {
     mOriginalWantsPopupControlCheck = mEvent->GetWantsPopupControlCheck();
     mEvent->SetWantsPopupControlCheck(mEvent->IsTrusted());
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -14,17 +14,19 @@
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventListenerManager.h"
 #ifdef MOZ_B2G
 #include "mozilla/Hal.h"
 #endif // #ifdef MOZ_B2G
 #include "mozilla/HalSensor.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "mozilla/JSEventHandler.h"
+#include "mozilla/Maybe.h"
 #include "mozilla/MemoryReporting.h"
+#include "mozilla/Preferences.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/TimelineConsumers.h"
 #include "mozilla/EventTimelineMarker.h"
 
 #include "EventListenerService.h"
 #include "nsCOMArray.h"
@@ -90,16 +92,31 @@ MutationBitForEventType(EventMessage aEv
     default:
       break;
   }
   return 0;
 }
 
 uint32_t EventListenerManager::sMainThreadCreatedCount = 0;
 
+static bool
+IsWebkitPrefixSupportEnabled()
+{
+  static bool sIsWebkitPrefixSupportEnabled;
+  static bool sIsPrefCached = false;
+
+  if (!sIsPrefCached) {
+    sIsPrefCached = true;
+    Preferences::AddBoolVarCache(&sIsWebkitPrefixSupportEnabled,
+                                 "layout.css.prefixes.webkit");
+  }
+
+  return sIsWebkitPrefixSupportEnabled;
+}
+
 EventListenerManagerBase::EventListenerManagerBase()
   : mNoListenerForEvent(eVoidEvent)
   , mMayHavePaintEventListener(false)
   , mMayHaveMutationListeners(false)
   , mMayHaveCapturingListeners(false)
   , mMayHaveSystemGroupListeners(false)
   , mMayHaveTouchEventListener(false)
   , mMayHaveMouseEnterLeaveEventListener(false)
@@ -598,34 +615,40 @@ EventListenerManager::RemoveEventListene
     if (nsCOMPtr<nsPIDOMWindowInner> window = GetTargetAsInnerWindow()) {
       window->DisableNetworkEvent(aEventMessage);
     }
 #endif // MOZ_B2G
   }
 }
 
 bool
-EventListenerManager::ListenerCanHandle(Listener* aListener,
-                                        WidgetEvent* aEvent)
+EventListenerManager::ListenerCanHandle(const Listener* aListener,
+                                        const WidgetEvent* aEvent,
+                                        EventMessage aEventMessage) const
+
 {
+  MOZ_ASSERT(aEventMessage == aEvent->mMessage ||
+             aEventMessage == GetLegacyEventMessage(aEvent->mMessage),
+             "aEvent and aEventMessage should agree, modulo legacyness");
+
   // This is slightly different from EVENT_TYPE_EQUALS in that it returns
   // true even when aEvent->mMessage == eUnidentifiedEvent and
   // aListener=>mEventMessage != eUnidentifiedEvent as long as the atoms are
   // the same
   if (aListener->mAllEvents) {
     return true;
   }
   if (aEvent->mMessage == eUnidentifiedEvent) {
     if (mIsMainThreadELM) {
       return aListener->mTypeAtom == aEvent->userType;
     }
     return aListener->mTypeString.Equals(aEvent->typeString);
   }
   MOZ_ASSERT(mIsMainThreadELM);
-  return aListener->mEventMessage == aEvent->mMessage;
+  return aListener->mEventMessage == aEventMessage;
 }
 
 void
 EventListenerManager::AddEventListenerByType(
                         const EventListenerHolder& aListenerHolder,
                         const nsAString& aType,
                         const EventListenerFlags& aFlags)
 {
@@ -1043,16 +1066,40 @@ EventListenerManager::HandleEventSubType
     if (mIsMainThreadELM) {
       nsContentUtils::LeaveMicroTask();
     }
   }
 
   return result;
 }
 
+EventMessage
+EventListenerManager::GetLegacyEventMessage(EventMessage aEventMessage) const
+{
+  // (If we're off-main-thread, we can't check the pref; so we just behave as
+  // if it's disabled.)
+  if (mIsMainThreadELM && IsWebkitPrefixSupportEnabled()) {
+    // webkit-prefixed legacy events:
+    if (aEventMessage == eTransitionEnd) {
+      return eWebkitTransitionEnd;
+    }
+    if (aEventMessage == eAnimationStart) {
+      return eWebkitAnimationStart;
+    }
+    if (aEventMessage == eAnimationEnd) {
+      return eWebkitAnimationEnd;
+    }
+    if (aEventMessage == eAnimationIteration) {
+      return eWebkitAnimationIteration;
+    }
+  }
+
+  return aEventMessage;
+}
+
 nsIDocShell*
 EventListenerManager::GetDocShellForTarget()
 {
   nsCOMPtr<nsINode> node(do_QueryInterface(mTarget));
   nsIDocument* doc = nullptr;
   nsIDocShell* docShell = nullptr;
 
   if (node) {
@@ -1099,87 +1146,117 @@ EventListenerManager::HandleEventInterna
                                           EventTarget* aCurrentTarget,
                                           nsEventStatus* aEventStatus)
 {
   //Set the value of the internal PreventDefault flag properly based on aEventStatus
   if (*aEventStatus == nsEventStatus_eConsumeNoDefault) {
     aEvent->mFlags.mDefaultPrevented = true;
   }
 
-  nsAutoTObserverArray<Listener, 2>::EndLimitedIterator iter(mListeners);
   Maybe<nsAutoPopupStatePusher> popupStatePusher;
   if (mIsMainThreadELM) {
     popupStatePusher.emplace(Event::GetEventPopupControlState(aEvent, *aDOMEvent));
   }
 
   bool hasListener = false;
-  while (iter.HasMore()) {
-    if (aEvent->mFlags.mImmediatePropagationStopped) {
-      break;
-    }
-    Listener* listener = &iter.GetNext();
-    // Check that the phase is same in event and event listener.
-    // Handle only trusted events, except when listener permits untrusted events.
-    if (ListenerCanHandle(listener, aEvent)) {
-      hasListener = true;
-      if (listener->IsListening(aEvent) &&
-          (aEvent->mFlags.mIsTrusted ||
-           listener->mFlags.mAllowUntrustedEvents)) {
-        if (!*aDOMEvent) {
-          // This is tiny bit slow, but happens only once per event.
-          nsCOMPtr<EventTarget> et =
-            do_QueryInterface(aEvent->originalTarget);
-          RefPtr<Event> event = EventDispatcher::CreateEvent(et, aPresContext,
+  bool usingLegacyMessage = false;
+  EventMessage eventMessage = aEvent->mMessage;
+
+  while (true) {
+    nsAutoTObserverArray<Listener, 2>::EndLimitedIterator iter(mListeners);
+    Maybe<EventMessageAutoOverride> legacyAutoOverride;
+    while (iter.HasMore()) {
+      if (aEvent->mFlags.mImmediatePropagationStopped) {
+        break;
+      }
+      Listener* listener = &iter.GetNext();
+      // Check that the phase is same in event and event listener.
+      // Handle only trusted events, except when listener permits untrusted events.
+      if (ListenerCanHandle(listener, aEvent, eventMessage)) {
+        hasListener = true;
+        if (listener->IsListening(aEvent) &&
+            (aEvent->mFlags.mIsTrusted ||
+             listener->mFlags.mAllowUntrustedEvents)) {
+          if (!*aDOMEvent) {
+            // This is tiny bit slow, but happens only once per event.
+            nsCOMPtr<EventTarget> et =
+              do_QueryInterface(aEvent->originalTarget);
+            RefPtr<Event> event = EventDispatcher::CreateEvent(et, aPresContext,
                                                                aEvent,
                                                                EmptyString());
-          event.forget(aDOMEvent);
-        }
-        if (*aDOMEvent) {
-          if (!aEvent->currentTarget) {
-            aEvent->currentTarget = aCurrentTarget->GetTargetForDOMEvent();
-            if (!aEvent->currentTarget) {
-              break;
-            }
+            event.forget(aDOMEvent);
           }
-
-          // Maybe add a marker to the docshell's timeline, but only
-          // bother with all the logic if some docshell is recording.
-          nsDocShell* docShell;
-          RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
-          bool needsEndEventMarker = false;
-
-          if (mIsMainThreadELM &&
-              listener->mListenerType != Listener::eNativeListener) {
-            nsCOMPtr<nsIDocShell> docShellComPtr = GetDocShellForTarget();
-            if (docShellComPtr) {
-              docShell = static_cast<nsDocShell*>(docShellComPtr.get());
-              if (timelines && timelines->HasConsumer(docShell)) {
-                needsEndEventMarker = true;
-                nsAutoString typeStr;
-                (*aDOMEvent)->GetType(typeStr);
-                uint16_t phase;
-                (*aDOMEvent)->GetEventPhase(&phase);
-                timelines->AddMarkerForDocShell(docShell, Move(
-                  MakeUnique<EventTimelineMarker>(
-                    typeStr, phase, MarkerTracingType::START)));
+          if (*aDOMEvent) {
+            if (!aEvent->currentTarget) {
+              aEvent->currentTarget = aCurrentTarget->GetTargetForDOMEvent();
+              if (!aEvent->currentTarget) {
+                break;
               }
             }
-          }
+            if (usingLegacyMessage && !legacyAutoOverride) {
+              // Override the aDOMEvent's event-message (its .type) until we
+              // finish traversing listeners (when legacyAutoOverride destructs)
+              legacyAutoOverride.emplace(*aDOMEvent, eventMessage);
+            }
+
+            // Maybe add a marker to the docshell's timeline, but only
+            // bother with all the logic if some docshell is recording.
+            nsDocShell* docShell;
+            RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
+            bool needsEndEventMarker = false;
 
-          if (NS_FAILED(HandleEventSubType(listener, *aDOMEvent, aCurrentTarget))) {
-            aEvent->mFlags.mExceptionHasBeenRisen = true;
-          }
+            if (mIsMainThreadELM &&
+                listener->mListenerType != Listener::eNativeListener) {
+              nsCOMPtr<nsIDocShell> docShellComPtr = GetDocShellForTarget();
+              if (docShellComPtr) {
+                docShell = static_cast<nsDocShell*>(docShellComPtr.get());
+                if (timelines && timelines->HasConsumer(docShell)) {
+                  needsEndEventMarker = true;
+                  nsAutoString typeStr;
+                  (*aDOMEvent)->GetType(typeStr);
+                  uint16_t phase;
+                  (*aDOMEvent)->GetEventPhase(&phase);
+                  timelines->AddMarkerForDocShell(docShell, Move(
+                    MakeUnique<EventTimelineMarker>(
+                      typeStr, phase, MarkerTracingType::START)));
+                }
+              }
+            }
 
-          if (needsEndEventMarker) {
-            timelines->AddMarkerForDocShell(
-              docShell, "DOMEvent", MarkerTracingType::END);
+            if (NS_FAILED(HandleEventSubType(listener, *aDOMEvent, aCurrentTarget))) {
+              aEvent->mFlags.mExceptionHasBeenRisen = true;
+            }
+
+            if (needsEndEventMarker) {
+              timelines->AddMarkerForDocShell(
+                docShell, "DOMEvent", MarkerTracingType::END);
+            }
           }
         }
       }
     }
+
+    // If we didn't find any matching listeners, and our event has a legacy
+    // version, we'll now switch to looking for that legacy version and we'll
+    // recheck our listeners.
+    if (hasListener || usingLegacyMessage) {
+      // (No need to recheck listeners, because we already found a match, or we
+      // already rechecked them.)
+      break;
+    }
+    EventMessage legacyEventMessage = GetLegacyEventMessage(eventMessage);
+    if (legacyEventMessage == eventMessage) {
+      break; // There's no legacy version of our event; no need to recheck.
+    }
+    MOZ_ASSERT(GetLegacyEventMessage(legacyEventMessage) == legacyEventMessage,
+               "Legacy event messages should not themselves have legacy versions");
+
+    // Recheck our listeners, using the legacy event message we just looked up:
+    eventMessage = legacyEventMessage;
+    usingLegacyMessage = true;
   }
 
   aEvent->currentTarget = nullptr;
 
   if (mIsMainThreadELM && !hasListener) {
     mNoListenerForEvent = aEvent->mMessage;
     mNoListenerForEventAtom = aEvent->userType;
   }
--- a/dom/events/EventListenerManager.h
+++ b/dom/events/EventListenerManager.h
@@ -453,16 +453,23 @@ protected:
                            nsIDOMEvent** aDOMEvent,
                            dom::EventTarget* aCurrentTarget,
                            nsEventStatus* aEventStatus);
 
   nsresult HandleEventSubType(Listener* aListener,
                               nsIDOMEvent* aDOMEvent,
                               dom::EventTarget* aCurrentTarget);
 
+  /**
+   * If the given EventMessage has a legacy version that we support, then this
+   * function returns that legacy version. Otherwise, this function simply
+   * returns the passed-in EventMessage.
+   */
+  EventMessage GetLegacyEventMessage(EventMessage aEventMessage) const;
+
   nsIDocShell* GetDocShellForTarget();
 
   /**
    * Compile the "inline" event listener for aListener.  The
    * body of the listener can be provided in aBody; if this is null we
    * will look for it on mTarget.  If aBody is provided, aElement should be
    * as well; otherwise it will also be inferred from mTarget.
    */
@@ -566,17 +573,19 @@ protected:
                                    const EventListenerFlags& aFlags,
                                    bool aAllEvents = false);
   void RemoveAllListeners();
   const EventTypeData* GetTypeDataForIID(const nsIID& aIID);
   const EventTypeData* GetTypeDataForEventName(nsIAtom* aName);
   nsPIDOMWindowInner* GetInnerWindowForTarget();
   already_AddRefed<nsPIDOMWindowInner> GetTargetAsInnerWindow() const;
 
-  bool ListenerCanHandle(Listener* aListener, WidgetEvent* aEvent);
+  bool ListenerCanHandle(const Listener* aListener,
+                         const WidgetEvent* aEvent,
+                         EventMessage aEventMessage) const;
 
   // BE AWARE, a lot of instances of EventListenerManager will be created.
   // Therefor, we need to keep this class compact.  When you add integer
   // members, please add them to EventListemerManagerBase and check the size
   // at build time.
 
   already_AddRefed<nsIScriptGlobalObject>
   GetScriptGlobalAndDocument(nsIDocument** aDoc);
--- a/dom/events/EventNameList.h
+++ b/dom/events/EventNameList.h
@@ -919,16 +919,17 @@ NON_IDL_EVENT(MozEdgeUICanceled,
               eEdgeUICanceled,
               EventNameType_None,
               eSimpleGestureEventClass)
 NON_IDL_EVENT(MozEdgeUICompleted,
               eEdgeUICompleted,
               EventNameType_None,
               eSimpleGestureEventClass)
 
+// CSS Transition & Animation events:
 NON_IDL_EVENT(transitionend,
               eTransitionEnd,
               EventNameType_None,
               eTransitionEventClass)
 NON_IDL_EVENT(animationstart,
               eAnimationStart,
               EventNameType_None,
               eAnimationEventClass)
@@ -936,16 +937,34 @@ NON_IDL_EVENT(animationend,
               eAnimationEnd,
               EventNameType_None,
               eAnimationEventClass)
 NON_IDL_EVENT(animationiteration,
               eAnimationIteration,
               EventNameType_None,
               eAnimationEventClass)
 
+// Webkit-prefixed versions of Transition & Animation events, for web compat:
+NON_IDL_EVENT(webkitTransitionEnd,
+              eWebkitTransitionEnd,
+              EventNameType_None,
+              eTransitionEventClass)
+NON_IDL_EVENT(webkitAnimationEnd,
+              eWebkitAnimationEnd,
+              EventNameType_None,
+              eAnimationEventClass)
+NON_IDL_EVENT(webkitAnimationIteration,
+              eWebkitAnimationIteration,
+              EventNameType_None,
+              eAnimationEventClass)
+NON_IDL_EVENT(webkitAnimationStart,
+              eWebkitAnimationStart,
+              EventNameType_None,
+              eAnimationEventClass)
+
 NON_IDL_EVENT(audioprocess,
               eAudioProcess,
               EventNameType_None,
               eBasicEventClass)
 
 NON_IDL_EVENT(complete,
               eAudioComplete,
               EventNameType_None,
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -726,17 +726,17 @@ EventStateManager::PreHandleEvent(nsPres
         modifierMask |= NS_MODIFIER_META;
       if (keyEvent->IsOS())
         modifierMask |= NS_MODIFIER_OS;
 
       // Prevent keyboard scrolling while an accesskey modifier is in use.
       if (modifierMask &&
           (modifierMask == Prefs::ChromeAccessModifierMask() ||
            modifierMask == Prefs::ContentAccessModifierMask())) {
-        nsAutoTArray<uint32_t, 10> accessCharCodes;
+        AutoTArray<uint32_t, 10> accessCharCodes;
         nsContentUtils::GetAccessKeyCandidates(keyEvent, accessCharCodes);
 
         if (HandleAccessKey(aPresContext, accessCharCodes,
                             keyEvent->mFlags.mIsTrusted, modifierMask)) {
           *aStatus = nsEventStatus_eConsumeNoDefault;
         }
       }
     }
@@ -1286,17 +1286,17 @@ EventStateManager::HandleCrossProcessEve
       !CrossProcessSafeEvent(*aEvent)) {
     return false;
   }
 
   // Collect the remote event targets we're going to forward this
   // event to.
   //
   // NB: the elements of |targets| must be unique, for correctness.
-  nsAutoTArray<nsCOMPtr<nsIContent>, 1> targets;
+  AutoTArray<nsCOMPtr<nsIContent>, 1> targets;
   if (aEvent->mClass != eTouchEventClass || aEvent->mMessage == eTouchStart) {
     // If this event only has one target, and it's remote, add it to
     // the array.
     nsIFrame* frame = GetEventTarget();
     nsIContent* target = frame ? frame->GetContent() : nullptr;
     if (IsRemoteTarget(target)) {
       targets.AppendElement(target);
     }
--- a/dom/events/TextComposition.h
+++ b/dom/events/TextComposition.h
@@ -424,17 +424,17 @@ private:
  * there.  Even if user switches native IME context, it's very rare that
  * second or more composition is started.
  * It's assumed that this is used by IMEStateManager for storing all active
  * compositions in the process.  If the instance is it, each TextComposition
  * in the array can be destroyed by calling some methods of itself.
  */
 
 class TextCompositionArray final :
-  public nsAutoTArray<RefPtr<TextComposition>, 2>
+  public AutoTArray<RefPtr<TextComposition>, 2>
 {
 public:
   // Looking for per native IME context.
   index_type IndexOf(const widget::NativeIMEContext& aNativeIMEContext);
   index_type IndexOf(nsIWidget* aWidget);
 
   TextComposition* GetCompositionFor(nsIWidget* aWidget);
   TextComposition* GetCompositionFor(
--- a/dom/events/test/mochitest.ini
+++ b/dom/events/test/mochitest.ini
@@ -163,16 +163,17 @@ skip-if = toolkit == 'android' #CRASH_DU
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' # b2g(drag event, also fails on Android) b2g-debug(drag event, also fails on Android) b2g-desktop(drag event, also fails on Android)
 [test_error_events.html]
 skip-if = toolkit == 'android' #TIMED_OUT
 [test_eventctors.html]
 skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
 [test_eventTimeStamp.html]
 [test_focus_disabled.html]
 skip-if = buildapp == 'mulet'
+[test_legacy_event.html]
 [test_messageEvent.html]
 [test_moz_mouse_pixel_scroll_event.html]
 skip-if = buildapp == 'b2g' # bug 1126090, no wheel events on b2g
 [test_onerror_handler_args.html]
 [test_wheel_default_action.html]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || e10s
 [test_dom_before_after_keyboard_event.html]
 support-files =
new file mode 100644
--- /dev/null
+++ b/dom/events/test/test_legacy_event.html
@@ -0,0 +1,256 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1236979
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 1236979 (events that have legacy alternative versions)</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <style>
+    @keyframes anim1 {
+      0%   { margin-left: 0px }
+      100% { margin-left: 100px }
+    }
+  </style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1236979">Mozilla Bug 1236979</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 1236979 **/
+
+'use strict';
+SimpleTest.waitForExplicitFinish();
+
+// Array of info-bundles about each legacy event to be tested:
+var gLegacyEventInfo = [
+  {
+    legacy_name: "webkitTransitionEnd",
+    modern_name: "transitionend",
+    trigger_event: triggerShortTransition,
+  },
+  {
+    legacy_name: "webkitAnimationStart",
+    modern_name: "animationstart",
+    trigger_event: triggerShortAnimation,
+  },
+  {
+    legacy_name: "webkitAnimationEnd",
+    modern_name: "animationend",
+    trigger_event: triggerShortAnimation,
+  },
+  {
+    legacy_name: "webkitAnimationIteration",
+    modern_name: "animationiteration",
+    trigger_event: triggerAnimationIteration,
+  }
+];
+
+// EVENT-TRIGGERING FUNCTIONS
+// --------------------------
+// This function triggers a very short (1ms long) transition, which will cause
+// events to fire for the transition ending.
+function triggerShortTransition(node) {
+  node.style.transition = "1ms color linear" ;
+  node.style.color = "purple";
+  // Flush style, so that the above assignment value actually takes effect
+  // in the computed style, so that a transition will get triggered when it
+  // changes.
+  window.getComputedStyle(node, "").color;
+  node.style.color = "teal";
+}
+
+// This function triggers a very short (1ms long) animation, which will cause
+// events to fire for the animation beginning & ending.
+function triggerShortAnimation(node) {
+  node.style.animation = "anim1 1ms linear";
+}
+
+// This function triggers a long animation with two iterations, which is
+// *nearly* at the end of its first iteration.  It will hit the end of that
+// iteration (firing an event) almost immediately, 1ms in the future.
+//
+// NOTE: It's important that this animation have a *long* duration.  If it were
+// short (e.g. 1ms duration), then we might jump past all its iterations in
+// a single refresh-driver tick. And if that were to happens, we'd *never* fire
+// any animationiteration events -- the CSS Animations spec says this event
+// must not be fired "...when an animationend event would fire at the same time"
+// (which would be the case in this example with a 1ms duration). So, to make
+// sure our event does fire, we use a long duration and a nearly-as-long
+// negative delay. This ensures we hit the end of the first iteration right
+// away, and that we don't risk hitting the end of the second iteration at the
+// same time.
+function triggerAnimationIteration(node) {
+  node.style.animation = "anim1 300s -299.999s linear 2";
+}
+
+// GENERAL UTILITY FUNCTIONS
+// -------------------------
+// Creates a new div and appends it as a child of the specified parentNode, or
+// (if no parent is specified) as a child of the element with ID 'display'.
+function createChildDiv(parentNode) {
+  if (!parentNode) {
+    parentNode = document.getElementById("display");
+    if (!parentNode) {
+      ok(false, "no 'display' element to append to");
+    }
+  }
+  var div = document.createElement("div");
+  parentNode.appendChild(div);
+  return div;
+}
+
+// Returns an event-handler function, which (when invoked) simply checks that
+// the event's type matches what's expected. If a callback is passed in, then
+// the event-handler will invoke that callback as well.
+function createHandlerWithTypeCheck(expectedEventType, extraHandlerLogic) {
+  var handler = function(e) {
+    is(e.type, expectedEventType,
+       "When an event handler for '" + expectedEventType + "' is invoked, " +
+       "the event's type field should be '" + expectedEventType + "'.");
+    if (extraHandlerLogic) {
+      extraHandlerLogic(e);
+    }
+  }
+  return handler;
+}
+
+// TEST FUNCTIONS
+// --------------
+// These functions expect to be passed an entry from gEventInfo, and they
+// return a Promise which performs the test & resolves when it's complete.
+// The function names all begin with "mp", which stands for "make promise".
+// So e.g. "mpTestLegacyEventSent" means "make a promise to test that the
+// legacy event is sent".
+
+// Tests that the legacy event type is sent, when only a legacy handler is
+// registered.
+function mpTestLegacyEventSent(eventInfo) {
+  return new Promise(
+    function(resolve, reject) {
+      // Create a node & register an event-handler for the legacy event:
+      var div = createChildDiv();
+
+      var handler = createHandlerWithTypeCheck(eventInfo.legacy_name,
+                                               function() {
+        // When event-handler is done, clean up & resolve:
+        div.parentNode.removeChild(div);
+        resolve();
+      });
+      div.addEventListener(eventInfo.legacy_name, handler);
+
+      // Trigger the event:
+      eventInfo.trigger_event(div);
+    }
+  );
+}
+
+// Test that the modern event type (and only the modern event type) is fired,
+// when listeners of both modern & legacy types are registered. The legacy
+// listener should not be invoked.
+function mpTestModernBeatsLegacy(eventInfo) {
+  return new Promise(
+    function(resolve, reject) {
+      var div = createChildDiv();
+
+      var legacyHandler = function(e) {
+        reject("Handler for legacy event '" + eventInfo.legacy_name +
+               "' should not be invoked when there's a handler registered " +
+               "for both modern & legacy event type on the same node");
+      };
+
+      var modernHandler = createHandlerWithTypeCheck(eventInfo.modern_name,
+                                                     function() {
+        // Indicate that the test has passed (we invoked the modern handler):
+        ok(true, "Handler for modern event '" + eventInfo.modern_name +
+           "' should be invoked when there's a handler registered for " +
+           "both modern & legacy event type on the same node");
+        // When event-handler is done, clean up & resolve:
+        div.parentNode.removeChild(div);
+        resolve();
+      });
+
+      div.addEventListener(eventInfo.legacy_name, legacyHandler);
+      div.addEventListener(eventInfo.modern_name, modernHandler);
+      eventInfo.trigger_event(div);
+    }
+  );
+}
+
+// Test that an event which bubbles may fire listeners of different flavors
+// (modern vs. legacy) at each bubbling level, depending on what's registered
+// at that level.
+function mpTestAncestorsWithDiffListeners(eventInfo) {
+  return new Promise(
+    function(resolve, reject) {
+      var grandparent = createChildDiv();
+      var parent = createChildDiv(grandparent);
+      var target = createChildDiv(parent);
+      var didEventFireOnTarget = false;
+      var didEventFireOnParent = false;
+      var eventSentToTarget;
+
+      target.addEventListener(eventInfo.modern_name,
+        createHandlerWithTypeCheck(eventInfo.modern_name,
+                                   function(e) {
+                                     ok(e.bubbles, "Expecting event to bubble");
+                                     eventSentToTarget = e;
+                                     didEventFireOnTarget = true;
+                                   }));
+
+      parent.addEventListener(eventInfo.legacy_name,
+        createHandlerWithTypeCheck(eventInfo.legacy_name,
+                                   function(e) {
+                                     is(e, eventSentToTarget,
+                                        "Same event object should bubble, " +
+                                        "despite difference in type");
+                                     didEventFireOnParent = true;
+                                   }));
+
+      grandparent.addEventListener(eventInfo.modern_name,
+        createHandlerWithTypeCheck(eventInfo.modern_name,
+                                   function(e) {
+                                     ok(didEventFireOnTarget,
+                                        "Event should have fired on child");
+                                     ok(didEventFireOnParent,
+                                        "Event should have fired on parent");
+                                     is(e, eventSentToTarget,
+                                        "Same event object should bubble, " +
+                                        "despite difference in type");
+                                     parent.removeChild(target);
+                                     resolve();
+                                   }));
+      eventInfo.trigger_event(target);
+    }
+  );
+}
+
+// MAIN FUNCTION: Kick off the tests.
+function main() {
+  Promise.resolve().then(function() {
+    return Promise.all(gLegacyEventInfo.map(mpTestLegacyEventSent))
+  }).then(function() {
+    return Promise.all(gLegacyEventInfo.map(mpTestModernBeatsLegacy));
+  }).then(function() {
+    return Promise.all(gLegacyEventInfo.map(mpTestAncestorsWithDiffListeners));
+  }).then(function() {
+    SimpleTest.finish();
+  }).catch(function(reason) {
+    ok(false, "Test failed: " + reason);
+    SimpleTest.finish();
+  });
+}
+
+main();
+
+</script>
+</pre>
+</body>
+</html>
--- a/dom/fetch/FetchDriver.cpp
+++ b/dom/fetch/FetchDriver.cpp
@@ -333,17 +333,17 @@ FetchDriver::HttpFetch()
   }
 
   // If preflight is required, start a "CORS preflight fetch"
   // https://fetch.spec.whatwg.org/#cors-preflight-fetch-0. All the
   // implementation is handled by the http channel calling into
   // nsCORSListenerProxy. We just inform it which unsafe headers are included
   // in the request.
   if (mRequest->Mode() == RequestMode::Cors) {
-    nsAutoTArray<nsCString, 5> unsafeHeaders;
+    AutoTArray<nsCString, 5> unsafeHeaders;
     mRequest->Headers()->GetUnsafeHeaders(unsafeHeaders);
     nsCOMPtr<nsILoadInfo> loadInfo = chan->GetLoadInfo();
     loadInfo->SetCorsPreflightInfo(unsafeHeaders, false);
   }
 
   rv = chan->AsyncOpen2(this);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -704,17 +704,17 @@ FetchDriver::SetDocument(nsIDocument* aD
   mDocument = aDocument;
 }
 
 void
 FetchDriver::SetRequestHeaders(nsIHttpChannel* aChannel) const
 {
   MOZ_ASSERT(aChannel);
 
-  nsAutoTArray<InternalHeaders::Entry, 5> headers;
+  AutoTArray<InternalHeaders::Entry, 5> headers;
   mRequest->Headers()->GetEntries(headers);
   bool hasAccept = false;
   for (uint32_t i = 0; i < headers.Length(); ++i) {
     if (!hasAccept && headers[i].mName.EqualsLiteral("accept")) {
       hasAccept = true;
     }
     if (headers[i].mValue.IsEmpty()) {
       aChannel->SetEmptyRequestHeader(headers[i].mName);
--- a/dom/fetch/InternalHeaders.cpp
+++ b/dom/fetch/InternalHeaders.cpp
@@ -304,17 +304,17 @@ InternalHeaders::CORSHeaders(InternalHea
 {
   RefPtr<InternalHeaders> cors = new InternalHeaders(aHeaders->mGuard);
   ErrorResult result;
 
   nsAutoCString acExposedNames;
   aHeaders->Get(NS_LITERAL_CSTRING("Access-Control-Expose-Headers"), acExposedNames, result);
   MOZ_ASSERT(!result.Failed());
 
-  nsAutoTArray<nsCString, 5> exposeNamesArray;
+  AutoTArray<nsCString, 5> exposeNamesArray;
   nsCCharSeparatedTokenizer exposeTokens(acExposedNames, ',');
   while (exposeTokens.hasMoreTokens()) {
     const nsDependentCSubstring& token = exposeTokens.nextToken();
     if (token.IsEmpty()) {
       continue;
     }
 
     if (!NS_IsValidHTTPToken(token)) {
--- a/dom/gamepad/linux/LinuxGamepad.cpp
+++ b/dom/gamepad/linux/LinuxGamepad.cpp
@@ -72,17 +72,17 @@ private:
   static gboolean OnUdevMonitor(GIOChannel *source,
                                 GIOCondition condition,
                                 gpointer data);
 
   udev_lib mUdev;
   struct udev_monitor* mMonitor;
   guint mMonitorSourceID;
   // Information about currently connected gamepads.
-  nsAutoTArray<Gamepad,4> mGamepads;
+  AutoTArray<Gamepad,4> mGamepads;
 };
 
 // singleton instance
 LinuxGamepadService* gService = nullptr;
 
 void
 LinuxGamepadService::AddDevice(struct udev_device* dev)
 {
--- a/dom/html/HTMLAllCollection.cpp
+++ b/dom/html/HTMLAllCollection.cpp
@@ -168,17 +168,17 @@ void
 HTMLAllCollection::GetSupportedNames(unsigned aFlags, nsTArray<nsString>& aNames)
 {
   if (!(aFlags & JSITER_HIDDEN)) {
     return;
   }
 
   // XXXbz this is very similar to nsContentList::GetSupportedNames,
   // but has to check IsAllNamedElement for the name case.
-  nsAutoTArray<nsIAtom*, 8> atoms;
+  AutoTArray<nsIAtom*, 8> atoms;
   for (uint32_t i = 0; i < Length(); ++i) {
     nsIContent *content = Item(i);
     if (content->HasID()) {
       nsIAtom* id = content->GetID();
       MOZ_ASSERT(id != nsGkAtoms::_empty,
                  "Empty ids don't get atomized");
       if (!atoms.Contains(id)) {
         atoms.AppendElement(id);
--- a/dom/html/HTMLOptionsCollection.cpp
+++ b/dom/html/HTMLOptionsCollection.cpp
@@ -282,17 +282,17 @@ HTMLOptionsCollection::NamedItem(const n
 void
 HTMLOptionsCollection::GetSupportedNames(unsigned aFlags,
                                          nsTArray<nsString>& aNames)
 {
   if (!(aFlags & JSITER_HIDDEN)) {
     return;
   }
 
-  nsAutoTArray<nsIAtom*, 8> atoms;
+  AutoTArray<nsIAtom*, 8> atoms;
   for (uint32_t i = 0; i < mElements.Length(); ++i) {
     HTMLOptionElement* content = mElements.ElementAt(i);
     if (content) {
       // Note: HasName means the names is exposed on the document,
       // which is false for options, so we don't check it here.
       const nsAttrValue* val = content->GetParsedAttr(nsGkAtoms::name);
       if (val && val->Type() == nsAttrValue::eAtom) {
         nsIAtom* name = val->GetAtomValue();
--- a/dom/html/TimeRanges.cpp
+++ b/dom/html/TimeRanges.cpp
@@ -107,17 +107,17 @@ TimeRanges::GetEndTime()
   }
   return mRanges[mRanges.Length() - 1].mEnd;
 }
 
 void
 TimeRanges::Normalize(double aTolerance)
 {
   if (mRanges.Length() >= 2) {
-    nsAutoTArray<TimeRange,4> normalized;
+    AutoTArray<TimeRange,4> normalized;
 
     mRanges.Sort(CompareTimeRanges());
 
     // This merges the intervals.
     TimeRange current(mRanges[0]);
     for (uint32_t i = 1; i < mRanges.Length(); i++) {
       if (current.mStart <= mRanges[i].mStart &&
           current.mEnd >= mRanges[i].mEnd) {
@@ -142,17 +142,17 @@ TimeRanges::Union(const TimeRanges* aOth
 {
   mRanges.AppendElements(aOtherRanges->mRanges);
   Normalize(aTolerance);
 }
 
 void
 TimeRanges::Intersection(const TimeRanges* aOtherRanges)
 {
-  nsAutoTArray<TimeRange,4> intersection;
+  AutoTArray<TimeRange,4> intersection;
 
   const nsTArray<TimeRange>& otherRanges = aOtherRanges->mRanges;
   for (index_type i = 0, j = 0; i < mRanges.Length() && j < otherRanges.Length();) {
     double start = std::max(mRanges[i].mStart, otherRanges[j].mStart);
     double end = std::min(mRanges[i].mEnd, otherRanges[j].mEnd);
     if (start < end) {
       intersection.AppendElement(TimeRange(start, end));
     }
--- a/dom/html/TimeRanges.h
+++ b/dom/html/TimeRanges.h
@@ -88,17 +88,17 @@ private:
       return aTr1.mStart == aTr2.mStart && aTr1.mEnd == aTr2.mEnd;
     }
 
     bool LessThan(const TimeRange& aTr1, const TimeRange& aTr2) const {
       return aTr1.mStart < aTr2.mStart;
     }
   };
 
-  nsAutoTArray<TimeRange,4> mRanges;
+  AutoTArray<TimeRange,4> mRanges;
 
   nsCOMPtr<nsISupports> mParent;
 
 public:
   typedef nsTArray<TimeRange>::index_type index_type;
   static const index_type NoIndex = index_type(-1);
 
   index_type Find(double aTime, double aTolerance = 0);
--- a/dom/html/nsHTMLContentSink.cpp
+++ b/dom/html/nsHTMLContentSink.cpp
@@ -155,17 +155,17 @@ protected:
 
   // The maximum length of a text run
   int32_t mMaxTextRun;
 
   RefPtr<nsGenericHTMLElement> mRoot;
   RefPtr<nsGenericHTMLElement> mBody;
   RefPtr<nsGenericHTMLElement> mHead;
 
-  nsAutoTArray<SinkContext*, 8> mContextStack;
+  AutoTArray<SinkContext*, 8> mContextStack;
   SinkContext* mCurrentContext;
   SinkContext* mHeadContext;
 
   // Boolean indicating whether we've seen a <head> tag that might have had
   // attributes once already.
   bool mHaveSeenHead;
 
   // Boolean indicating whether we've notified insertion of our root content
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -833,20 +833,19 @@ MakeCompressedIndexDataValues(
 
   aCompressedIndexDataValues.swap(blobData);
   *aCompressedIndexDataValuesLength = uint32_t(blobDataLength);
 
   return NS_OK;
 }
 
 nsresult
-ReadCompressedIndexDataValuesFromBlob(
-                                   const uint8_t* aBlobData,
-                                   uint32_t aBlobDataLength,
-                                   FallibleTArray<IndexDataValue>& aIndexValues)
+ReadCompressedIndexDataValuesFromBlob(const uint8_t* aBlobData,
+                                      uint32_t aBlobDataLength,
+                                      nsTArray<IndexDataValue>& aIndexValues)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(!IsOnBackgroundThread());
   MOZ_ASSERT(aBlobData);
   MOZ_ASSERT(aBlobDataLength);
   MOZ_ASSERT(aIndexValues.IsEmpty());
 
   PROFILER_LABEL("IndexedDB",
@@ -911,20 +910,19 @@ ReadCompressedIndexDataValuesFromBlob(
   MOZ_ASSERT(blobDataIter == blobDataEnd);
 
   return NS_OK;
 }
 
 // static
 template <typename T>
 nsresult
-ReadCompressedIndexDataValuesFromSource(
-                                   T* aSource,
-                                   uint32_t aColumnIndex,
-                                   FallibleTArray<IndexDataValue>& aIndexValues)
+ReadCompressedIndexDataValuesFromSource(T* aSource,
+                                        uint32_t aColumnIndex,
+                                        nsTArray<IndexDataValue>& aIndexValues)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(!IsOnBackgroundThread());
   MOZ_ASSERT(aSource);
   MOZ_ASSERT(aIndexValues.IsEmpty());
 
   int32_t columnType;
   nsresult rv = aSource->GetTypeOfIndex(aColumnIndex, &columnType);
@@ -958,27 +956,27 @@ ReadCompressedIndexDataValuesFromSource(
   }
 
   return NS_OK;
 }
 
 nsresult
 ReadCompressedIndexDataValues(mozIStorageStatement* aStatement,
                               uint32_t aColumnIndex,
-                              FallibleTArray<IndexDataValue>& aIndexValues)
+                              nsTArray<IndexDataValue>& aIndexValues)
 {
   return ReadCompressedIndexDataValuesFromSource(aStatement,
                                                  aColumnIndex,
                                                  aIndexValues);
 }
 
 nsresult
 ReadCompressedIndexDataValues(mozIStorageValueArray* aValues,
                               uint32_t aColumnIndex,
-                              FallibleTArray<IndexDataValue>& aIndexValues)
+                              nsTArray<IndexDataValue>& aIndexValues)
 {
   return ReadCompressedIndexDataValuesFromSource(aValues,
                                                  aColumnIndex,
                                                  aIndexValues);
 }
 
 nsresult
 CreateFileTables(mozIStorageConnection* aConnection)
@@ -2763,17 +2761,17 @@ InsertIndexDataValuesFunction::OnFunctio
 
     MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aValues->GetTypeOfIndex(3, &valueType)));
     MOZ_ASSERT(valueType == mozIStorageValueArray::VALUE_TYPE_BLOB);
   }
 #endif
 
   // Read out the previous value. It may be NULL, in which case we'll just end
   // up with an empty array.
-  AutoFallibleTArray<IndexDataValue, 32> indexValues;
+  AutoTArray<IndexDataValue, 32> indexValues;
   nsresult rv = ReadCompressedIndexDataValues(aValues, 0, indexValues);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   int64_t indexId;
   rv = aValues->GetInt64(1, &indexId);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -3861,30 +3859,30 @@ private:
   ~UpgradeIndexDataValuesFunction()
   {
     AssertIsOnIOThread();
   }
 
   nsresult
   ReadOldCompressedIDVFromBlob(const uint8_t* aBlobData,
                                uint32_t aBlobDataLength,
-                               FallibleTArray<IndexDataValue>& aIndexValues);
+                               nsTArray<IndexDataValue>& aIndexValues);
 
   NS_IMETHOD
   OnFunctionCall(mozIStorageValueArray* aArguments,
                  nsIVariant** aResult) override;
 };
 
 NS_IMPL_ISUPPORTS(UpgradeIndexDataValuesFunction, mozIStorageFunction)
 
 nsresult
 UpgradeIndexDataValuesFunction::ReadOldCompressedIDVFromBlob(
                                    const uint8_t* aBlobData,
                                    uint32_t aBlobDataLength,
-                                   FallibleTArray<IndexDataValue>& aIndexValues)
+                                   nsTArray<IndexDataValue>& aIndexValues)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(!IsOnBackgroundThread());
   MOZ_ASSERT(aBlobData);
   MOZ_ASSERT(aBlobDataLength);
   MOZ_ASSERT(aIndexValues.IsEmpty());
 
   const uint8_t* blobDataIter = aBlobData;
@@ -3986,17 +3984,17 @@ UpgradeIndexDataValuesFunction::OnFuncti
 
   const uint8_t* oldBlob;
   uint32_t oldBlobLength;
   rv = aArguments->GetSharedBlob(0, &oldBlobLength, &oldBlob);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  AutoFallibleTArray<IndexDataValue, 32> oldIdv;
+  AutoTArray<IndexDataValue, 32> oldIdv;
   rv = ReadOldCompressedIDVFromBlob(oldBlob, oldBlobLength, oldIdv);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   UniqueFreePtr<uint8_t> newIdv;
   uint32_t newIdvLength;
   rv = MakeCompressedIndexDataValues(oldIdv, newIdv, &newIdvLength);
@@ -5857,20 +5855,19 @@ protected:
 
   static nsresult
   GetUniqueIndexTableForObjectStore(
                                TransactionBase* aTransaction,
                                int64_t aObjectStoreId,
                                Maybe<UniqueIndexTable>& aMaybeUniqueIndexTable);
 
   static nsresult
-  IndexDataValuesFromUpdateInfos(
-                              const nsTArray<IndexUpdateInfo>& aUpdateInfos,
-                              const UniqueIndexTable& aUniqueIndexTable,
-                              FallibleTArray<IndexDataValue>& aIndexValues);
+  IndexDataValuesFromUpdateInfos(const nsTArray<IndexUpdateInfo>& aUpdateInfos,
+                                 const UniqueIndexTable& aUniqueIndexTable,
+                                 nsTArray<IndexDataValue>& aIndexValues);
 
   static nsresult
   InsertIndexTableRows(DatabaseConnection* aConnection,
                        const int64_t aObjectStoreId,
                        const Key& aObjectStoreKey,
                        const FallibleTArray<IndexDataValue>& aIndexValues);
 
   static nsresult
@@ -7907,17 +7904,17 @@ private:
                 const bool aIsLastIndex);
 
   ~DeleteIndexOp()
   { }
 
   nsresult
   RemoveReferencesToIndex(DatabaseConnection* aConnection,
                           const Key& aObjectDataKey,
-                          FallibleTArray<IndexDataValue>& aIndexValues);
+                          nsTArray<IndexDataValue>& aIndexValues);
 
   virtual nsresult
   DoDatabaseWork(DatabaseConnection* aConnection) override;
 };
 
 class NormalTransactionOp
   : public TransactionDatabaseOperationBase
   , public PBackgroundIDBRequestParent
@@ -8045,17 +8042,17 @@ struct ObjectStoreAddOrPutRequestOp::Sto
 class ObjectStoreGetRequestOp final
   : public NormalTransactionOp
 {
   friend class TransactionBase;
 
   const uint32_t mObjectStoreId;
   RefPtr<Database> mDatabase;
   const OptionalKeyRange mOptionalKeyRange;
-  AutoFallibleTArray<StructuredCloneReadInfo, 1> mResponse;
+  AutoTArray<StructuredCloneReadInfo, 1> mResponse;
   PBackgroundParent* mBackgroundParent;
   const uint32_t mLimit;
   const bool mGetAll;
 
 private:
   // Only created by TransactionBase.
   ObjectStoreGetRequestOp(TransactionBase* aTransaction,
                           const RequestParams& aParams,
@@ -8206,17 +8203,17 @@ private:
 
 class IndexGetRequestOp final
   : public IndexRequestOpBase
 {
   friend class TransactionBase;
 
   RefPtr<Database> mDatabase;
   const OptionalKeyRange mOptionalKeyRange;
-  AutoFallibleTArray<StructuredCloneReadInfo, 1> mResponse;
+  AutoTArray<StructuredCloneReadInfo, 1> mResponse;
   PBackgroundParent* mBackgroundParent;
   const uint32_t mLimit;
   const bool mGetAll;
 
 private:
   // Only created by TransactionBase.
   IndexGetRequestOp(TransactionBase* aTransaction,
                     const RequestParams& aParams,
@@ -8233,17 +8230,17 @@ private:
 };
 
 class IndexGetKeyRequestOp final
   : public IndexRequestOpBase
 {
   friend class TransactionBase;
 
   const OptionalKeyRange mOptionalKeyRange;
-  AutoFallibleTArray<Key, 1> mResponse;
+  AutoTArray<Key, 1> mResponse;
   const uint32_t mLimit;
   const bool mGetAll;
 
 private:
   // Only created by TransactionBase.
   IndexGetKeyRequestOp(TransactionBase* aTransaction,
                        const RequestParams& aParams,
                        bool aGetAll);
@@ -16347,20 +16344,20 @@ QuotaClient::InitOrigin(PersistenceType 
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   // We need to see if there are any files in the directory already. If they
   // are database files then we need to cleanup stored files (if it's needed)
   // and also get the usage.
 
-  nsAutoTArray<nsString, 20> subdirsToProcess;
+  AutoTArray<nsString, 20> subdirsToProcess;
   nsTArray<nsCOMPtr<nsIFile>> unknownFiles;
   nsTHashtable<nsStringHashKey> validSubdirs(20);
-  nsAutoTArray<FileManagerInitInfo, 20> initInfos;
+  AutoTArray<FileManagerInitInfo, 20> initInfos;
 
   nsCOMPtr<nsISimpleEnumerator> entries;
   rv = directory->GetDirectoryEntries(getter_AddRefs(entries));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   const NS_ConvertASCIItoUTF16 filesSuffix(
@@ -18197,32 +18194,32 @@ DatabaseOperationBase::GetStructuredClon
   size_t compressedLength = size_t(aBlobDataLength);
 
   size_t uncompressedLength;
   if (NS_WARN_IF(!snappy::GetUncompressedLength(compressed, compressedLength,
                                                 &uncompressedLength))) {
     return NS_ERROR_FILE_CORRUPTED;
   }
 
-  AutoFallibleTArray<uint8_t, 512> uncompressed;
+  AutoTArray<uint8_t, 512> uncompressed;
   if (NS_WARN_IF(!uncompressed.SetLength(uncompressedLength, fallible))) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   char* uncompressedBuffer = reinterpret_cast<char*>(uncompressed.Elements());
 
   if (NS_WARN_IF(!snappy::RawUncompress(compressed, compressedLength,
                                         uncompressedBuffer))) {
     return NS_ERROR_FILE_CORRUPTED;
   }
 
   aInfo->mData.SwapElements(uncompressed);
 
   if (!aFileIds.IsVoid()) {
-    nsAutoTArray<int64_t, 10> array;
+    AutoTArray<int64_t, 10> array;
     nsresult rv = ConvertFileIdsToArray(aFileIds, array);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     for (uint32_t count = array.Length(), index = 0; index < count; index++) {
       int64_t id = array[index];
       MOZ_ASSERT(id != 0);
@@ -18398,17 +18395,17 @@ DatabaseOperationBase::GetUniqueIndexTab
   return NS_OK;
 }
 
 // static
 nsresult
 DatabaseOperationBase::IndexDataValuesFromUpdateInfos(
                                   const nsTArray<IndexUpdateInfo>& aUpdateInfos,
                                   const UniqueIndexTable& aUniqueIndexTable,
-                                  FallibleTArray<IndexDataValue>& aIndexValues)
+                                  nsTArray<IndexDataValue>& aIndexValues)
 {
   MOZ_ASSERT(aIndexValues.IsEmpty());
   MOZ_ASSERT_IF(!aUpdateInfos.IsEmpty(), aUniqueIndexTable.Count());
 
   PROFILER_LABEL("IndexedDB",
                  "DatabaseOperationBase::IndexDataValuesFromUpdateInfos",
                  js::ProfileEntry::Category::STORAGE);
 
@@ -18718,17 +18715,17 @@ DatabaseOperationBase::DeleteObjectStore
   }
 
   rv = selectStmt->BindInt64ByName(objectStoreIdString, aObjectStoreId);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   DatabaseConnection::CachedStatement deleteStmt;
-  AutoFallibleTArray<IndexDataValue, 32> indexValues;
+  AutoTArray<IndexDataValue, 32> indexValues;
 
   DebugOnly<uint32_t> resultCountDEBUG = 0;
 
   bool hasResult;
   while (NS_SUCCEEDED(rv = selectStmt->ExecuteStep(&hasResult)) && hasResult) {
     if (!singleRowOnly) {
       rv = objectStoreKey.SetFromStatement(selectStmt, 1);
       if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -23339,17 +23336,17 @@ UpdateIndexDataValuesFunction::OnFunctio
                                                         cloneInfo,
                                                         &clone))) {
     return NS_ERROR_DOM_DATA_CLONE_ERR;
   }
 
   const IndexMetadata& metadata = mOp->mMetadata;
   const int64_t& objectStoreId = mOp->mObjectStoreId;
 
-  nsAutoTArray<IndexUpdateInfo, 32> updateInfos;
+  AutoTArray<IndexUpdateInfo, 32> updateInfos;
   rv = IDBObjectStore::AppendIndexUpdateInfo(metadata.id(),
                                              metadata.keyPath(),
                                              metadata.unique(),
                                              metadata.multiEntry(),
                                              metadata.locale(),
                                              mCx,
                                              clone,
                                              updateInfos);
@@ -23405,17 +23402,17 @@ UpdateIndexDataValuesFunction::OnFunctio
   }
 
   Key key;
   rv = key.SetFromValueArray(aValues, 0);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  AutoFallibleTArray<IndexDataValue, 32> indexValues;
+  AutoTArray<IndexDataValue, 32> indexValues;
   rv = ReadCompressedIndexDataValues(aValues, 1, indexValues);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   const bool hadPreviousIndexValues = !indexValues.IsEmpty();
 
   const uint32_t updateInfoCount = updateInfos.Length();
@@ -23504,20 +23501,19 @@ DeleteIndexOp::DeleteIndexOp(VersionChan
   , mUnique(aUnique)
   , mIsLastIndex(aIsLastIndex)
 {
   MOZ_ASSERT(aObjectStoreId);
   MOZ_ASSERT(aIndexId);
 }
 
 nsresult
-DeleteIndexOp::RemoveReferencesToIndex(
-                                   DatabaseConnection* aConnection,
-                                   const Key& aObjectStoreKey,
-                                   FallibleTArray<IndexDataValue>& aIndexValues)
+DeleteIndexOp::RemoveReferencesToIndex(DatabaseConnection* aConnection,
+                                       const Key& aObjectStoreKey,
+                                       nsTArray<IndexDataValue>& aIndexValues)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(!IsOnBackgroundThread());
   MOZ_ASSERT(aConnection);
   MOZ_ASSERT(!aObjectStoreKey.IsUnset());
   MOZ_ASSERT_IF(!mIsLastIndex, !aIndexValues.IsEmpty());
 
   struct MOZ_STACK_CLASS IndexIdComparator final
@@ -23762,17 +23758,17 @@ DeleteIndexOp::DoDatabaseWork(DatabaseCo
 
   NS_NAMED_LITERAL_CSTRING(valueString, "value");
   NS_NAMED_LITERAL_CSTRING(objectDataKeyString, "object_data_key");
 
   DatabaseConnection::CachedStatement deleteIndexRowStmt;
   DatabaseConnection::CachedStatement nullIndexDataValuesStmt;
 
   Key lastObjectStoreKey;
-  AutoFallibleTArray<IndexDataValue, 32> lastIndexValues;
+  AutoTArray<IndexDataValue, 32> lastIndexValues;
 
   bool hasResult;
   while (NS_SUCCEEDED(rv = selectStmt->ExecuteStep(&hasResult)) && hasResult) {
     // We always need the index key to delete the index row.
     Key indexKey;
     rv = indexKey.SetFromStatement(selectStmt, 0);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
@@ -24106,17 +24102,17 @@ ObjectStoreAddOrPutRequestOp::RemoveOldI
 
   bool hasResult;
   rv = indexValuesStmt->ExecuteStep(&hasResult);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (hasResult) {
-    AutoFallibleTArray<IndexDataValue, 32> existingIndexValues;
+    AutoTArray<IndexDataValue, 32> existingIndexValues;
     rv = ReadCompressedIndexDataValues(indexValuesStmt,
                                         0,
                                         existingIndexValues);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     rv = DeleteIndexDataTableRows(aConnection, mResponse, existingIndexValues);
@@ -24634,17 +24630,17 @@ ObjectStoreAddOrPutRequestOp::DoDatabase
     return rv;
   }
 
   // Update our indexes if needed.
   if (!mParams.indexUpdateInfos().IsEmpty()) {
     MOZ_ASSERT(mUniqueIndexTable.isSome());
 
     // Write the index_data_values column.
-    AutoFallibleTArray<IndexDataValue, 32> indexValues;
+    AutoTArray<IndexDataValue, 32> indexValues;
     rv = IndexDataValuesFromUpdateInfos(mParams.indexUpdateInfos(),
                                         mUniqueIndexTable.ref(),
                                         indexValues);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     rv = UpdateIndexValues(aConnection, osid, key, indexValues);
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -662,17 +662,17 @@ IDBDatabase::Transaction(const StringOrS
     IDB_REPORT_INTERNAL_ERR();
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
   if (mClosed || RunningVersionChangeTransaction()) {
     return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
   }
 
-  nsAutoTArray<nsString, 1> stackSequence;
+  AutoTArray<nsString, 1> stackSequence;
 
   if (aStoreNames.IsString()) {
     stackSequence.AppendElement(aStoreNames.GetAsString());
   } else {
     MOZ_ASSERT(aStoreNames.IsStringSequence());
     if (aStoreNames.GetAsStringSequence().IsEmpty()) {
       return NS_ERROR_DOM_INVALID_ACCESS_ERR;
     }
@@ -843,18 +843,18 @@ IDBDatabase::UnregisterTransaction(IDBTr
 
 void
 IDBDatabase::AbortTransactions(bool aShouldWarn)
 {
   AssertIsOnOwningThread();
 
   class MOZ_STACK_CLASS Helper final
   {
-    typedef nsAutoTArray<RefPtr<IDBTransaction>, 20> StrongTransactionArray;
-    typedef nsAutoTArray<IDBTransaction*, 20> WeakTransactionArray;
+    typedef AutoTArray<RefPtr<IDBTransaction>, 20> StrongTransactionArray;
+    typedef AutoTArray<IDBTransaction*, 20> WeakTransactionArray;
 
   public:
     static void
     AbortTransactions(IDBDatabase* aDatabase, const bool aShouldWarn)
     {
       MOZ_ASSERT(aDatabase);
       aDatabase->AssertIsOnOwningThread();
 
--- a/dom/indexedDB/Key.cpp
+++ b/dom/indexedDB/Key.cpp
@@ -465,17 +465,17 @@ Key::EncodeLocaleString(const nsDependen
 
   UErrorCode uerror = U_ZERO_ERROR;
   UCollator* collator = ucol_open(aLocale.get(), &uerror);
   if (NS_WARN_IF(U_FAILURE(uerror))) {
     return NS_ERROR_FAILURE;
   }
   MOZ_ASSERT(collator);
 
-  nsAutoTArray<uint8_t, 128> keyBuffer;
+  AutoTArray<uint8_t, 128> keyBuffer;
   int32_t sortKeyLength = ucol_getSortKey(collator, ustr, length,
                                           keyBuffer.Elements(),
                                           keyBuffer.Length());
   if (sortKeyLength > (int32_t)keyBuffer.Length()) {
     keyBuffer.SetLength(sortKeyLength);
     sortKeyLength = ucol_getSortKey(collator, ustr, length,
                                     keyBuffer.Elements(),
                                     sortKeyLength);
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -602,17 +602,17 @@ public:
 
 NS_IMPL_ISUPPORTS(ContentParentsMemoryReporter, nsIMemoryReporter)
 
 NS_IMETHODIMP
 ContentParentsMemoryReporter::CollectReports(nsIMemoryReporterCallback* cb,
                                              nsISupports* aClosure,
                                              bool aAnonymize)
 {
-  nsAutoTArray<ContentParent*, 16> cps;
+  AutoTArray<ContentParent*, 16> cps;
   ContentParent::GetAllEvenIfDead(cps);
 
   for (uint32_t i = 0; i < cps.Length(); i++) {
     ContentParent* cp = cps[i];
     MessageChannel* channel = cp->GetIPCChannel();
 
     nsString friendlyName;
     cp->FriendlyName(friendlyName, aAnonymize);
@@ -906,17 +906,17 @@ ContentParent::JoinProcessesIOThread(con
   // Don't touch any arguments to this function from now on.
 }
 
 /*static*/ void
 ContentParent::JoinAllSubprocesses()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  nsAutoTArray<ContentParent*, 8> processes;
+  AutoTArray<ContentParent*, 8> processes;
   GetAll(processes);
   if (processes.IsEmpty()) {
     printf_stderr("There are no live subprocesses.");
     return;
   }
 
   printf_stderr("Subprocesses are still alive.  Doing emergency join.\n");
 
@@ -5140,17 +5140,17 @@ ContentParent::IgnoreIPCPrincipal()
                                  "dom.testing.ignore_ipc_principal", false);
   }
   return sIgnoreIPCPrincipal;
 }
 
 void
 ContentParent::NotifyUpdatedDictionaries()
 {
-  nsAutoTArray<ContentParent*, 8> processes;
+  AutoTArray<ContentParent*, 8> processes;
   GetAll(processes);
 
   nsCOMPtr<nsISpellChecker> spellChecker(do_GetService(NS_SPELLCHECKER_CONTRACTID));
   MOZ_ASSERT(spellChecker, "No spell checker?");
 
   InfallibleTArray<nsString> dictionaries;
   spellChecker->GetDictionaryList(&dictionaries);
 
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -65,16 +65,17 @@ using mozilla::WritingMode from "mozilla
 using mozilla::layers::AsyncDragMetrics from "mozilla/layers/AsyncDragMetrics.h";
 using mozilla::layers::TouchBehaviorFlags from "mozilla/layers/APZUtils.h";
 using nsIWidget::TouchPointerState from "nsIWidget.h";
 using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h";
 using class mozilla::dom::ipc::StructuredCloneData from "ipc/IPCMessageUtils.h";
 using mozilla::EventMessage from "mozilla/EventForwards.h";
 using nsEventStatus from "mozilla/EventForwards.h";
 using nsSizeMode from "nsIWidgetListener.h";
+using mozilla::widget::CandidateWindowPosition from "ipc/nsGUIEventIPC.h";
 
 namespace mozilla {
 namespace dom {
 
 struct NativeKeyBinding
 {
   CommandInt[] singleLineCommands;
   CommandInt[] multiLineCommands;
@@ -279,17 +280,17 @@ parent:
      *
      * aFocused  Whether or not a plugin is focused
      */
     prio(urgent) async SetPluginFocused(bool aFocused);
 
     /**
      * Set IME candidate window by windowless plugin if plugin has focus.
      */
-    async SetCandidateWindowForPlugin(int32_t aX, int32_t aY);
+    async SetCandidateWindowForPlugin(CandidateWindowPosition aPosition);
 
     /**
      *  When plugin event isn't consumed, call this
      */
     async DefaultProcOfPluginEvent(WidgetPluginEvent aEvent);
 
     /**
      * Request that the parent process move focus to the browser's frame. If
--- a/dom/ipc/PreallocatedProcessManager.cpp
+++ b/dom/ipc/PreallocatedProcessManager.cpp
@@ -66,18 +66,18 @@ public:
 
 private:
   void NuwaFork();
 
   // initialization off the critical path of app startup.
   CancelableTask* mPreallocateAppProcessTask;
 
   // The array containing the preallocated processes. 4 as the inline storage size
-  // should be enough so we don't need to grow the nsAutoTArray.
-  nsAutoTArray<RefPtr<ContentParent>, 4> mSpareProcesses;
+  // should be enough so we don't need to grow the AutoTArray.
+  AutoTArray<RefPtr<ContentParent>, 4> mSpareProcesses;
 
   // Nuwa process is ready for creating new process.
   bool mIsNuwaReady;
 #endif
 
 private:
   static mozilla::StaticRefPtr<PreallocatedProcessManagerImpl> sSingleton;
 
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -701,17 +701,17 @@ private:
   RefPtr<nsIContentChild> mManager;
   uint32_t mChromeFlags;
   int32_t mActiveSuppressDisplayport;
   uint64_t mLayersId;
   CSSRect mUnscaledOuterRect;
   // Whether we have already received a FileDescriptor for the app package.
   bool mAppPackageFileDescriptorRecved;
   // At present only 1 of these is really expected.
-  nsAutoTArray<nsAutoPtr<CachedFileDescriptorInfo>, 1>
+  AutoTArray<nsAutoPtr<CachedFileDescriptorInfo>, 1>
       mCachedFileDescriptorInfos;
   nscolor mLastBackgroundColor;
   bool mDidFakeShow;
   bool mNotified;
   bool mTriedBrowserInit;
   ScreenOrientationInternal mOrientation;
   bool mUpdateHitRegion;
 
@@ -729,17 +729,17 @@ private:
   double mDefaultScale;
 
   bool mIPCOpen;
   bool mParentIsActive;
   bool mAsyncPanZoomEnabled;
   CSSSize mUnscaledInnerSize;
   bool mDidSetRealShowInfo;
 
-  nsAutoTArray<bool, NUMBER_OF_AUDIO_CHANNELS> mAudioChannelsActive;
+  AutoTArray<bool, NUMBER_OF_AUDIO_CHANNELS> mAudioChannelsActive;
 
   DISALLOW_EVIL_CONSTRUCTORS(TabChild);
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_TabChild_h
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -1492,19 +1492,19 @@ DoCommandCallback(mozilla::Command aComm
 {
   static_cast<InfallibleTArray<mozilla::CommandInt>*>(aData)->AppendElement(aCommand);
 }
 
 bool
 TabParent::RecvRequestNativeKeyBindings(const WidgetKeyboardEvent& aEvent,
                                         MaybeNativeKeyBinding* aBindings)
 {
-  AutoInfallibleTArray<mozilla::CommandInt, 4> singleLine;
-  AutoInfallibleTArray<mozilla::CommandInt, 4> multiLine;
-  AutoInfallibleTArray<mozilla::CommandInt, 4> richText;
+  AutoTArray<mozilla::CommandInt, 4> singleLine;
+  AutoTArray<mozilla::CommandInt, 4> multiLine;
+  AutoTArray<mozilla::CommandInt, 4> richText;
 
   *aBindings = mozilla::void_t();
 
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget) {
     return true;
   }
 
@@ -1706,19 +1706,19 @@ bool TabParent::SendRealKeyEvent(WidgetK
   }
   event.refPoint += GetChildProcessOffset();
 
   MaybeNativeKeyBinding bindings;
   bindings = void_t();
   if (event.mMessage == eKeyPress) {
     nsCOMPtr<nsIWidget> widget = GetWidget();
 
-    AutoInfallibleTArray<mozilla::CommandInt, 4> singleLine;
-    AutoInfallibleTArray<mozilla::CommandInt, 4> multiLine;
-    AutoInfallibleTArray<mozilla::CommandInt, 4> richText;
+    AutoTArray<mozilla::CommandInt, 4> singleLine;
+    AutoTArray<mozilla::CommandInt, 4> multiLine;
+    AutoTArray<mozilla::CommandInt, 4> richText;
 
     widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForSingleLineEditor,
                                     event, DoCommandCallback, &singleLine);
     widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForMultiLineEditor,
                                     event, DoCommandCallback, &multiLine);
     widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForRichTextEditor,
                                     event, DoCommandCallback, &richText);
 
@@ -2387,25 +2387,25 @@ TabParent::RecvSetPluginFocused(const bo
   if (!widget) {
     return true;
   }
   widget->SetPluginFocused((bool&)aFocused);
   return true;
 }
 
  bool
-TabParent::RecvSetCandidateWindowForPlugin(const int32_t& aX,
-                                           const int32_t& aY)
+TabParent::RecvSetCandidateWindowForPlugin(
+             const CandidateWindowPosition& aPosition)
 {
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget) {
     return true;
   }
 
-  widget->SetCandidateWindowForPlugin(aX, aY);
+  widget->SetCandidateWindowForPlugin(aPosition);
   return true;
 }
 
 bool
 TabParent::RecvDefaultProcOfPluginEvent(const WidgetPluginEvent& aEvent)
 {
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget) {
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -233,18 +233,18 @@ public:
   virtual bool
   RecvStartPluginIME(const WidgetKeyboardEvent& aKeyboardEvent,
                      const int32_t& aPanelX,
                      const int32_t& aPanelY,
                      nsString* aCommitted) override;
 
   virtual bool RecvSetPluginFocused(const bool& aFocused) override;
 
-  virtual bool RecvSetCandidateWindowForPlugin(const int32_t& aX,
-                                               const int32_t& aY) override;
+  virtual bool RecvSetCandidateWindowForPlugin(
+                 const widget::CandidateWindowPosition& aPosition) override;
 
   virtual bool
   RecvDefaultProcOfPluginEvent(const WidgetPluginEvent& aEvent) override;
 
   virtual bool RecvGetInputContext(int32_t* aIMEEnabled,
                                    int32_t* aIMEOpen) override;
 
   virtual bool RecvSetInputContext(const int32_t& aIMEEnabled,
--- a/dom/locales/en-US/chrome/dom/dom.properties
+++ b/dom/locales/en-US/chrome/dom/dom.properties
@@ -184,11 +184,21 @@ InterceptedUsedResponseWithURL=Failed to
 BadOpaqueRedirectInterceptionWithURL=Failed to load '%S'. A ServiceWorker passed an opaqueredirect Response to FetchEvent.respondWith() while handling a non-navigation FetchEvent.
 # LOCALIZATION NOTE: Do not translate "ServiceWorker" or "FetchEvent.preventDefault()". %S is a URL.
 InterceptionCanceledWithURL=Failed to load '%S'. A ServiceWorker canceled the load by calling FetchEvent.preventDefault().
 # LOCALIZATION NOTE: Do not translate "ServiceWorker", "promise", or "FetchEvent.respondWith()". %1$S is a URL. %2$S is an error string.
 InterceptionRejectedResponseWithURL=Failed to load '%1$S'. A ServiceWorker passed a promise to FetchEvent.respondWith() that rejected with '%2$S'.
 # LOCALIZATION NOTE: Do not translate "ServiceWorker", "promise", "FetchEvent.respondWith()", or "Response". %1$S is a URL. %2$S is an error string.
 InterceptedNonResponseWithURL=Failed to load '%1$S'. A ServiceWorker passed a promise to FetchEvent.respondWith() that resolved with non-Response value '%2$S'.
 ExecCommandCutCopyDeniedNotInputDriven=document.execCommand('cut'/'copy') was denied because it was not called from inside a short running user-generated event handler.
+ManifestShouldBeObject=Manifest should be an object.
+ManifestScopeURLInvalid=The scope URL is invalid.
+ManifestScopeNotSameOrigin=The scope URL must be same origin as document.
+ManifestStartURLOutsideScope=The start URL is outside the scope, so the scope is invalid.
+ManifestStartURLInvalid=The start URL is invalid.
+ManifestStartURLShouldBeSameOrigin=The start URL must be same origin as document.
+# LOCALIZATION NOTE: %1$S is the name of the object whose property is invalid. %2$S is the name of the invalid property. %3$S is the expected type of the property value. E.g. "Expected the manifest's start_url member to be a string."
+ManifestInvalidType=Expected the %1$S's %2$S member to be a %3$S.
+# LOCALIZATION NOTE: %1$S is the name of the property whose value is invalid. %2$S is the (invalid) value of the property. E.g. "theme_color: 42 is not a valid CSS color."
+ManifestInvalidCSSColor=%1$S: %2$S is not a valid CSS color.
 PatternAttributeCompileFailure=Unable to check <input pattern='%S'> because the pattern is not a valid regexp: %S
 # LOCALIZATION NOTE: Do not translate "postMessage" or DOMWindow. %S values are origins, like https://domain.com:port
 TargetPrincipalDoesNotMatch=Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('%S') does not match the recipient window's origin ('%S').
--- a/dom/manifest/ImageObjectProcessor.jsm
+++ b/dom/manifest/ImageObjectProcessor.jsm
@@ -1,17 +1,17 @@
 /* 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 https://mozilla.org/MPL/2.0/. */
 /*
  * ImageObjectProcessor
  * Implementation of Image Object processing algorithms from:
  * http://www.w3.org/TR/appmanifest/#image-object-and-its-members
  *
- * This is intended to be used in conjunction with ManifestProcessor.js
+ * This is intended to be used in conjunction with ManifestProcessor.jsm
  *
  * Creates an object to process Image Objects as defined by the
  * W3C specification. This is used to process things like the
  * icon member and the splash_screen member.
  *
  * Usage:
  *
  *   .process(aManifest, aBaseURL, aMemberName);
--- a/dom/manifest/ManifestProcessor.jsm
+++ b/dom/manifest/ManifestProcessor.jsm
@@ -28,16 +28,17 @@ Cu.importGlobalProperties(['URL']);
 const displayModes = new Set(['fullscreen', 'standalone', 'minimal-ui',
   'browser'
 ]);
 const orientationTypes = new Set(['any', 'natural', 'landscape', 'portrait',
   'portrait-primary', 'portrait-secondary', 'landscape-primary',
   'landscape-secondary'
 ]);
 Cu.import('resource://gre/modules/Console.jsm');
+Cu.import("resource://gre/modules/Services.jsm");
 // ValueExtractor is used by the various processors to get values
 // from the manifest and to report errors.
 Cu.import('resource://gre/modules/ValueExtractor.jsm');
 // ImageObjectProcessor is used to process things like icons and images
 Cu.import('resource://gre/modules/ImageObjectProcessor.jsm');
 
 this.ManifestProcessor = { // jshint ignore:line
   get defaultDisplayMode() {
@@ -55,31 +56,32 @@ this.ManifestProcessor = { // jshint ign
   //  * jsonText: the JSON string to be processed.
   //  * manifestURL: the URL of the manifest, to resolve URLs.
   //  * docURL: the URL of the owner doc, for security checks
   process({
     jsonText,
     manifestURL: aManifestURL,
     docURL: aDocURL
   }) {
+    const domBundle = Services.strings.createBundle("chrome://global/locale/dom/dom.properties");
+
     const console = new ConsoleAPI({
       prefix: 'Web Manifest'
     });
     const manifestURL = new URL(aManifestURL);
     const docURL = new URL(aDocURL);
     let rawManifest = {};
     try {
       rawManifest = JSON.parse(jsonText);
     } catch (e) {}
     if (typeof rawManifest !== 'object' || rawManifest === null) {
-      let msg = 'Manifest needs to be an object.';
-      console.warn(msg);
+      console.warn(domBundle.GetStringFromName('ManifestShouldBeObject'));
       rawManifest = {};
     }
-    const extractor = new ValueExtractor(console);
+    const extractor = new ValueExtractor(console, domBundle);
     const imgObjProcessor = new ImageObjectProcessor(console, extractor);
     const processedManifest = {
       'lang': processLangMember(),
       'start_url': processStartURLMember(),
       'display': processDisplayMember.call(this),
       'orientation': processOrientationMember.call(this),
       'name': processNameMember(),
       'icons': imgObjProcessor.process(
@@ -160,31 +162,27 @@ this.ManifestProcessor = { // jshint ign
       const startURL = new URL(processedManifest.start_url);
       const value = extractor.extractValue(spec);
       if (value === undefined || value === '') {
         return undefined;
       }
       try {
         scopeURL = new URL(value, manifestURL);
       } catch (e) {
-        let msg = 'The URL of scope is invalid.';
-        console.warn(msg);
+        console.warn(domBundle.GetStringFromName('ManifestScopeURLInvalid'));
         return undefined;
       }
       if (scopeURL.origin !== docURL.origin) {
-        let msg = 'Scope needs to be same-origin as Document.';
-        console.warn(msg);
+        console.warn(domBundle.GetStringFromName('ManifestScopeNotSameOrigin'));
         return undefined;
       }
       // If start URL is not within scope of scope URL:
       let isSameOrigin = startURL && startURL.origin !== scopeURL.origin;
       if (isSameOrigin || !startURL.pathname.startsWith(scopeURL.pathname)) {
-        let msg =
-          'The start URL is outside the scope, so scope is invalid.';
-        console.warn(msg);
+        console.warn(domBundle.GetStringFromName('ManifestStartURLOutsideScope'));
         return undefined;
       }
       return scopeURL.href;
     }
 
     function processStartURLMember() {
       const spec = {
         objectName: 'manifest',
@@ -197,22 +195,21 @@ this.ManifestProcessor = { // jshint ign
       const value = extractor.extractValue(spec);
       if (value === undefined || value === '') {
         return result;
       }
       let potentialResult;
       try {
         potentialResult = new URL(value, manifestURL);
       } catch (e) {
-        console.warn('Invalid URL.');
+        console.warn(domBundle.GetStringFromName('ManifestStartURLInvalid'))
         return result;
       }
       if (potentialResult.origin !== docURL.origin) {
-        let msg = 'start_url must be same origin as document.';
-        console.warn(msg);
+        console.warn(domBundle.GetStringFromName('ManifestStartURLShouldBeSameOrigin'));
       } else {
         result = potentialResult.href;
       }
       return result;
     }
 
     function processThemeColorMember() {
       const spec = {
--- a/dom/manifest/ValueExtractor.jsm
+++ b/dom/manifest/ValueExtractor.jsm
@@ -7,18 +7,19 @@
  */
 /*globals Components*/
 'use strict';
 const {
   classes: Cc,
   interfaces: Ci
 } = Components;
 
-function ValueExtractor(aConsole) {
+function ValueExtractor(aConsole, aBundle) {
   this.console = aConsole;
+  this.domBundle = aBundle;
 }
 
 ValueExtractor.prototype = {
   // This function takes a 'spec' object and destructures
   // it to extract a value. If the value is of th wrong type, it
   // warns the developer and returns undefined.
   //  expectType: is the type of a JS primitive (string, number, etc.)
   //  object: is the object from which to extract the value.
@@ -27,19 +28,19 @@ ValueExtractor.prototype = {
   //  trim: boolean, if the value should be trimmed (used by string type).
   extractValue({expectedType, object, objectName, property, trim}) {
     const value = object[property];
     const isArray = Array.isArray(value);
     // We need to special-case "array", as it's not a JS primitive.
     const type = (isArray) ? 'array' : typeof value;
     if (type !== expectedType) {
       if (type !== 'undefined') {
-        let msg = `Expected the ${objectName}'s ${property} `;
-        msg += `member to be a ${expectedType}.`;
-        this.console.log(msg);
+        this.console.warn(this.domBundle.formatStringFromName("ManifestInvalidType",
+                                                              [objectName, property, expectedType],
+                                                              3));
       }
       return undefined;
     }
     // Trim string and returned undefined if the empty string.
     const shouldTrim = expectedType === 'string' && value && trim;
     if (shouldTrim) {
       return value.trim() || undefined;
     }
@@ -48,16 +49,17 @@ ValueExtractor.prototype = {
   extractColorValue(spec) {
     const value = this.extractValue(spec);
     const DOMUtils = Cc['@mozilla.org/inspector/dom-utils;1']
       .getService(Ci.inIDOMUtils);
     let color;
     if (DOMUtils.isValidCSSColor(value)) {
       color = value;
     } else if (value) {
-      const msg = `${spec.property}: ${value} is not a valid CSS color.`;
-      this.console.warn(msg);
+      this.console.warn(this.domBundle.formatStringFromName("ManifestInvalidCSSColor",
+                                                            [spec.property, value],
+                                                            2));
     }
     return color;
   }
 };
 this.ValueExtractor = ValueExtractor; // jshint ignore:line
 this.EXPORTED_SYMBOLS = ['ValueExtractor']; // jshint ignore:line
--- a/dom/manifest/test/mochitest.ini
+++ b/dom/manifest/test/mochitest.ini
@@ -12,8 +12,9 @@ support-files =
 [test_ManifestProcessor_icons.html]
 [test_ManifestProcessor_JSON.html]
 [test_ManifestProcessor_lang.html]
 [test_ManifestProcessor_name_and_short_name.html]
 [test_ManifestProcessor_orientation.html]
 [test_ManifestProcessor_scope.html]
 [test_ManifestProcessor_splash_screens.html]
 [test_ManifestProcessor_start_url.html]
+[test_ManifestProcessor_warnings.html]
new file mode 100644
--- /dev/null
+++ b/dom/manifest/test/test_ManifestProcessor_warnings.html
@@ -0,0 +1,90 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1086997
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 1086997</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script src="common.js"></script>
+  <script>
+'use strict';
+
+const {
+  ConsoleAPI
+} = SpecialPowers.Cu.import('resource://gre/modules/Console.jsm');
+
+var warning = null;
+
+var originalWarn = ConsoleAPI.prototype.warn;
+ConsoleAPI.prototype.warn = function(aWarning) {
+  warning = aWarning;
+};
+
+[
+  {
+    func: () => data.jsonText = JSON.stringify(1),
+    warning: 'Manifest should be an object.',
+  },
+  {
+    func: () => data.jsonText = JSON.stringify(null),
+    warning: 'Manifest should be an object.',
+  },
+  {
+    func: () => data.jsonText = JSON.stringify('a string'),
+    warning: 'Manifest should be an object.',
+  },
+  {
+    func: () => data.jsonText = JSON.stringify({
+      scope: 'https://www.mozilla.org',
+    }),
+    warning: 'The scope URL must be same origin as document.',
+  },
+  {
+    func: () => data.jsonText = JSON.stringify({
+      scope: 'foo',
+      start_url: 'bar',
+    }),
+    warning: 'The start URL is outside the scope, so the scope is invalid.',
+  },
+  {
+    func: () => data.jsonText = JSON.stringify({
+      start_url: 'https://www.mozilla.org',
+    }),
+    warning: 'The start URL must be same origin as document.',
+  },
+  {
+    func: () => data.jsonText = JSON.stringify({
+      start_url: 42,
+    }),
+    warning: 'Expected the manifest\'s start_url member to be a string.',
+  },
+  {
+    func: () => data.jsonText = JSON.stringify({
+      theme_color: '42',
+    }),
+    warning: 'theme_color: 42 is not a valid CSS color.',
+  },
+  {
+    func: () => data.jsonText = JSON.stringify({
+      background_color: '42',
+    }),
+    warning: 'background_color: 42 is not a valid CSS color.',
+  },
+].forEach(function(test) {
+  test.func();
+
+  processor.process(data);
+
+  is(warning, test.warning, 'Correct warning.');
+
+  warning = null;
+  data.manifestURL = manifestURL;
+  data.docURL = docURL;
+});
+
+ConsoleAPI.prototype.warn = originalWarn;
+  </script>
+</head>
--- a/dom/media/AbstractMediaDecoder.h
+++ b/dom/media/AbstractMediaDecoder.h
@@ -32,21 +32,16 @@ class CDMProxy;
 #endif
 
 typedef nsDataHashtable<nsCStringHashKey, nsCString> MetadataTags;
 
 static inline bool IsCurrentThread(nsIThread* aThread) {
   return NS_GetCurrentThread() == aThread;
 }
 
-enum class MediaDecoderEventVisibility : int8_t {
-  Observable,
-  Suppressed
-};
-
 /**
  * The AbstractMediaDecoder class describes the public interface for a media decoder
  * and is used by the MediaReader classes.
  */
 class AbstractMediaDecoder : public nsIObserver
 {
 public:
   // A special version of the above for the ogg decoder that is allowed to be
--- a/dom/media/AudioCaptureStream.cpp
+++ b/dom/media/AudioCaptureStream.cpp
@@ -97,18 +97,18 @@ AudioCaptureStream::ProcessInput(GraphTi
   mBuffer.AdvanceKnownTracksTime(GraphTimeToStreamTimeWithBlocking((aTo)));
 }
 
 void
 AudioCaptureStream::MixerCallback(AudioDataValue* aMixedBuffer,
                                   AudioSampleFormat aFormat, uint32_t aChannels,
                                   uint32_t aFrames, uint32_t aSampleRate)
 {
-  nsAutoTArray<nsTArray<AudioDataValue>, MONO> output;
-  nsAutoTArray<const AudioDataValue*, MONO> bufferPtrs;
+  AutoTArray<nsTArray<AudioDataValue>, MONO> output;
+  AutoTArray<const AudioDataValue*, MONO> bufferPtrs;
   output.SetLength(MONO);
   bufferPtrs.SetLength(MONO);
 
   uint32_t written = 0;
   // We need to copy here, because the mixer will reuse the storage, we should
   // not hold onto it. Buffers are in planar format.
   for (uint32_t channel = 0; channel < aChannels; channel++) {
     AudioDataValue* out = output[channel].AppendElements(aFrames);
--- a/dom/media/AudioSegment.cpp
+++ b/dom/media/AudioSegment.cpp
@@ -80,19 +80,19 @@ PointerForOffsetInChannel(AudioDataValue
              "Offset request out of bounds.");
   return aData + beginningOfChannel + aOffsetSamples;
 }
 
 void
 AudioSegment::Mix(AudioMixer& aMixer, uint32_t aOutputChannels,
                   uint32_t aSampleRate)
 {
-  nsAutoTArray<AudioDataValue, SilentChannel::AUDIO_PROCESSING_FRAMES* GUESS_AUDIO_CHANNELS>
+  AutoTArray<AudioDataValue, SilentChannel::AUDIO_PROCESSING_FRAMES* GUESS_AUDIO_CHANNELS>
   buf;
-  nsAutoTArray<const AudioDataValue*, GUESS_AUDIO_CHANNELS> channelData;
+  AutoTArray<const AudioDataValue*, GUESS_AUDIO_CHANNELS> channelData;
   uint32_t offsetSamples = 0;
   uint32_t duration = GetDuration();
 
   if (duration <= 0) {
     MOZ_ASSERT(duration == 0);
     return;
   }
 
@@ -127,17 +127,17 @@ AudioSegment::Mix(AudioMixer& aMixer, ui
             PointerForOffsetInChannel(buf.Elements(), outBufferLength,
                                       aOutputChannels, channel, offsetSamples);
           PodCopy(ptr, reinterpret_cast<const AudioDataValue*>(channelData[channel]),
                   frames);
         }
         MOZ_ASSERT(channelData.Length() == aOutputChannels);
       } else if (channelData.Length() > aOutputChannels) {
         // Down mix.
-        nsAutoTArray<AudioDataValue*, GUESS_AUDIO_CHANNELS> outChannelPtrs;
+        AutoTArray<AudioDataValue*, GUESS_AUDIO_CHANNELS> outChannelPtrs;
         outChannelPtrs.SetLength(aOutputChannels);
         uint32_t offsetSamples = 0;
         for (uint32_t channel = 0; channel < aOutputChannels; channel++) {
           outChannelPtrs[channel] =
             PointerForOffsetInChannel(buf.Elements(), outBufferLength,
                                       aOutputChannels, channel, offsetSamples);
         }
         AudioChannelsDownMix(channelData, outChannelPtrs.Elements(),
@@ -161,17 +161,17 @@ AudioSegment::Mix(AudioMixer& aMixer, ui
                "We forgot to write some samples?");
     aMixer.Mix(buf.Elements(), aOutputChannels, offsetSamples, aSampleRate);
   }
 }
 
 void
 AudioSegment::WriteTo(uint64_t aID, AudioMixer& aMixer, uint32_t aOutputChannels, uint32_t aSampleRate)
 {
-  nsAutoTArray<AudioDataValue,SilentChannel::AUDIO_PROCESSING_FRAMES*GUESS_AUDIO_CHANNELS> buf;
+  AutoTArray<AudioDataValue,SilentChannel::AUDIO_PROCESSING_FRAMES*GUESS_AUDIO_CHANNELS> buf;
   // Offset in the buffer that will be written to the mixer, in samples.
   uint32_t offset = 0;
 
   if (GetDuration() <= 0) {
     MOZ_ASSERT(GetDuration() == 0);
     return;
   }
 
--- a/dom/media/AudioSegment.h
+++ b/dom/media/AudioSegment.h
@@ -113,18 +113,18 @@ DownmixAndInterleave(const nsTArray<cons
                      int32_t aDuration, float aVolume, uint32_t aOutputChannels,
                      DestT* aOutput)
 {
 
   if (aChannelData.Length() == aOutputChannels) {
     InterleaveAndConvertBuffer(aChannelData.Elements(),
                                aDuration, aVolume, aOutputChannels, aOutput);
   } else {
-    nsAutoTArray<SrcT*,GUESS_AUDIO_CHANNELS> outputChannelData;
-    nsAutoTArray<SrcT, SilentChannel::AUDIO_PROCESSING_FRAMES * GUESS_AUDIO_CHANNELS> outputBuffers;
+    AutoTArray<SrcT*,GUESS_AUDIO_CHANNELS> outputChannelData;
+    AutoTArray<SrcT, SilentChannel::AUDIO_PROCESSING_FRAMES * GUESS_AUDIO_CHANNELS> outputBuffers;
     outputChannelData.SetLength(aOutputChannels);
     outputBuffers.SetLength(aDuration * aOutputChannels);
     for (uint32_t i = 0; i < aOutputChannels; i++) {
       outputChannelData[i] = outputBuffers.Elements() + aDuration * i;
     }
     AudioChannelsDownMix(aChannelData,
                          outputChannelData.Elements(),
                          aOutputChannels,
@@ -249,18 +249,18 @@ public:
   void Resample(SpeexResamplerState* aResampler, uint32_t aInRate, uint32_t aOutRate)
   {
     mDuration = 0;
 #ifdef DEBUG
     uint32_t segmentChannelCount = ChannelCount();
 #endif
 
     for (ChunkIterator ci(*this); !ci.IsEnded(); ci.Next()) {
-      nsAutoTArray<nsTArray<T>, GUESS_AUDIO_CHANNELS> output;
-      nsAutoTArray<const T*, GUESS_AUDIO_CHANNELS> bufferPtrs;
+      AutoTArray<nsTArray<T>, GUESS_AUDIO_CHANNELS> output;
+      AutoTArray<const T*, GUESS_AUDIO_CHANNELS> bufferPtrs;
       AudioChunk& c = *ci;
       // If this chunk is null, don't bother resampling, just alter its duration
       if (c.IsNull()) {
         c.mDuration = (c.mDuration * aOutRate) / aInRate;
         mDuration += c.mDuration;
         continue;
       }
       uint32_t channels = c.mChannelData.Length();
@@ -390,17 +390,17 @@ public:
   }
 };
 
 template<typename SrcT>
 void WriteChunk(AudioChunk& aChunk,
                 uint32_t aOutputChannels,
                 AudioDataValue* aOutputBuffer)
 {
-  nsAutoTArray<const SrcT*,GUESS_AUDIO_CHANNELS> channelData;
+  AutoTArray<const SrcT*,GUESS_AUDIO_CHANNELS> channelData;
 
   channelData = aChunk.ChannelData<SrcT>();
 
   if (channelData.Length() < aOutputChannels) {
     // Up-mix. Note that this might actually make channelData have more
     // than aOutputChannels temporarily.
     AudioChannelsUpMix(&channelData, aOutputChannels, SilentChannel::ZeroChannel<SrcT>());
   }
--- a/dom/media/AudioStream.cpp
+++ b/dom/media/AudioStream.cpp
@@ -108,17 +108,17 @@ public:
       // sample rate = 44.1k file, the error will be less than 1 microsecond
       // after playing 24 hours. So we are fine with that.
       mBaseOffset += c.totalFrames;
       mBasePosition += FramesToUs<double>(c.servicedFrames, c.rate);
       mChunks.RemoveElementAt(0);
     }
   }
 private:
-  nsAutoTArray<Chunk, 7> mChunks;
+  AutoTArray<Chunk, 7> mChunks;
   int64_t mBaseOffset;
   double mBasePosition;
 };
 
 AudioStream::AudioStream(DataSource& aSource)
   : mMonitor("AudioStream")
   , mInRate(0)
   , mOutRate(0)
@@ -282,17 +282,17 @@ WriteDumpFile(FILE* aDumpFile, AudioStre
 
   uint32_t samples = aStream->GetOutChannels()*aFrames;
   if (AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_S16) {
     fwrite(aBuffer, 2, samples, aDumpFile);
     return;
   }
 
   NS_ASSERTION(AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_FLOAT32, "bad format");
-  nsAutoTArray<uint8_t, 1024*2> buf;
+  AutoTArray<uint8_t, 1024*2> buf;
   buf.SetLength(samples*2);
   float* input = static_cast<float*>(aBuffer);
   uint8_t* output = buf.Elements();
   for (uint32_t i = 0; i < samples; ++i) {
     SetUint16LE(output + i*2, int16_t(input[i]*32767.0f));
   }
   fwrite(output, 2, samples, aDumpFile);
   fflush(aDumpFile);
@@ -611,17 +611,17 @@ AudioStream::GetTimeStretched(AudioBuffe
     if (c->Frames() == 0) {
       break;
     }
     MOZ_ASSERT(c->Frames() <= toPopFrames);
     if (Downmix(c.get())) {
       mTimeStretcher->putSamples(c->Data(), c->Frames());
     } else {
       // Write silence if downmixing fails.
-      nsAutoTArray<AudioDataValue, 1000> buf;
+      AutoTArray<AudioDataValue, 1000> buf;
       buf.SetLength(mOutChannels * c->Frames());
       memset(buf.Elements(), 0, buf.Length() * sizeof(AudioDataValue));
       mTimeStretcher->putSamples(buf.Elements(), c->Frames());
     }
   }
 
   auto timeStretcher = mTimeStretcher;
   aWriter.Write([timeStretcher] (AudioDataValue* aPtr, uint32_t aFrames) {
--- a/dom/media/DOMMediaStream.h
+++ b/dom/media/DOMMediaStream.h
@@ -578,20 +578,20 @@ protected:
   // This port connects mInputStream to mOwnedStream. All tracks forwarded.
   RefPtr<MediaInputPort> mOwnedPort;
 
   // This port connects mOwnedStream to mPlaybackStream. All tracks not
   // explicitly blocked due to removal are forwarded.
   RefPtr<MediaInputPort> mPlaybackPort;
 
   // MediaStreamTracks corresponding to tracks in our mOwnedStream.
-  nsAutoTArray<RefPtr<TrackPort>, 2> mOwnedTracks;
+  AutoTArray<RefPtr<TrackPort>, 2> mOwnedTracks;
 
   // MediaStreamTracks corresponding to tracks in our mPlaybackStream.
-  nsAutoTArray<RefPtr<TrackPort>, 2> mTracks;
+  AutoTArray<RefPtr<TrackPort>, 2> mTracks;
 
   RefPtr<OwnedStreamListener> mOwnedListener;
   RefPtr<PlaybackStreamListener> mPlaybackListener;
 
   nsTArray<nsAutoPtr<OnTracksAvailableCallback> > mRunOnTracksAvailable;
 
   // Set to true after MediaStreamGraph has created tracks for mPlaybackStream.
   bool mTracksCreated;
--- a/dom/media/FileBlockCache.h
+++ b/dom/media/FileBlockCache.h
@@ -197,17 +197,17 @@ private:
   // cached in memory waiting to be written, or this block is the target of a
   // block move.
   nsTArray< RefPtr<BlockChange> > mBlockChanges;
   // Thread upon which block writes and block moves are performed. This is
   // created upon open, and shutdown (asynchronously) upon close (on the
   // main thread).
   nsCOMPtr<nsIThread> mThread;
   // Queue of pending block indexes that need to be written or moved.
-  //nsAutoTArray<int32_t, 8> mChangeIndexList;
+  //AutoTArray<int32_t, 8> mChangeIndexList;
   Int32Queue mChangeIndexList;
   // True if we've dispatched an event to commit all pending block changes
   // to file on mThread.
   bool mIsWriteScheduled;
   // True if the writer is ready to write data to file.
   bool mIsOpen;
 };
 
--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -1093,17 +1093,17 @@ AudioCallbackDriver::EnqueueStreamAndPro
   MonitorAutoLock mon(mGraphImpl->GetMonitor());
   mPromisesForOperation.AppendElement(StreamAndPromiseForOperation(aStream,
                                                                    aPromise,
                                                                    aOperation));
 }
 
 void AudioCallbackDriver::CompleteAudioContextOperations(AsyncCubebOperation aOperation)
 {
-  nsAutoTArray<StreamAndPromiseForOperation, 1> array;
+  AutoTArray<StreamAndPromiseForOperation, 1> array;
 
   // We can't lock for the whole function because AudioContextOperationCompleted
   // will grab the monitor
   {
     MonitorAutoLock mon(GraphImpl()->GetMonitor());
     array.SwapElements(mPromisesForOperation);
   }
 
--- a/dom/media/GraphDriver.h
+++ b/dom/media/GraphDriver.h
@@ -514,17 +514,17 @@ private:
     ~AutoInCallback();
     AudioCallbackDriver* mDriver;
   };
 
   /* Thread for off-main-thread initialization and
    * shutdown of the audio stream. */
   nsCOMPtr<nsIThread> mInitShutdownThread;
   /* This must be accessed with the graph monitor held. */
-  nsAutoTArray<StreamAndPromiseForOperation, 1> mPromisesForOperation;
+  AutoTArray<StreamAndPromiseForOperation, 1> mPromisesForOperation;
   /* This is set during initialization, and can be read safely afterwards. */
   dom::AudioChannel mAudioChannel;
   /* Used to queue us to add the mixer callback on first run. */
   bool mAddedMixer;
 
   /* This is atomic and is set by the audio callback thread. It can be read by
    * any thread safely. */
   Atomic<bool> mInCallback;
--- a/dom/media/Intervals.h
+++ b/dom/media/Intervals.h
@@ -250,17 +250,17 @@ private:
 // An IntervalSet in a collection of Intervals. The IntervalSet is always
 // normalized.
 template<typename T>
 class IntervalSet
 {
 public:
   typedef IntervalSet<T> SelfType;
   typedef Interval<T> ElemType;
-  typedef nsAutoTArray<ElemType,4> ContainerType;
+  typedef AutoTArray<ElemType,4> ContainerType;
   typedef typename ContainerType::index_type IndexType;
 
   IntervalSet()
   {
   }
   virtual ~IntervalSet()
   {
   }
--- a/dom/media/MediaCache.cpp
+++ b/dom/media/MediaCache.cpp
@@ -789,17 +789,17 @@ MediaCache::FindReusableBlock(TimeStamp 
       blockIndex = mFreeBlocks.GetNextBlock(blockIndex);
     } while (blockIndex >= 0);
   }
 
   // Build a list of the blocks we should consider for the "latest
   // predicted time of next use". We can exploit the fact that the block
   // linked lists are ordered by increasing time of next use. This is
   // actually the whole point of having the linked lists.
-  nsAutoTArray<uint32_t,8> candidates;
+  AutoTArray<uint32_t,8> candidates;
   for (uint32_t i = 0; i < mStreams.Length(); ++i) {
     MediaCacheStream* stream = mStreams[i];
     if (stream->mPinCount > 0) {
       // No point in even looking at this stream's blocks
       continue;
     }
 
     AppendMostReusableBlock(&stream->mMetadataBlocks, &candidates, length);
@@ -1035,17 +1035,17 @@ void
 MediaCache::Update()
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
   // The action to use for each stream. We store these so we can make
   // decisions while holding the cache lock but implement those decisions
   // without holding the cache lock, since we need to call out to
   // stream, decoder and element code.
-  nsAutoTArray<StreamAction,10> actions;
+  AutoTArray<StreamAction,10> actions;
 
   {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mUpdateQueued = false;
 #ifdef DEBUG
     mInUpdate = true;
 #endif
 
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -800,19 +800,17 @@ MediaDecoder::Seek(double aTime, SeekTar
   MOZ_ASSERT(NS_IsMainThread());
   NS_ENSURE_TRUE(!mShuttingDown, NS_ERROR_FAILURE);
 
   UpdateDormantState(false /* aDormantTimeout */, true /* aActivity */);
 
   MOZ_ASSERT(!mIsDormant, "should be out of dormant by now");
   MOZ_ASSERT(aTime >= 0.0, "Cannot seek to a negative value.");
 
-  int64_t timeUsecs = 0;
-  nsresult rv = SecondsToUsecs(aTime, timeUsecs);
-  NS_ENSURE_SUCCESS(rv, rv);
+  int64_t timeUsecs = TimeUnit::FromSeconds(aTime).ToMicroseconds();
 
   mLogicalPosition = aTime;
   mWasEndedWhenEnteredDormant = false;
 
   mLogicallySeeking = true;
   SeekTarget target = SeekTarget(timeUsecs, aSeekType);
   CallSeek(target);
 
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -31,16 +31,17 @@
 #include "MediaDecoderOwner.h"
 #include "MediaEventSource.h"
 #include "MediaMetadataManager.h"
 #include "MediaResource.h"
 #include "MediaResourceCallback.h"
 #include "MediaStatistics.h"
 #include "MediaStreamGraph.h"
 #include "TimeUnits.h"
+#include "SeekTarget.h"
 
 class nsIStreamListener;
 class nsIPrincipal;
 
 namespace mozilla {
 
 class VideoFrameContainer;
 class MediaDecoderStateMachine;
@@ -48,61 +49,16 @@ class MediaDecoderStateMachine;
 enum class MediaEventType : int8_t;
 
 // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
 // GetTickCount() and conflicts with MediaDecoder::GetCurrentTime implementation.
 #ifdef GetCurrentTime
 #undef GetCurrentTime
 #endif
 
-// Stores the seek target; the time to seek to, and whether an Accurate,
-// or "Fast" (nearest keyframe) seek was requested.
-struct SeekTarget {
-  enum Type {
-    Invalid,
-    PrevSyncPoint,
-    Accurate
-  };
-  SeekTarget()
-    : mTime(-1.0)
-    , mType(SeekTarget::Invalid)
-    , mEventVisibility(MediaDecoderEventVisibility::Observable)
-  {
-  }
-  SeekTarget(int64_t aTimeUsecs,
-             Type aType,
-             MediaDecoderEventVisibility aEventVisibility =
-               MediaDecoderEventVisibility::Observable)
-    : mTime(aTimeUsecs)
-    , mType(aType)
-    , mEventVisibility(aEventVisibility)
-  {
-  }
-  SeekTarget(const SeekTarget& aOther)
-    : mTime(aOther.mTime)
-    , mType(aOther.mType)
-    , mEventVisibility(aOther.mEventVisibility)
-  {
-  }
-  bool IsValid() const {
-    return mType != SeekTarget::Invalid;
-  }
-  void Reset() {
-    mTime = -1;
-    mType = SeekTarget::Invalid;
-  }
-  // Seek target time in microseconds.
-  int64_t mTime;
-  // Whether we should seek "Fast", or "Accurate".
-  // "Fast" seeks to the seek point preceeding mTime, whereas
-  // "Accurate" seeks as close as possible to mTime.
-  Type mType;
-  MediaDecoderEventVisibility mEventVisibility;
-};
-
 class MediaDecoder : public AbstractMediaDecoder
 {
 public:
   struct SeekResolveValue {
     SeekResolveValue(bool aAtEnd, MediaDecoderEventVisibility aEventVisibility)
       : mAtEnd(aAtEnd), mEventVisibility(aEventVisibility) {}
     bool mAtEnd;
     MediaDecoderEventVisibility mEventVisibility;
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -12,16 +12,17 @@
 #include "MediaInfo.h"
 #include "MediaData.h"
 #include "MediaMetadataManager.h"
 #include "MediaQueue.h"
 #include "MediaTimer.h"
 #include "AudioCompactor.h"
 #include "Intervals.h"
 #include "TimeUnits.h"
+#include "SeekTarget.h"
 
 namespace mozilla {
 
 class CDMProxy;
 class MediaDecoderReader;
 
 struct WaitForDataRejectValue
 {
@@ -73,17 +74,17 @@ public:
   };
 
   using MetadataPromise =
     MozPromise<RefPtr<MetadataHolder>, ReadMetadataFailureReason, IsExclusive>;
   using AudioDataPromise =
     MozPromise<RefPtr<MediaData>, NotDecodedReason, IsExclusive>;
   using VideoDataPromise =
     MozPromise<RefPtr<MediaData>, NotDecodedReason, IsExclusive>;
-  using SeekPromise = MozPromise<int64_t, nsresult, IsExclusive>;
+  using SeekPromise = MozPromise<media::TimeUnit, nsresult, IsExclusive>;
 
   // Note that, conceptually, WaitForData makes sense in a non-exclusive sense.
   // But in the current architecture it's only ever used exclusively (by MDSM),
   // so we mark it that way to verify our assumptions. If you have a use-case
   // for multiple WaitForData consumers, feel free to flip the exclusivity here.
   using WaitForDataPromise =
     MozPromise<MediaData::Type, WaitForDataRejectValue, IsExclusive>;
 
@@ -172,17 +173,17 @@ public:
 
   // Fills aInfo with the latest cached data required to present the media,
   // ReadUpdatedMetadata will always be called once ReadMetadata has succeeded.
   virtual void ReadUpdatedMetadata(MediaInfo* aInfo) {}
 
   // Moves the decode head to aTime microseconds. aEndTime denotes the end
   // time of the media in usecs. This is only needed for OggReader, and should
   // probably be removed somehow.
-  virtual RefPtr<SeekPromise> Seek(int64_t aTime, int64_t aEndTime) = 0;
+  virtual RefPtr<SeekPromise> Seek(SeekTarget aTarget, int64_t aEndTime) = 0;
 
   // Called to move the reader into idle state. When the reader is
   // created it is assumed to be active (i.e. not idle). When the media
   // element is paused and we don't need to decode any more data, the state
   // machine calls SetIdle() to inform the reader that its decoder won't be
   // needed for a while. The reader can use these notifications to enter
   // a low power state when the decoder isn't needed, if desired.
   // This is most useful on mobile.
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -642,28 +642,28 @@ MediaDecoderStateMachine::OnAudioDecoded
         return;
       }
       if (audio->mDiscontinuity) {
         mDropAudioUntilNextDiscontinuity = false;
       }
       if (!mDropAudioUntilNextDiscontinuity) {
         // We must be after the discontinuity; we're receiving samples
         // at or after the seek target.
-        if (mCurrentSeek.mTarget.mType == SeekTarget::PrevSyncPoint &&
-            mCurrentSeek.mTarget.mTime > mCurrentTimeBeforeSeek &&
+        if (mCurrentSeek.mTarget.IsFast() &&
+            mCurrentSeek.mTarget.GetTime().ToMicroseconds() > mCurrentTimeBeforeSeek &&
             audio->mTime < mCurrentTimeBeforeSeek) {
           // We are doing a fastSeek, but we ended up *before* the previous
           // playback position. This is surprising UX, so switch to an accurate
           // seek and decode to the seek target. This is not conformant to the
           // spec, fastSeek should always be fast, but until we get the time to
           // change all Readers to seek to the keyframe after the currentTime
           // in this case, we'll just decode forward. Bug 1026330.
-          mCurrentSeek.mTarget.mType = SeekTarget::Accurate;
+          mCurrentSeek.mTarget.SetType(SeekTarget::Accurate);
         }
-        if (mCurrentSeek.mTarget.mType == SeekTarget::PrevSyncPoint) {
+        if (mCurrentSeek.mTarget.IsFast()) {
           // Non-precise seek; we can stop the seek at the first sample.
           Push(audio, MediaData::AUDIO_DATA);
         } else {
           // We're doing an accurate seek. We must discard
           // MediaData up to the one containing exact seek target.
           if (NS_FAILED(DropAudioUpToSeekTarget(audio))) {
             DecodeError();
             return;
@@ -962,28 +962,28 @@ MediaDecoderStateMachine::OnVideoDecoded
       if (mDropVideoUntilNextDiscontinuity) {
         if (video->mDiscontinuity) {
           mDropVideoUntilNextDiscontinuity = false;
         }
       }
       if (!mDropVideoUntilNextDiscontinuity) {
         // We must be after the discontinuity; we're receiving samples
         // at or after the seek target.
-        if (mCurrentSeek.mTarget.mType == SeekTarget::PrevSyncPoint &&
-            mCurrentSeek.mTarget.mTime > mCurrentTimeBeforeSeek &&
+        if (mCurrentSeek.mTarget.IsFast() &&
+            mCurrentSeek.mTarget.GetTime().ToMicroseconds() > mCurrentTimeBeforeSeek &&
             video->mTime < mCurrentTimeBeforeSeek) {
           // We are doing a fastSeek, but we ended up *before* the previous
           // playback position. This is surprising UX, so switch to an accurate
           // seek and decode to the seek target. This is not conformant to the
           // spec, fastSeek should always be fast, but until we get the time to
           // change all Readers to seek to the keyframe after the currentTime
           // in this case, we'll just decode forward. Bug 1026330.
-          mCurrentSeek.mTarget.mType = SeekTarget::Accurate;
+          mCurrentSeek.mTarget.SetType(SeekTarget::Accurate);
         }
-        if (mCurrentSeek.mTarget.mType == SeekTarget::PrevSyncPoint ||
+        if (mCurrentSeek.mTarget.IsFast() ||
             mPendingSeek.Exists()) {
           // Non-precise seek; or a pending seek exists ; we can stop the seek
           // at the first sample.
           Push(video, MediaData::VIDEO_DATA);
         } else {
           // We're doing an accurate seek. We still need to discard
           // MediaData up to the one containing exact seek target.
           if (NS_FAILED(DropVideoUpToSeekTarget(video))) {
@@ -1519,17 +1519,17 @@ MediaDecoderStateMachine::Seek(SeekTarge
     mQueuedSeek.RejectIfExists(__func__);
     mQueuedSeek.mTarget = aTarget;
     return mQueuedSeek.mPromise.Ensure(__func__);
   }
   mQueuedSeek.RejectIfExists(__func__);
   mPendingSeek.RejectIfExists(__func__);
   mPendingSeek.mTarget = aTarget;
 
-  DECODER_LOG("Changed state to SEEKING (to %lld)", mPendingSeek.mTarget.mTime);
+  DECODER_LOG("Changed state to SEEKING (to %lld)", mPendingSeek.mTarget.GetTime().ToMicroseconds());
   SetState(DECODER_STATE_SEEKING);
   ScheduleStateMachine();
 
   return mPendingSeek.mPromise.Ensure(__func__);
 }
 
 RefPtr<MediaDecoder::SeekPromise>
 MediaDecoderStateMachine::InvokeSeek(SeekTarget aTarget)
@@ -1613,45 +1613,47 @@ MediaDecoderStateMachine::InitiateSeek()
   MOZ_ASSERT(OnTaskQueue());
 
   mCurrentSeek.RejectIfExists(__func__);
   mCurrentSeek.Steal(mPendingSeek);
 
   // Bound the seek time to be inside the media range.
   int64_t end = Duration().ToMicroseconds();
   NS_ASSERTION(end != -1, "Should know end time by now");
-  int64_t seekTime = mCurrentSeek.mTarget.mTime;
+  int64_t seekTime = mCurrentSeek.mTarget.GetTime().ToMicroseconds();
   seekTime = std::min(seekTime, end);
   seekTime = std::max(int64_t(0), seekTime);
   NS_ASSERTION(seekTime >= 0 && seekTime <= end,
                "Can only seek in range [0,duration]");
-  mCurrentSeek.mTarget.mTime = seekTime;
+  mCurrentSeek.mTarget.SetTime(media::TimeUnit::FromMicroseconds(seekTime));
 
   mDropAudioUntilNextDiscontinuity = HasAudio();
   mDropVideoUntilNextDiscontinuity = HasVideo();
   mCurrentTimeBeforeSeek = GetMediaTime();
 
   // Stop playback now to ensure that while we're outside the monitor
   // dispatching SeekingStarted, playback doesn't advance and mess with
   // mCurrentPosition that we've setting to seekTime here.
   StopPlayback();
-  UpdatePlaybackPositionInternal(mCurrentSeek.mTarget.mTime);
+  UpdatePlaybackPositionInternal(mCurrentSeek.mTarget.GetTime().ToMicroseconds());
 
   mOnSeekingStart.Notify(mCurrentSeek.mTarget.mEventVisibility);
 
   // Reset our state machine and decoding pipeline before seeking.
   Reset();
 
   // Do the seek.
   RefPtr<MediaDecoderStateMachine> self = this;
+  SeekTarget seekTarget = mCurrentSeek.mTarget;
+  seekTarget.SetTime(seekTarget.GetTime() + media::TimeUnit::FromMicroseconds(StartTime()));
   mSeekRequest.Begin(InvokeAsync(DecodeTaskQueue(), mReader.get(), __func__,
-                                 &MediaDecoderReader::Seek, mCurrentSeek.mTarget.mTime + StartTime(),
+                                 &MediaDecoderReader::Seek, seekTarget,
                                  Duration().ToMicroseconds())
     ->Then(OwnerThread(), __func__,
-           [self] (int64_t) -> void {
+           [self] (media::TimeUnit) -> void {
              self->mSeekRequest.Complete();
              // We must decode the first samples of active streams, so we can determine
              // the new stream time. So dispatch tasks to do that.
              self->mDecodeToSeekTarget = true;
              self->DispatchDecodeTasksIfNeeded();
            }, [self] (nsresult aResult) -> void {
              self->mSeekRequest.Complete();
              MOZ_ASSERT(NS_FAILED(aResult), "Cancels should also disconnect mSeekRequest");
@@ -2075,34 +2077,41 @@ MediaDecoderStateMachine::FinishDecodeFi
 }
 
 void
 MediaDecoderStateMachine::SeekCompleted()
 {
   MOZ_ASSERT(OnTaskQueue());
   MOZ_ASSERT(mState == DECODER_STATE_SEEKING);
 
-  int64_t seekTime = mCurrentSeek.mTarget.mTime;
+  int64_t seekTime = mCurrentSeek.mTarget.GetTime().ToMicroseconds();
   int64_t newCurrentTime = seekTime;
 
   // Setup timestamp state.
   RefPtr<MediaData> video = VideoQueue().PeekFront();
   if (seekTime == Duration().ToMicroseconds()) {
     newCurrentTime = seekTime;
   } else if (HasAudio()) {
     MediaData* audio = AudioQueue().PeekFront();
     // Though we adjust the newCurrentTime in audio-based, and supplemented
     // by video. For better UX, should NOT bind the slide position to
     // the first audio data timestamp directly.
     // While seeking to a position where there's only either audio or video, or
     // seeking to a position lies before audio or video, we need to check if
     // seekTime is bounded in suitable duration. See Bug 1112438.
-    int64_t videoStart = video ? video->mTime : seekTime;
     int64_t audioStart = audio ? audio->mTime : seekTime;
-    newCurrentTime = std::min(audioStart, videoStart);
+    // We only pin the seek time to the video start time if the video frame
+    // contains the seek time. We also perform this operation if there's no
+    // video in order to get around bug 1244639.
+    if (!video || (video->mTime <= seekTime && video->GetEndTime() > seekTime)) {
+      int64_t videoStart = video ? video->mTime : seekTime;
+      newCurrentTime = std::min(audioStart, videoStart);
+    } else {
+      newCurrentTime = audioStart;
+    }
   } else {
     newCurrentTime = video ? video->mTime : seekTime;
   }
 
   // Change state to DECODING or COMPLETED now. SeekingStopped will
   // call MediaDecoderStateMachine::Seek to reset our state to SEEKING
   // if we need to seek again.
 
@@ -2500,17 +2509,17 @@ nsresult
 MediaDecoderStateMachine::DropVideoUpToSeekTarget(MediaData* aSample)
 {
   MOZ_ASSERT(OnTaskQueue());
   RefPtr<VideoData> video(aSample->As<VideoData>());
   MOZ_ASSERT(video);
   DECODER_LOG("DropVideoUpToSeekTarget() frame [%lld, %lld]",
               video->mTime, video->GetEndTime());
   MOZ_ASSERT(mCurrentSeek.Exists());
-  const int64_t target = mCurrentSeek.mTarget.mTime;
+  const int64_t target = mCurrentSeek.mTarget.GetTime().ToMicroseconds();
 
   // If the frame end time is less than the seek target, we won't want
   // to display this frame after the seek, so discard it.
   if (target >= video->GetEndTime()) {
     DECODER_LOG("DropVideoUpToSeekTarget() pop video frame [%lld, %lld] target=%lld",
                 video->mTime, video->GetEndTime(), target);
     mFirstVideoFrameAfterSeek = video;
   } else {
@@ -2534,53 +2543,53 @@ MediaDecoderStateMachine::DropVideoUpToS
 
 nsresult
 MediaDecoderStateMachine::DropAudioUpToSeekTarget(MediaData* aSample)
 {
   MOZ_ASSERT(OnTaskQueue());
   RefPtr<AudioData> audio(aSample->As<AudioData>());
   MOZ_ASSERT(audio &&
              mCurrentSeek.Exists() &&
-             mCurrentSeek.mTarget.mType == SeekTarget::Accurate);
+             mCurrentSeek.mTarget.IsAccurate());
 
   CheckedInt64 sampleDuration =
     FramesToUsecs(audio->mFrames, mInfo.mAudio.mRate);
   if (!sampleDuration.isValid()) {
     return NS_ERROR_FAILURE;
   }
 
-  if (audio->mTime + sampleDuration.value() <= mCurrentSeek.mTarget.mTime) {
+  if (audio->mTime + sampleDuration.value() <= mCurrentSeek.mTarget.GetTime().ToMicroseconds()) {
     // Our seek target lies after the frames in this AudioData. Don't
     // push it onto the audio queue, and keep decoding forwards.
     return NS_OK;
   }
 
-  if (audio->mTime > mCurrentSeek.mTarget.mTime) {
+  if (audio->mTime > mCurrentSeek.mTarget.GetTime().ToMicroseconds()) {
     // The seek target doesn't lie in the audio block just after the last
     // audio frames we've seen which were before the seek target. This
     // could have been the first audio data we've seen after seek, i.e. the
     // seek terminated after the seek target in the audio stream. Just
     // abort the audio decode-to-target, the state machine will play
     // silence to cover the gap. Typically this happens in poorly muxed
     // files.
     DECODER_WARN("Audio not synced after seek, maybe a poorly muxed file?");
     Push(audio, MediaData::AUDIO_DATA);
     return NS_OK;
   }
 
   // The seek target lies somewhere in this AudioData's frames, strip off
   // any frames which lie before the seek target, so we'll begin playback
   // exactly at the seek target.
-  NS_ASSERTION(mCurrentSeek.mTarget.mTime >= audio->mTime,
+  NS_ASSERTION(mCurrentSeek.mTarget.GetTime().ToMicroseconds() >= audio->mTime,
                "Target must at or be after data start.");
-  NS_ASSERTION(mCurrentSeek.mTarget.mTime < audio->mTime + sampleDuration.value(),
+  NS_ASSERTION(mCurrentSeek.mTarget.GetTime().ToMicroseconds() < audio->mTime + sampleDuration.value(),
                "Data must end after target.");
 
   CheckedInt64 framesToPrune =
-    UsecsToFrames(mCurrentSeek.mTarget.mTime - audio->mTime, mInfo.mAudio.mRate);
+    UsecsToFrames(mCurrentSeek.mTarget.GetTime().ToMicroseconds() - audio->mTime, mInfo.mAudio.mRate);
   if (!framesToPrune.isValid()) {
     return NS_ERROR_FAILURE;
   }
   if (framesToPrune.value() > audio->mFrames) {
     // We've messed up somehow. Don't try to trim frames, the |frames|
     // variable below will overflow.
     DECODER_WARN("Can't prune more frames that we have!");
     return NS_ERROR_FAILURE;
@@ -2591,17 +2600,17 @@ MediaDecoderStateMachine::DropAudioUpToS
   memcpy(audioData.get(),
          audio->mAudioData.get() + (framesToPrune.value() * channels),
          frames * channels * sizeof(AudioDataValue));
   CheckedInt64 duration = FramesToUsecs(frames, mInfo.mAudio.mRate);
   if (!duration.isValid()) {
     return NS_ERROR_FAILURE;
   }
   RefPtr<AudioData> data(new AudioData(audio->mOffset,
-                                       mCurrentSeek.mTarget.mTime,
+                                       mCurrentSeek.mTarget.GetTime().ToMicroseconds(),
                                        duration.value(),
                                        frames,
                                        Move(audioData),
                                        channels,
                                        audio->mRate));
   PushFront(data, MediaData::AUDIO_DATA);
 
   return NS_OK;
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -924,18 +924,18 @@ MediaFormatReader::HandleDemuxedSamples(
       // Flush will clear our array of queued samples. So make a copy now.
       nsTArray<RefPtr<MediaRawData>> samples{decoder.mQueuedSamples};
       Flush(aTrack);
       decoder.ShutdownDecoder();
       if (sample->mKeyframe) {
         decoder.mQueuedSamples.AppendElements(Move(samples));
         NotifyDecodingRequested(aTrack);
       } else {
-        SeekTarget seekTarget =
-          decoder.mTimeThreshold.refOr(SeekTarget(TimeUnit::FromMicroseconds(sample->mTime), false));
+        InternalSeekTarget seekTarget =
+          decoder.mTimeThreshold.refOr(InternalSeekTarget(TimeUnit::FromMicroseconds(sample->mTime), false));
         LOG("Stream change occurred on a non-keyframe. Seeking to:%lld",
             seekTarget.mTime.ToMicroseconds());
         InternalSeek(aTrack, seekTarget);
       }
       return;
     }
 
     LOGV("Input:%lld (dts:%lld kf:%d)",
@@ -963,17 +963,17 @@ MediaFormatReader::HandleDemuxedSamples(
     samplesPending = true;
   }
 
   // We have serviced the decoder's request for more data.
   decoder.mInputExhausted = false;
 }
 
 void
-MediaFormatReader::InternalSeek(TrackType aTrack, const SeekTarget& aTarget)
+MediaFormatReader::InternalSeek(TrackType aTrack, const InternalSeekTarget& aTarget)
 {
   MOZ_ASSERT(OnTaskQueue());
   auto& decoder = GetDecoderData(aTrack);
   decoder.mTimeThreshold = Some(aTarget);
   RefPtr<MediaFormatReader> self = this;
   decoder.ResetDemuxer();
   decoder.mSeekRequest.Begin(decoder.mTrackDemuxer->Seek(decoder.mTimeThreshold.ref().mTime)
              ->Then(OwnerThread(), __func__,
@@ -1053,17 +1053,17 @@ MediaFormatReader::Update(TrackType aTra
 
   // Record number of frames decoded and parsed. Automatically update the
   // stats counters using the AutoNotifyDecoded stack-based class.
   AbstractMediaDecoder::AutoNotifyDecoded a(mDecoder);
 
   // Drop any frames found prior our internal seek target.
   while (decoder.mTimeThreshold && decoder.mOutput.Length()) {
     RefPtr<MediaData>& output = decoder.mOutput[0];
-    SeekTarget target = decoder.mTimeThreshold.ref();
+    InternalSeekTarget target = decoder.mTimeThreshold.ref();
     media::TimeUnit time = media::TimeUnit::FromMicroseconds(output->mTime);
     if (time >= target.mTime) {
       // We have reached our internal seek target.
       decoder.mTimeThreshold.reset();
     }
     if (time < target.mTime || target.mDropTarget) {
       LOGV("Internal Seeking: Dropping %s frame time:%f wanted:%f (kf:%d)",
            TrackTypeToStr(aTrack),
@@ -1107,17 +1107,17 @@ MediaFormatReader::Update(TrackType aTra
       } else if (decoder.mWaitingForData) {
         if (wasDraining && decoder.mLastSampleTime &&
             !decoder.mNextStreamSourceID) {
           // We have completed draining the decoder following WaitingForData.
           // Set up the internal seek machinery to be able to resume from the
           // last sample decoded.
           LOG("Seeking to last sample time: %lld",
               decoder.mLastSampleTime.ref().ToMicroseconds());
-          InternalSeek(aTrack, SeekTarget(decoder.mLastSampleTime.ref(), true));
+          InternalSeek(aTrack, InternalSeekTarget(decoder.mLastSampleTime.ref(), true));
         }
         LOG("Rejecting %s promise: WAITING_FOR_DATA", TrackTypeToStr(aTrack));
         decoder.RejectPromise(WAITING_FOR_DATA, __func__);
       }
       // Now that draining has completed, we check if we have received
       // new data again as the result may now be different from the earlier
       // run.
       if (UpdateReceivedNewData(aTrack)) {
@@ -1398,21 +1398,21 @@ MediaFormatReader::OnVideoSkipFailed(Med
       break;
     default:
       NotifyError(TrackType::kVideoTrack);
       break;
   }
 }
 
 RefPtr<MediaDecoderReader::SeekPromise>
-MediaFormatReader::Seek(int64_t aTime, int64_t aUnused)
+MediaFormatReader::Seek(SeekTarget aTarget, int64_t aUnused)
 {
   MOZ_ASSERT(OnTaskQueue());
 
-  LOG("aTime=(%lld)", aTime);
+  LOG("aTarget=(%lld)", aTarget.GetTime().ToMicroseconds());
 
   MOZ_DIAGNOSTIC_ASSERT(mSeekPromise.IsEmpty());
   MOZ_DIAGNOSTIC_ASSERT(!mVideo.HasPromise());
   MOZ_DIAGNOSTIC_ASSERT(!mAudio.HasPromise());
   MOZ_DIAGNOSTIC_ASSERT(mPendingSeekTime.isNothing());
   MOZ_DIAGNOSTIC_ASSERT(mVideo.mTimeThreshold.isNothing());
   MOZ_DIAGNOSTIC_ASSERT(mAudio.mTimeThreshold.isNothing());
 
@@ -1420,18 +1420,18 @@ MediaFormatReader::Seek(int64_t aTime, i
     LOG("Seek() END (Unseekable)");
     return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
   }
 
   if (mShutdown) {
     return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
   }
 
-  mOriginalSeekTime = Some(media::TimeUnit::FromMicroseconds(aTime));
-  mPendingSeekTime = mOriginalSeekTime;
+  mOriginalSeekTarget = Some(aTarget);
+  mPendingSeekTime = Some(aTarget.GetTime());
 
   RefPtr<SeekPromise> p = mSeekPromise.Ensure(__func__);
 
   RefPtr<nsIRunnable> task(
     NS_NewRunnableMethod(this, &MediaFormatReader::AttemptSeek));
   OwnerThread()->Dispatch(task.forget());
 
   return p;
@@ -1465,38 +1465,38 @@ MediaFormatReader::OnSeekFailed(TrackTyp
   if (aTrack == TrackType::kVideoTrack) {
     mVideo.mSeekRequest.Complete();
   } else {
     mAudio.mSeekRequest.Complete();
   }
 
   if (aResult == DemuxerFailureReason::WAITING_FOR_DATA) {
     if (HasVideo() && aTrack == TrackType::kAudioTrack &&
-        mOriginalSeekTime.isSome() &&
-        mPendingSeekTime.ref() != mOriginalSeekTime.ref()) {
+        mOriginalSeekTarget.isSome() &&
+        mPendingSeekTime.ref() != mOriginalSeekTarget.ref().GetTime()) {
       // We have failed to seek audio where video seeked to earlier.
       // Attempt to seek instead to the closest point that we know we have in
       // order to limit A/V sync discrepency.
 
       // Ensure we have the most up to date buffered ranges.
       UpdateReceivedNewData(TrackType::kAudioTrack);
       Maybe<media::TimeUnit> nextSeekTime;
       // Find closest buffered time found after video seeked time.
       for (const auto& timeRange : mAudio.mTimeRanges) {
         if (timeRange.mStart >= mPendingSeekTime.ref()) {
           nextSeekTime.emplace(timeRange.mStart);
           break;
         }
       }
       if (nextSeekTime.isNothing() ||
-          nextSeekTime.ref() > mOriginalSeekTime.ref()) {
-        nextSeekTime = mOriginalSeekTime;
+          nextSeekTime.ref() > mOriginalSeekTarget.ref().GetTime()) {
+        nextSeekTime = Some(mOriginalSeekTarget.ref().GetTime());
         LOG("Unable to seek audio to video seek time. A/V sync may be broken");
       } else {
-        mOriginalSeekTime.reset();
+        mOriginalSeekTarget.reset();
       }
       mPendingSeekTime = nextSeekTime;
       DoAudioSeek();
       return;
     }
     NotifyWaitingForData(aTrack);
     return;
   }
@@ -1520,22 +1520,26 @@ MediaFormatReader::DoVideoSeek()
 void
 MediaFormatReader::OnVideoSeekCompleted(media::TimeUnit aTime)
 {
   MOZ_ASSERT(OnTaskQueue());
   LOGV("Video seeked to %lld", aTime.ToMicroseconds());
   mVideo.mSeekRequest.Complete();
 
   if (HasAudio()) {
-    MOZ_ASSERT(mPendingSeekTime.isSome());
-    mPendingSeekTime = Some(aTime);
+    MOZ_ASSERT(mPendingSeekTime.isSome() && mOriginalSeekTarget.isSome());
+    if (mOriginalSeekTarget.ref().IsFast()) {
+      // We are performing a fast seek. We need to seek audio to where the
+      // video seeked to, to ensure proper A/V sync once playback resume.
+      mPendingSeekTime = Some(aTime);
+    }
     DoAudioSeek();
   } else {
     mPendingSeekTime.reset();
-    mSeekPromise.Resolve(aTime.ToMicroseconds(), __func__);
+    mSeekPromise.Resolve(aTime, __func__);
   }
 }
 
 void
 MediaFormatReader::DoAudioSeek()
 {
   MOZ_ASSERT(mPendingSeekTime.isSome());
   LOGV("Seeking audio to %lld", mPendingSeekTime.ref().ToMicroseconds());
@@ -1548,17 +1552,17 @@ MediaFormatReader::DoAudioSeek()
 
 void
 MediaFormatReader::OnAudioSeekCompleted(media::TimeUnit aTime)
 {
   MOZ_ASSERT(OnTaskQueue());
   LOGV("Audio seeked to %lld", aTime.ToMicroseconds());
   mAudio.mSeekRequest.Complete();
   mPendingSeekTime.reset();
-  mSeekPromise.Resolve(aTime.ToMicroseconds(), __func__);
+  mSeekPromise.Resolve(aTime, __func__);
 }
 
 media::TimeIntervals
 MediaFormatReader::GetBuffered()
 {
   MOZ_ASSERT(OnTaskQueue());
   media::TimeIntervals videoti;
   media::TimeIntervals audioti;
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -43,17 +43,17 @@ public:
 
   RefPtr<AudioDataPromise> RequestAudioData() override;
 
   RefPtr<MetadataPromise> AsyncReadMetadata() override;
 
   void ReadUpdatedMetadata(MediaInfo* aInfo) override;
 
   RefPtr<SeekPromise>
-  Seek(int64_t aTime, int64_t aUnused) override;
+  Seek(SeekTarget aTarget, int64_t aUnused) override;
 
 protected:
   void NotifyDataArrivedInternal() override;
 
 public:
   media::TimeIntervals GetBuffered() override;
 
   bool ForceZeroStartTime() const override;
@@ -128,30 +128,30 @@ private:
   void RequestDemuxSamples(TrackType aTrack);
   // Handle demuxed samples by the input behavior.
   void HandleDemuxedSamples(TrackType aTrack,
                             AbstractMediaDecoder::AutoNotifyDecoded& aA);
   // Decode any pending already demuxed samples.
   bool DecodeDemuxedSamples(TrackType aTrack,
                             MediaRawData* aSample);
 
-  struct SeekTarget {
-    SeekTarget(const media::TimeUnit& aTime, bool aDropTarget)
+  struct InternalSeekTarget {
+    InternalSeekTarget(const media::TimeUnit& aTime, bool aDropTarget)
       : mTime(aTime)
       , mDropTarget(aDropTarget)
       , mWaiting(false)
     {}
 
     media::TimeUnit mTime;
     bool mDropTarget;
     bool mWaiting;
   };
   // Perform an internal seek to aTime. If aDropTarget is true then
   // the first sample past the target will be dropped.
-  void InternalSeek(TrackType aTrack, const SeekTarget& aTarget);
+  void InternalSeek(TrackType aTrack, const InternalSeekTarget& aTarget);
 
   // Drain the current decoder.
   void DrainDecoder(TrackType aTrack);
   void NotifyNewOutput(TrackType aTrack, MediaData* aSample);
   void NotifyInputExhausted(TrackType aTrack);
   void NotifyDrainComplete(TrackType aTrack);
   void NotifyError(TrackType aTrack);
   void NotifyWaitingForData(TrackType aTrack);
@@ -295,17 +295,17 @@ private:
     bool mInputExhausted;
     bool mError;
     bool mNeedDraining;
     bool mDraining;
     bool mDrainComplete;
     // If set, all decoded samples prior mTimeThreshold will be dropped.
     // Used for internal seeking when a change of stream is detected or when
     // encountering data discontinuity.
-    Maybe<SeekTarget> mTimeThreshold;
+    Maybe<InternalSeekTarget> mTimeThreshold;
     // Time of last sample returned.
     Maybe<media::TimeUnit> mLastSampleTime;
 
     // Decoded samples returned my mDecoder awaiting being returned to
     // state machine upon request.
     nsTArray<RefPtr<MediaData>> mOutput;
     uint64_t mNumSamplesInput;
     uint64_t mNumSamplesOutput;
@@ -461,17 +461,17 @@ private:
 
   void DoAudioSeek();
   void OnAudioSeekCompleted(media::TimeUnit aTime);
   void OnAudioSeekFailed(DemuxerFailureReason aFailure)
   {
     OnSeekFailed(TrackType::kAudioTrack, aFailure);
   }
   // Temporary seek information while we wait for the data
-  Maybe<media::TimeUnit> mOriginalSeekTime;
+  Maybe<SeekTarget> mOriginalSeekTarget;
   Maybe<media::TimeUnit> mPendingSeekTime;
   MozPromiseHolder<SeekPromise> mSeekPromise;
 
   RefPtr<VideoFrameContainer> mVideoFrameContainer;
   layers::ImageContainer* GetImageContainer();
 
 #ifdef MOZ_EME
   RefPtr<CDMProxy> mCDMProxy;
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -601,17 +601,17 @@ MediaStreamGraphImpl::CreateOrDestroyAud
 
   if (!aStream->GetStreamBuffer().GetAndResetTracksDirty() &&
       !aStream->mAudioOutputStreams.IsEmpty()) {
     return;
   }
 
   STREAM_LOG(LogLevel::Debug, ("Updating AudioOutputStreams for MediaStream %p", aStream));
 
-  nsAutoTArray<bool,2> audioOutputStreamsFound;
+  AutoTArray<bool,2> audioOutputStreamsFound;
   for (uint32_t i = 0; i < aStream->mAudioOutputStreams.Length(); ++i) {
     audioOutputStreamsFound.AppendElement(false);
   }
 
   for (StreamBuffer::TrackIter tracks(aStream->GetStreamBuffer(), MediaSegment::AUDIO);
        !tracks.IsEnded(); tracks.Next()) {
     uint32_t i;
     for (i = 0; i < audioOutputStreamsFound.Length(); ++i) {
@@ -786,17 +786,17 @@ MediaStreamGraphImpl::PlayVideo(MediaStr
   MOZ_ASSERT(mRealtime, "Should only attempt to play video in realtime mode");
 
   if (aStream->mVideoOutputs.IsEmpty())
     return;
 
   TimeStamp currentTimeStamp = CurrentDriver()->GetCurrentTimeStamp();
 
   // Collect any new frames produced in this iteration.
-  nsAutoTArray<ImageContainer::NonOwningImage,4> newImages;
+  AutoTArray<ImageContainer::NonOwningImage,4> newImages;
   RefPtr<Image> blackImage;
 
   MOZ_ASSERT(mProcessedTime >= aStream->mBufferStartTime, "frame position before buffer?");
   // We only look at the non-blocking interval
   StreamTime frameBufferTime = aStream->GraphTimeToStreamTime(mProcessedTime);
   StreamTime bufferEndTime = aStream->GraphTimeToStreamTime(aStream->mStartBlocking);
   StreamTime start;
   const VideoChunk* chunk;
@@ -856,24 +856,24 @@ MediaStreamGraphImpl::PlayVideo(MediaStr
     newImages.AppendElement(ImageContainer::NonOwningImage(image, targetTime));
 
     aStream->mLastPlayedVideoFrame = *frame;
   }
 
   if (!aStream->mLastPlayedVideoFrame.GetImage())
     return;
 
-  nsAutoTArray<ImageContainer::NonOwningImage,4> images;
+  AutoTArray<ImageContainer::NonOwningImage,4> images;
   bool haveMultipleImages = false;
 
   for (uint32_t i = 0; i < aStream->mVideoOutputs.Length(); ++i) {
     VideoFrameContainer* output = aStream->mVideoOutputs[i];
 
     // Find previous frames that may still be valid.
-    nsAutoTArray<ImageContainer::OwningImage,4> previousImages;
+    AutoTArray<ImageContainer::OwningImage,4> previousImages;
     output->GetImageContainer()->GetCurrentImages(&previousImages);
     uint32_t j = previousImages.Length();
     if (j) {
       // Re-use the most recent frame before currentTimeStamp and subsequent,
       // always keeping at least one frame.
       do {
         --j;
       } while (j > 0 && previousImages[j].mTimeStamp > currentTimeStamp);
new file mode 100644
--- /dev/null
+++ b/dom/media/SeekTarget.h
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef SEEK_TARGET_H
+#define SEEK_TARGET_H
+
+#include "TimeUnits.h"
+
+namespace mozilla {
+
+enum class MediaDecoderEventVisibility : int8_t {
+  Observable,
+  Suppressed
+};
+
+// Stores the seek target; the time to seek to, and whether an Accurate,
+// or "Fast" (nearest keyframe) seek was requested.
+struct SeekTarget {
+  enum Type {
+    Invalid,
+    PrevSyncPoint,
+    Accurate
+  };
+  SeekTarget()
+    : mEventVisibility(MediaDecoderEventVisibility::Observable)
+    , mTime(media::TimeUnit::Invalid())
+    , mType(SeekTarget::Invalid)
+  {
+  }
+  SeekTarget(int64_t aTimeUsecs,
+             Type aType,
+             MediaDecoderEventVisibility aEventVisibility =
+               MediaDecoderEventVisibility::Observable)
+    : mEventVisibility(aEventVisibility)
+    , mTime(media::TimeUnit::FromMicroseconds(aTimeUsecs))
+    , mType(aType)
+  {
+  }
+  SeekTarget(const media::TimeUnit& aTime,
+             Type aType,
+             MediaDecoderEventVisibility aEventVisibility =
+               MediaDecoderEventVisibility::Observable)
+    : mEventVisibility(aEventVisibility)
+    , mTime(aTime)
+    , mType(aType)
+  {
+  }
+  SeekTarget(const SeekTarget& aOther)
+    : mEventVisibility(aOther.mEventVisibility)
+    , mTime(aOther.mTime)
+    , mType(aOther.mType)
+  {
+  }
+  bool IsValid() const {
+    return mType != SeekTarget::Invalid;
+  }
+  void Reset() {
+    mTime = media::TimeUnit::Invalid();
+    mType = SeekTarget::Invalid;
+  }
+  media::TimeUnit GetTime() const {
+    NS_ASSERTION(mTime.IsValid(), "Invalid SeekTarget");
+    return mTime;
+  }
+  void SetTime(const media::TimeUnit& aTime) {
+    NS_ASSERTION(aTime.IsValid(), "Invalid SeekTarget destination");
+    mTime = aTime;
+  }
+  void SetType(Type aType) {
+    mType = aType;
+  }
+  bool IsFast() const {
+    return mType == SeekTarget::Type::PrevSyncPoint;
+  }
+  bool IsAccurate() const {
+    return mType == SeekTarget::Type::Accurate;
+  }
+
+  MediaDecoderEventVisibility mEventVisibility;
+
+private:
+  // Seek target time.
+  media::TimeUnit mTime;
+  // Whether we should seek "Fast", or "Accurate".
+  // "Fast" seeks to the seek point preceeding mTime, whereas
+  // "Accurate" seeks as close as possible to mTime.
+  Type mType;
+};
+
+} // namespace mozilla
+
+#endif /* SEEK_TARGET_H */
--- a/dom/media/TrackUnionStream.cpp
+++ b/dom/media/TrackUnionStream.cpp
@@ -62,18 +62,18 @@ TrackUnionStream::TrackUnionStream(DOMMe
     }
     ProcessedMediaStream::RemoveInput(aPort);
   }
   void TrackUnionStream::ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags)
   {
     if (IsFinishedOnGraphThread()) {
       return;
     }
-    nsAutoTArray<bool,8> mappedTracksFinished;
-    nsAutoTArray<bool,8> mappedTracksWithMatchingInputTracks;
+    AutoTArray<bool,8> mappedTracksFinished;
+    AutoTArray<bool,8> mappedTracksWithMatchingInputTracks;
     for (uint32_t i = 0; i < mTrackMap.Length(); ++i) {
       mappedTracksFinished.AppendElement(true);
       mappedTracksWithMatchingInputTracks.AppendElement(false);
     }
     bool allFinished = !mInputs.IsEmpty();
     bool allHaveCurrentData = !mInputs.IsEmpty();
     for (uint32_t i = 0; i < mInputs.Length(); ++i) {
       MediaStream* stream = mInputs[i]->GetSource();
--- a/dom/media/VideoFrameContainer.cpp
+++ b/dom/media/VideoFrameContainer.cpp
@@ -30,17 +30,17 @@ VideoFrameContainer::~VideoFrameContaine
 {}
 
 void VideoFrameContainer::SetCurrentFrame(const gfx::IntSize& aIntrinsicSize,
                                           Image* aImage,
                                           const TimeStamp& aTargetTime)
 {
   if (aImage) {
     MutexAutoLock lock(mMutex);
-    nsAutoTArray<ImageContainer::NonOwningImage,1> imageList;
+    AutoTArray<ImageContainer::NonOwningImage,1> imageList;
     imageList.AppendElement(
         ImageContainer::NonOwningImage(aImage, aTargetTime, ++mFrameID));
     SetCurrentFramesLocked(aIntrinsicSize, imageList);
   } else {
     ClearCurrentFrame(aIntrinsicSize);
   }
 }
 
--- a/dom/media/android/AndroidMediaReader.cpp
+++ b/dom/media/android/AndroidMediaReader.cpp
@@ -309,45 +309,45 @@ bool AndroidMediaReader::DecodeAudioData
                               frames,
                               source.mAudioChannels,
                               MPCopy(static_cast<uint8_t *>(source.mData),
                                      source.mSize,
                                      source.mAudioChannels));
 }
 
 RefPtr<MediaDecoderReader::SeekPromise>
-AndroidMediaReader::Seek(int64_t aTarget, int64_t aEndTime)
+AndroidMediaReader::Seek(SeekTarget aTarget, int64_t aEndTime)
 {
   MOZ_ASSERT(OnTaskQueue());
 
   RefPtr<SeekPromise> p = mSeekPromise.Ensure(__func__);
   if (mHasAudio && mHasVideo) {
     // The decoder seeks/demuxes audio and video streams separately. So if
     // we seek both audio and video to aTarget, the audio stream can typically
     // seek closer to the seek target, since typically every audio block is
     // a sync point, whereas for video there are only keyframes once every few
     // seconds. So if we have both audio and video, we must seek the video
     // stream to the preceeding keyframe first, get the stream time, and then
     // seek the audio stream to match the video stream's time. Otherwise, the
     // audio and video streams won't be in sync after the seek.
-    mVideoSeekTimeUs = aTarget;
+    mVideoSeekTimeUs = aTarget.GetTime().ToMicroseconds();
 
     RefPtr<AndroidMediaReader> self = this;
     mSeekRequest.Begin(DecodeToFirstVideoData()->Then(OwnerThread(), __func__, [self] (MediaData* v) {
       self->mSeekRequest.Complete();
       self->mAudioSeekTimeUs = v->mTime;
-      self->mSeekPromise.Resolve(self->mAudioSeekTimeUs, __func__);
+      self->mSeekPromise.Resolve(media::TimeUnit::FromMicroseconds(self->mAudioSeekTimeUs), __func__);
     }, [self, aTarget] () {
       self->mSeekRequest.Complete();
-      self->mAudioSeekTimeUs = aTarget;
-      self->mSeekPromise.Resolve(aTarget, __func__);
+      self->mAudioSeekTimeUs = aTarget.GetTime().ToMicroseconds();
+      self->mSeekPromise.Resolve(aTarget.GetTime(), __func__);
     }));
   } else {
-    mAudioSeekTimeUs = mVideoSeekTimeUs = aTarget;
-    mSeekPromise.Resolve(aTarget, __func__);
+    mAudioSeekTimeUs = mVideoSeekTimeUs = aTarget.GetTime().ToMicroseconds();
+    mSeekPromise.Resolve(aTarget.GetTime(), __func__);
   }
 
   return p;
 }
 
 AndroidMediaReader::ImageBufferCallback::ImageBufferCallback(mozilla::layers::ImageContainer *aImageContainer) :
   mImageContainer(aImageContainer)
 {
--- a/dom/media/android/AndroidMediaReader.h
+++ b/dom/media/android/AndroidMediaReader.h
@@ -43,17 +43,17 @@ public:
                      const nsACString& aContentType);
 
   nsresult ResetDecode() override;
 
   bool DecodeAudioData() override;
   bool DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold) override;
 
   nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags) override;
-  RefPtr<SeekPromise> Seek(int64_t aTime, int64_t aEndTime) override;
+  RefPtr<SeekPromise> Seek(SeekTarget aTarget, int64_t aEndTime) override;
 
   RefPtr<ShutdownPromise> Shutdown() override;
 
   class ImageBufferCallback : public MPAPI::BufferCallback {
     typedef mozilla::layers::Image Image;
 
   public:
     ImageBufferCallback(mozilla::layers::ImageContainer *aImageContainer);
--- a/dom/media/directshow/DirectShowReader.cpp
+++ b/dom/media/directshow/DirectShowReader.cpp
@@ -324,23 +324,23 @@ bool
 DirectShowReader::DecodeVideoFrame(bool &aKeyframeSkip,
                                    int64_t aTimeThreshold)
 {
   MOZ_ASSERT(OnTaskQueue());
   return false;
 }
 
 RefPtr<MediaDecoderReader::SeekPromise>
-DirectShowReader::Seek(int64_t aTargetUs, int64_t aEndTime)
+DirectShowReader::Seek(SeekTarget aTarget, int64_t aEndTime)
 {
-  nsresult res = SeekInternal(aTargetUs);
+  nsresult res = SeekInternal(aTarget.GetTime().ToMicroseconds());
   if (NS_FAILED(res)) {
     return SeekPromise::CreateAndReject(res, __func__);
   } else {
-    return SeekPromise::CreateAndResolve(aTargetUs, __func__);
+    return SeekPromise::CreateAndResolve(aTarget.GetTime(), __func__);
   }
 }
 
 nsresult
 DirectShowReader::SeekInternal(int64_t aTargetUs)
 {
   HRESULT hr;
   MOZ_ASSERT(OnTaskQueue());
--- a/dom/media/directshow/DirectShowReader.h
+++ b/dom/media/directshow/DirectShowReader.h
@@ -47,17 +47,17 @@ public:
   bool DecodeAudioData() override;
   bool DecodeVideoFrame(bool &aKeyframeSkip,
                         int64_t aTimeThreshold) override;
 
   nsresult ReadMetadata(MediaInfo* aInfo,
                         MetadataTags** aTags) override;
 
   RefPtr<SeekPromise>
-  Seek(int64_t aTime, int64_t aEndTime) override;
+  Seek(SeekTarget aTarget, int64_t aEndTime) override;
 
 protected:
   void NotifyDataArrivedInternal() override;
 
 private:
   // Notifies the filter graph that playback is complete. aStatus is
   // the code to send to the filter graph. Always returns false, so
   // that we can just "return Finish()" from DecodeAudioData().
--- a/dom/media/encoder/OpusTrackEncoder.cpp
+++ b/dom/media/encoder/OpusTrackEncoder.cpp
@@ -308,17 +308,17 @@ OpusTrackEncoder::GetEncodedTrack(Encode
     // original data, the pcm duration will be calculated at rate 48K later.
     if (mEndOfStream && !mEosSetInEncoder) {
       mEosSetInEncoder = true;
       mSourceSegment.AppendNullData(mLookahead);
     }
   }
 
   // Start encoding data.
-  nsAutoTArray<AudioDataValue, 9600> pcm;
+  AutoTArray<AudioDataValue, 9600> pcm;
   pcm.SetLength(GetPacketDuration() * mChannels);
   AudioSegment::ChunkIterator iter(mSourceSegment);
   int frameCopied = 0;
 
   while (!iter.IsEnded() && frameCopied < framesToFetch) {
     AudioChunk chunk = *iter;
 
     // Chunk to the required frame size.
@@ -339,17 +339,17 @@ OpusTrackEncoder::GetEncodedTrack(Encode
     frameCopied += frameToCopy;
     iter.Next();
   }
 
   RefPtr<EncodedFrame> audiodata = new EncodedFrame();
   audiodata->SetFrameType(EncodedFrame::OPUS_AUDIO_FRAME);
   int framesInPCM = frameCopied;
   if (mResampler) {
-    nsAutoTArray<AudioDataValue, 9600> resamplingDest;
+    AutoTArray<AudioDataValue, 9600> resamplingDest;
     // We want to consume all the input data, so we slightly oversize the
     // resampled data buffer so we can fit the output data in. We cannot really
     // predict the output frame count at each call.
     uint32_t outframes = frameCopied * kOpusSamplingRate / mSamplingRate + 1;
     uint32_t inframes = frameCopied;
 
     resamplingDest.SetLength(outframes * mChannels);
 
--- a/dom/media/encoder/TrackEncoder.cpp
+++ b/dom/media/encoder/TrackEncoder.cpp
@@ -135,26 +135,26 @@ AudioTrackEncoder::AppendAudioSegment(co
 void
 AudioTrackEncoder::InterleaveTrackData(AudioChunk& aChunk,
                                        int32_t aDuration,
                                        uint32_t aOutputChannels,
                                        AudioDataValue* aOutput)
 {
   switch(aChunk.mBufferFormat) {
     case AUDIO_FORMAT_S16: {
-      nsAutoTArray<const int16_t*, 2> array;
+      AutoTArray<const int16_t*, 2> array;
       array.SetLength(aOutputChannels);
       for (uint32_t i = 0; i < array.Length(); i++) {
         array[i] = static_cast<const int16_t*>(aChunk.mChannelData[i]);
       }
       InterleaveTrackData(array, aDuration, aOutputChannels, aOutput, aChunk.mVolume);
       break;
     }
     case AUDIO_FORMAT_FLOAT32: {
-      nsAutoTArray<const float*, 2> array;
+      AutoTArray<const float*, 2> array;
       array.SetLength(aOutputChannels);
       for (uint32_t i = 0; i < array.Length(); i++) {
         array[i] = static_cast<const float*>(aChunk.mChannelData[i]);
       }
       InterleaveTrackData(array, aDuration, aOutputChannels, aOutput, aChunk.mVolume);
       break;
    }
    case AUDIO_FORMAT_SILENCE: {
--- a/dom/media/encoder/VorbisTrackEncoder.cpp
+++ b/dom/media/encoder/VorbisTrackEncoder.cpp
@@ -197,18 +197,18 @@ VorbisTrackEncoder::GetEncodedTrack(Enco
 
   // Start encoding data.
   AudioSegment::ChunkIterator iter(*sourceSegment);
 
   AudioDataValue **vorbisBuffer =
     vorbis_analysis_buffer(&mVorbisDsp, (int)sourceSegment->GetDuration());
 
   int framesCopied = 0;
-  nsAutoTArray<AudioDataValue, 9600> interleavedPcm;
-  nsAutoTArray<AudioDataValue, 9600> nonInterleavedPcm;
+  AutoTArray<AudioDataValue, 9600> interleavedPcm;
+  AutoTArray<AudioDataValue, 9600> nonInterleavedPcm;
   interleavedPcm.SetLength(sourceSegment->GetDuration() * mChannels);
   nonInterleavedPcm.SetLength(sourceSegment->GetDuration() * mChannels);
   while (!iter.IsEnded()) {
     AudioChunk chunk = *iter;
     int frameToCopy = chunk.GetDuration();
     if (!chunk.IsNull()) {
       InterleaveTrackData(chunk, frameToCopy, mChannels,
                           interleavedPcm.Elements() + framesCopied * mChannels);
--- a/dom/media/gmp/GMPDecryptorChild.cpp
+++ b/dom/media/gmp/GMPDecryptorChild.cpp
@@ -152,17 +152,17 @@ GMPDecryptorChild::SessionError(const ch
 
 void
 GMPDecryptorChild::KeyStatusChanged(const char* aSessionId,
                                     uint32_t aSessionIdLength,
                                     const uint8_t* aKeyId,
                                     uint32_t aKeyIdLength,
                                     GMPMediaKeyStatus aStatus)
 {
-  nsAutoTArray<uint8_t, 16> kid;
+  AutoTArray<uint8_t, 16> kid;
   kid.AppendElements(aKeyId, aKeyIdLength);
   CALL_ON_GMP_THREAD(SendKeyStatusChanged,
                      nsCString(aSessionId, aSessionIdLength), kid,
                      aStatus);
 }
 
 void
 GMPDecryptorChild::Decrypted(GMPBuffer* aBuffer, GMPErr aResult)
--- a/dom/media/gtest/TestVorbisTrackEncoder.cpp
+++ b/dom/media/gtest/TestVorbisTrackEncoder.cpp
@@ -178,17 +178,17 @@ TEST(VorbisTrackEncoder, EncodedFrame)
   // Generate 1 second samples.
   // Reference PeerConnectionMedia.h::Fake_AudioGenerator
   RefPtr<mozilla::SharedBuffer> samples =
     mozilla::SharedBuffer::Create(rate * sizeof(AudioDataValue));
   AudioDataValue* data = static_cast<AudioDataValue*>(samples->Data());
   for (int i = 0; i < rate; i++) {
     data[i] = ((i%8)*4000) - (7*4000)/2;
   }
-  nsAutoTArray<const AudioDataValue*,1> channelData;
+  AutoTArray<const AudioDataValue*,1> channelData;
   channelData.AppendElement(data);
   AudioSegment segment;
   segment.AppendFrames(samples.forget(), channelData, 44100);
 
   // Track change notification.
   encoder.NotifyQueuedTrackChanges(nullptr, 0, 0, 0, segment);
 
   // Pull Encoded data back from encoder and verify encoded samples.
--- a/dom/media/mediasink/DecodedStream.cpp
+++ b/dom/media/mediasink/DecodedStream.cpp
@@ -495,17 +495,17 @@ SendStreamAudio(DecodedStreamData* aStre
     aOutput->AppendFrom(&silence);
   }
 
   // Always write the whole sample without truncation to be consistent with
   // DecodedAudioDataSink::PlayFromAudioQueue()
   audio->EnsureAudioBuffer();
   RefPtr<SharedBuffer> buffer = audio->mAudioBuffer;
   AudioDataValue* bufferData = static_cast<AudioDataValue*>(buffer->Data());
-  nsAutoTArray<const AudioDataValue*, 2> channels;
+  AutoTArray<const AudioDataValue*, 2> channels;
   for (uint32_t i = 0; i < audio->mChannels; ++i) {
     channels.AppendElement(bufferData + i * audio->mFrames);
   }
   aOutput->AppendFrames(buffer.forget(), channels, audio->mFrames);
   aStream->mAudioFramesWritten += audio->mFrames;
   aOutput->ApplyVolume(aVolume);
 
   aStream->mNextAudioTime = audio->GetEndTime();
@@ -517,17 +517,17 @@ DecodedStream::SendAudio(double aVolume,
   AssertOwnerThread();
 
   if (!mInfo.HasAudio()) {
     return;
   }
 
   AudioSegment output;
   uint32_t rate = mInfo.mAudio.mRate;
-  nsAutoTArray<RefPtr<MediaData>,10> audio;
+  AutoTArray<RefPtr<MediaData>,10> audio;
   TrackID audioTrackId = mInfo.mAudio.mTrackId;
   SourceMediaStream* sourceStream = mData->mStream;
 
   // It's OK to hold references to the AudioData because AudioData
   // is ref-counted.
   mAudioQueue.GetElementsAfter(mData->mNextAudioTime, &audio);
   for (uint32_t i = 0; i < audio.Length(); ++i) {
     SendStreamAudio(mData.get(), mStartTime.ref(), audio[i], &output, rate, aVolume);
@@ -582,17 +582,17 @@ DecodedStream::SendVideo(bool aIsSameOri
   AssertOwnerThread();
 
   if (!mInfo.HasVideo()) {
     return;
   }
 
   VideoSegment output;
   TrackID videoTrackId = mInfo.mVideo.mTrackId;
-  nsAutoTArray<RefPtr<MediaData>, 10> video;
+  AutoTArray<RefPtr<MediaData>, 10> video;
   SourceMediaStream* sourceStream = mData->mStream;
 
   // It's OK to hold references to the VideoData because VideoData
   // is ref-counted.
   mVideoQueue.GetElementsAfter(mData->mNextVideoTime, &video);
 
   for (uint32_t i = 0; i < video.Length(); ++i) {
     VideoData* v = video[i]->As<VideoData>();
--- a/dom/media/mediasink/VideoSink.cpp
+++ b/dom/media/mediasink/VideoSink.cpp
@@ -309,23 +309,23 @@ VideoSink::DisconnectListener()
 
 void
 VideoSink::RenderVideoFrames(int32_t aMaxFrames,
                              int64_t aClockTime,
                              const TimeStamp& aClockTimeStamp)
 {
   AssertOwnerThread();
 
-  nsAutoTArray<RefPtr<MediaData>,16> frames;
+  AutoTArray<RefPtr<MediaData>,16> frames;
   VideoQueue().GetFirstElements(aMaxFrames, &frames);
   if (frames.IsEmpty() || !mContainer) {
     return;
   }
 
-  nsAutoTArray<ImageContainer::NonOwningImage,16> images;
+  AutoTArray<ImageContainer::NonOwningImage,16> images;
   TimeStamp lastFrameTime;
   MediaSink::PlaybackParams params = mAudioSink->GetPlaybackParams();
   for (uint32_t i = 0; i < frames.Length(); ++i) {
     VideoData* frame = frames[i]->As<VideoData>();
 
     frame->mSentToCompositor = true;
 
     if (!frame->mImage || !frame->mImage->IsValid()) {
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -781,16 +781,19 @@ TrackBuffersManager::ShutdownDemuxers()
   if (mVideoTracks.mDemuxer) {
     mVideoTracks.mDemuxer->BreakCycles();
     mVideoTracks.mDemuxer = nullptr;
   }
   if (mAudioTracks.mDemuxer) {
     mAudioTracks.mDemuxer->BreakCycles();
     mAudioTracks.mDemuxer = nullptr;
   }
+  // We shouldn't change mInputDemuxer while a demuxer init/reset request is
+  // being processed. See bug 1239983.
+  MOZ_DIAGNOSTIC_ASSERT(!mDemuxerInitRequest.Exists());
   mInputDemuxer = nullptr;
   mLastParsedEndTime.reset();
 }
 
 void
 TrackBuffersManager::CreateDemuxerforMIMEType()
 {
   ShutdownDemuxers();
@@ -838,16 +841,19 @@ TrackBuffersManager::OnDemuxerResetDone(
 {
   MOZ_ASSERT(OnTaskQueue());
   MSE_DEBUG("mAbort:%d", static_cast<bool>(mAbort));
   mDemuxerInitRequest.Complete();
   if (mAbort) {
     RejectAppend(NS_ERROR_ABORT, __func__);
     return;
   }
+  // mInputDemuxer shouldn't have been destroyed while a demuxer init/reset
+  // request was being processed. See bug 1239983.
+  MOZ_DIAGNOSTIC_ASSERT(mInputDemuxer);
 
   // Recreate track demuxers.
   uint32_t numVideos = mInputDemuxer->GetNumberTracks(TrackInfo::kVideoTrack);
   if (numVideos) {
     // We currently only handle the first video track.
     mVideoTracks.mDemuxer = mInputDemuxer->GetTrackDemuxer(TrackInfo::kVideoTrack, 0);
     MOZ_ASSERT(mVideoTracks.mDemuxer);
   }
@@ -913,16 +919,19 @@ TrackBuffersManager::OnDemuxerInitDone(n
   MOZ_ASSERT(OnTaskQueue());
   MSE_DEBUG("mAbort:%d", static_cast<bool>(mAbort));
   mDemuxerInitRequest.Complete();
 
   if (mAbort) {
     RejectAppend(NS_ERROR_ABORT, __func__);
     return;
   }
+  // mInputDemuxer shouldn't have been destroyed while a demuxer init/reset
+  // request was being processed. See bug 1239983.
+  MOZ_DIAGNOSTIC_ASSERT(mInputDemuxer);
 
   MediaInfo info;
 
   uint32_t numVideos = mInputDemuxer->GetNumberTracks(TrackInfo::kVideoTrack);
   if (numVideos) {
     // We currently only handle the first video track.
     mVideoTracks.mDemuxer = mInputDemuxer->GetTrackDemuxer(TrackInfo::kVideoTrack, 0);
     MOZ_ASSERT(mVideoTracks.mDemuxer);
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -128,16 +128,17 @@ EXPORTS += [
     'MediaTimer.h',
     'MediaTrack.h',
     'MediaTrackList.h',
     'MP3Decoder.h',
     'MP3Demuxer.h',
     'MP3FrameParser.h',
     'nsIDocumentActivity.h',
     'RtspMediaResource.h',
+    'SeekTarget.h',
     'SelfRef.h',
     'SharedBuffer.h',
     'StreamBuffer.h',
     'ThreadPoolCOMListener.h',
     'TimeUnits.h',
     'TrackUnionStream.h',
     'VideoFrameContainer.h',
     'VideoSegment.h',
--- a/dom/media/ogg/OggReader.cpp
+++ b/dom/media/ogg/OggReader.cpp
@@ -291,17 +291,17 @@ void OggReader::SetupTargetSkeleton(Skel
   if (aSkeletonState) {
     if (!HasAudio() && !HasVideo()) {
       // We have a skeleton track, but no audio or video, may as well disable
       // the skeleton, we can't do anything useful with this media.
       aSkeletonState->Deactivate();
     } else if (ReadHeaders(aSkeletonState) && aSkeletonState->HasIndex()) {
       // Extract the duration info out of the index, so we don't need to seek to
       // the end of resource to get it.
-      nsAutoTArray<uint32_t, 2> tracks;
+      AutoTArray<uint32_t, 2> tracks;
       BuildSerialList(tracks);
       int64_t duration = 0;
       if (NS_SUCCEEDED(aSkeletonState->GetDuration(tracks, duration))) {
         LOG(LogLevel::Debug, ("Got duration from Skeleton index %lld", duration));
         mInfo.mMetadataDuration.emplace(TimeUnit::FromMicroseconds(duration));
       }
     }
   }
@@ -390,17 +390,17 @@ nsresult OggReader::ReadMetadata(MediaIn
   // We read packets until all bitstreams have read all their header packets.
   // We record the offset of the first non-header page so that we know
   // what page to seek to when seeking to the media start.
 
   NS_ASSERTION(aTags, "Called with null MetadataTags**.");
   *aTags = nullptr;
 
   ogg_page page;
-  nsAutoTArray<OggCodecState*,4> bitstreams;
+  AutoTArray<OggCodecState*,4> bitstreams;
   nsTArray<uint32_t> serials;
   bool readAllBOS = false;
   while (!readAllBOS) {
     if (!ReadOggPage(&page)) {
       // Some kind of error...
       break;
     }
 
@@ -1249,17 +1249,17 @@ OggReader::IndexedSeekResult OggReader::
 }
 
 OggReader::IndexedSeekResult OggReader::SeekToKeyframeUsingIndex(int64_t aTarget)
 {
   if (!HasSkeleton() || !mSkeletonState->HasIndex()) {
     return SEEK_INDEX_FAIL;
   }
   // We have an index from the Skeleton track, try to use it to seek.
-  nsAutoTArray<uint32_t, 2> tracks;
+  AutoTArray<uint32_t, 2> tracks;
   BuildSerialList(tracks);
   SkeletonState::nsSeekTarget keyframe;
   if (NS_FAILED(mSkeletonState->IndexedSeekTarget(aTarget,
                                                   tracks,
                                                   keyframe)))
   {
     // Could not locate a keypoint for the target in the index.
     return SEEK_INDEX_FAIL;
@@ -1403,23 +1403,23 @@ nsresult OggReader::SeekInUnbuffered(int
   int64_t seekTarget = std::max(aStartTime, aTarget - keyframeOffsetMs);
   // Minimize the bisection search space using the known timestamps from the
   // buffered ranges.
   SeekRange k = SelectSeekRange(aRanges, seekTarget, aStartTime, aEndTime, false);
   return SeekBisection(seekTarget, k, SEEK_FUZZ_USECS);
 }
 
 RefPtr<MediaDecoderReader::SeekPromise>
-OggReader::Seek(int64_t aTarget, int64_t aEndTime)
+OggReader::Seek(SeekTarget aTarget, int64_t aEndTime)
 {
-  nsresult res = SeekInternal(aTarget, aEndTime);
+  nsresult res = SeekInternal(aTarget.GetTime().ToMicroseconds(), aEndTime);
   if (NS_FAILED(res)) {
     return SeekPromise::CreateAndReject(res, __func__);
   } else {
-    return SeekPromise::CreateAndResolve(aTarget, __func__);
+    return SeekPromise::CreateAndResolve(aTarget.GetTime(), __func__);
   }
 }
 
 nsresult OggReader::SeekInternal(int64_t aTarget, int64_t aEndTime)
 {
   MOZ_ASSERT(OnTaskQueue());
   NS_ENSURE_TRUE(HaveStartTime(), NS_ERROR_FAILURE);
   if (mIsChained)
@@ -1444,17 +1444,17 @@ nsresult OggReader::SeekInternal(int64_t
     // have a way of asking Skeleton to seek to a different target for each
     // stream yet. Using adjustedTarget here is at least correct, if slow.
     IndexedSeekResult sres = SeekToKeyframeUsingIndex(adjustedTarget);
     NS_ENSURE_TRUE(sres != SEEK_FATAL_ERROR, NS_ERROR_FAILURE);
     if (sres == SEEK_INDEX_FAIL) {
       // No index or other non-fatal index-related failure. Try to seek
       // using a bisection search. Determine the already downloaded data
       // in the media cache, so we can try to seek in the cached data first.
-      nsAutoTArray<SeekRange, 16> ranges;
+      AutoTArray<SeekRange, 16> ranges;
       res = GetSeekRanges(ranges);
       NS_ENSURE_SUCCESS(res,res);
 
       // Figure out if the seek target lies in a buffered range.
       SeekRange r = SelectSeekRange(ranges, aTarget, StartTime(), aEndTime, true);
 
       if (!r.IsNull()) {
         // We know the buffered range in which the seek target lies, do a
--- a/dom/media/ogg/OggReader.h
+++ b/dom/media/ogg/OggReader.h
@@ -55,17 +55,17 @@ public:
   bool DecodeAudioData() override;
 
   // If the Theora granulepos has not been captured, it may read several packets
   // until one with a granulepos has been captured, to ensure that all packets
   // read have valid time info.
   bool DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold) override;
 
   nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags) override;
-  RefPtr<SeekPromise> Seek(int64_t aTime, int64_t aEndTime) override;
+  RefPtr<SeekPromise> Seek(SeekTarget aTarget, int64_t aEndTime) override;
   media::TimeIntervals GetBuffered() override;
 
 private:
   bool HasAudio() {
     return (mVorbisState != 0 && mVorbisState->mActive) ||
            (mOpusState != 0 && mOpusState->mActive);
   }
 
--- a/dom/media/omx/AudioOffloadPlayer.cpp
+++ b/dom/media/omx/AudioOffloadPlayer.cpp
@@ -340,21 +340,22 @@ RefPtr<MediaDecoder::SeekPromise> AudioO
 }
 
 status_t AudioOffloadPlayer::DoSeek()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mSeekTarget.IsValid());
   CHECK(mAudioSink.get());
 
-  AUDIO_OFFLOAD_LOG(LogLevel::Debug, ("DoSeek ( %lld )", mSeekTarget.mTime));
+  AUDIO_OFFLOAD_LOG(LogLevel::Debug,
+                    ("DoSeek ( %lld )", mSeekTarget.GetTime().ToMicroseconds()));
 
   mReachedEOS = false;
   mPositionTimeMediaUs = -1;
-  mStartPosUs = mSeekTarget.mTime;
+  mStartPosUs = mSeekTarget.GetTime().ToMicroseconds();
 
   if (!mSeekPromise.IsEmpty()) {
     nsCOMPtr<nsIRunnable> nsEvent =
       NS_NewRunnableMethodWithArg<MediaDecoderEventVisibility>(
         mObserver,
         &MediaDecoder::SeekingStarted,
         mSeekTarget.mEventVisibility);
     NS_DispatchToCurrentThread(nsEvent);
@@ -382,17 +383,17 @@ status_t AudioOffloadPlayer::DoSeek()
 }
 
 int64_t AudioOffloadPlayer::GetMediaTimeUs()
 {
   android::Mutex::Autolock autoLock(mLock);
 
   int64_t playPosition = 0;
   if (mSeekTarget.IsValid()) {
-    return mSeekTarget.mTime;
+    return mSeekTarget.GetTime().ToMicroseconds();
   }
   if (!mStarted) {
     return mPositionTimeMediaUs;
   }
 
   playPosition = GetOutputPlayPositionUs_l();
   if (!mReachedEOS) {
     mPositionTimeMediaUs = playPosition;
@@ -500,17 +501,17 @@ size_t AudioOffloadPlayer::FillBuffer(vo
   int64_t seekTimeUs = -1;
   while (sizeRemaining > 0) {
     MediaSource::ReadOptions options;
     bool refreshSeekTime = false;
     {
       android::Mutex::Autolock autoLock(mLock);
 
       if (mSeekTarget.IsValid()) {
-        seekTimeUs = mSeekTarget.mTime;
+        seekTimeUs = mSeekTarget.GetTime().ToMicroseconds();
         options.setSeekTo(seekTimeUs);
         refreshSeekTime = true;
 
         if (mInputBuffer) {
           mInputBuffer->release();
           mInputBuffer = nullptr;
         }
       }
@@ -552,17 +553,18 @@ size_t AudioOffloadPlayer::FillBuffer(vo
         break;
       }
 
       if(mInputBuffer->range_length() != 0) {
         CHECK(mInputBuffer->meta_data()->findInt64(
             kKeyTime, &mPositionTimeMediaUs));
       }
 
-      if (mSeekTarget.IsValid() && seekTimeUs == mSeekTarget.mTime) {
+      if (mSeekTarget.IsValid() &&
+          seekTimeUs == mSeekTarget.GetTime().ToMicroseconds()) {
         MOZ_ASSERT(mSeekTarget.IsValid());
         mSeekTarget.Reset();
         if (!mSeekPromise.IsEmpty()) {
           AUDIO_OFFLOAD_LOG(LogLevel::Debug, ("FillBuffer posting SEEK_COMPLETE"));
           MediaDecoder::SeekResolveValue val(mReachedEOS, mSeekTarget.mEventVisibility);
           mSeekPromise.Resolve(val, __func__);
         }
       } else if (mSeekTarget.IsValid()) {
--- a/dom/media/omx/MediaOmxReader.cpp
+++ b/dom/media/omx/MediaOmxReader.cpp
@@ -518,46 +518,46 @@ bool MediaOmxReader::DecodeAudioData()
                               frames,
                               source.mAudioChannels,
                               OmxCopy(static_cast<uint8_t *>(source.mData),
                                       source.mSize,
                                       source.mAudioChannels));
 }
 
 RefPtr<MediaDecoderReader::SeekPromise>
-MediaOmxReader::Seek(int64_t aTarget, int64_t aEndTime)
+MediaOmxReader::Seek(SeekTarget aTarget, int64_t aEndTime)
 {
   MOZ_ASSERT(OnTaskQueue());
   EnsureActive();
   RefPtr<SeekPromise> p = mSeekPromise.Ensure(__func__);
 
   if (mHasAudio && mHasVideo) {
     // The OMXDecoder seeks/demuxes audio and video streams separately. So if
     // we seek both audio and video to aTarget, the audio stream can typically
     // seek closer to the seek target, since typically every audio block is
     // a sync point, whereas for video there are only keyframes once every few
     // seconds. So if we have both audio and video, we must seek the video
     // stream to the preceeding keyframe first, get the stream time, and then
     // seek the audio stream to match the video stream's time. Otherwise, the
     // audio and video streams won't be in sync after the seek.
-    mVideoSeekTimeUs = aTarget;
+    mVideoSeekTimeUs = aTarget.GetTime().ToMicroseconds();
 
     RefPtr<MediaOmxReader> self = this;
     mSeekRequest.Begin(DecodeToFirstVideoData()->Then(OwnerThread(), __func__, [self] (MediaData* v) {
       self->mSeekRequest.Complete();
       self->mAudioSeekTimeUs = v->mTime;
-      self->mSeekPromise.Resolve(self->mAudioSeekTimeUs, __func__);
+      self->mSeekPromise.Resolve(media::TimeUnit::FromMicroseconds(self->mAudioSeekTimeUs), __func__);
     }, [self, aTarget] () {
       self->mSeekRequest.Complete();
-      self->mAudioSeekTimeUs = aTarget;
-      self->mSeekPromise.Resolve(aTarget, __func__);
+      self->mAudioSeekTimeUs = aTarget.GetTime().ToMicroseconds();
+      self->mSeekPromise.Resolve(aTarget.GetTime(), __func__);
     }));
   } else {
-    mAudioSeekTimeUs = mVideoSeekTimeUs = aTarget;
-    mSeekPromise.Resolve(aTarget, __func__);
+    mAudioSeekTimeUs = mVideoSeekTimeUs = aTarget.GetTime().ToMicroseconds();
+    mSeekPromise.Resolve(aTarget.GetTime(), __func__);
   }
 
   return p;
 }
 
 void MediaOmxReader::SetIdle() {
   if (!mOmxDecoder.get()) {
     return;
--- a/dom/media/omx/MediaOmxReader.h
+++ b/dom/media/omx/MediaOmxReader.h
@@ -84,17 +84,17 @@ public:
   bool DecodeAudioData() override;
   bool DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold) override;
 
   void ReleaseMediaResources() override;
 
   RefPtr<MediaDecoderReader::MetadataPromise> AsyncReadMetadata() override;
 
   RefPtr<SeekPromise>
-  Seek(int64_t aTime, int64_t aEndTime) override;
+  Seek(SeekTarget aTarget, int64_t aEndTime) override;
 
   void SetIdle() override;
 
   RefPtr<ShutdownPromise> Shutdown() override;
 
   android::sp<android::MediaSource> GetAudioOffloadTrack();
 
   // This method is intended only for private use but public only for
--- a/dom/media/omx/OMXCodecWrapper.cpp
+++ b/dom/media/omx/OMXCodecWrapper.cpp
@@ -746,17 +746,17 @@ public:
       if (aChunk.IsNull()) {
         bytesCopied = SendSilenceToBuffer(chunkSamples);
       } else {
         bytesCopied = SendChunkToBuffer(aChunk, chunkSamples);
       }
       UpdateAfterSendChunk(chunkSamples, bytesCopied, aSamplesRead);
     } else {
       // Interleave data to a temporary buffer.
-      nsAutoTArray<AudioDataValue, 9600> pcm;
+      AutoTArray<AudioDataValue, 9600> pcm;
       pcm.SetLength(bytesToCopy);
       AudioDataValue* interleavedSource = pcm.Elements();
       AudioTrackEncoder::InterleaveTrackData(aChunk, chunkSamples,
                                              mOMXAEncoder.mChannels,
                                              interleavedSource);
 
       // When the data size of chunk is larger than the buffer capacity,
       // we split it into sub-chunks to fill up buffers.
@@ -848,17 +848,17 @@ private:
   // and return the copied bytes number of audio data.
   size_t SendChunkToBuffer(AudioChunk& aSource, size_t aSamplesNum)
   {
     AudioDataValue* dst = reinterpret_cast<AudioDataValue*>(GetPointer());
     size_t bytesToCopy = aSamplesNum * mOMXAEncoder.mResamplingRatio
                          * mOMXAEncoder.mChannels * sizeof(AudioDataValue);
     uint32_t dstSamplesCopied = aSamplesNum;
     if (mOMXAEncoder.mResampler) {
-      nsAutoTArray<AudioDataValue, 9600> pcm;
+      AutoTArray<AudioDataValue, 9600> pcm;
       pcm.SetLength(bytesToCopy);
       AudioTrackEncoder::InterleaveTrackData(aSource, aSamplesNum,
                                              mOMXAEncoder.mChannels,
                                              pcm.Elements());
       int16_t* tempSource = reinterpret_cast<int16_t*>(pcm.Elements());
       speex_resampler_process_interleaved_int(mOMXAEncoder.mResampler, tempSource,
                                               &aSamplesNum, dst,
                                               &dstSamplesCopied);
--- a/dom/media/omx/RtspOmxReader.cpp
+++ b/dom/media/omx/RtspOmxReader.cpp
@@ -28,33 +28,33 @@ nsresult RtspOmxReader::InitOmxDecoder()
     if (!mOmxDecoder->Init(mExtractor)) {
       return NS_ERROR_FAILURE;
     }
   }
   return NS_OK;
 }
 
 RefPtr<MediaDecoderReader::SeekPromise>
-RtspOmxReader::Seek(int64_t aTime, int64_t aEndTime)
+RtspOmxReader::Seek(SeekTarget aTarget, int64_t aEndTime)
 {
   // The seek function of Rtsp is time-based, we call the SeekTime function in
   // RtspMediaResource. The SeekTime function finally send a seek command to
   // Rtsp stream server through network and also clear the buffer data in
   // RtspMediaResource.
   if (mRtspResource) {
-    mRtspResource->SeekTime(aTime);
+    mRtspResource->SeekTime(aTarget.GetTime().ToMicroseconds());
     mRtspResource->EnablePlayoutDelay();
   }
 
   // Call |MediaOmxReader::Seek| to notify the OMX decoder we are performing a
   // seek operation. The function will clear the |mVideoQueue| and |mAudioQueue|
   // that store the decoded data and also call the |DecodeToTarget| to pass
   // the seek time to OMX a/v decoders.
   mEnsureActiveFromSeek = true;
-  return MediaOmxReader::Seek(aTime, aEndTime);
+  return MediaOmxReader::Seek(aTarget, aEndTime);
 }
 
 void RtspOmxReader::SetIdle() {
   // Call parent class to set OMXCodec idle.
   MediaOmxReader::SetIdle();
 
   // Need to pause RTSP streaming OMXCodec decoding.
   if (mRtspResource) {
--- a/dom/media/omx/RtspOmxReader.h
+++ b/dom/media/omx/RtspOmxReader.h
@@ -43,17 +43,17 @@ public:
     MOZ_ASSERT(mRtspResource);
   }
 
   virtual ~RtspOmxReader() {
     MOZ_COUNT_DTOR(RtspOmxReader);
   }
 
   // Implement a time-based seek instead of byte-based..
-  RefPtr<SeekPromise> Seek(int64_t aTime, int64_t aEndTime) final override;
+  RefPtr<SeekPromise> Seek(SeekTarget aTarget, int64_t aEndTime) final override;
 
   // Override GetBuffered() to do nothing for below reasons:
   // 1. Because the Rtsp stream is a/v separated. The buffered data in a/v
   // tracks are not consistent with time stamp.
   // For example: audio buffer: 1~2s, video buffer: 1.5~2.5s
   // 2. Since the Rtsp is a realtime streaming, the buffer we made for
   // RtspMediaResource is quite small. The small buffer implies the time ranges
   // we returned are not useful for the MediaDecodeStateMachine. Unlike the
--- a/dom/media/platforms/agnostic/VorbisDecoder.cpp
+++ b/dom/media/platforms/agnostic/VorbisDecoder.cpp
@@ -66,18 +66,18 @@ VorbisDataDecoder::Shutdown()
 RefPtr<MediaDataDecoder::InitPromise>
 VorbisDataDecoder::Init()
 {
   vorbis_info_init(&mVorbisInfo);
   vorbis_comment_init(&mVorbisComment);
   PodZero(&mVorbisDsp);
   PodZero(&mVorbisBlock);
 
-  nsAutoTArray<unsigned char*,4> headers;
-  nsAutoTArray<size_t,4> headerLens;
+  AutoTArray<unsigned char*,4> headers;
+  AutoTArray<size_t,4> headerLens;
   if (!XiphExtradataToHeaders(headers, headerLens,
                               mInfo.mCodecSpecificConfig->Elements(),
                               mInfo.mCodecSpecificConfig->Length())) {
     return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
   }
   for (size_t i = 0; i < headers.Length(); i++) {
     if (NS_FAILED(DecodeHeader(headers[i], headerLens[i]))) {
       return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
@@ -118,17 +118,17 @@ private:
     }
     // Remove all elements of the map.
     void Clear()
     {
       mMap.Clear();
     }
 
   private:
-    nsAutoTArray<DurationElement, 16> mMap;
+    AutoTArray<DurationElement, 16> mMap;
   };
 
   DurationMap mDurationMap;
 };
 
 } // namespace mozilla
 
 #endif // __FFmpegVideoDecoder_h__
--- a/dom/media/raw/RawReader.cpp
+++ b/dom/media/raw/RawReader.cpp
@@ -201,49 +201,49 @@ bool RawReader::DecodeVideoFrame(bool &a
   mVideoQueue.Push(v);
   mCurrentFrame++;
   a.mDecoded++;
 
   return true;
 }
 
 RefPtr<MediaDecoderReader::SeekPromise>
-RawReader::Seek(int64_t aTime, int64_t aEndTime)
+RawReader::Seek(SeekTarget aTarget, int64_t aEndTime)
 {
   MOZ_ASSERT(OnTaskQueue());
 
   uint32_t frame = mCurrentFrame;
-  if (aTime >= UINT_MAX)
+  if (aTarget.GetTime().ToMicroseconds() >= UINT_MAX)
     return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
-  mCurrentFrame = aTime * mFrameRate / USECS_PER_S;
+  mCurrentFrame = aTarget.GetTime().ToMicroseconds() * mFrameRate / USECS_PER_S;
 
   CheckedUint32 offset = CheckedUint32(mCurrentFrame) * mFrameSize;
   offset += sizeof(RawVideoHeader);
   NS_ENSURE_TRUE(offset.isValid(), SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__));
 
   nsresult rv = mResource.Seek(nsISeekableStream::NS_SEEK_SET, offset.value());
   NS_ENSURE_SUCCESS(rv, SeekPromise::CreateAndReject(rv, __func__));
 
   mVideoQueue.Reset();
   RefPtr<SeekPromise::Private> p = new SeekPromise::Private(__func__);
   RefPtr<RawReader> self = this;
   InvokeUntil([self] () {
     MOZ_ASSERT(self->OnTaskQueue());
     NS_ENSURE_TRUE(!self->mShutdown, false);
     bool skip = false;
     return self->DecodeVideoFrame(skip, 0);
-  }, [self, aTime] () {
+  }, [self, aTarget] () {
     MOZ_ASSERT(self->OnTaskQueue());
     return self->mVideoQueue.Peek() &&
-           self->mVideoQueue.Peek()->GetEndTime() >= aTime;
-  })->Then(OwnerThread(), __func__, [self, p, aTime] () {
+           self->mVideoQueue.Peek()->GetEndTime() >= aTarget.GetTime().ToMicroseconds();
+  })->Then(OwnerThread(), __func__, [self, p, aTarget] () {
     while (self->mVideoQueue.GetSize() >= 2) {
       RefPtr<VideoData> releaseMe = self->mVideoQueue.PopFront();
     }
-    p->Resolve(aTime, __func__);
+    p->Resolve(aTarget.GetTime(), __func__);
   }, [self, p, frame] {
     self->mCurrentFrame = frame;
     self->mVideoQueue.Reset();
     p->Reject(NS_ERROR_FAILURE, __func__);
   });
 
   return p.forget();
 }
--- a/dom/media/raw/RawReader.h
+++ b/dom/media/raw/RawReader.h
@@ -23,17 +23,17 @@ public:
   nsresult ResetDecode() override;
   bool DecodeAudioData() override;
 
   bool DecodeVideoFrame(bool &aKeyframeSkip,
                         int64_t aTimeThreshold) override;
 
   nsresult ReadMetadata(MediaInfo* aInfo,
                         MetadataTags** aTags) override;
-  RefPtr<SeekPromise> Seek(int64_t aTime, int64_t aEndTime) override;
+  RefPtr<SeekPromise> Seek(SeekTarget aTarget, int64_t aEndTime) override;
 
   media::TimeIntervals GetBuffered() override;
 
 private:
   bool ReadFromResource(uint8_t *aBuf, uint32_t aLength);
 
   RawVideoHeader mMetadata;
   uint32_t mCurrentFrame;
--- a/dom/media/systemservices/MediaUtils.h
+++ b/dom/media/systemservices/MediaUtils.h
@@ -316,17 +316,17 @@ public:
   }
 
 private:
   static uint32_t GetNextId()
   {
     static uint32_t counter = 0;
     return ++counter;
   };
-  nsAutoTArray<Element, 3> mElements;
+  AutoTArray<Element, 3> mElements;
 };
 
 /* media::Refcountable - Add threadsafe ref-counting to something that isn't.
  *
  * Often, reference counting is the most practical way to share an object with
  * another thread without imposing lifetime restrictions, even if there's
  * otherwise no concurrent access happening on the object.  For instance, an
  * algorithm on another thread may find it more expedient to modify a passed-in
--- a/dom/media/test/external/requirements.txt
+++ b/dom/media/test/external/requirements.txt
@@ -10,15 +10,14 @@ mozInstall==1.12
 mozlog==3.1
 moznetwork==0.27
 mozprocess==0.22
 mozprofile==0.28
 mozrunner==6.11
 moztest==0.7
 mozversion==1.4
 wptserve==1.3.0
-marionette-client == 2.1.0
-marionette-driver == 1.2.0
-marionette-transport == 1.1.0
+marionette-client==2.1.0
+marionette-driver==1.2.0
 firefox-puppeteer==3.1.0
 
 # Install the firefox media tests package
 ./
--- a/dom/media/test/manifest.js
+++ b/dom/media/test/manifest.js
@@ -475,17 +475,20 @@ var gSeekTests = [
   { name:"320x240.ogv", type:"video/ogg", duration:0.266 },
   { name:"seek.webm", type:"video/webm", duration:3.966 },
   { name:"sine.webm", type:"audio/webm", duration:4.001 },
   { name:"bug516323.indexed.ogv", type:"video/ogg", duration:4.208333 },
   { name:"split.webm", type:"video/webm", duration:1.967 },
   { name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 },
   { name:"gizmo.mp4", type:"video/mp4", duration:5.56 },
   { name:"owl.mp3", type:"audio/mpeg", duration:3.343 },
-  { name:"bogus.duh", type:"bogus/duh", duration:123 }
+  { name:"bogus.duh", type:"bogus/duh", duration:123 },
+
+  // Bug 1242338: hit a numerical problem while seeking to the duration.
+  { name:"bug482461-theora.ogv", type:"video/ogg", duration:4.138 },
 ];
 
 var gFastSeekTests = [
   { name:"gizmo.mp4", type:"video/mp4", keyframes:[0, 1.0, 2.0, 3.0, 4.0, 5.0 ] },
   // Note: Not all keyframes in the file are actually referenced in the Cues in this file.
   { name:"seek.webm", type:"video/webm", keyframes:[0, 0.8, 1.6, 2.4, 3.2]},
   // Note: the sync points are the points on both the audio and video streams
   // before the keyframes. You can't just assume that the keyframes are the sync
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -596,16 +596,17 @@ skip-if = os == 'win' && !debug # bug 11
 [test_bug883173.html]
 [test_bug895091.html]
 [test_bug895305.html]
 [test_bug919265.html]
 [test_bug957847.html]
 [test_bug1018933.html]
 [test_bug1113600.html]
 tags=capturestream
+[test_bug1242338.html]
 [test_can_play_type.html]
 [test_can_play_type_mpeg.html]
 skip-if = buildapp == 'b2g' || (toolkit == 'android' && processor == 'x86') # bug 1021675 #x86 only bug 914439
 [test_can_play_type_no_ogg.html]
 [test_can_play_type_ogg.html]
 [test_chaining.html]
 [test_clone_media_element.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
new file mode 100644
--- /dev/null
+++ b/dom/media/test/test_bug1242338.html
@@ -0,0 +1,66 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test Bug 1242338</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+var manager = new MediaTestManager;
+
+function startTest(test, token) {
+  var video = document.createElement('video');
+  video.preload = "metadata";
+  video.token = token;
+
+  var handler = {
+    "ontimeout": function() {
+      Log(token, "timed out");
+    }
+  };
+  manager.started(token, handler);
+
+  video.src = test.name;
+  video.name = test.name;
+
+  function finish() {
+    video.finished = true;
+    video.removeEventListener("loadedmetadata", onLoadedmetadata, false);
+    video.removeEventListener("ended", onEnded, false);
+    removeNodeAndSource(video);
+    manager.finished(video.token);
+  }
+
+  function onLoadedmetadata() {
+    // seek to the media's duration
+    var duration = video.duration;
+    console.log("onloadedmetadata(), duration = " + duration);
+    video.currentTime = duration;
+  }
+
+  function onEnded() {
+    ok(video.ended, test.name + " checking playback has ended");
+    ok(!video.finished, test.name + " shouldn't be finished");
+    ok(!video.seenEnded, test.name + " shouldn't be ended");
+    video.seenEnded = true;
+
+    ok(true, "Seeking to the duration triggers ended event");
+    finish();
+  }
+
+  video.addEventListener("loadedmetadata", onLoadedmetadata, false);
+  video.addEventListener("ended", onEnded, false);
+
+  document.body.appendChild(video);
+}
+
+manager.runTests(gSeekTests, startTest);
+
+</script>
+</pre>
+</body>
+</html>
\ No newline at end of file
--- a/dom/media/wave/WaveReader.cpp
+++ b/dom/media/wave/WaveReader.cpp
@@ -267,36 +267,36 @@ bool WaveReader::DecodeVideoFrame(bool &
                                       int64_t aTimeThreshold)
 {
   MOZ_ASSERT(OnTaskQueue());
 
   return false;
 }
 
 RefPtr<MediaDecoderReader::SeekPromise>
-WaveReader::Seek(int64_t aTarget, int64_t aEndTime)
+WaveReader::Seek(SeekTarget aTarget, int64_t aEndTime)
 {
   MOZ_ASSERT(OnTaskQueue());
-  LOG(LogLevel::Debug, ("%p About to seek to %lld", mDecoder, aTarget));
+  LOG(LogLevel::Debug, ("%p About to seek to %lld", mDecoder, aTarget.GetTime().ToMicroseconds()));
 
   if (NS_FAILED(ResetDecode())) {
     return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
   }
   double d = BytesToTime(GetDataLength());
   NS_ASSERTION(d < INT64_MAX / USECS_PER_S, "Duration overflow");
-  int64_t duration = static_cast<int64_t>(d * USECS_PER_S);
-  double seekTime = std::min(aTarget, duration) / static_cast<double>(USECS_PER_S);
+  media::TimeUnit duration = media::TimeUnit::FromSeconds(d);
+  double seekTime = std::min(aTarget.GetTime(), duration).ToSeconds();
   int64_t position = RoundDownToFrame(static_cast<int64_t>(TimeToBytes(seekTime)));
   NS_ASSERTION(INT64_MAX - mWavePCMOffset > position, "Integer overflow during wave seek");
   position += mWavePCMOffset;
   nsresult res = mResource.Seek(nsISeekableStream::NS_SEEK_SET, position);
   if (NS_FAILED(res)) {
     return SeekPromise::CreateAndReject(res, __func__);
   } else {
-    return SeekPromise::CreateAndResolve(aTarget, __func__);
+    return SeekPromise::CreateAndResolve(aTarget.GetTime(), __func__);
   }
 }
 
 media::TimeIntervals WaveReader::GetBuffered()
 {
   MOZ_ASSERT(OnTaskQueue());
   if (!mInfo.HasAudio()) {
     return media::TimeIntervals();
--- a/dom/media/wave/WaveReader.h
+++ b/dom/media/wave/WaveReader.h
@@ -22,17 +22,17 @@ protected:
   ~WaveReader();
 
 public:
   bool DecodeAudioData() override;
   bool DecodeVideoFrame(bool &aKeyframeSkip,
                         int64_t aTimeThreshold) override;
 
   nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags) override;
-  RefPtr<SeekPromise> Seek(int64_t aTime, int64_t aEndTime) override;
+  RefPtr<SeekPromise> Seek(SeekTarget aTarget, int64_t aEndTime) override;
 
   media::TimeIntervals GetBuffered() override;
 
 private:
   bool ReadAll(char* aBuf, int64_t aSize, int64_t* aBytesRead = nullptr);
   bool LoadRIFFChunk();
   bool LoadFormatChunk(uint32_t aChunkSize);
   bool FindDataOffset(uint32_t aChunkSize);
--- a/dom/media/webaudio/AudioBuffer.h
+++ b/dom/media/webaudio/AudioBuffer.h
@@ -114,17 +114,17 @@ protected:
 
   already_AddRefed<ThreadSharedFloatArrayBufferList>
   StealJSArrayDataIntoSharedChannels(JSContext* aJSContext);
 
   void ClearJSChannels();
 
   nsWeakPtr mOwnerWindow;
   // Float32Arrays
-  nsAutoTArray<JS::Heap<JSObject*>, 2> mJSChannels;
+  AutoTArray<JS::Heap<JSObject*>, 2> mJSChannels;
 
   // mSharedChannels aggregates the data from mJSChannels. This is non-null
   // if and only if the mJSChannels' buffers are detached.
   RefPtr<ThreadSharedFloatArrayBufferList> mSharedChannels;
 
   uint32_t mLength;
   float mSampleRate;
 };
--- a/dom/media/webaudio/AudioNodeEngine.h
+++ b/dom/media/webaudio/AudioNodeEngine.h
@@ -123,17 +123,17 @@ public:
   }
 
   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
   {
     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   }
 
 private:
-  nsAutoTArray<Storage, 2> mContents;
+  AutoTArray<Storage, 2> mContents;
 };
 
 /**
  * aChunk must have been allocated by AllocateAudioBlock.
  */
 void WriteZeroesToAudioBlock(AudioBlock* aChunk, uint32_t aStart,
                              uint32_t aLength);
 
@@ -248,17 +248,17 @@ AudioBufferSumOfSquares(const float* aIn
 /**
  * All methods of this class and its subclasses are called on the
  * MediaStreamGraph thread.
  */
 class AudioNodeEngine
 {
 public:
   // This should be compatible with AudioNodeStream::OutputChunks.
-  typedef nsAutoTArray<AudioBlock, 1> OutputChunks;
+  typedef AutoTArray<AudioBlock, 1> OutputChunks;
 
   explicit AudioNodeEngine(dom::AudioNode* aNode)
     : mNode(aNode)
     , mInputCount(aNode ? aNode->NumberOfInputs() : 1)
     , mOutputCount(aNode ? aNode->NumberOfOutputs() : 0)
   {
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_COUNT_CTOR(AudioNodeEngine);
--- a/dom/media/webaudio/AudioNodeExternalInputStream.cpp
+++ b/dom/media/webaudio/AudioNodeExternalInputStream.cpp
@@ -44,17 +44,17 @@ AudioNodeExternalInputStream::Create(Med
  * count that's a superset of the channels in aInput.
  */
 template <typename T>
 static void
 CopyChunkToBlock(AudioChunk& aInput, AudioBlock *aBlock,
                  uint32_t aOffsetInBlock)
 {
   uint32_t blockChannels = aBlock->ChannelCount();
-  nsAutoTArray<const T*,2> channels;
+  AutoTArray<const T*,2> channels;
   if (aInput.IsNull()) {
     channels.SetLength(blockChannels);
     PodZero(channels.Elements(), blockChannels);
   } else {
     const nsTArray<const T*>& inputChannels = aInput.ChannelData<T>();
     channels.SetLength(inputChannels.Length());
     PodCopy(channels.Elements(), inputChannels.Elements(), channels.Length());
     if (channels.Length() != blockChannels) {
@@ -132,17 +132,17 @@ AudioNodeExternalInputStream::ProcessInp
   if (!IsEnabled() || mInputs.IsEmpty() || mPassThrough) {
     mLastChunks[0].SetNull(WEBAUDIO_BLOCK_SIZE);
     return;
   }
 
   MOZ_ASSERT(mInputs.Length() == 1);
 
   MediaStream* source = mInputs[0]->GetSource();
-  nsAutoTArray<AudioSegment,1> audioSegments;
+  AutoTArray<AudioSegment,1> audioSegments;
   uint32_t inputChannels = 0;
   for (StreamBuffer::TrackIter tracks(source->mBuffer, MediaSegment::AUDIO);
        !tracks.IsEnded(); tracks.Next()) {
     const StreamBuffer::Track& inputTrack = *tracks;
     if (!mInputs[0]->PassTrackThrough(tracks->GetID())) {
       continue;
     }
 
@@ -187,17 +187,17 @@ AudioNodeExternalInputStream::ProcessInp
 
     for (AudioSegment::ChunkIterator iter(segment); !iter.IsEnded(); iter.Next()) {
       inputChannels = GetAudioChannelsSuperset(inputChannels, iter->ChannelCount());
     }
   }
 
   uint32_t accumulateIndex = 0;
   if (inputChannels) {
-    nsAutoTArray<float,GUESS_AUDIO_CHANNELS*WEBAUDIO_BLOCK_SIZE> downmixBuffer;
+    AutoTArray<float,GUESS_AUDIO_CHANNELS*WEBAUDIO_BLOCK_SIZE> downmixBuffer;
     for (uint32_t i = 0; i < audioSegments.Length(); ++i) {
       AudioBlock tmpChunk;
       ConvertSegmentToAudioBlock(&audioSegments[i], &tmpChunk, inputChannels);
       if (!tmpChunk.IsNull()) {
         if (accumulateIndex == 0) {
           mLastChunks[0].AllocateChannels(inputChannels);
         }
         AccumulateInputChunk(accumulateIndex, tmpChunk, &mLastChunks[0], &downmixBuffer);
--- a/dom/media/webaudio/AudioNodeStream.cpp
+++ b/dom/media/webaudio/AudioNodeStream.cpp
@@ -403,17 +403,17 @@ AudioNodeStream::AdvanceAndResume(Stream
 }
 
 void
 AudioNodeStream::ObtainInputBlock(AudioBlock& aTmpChunk,
                                   uint32_t aPortIndex)
 {
   uint32_t inputCount = mInputs.Length();
   uint32_t outputChannelCount = 1;
-  nsAutoTArray<const AudioBlock*,250> inputChunks;
+  AutoTArray<const AudioBlock*,250> inputChunks;
   for (uint32_t i = 0; i < inputCount; ++i) {
     if (aPortIndex != mInputs[i]->InputNumber()) {
       // This input is connected to a different port
       continue;
     }
     MediaStream* s = mInputs[i]->GetSource();
     AudioNodeStream* a = static_cast<AudioNodeStream*>(s);
     MOZ_ASSERT(a == s->AsAudioNodeStream());
@@ -449,30 +449,30 @@ AudioNodeStream::ObtainInputBlock(AudioB
 
   if (outputChannelCount == 0) {
     aTmpChunk.SetNull(WEBAUDIO_BLOCK_SIZE);
     return;
   }
 
   aTmpChunk.AllocateChannels(outputChannelCount);
   // The static storage here should be 1KB, so it's fine
-  nsAutoTArray<float, GUESS_AUDIO_CHANNELS*WEBAUDIO_BLOCK_SIZE> downmixBuffer;
+  AutoTArray<float, GUESS_AUDIO_CHANNELS*WEBAUDIO_BLOCK_SIZE> downmixBuffer;
 
   for (uint32_t i = 0; i < inputChunkCount; ++i) {
     AccumulateInputChunk(i, *inputChunks[i], &aTmpChunk, &downmixBuffer);
   }
 }
 
 void
 AudioNodeStream::AccumulateInputChunk(uint32_t aInputIndex,
                                       const AudioBlock& aChunk,
                                       AudioBlock* aBlock,
                                       nsTArray<float>* aDownmixBuffer)
 {
-  nsAutoTArray<const float*,GUESS_AUDIO_CHANNELS> channels;
+  AutoTArray<const float*,GUESS_AUDIO_CHANNELS> channels;
   UpMixDownMixChunk(&aChunk, aBlock->ChannelCount(), channels, *aDownmixBuffer);
 
   for (uint32_t c = 0; c < channels.Length(); ++c) {
     const float* inputData = static_cast<const float*>(channels[c]);
     float* outputData = aBlock->ChannelFloatsForWrite(c);
     if (inputData) {
       if (aInputIndex == 0) {
         AudioBlockCopyChannelWithScale(inputData, aChunk.mVolume, outputData);
@@ -504,17 +504,17 @@ AudioNodeStream::UpMixDownMixChunk(const
     } else {
       // Fill up the remaining aOutputChannels by zeros
       for (uint32_t j = aOutputChannels.Length(); j < aOutputChannelCount; ++j) {
         aOutputChannels.AppendElement(nullptr);
       }
     }
   } else if (aOutputChannels.Length() > aOutputChannelCount) {
     if (mChannelInterpretation == ChannelInterpretation::Speakers) {
-      nsAutoTArray<float*,GUESS_AUDIO_CHANNELS> outputChannels;
+      AutoTArray<float*,GUESS_AUDIO_CHANNELS> outputChannels;
       outputChannels.SetLength(aOutputChannelCount);
       aDownmixBuffer.SetLength(aOutputChannelCount * WEBAUDIO_BLOCK_SIZE);
       for (uint32_t j = 0; j < aOutputChannelCount; ++j) {
         outputChannels[j] = &aDownmixBuffer[j * WEBAUDIO_BLOCK_SIZE];
       }
 
       AudioChannelsDownMix(aOutputChannels, outputChannels.Elements(),
                            aOutputChannelCount, WEBAUDIO_BLOCK_SIZE);
--- a/dom/media/webaudio/AudioNodeStream.h
+++ b/dom/media/webaudio/AudioNodeStream.h
@@ -36,17 +36,17 @@ class AudioNodeStream : public Processed
   typedef dom::ChannelCountMode ChannelCountMode;
   typedef dom::ChannelInterpretation ChannelInterpretation;
 
 public:
   typedef mozilla::dom::AudioContext AudioContext;
 
   enum { AUDIO_TRACK = 1 };
 
-  typedef nsAutoTArray<AudioBlock, 1> OutputChunks;
+  typedef AutoTArray<AudioBlock, 1> OutputChunks;
 
   // Flags re main thread updates and stream output.
   typedef unsigned Flags;
   enum : Flags {
     NO_STREAM_FLAGS = 0U,
     NEED_MAIN_THREAD_FINISHED = 1U << 0,
     NEED_MAIN_THREAD_CURRENT_TIME = 1U << 1,
     // Internal AudioNodeStreams can only pass their output to another
--- a/dom/media/webaudio/DelayBuffer.h
+++ b/dom/media/webaudio/DelayBuffer.h
@@ -89,17 +89,17 @@ private:
   int OffsetForPosition(int aPosition);
   int ChunkForDelay(int aDelay);
   void UpdateUpmixChannels(int aNewReadChunk, uint32_t channelCount,
                            ChannelInterpretation aChannelInterpretation);
 
   // Circular buffer for capturing delayed samples.
   FallibleTArray<AudioChunk> mChunks;
   // Cache upmixed channel arrays.
-  nsAutoTArray<const float*,GUESS_AUDIO_CHANNELS> mUpmixChannels;
+  AutoTArray<const float*,GUESS_AUDIO_CHANNELS> mUpmixChannels;
   double mSmoothingRate;
   // Current delay, in fractional ticks
   double mCurrentDelay;
   // Maximum delay, in ticks
   int mMaxDelayTicks;
   // The current position in the circular buffer.  The next write will be to
   // this chunk, and the next read may begin before this chunk.
   int mCurrentChunk;
--- a/dom/media/webaudio/WebAudioUtils.cpp
+++ b/dom/media/webaudio/WebAudioUtils.cpp
@@ -31,18 +31,18 @@ WebAudioUtils::Shutdown()
 
 int
 WebAudioUtils::SpeexResamplerProcess(SpeexResamplerState* aResampler,
                                      uint32_t aChannel,
                                      const float* aIn, uint32_t* aInLen,
                                      float* aOut, uint32_t* aOutLen)
 {
 #ifdef MOZ_SAMPLE_TYPE_S16
-  nsAutoTArray<AudioDataValue, WEBAUDIO_BLOCK_SIZE*4> tmp1;
-  nsAutoTArray<AudioDataValue, WEBAUDIO_BLOCK_SIZE*4> tmp2;
+  AutoTArray<AudioDataValue, WEBAUDIO_BLOCK_SIZE*4> tmp1;
+  AutoTArray<AudioDataValue, WEBAUDIO_BLOCK_SIZE*4> tmp2;
   tmp1.SetLength(*aInLen);
   tmp2.SetLength(*aOutLen);
   ConvertAudioSamples(aIn, tmp1.Elements(), *aInLen);
   int result = speex_resampler_process_int(aResampler, aChannel, tmp1.Elements(), aInLen, tmp2.Elements(), aOutLen);
   ConvertAudioSamples(tmp2.Elements(), aOut, *aOutLen);
   return result;
 #else
   return speex_resampler_process_float(aResampler, aChannel, aIn, aInLen, aOut, aOutLen);
@@ -50,17 +50,17 @@ WebAudioUtils::SpeexResamplerProcess(Spe
 }
 
 int
 WebAudioUtils::SpeexResamplerProcess(SpeexResamplerState* aResampler,
                                      uint32_t aChannel,
                                      const int16_t* aIn, uint32_t* aInLen,
                                      float* aOut, uint32_t* aOutLen)
 {
-  nsAutoTArray<AudioDataValue, WEBAUDIO_BLOCK_SIZE*4> tmp;
+  AutoTArray<AudioDataValue, WEBAUDIO_BLOCK_SIZE*4> tmp;
 #ifdef MOZ_SAMPLE_TYPE_S16
   tmp.SetLength(*aOutLen);
   int result = speex_resampler_process_int(aResampler, aChannel, aIn, aInLen, tmp.Elements(), aOutLen);
   ConvertAudioSamples(tmp.Elements(), aOut, *aOutLen);
   return result;
 #else
   tmp.SetLength(*aInLen);
   ConvertAudioSamples(aIn, tmp.Elements(), *aInLen);
@@ -73,18 +73,18 @@ int
 WebAudioUtils::SpeexResamplerProcess(SpeexResamplerState* aResampler,
                                      uint32_t aChannel,
                                      const int16_t* aIn, uint32_t* aInLen,
                                      int16_t* aOut, uint32_t* aOutLen)
 {
 #ifdef MOZ_SAMPLE_TYPE_S16
   return speex_resampler_process_int(aResampler, aChannel, aIn, aInLen, aOut, aOutLen);
 #else
-  nsAutoTArray<AudioDataValue, WEBAUDIO_BLOCK_SIZE*4> tmp1;
-  nsAutoTArray<AudioDataValue, WEBAUDIO_BLOCK_SIZE*4> tmp2;
+  AutoTArray<AudioDataValue, WEBAUDIO_BLOCK_SIZE*4> tmp1;
+  AutoTArray<AudioDataValue, WEBAUDIO_BLOCK_SIZE*4> tmp2;
   tmp1.SetLength(*aInLen);
   tmp2.SetLength(*aOutLen);
   ConvertAudioSamples(aIn, tmp1.Elements(), *aInLen);
   int result = speex_resampler_process_float(aResampler, aChannel, tmp1.Elements(), aInLen, tmp2.Elements(), aOutLen);
   ConvertAudioSamples(tmp2.Elements(), aOut, *aOutLen);
   return result;
 #endif
 }
--- a/dom/media/webaudio/blink/HRTFElevation.cpp
+++ b/dom/media/webaudio/blink/HRTFElevation.cpp
@@ -123,17 +123,17 @@ nsReturnRef<HRTFKernel> HRTFElevation::c
     float response[ResponseFrameSize];
     ConvertAudioSamples(impulse_response_data, response, ResponseFrameSize);
     float* resampledResponse;
 #endif
 
     // Note that depending on the fftSize returned by the panner, we may be truncating the impulse response.
     const size_t resampledResponseLength = fftSizeForSampleRate(sampleRate) / 2;
 
-    nsAutoTArray<AudioDataValue, 2 * ResponseFrameSize> resampled;
+    AutoTArray<AudioDataValue, 2 * ResponseFrameSize> resampled;
     if (sampleRate == rawSampleRate) {
         resampledResponse = response;
         MOZ_ASSERT(resampledResponseLength == ResponseFrameSize);
     } else {
         resampled.SetLength(resampledResponseLength);
         resampledResponse = resampled.Elements();
         speex_resampler_skip_zeros(resampler);
 
@@ -158,17 +158,17 @@ nsReturnRef<HRTFKernel> HRTFElevation::c
             PodZero(resampled.Elements() + out_index,
                     resampled.Length() - out_index);
         }
 
         speex_resampler_reset_mem(resampler);
     }
 
 #ifdef MOZ_SAMPLE_TYPE_S16
-    nsAutoTArray<float, 2 * ResponseFrameSize> floatArray;
+    AutoTArray<float, 2 * ResponseFrameSize> floatArray;
     floatArray.SetLength(resampledResponseLength);
     float *floatResponse = floatArray.Elements();
     ConvertAudioSamples(resampledResponse,
                         floatResponse, resampledResponseLength);
 #else
     float *floatResponse = resampledResponse;
 #endif
 #undef RESAMPLER_PROCESS
--- a/dom/media/webaudio/blink/Reverb.cpp
+++ b/dom/media/webaudio/blink/Reverb.cpp
@@ -76,21 +76,21 @@ static float calculateNormalizationScale
 
     return scale;
 }
 
 Reverb::Reverb(ThreadSharedFloatArrayBufferList* impulseResponse, size_t impulseResponseBufferLength, size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads, bool normalize, float sampleRate)
 {
     float scale = 1;
 
-    nsAutoTArray<const float*,4> irChannels;
+    AutoTArray<const float*,4> irChannels;
     for (size_t i = 0; i < impulseResponse->GetChannels(); ++i) {
         irChannels.AppendElement(impulseResponse->GetData(i));
     }
-    nsAutoTArray<float,1024> tempBuf;
+    AutoTArray<float,1024> tempBuf;
 
     if (normalize) {
         scale = calculateNormalizationScale(impulseResponse, impulseResponseBufferLength, sampleRate);
 
         if (scale) {
             tempBuf.SetLength(irChannels.Length()*impulseResponseBufferLength);
             for (uint32_t i = 0; i < irChannels.Length(); ++i) {
                 float* buf = &tempBuf[i*impulseResponseBufferLength];
--- a/dom/media/webm/WebMBufferedParser.h
+++ b/dom/media/webm/WebMBufferedParser.h
@@ -55,20 +55,29 @@ struct WebMTimeDataOffset
 struct WebMBufferedParser
 {
   explicit WebMBufferedParser(int64_t aOffset)
     : mStartOffset(aOffset)
     , mCurrentOffset(aOffset)
     , mInitEndOffset(-1)
     , mBlockEndOffset(-1)
     , mState(READ_ELEMENT_ID)
+    , mNextState(READ_ELEMENT_ID)
     , mVIntRaw(false)
     , mLastInitStartOffset(-1)
     , mClusterSyncPos(0)
+    , mVIntLeft(0)
+    , mBlockSize(0)
+    , mClusterTimecode(0)
+    , mClusterOffset(0)
     , mClusterEndOffset(-1)
+    , mBlockOffset(0)
+    , mBlockTimecode(0)
+    , mBlockTimecodeLength(0)
+    , mSkipBytes(0)
     , mTimecodeScale(1000000)
     , mGotTimecodeScale(false)
   {
     if (mStartOffset != 0) {
       mState = FIND_CLUSTER_SYNC;
     }
   }
 
--- a/dom/media/webm/WebMDemuxer.cpp
+++ b/dom/media/webm/WebMDemuxer.cpp
@@ -384,18 +384,18 @@ WebMDemuxer::ReadMetadata()
       mInfo.mAudio.mChannels = params.channels;
 
       unsigned int nheaders = 0;
       r = nestegg_track_codec_data_count(mContext, track, &nheaders);
       if (r == -1) {
         return NS_ERROR_FAILURE;
       }
 
-      nsAutoTArray<const unsigned char*,4> headers;
-      nsAutoTArray<size_t,4> headerLens;
+      AutoTArray<const unsigned char*,4> headers;
+      AutoTArray<size_t,4> headerLens;
       for (uint32_t header = 0; header < nheaders; ++header) {
         unsigned char* data = 0;
         size_t length = 0;
         r = nestegg_track_codec_data(mContext, track, header, &data, &length);
         if (r == -1) {
           return NS_ERROR_FAILURE;
         }
         headers.AppendElement(data);
--- a/dom/media/webrtc/MediaEngineDefault.cpp
+++ b/dom/media/webrtc/MediaEngineDefault.cpp
@@ -505,17 +505,17 @@ MediaEngineDefaultAudioSource::Restart(c
 void
 MediaEngineDefaultAudioSource::AppendToSegment(AudioSegment& aSegment,
                                                TrackTicks aSamples)
 {
   RefPtr<SharedBuffer> buffer = SharedBuffer::Create(aSamples * sizeof(int16_t));
   int16_t* dest = static_cast<int16_t*>(buffer->Data());
 
   mSineGenerator->generate(dest, aSamples);
-  nsAutoTArray<const int16_t*,1> channels;
+  AutoTArray<const int16_t*,1> channels;
   channels.AppendElement(dest);
   aSegment.AppendFrames(buffer.forget(), channels, aSamples);
 }
 
 NS_IMETHODIMP
 MediaEngineDefaultAudioSource::Notify(nsITimer* aTimer)
 {
   TimeStamp now = TimeStamp::Now();
--- a/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
@@ -634,17 +634,17 @@ MediaEngineWebRTCMicrophoneSource::Proce
   uint32_t len = mSources.Length();
   for (uint32_t i = 0; i < len; i++) {
     RefPtr<SharedBuffer> buffer = SharedBuffer::Create(length * sizeof(sample));
 
     sample* dest = static_cast<sample*>(buffer->Data());
     memcpy(dest, audio10ms, length * sizeof(sample));
 
     nsAutoPtr<AudioSegment> segment(new AudioSegment());
-    nsAutoTArray<const sample*,1> channels;
+    AutoTArray<const sample*,1> channels;
     channels.AppendElement(dest);
     segment->AppendFrames(buffer.forget(), channels, length);
     TimeStamp insertTime;
     segment->GetStartTime(insertTime);
 
     if (mSources[i]) {
       // Make sure we include the stream and the track.
       // The 0:1 is a flag to note when we've done the final insert for a given input block.
--- a/dom/media/webspeech/recognition/SpeechRecognition.cpp
+++ b/dom/media/webspeech/recognition/SpeechRecognition.cpp
@@ -927,17 +927,17 @@ SpeechRecognition::SplitSamplesBuffer(co
 AudioSegment*
 SpeechRecognition::CreateAudioSegment(nsTArray<RefPtr<SharedBuffer>>& aChunks)
 {
   AudioSegment* segment = new AudioSegment();
   for (uint32_t i = 0; i < aChunks.Length(); ++i) {
     RefPtr<SharedBuffer> buffer = aChunks[i];
     const int16_t* chunkData = static_cast<const int16_t*>(buffer->Data());
 
-    nsAutoTArray<const int16_t*, 1> channels;
+    AutoTArray<const int16_t*, 1> channels;
     channels.AppendElement(chunkData);
     segment->AppendFrames(buffer.forget(), channels, mAudioSamplesPerChunk);
   }
 
   return segment;
 }
 
 void
@@ -954,17 +954,17 @@ SpeechRecognition::FeedAudioData(already
   // chunks, we must buffer and split them in chunks of mAudioSamplesPerChunk
   // (a multiple of Endpointer's frame size) before feeding to Endpointer.
 
   // ensure aSamples is deleted
   RefPtr<SharedBuffer> refSamples = aSamples;
 
   uint32_t samplesIndex = 0;
   const int16_t* samples = static_cast<int16_t*>(refSamples->Data());
-  nsAutoTArray<RefPtr<SharedBuffer>, 5> chunksToSend;
+  AutoTArray<RefPtr<SharedBuffer>, 5> chunksToSend;
 
   // fill up our buffer and make a chunk out of it, if possible
   if (mBufferedSamples > 0) {
     samplesIndex += FillSamplesBuffer(samples, aDuration);
 
     if (mBufferedSamples == mAudioSamplesPerChunk) {
       chunksToSend.AppendElement(mAudioSamplesBuffer.forget());
       mBufferedSamples = 0;
--- a/dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerService.mm
+++ b/dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerService.mm
@@ -270,17 +270,17 @@ private:
   RefPtr<OSXSpeechSynthesizerService> mSpeechService;
 };
 
 NS_IMETHODIMP
 EnumVoicesRunnable::Run()
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
-  nsAutoTArray<OSXVoice, 64> list;
+  AutoTArray<OSXVoice, 64> list;
 
   NSArray* voices = [NSSpeechSynthesizer availableVoices];
   NSString* defaultVoice = [NSSpeechSynthesizer defaultVoice];
 
   for (NSString* voice in voices) {
     OSXVoice item;
 
     NSDictionary* attr = [NSSpeechSynthesizer attributesForVoice:voice];
--- a/dom/media/webspeech/synth/nsSpeechTask.cpp
+++ b/dom/media/webspeech/synth/nsSpeechTask.cpp
@@ -318,17 +318,17 @@ void
 nsSpeechTask::SendAudioImpl(RefPtr<mozilla::SharedBuffer>& aSamples, uint32_t aDataLen)
 {
   if (aDataLen == 0) {
     mStream->EndAllTrackAndFinish();
     return;
   }
 
   AudioSegment segment;
-  nsAutoTArray<const int16_t*, 1> channelData;
+  AutoTArray<const int16_t*, 1> channelData;
   channelData.AppendElement(static_cast<int16_t*>(aSamples->Data()));
   segment.AppendFrames(aSamples.forget(), channelData, aDataLen);
   mStream->AppendToTrack(1, &segment);
   mStream->AdvanceKnownTracksTime(STREAM_TIME_MAX);
 }
 
 NS_IMETHODIMP
 nsSpeechTask::DispatchStart()
--- a/dom/media/webspeech/synth/nsSynthVoiceRegistry.cpp
+++ b/dom/media/webspeech/synth/nsSynthVoiceRegistry.cpp
@@ -31,25 +31,25 @@ extern mozilla::LogModule* GetSpeechSynt
 namespace {
 
 void
 GetAllSpeechSynthActors(InfallibleTArray<mozilla::dom::SpeechSynthesisParent*>& aActors)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aActors.IsEmpty());
 
-  nsAutoTArray<mozilla::dom::ContentParent*, 20> contentActors;
+  AutoTArray<mozilla::dom::ContentParent*, 20> contentActors;
   mozilla::dom::ContentParent::GetAll(contentActors);
 
   for (uint32_t contentIndex = 0;
        contentIndex < contentActors.Length();
        ++contentIndex) {
     MOZ_ASSERT(contentActors[contentIndex]);
 
-    AutoInfallibleTArray<mozilla::dom::PSpeechSynthesisParent*, 5> speechsynthActors;
+    AutoTArray<mozilla::dom::PSpeechSynthesisParent*, 5> speechsynthActors;
     contentActors[contentIndex]->ManagedPSpeechSynthesisParent(speechsynthActors);
 
     for (uint32_t speechsynthIndex = 0;
          speechsynthIndex < speechsynthActors.Length();
          ++speechsynthIndex) {
       MOZ_ASSERT(speechsynthActors[speechsynthIndex]);
 
       mozilla::dom::SpeechSynthesisParent* actor =
--- a/dom/messagechannel/MessagePort.cpp
+++ b/dom/messagechannel/MessagePort.cpp
@@ -470,20 +470,20 @@ MessagePort::PostMessage(JSContext* aCx,
   if (mState == eStateEntangling) {
     mMessagesForTheOtherPort.AppendElement(data);
     return;
   }
 
   MOZ_ASSERT(mActor);
   MOZ_ASSERT(mMessagesForTheOtherPort.IsEmpty());
 
-  nsAutoTArray<RefPtr<SharedMessagePortMessage>, 1> array;
+  AutoTArray<RefPtr<SharedMessagePortMessage>, 1> array;
   array.AppendElement(data);
 
-  nsAutoTArray<MessagePortMessage, 1> messages;
+  AutoTArray<MessagePortMessage, 1> messages;
   SharedMessagePortMessage::FromSharedToMessagesChild(mActor, array, messages);
   mActor->SendPostMessages(messages);
 }
 
 void
 MessagePort::Start()
 {
   if (mMessageQueueEnabled) {
--- a/dom/mobilemessage/ipc/SmsChild.cpp
+++ b/dom/mobilemessage/ipc/SmsChild.cpp
@@ -344,20 +344,20 @@ MobileMessageCursorChild::HandleContinue
 }
 
 void
 MobileMessageCursorChild::DoNotifyResult(const nsTArray<MobileMessageData>& aDataArray)
 {
   const uint32_t length = aDataArray.Length();
   MOZ_ASSERT(length);
 
-  AutoFallibleTArray<nsISupports*, 1> autoArray;
+  AutoTArray<nsISupports*, 1> autoArray;
   NS_ENSURE_TRUE_VOID(autoArray.SetCapacity(length, fallible));
 
-  AutoFallibleTArray<nsCOMPtr<nsISupports>, 1> messages;
+  AutoTArray<nsCOMPtr<nsISupports>, 1> messages;
   NS_ENSURE_TRUE_VOID(messages.SetCapacity(length, fallible));
 
   for (uint32_t i = 0; i < length; i++) {
     nsCOMPtr<nsISupports> message = CreateMessageFromMessageData(aDataArray[i]);
     NS_ENSURE_TRUE_VOID(messages.AppendElement(message, fallible));
     NS_ENSURE_TRUE_VOID(autoArray.AppendElement(message.get(), fallible));
   }
 
@@ -365,20 +365,20 @@ MobileMessageCursorChild::DoNotifyResult
 }
 
 void
 MobileMessageCursorChild::DoNotifyResult(const nsTArray<ThreadData>& aDataArray)
 {
   const uint32_t length = aDataArray.Length();
   MOZ_ASSERT(length);
 
-  AutoFallibleTArray<nsISupports*, 1> autoArray;
+  AutoTArray<nsISupports*, 1> autoArray;
   NS_ENSURE_TRUE_VOID(autoArray.SetCapacity(length, fallible));
 
-  AutoFallibleTArray<nsCOMPtr<nsISupports>, 1> threads;
+  AutoTArray<nsCOMPtr<nsISupports>, 1> threads;
   NS_ENSURE_TRUE_VOID(threads.SetCapacity(length, fallible));
 
   for (uint32_t i = 0; i < length; i++) {
     nsCOMPtr<nsISupports> thread =
       new MobileMessageThreadInternal(aDataArray[i]);
     NS_ENSURE_TRUE_VOID(threads.AppendElement(thread, fallible));
     NS_ENSURE_TRUE_VOID(autoArray.AppendElement(thread.get(), fallible));
   }
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -153,17 +153,17 @@ public:
 
   NS_IMETHOD Done(JSContext* aCx) final
   {
     AutoJSAPI jsapi;
     DebugOnly<bool> ok = jsapi.Init(mWindow, aCx);
     MOZ_ASSERT(ok);
 
     ErrorResult result;
-    nsAutoTArray<RefPtr<Notification>, 5> notifications;
+    AutoTArray<RefPtr<Notification>, 5> notifications;
 
     for (uint32_t i = 0; i < mStrings.Length(); ++i) {
       RefPtr<Notification> n =
         Notification::ConstructFromFields(mWindow,
                                           mStrings[i].mID,
                                           mStrings[i].mTitle,
                                           mStrings[i].mDir,
                                           mStrings[i].mLang,
@@ -2089,17 +2089,17 @@ public:
   }
 
   void
   WorkerRunInternal(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
   {
     RefPtr<Promise> workerPromise = mPromiseProxy->WorkerPromise();
 
     ErrorResult result;
-    nsAutoTArray<RefPtr<Notification>, 5> notifications;
+    AutoTArray<RefPtr<Notification>, 5> notifications;
     for (uint32_t i = 0; i < mStrings.Length(); ++i) {
       RefPtr<Notification> n =
         Notification::ConstructFromFields(aWorkerPrivate->GlobalScope(),
                                           mStrings[i].mID,
                                           mStrings[i].mTitle,
                                           mStrings[i].mDir,
                                           mStrings[i].mLang,
                                           mStrings[i].mBody,
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -1688,17 +1688,17 @@ void
 
       if (s->UTF8Characters) {
 #if defined(MOZ_MEMORY_WINDOWS)
         if (malloc_usable_size((void *)s->UTF8Characters) != 0) {
           PR_Free((void *)s->UTF8Characters);
         } else {
           void *p = (void *)s->UTF8Characters;
           DWORD nheaps = 0;
-          nsAutoTArray<HANDLE, 50> heaps;
+          AutoTArray<HANDLE, 50> heaps;
           nheaps = GetProcessHeaps(0, heaps.Elements());
           heaps.AppendElements(nheaps);
           GetProcessHeaps(nheaps, heaps.Elements());
           for (DWORD i = 0; i < nheaps; i++) {
             if (InHeap(heaps[i], p)) {
               HeapFree(heaps[i], 0, p);
               break;
             }
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -2106,17 +2106,17 @@ nsresult nsPluginHost::ScanPluginsDirect
   ("nsPluginHost::ScanPluginsDirectory dir=%s\n", dirPath.get()));
 #endif
 
   nsCOMPtr<nsISimpleEnumerator> iter;
   rv = pluginsDir->GetDirectoryEntries(getter_AddRefs(iter));
   if (NS_FAILED(rv))
     return rv;
 
-  nsAutoTArray<nsCOMPtr<nsIFile>, 6> pluginFiles;
+  AutoTArray<nsCOMPtr<nsIFile>, 6> pluginFiles;
 
   bool hasMore;
   while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
     nsCOMPtr<nsISupports> supports;
     rv = iter->GetNext(getter_AddRefs(supports));
     if (NS_FAILED(rv))
       continue;
     nsCOMPtr<nsIFile> dirEntry(do_QueryInterface(supports, &rv));
@@ -3661,17 +3661,17 @@ nsPluginHost::ParsePostBufferToFixHeader
   *outPostData = 0;
   *outPostDataLen = 0;
 
   const char CR = '\r';
   const char LF = '\n';
   const char CRLFCRLF[] = {CR,LF,CR,LF,'\0'}; // C string"\r\n\r\n"
   const char ContentLenHeader[] = "Content-length";
 
-  nsAutoTArray<const char*, 8> singleLF;
+  AutoTArray<const char*, 8> singleLF;
   const char *pSCntlh = 0;// pointer to start of ContentLenHeader in inPostData
   const char *pSod = 0;   // pointer to start of data in inPostData
   const char *pEoh = 0;   // pointer to end of headers in inPostData
   const char *pEod = inPostData + inPostDataLen; // pointer to end of inPostData
   if (*inPostData == LF) {
     // If no custom headers are required, simply add a blank
     // line ('\n') to the beginning of the file or buffer.
     // so *inPostData == '\n' is valid
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -898,17 +898,17 @@ nsPluginInstanceOwner::GetCompositionStr
     case GCS_COMPCLAUSE: {
       RefPtr<TextRangeArray> ranges = composition->GetLastRanges();
       if (!ranges || ranges->IsEmpty()) {
         aDist->SetLength(sizeof(uint32_t));
         memset(aDist->Elements(), 0, sizeof(uint32_t));
         *aLength = aDist->Length();
         return true;
       }
-      nsAutoTArray<uint32_t, 16> clauses;
+      AutoTArray<uint32_t, 16> clauses;
       clauses.AppendElement(0);
       for (TextRange& range : *ranges) {
         if (!range.IsClause()) {
           continue;
         }
         clauses.AppendElement(range.mEndOffset);
       }
 
@@ -936,31 +936,32 @@ nsPluginInstanceOwner::GetCompositionStr
                         aType).get());
       break;
   }
 
   return false;
 }
 
 bool
-nsPluginInstanceOwner::SetCandidateWindow(int32_t aX, int32_t aY)
+nsPluginInstanceOwner::SetCandidateWindow(
+    const widget::CandidateWindowPosition& aPosition)
 {
   if (NS_WARN_IF(!mPluginFrame)) {
     return false;
   }
 
   nsCOMPtr<nsIWidget> widget = GetContainingWidgetIfOffset();
   if (!widget) {
     widget = GetRootWidgetForPluginFrame(mPluginFrame);
     if (NS_WARN_IF(!widget)) {
       return false;
     }
   }
 
-  widget->SetCandidateWindowForPlugin(aX, aY);
+  widget->SetCandidateWindowForPlugin(aPosition);
   return true;
 }
 
 bool
 nsPluginInstanceOwner::RequestCommitOrCancel(bool aCommitted)
 {
   nsCOMPtr<nsIWidget> widget = GetContainingWidgetIfOffset();
   if (!widget) {
--- a/dom/plugins/base/nsPluginInstanceOwner.h
+++ b/dom/plugins/base/nsPluginInstanceOwner.h
@@ -264,17 +264,18 @@ public:
 #endif
 
   void NotifyHostAsyncInitFailed();
   void NotifyHostCreateWidget();
   void NotifyDestroyPending();
 
   bool GetCompositionString(uint32_t aIndex, nsTArray<uint8_t>* aString,
                             int32_t* aLength);
-  bool SetCandidateWindow(int32_t aX, int32_t aY);
+  bool SetCandidateWindow(
+           const mozilla::widget::CandidateWindowPosition& aPosition);
   bool RequestCommitOrCancel(bool aCommitted);
 
 private:
   virtual ~nsPluginInstanceOwner();
 
   // return FALSE if LayerSurface dirty (newly created and don't have valid plugin content yet)
   bool IsUpToDate()
   {
--- a/dom/plugins/base/nsPluginsDirUtils.h
+++ b/dom/plugins/base/nsPluginsDirUtils.h
@@ -21,17 +21,17 @@ static nsresult
 ParsePluginMimeDescription(const char *mdesc, nsPluginInfo &info)
 {
     nsresult rv = NS_ERROR_FAILURE;
     if (!mdesc || !*mdesc)
        return rv;
 
     char *mdescDup = PL_strdup(mdesc); // make a dup of intput string we'll change it content
     char anEmptyString[] = "";
-    nsAutoTArray<char*, 8> tmpMimeTypeArr;
+    AutoTArray<char*, 8> tmpMimeTypeArr;
     char delimiters[] = {':',':',';'};
     int mimeTypeVariantCount = 0;
     char *p = mdescDup; // make a dup of intput string we'll change it content
     while(p) {
         char *ptrMimeArray[] = {anEmptyString, anEmptyString, anEmptyString};
 
         // It's easy to point out ptrMimeArray[0] to the string sounds like
         // "Mime type is not specified, plugin will not function properly."
--- a/dom/plugins/ipc/PPluginInstance.ipdl
+++ b/dom/plugins/ipc/PPluginInstance.ipdl
@@ -26,16 +26,17 @@ using mozilla::gfx::IntSize from "mozill
 using mozilla::gfx::IntRect from "mozilla/gfx/2D.h";
 using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
 using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
 using mozilla::plugins::WindowsSharedMemoryHandle from "mozilla/plugins/PluginMessageUtils.h";
 using mozilla::layers::SurfaceDescriptorX11 from "gfxipc/ShadowLayerUtils.h";
 using nsIntRect from "nsRect.h";
 using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
 using struct DxgiAdapterDesc from "mozilla/D3DMessageUtils.h";
+using struct mozilla::widget::CandidateWindowPosition from "ipc/nsGUIEventIPC.h";
 
 namespace mozilla {
 namespace plugins {
 
 struct IOSurfaceDescriptor {
   uint32_t surfaceId;
   double contentsScaleFactor;
 };
@@ -259,19 +260,18 @@ parent:
   // Sends a native window to be adopted by the native window that would be
   // returned by NPN_GetValue_NPNVnetscapeWindow. Only used on Windows.
   async SetNetscapeWindowAsParent(NativeWindowHandle childWindow);
 
   sync GetCompositionString(uint32_t aType)
                             returns (uint8_t[] aDist, int32_t aLength);
   // Set candidate window position.
   //
-  // @param aX  x position of candidate window
-  // @param aY  y position of candidate window
-  async SetCandidateWindow(int32_t aX, int32_t aY);
+  // @param aPosition  position information of candidate window
+  async SetCandidateWindow(CandidateWindowPosition aPosition);
   async RequestCommitOrCancel(bool aCommitted);
 
 both:
   async PPluginScriptableObject();
 
 child:
   /* NPP_NewStream */
   async PBrowserStream(nsCString url,
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -2038,17 +2038,17 @@ PluginInstanceChild::ImmGetCompositionSt
                                                  LPVOID aBuf, DWORD aLen)
 {
     if (aIMC != sHookIMC) {
         return sImm32ImmGetCompositionStringStub(aIMC, aIndex, aBuf, aLen);
     }
     if (!sCurrentPluginInstance) {
         return IMM_ERROR_GENERAL;
     }
-    nsAutoTArray<uint8_t, 16> dist;
+    AutoTArray<uint8_t, 16> dist;
     int32_t length = 0; // IMM_ERROR_NODATA
     sCurrentPluginInstance->SendGetCompositionString(aIndex, &dist, &length);
     if (length == IMM_ERROR_NODATA || length == IMM_ERROR_GENERAL) {
       return length;
     }
 
     if (aBuf && aLen >= static_cast<DWORD>(length)) {
         memcpy(aBuf, dist.Elements(), length);
@@ -2060,24 +2060,32 @@ PluginInstanceChild::ImmGetCompositionSt
 BOOL
 PluginInstanceChild::ImmSetCandidateWindowProc(HIMC aIMC, LPCANDIDATEFORM aForm)
 {
     if (aIMC != sHookIMC) {
         return sImm32ImmSetCandidateWindowStub(aIMC, aForm);
     }
 
     if (!sCurrentPluginInstance ||
-        aForm->dwIndex != 0 ||
-        !(aForm->dwStyle & CFS_CANDIDATEPOS)) {
-        // Flash only uses CFS_CANDIDATEPOS with index == 0.
+        aForm->dwIndex != 0) {
         return FALSE;
     }
 
-    sCurrentPluginInstance->SendSetCandidateWindow(
-        aForm->ptCurrentPos.x, aForm->ptCurrentPos.y);
+    CandidateWindowPosition position;
+    position.mPoint.x = aForm->ptCurrentPos.x;
+    position.mPoint.y = aForm->ptCurrentPos.y;
+    position.mExcludeRect = !!(aForm->dwStyle & CFS_EXCLUDE);
+    if (position.mExcludeRect) {
+      position.mRect.x = aForm->rcArea.left;
+      position.mRect.y = aForm->rcArea.top;
+      position.mRect.width = aForm->rcArea.right - aForm->rcArea.left;
+      position.mRect.height = aForm->rcArea.bottom - aForm->rcArea.top;
+    }
+
+    sCurrentPluginInstance->SendSetCandidateWindow(position);
     return TRUE;
 }
 
 // static
 BOOL
 PluginInstanceChild::ImmNotifyIME(HIMC aIMC, DWORD aAction, DWORD aIndex,
                                   DWORD aValue)
 {
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -802,17 +802,17 @@ PluginInstanceParent::RecvShowDirectBitm
 
 void
 PluginInstanceParent::SetCurrentImage(Image* aImage)
 {
     MOZ_ASSERT(IsUsingDirectDrawing());
     ImageContainer::NonOwningImage holder(aImage);
     holder.mFrameID = ++mFrameID;
 
-    nsAutoTArray<ImageContainer::NonOwningImage,1> imageList;
+    AutoTArray<ImageContainer::NonOwningImage,1> imageList;
     imageList.AppendElement(holder);
     mImageContainer->SetCurrentImages(imageList);
 
     RecordDrawingModel();
 }
 
 bool
 PluginInstanceParent::RecvShowDirectDXGISurface(const WindowsHandle& handle,
@@ -954,17 +954,17 @@ PluginInstanceParent::RecvShow(const NPR
                    updatedRect.right - updatedRect.left,
                    updatedRect.bottom - updatedRect.top);
         surface->MarkDirty(ur);
 
         RefPtr<gfx::SourceSurface> sourceSurface =
             gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, surface);
         RefPtr<SourceSurfaceImage> image = new SourceSurfaceImage(surface->GetSize(), sourceSurface);
 
-        nsAutoTArray<ImageContainer::NonOwningImage,1> imageList;
+        AutoTArray<ImageContainer::NonOwningImage,1> imageList;
         imageList.AppendElement(
             ImageContainer::NonOwningImage(image));
 
         ImageContainer *container = GetImageContainer();
         container->SetCurrentImages(imageList);
     }
     else if (mImageContainer) {
         mImageContainer->ClearAllImages();
@@ -2391,23 +2391,23 @@ PluginInstanceParent::RecvGetComposition
     if (!owner->GetCompositionString(aIndex, aDist, aLength)) {
         *aLength = IMM_ERROR_NODATA;
     }
 #endif
     return true;
 }
 
 bool
-PluginInstanceParent::RecvSetCandidateWindow(const int32_t& aX,
-                                             const int32_t& aY)
+PluginInstanceParent::RecvSetCandidateWindow(
+    const mozilla::widget::CandidateWindowPosition& aPosition)
 {
 #if defined(OS_WIN)
     nsPluginInstanceOwner* owner = GetOwner();
     if (owner) {
-        owner->SetCandidateWindow(aX, aY);
+        owner->SetCandidateWindow(aPosition);
     }
 #endif
     return true;
 }
 
 bool
 PluginInstanceParent::RecvRequestCommitOrCancel(const bool& aCommitted)
 {
--- a/dom/plugins/ipc/PluginInstanceParent.h
+++ b/dom/plugins/ipc/PluginInstanceParent.h
@@ -354,17 +354,18 @@ public:
                                       PluginAsyncSurrogate** aSurrogate = nullptr);
 
     // for IME hook
     virtual bool
     RecvGetCompositionString(const uint32_t& aIndex,
                              nsTArray<uint8_t>* aBuffer,
                              int32_t* aLength) override;
     virtual bool
-    RecvSetCandidateWindow(const int32_t& aX, const int32_t& aY) override;
+    RecvSetCandidateWindow(
+        const mozilla::widget::CandidateWindowPosition& aPosition) override;
     virtual bool
     RecvRequestCommitOrCancel(const bool& aCommitted) override;
 
 private:
     // Create an appropriate platform surface for a background of size
     // |aSize|.  Return true if successful.
     bool CreateBackground(const nsIntSize& aSize);
     void DestroyBackground();
--- a/dom/plugins/ipc/PluginModuleChild.h
+++ b/dom/plugins/ipc/PluginModuleChild.h
@@ -358,17 +358,17 @@ private:
             : _spinning(false)
             , _savedNestableTasksAllowed(false)
         { }
 
         bool _spinning;
         bool _savedNestableTasksAllowed;
     };
 
-    nsAutoTArray<IncallFrame, 8> mIncallPumpingStack;
+    AutoTArray<IncallFrame, 8> mIncallPumpingStack;
 
     static LRESULT CALLBACK NestedInputEventHook(int code,
                                                  WPARAM wParam,
                                                  LPARAM lParam);
     static LRESULT CALLBACK CallWindowProcHook(int code,
                                                WPARAM wParam,
                                                LPARAM lParam);
     void SetEventHooks();
--- a/dom/plugins/ipc/PluginScriptableObjectChild.cpp
+++ b/dom/plugins/ipc/PluginScriptableObjectChild.cpp
@@ -431,17 +431,17 @@ PluginScriptableObjectChild::ScriptableE
     NS_WARNING("Calling method on an invalidated object!");
     return false;
   }
 
   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
   NS_ASSERTION(actor, "This shouldn't ever be null!");
   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
 
-  AutoInfallibleTArray<PluginIdentifier, 10> identifiers;
+  AutoTArray<PluginIdentifier, 10> identifiers;
   bool success;
   actor->CallEnumerate(&identifiers, &success);
 
   if (!success) {
     return false;
   }
 
   *aCount = identifiers.Length();
@@ -770,17 +770,17 @@ PluginScriptableObjectChild::AnswerInvok
   NS_ASSERTION(mType == LocalObject, "Bad type!");
 
   if (!(mObject->_class && mObject->_class->invoke)) {
     *aResult = void_t();
     *aSuccess = false;
     return true;
   }
 
-  AutoFallibleTArray<NPVariant, 10> convertedArgs;
+  AutoTArray<NPVariant, 10> convertedArgs;
   uint32_t argCount = aArgs.Length();
 
   if (!convertedArgs.SetLength(argCount, mozilla::fallible)) {
     *aResult = void_t();
     *aSuccess = false;
     return true;
   }
 
@@ -840,17 +840,17 @@ PluginScriptableObjectChild::AnswerInvok
   NS_ASSERTION(mType == LocalObject, "Bad type!");
 
   if (!(mObject->_class && mObject->_class->invokeDefault)) {
     *aResult = void_t();
     *aSuccess = false;
     return true;
   }
 
-  AutoFallibleTArray<NPVariant, 10> convertedArgs;
+  AutoTArray<NPVariant, 10> convertedArgs;
   uint32_t argCount = aArgs.Length();
 
   if (!convertedArgs.SetLength(argCount, mozilla::fallible)) {
     *aResult = void_t();
     *aSuccess = false;
     return true;
   }
 
@@ -1091,17 +1091,17 @@ PluginScriptableObjectChild::AnswerConst
   NS_ASSERTION(mType == LocalObject, "Bad type!");
 
   if (!(mObject->_class && mObject->_class->construct)) {
     *aResult = void_t();
     *aSuccess = false;
     return true;
   }
 
-  AutoFallibleTArray<NPVariant, 10> convertedArgs;
+  AutoTArray<NPVariant, 10> convertedArgs;
   uint32_t argCount = aArgs.Length();
 
   if (!convertedArgs.SetLength(argCount, mozilla::fallible)) {
     *aResult = void_t();
     *aSuccess = false;
     return true;
   }
 
--- a/dom/plugins/ipc/PluginScriptableObjectParent.cpp
+++ b/dom/plugins/ipc/PluginScriptableObjectParent.cpp
@@ -480,17 +480,17 @@ PluginScriptableObjectParent::Scriptable
   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
 
   const NPNetscapeFuncs* npn = GetNetscapeFuncs(aObject);
   if (!npn) {
     NS_ERROR("No netscape funcs!");
     return false;
   }
 
-  AutoInfallibleTArray<PluginIdentifier, 10> identifiers;
+  AutoTArray<PluginIdentifier, 10> identifiers;
   bool success;
   if (!actor->CallEnumerate(&identifiers, &success)) {
     NS_WARNING("Failed to send message!");
     return false;
   }
 
   if (!success) {
     return false;
@@ -825,17 +825,17 @@ PluginScriptableObjectParent::AnswerInvo
 
   StackIdentifier stackID(aId);
   if (stackID.Failed()) {
     *aResult = void_t();
     *aSuccess = false;
     return true;
   }
 
-  AutoFallibleTArray<NPVariant, 10> convertedArgs;
+  AutoTArray<NPVariant, 10> convertedArgs;
   uint32_t argCount = aArgs.Length();
 
   if (!convertedArgs.SetLength(argCount, fallible)) {
     *aResult = void_t();
     *aSuccess = false;
     return true;
   }
 
@@ -908,17 +908,17 @@ PluginScriptableObjectParent::AnswerInvo
   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
   if (!npn) {
     NS_ERROR("No netscape funcs?!");
     *aResult = void_t();
     *aSuccess = false;
     return true;
   }
 
-  AutoFallibleTArray<NPVariant, 10> convertedArgs;
+  AutoTArray<NPVariant, 10> convertedArgs;
   uint32_t argCount = aArgs.Length();
 
   if (!convertedArgs.SetLength(argCount, fallible)) {
     *aResult = void_t();
     *aSuccess = false;
     return true;
   }
 
@@ -1228,17 +1228,17 @@ PluginScriptableObjectParent::AnswerCons
   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
   if (!npn) {
     NS_ERROR("No netscape funcs?!");
     *aResult = void_t();
     *aSuccess = false;
     return true;
   }
 
-  AutoFallibleTArray<NPVariant, 10> convertedArgs;
+  AutoTArray<NPVariant, 10> convertedArgs;
   uint32_t argCount = aArgs.Length();
 
   if (!convertedArgs.SetLength(argCount, fallible)) {
     *aResult = void_t();
     *aSuccess = false;
     return true;
   }
 
--- a/dom/power/PowerManager.cpp
+++ b/dom/power/PowerManager.cpp
@@ -130,17 +130,17 @@ PowerManager::Callback(const nsAString &
   /**
    * We maintain a local listener list instead of using the global
    * list so that when the window is destroyed we don't have to
    * cleanup the mess.
    * Copy the listeners list before we walk through the callbacks
    * because the callbacks may install new listeners. We expect no
    * more than one listener per window, so it shouldn't be too long.
    */
-  nsAutoTArray<nsCOMPtr<nsIDOMMozWakeLockListener>, 2> listeners(mListeners);
+  AutoTArray<nsCOMPtr<nsIDOMMozWakeLockListener>, 2> listeners(mListeners);
   for (uint32_t i = 0; i < listeners.Length(); ++i) {
     listeners[i]->Callback(aTopic, aState);
   }
 
   return NS_OK;
 }
 
 bool
--- a/dom/power/PowerManagerService.cpp
+++ b/dom/power/PowerManagerService.cpp
@@ -107,17 +107,17 @@ PowerManagerService::Notify(const WakeLo
   nsAutoString state;
   ComputeWakeLockState(aWakeLockInfo, state);
 
   /**
    * Copy the listeners list before we walk through the callbacks
    * because the callbacks may install new listeners. We expect no
    * more than one listener per window, so it shouldn't be too long.
    */
-  nsAutoTArray<nsCOMPtr<nsIDOMMozWakeLockListener>, 2> listeners(mWakeLockListeners);
+  AutoTArray<nsCOMPtr<nsIDOMMozWakeLockListener>, 2> listeners(mWakeLockListeners);
 
   for (uint32_t i = 0; i < listeners.Length(); ++i) {
     listeners[i]->Callback(aWakeLockInfo.topic(), state);
   }
 }
 
 void
 PowerManagerService::SyncProfile()
--- a/dom/quota/ActorsParent.cpp
+++ b/dom/quota/ActorsParent.cpp
@@ -2471,17 +2471,17 @@ QuotaObject::MaybeUpdateSize(int64_t aSi
 
   AssertNoOverflow(quotaManager->mTemporaryStorageUsage, delta);
   uint64_t newTemporaryStorageUsage = quotaManager->mTemporaryStorageUsage +
                                       delta;
 
   if (newTemporaryStorageUsage > quotaManager->mTemporaryStorageLimit) {
     // This will block the thread without holding the lock while waitting.
 
-    nsAutoTArray<RefPtr<DirectoryLockImpl>, 10> locks;
+    AutoTArray<RefPtr<DirectoryLockImpl>, 10> locks;
 
     uint64_t sizeToBeFreed =
       quotaManager->LockedCollectOriginsForEviction(delta, locks);
 
     if (!sizeToBeFreed) {
       return false;
     }
 
@@ -3796,17 +3796,17 @@ QuotaManager::OpenDirectoryInternal(Null
   MOZ_ASSERT(lock);
 
   if (!aExclusive) {
     return;
   }
 
   // All the locks that block this new exclusive lock need to be invalidated.
   // We also need to notify clients to abort operations for them.
-  nsAutoTArray<nsAutoPtr<nsTHashtable<nsCStringHashKey>>,
+  AutoTArray<nsAutoPtr<nsTHashtable<nsCStringHashKey>>,
                Client::TYPE_MAX> origins;
   origins.SetLength(Client::TYPE_MAX);
 
   const nsTArray<DirectoryLockImpl*>& blockedOnLocks =
     lock->GetBlockedOnLocks();
 
   for (DirectoryLockImpl* blockedOnLock : blockedOnLocks) {
     blockedOnLock->Invalidate();
--- a/dom/quota/QuotaManager.h
+++ b/dom/quota/QuotaManager.h
@@ -495,17 +495,17 @@ private:
 
   // A timer that gets activated at shutdown to ensure we close all storages.
   nsCOMPtr<nsITimer> mShutdownTimer;
 
   // A list of all successfully initialized origins. This list isn't protected
   // by any mutex but it is only ever touched on the IO thread.
   nsTArray<nsCString> mInitializedOrigins;
 
-  nsAutoTArray<RefPtr<Client>, Client::TYPE_MAX> mClients;
+  AutoTArray<RefPtr<Client>, Client::TYPE_MAX> mClients;
 
   nsString mIndexedDBPath;
   nsString mStoragePath;
   nsString mPermanentStoragePath;
   nsString mTemporaryStoragePath;
   nsString mDefaultStoragePath;
 
   uint64_t mTemporaryStorageLimit;
--- a/dom/security/nsContentSecurityManager.cpp
+++ b/dom/security/nsContentSecurityManager.cpp
@@ -138,18 +138,27 @@ DoContentSecurityChecks(nsIURI* aURI, ns
     }
 
     case nsIContentPolicy::TYPE_SCRIPT: {
       mimeTypeGuess = NS_LITERAL_CSTRING("application/javascript");
       requestingContext = aLoadInfo->LoadingNode();
       break;
     }
 
-    case nsIContentPolicy::TYPE_IMAGE:
-    case nsIContentPolicy::TYPE_STYLESHEET:
+    case nsIContentPolicy::TYPE_IMAGE: {
+      MOZ_ASSERT(false, "contentPolicyType not supported yet");
+      break;
+    }
+
+    case nsIContentPolicy::TYPE_STYLESHEET: {
+      mimeTypeGuess = NS_LITERAL_CSTRING("text/css");
+      requestingContext = aLoadInfo->LoadingNode();
+      break;
+    }
+
     case nsIContentPolicy::TYPE_OBJECT:
     case nsIContentPolicy::TYPE_DOCUMENT: {
       MOZ_ASSERT(false, "contentPolicyType not supported yet");
       break;
     }
 
     case nsIContentPolicy::TYPE_SUBDOCUMENT: {
       mimeTypeGuess = NS_LITERAL_CSTRING("text/html");
--- a/dom/storage/DOMStorageDBUpdater.cpp
+++ b/dom/storage/DOMStorageDBUpdater.cpp
@@ -331,17 +331,27 @@ nsresult Update(mozIStorageConnection *a
       rv = aWorkerConnection->ExecuteSimpleSQL(
         NS_LITERAL_CSTRING("DROP TABLE moz_webappsstore"));
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     aWorkerConnection->RemoveFunction(NS_LITERAL_CSTRING("REVERSESTRING"));
 
     // Update the scoping to match the new implememntation: split to oa suffix and origin key
-    // First rename the old table, we want to remove some columns no longer needed.
+    // First rename the old table, we want to remove some columns no longer needed,
+    // but even before that drop all indexes from it (CREATE IF NOT EXISTS for index on the
+    // new table would falsely find the index!)
+    rv = aWorkerConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
+          "DROP INDEX IF EXISTS webappsstore2.origin_key_index"));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = aWorkerConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
+          "DROP INDEX IF EXISTS webappsstore2.scope_key_index"));
+    NS_ENSURE_SUCCESS(rv, rv);
+
     rv = aWorkerConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
           "ALTER TABLE webappsstore2 RENAME TO webappsstore2_old"));
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<mozIStorageFunction> oaSuffixFunc(
       new GetOriginParticular(GetOriginParticular::ORIGIN_ATTRIBUTES_SUFFIX));
     rv = aWorkerConnection->CreateFunction(NS_LITERAL_CSTRING("GET_ORIGIN_SUFFIX"), 1, oaSuffixFunc);
     NS_ENSURE_SUCCESS(rv, rv);
--- a/dom/svg/SVGLengthList.h
+++ b/dom/svg/SVGLengthList.h
@@ -125,30 +125,30 @@ private:
   bool AppendItem(SVGLength aLength) {
     return !!mLengths.AppendElement(aLength, fallible);
   }
 
 protected:
 
   /* Rationale for using nsTArray<SVGLength> and not nsTArray<SVGLength, 1>:
    *
-   * It might seem like we should use nsAutoTArray<SVGLength, 1> instead of
+   * It might seem like we should use AutoTArray<SVGLength, 1> instead of
    * nsTArray<SVGLength>. That would preallocate space for one SVGLength and
    * avoid an extra memory allocation call in the common case of the 'x'
    * and 'y' attributes each containing a single length (and the 'dx' and 'dy'
    * attributes being empty). However, consider this:
    *
-   * An empty nsTArray uses sizeof(Header*). An nsAutoTArray<class E,
+   * An empty nsTArray uses sizeof(Header*). An AutoTArray<class E,
    * uint32_t N> on the other hand uses sizeof(Header*) +
    * (2 * sizeof(uint32_t)) + (N * sizeof(E)), which for one SVGLength is
    * sizeof(Header*) + 16 bytes.
    *
    * Now consider that for text elements we have four length list attributes
    * (x, y, dx, dy), each of which can have a baseVal and an animVal list. If
-   * we were to go the nsAutoTArray<SVGLength, 1> route for each of these, we'd
+   * we were to go the AutoTArray<SVGLength, 1> route for each of these, we'd
    * end up using at least 160 bytes for these four attributes alone, even
    * though we only need storage for two SVGLengths (16 bytes) in the common
    * case!!
    *
    * A compromise might be to template SVGLengthList to allow
    * SVGAnimatedLengthList to preallocate space for an SVGLength for the
    * baseVal lists only, and that would cut the space used by the four
    * attributes to 96 bytes. Taking that even further and templating
--- a/dom/system/gonk/GonkGPSGeolocationProvider.cpp
+++ b/dom/system/gonk/GonkGPSGeolocationProvider.cpp
@@ -533,23 +533,23 @@ GonkGPSGeolocationProvider::RequestSetti
   if (!ss) {
     MOZ_ASSERT(ss);
     return;
   }
 
   nsCOMPtr<nsISettingsServiceLock> lock;
   nsresult rv = ss->CreateLock(nullptr, getter_AddRefs(lock));
   if (NS_FAILED(rv)) {
-    ERR("error while createLock setting '%s': %d\n", aKey, rv);
+    ERR("error while createLock setting '%s': %d\n", aKey, uint32_t(rv));
     return;
   }
 
   rv = lock->Get(aKey, this);
   if (NS_FAILED(rv)) {
-    ERR("error while get setting '%s': %d\n", aKey, rv);
+    ERR("error while get setting '%s': %d\n", aKey, uint32_t(rv));
     return;
   }
 }
 
 #ifdef MOZ_B2G_RIL
 void
 GonkGPSGeolocationProvider::RequestDataConnection()
 {
--- a/dom/voicemail/Voicemail.h
+++ b/dom/voicemail/Voicemail.h
@@ -82,17 +82,17 @@ private:
 
 private:
   nsCOMPtr<nsIVoicemailService> mService;
   RefPtr<Listener> mListener;
 
   // |mStatuses| keeps all instantiated VoicemailStatus objects as well as the
   // empty slots for not interested ones. The length of |mStatuses| is decided
   // in the constructor and is never changed ever since.
-  nsAutoTArray<RefPtr<VoicemailStatus>, 1> mStatuses;
+  AutoTArray<RefPtr<VoicemailStatus>, 1> mStatuses;
 
   // Return a nsIVoicemailProvider instance based on the requests from external
   // components. Return nullptr if aOptionalServiceId contains an invalid
   // service id or the default one is just not available.
   already_AddRefed<nsIVoicemailProvider>
   GetItemByServiceId(const Optional<uint32_t>& aOptionalServiceId,
                      uint32_t& aActualServiceId) const;
 
--- a/dom/wifi/test/marionette/manifest.ini
+++ b/dom/wifi/test/marionette/manifest.ini
@@ -5,23 +5,20 @@ qemu = true
 
 [test_wifi_enable.js]
 [test_wifi_scan.js]
 [test_wifi_associate.js]
 [test_wifi_associate_wo_connect.js]
 [test_wifi_auto_connect.js]
 [test_wifi_static_ip.js]
 [test_wifi_tethering_wifi_disabled.js]
-skip-if = android_version > '15' # Bug 1203075
 [test_wifi_tethering_wifi_inactive.js]
-skip-if = android_version > '15' # Bug 1203075
 [test_wifi_tethering_wifi_active.js]
-skip-if = android_version > '15' # Bug 1203075
 [test_wifi_manage_server_certificate.js]
 [test_wifi_manage_user_certificate.js]
 [test_wifi_manage_pkcs12_certificate.js]
 [test_wifi_associate_WPA_EAP_PEAP.js]
-disabled = Bug 1173697
+skip-if = android_version < '16' # EAP test not working before KK.
 [test_wifi_associate_WPA_EAP_TTLS.js]
-disabled = Bug 1173697
+skip-if = android_version < '16'
 [test_wifi_associate_WPA_EAP_TLS.js]
-disabled = Bug 1173697
+skip-if = android_version < '16'
 [test_wifi_enable_api.js]
--- a/dom/workers/Queue.h
+++ b/dom/workers/Queue.h
@@ -12,17 +12,17 @@
 #include "mozilla/Mutex.h"
 #include "nsTArray.h"
 
 BEGIN_WORKERS_NAMESPACE
 
 template <typename T, int TCount>
 struct StorageWithTArray
 {
-  typedef nsAutoTArray<T, TCount> StorageType;
+  typedef AutoTArray<T, TCount> StorageType;
 
   static void Reverse(StorageType& aStorage)
   {
     uint32_t length = aStorage.Length();
     for (uint32_t index = 0; index < length / 2; index++) {
       uint32_t reverseIndex = length - 1 - index;
 
       T t1 = aStorage.ElementAt(index);
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -121,17 +121,17 @@ static_assert(MAX_WORKERS_PER_DOMAIN >= 
 #define GC_REQUEST_OBSERVER_TOPIC "child-gc-request"
 #define CC_REQUEST_OBSERVER_TOPIC "child-cc-request"
 #define MEMORY_PRESSURE_OBSERVER_TOPIC "memory-pressure"
 
 #define BROADCAST_ALL_WORKERS(_func, ...)                                      \
   PR_BEGIN_MACRO                                                               \
     AssertIsOnMainThread();                                                    \
                                                                                \
-    nsAutoTArray<WorkerPrivate*, 100> workers;                                 \
+    AutoTArray<WorkerPrivate*, 100> workers;                                 \
     {                                                                          \
       MutexAutoLock lock(mMutex);                                              \
                                                                                \
       AddAllTopLevelWorkersToArray(workers);                                   \
     }                                                                          \
                                                                                \
     if (!workers.IsEmpty()) {                                                  \
       AutoSafeJSContext cx;                                                    \
@@ -1783,17 +1783,17 @@ RuntimeService::ShutdownIdleThreads(nsIT
 
   NS_ASSERTION(aTimer == runtime->mIdleThreadTimer, "Wrong timer!");
 
   // Cheat a little and grab all threads that expire within one second of now.
   TimeStamp now = TimeStamp::NowLoRes() + TimeDuration::FromSeconds(1);
 
   TimeStamp nextExpiration;
 
-  nsAutoTArray<RefPtr<WorkerThread>, 20> expiredThreads;
+  AutoTArray<RefPtr<WorkerThread>, 20> expiredThreads;
   {
     MutexAutoLock lock(runtime->mMutex);
 
     for (uint32_t index = 0; index < runtime->mIdleThreadArray.Length();
          index++) {
       IdleThreadInfo& info = runtime->mIdleThreadArray[index];
       if (info.mExpirationTime > now) {
         nextExpiration = info.mExpirationTime;
@@ -1987,17 +1987,17 @@ RuntimeService::Shutdown()
   if (obs && NS_FAILED(obs->NotifyObservers(nullptr, WORKERS_SHUTDOWN_TOPIC,
                                             nullptr))) {
     NS_WARNING("NotifyObservers failed!");
   }
 
   {
     MutexAutoLock lock(mMutex);
 
-    nsAutoTArray<WorkerPrivate*, 100> workers;
+    AutoTArray<WorkerPrivate*, 100> workers;
     AddAllTopLevelWorkersToArray(workers);
 
     if (!workers.IsEmpty()) {
       // Cancel all top-level workers.
       {
         MutexAutoUnlock unlock(mMutex);
 
         AutoSafeJSContext cx;
@@ -2028,26 +2028,26 @@ RuntimeService::Cleanup()
       NS_WARNING("Failed to cancel idle timer!");
     }
     mIdleThreadTimer = nullptr;
   }
 
   {
     MutexAutoLock lock(mMutex);
 
-    nsAutoTArray<WorkerPrivate*, 100> workers;
+    AutoTArray<WorkerPrivate*, 100> workers;
     AddAllTopLevelWorkersToArray(workers);
 
     if (!workers.IsEmpty()) {
       nsIThread* currentThread = NS_GetCurrentThread();
       NS_ASSERTION(currentThread, "This should never be null!");
 
       // Shut down any idle threads.
       if (!mIdleThreadArray.IsEmpty()) {
-        nsAutoTArray<RefPtr<WorkerThread>, 20> idleThreads;
+        AutoTArray<RefPtr<WorkerThread>, 20> idleThreads;
 
         uint32_t idleThreadCount = mIdleThreadArray.Length();
         idleThreads.SetLength(idleThreadCount);
 
         for (uint32_t index = 0; index < idleThreadCount; index++) {
           NS_ASSERTION(mIdleThreadArray[index].mThread, "Null thread!");
           idleThreads[index].swap(mIdleThreadArray[index].mThread);
         }
@@ -2192,17 +2192,17 @@ RuntimeService::GetWorkersForWindow(nsPI
   }
 }
 
 void
 RuntimeService::CancelWorkersForWindow(nsPIDOMWindowInner* aWindow)
 {
   AssertIsOnMainThread();
 
-  nsAutoTArray<WorkerPrivate*, MAX_WORKERS_PER_DOMAIN> workers;
+  AutoTArray<WorkerPrivate*, MAX_WORKERS_PER_DOMAIN> workers;
   GetWorkersForWindow(aWindow, workers);
 
   if (!workers.IsEmpty()) {
     AutoJSAPI jsapi;
     if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(aWindow))) {
       return;
     }
     JSContext* cx = jsapi.cx();
@@ -2220,17 +2220,17 @@ RuntimeService::CancelWorkersForWindow(n
 }
 
 void
 RuntimeService::FreezeWorkersForWindow(nsPIDOMWindowInner* aWindow)
 {
   AssertIsOnMainThread();
   MOZ_ASSERT(aWindow);
 
-  nsAutoTArray<WorkerPrivate*, MAX_WORKERS_PER_DOMAIN> workers;
+  AutoTArray<WorkerPrivate*, MAX_WORKERS_PER_DOMAIN> workers;
   GetWorkersForWindow(aWindow, workers);
 
   if (!workers.IsEmpty()) {
     AutoJSAPI jsapi;
     if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(aWindow))) {
       return;
     }
     JSContext* cx = jsapi.cx();
@@ -2244,17 +2244,17 @@ RuntimeService::FreezeWorkersForWindow(n
 }
 
 void
 RuntimeService::ThawWorkersForWindow(nsPIDOMWindowInner* aWindow)
 {
   AssertIsOnMainThread();
   MOZ_ASSERT(aWindow);