Merge mozilla-central to mozilla-inbound
authorEd Morley <emorley@mozilla.com>
Thu, 14 Feb 2013 11:09:15 +0000
changeset 121898 6b975147c01541a2232faf86c5d42d1933e47070
parent 121844 aceeea086ccb5493ad9269af922bcb05ef6b2b13 (current diff)
parent 121897 e941e0df729c327ceb2badf5ca1795e6aeec99a3 (diff)
child 121899 b1905f6653d40b28264e7549e7466b8d3941997a
push idunknown
push userunknown
push dateunknown
milestone21.0a1
Merge mozilla-central to mozilla-inbound
accessible/public/msaa/nsIWinAccessNode.idl
config/expandlibs_exec.py
config/nspr/build.mk
js/src/config/expandlibs_exec.py
--- a/accessible/public/msaa/Makefile.in
+++ b/accessible/public/msaa/Makefile.in
@@ -4,26 +4,21 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 LIBRARY_NAME	= AccessibleMarshal
 MODULE    = accessibility
-XPIDL_MODULE = accessibility-msaa
 GRE_MODULE   = 1
 DEFFILE = $(win_srcdir)/AccessibleMarshal.def
 
 include $(DEPTH)/config/autoconf.mk
 
-XPIDLSRCS = \
-      nsIWinAccessNode.idl \
-      $(NULL)
-
 DEFINES += -DREGISTER_PROXY_DLL
 
 GARBAGE += $(MIDL_GENERATED_FILES) done_gen dlldata.c
 
 FORCE_SHARED_LIB = 1
 
 SRCS_IN_OBJDIR	= 1
 
deleted file mode 100644
--- a/accessible/public/msaa/nsIWinAccessNode.idl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * 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 "nsISupports.idl"
-
-%{C++
-#include "guiddef.h"
-%}
-
-[ref] native MSCOMIIDRef(IID);
-
-[uuid(63efe9c5-2610-4d2f-861b-e4ddfe1b70d9)]
-interface nsIWinAccessNode : nsISupports
-{
-  voidPtr queryNativeInterface([const] in MSCOMIIDRef aIID);
-};
-
--- a/accessible/src/base/ARIAStateMap.cpp
+++ b/accessible/src/base/ARIAStateMap.cpp
@@ -267,16 +267,26 @@ aria::MapToState(EStateRule aRule, dom::
       static const TokenTypeData data(
         nsGkAtoms::aria_readonly, eBoolType | eDefinedIfAbsent,
         0, states::READONLY, states::EDITABLE);
 
       MapTokenType(aElement, aState, data);
       return true;
     }
 
+    case eARIAReadonlyOrEditableIfDefined:
+    {
+      static const TokenTypeData data(
+        nsGkAtoms::aria_readonly, eBoolType,
+        0, states::READONLY, states::EDITABLE);
+
+      MapTokenType(aElement, aState, data);
+      return true;
+    }
+
     case eARIARequired:
     {
       static const TokenTypeData data(
         nsGkAtoms::aria_required, eBoolType,
         0, states::REQUIRED);
 
       MapTokenType(aElement, aState, data);
       return true;
--- a/accessible/src/base/ARIAStateMap.h
+++ b/accessible/src/base/ARIAStateMap.h
@@ -34,16 +34,17 @@ enum EStateRule
   eARIAHasPopup,
   eARIAInvalid,
   eARIAMultiline,
   eARIAMultiSelectable,
   eARIAOrientation,
   eARIAPressed,
   eARIAReadonly,
   eARIAReadonlyOrEditable,
+  eARIAReadonlyOrEditableIfDefined,
   eARIARequired,
   eARIASelectable,
   eReadonlyUntilEditable,
   eIndeterminateIfNoValue
 };
 
 /**
  * Expose the accessible states for the given element accordingly to state
--- a/accessible/src/base/nsARIAMap.cpp
+++ b/accessible/src/base/nsARIAMap.cpp
@@ -173,29 +173,29 @@ static nsRoleMapEntry sWAIRoleMaps[] =
     roles::TABLE,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     eSelect | eTable,
     states::FOCUSABLE,
     eARIAMultiSelectable,
-    eARIAReadonly
+    eARIAReadonlyOrEditable
   },
   { // gridcell
     &nsGkAtoms::gridcell,
     roles::GRID_CELL,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     eTableCell,
     kNoReqStates,
     eARIASelectable,
-    eARIAReadonly
+    eARIAReadonlyOrEditableIfDefined
   },
   { // group
     &nsGkAtoms::group,
     roles::GROUPING,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
--- a/accessible/src/generic/Accessible.cpp
+++ b/accessible/src/generic/Accessible.cpp
@@ -17,16 +17,18 @@
 #include "nsIAccessibleRelation.h"
 #include "nsEventShell.h"
 #include "nsTextEquivUtils.h"
 #include "Relation.h"
 #include "Role.h"
 #include "RootAccessible.h"
 #include "States.h"
 #include "StyleInfo.h"
+#include "TableAccessible.h"
+#include "TableCellAccessible.h"
 #include "TreeWalker.h"
 
 #include "nsContentUtils.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMNodeFilter.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMTreeWalker.h"
@@ -1592,16 +1594,32 @@ Accessible::ApplyARIAState(uint64_t* aSt
   if (!mRoleMapEntry)
     return;
 
   *aState |= mRoleMapEntry->state;
 
   if (aria::MapToState(mRoleMapEntry->attributeMap1, element, aState) &&
       aria::MapToState(mRoleMapEntry->attributeMap2, element, aState))
     aria::MapToState(mRoleMapEntry->attributeMap3, element, aState);
+
+  // ARIA gridcell inherits editable/readonly states from the grid until it's
+  // overridden.
+  if (mRoleMapEntry->Is(nsGkAtoms::gridcell) &&
+      !(*aState & (states::READONLY | states::EDITABLE))) {
+    const TableCellAccessible* cell = AsTableCell();
+    if (cell) {
+      TableAccessible* table = cell->Table();
+      if (table) {
+        Accessible* grid = table->AsAccessible();
+        uint64_t gridState = 0;
+        grid->ApplyARIAState(&gridState);
+        *aState |= (gridState & (states::READONLY | states::EDITABLE));
+      }
+    }
+  }
 }
 
 NS_IMETHODIMP
 Accessible::GetValue(nsAString& aValue)
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -509,16 +509,18 @@ public:
   a11y::RootAccessible* AsRoot();
 
   bool IsSelect() const { return HasGenericType(eSelect); }
 
   bool IsTable() const { return HasGenericType(eTable); }
   virtual TableAccessible* AsTable() { return nullptr; }
 
   virtual TableCellAccessible* AsTableCell() { return nullptr; }
+  const TableCellAccessible* AsTableCell() const
+    { return const_cast<Accessible*>(this)->AsTableCell(); }
 
   bool IsTableRow() const { return HasGenericType(eTableRow); }
 
   bool IsTextLeaf() const { return mType == eTextLeafType; }
   TextLeafAccessible* AsTextLeaf();
 
   bool IsXULTabpanels() const { return mType == eXULTabpanelsType; }
 
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -40,28 +40,17 @@ nsAccessNodeWrap::
 nsAccessNodeWrap::~nsAccessNodeWrap()
 {
 }
 
 //-----------------------------------------------------
 // nsISupports methods
 //-----------------------------------------------------
 
-NS_IMPL_ISUPPORTS_INHERITED1(nsAccessNodeWrap, nsAccessNode, nsIWinAccessNode)
-
-//-----------------------------------------------------
-// nsIWinAccessNode methods
-//-----------------------------------------------------
-
-NS_IMETHODIMP
-nsAccessNodeWrap::QueryNativeInterface(REFIID aIID, void** aInstancePtr)
-{
-  // XXX Wrong for E_NOINTERFACE
-  return static_cast<nsresult>(QueryInterface(aIID, aInstancePtr));
-}
+NS_IMPL_ISUPPORTS_INHERITED0(nsAccessNodeWrap, nsAccessNode)
 
 STDMETHODIMP nsAccessNodeWrap::QueryInterface(REFIID iid, void** ppv)
 {
   *ppv = nullptr;
 
   if (IID_IUnknown == iid) {
     *ppv = static_cast<IUnknown*>(this);
   } else {
@@ -117,22 +106,22 @@ nsAccessNodeWrap::QueryService(REFGUID g
 
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
   // Can get to IAccessibleApplication from any node via QS
   if (guidService == IID_IAccessibleApplication ||
       (Compatibility::IsJAWS() && iid == IID_IAccessibleApplication)) {
-    ApplicationAccessible* applicationAcc = ApplicationAcc();
+    ApplicationAccessibleWrap* applicationAcc =
+      static_cast<ApplicationAccessibleWrap*>(ApplicationAcc());
     if (!applicationAcc)
       return E_NOINTERFACE;
 
-    nsresult rv = applicationAcc->QueryNativeInterface(iid, ppv);
-    return NS_SUCCEEDED(rv) ? S_OK : E_NOINTERFACE;
+    return applicationAcc->QueryInterface(iid, ppv);
   }
 
   /**
    * To get an ISimpleDOMNode, ISimpleDOMDocument, ISimpleDOMText
    * or any IAccessible2 interface on should use IServiceProvider like this:
    * -----------------------------------------------------------------------
    * ISimpleDOMDocument *pAccDoc = NULL;
    * IServiceProvider *pServProv = NULL;
--- a/accessible/src/msaa/nsAccessNodeWrap.h
+++ b/accessible/src/msaa/nsAccessNodeWrap.h
@@ -17,17 +17,16 @@
 // importance than the missing dereference for the nsCOMPtr<>
 #ifdef _MSC_VER
 #pragma warning( disable : 4509 )
 #endif
 
 #include "nsCOMPtr.h"
 #include "nsIAccessible.h"
 #include "nsIAccessibleEvent.h"
-#include "nsIWinAccessNode.h"
 #include "nsIDOMElement.h"
 #include "nsIContent.h"
 #include "nsAccessNode.h"
 #include "oleidl.h"
 #include "oleacc.h"
 #include <winuser.h>
 #ifdef MOZ_CRASHREPORTER
 #include "nsICrashReporter.h"
@@ -50,22 +49,20 @@ namespace a11y {
 #ifdef __GNUC__
 // Inheriting from both XPCOM and MSCOM interfaces causes a lot of warnings
 // about virtual functions being hidden by each other. This is done by
 // design, so silence the warning.
 #pragma GCC diagnostic ignored "-Woverloaded-virtual"
 #endif
 
 class nsAccessNodeWrap : public nsAccessNode,
-                         public nsIWinAccessNode,
                          public IServiceProvider
 {
   public:
     NS_DECL_ISUPPORTS_INHERITED
-    NS_DECL_NSIWINACCESSNODE
 
 public: // construction, destruction
   nsAccessNodeWrap(nsIContent* aContent, DocAccessible* aDoc);
   virtual ~nsAccessNodeWrap();
 
   // IUnknown
   virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID aIID,
                                                    void** aInstancePtr);
--- a/accessible/src/msaa/nsWinUtils.cpp
+++ b/accessible/src/msaa/nsWinUtils.cpp
@@ -38,69 +38,16 @@ nsWinUtils::GetComputedStyleDeclaration(
     return nullptr;
 
   nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
   nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(elm));
   window->GetComputedStyle(domElement, EmptyString(), getter_AddRefs(cssDecl));
   return cssDecl.forget();
 }
 
-HRESULT
-nsWinUtils::ConvertToIA2Array(nsIArray *aGeckoArray, IUnknown ***aIA2Array,
-                              long *aIA2ArrayLen)
-{
-  *aIA2Array = NULL;
-  *aIA2ArrayLen = 0;
-
-  if (!aGeckoArray)
-    return S_FALSE;
-
-  uint32_t length = 0;
-  nsresult rv = aGeckoArray->GetLength(&length);
-  if (NS_FAILED(rv))
-    return GetHRESULT(rv);
-
-  if (length == 0)
-    return S_FALSE;
-
-  *aIA2Array =
-    static_cast<IUnknown**>(::CoTaskMemAlloc((length) * sizeof(IUnknown*)));
-  if (!*aIA2Array)
-    return E_OUTOFMEMORY;
-
-  uint32_t idx = 0;
-  for (; idx < length; ++idx) {
-    nsCOMPtr<nsIWinAccessNode> winAccessNode =
-      do_QueryElementAt(aGeckoArray, idx, &rv);
-    if (NS_FAILED(rv))
-      break;
-
-    void *instancePtr = NULL;
-    nsresult rv = winAccessNode->QueryNativeInterface(IID_IUnknown,
-                                                      &instancePtr);
-    if (NS_FAILED(rv))
-      break;
-
-    (*aIA2Array)[idx] = static_cast<IUnknown*>(instancePtr);
-  }
-
-  if (NS_FAILED(rv)) {
-    for (uint32_t idx2 = 0; idx2 < idx; idx2++) {
-      (*aIA2Array)[idx2]->Release();
-      (*aIA2Array)[idx2] = NULL;
-    }
-
-    ::CoTaskMemFree(*aIA2Array);
-    return GetHRESULT(rv);
-  }
-
-  *aIA2ArrayLen = length;
-  return S_OK;
-}
-
 bool
 nsWinUtils::MaybeStartWindowEmulation()
 {
   // Register window class that'll be used for document accessibles associated
   // with tabs.
   if (Compatibility::IsJAWS() || Compatibility::IsWE() ||
       Compatibility::IsDolphin() ||
       Preferences::GetBool("browser.tabs.remote")) {
--- a/accessible/src/msaa/nsWinUtils.h
+++ b/accessible/src/msaa/nsWinUtils.h
@@ -26,23 +26,16 @@ public:
    *
    * @note Please use it carefully since it can shutdown the accessible tree
    *       you operate on.
    */
   static already_AddRefed<nsIDOMCSSStyleDeclaration>
     GetComputedStyleDeclaration(nsIContent* aContent);
 
   /**
-   * Convert nsIArray array of accessible objects to an array of IUnknown*
-   * objects used in IA2 methods.
-   */
-  static HRESULT ConvertToIA2Array(nsIArray *aCollection,
-                                   IUnknown ***aAccessibles, long *aCount);
-
-  /**
    * Start window emulation if presence of specific AT is detected.
    */
   static bool MaybeStartWindowEmulation();
 
   /**
    * Free resources used for window emulation.
    */
   static void ShutdownWindowEmulation();
--- a/accessible/src/windows/ia2/ia2AccessibleHyperlink.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleHyperlink.cpp
@@ -5,17 +5,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/. */
 
 #include "Accessible2.h"
 #include "AccessibleHyperlink.h"
 #include "AccessibleHyperlink_i.c"
 
 #include "AccessibleWrap.h"
-#include "nsIWinAccessNode.h"
 
 using namespace mozilla::a11y;
 
 // IUnknown
 
 STDMETHODIMP
 ia2AccessibleHyperlink::QueryInterface(REFIID iid, void** ppv)
 {
--- a/accessible/src/windows/ia2/ia2AccessibleHypertext.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleHypertext.cpp
@@ -40,27 +40,22 @@ ia2AccessibleHypertext::get_hyperlink(lo
 
   *aHyperlink = NULL;
 
   HyperTextAccessibleWrap* hyperText = static_cast<HyperTextAccessibleWrap*>(this);
   if (hyperText->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   Accessible* hyperLink = hyperText->GetLinkAt(aLinkIndex);
-  nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryObject(hyperLink));
-  if (!winAccessNode)
+  if (!hyperText)
     return E_FAIL;
 
-  void *instancePtr = NULL;
-  nsresult rv =  winAccessNode->QueryNativeInterface(IID_IAccessibleHyperlink,
-                                                     &instancePtr);
-  if (NS_FAILED(rv))
-    return E_FAIL;
-
-  *aHyperlink = static_cast<IAccessibleHyperlink*>(instancePtr);
+  *aHyperlink =
+    static_cast<IAccessibleHyperlink*>(static_cast<AccessibleWrap*>(hyperLink));
+  (*aHyperlink)->AddRef();
   return S_OK;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleHypertext::get_hyperlinkIndex(long aCharIndex, long* aHyperlinkIndex)
 {
--- a/accessible/src/windows/ia2/ia2AccessibleRelation.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleRelation.cpp
@@ -158,17 +158,21 @@ ia2AccessibleRelation::get_nTargets(long
 STDMETHODIMP
 ia2AccessibleRelation::get_target(long aTargetIndex, IUnknown **aTarget)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (aTargetIndex < 0 || (uint32_t)aTargetIndex >= mTargets.Length() || !aTarget)
     return E_INVALIDARG;
 
-  mTargets[aTargetIndex]->QueryNativeInterface(IID_IUnknown, (void**) aTarget);
+  AccessibleWrap* target =
+    static_cast<AccessibleWrap*>(mTargets[aTargetIndex].get());
+  *aTarget = static_cast<IAccessible*>(target);
+  (*aTarget)->AddRef();
+
   return S_OK;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleRelation::get_targets(long aMaxTargets, IUnknown **aTargets,
                                    long *aNTargets)
--- a/accessible/tests/mochitest/states/test_aria.html
+++ b/accessible/tests/mochitest/states/test_aria.html
@@ -105,16 +105,30 @@
                  STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
 
       // aria-pressed
       testStates("aria_pressed_button", STATE_PRESSED | STATE_CHECKABLE);
 
       // aria-readonly
       testStates("aria_readonly_textbox", STATE_READONLY);
 
+      // readonly/editable on grid and gridcell
+      testStates("aria_grid_default", 0, EXT_STATE_EDITABLE,
+                 STATE_READONLY, 0);
+      testStates("aria_grid_default_cell_readonly", STATE_READONLY, 0,
+                 0, EXT_STATE_EDITABLE);
+      testStates("aria_grid_default_cell_inherited", 0, EXT_STATE_EDITABLE,
+                 STATE_READONLY, 0);
+      testStates("aria_grid_readonly", STATE_READONLY, 0,
+                 0, EXT_STATE_EDITABLE);
+      testStates("aria_grid_readonly_cell_editable", 0, EXT_STATE_EDITABLE,
+                 STATE_READONLY, 0);
+      testStates("aria_grid_readonly_cell_inherited", STATE_READONLY, 0,
+                 0, EXT_STATE_EDITABLE);
+
       // aria-selectable
       testStates("aria_selectable_listitem", STATE_SELECTABLE | STATE_SELECTED);
 
       // active state caused by aria-activedescendant
       testStates("as_item1", 0, EXT_STATE_ACTIVE);
       testStates("as_item2", 0, 0, 0, EXT_STATE_ACTIVE);
 
       // universal ARIA properties inherited from file input control
@@ -225,16 +239,21 @@
      title="ARIA undetermined progressmeters should expose mixed state">
     Mozilla Bug 740851
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=762876
      title="fix default horizontal / vertical state of role=scrollbar and ensure only one of horizontal / vertical states is exposed">
     Mozilla Bug 762876
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=835121
+     title="ARIA grid should be editable by default">
+    Mozilla Bug 835121
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <div id="textbox_autocomplete_inline" role="textbox" aria-autocomplete="inline"></div>
   <div id="textbox_autocomplete_list" role="textbox" aria-autocomplete="list"></div>
   <div id="textbox_autocomplete_both" role="textbox" aria-autocomplete="both"></div>
@@ -260,17 +279,36 @@
   </div>
 
   <div id="aria_mixed_checkbox" role="checkbox" aria-checked="mixed">
     I might agree
   </div>
   <div id="aria_multiline_textbox" role="textbox" aria-multiline="true"></div>
   <div id="aria_multiselectable_listbox" role="listbox" aria-multiselectable="true"></div>
   <div id="aria_pressed_button" role="button" aria-pressed="true">Button</div>
-  <div id="aria_readonly_textbox" role="textbox" aria-readonly="true">This text should be readonly</div>
+
+  <div id="aria_readonly_textbox"
+       role="textbox" aria-readonly="true">This text should be readonly</div>
+
+  <div id="aria_grid_default" role="grid">
+    <div role="row">
+      <div id="aria_grid_default_cell_readonly"
+           role="gridcell" aria-readonly="true">gridcell1</div>
+      <div id="aria_grid_default_cell_inherited"
+           role="gridcell">gridcell2</div>
+  </div>
+
+  <div id="aria_grid_readonly" role="grid" aria-readonly="true">
+    <div role="row">
+      <div id="aria_grid_readonly_cell_editable"
+           role="gridcell" aria-readonly="false">gridcell1</div>
+      <div id="aria_grid_readonly_cell_inherited"
+           role="gridcell">gridcell2</div>
+  </div>
+
   <div role="listbox">
     <div id="aria_selectable_listitem" role="option" aria-selected="true">Item1</div>
   </div>
 
   <!-- Test that aria-disabled state gets propagated to all descendants -->
   <div id="group" role="group" aria-disabled="true">
     <button>hi</button>
     <div tabindex="0" role="listbox" aria-activedescendant="item1">
@@ -308,17 +346,17 @@
   <!-- strange edge case: please don't do this in the wild -->
   <a id="aria_link_link" role="link" href="foo">link</a>
   <a id="aria_link_anchor" role="link" name="link_anchor">link</a>
 
   <!-- landmarks: links -->
   <a id="aria_application_link" role="application" href="foo">app</a>
   <a id="aria_main_link" role="main" href="foo">main</a>
   <a id="aria_navigation_link" role="navigation" href="foo">nav</a>
-  
+
   <!-- landmarks: anchors -->
   <a id="aria_application_anchor" role="application" name="app_anchor">app</a>
   <a id="aria_main_anchor" role="main" name="main_anchor">main</a>
   <a id="aria_navigation_anchor" role="navigation" name="nav_anchor">nav</a>
 
   <!-- aria-orientation -->
   <div id="aria_scrollbar" role="scrollbar">scrollbar</div>
   <div id="aria_hscrollbar" role="scrollbar" aria-orientation="horizontal">horizontal scrollbar</div>
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -124,17 +124,16 @@
 #endif
 
 ; [Components]
 @BINPATH@/components/components.manifest
 @BINPATH@/components/alerts.xpt
 #ifdef ACCESSIBILITY
 #ifdef XP_WIN32
 @BINPATH@/AccessibleMarshal.dll
-@BINPATH@/components/accessibility-msaa.xpt
 #endif
 @BINPATH@/components/accessibility.xpt
 #endif
 @BINPATH@/components/appshell.xpt
 @BINPATH@/components/appstartup.xpt
 @BINPATH@/components/autocomplete.xpt
 @BINPATH@/components/autoconfig.xpt
 @BINPATH@/components/browsercompsbase.xpt
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -114,20 +114,16 @@ ifeq ($(OS_ARCH),WINNT) #{
 #
 # The default heap size is 1MB on Win32.
 # The heap will grow if need be.
 #
 # Set it to 256k.  See bug 127069.
 #
 ifndef GNU_CC #{
 LDFLAGS += /HEAP:0x40000
-ifeq ($(OS_TEST),x86_64) #{
-# set stack to 2MB on x64 build.  See bug 582910
-LDFLAGS += -STACK:2097152
-endif #}
 endif #}
 endif #}
 
 ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH)))
 
 libs:: 
 	cp -p $(MOZ_APP_NAME)$(BIN_SUFFIX) $(DIST)/bin/$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)
 
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -260,17 +260,16 @@
 #endif
       </hbox>
     </panel>
 
     <panel id="social-notification-panel"
            class="social-panel"
            type="arrow"
            hidden="true"
-           consumeoutsideclicks="false"
            noautofocus="true"/>
     <panel id="social-flyout-panel"
            class="social-panel"
            onpopupshown="SocialFlyout.onShown()"
            onpopuphidden="SocialFlyout.onHidden()"
            side="right"
            type="arrow"
            hidden="true"
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -134,17 +134,16 @@
 #endif
 
 ; [Components]
 @BINPATH@/browser/components/components.manifest
 @BINPATH@/components/alerts.xpt
 #ifdef ACCESSIBILITY
 #ifdef XP_WIN32
 @BINPATH@/AccessibleMarshal.dll
-@BINPATH@/components/accessibility-msaa.xpt
 #endif
 @BINPATH@/components/accessibility.xpt
 #endif
 @BINPATH@/components/appshell.xpt
 @BINPATH@/components/appstartup.xpt
 @BINPATH@/components/autocomplete.xpt
 @BINPATH@/components/autoconfig.xpt
 @BINPATH@/browser/components/browsercompsbase.xpt
--- a/config/config.mk
+++ b/config/config.mk
@@ -584,16 +584,23 @@ ifdef GNU_CC
 WIN32_EXE_LDFLAGS	+= -mwindows
 else
 WIN32_EXE_LDFLAGS	+= -SUBSYSTEM:WINDOWS
 endif
 endif
 endif
 endif
 
+ifdef _MSC_VER
+ifeq ($(CPU_ARCH),x86_64)
+# set stack to 2MB on x64 build.  See bug 582910
+WIN32_EXE_LDFLAGS	+= -STACK:2097152
+endif
+endif
+
 # If we're building a component on MSVC, we don't want to generate an
 # import lib, because that import lib will collide with the name of a
 # static version of the same library.
 ifeq ($(GNU_LD)$(OS_ARCH),WINNT)
 ifdef IS_COMPONENT
 LDFLAGS += -IMPLIB:fake.lib
 DELETE_AFTER_LINK = fake.lib fake.exp
 endif
--- a/config/expandlibs_exec.py
+++ b/config/expandlibs_exec.py
@@ -262,16 +262,24 @@ class SectionFinder(object):
             # We only need to consider cases where "<section>\t<length> <symbol>" is present,
             # and where the [FfO] flag is either F (function) or O (object).
             if len(tmp) > 1 and len(tmp[1]) > 6 and tmp[1][6] in ['O', 'F']:
                 tmp = tmp[1][8:].split()
                 # That gives us ["<section>","<length>", "<symbol>"]
                 syms.append((tmp[-1], tmp[0]))
         return syms
 
+def print_command(out, args):
+    print >>out, "Executing: " + " ".join(args)
+    for tmp in [f for f in args.tmp if os.path.isfile(f)]:
+        print >>out, tmp + ":"
+        with open(tmp) as file:
+            print >>out, "".join(["    " + l for l in file.readlines()])
+    out.flush()
+
 def main():
     parser = OptionParser()
     parser.add_option("--depend", dest="depend", metavar="FILE",
         help="generate dependencies for the given execution and store it in the given file")
     parser.add_option("--target", dest="target", metavar="FILE",
         help="designate the target for dependencies")
     parser.add_option("--extract", action="store_true", dest="extract",
         help="when a library has no descriptor file, extract it first, when possible")
@@ -297,25 +305,25 @@ def main():
         if options.extract:
             args.extract()
         if options.symbol_order:
             args.orderSymbols(options.symbol_order)
         if options.uselist:
             args.makelist()
 
         if options.verbose:
-            print >>sys.stderr, "Executing: " + " ".join(args)
-            for tmp in [f for f in args.tmp if os.path.isfile(f)]:
-                print >>sys.stderr, tmp + ":"
-                with open(tmp) as file:
-                    print >>sys.stderr, "".join(["    " + l for l in file.readlines()])
-            sys.stderr.flush()
-        ret = subprocess.call(args)
-        if ret:
-            exit(ret)
+            print_command(sys.stderr, args)
+        proc = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
+        (stdout, stderr) = proc.communicate()
+        if proc.returncode and not options.verbose:
+            print_command(sys.stderr, args)
+        sys.stderr.write(stdout)
+        sys.stderr.flush()
+        if proc.returncode:
+            exit(proc.returncode)
     if not options.depend:
         return
     ensureParentDir(options.depend)
     with open(options.depend, 'w') as depfile:
         depfile.write("%s : %s\n" % (options.target, ' '.join(dep for dep in deps if os.path.isfile(dep) and dep != options.target)))
 
 
 if __name__ == '__main__':
--- a/config/nspr/Makefile.in
+++ b/config/nspr/Makefile.in
@@ -27,13 +27,8 @@ libs::
 	$(INSTALL) $(DEPTH)/nsprpub/config/nspr-config $(DIST)/sdk/bin
 	$(RM) -rf $(DIST)/sdk/dummy
 ifneq (,$(filter OS2 WINNT,$(OS_ARCH))) # {
 	$(RM) -f $(DIST)/sdk/lib/$(DLL_PREFIX)nspr4$(DLL_SUFFIX) $(DIST)/sdk/lib/$(DLL_PREFIX)plc4$(DLL_SUFFIX) $(DIST)/sdk/lib/$(DLL_PREFIX)plds4$(DLL_SUFFIX)
 	$(RM) -f $(DIST)/sdk/lib/$(LIB_PREFIX)nspr4_s.$(LIB_SUFFIX) $(DIST)/sdk/lib/$(LIB_PREFIX)plc4_s.$(LIB_SUFFIX) $(DIST)/sdk/lib/$(LIB_PREFIX)plds4_s.$(LIB_SUFFIX)
 else # } {
 	$(RM) -f $(DIST)/sdk/lib/$(LIB_PREFIX)nspr4.$(LIB_SUFFIX) $(DIST)/sdk/lib/$(LIB_PREFIX)plc4.$(LIB_SUFFIX) $(DIST)/sdk/lib/$(LIB_PREFIX)plds4.$(LIB_SUFFIX)
 endif # }
-
-install::
-	$(MAKE) -C $(DEPTH)/nsprpub install DESTDIR=$(DESTDIR) libdir=$(mozappdir) includedir=$(includedir)/nspr
-	$(RM) -f $(addprefix $(DESTDIR)$(mozappdir)/$(LIB_PREFIX), $(addsuffix .$(LIB_SUFFIX), nspr4 plds4 plc4))
-	$(RM) -f $(addprefix $(DESTDIR)$(bindir)/,nspr-config compile-et.pl prerr.properties)
deleted file mode 100644
--- a/config/nspr/build.mk
+++ /dev/null
@@ -1,10 +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/.
-
-TIERS += nspr
-
-ifndef MOZ_NATIVE_NSPR
-tier_nspr_staticdirs += nsprpub
-tier_nspr_dirs += config/nspr
-endif
--- a/content/base/public/nsISelection.idl
+++ b/content/base/public/nsISelection.idl
@@ -13,17 +13,17 @@ interface nsINode;
 
 /**
  * Interface for manipulating and querying the current selected range
  * of nodes within the document.
  *
  * @version 1.0
  */
 
-[scriptable, uuid(12cf5a4d-fffb-4f2f-9cec-c65195661d76)]
+[scriptable, builtinclass, uuid(12cf5a4d-fffb-4f2f-9cec-c65195661d76)]
 interface nsISelection : nsISupports
 {
     /**
      * Returns the node in which the selection begins.
      */
     readonly attribute nsIDOMNode anchorNode;
 
     /**
--- a/content/base/public/nsISelectionPrivate.idl
+++ b/content/base/public/nsISelectionPrivate.idl
@@ -26,17 +26,17 @@ struct ScrollAxis;
 [ptr] native nsFrameSelection(nsFrameSelection);
 [ptr] native nsIFrame(nsIFrame);
 [ptr] native RangeArray(nsTArray<nsRange*>);
 [ref] native constTextRangeStyleRef(const nsTextRangeStyle);
 [ref] native nsPointRef(nsPoint);
 native nsDirection(nsDirection);
 native ScrollAxis(nsIPresShell::ScrollAxis);
 
-[scriptable, uuid(2e44b10f-7d6d-4bf4-92e2-f9551d22f422)]
+[scriptable, builtinclass, uuid(2e44b10f-7d6d-4bf4-92e2-f9551d22f422)]
 interface nsISelectionPrivate : nsISelection
  {
     const short ENDOFPRECEDINGLINE=0;
     const short STARTOFNEXTLINE=1;
     
     attribute boolean interlinePosition;
 
     /* startBatchChanges
--- a/content/base/src/nsDocumentEncoder.cpp
+++ b/content/base/src/nsDocumentEncoder.cpp
@@ -29,22 +29,21 @@
 #include "nsIDOMDocumentType.h"
 #include "nsIDOMNodeList.h"
 #include "nsRange.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMDocument.h"
 #include "nsICharsetConverterManager.h"
 #include "nsGkAtoms.h"
 #include "nsIContent.h"
-#include "nsIEnumerator.h"
 #include "nsIParserService.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptSecurityManager.h"
-#include "nsISelection.h"
+#include "mozilla/Selection.h"
 #include "nsISelectionPrivate.h"
 #include "nsITransferable.h" // for kUnicodeMime
 #include "nsContentUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsReadableUtils.h"
 #include "nsTArray.h"
 #include "nsIFrame.h"
 #include "nsStringBuffer.h"
@@ -1343,29 +1342,27 @@ nsHTMLCopyEncoder::SetSelection(nsISelec
   // we don't tweak the selection to be outside of the magic
   // div that ender-lite text widgets are embedded in.
   
   if (!aSelection) 
     return NS_ERROR_NULL_POINTER;
   
   nsCOMPtr<nsIDOMRange> range;
   nsCOMPtr<nsIDOMNode> commonParent;
-  int32_t count = 0;
-
-  nsresult rv = aSelection->GetRangeCount(&count);
-  NS_ENSURE_SUCCESS(rv, rv);
+  Selection* selection = static_cast<Selection*>(aSelection);
+  uint32_t rangeCount = selection->GetRangeCount();
 
   // if selection is uninitialized return
-  if (!count)
+  if (!rangeCount)
     return NS_ERROR_FAILURE;
   
   // we'll just use the common parent of the first range.  Implicit assumption
   // here that multi-range selections are table cell selections, in which case
   // the common parent is somewhere in the table and we don't really care where.
-  rv = aSelection->GetRangeAt(0, getter_AddRefs(range));
+  nsresult rv = aSelection->GetRangeAt(0, getter_AddRefs(range));
   NS_ENSURE_SUCCESS(rv, rv);
   if (!range)
     return NS_ERROR_NULL_POINTER;
   range->GetCommonAncestorContainer(getter_AddRefs(commonParent));
 
   for (nsCOMPtr<nsIContent> selContent(do_QueryInterface(commonParent));
        selContent;
        selContent = selContent->GetParent())
@@ -1407,48 +1404,31 @@ nsHTMLCopyEncoder::SetSelection(nsISelec
     return NS_OK;
   }
   
   // there's no Clone() for selection! fix...
   //nsresult rv = aSelection->Clone(getter_AddRefs(mSelection);
   //NS_ENSURE_SUCCESS(rv, rv);
   NS_NewDomSelection(getter_AddRefs(mSelection));
   NS_ENSURE_TRUE(mSelection, NS_ERROR_FAILURE);
-  nsCOMPtr<nsISelectionPrivate> privSelection( do_QueryInterface(aSelection) );
-  NS_ENSURE_TRUE(privSelection, NS_ERROR_FAILURE);
   
-  // get selection range enumerator
-  nsCOMPtr<nsIEnumerator> enumerator;
-  rv = privSelection->GetEnumerator(getter_AddRefs(enumerator));
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
-
   // loop thru the ranges in the selection
-  enumerator->First(); 
-  nsCOMPtr<nsISupports> currentItem;
-  while (static_cast<nsresult>(NS_ENUMERATOR_FALSE) == enumerator->IsDone())
-  {
-    rv = enumerator->CurrentItem(getter_AddRefs(currentItem));
-    NS_ENSURE_SUCCESS(rv, rv);
-    NS_ENSURE_TRUE(currentItem, NS_ERROR_FAILURE);
-    
-    range = do_QueryInterface(currentItem);
+  for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
+    range = selection->GetRangeAt(rangeIdx);
     NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
     nsCOMPtr<nsIDOMRange> myRange;
     range->CloneRange(getter_AddRefs(myRange));
     NS_ENSURE_TRUE(myRange, NS_ERROR_FAILURE);
 
     // adjust range to include any ancestors who's children are entirely selected
     rv = PromoteRange(myRange);
     NS_ENSURE_SUCCESS(rv, rv);
     
     rv = mSelection->AddRange(myRange);
     NS_ENSURE_SUCCESS(rv, rv);
-
-    enumerator->Next();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLCopyEncoder::EncodeToStringWithContext(nsAString& aContextString,
                                              nsAString& aInfoString,
--- a/dom/apps/src/Webapps.js
+++ b/dom/apps/src/Webapps.js
@@ -388,16 +388,17 @@ WebappsApplication.prototype = {
     this._ondownloadavailable = null;
     this._ondownloadapplied = null;
 
     this._downloadError = null;
 
     this.initHelper(aWindow, ["Webapps:OfflineCache",
                               "Webapps:CheckForUpdate:Return:OK",
                               "Webapps:CheckForUpdate:Return:KO",
+                              "Webapps:Launch:Return:KO",
                               "Webapps:PackageEvent"]);
 
     cpmm.sendAsyncMessage("Webapps:RegisterForMessages",
                           ["Webapps:OfflineCache",
                            "Webapps:PackageEvent",
                            "Webapps:CheckForUpdate:Return:OK"]);
   },
 
--- a/dom/tests/browser/browser_xhr_sandbox.js
+++ b/dom/tests/browser/browser_xhr_sandbox.js
@@ -34,16 +34,16 @@ function test() {
     let workerWindow = frame.contentWindow;
     workerWindow.addEventListener("message", function(evt) {
       is(evt.data.result, "ok", "check the sandbox code was happy");
       finish();
     }, true);
     let sandbox = new Cu.Sandbox(workerWindow);
     // inject some functions from the window into the sandbox.
     // postMessage so the async code in the sandbox can report a result.
-    sandbox.importFunction(workerWindow.postMessage, "postMessage");
+    sandbox.importFunction(workerWindow.postMessage.bind(workerWindow), "postMessage");
     sandbox.importFunction(workerWindow.XMLHttpRequest, "XMLHttpRequest");
     Cu.evalInSandbox(sandboxCode, sandbox, "1.8");
   }, true);
 
   let container = doc.body ? doc.body : doc.documentElement;
   container.appendChild(frame);
 }
--- a/editor/libeditor/base/nsEditor.cpp
+++ b/editor/libeditor/base/nsEditor.cpp
@@ -67,17 +67,16 @@
 #include "nsIDOMNodeList.h"             // for nsIDOMNodeList
 #include "nsIDOMRange.h"                // for nsIDOMRange
 #include "nsIDOMText.h"                 // for nsIDOMText
 #include "nsIDocument.h"                // for nsIDocument
 #include "nsIDocumentStateListener.h"   // for nsIDocumentStateListener
 #include "nsIEditActionListener.h"      // for nsIEditActionListener
 #include "nsIEditorObserver.h"          // for nsIEditorObserver
 #include "nsIEditorSpellCheck.h"        // for nsIEditorSpellCheck
-#include "nsIEnumerator.h"              // for nsIEnumerator, etc
 #include "nsIFrame.h"                   // for nsIFrame
 #include "nsIInlineSpellChecker.h"      // for nsIInlineSpellChecker, etc
 #include "nsIMEStateManager.h"          // for nsIMEStateManager
 #include "nsINameSpaceManager.h"        // for kNameSpaceID_None, etc
 #include "nsINode.h"                    // for nsINode, etc
 #include "nsIObserverService.h"         // for nsIObserverService
 #include "nsIPlaintextEditor.h"         // for nsIPlaintextEditor, etc
 #include "nsIPresShell.h"               // for nsIPresShell
@@ -3887,31 +3886,23 @@ nsEditor::GetStartNodeAndOffset(nsISelec
                                        nsIDOMNode **outStartNode,
                                        int32_t *outStartOffset)
 {
   NS_ENSURE_TRUE(outStartNode && outStartOffset && aSelection, NS_ERROR_NULL_POINTER);
 
   *outStartNode = nullptr;
   *outStartOffset = 0;
 
-  nsCOMPtr<nsISelectionPrivate>selPrivate(do_QueryInterface(aSelection));
-  nsCOMPtr<nsIEnumerator> enumerator;
-  nsresult result = selPrivate->GetEnumerator(getter_AddRefs(enumerator));
-  NS_ENSURE_SUCCESS(result, result);
-  NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
-
-  enumerator->First(); 
-  nsCOMPtr<nsISupports> currentItem;
-  result = enumerator->CurrentItem(getter_AddRefs(currentItem));
-  NS_ENSURE_SUCCESS(result, result);
-
-  nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
+  Selection* selection = static_cast<Selection*>(aSelection);
+  NS_ENSURE_TRUE(selection->GetRangeCount(), NS_ERROR_FAILURE);
+
+  nsRange* range = selection->GetRangeAt(0);
   NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
 
-  result = range->GetStartContainer(outStartNode);
+  nsresult result = range->GetStartContainer(outStartNode);
   NS_ENSURE_SUCCESS(result, result);
 
   result = range->GetStartOffset(outStartOffset);
   NS_ENSURE_SUCCESS(result, result);
 
   return NS_OK;
 }
 
@@ -3923,28 +3914,21 @@ nsresult
 nsEditor::GetEndNodeAndOffset(nsISelection *aSelection,
                                        nsIDOMNode **outEndNode,
                                        int32_t *outEndOffset)
 {
   NS_ENSURE_TRUE(outEndNode && outEndOffset, NS_ERROR_NULL_POINTER);
 
   *outEndNode = nullptr;
     
-  nsCOMPtr<nsISelectionPrivate>selPrivate(do_QueryInterface(aSelection));
-  nsCOMPtr<nsIEnumerator> enumerator;
-  nsresult result = selPrivate->GetEnumerator(getter_AddRefs(enumerator));
-  if (NS_FAILED(result) || !enumerator)
-    return NS_ERROR_FAILURE;
-    
-  enumerator->First(); 
-  nsCOMPtr<nsISupports> currentItem;
-  if (NS_FAILED(enumerator->CurrentItem(getter_AddRefs(currentItem))))
-    return NS_ERROR_FAILURE;
-
-  nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
+  Selection* selection = static_cast<Selection*>(aSelection);
+  NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(selection->GetRangeCount(), NS_ERROR_FAILURE);
+
+  nsRange* range = selection->GetRangeAt(0);
   NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
     
   if (NS_FAILED(range->GetEndContainer(outEndNode)))
     return NS_ERROR_FAILURE;
     
   if (NS_FAILED(range->GetEndOffset(outEndOffset)))
     return NS_ERROR_FAILURE;
     
--- a/editor/libeditor/html/nsHTMLEditRules.cpp
+++ b/editor/libeditor/html/nsHTMLEditRules.cpp
@@ -33,17 +33,16 @@
 #include "nsIContentIterator.h"
 #include "nsID.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMText.h"
-#include "nsIEnumerator.h"
 #include "nsIHTMLAbsPosEditor.h"
 #include "nsIHTMLDocument.h"
 #include "nsINode.h"
 #include "nsISelection.h"
 #include "nsISelectionPrivate.h"
 #include "nsLiteralString.h"
 #include "nsPlaintextEditor.h"
 #include "nsRange.h"
@@ -2301,32 +2300,23 @@ nsHTMLEditRules::WillDeleteSelection(Sel
             // fix up selection
             res = aSelection->Collapse(selNode,selOffset);
             return res;
           }
         }
         
         // else blocks not same type, or not siblings.  Delete everything except
         // table elements.
-        nsCOMPtr<nsIEnumerator> enumerator;
-        res = aSelection->GetEnumerator(getter_AddRefs(enumerator));
-        NS_ENSURE_SUCCESS(res, res);
-        NS_ENSURE_TRUE(enumerator, NS_ERROR_UNEXPECTED);
-
         join = true;
 
-        for (enumerator->First(); NS_OK!=enumerator->IsDone(); enumerator->Next())
-        {
-          nsCOMPtr<nsISupports> currentItem;
-          res = enumerator->CurrentItem(getter_AddRefs(currentItem));
-          NS_ENSURE_SUCCESS(res, res);
-          NS_ENSURE_TRUE(currentItem, NS_ERROR_UNEXPECTED);
+        uint32_t rangeCount = aSelection->GetRangeCount();
+        for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
+          nsRefPtr<nsRange> range = aSelection->GetRangeAt(rangeIdx);
 
           // build a list of nodes in the range
-          nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
           nsCOMArray<nsIDOMNode> arrayOfNodes;
           nsTrivialFunctor functor;
           nsDOMSubtreeIterator iter;
           res = iter.Init(range);
           NS_ENSURE_SUCCESS(res, res);
           res = iter.AppendList(functor, arrayOfNodes);
           NS_ENSURE_SUCCESS(res, res);
       
@@ -5771,35 +5761,25 @@ nsHTMLEditRules::GetListActionNodes(nsCO
                                     bool aEntireList,
                                     bool aDontTouchContent)
 {
   nsresult res = NS_OK;
   
   nsCOMPtr<nsISelection>selection;
   res = mHTMLEditor->GetSelection(getter_AddRefs(selection));
   NS_ENSURE_SUCCESS(res, res);
-  nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
-  NS_ENSURE_TRUE(selPriv, NS_ERROR_FAILURE);
+  Selection* sel = static_cast<Selection*>(selection.get());
+  NS_ENSURE_TRUE(sel, NS_ERROR_FAILURE);
   // added this in so that ui code can ask to change an entire list, even if selection
   // is only in part of it.  used by list item dialog.
   if (aEntireList)
   {       
-    nsCOMPtr<nsIEnumerator> enumerator;
-    res = selPriv->GetEnumerator(getter_AddRefs(enumerator));
-    NS_ENSURE_SUCCESS(res, res);
-    NS_ENSURE_TRUE(enumerator, NS_ERROR_UNEXPECTED);
-
-    for (enumerator->First(); NS_OK!=enumerator->IsDone(); enumerator->Next())
-    {
-      nsCOMPtr<nsISupports> currentItem;
-      res = enumerator->CurrentItem(getter_AddRefs(currentItem));
-      NS_ENSURE_SUCCESS(res, res);
-      NS_ENSURE_TRUE(currentItem, NS_ERROR_UNEXPECTED);
-
-      nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
+    uint32_t rangeCount = sel->GetRangeCount();
+    for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
+      nsRefPtr<nsRange> range = sel->GetRangeAt(rangeIdx);
       nsCOMPtr<nsIDOMNode> commonParent, parent, tmp;
       range->GetCommonAncestorContainer(getter_AddRefs(commonParent));
       if (commonParent)
       {
         parent = commonParent;
         while (parent)
         {
           if (nsHTMLEditUtils::IsList(parent))
@@ -7792,31 +7772,21 @@ nsHTMLEditRules::SelectionEndpointInNode
 
   nsIDOMNode* node = aNode->AsDOMNode();
   
   *aResult = false;
   
   nsCOMPtr<nsISelection>selection;
   nsresult res = mHTMLEditor->GetSelection(getter_AddRefs(selection));
   NS_ENSURE_SUCCESS(res, res);
-  nsCOMPtr<nsISelectionPrivate>selPriv(do_QueryInterface(selection));
-  
-  nsCOMPtr<nsIEnumerator> enumerator;
-  res = selPriv->GetEnumerator(getter_AddRefs(enumerator));
-  NS_ENSURE_SUCCESS(res, res);
-  NS_ENSURE_TRUE(enumerator, NS_ERROR_UNEXPECTED);
-
-  for (enumerator->First(); NS_OK!=enumerator->IsDone(); enumerator->Next())
-  {
-    nsCOMPtr<nsISupports> currentItem;
-    res = enumerator->CurrentItem(getter_AddRefs(currentItem));
-    NS_ENSURE_SUCCESS(res, res);
-    NS_ENSURE_TRUE(currentItem, NS_ERROR_UNEXPECTED);
-
-    nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
+  
+  Selection* sel = static_cast<Selection*>(selection.get());
+  uint32_t rangeCount = sel->GetRangeCount();
+  for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
+    nsRefPtr<nsRange> range = sel->GetRangeAt(rangeIdx);
     nsCOMPtr<nsIDOMNode> startParent, endParent;
     range->GetStartContainer(getter_AddRefs(startParent));
     if (startParent)
     {
       if (node == startParent) {
         *aResult = true;
         return NS_OK;
       }
--- a/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/editor/libeditor/html/nsHTMLEditor.cpp
@@ -32,17 +32,16 @@
 #include "nsIDOMHTMLDocument.h"
 #include "nsILinkHandler.h"
 #include "nsIInlineSpellChecker.h"
 
 #include "mozilla/css/Loader.h"
 #include "nsCSSStyleSheet.h"
 #include "nsIDOMStyleSheet.h"
 
-#include "nsIEnumerator.h"
 #include "nsIContent.h"
 #include "nsIContentIterator.h"
 #include "nsIDOMRange.h"
 #include "nsISupportsArray.h"
 #include "nsContentUtils.h"
 #include "nsIDocumentEncoder.h"
 #include "nsIDOMDocumentFragment.h"
 #include "nsIPresShell.h"
@@ -2383,17 +2382,17 @@ nsHTMLEditor::GetSelectedElement(const n
   // default is null - no element found
   *aReturn = nullptr;
   
   // First look for a single element in selection
   nsCOMPtr<nsISelection>selection;
   nsresult res = GetSelection(getter_AddRefs(selection));
   NS_ENSURE_SUCCESS(res, res);
   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
-  nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
+  Selection* sel = static_cast<Selection*>(selection.get());
 
   bool bNodeFound = false;
   bool isCollapsed = selection->Collapsed();
 
   nsAutoString domTagName;
   nsAutoString TagName(aTagName);
   ToLowerCase(TagName);
   // Empty string indicates we should match any element tag
@@ -2448,57 +2447,44 @@ nsHTMLEditor::GetSelectedElement(const n
       //  found for any selection that is totally within a link,
       //  included a collapsed selection (just a caret in a link)
       nsCOMPtr<nsIDOMNode> anchorNode;
       res = selection->GetAnchorNode(getter_AddRefs(anchorNode));
       NS_ENSURE_SUCCESS(res, res);
       int32_t anchorOffset = -1;
       if (anchorNode)
         selection->GetAnchorOffset(&anchorOffset);
-    
+
       nsCOMPtr<nsIDOMNode> focusNode;
       res = selection->GetFocusNode(getter_AddRefs(focusNode));
       NS_ENSURE_SUCCESS(res, res);
       int32_t focusOffset = -1;
       if (focusNode)
         selection->GetFocusOffset(&focusOffset);
 
       // Link node must be the same for both ends of selection
       if (NS_SUCCEEDED(res) && anchorNode)
       {
-  #ifdef DEBUG_cmanske
-        {
-        nsAutoString name;
-        anchorNode->GetNodeName(name);
-        printf("GetSelectedElement: Anchor node of selection: ");
-        wprintf(name.get());
-        printf(" Offset: %d\n", anchorOffset);
-        focusNode->GetNodeName(name);
-        printf("Focus node of selection: ");
-        wprintf(name.get());
-        printf(" Offset: %d\n", focusOffset);
-        }
-  #endif
         nsCOMPtr<nsIDOMElement> parentLinkOfAnchor;
         res = GetElementOrParentByTagName(NS_LITERAL_STRING("href"), anchorNode, getter_AddRefs(parentLinkOfAnchor));
         // XXX: ERROR_HANDLING  can parentLinkOfAnchor be null?
         if (NS_SUCCEEDED(res) && parentLinkOfAnchor)
         {
           if (isCollapsed)
           {
             // We have just a caret in the link
             bNodeFound = true;
           } else if(focusNode) 
           {  // Link node must be the same for both ends of selection
             nsCOMPtr<nsIDOMElement> parentLinkOfFocus;
             res = GetElementOrParentByTagName(NS_LITERAL_STRING("href"), focusNode, getter_AddRefs(parentLinkOfFocus));
             if (NS_SUCCEEDED(res) && parentLinkOfFocus == parentLinkOfAnchor)
               bNodeFound = true;
           }
-      
+
           // We found a link node parent
           if (bNodeFound) {
             // GetElementOrParentByTagName addref'd this, so we don't need to do it here
             *aReturn = parentLinkOfAnchor;
             NS_IF_ADDREF(*aReturn);
             return NS_OK;
           }
         }
@@ -2513,87 +2499,73 @@ nsHTMLEditor::GetSelectedElement(const n
             bNodeFound = true;
           }
         }
       }
     } 
 
     if (!isCollapsed)   // Don't bother to examine selection if it is collapsed
     {
-      nsCOMPtr<nsIEnumerator> enumerator;
-      res = selPriv->GetEnumerator(getter_AddRefs(enumerator));
-      if (NS_SUCCEEDED(res))
-      {
-        if(!enumerator)
-          return NS_ERROR_NULL_POINTER;
-
-        enumerator->First(); 
-        nsCOMPtr<nsISupports> currentItem;
-        res = enumerator->CurrentItem(getter_AddRefs(currentItem));
-        if ((NS_SUCCEEDED(res)) && currentItem)
+      nsRefPtr<nsRange> currange = sel->GetRangeAt(0);
+      if (currange) {
+        nsCOMPtr<nsIContentIterator> iter =
+          do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &res);
+        NS_ENSURE_SUCCESS(res, res);
+
+        iter->Init(currange);
+        // loop through the content iterator for each content node
+        while (!iter->IsDone())
         {
-          nsCOMPtr<nsIDOMRange> currange( do_QueryInterface(currentItem) );
-          nsCOMPtr<nsIContentIterator> iter =
-            do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &res);
-          NS_ENSURE_SUCCESS(res, res);
-
-          iter->Init(currange);
-          // loop through the content iterator for each content node
-          while (!iter->IsDone())
+          // Query interface to cast nsIContent to nsIDOMNode
+          //  then get tagType to compare to  aTagName
+          // Clone node of each desired type and append it to the aDomFrag
+          selectedElement = do_QueryInterface(iter->GetCurrentNode());
+          if (selectedElement)
           {
-            // Query interface to cast nsIContent to nsIDOMNode
-            //  then get tagType to compare to  aTagName
-            // Clone node of each desired type and append it to the aDomFrag
-            selectedElement = do_QueryInterface(iter->GetCurrentNode());
-            if (selectedElement)
+            // If we already found a node, then we have another element,
+            //  thus there's not just one element selected
+            if (bNodeFound)
             {
-              // If we already found a node, then we have another element,
-              //  thus there's not just one element selected
-              if (bNodeFound)
-              {
-                bNodeFound = false;
-                break;
-              }
-
-              selectedElement->GetNodeName(domTagName);
-              ToLowerCase(domTagName);
-
-              if (anyTag)
-              {
-                // Get name of first selected element
-                selectedElement->GetTagName(TagName);
-                ToLowerCase(TagName);
-                anyTag = false;
-              }
-
-              // The "A" tag is a pain,
-              //  used for both link(href is set) and "Named Anchor"
-              nsCOMPtr<nsIDOMNode> selectedNode = do_QueryInterface(selectedElement);
-              if ( (isLinkTag && nsHTMLEditUtils::IsLink(selectedNode)) ||
-                   (isNamedAnchorTag && nsHTMLEditUtils::IsNamedAnchor(selectedNode)) )
-              {
-                bNodeFound = true;
-              } else if (TagName == domTagName) { // All other tag names are handled here
-                bNodeFound = true;
-              }
-              if (!bNodeFound)
-              {
-                // Check if node we have is really part of the selection???
-                break;
-              }
+              bNodeFound = false;
+              break;
+            }
+
+            selectedElement->GetNodeName(domTagName);
+            ToLowerCase(domTagName);
+
+            if (anyTag)
+            {
+              // Get name of first selected element
+              selectedElement->GetTagName(TagName);
+              ToLowerCase(TagName);
+              anyTag = false;
             }
-            iter->Next();
+
+            // The "A" tag is a pain,
+            //  used for both link(href is set) and "Named Anchor"
+            nsCOMPtr<nsIDOMNode> selectedNode = do_QueryInterface(selectedElement);
+            if ( (isLinkTag && nsHTMLEditUtils::IsLink(selectedNode)) ||
+                (isNamedAnchorTag && nsHTMLEditUtils::IsNamedAnchor(selectedNode)) )
+            {
+              bNodeFound = true;
+            } else if (TagName == domTagName) { // All other tag names are handled here
+              bNodeFound = true;
+            }
+            if (!bNodeFound)
+            {
+              // Check if node we have is really part of the selection???
+              break;
+            }
           }
-        } else {
-          // Should never get here?
-          isCollapsed = true;
-          printf("isCollapsed was FALSE, but no elements found in selection\n");
+          iter->Next();
         }
       } else {
-        printf("Could not create enumerator for GetSelectionProperties\n");
+        // Should never get here?
+        isCollapsed = true;
+        NS_WARNING("isCollapsed was FALSE, but no elements found in selection\n");
       }
     }
   }
   if (bNodeFound)
   {
     
     *aReturn = selectedElement;
     if (selectedElement)
@@ -4673,33 +4645,23 @@ nsHTMLEditor::SetCSSBackgroundColor(cons
   nsAutoTxnsConserveSelection dontSpazMySelection(this);
   
   bool cancel, handled;
   nsTextRulesInfo ruleInfo(EditAction::setTextProperty);
   nsresult res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
   NS_ENSURE_SUCCESS(res, res);
   if (!cancel && !handled)
   {
-    // get selection range enumerator
-    nsCOMPtr<nsIEnumerator> enumerator;
-    res = selection->GetEnumerator(getter_AddRefs(enumerator));
-    NS_ENSURE_SUCCESS(res, res);
-    NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
-
     // loop thru the ranges in the selection
-    enumerator->First(); 
-    nsCOMPtr<nsISupports> currentItem;
     nsAutoString bgcolor; bgcolor.AssignLiteral("bgcolor");
-    nsCOMPtr<nsIDOMNode> cachedBlockParent = nullptr;
-    while (static_cast<nsresult>(NS_ENUMERATOR_FALSE) == enumerator->IsDone()) {
-      res = enumerator->CurrentItem(getter_AddRefs(currentItem));
-      NS_ENSURE_SUCCESS(res, res);
-      NS_ENSURE_TRUE(currentItem, NS_ERROR_FAILURE);
-      
-      nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
+    uint32_t rangeCount = selection->GetRangeCount();
+    for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
+      nsCOMPtr<nsIDOMNode> cachedBlockParent = nullptr;
+      nsRefPtr<nsRange> range = selection->GetRangeAt(rangeIdx);
+      NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
       
       // check for easy case: both range endpoints in same text node
       nsCOMPtr<nsIDOMNode> startNode, endNode;
       int32_t startOffset, endOffset;
       res = range->GetStartContainer(getter_AddRefs(startNode));
       NS_ENSURE_SUCCESS(res, res);
       res = range->GetEndContainer(getter_AddRefs(endNode));
       NS_ENSURE_SUCCESS(res, res);
@@ -4849,17 +4811,16 @@ nsHTMLEditor::SetCSSBackgroundColor(cons
             cachedBlockParent = blockParent;
             nsCOMPtr<nsIDOMElement> element = do_QueryInterface(blockParent);
             int32_t count;
             res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
             NS_ENSURE_SUCCESS(res, res);
           }
         }
       }
-      enumerator->Next();
     }
   }
   if (!cancel)
   {
     // post-process
     res = mRules->DidDoAction(selection, &ruleInfo, res);
   }
   return res;
--- a/editor/libeditor/html/nsHTMLEditorStyle.cpp
+++ b/editor/libeditor/html/nsHTMLEditorStyle.cpp
@@ -28,17 +28,16 @@
 #include "nsIContent.h"
 #include "nsIContentIterator.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMRange.h"
 #include "nsIEditor.h"
 #include "nsIEditorIMESupport.h"
-#include "nsIEnumerator.h"
 #include "nsINameSpaceManager.h"
 #include "nsINode.h"
 #include "nsISelection.h"
 #include "nsISelectionPrivate.h"
 #include "nsISupportsImpl.h"
 #include "nsLiteralString.h"
 #include "nsReadableUtils.h"
 #include "nsSelectionState.h"
@@ -139,32 +138,20 @@ nsHTMLEditor::SetInlineProperty(nsIAtom 
   nsAutoSelectionReset selectionResetter(selection, this);
   nsAutoTxnsConserveSelection dontSpazMySelection(this);
 
   bool cancel, handled;
   nsTextRulesInfo ruleInfo(EditAction::setTextProperty);
   nsresult res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
   NS_ENSURE_SUCCESS(res, res);
   if (!cancel && !handled) {
-    // get selection range enumerator
-    nsCOMPtr<nsIEnumerator> enumerator;
-    res = selection->GetEnumerator(getter_AddRefs(enumerator));
-    NS_ENSURE_SUCCESS(res, res);
-    NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
-
     // loop thru the ranges in the selection
-    nsCOMPtr<nsISupports> currentItem;
-    for (enumerator->First();
-         static_cast<nsresult>(NS_ENUMERATOR_FALSE) == enumerator->IsDone();
-         enumerator->Next()) {
-      res = enumerator->CurrentItem(getter_AddRefs(currentItem));
-      NS_ENSURE_SUCCESS(res, res);
-      NS_ENSURE_TRUE(currentItem, NS_ERROR_FAILURE);
-
-      nsCOMPtr<nsIDOMRange> range(do_QueryInterface(currentItem));
+    uint32_t rangeCount = selection->GetRangeCount();
+    for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
+      nsRefPtr<nsRange> range = selection->GetRangeAt(rangeIdx);
 
       // adjust range to include any ancestors whose children are entirely
       // selected
       res = PromoteInlineRange(range);
       NS_ENSURE_SUCCESS(res, res);
 
       // check for easy case: both range endpoints in same text node
       nsCOMPtr<nsIDOMNode> startNode, endNode;
@@ -1110,33 +1097,25 @@ nsHTMLEditor::GetInlinePropertyBase(nsIA
   *aAll = true;
   *aFirst = false;
   bool first = true;
 
   nsCOMPtr<nsISelection> selection;
   result = GetSelection(getter_AddRefs(selection));
   NS_ENSURE_SUCCESS(result, result);
   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
-  nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
+  Selection* sel = static_cast<Selection*>(selection.get());
 
   bool isCollapsed = selection->Collapsed();
   nsCOMPtr<nsIDOMNode> collapsedNode;
-  nsCOMPtr<nsIEnumerator> enumerator;
-  result = selPriv->GetEnumerator(getter_AddRefs(enumerator));
-  NS_ENSURE_SUCCESS(result, result);
-  NS_ENSURE_TRUE(enumerator, NS_ERROR_NULL_POINTER);
-
-  enumerator->First(); 
-  nsCOMPtr<nsISupports> currentItem;
-  result = enumerator->CurrentItem(getter_AddRefs(currentItem));
+  nsRefPtr<nsRange> range = sel->GetRangeAt(0);
   // XXX: should be a while loop, to get each separate range
   // XXX: ERROR_HANDLING can currentItem be null?
-  if (NS_SUCCEEDED(result) && currentItem) {
+  if (range) {
     bool firstNodeInRange = true; // for each range, set a flag 
-    nsCOMPtr<nsIDOMRange> range(do_QueryInterface(currentItem));
 
     if (isCollapsed) {
       range->GetStartContainer(getter_AddRefs(collapsedNode));
       NS_ENSURE_TRUE(collapsedNode, NS_ERROR_FAILURE);
       bool isSet, theSetting;
       nsString tOutString;
       if (aAttribute) {
         nsString tString(*aAttribute);
@@ -1374,32 +1353,20 @@ nsresult nsHTMLEditor::RemoveInlinePrope
   nsAutoTxnsConserveSelection dontSpazMySelection(this);
   
   bool cancel, handled;
   nsTextRulesInfo ruleInfo(EditAction::removeTextProperty);
   res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
   NS_ENSURE_SUCCESS(res, res);
   if (!cancel && !handled)
   {
-    // get selection range enumerator
-    nsCOMPtr<nsIEnumerator> enumerator;
-    res = selection->GetEnumerator(getter_AddRefs(enumerator));
-    NS_ENSURE_SUCCESS(res, res);
-    NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
-
     // loop thru the ranges in the selection
-    enumerator->First(); 
-    nsCOMPtr<nsISupports> currentItem;
-    while (static_cast<nsresult>(NS_ENUMERATOR_FALSE) == enumerator->IsDone()) {
-      res = enumerator->CurrentItem(getter_AddRefs(currentItem));
-      NS_ENSURE_SUCCESS(res, res);
-      NS_ENSURE_TRUE(currentItem, NS_ERROR_FAILURE);
-      
-      nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
-
+    uint32_t rangeCount = selection->GetRangeCount();
+    for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
+      nsRefPtr<nsRange> range = selection->GetRangeAt(rangeIdx);
       if (aProperty == nsEditProperty::name)
       {
         // promote range if it starts or end in a named anchor and we
         // want to remove named anchors
         res = PromoteRangeIfStartsOrEndsInNamedAnchor(range);
       }
       else {
         // adjust range to include any ancestors who's children are entirely selected
@@ -1495,17 +1462,16 @@ nsresult nsHTMLEditor::RemoveInlinePrope
                 nsAutoString value; value.AssignLiteral("-moz-editor-invert-value");
                 SetInlinePropertyOnNode(node, aProperty, aAttribute, &value);
               }
             }
           }
         }
         arrayOfNodes.Clear();
       }
-      enumerator->Next();
     }
   }
   if (!cancel)
   {
     // post-process 
     res = mRules->DidDoAction(selection, &ruleInfo, res);
   }
   return res;
@@ -1561,34 +1527,23 @@ nsHTMLEditor::RelativeFontChange( int32_
   }
   
   // wrap with txn batching, rules sniffing, and selection preservation code
   nsAutoEditBatch batchIt(this);
   nsAutoRules beginRulesSniffing(this, EditAction::setTextProperty, nsIEditor::eNext);
   nsAutoSelectionReset selectionResetter(selection, this);
   nsAutoTxnsConserveSelection dontSpazMySelection(this);
 
-  // get selection range enumerator
-  nsCOMPtr<nsIEnumerator> enumerator;
-  nsresult res = selection->GetEnumerator(getter_AddRefs(enumerator));
-  NS_ENSURE_SUCCESS(res, res);
-  NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
-
   // loop thru the ranges in the selection
-  enumerator->First(); 
-  nsCOMPtr<nsISupports> currentItem;
-  while (static_cast<nsresult>(NS_ENUMERATOR_FALSE) == enumerator->IsDone()) {
-    res = enumerator->CurrentItem(getter_AddRefs(currentItem));
-    NS_ENSURE_SUCCESS(res, res);
-    NS_ENSURE_TRUE(currentItem, NS_ERROR_FAILURE);
-    
-    nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
+  uint32_t rangeCount = selection->GetRangeCount();
+  for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
+    nsRefPtr<nsRange> range = selection->GetRangeAt(rangeIdx);
 
     // adjust range to include any ancestors who's children are entirely selected
-    res = PromoteInlineRange(range);
+    nsresult res = PromoteInlineRange(range);
     NS_ENSURE_SUCCESS(res, res);
     
     // check for easy case: both range endpoints in same text node
     nsCOMPtr<nsIDOMNode> startNode, endNode;
     res = range->GetStartContainer(getter_AddRefs(startNode));
     NS_ENSURE_SUCCESS(res, res);
     res = range->GetEndContainer(getter_AddRefs(endNode));
     NS_ENSURE_SUCCESS(res, res);
@@ -1660,20 +1615,19 @@ nsHTMLEditor::RelativeFontChange( int32_
       {
         nsCOMPtr<nsIDOMCharacterData> nodeAsText = do_QueryInterface(endNode);
         int32_t endOffset;
         range->GetEndOffset(&endOffset);
         res = RelativeFontChangeOnTextNode(aSizeChange, nodeAsText, 0, endOffset);
         NS_ENSURE_SUCCESS(res, res);
       }
     }
-    enumerator->Next();
   }
   
-  return res;  
+  return NS_OK;  
 }
 
 nsresult
 nsHTMLEditor::RelativeFontChangeOnTextNode( int32_t aSizeChange, 
                                             nsIDOMCharacterData *aTextNode, 
                                             int32_t aStartOffset,
                                             int32_t aEndOffset)
 {
--- a/embedding/tests/winEmbed/Makefile.in
+++ b/embedding/tests/winEmbed/Makefile.in
@@ -71,18 +71,14 @@ include $(topsrcdir)/config/rules.mk
 #
 # The default heap size is 1MB on Win32.
 # The heap will grow if need be.
 #
 # Set it to 256k.  See bug 127069.
 #
 ifndef GNU_CC
 LDFLAGS += /HEAP:0x40000
-ifeq ($(OS_TEST),x86_64)
-# set stack to 2MB on x64 build.  See bug 582910
-LDFLAGS += -STACK:2097152
-endif
 endif
 
 # Get rid of console window
 ifdef GNU_CC
 LDFLAGS += -mwindows
 endif
--- a/ipc/app/Makefile.in
+++ b/ipc/app/Makefile.in
@@ -72,20 +72,16 @@ ifeq ($(OS_ARCH),WINNT) #{
 #
 # The default heap size is 1MB on Win32.
 # The heap will grow if need be.
 #
 # Set it to 256k.  See bug 127069.
 #
 ifndef GNU_CC #{
 LDFLAGS += /HEAP:0x40000
-ifeq ($(OS_TEST),x86_64) #{
-# set stack to 2MB on x64 build.  See bug 582910
-LDFLAGS += -STACK:2097152
-endif #}
 endif #}
 endif #}
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) #{
 
 libs::
 	$(NSINSTALL) -D $(DIST)/bin/$(PROGRAM).app
 	rsync -a -C --exclude "*.in" $(srcdir)/macbuild/Contents $(DIST)/bin/$(PROGRAM).app 
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -584,16 +584,23 @@ ifdef GNU_CC
 WIN32_EXE_LDFLAGS	+= -mwindows
 else
 WIN32_EXE_LDFLAGS	+= -SUBSYSTEM:WINDOWS
 endif
 endif
 endif
 endif
 
+ifdef _MSC_VER
+ifeq ($(CPU_ARCH),x86_64)
+# set stack to 2MB on x64 build.  See bug 582910
+WIN32_EXE_LDFLAGS	+= -STACK:2097152
+endif
+endif
+
 # If we're building a component on MSVC, we don't want to generate an
 # import lib, because that import lib will collide with the name of a
 # static version of the same library.
 ifeq ($(GNU_LD)$(OS_ARCH),WINNT)
 ifdef IS_COMPONENT
 LDFLAGS += -IMPLIB:fake.lib
 DELETE_AFTER_LINK = fake.lib fake.exp
 endif
--- a/js/src/config/expandlibs_exec.py
+++ b/js/src/config/expandlibs_exec.py
@@ -262,16 +262,24 @@ class SectionFinder(object):
             # We only need to consider cases where "<section>\t<length> <symbol>" is present,
             # and where the [FfO] flag is either F (function) or O (object).
             if len(tmp) > 1 and len(tmp[1]) > 6 and tmp[1][6] in ['O', 'F']:
                 tmp = tmp[1][8:].split()
                 # That gives us ["<section>","<length>", "<symbol>"]
                 syms.append((tmp[-1], tmp[0]))
         return syms
 
+def print_command(out, args):
+    print >>out, "Executing: " + " ".join(args)
+    for tmp in [f for f in args.tmp if os.path.isfile(f)]:
+        print >>out, tmp + ":"
+        with open(tmp) as file:
+            print >>out, "".join(["    " + l for l in file.readlines()])
+    out.flush()
+
 def main():
     parser = OptionParser()
     parser.add_option("--depend", dest="depend", metavar="FILE",
         help="generate dependencies for the given execution and store it in the given file")
     parser.add_option("--target", dest="target", metavar="FILE",
         help="designate the target for dependencies")
     parser.add_option("--extract", action="store_true", dest="extract",
         help="when a library has no descriptor file, extract it first, when possible")
@@ -297,25 +305,25 @@ def main():
         if options.extract:
             args.extract()
         if options.symbol_order:
             args.orderSymbols(options.symbol_order)
         if options.uselist:
             args.makelist()
 
         if options.verbose:
-            print >>sys.stderr, "Executing: " + " ".join(args)
-            for tmp in [f for f in args.tmp if os.path.isfile(f)]:
-                print >>sys.stderr, tmp + ":"
-                with open(tmp) as file:
-                    print >>sys.stderr, "".join(["    " + l for l in file.readlines()])
-            sys.stderr.flush()
-        ret = subprocess.call(args)
-        if ret:
-            exit(ret)
+            print_command(sys.stderr, args)
+        proc = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
+        (stdout, stderr) = proc.communicate()
+        if proc.returncode and not options.verbose:
+            print_command(sys.stderr, args)
+        sys.stderr.write(stdout)
+        sys.stderr.flush()
+        if proc.returncode:
+            exit(proc.returncode)
     if not options.depend:
         return
     ensureParentDir(options.depend)
     with open(options.depend, 'w') as depfile:
         depfile.write("%s : %s\n" % (options.target, ' '.join(dep for dep in deps if os.path.isfile(dep) and dep != options.target)))
 
 
 if __name__ == '__main__':
--- a/js/src/ion/IonMacroAssembler.cpp
+++ b/js/src/ion/IonMacroAssembler.cpp
@@ -68,50 +68,94 @@ MacroAssembler::guardTypeSet(const T &ad
 template void MacroAssembler::guardTypeSet(const Address &address, const types::TypeSet *types,
                                            Register scratch, Label *mismatched);
 template void MacroAssembler::guardTypeSet(const ValueOperand &value, const types::TypeSet *types,
                                            Register scratch, Label *mismatched);
 
 void
 MacroAssembler::PushRegsInMask(RegisterSet set)
 {
-    size_t diff = set.gprs().size() * STACK_SLOT_SIZE +
-                  set.fpus().size() * sizeof(double);
-
-    reserveStack(diff);
+    int32_t diffF = set.fpus().size() * sizeof(double);
+    int32_t diffG = set.gprs().size() * STACK_SLOT_SIZE;
 
-    for (GeneralRegisterIterator iter(set.gprs()); iter.more(); iter++) {
-        diff -= STACK_SLOT_SIZE;
-        storePtr(*iter, Address(StackPointer, diff));
+    reserveStack(diffG);
+#ifdef JS_CPU_ARM
+    if (set.gprs().size() > 1) {
+        startDataTransferM(IsStore, StackPointer, IA, NoWriteBack);
+        for (GeneralRegisterIterator iter(set.gprs()); iter.more(); iter++) {
+            diffG -= STACK_SLOT_SIZE;
+            transferReg(*iter);
+        }
+        finishDataTransfer();
+    } else
+#endif
+    {
+        for (GeneralRegisterIterator iter(set.gprs()); iter.more(); iter++) {
+            diffG -= STACK_SLOT_SIZE;
+            storePtr(*iter, Address(StackPointer, diffG));
+        }
     }
+    JS_ASSERT(diffG == 0);
+
+    reserveStack(diffF);
+#ifdef JS_CPU_ARM
+    diffF -= transferMultipleByRuns(set.fpus(), IsStore, StackPointer, IA);
+#else
     for (FloatRegisterIterator iter(set.fpus()); iter.more(); iter++) {
-        diff -= sizeof(double);
-        storeDouble(*iter, Address(StackPointer, diff));
+        diffF -= sizeof(double);
+        storeDouble(*iter, Address(StackPointer, diffF));
     }
+#endif
+    JS_ASSERT(diffF == 0);
 }
 
 void
 MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore)
 {
-    size_t diff = set.gprs().size() * STACK_SLOT_SIZE +
-                  set.fpus().size() * sizeof(double);
-    size_t reserved = diff;
+    int32_t diffG = set.gprs().size() * STACK_SLOT_SIZE;
+    int32_t diffF = set.fpus().size() * sizeof(double);
+    const int32_t reservedG = diffG;
+    const int32_t reservedF = diffF;
 
-    for (GeneralRegisterIterator iter(set.gprs()); iter.more(); iter++) {
-        diff -= STACK_SLOT_SIZE;
-        if (!ignore.has(*iter))
-            loadPtr(Address(StackPointer, diff), *iter);
+#ifdef JS_CPU_ARM
+    // ARM can load multiple registers at once, but only if we want back all
+    // the registers we previously saved to the stack.
+    if (ignore.empty(true)) {
+        diffF -= transferMultipleByRuns(set.fpus(), IsLoad, StackPointer, IA);
+    } else
+#endif
+    {
+        for (FloatRegisterIterator iter(set.fpus()); iter.more(); iter++) {
+            diffF -= sizeof(double);
+            if (!ignore.has(*iter))
+                loadDouble(Address(StackPointer, diffF), *iter);
+        }
     }
-    for (FloatRegisterIterator iter(set.fpus()); iter.more(); iter++) {
-        diff -= sizeof(double);
-        if (!ignore.has(*iter))
-            loadDouble(Address(StackPointer, diff), *iter);
+    freeStack(reservedF);
+    JS_ASSERT(diffF == 0);
+
+#ifdef JS_CPU_ARM
+    if (set.gprs().size() > 1 && ignore.empty(false)) {
+        startDataTransferM(IsLoad, StackPointer, IA, NoWriteBack);
+        for (GeneralRegisterIterator iter(set.gprs()); iter.more(); iter++) {
+            diffG -= STACK_SLOT_SIZE;
+            transferReg(*iter);
+        }
+        finishDataTransfer();
+    } else
+#endif
+    {
+        for (GeneralRegisterIterator iter(set.gprs()); iter.more(); iter++) {
+            diffG -= STACK_SLOT_SIZE;
+            if (!ignore.has(*iter))
+                loadPtr(Address(StackPointer, diffG), *iter);
+        }
     }
-
-    freeStack(reserved);
+    freeStack(reservedG);
+    JS_ASSERT(diffG == 0);
 }
 
 template<typename T>
 void
 MacroAssembler::loadFromTypedArray(int arrayType, const T &src, AnyRegister dest, Register temp,
                                    Label *fail)
 {
     switch (arrayType) {
--- a/js/src/ion/RegisterSets.h
+++ b/js/src/ion/RegisterSets.h
@@ -313,16 +313,21 @@ class TypedRegisterSet
         return TypedRegisterSet(T::Codes::AllocatableMask & T::Codes::VolatileMask);
     }
     void intersect(TypedRegisterSet other) {
         bits_ &= ~other.bits_;
     }
     bool has(T reg) const {
         return !!(bits_ & (1 << reg.code()));
     }
+    bool hasNextRegister(T reg) const {
+        if (reg.code() == sizeof(bits_)*8)
+            return false;
+        return !!(bits_ & (1 << (reg.code()+1)));
+    }
     void addUnchecked(T reg) {
         bits_ |= (1 << reg.code());
     }
     void add(T reg) {
         JS_ASSERT(!has(reg));
         addUnchecked(reg);
     }
     // Determemine if some register are still allocated.  This function should
@@ -339,22 +344,33 @@ class TypedRegisterSet
         bits_ &= ~(1 << reg.code());
     }
     T getAny() const {
         JS_ASSERT(!empty());
         int ireg;
         JS_FLOOR_LOG2(ireg, bits_);
         return T::FromCode(ireg);
     }
+    T getFirst() const {
+        JS_ASSERT(!empty());
+        int ireg = js_bitscan_ctz32(bits_);
+        return T::FromCode(ireg);
+    }
     T takeAny() {
         JS_ASSERT(!empty());
         T reg = getAny();
         take(reg);
         return reg;
     }
+    T takeFirst() {
+        JS_ASSERT(!empty());
+        T reg = getFirst();
+        take(reg);
+        return reg;
+    }
     void clear() {
         bits_ = 0;
     }
     uint32_t bits() const {
         return bits_;
     }
     uint32_t size() const {
         uint32_t sum2  = (bits_ & 0x55555555) + ((bits_ & 0xaaaaaaaa) >> 1);
@@ -528,16 +544,17 @@ class RegisterSet {
     void maybeTake(TypedOrValueRegister reg) {
         if (reg.hasValue())
             maybeTake(reg.valueReg());
         else if (reg.hasTyped())
             maybeTake(reg.typedReg());
     }
 };
 
+// iterates backwards, that is, rn to r0
 template <typename T>
 class TypedRegisterIterator
 {
     TypedRegisterSet<T> regset_;
 
   public:
     TypedRegisterIterator(TypedRegisterSet<T> regset) : regset_(regset)
     { }
@@ -547,23 +564,58 @@ class TypedRegisterIterator
     bool more() const {
         return !regset_.empty();
     }
     TypedRegisterIterator<T> operator ++(int) {
         TypedRegisterIterator<T> old(*this);
         regset_.takeAny();
         return old;
     }
+    TypedRegisterIterator<T>& operator ++() {
+        regset_.takeAny();
+        return *this;
+    }
     T operator *() const {
         return regset_.getAny();
     }
 };
 
+// iterates forwards, that is r0 to rn
+template <typename T>
+class TypedRegisterForwardIterator
+{
+    TypedRegisterSet<T> regset_;
+
+  public:
+    TypedRegisterForwardIterator(TypedRegisterSet<T> regset) : regset_(regset)
+    { }
+    TypedRegisterForwardIterator(const TypedRegisterForwardIterator &other) : regset_(other.regset_)
+    { }
+
+    bool more() const {
+        return !regset_.empty();
+    }
+    TypedRegisterForwardIterator<T> operator ++(int) {
+        TypedRegisterIterator<T> old(*this);
+        regset_.takeFirst();
+        return old;
+    }
+    TypedRegisterForwardIterator<T>& operator ++() {
+        regset_.takeFirst();
+        return *this;
+    }
+    T operator *() const {
+        return regset_.getFirst();
+    }
+};
+
 typedef TypedRegisterIterator<Register> GeneralRegisterIterator;
 typedef TypedRegisterIterator<FloatRegister> FloatRegisterIterator;
+typedef TypedRegisterForwardIterator<Register> GeneralRegisterForwardIterator;
+typedef TypedRegisterForwardIterator<FloatRegister> FloatRegisterForwardIterator;
 
 class AnyRegisterIterator
 {
     GeneralRegisterIterator geniter_;
     FloatRegisterIterator floatiter_;
 
   public:
     AnyRegisterIterator()
--- a/js/src/ion/arm/MacroAssembler-arm.cpp
+++ b/js/src/ion/arm/MacroAssembler-arm.cpp
@@ -1378,16 +1378,47 @@ MacroAssemblerARM::ma_vstr(VFPRegister s
 }
 void
 MacroAssemblerARM::ma_vstr(VFPRegister src, Register base, Register index, int32_t shift, Condition cc)
 {
     as_add(ScratchRegister, base, lsl(index, shift), NoSetCond, cc);
     ma_vstr(src, Operand(ScratchRegister, 0), cc);
 }
 
+
+int32_t
+MacroAssemblerARM::transferMultipleByRuns(FloatRegisterSet set, LoadStore ls,
+                                          Register rm, DTMMode mode)
+{
+    int32_t delta;
+    if (mode == IA) {
+        delta = sizeof(double);
+    } else if (mode == DB) {
+        delta = -sizeof(double);
+    } else {
+        JS_NOT_REACHED("Invalid data transfer addressing mode");
+    }
+
+    int32_t offset = 0;
+    FloatRegisterForwardIterator iter(set);
+    while (iter.more()) {
+        startFloatTransferM(ls, rm, mode, WriteBack);
+        int32_t reg = (*iter).code_;
+        do {
+            offset += delta;
+            transferFloatReg(*iter);
+        } while ((++iter).more() && (*iter).code_ == ++reg);
+        finishFloatTransfer();
+    }
+
+    JS_ASSERT(offset == set.size() * sizeof(double) * (mode == DB ? -1 : 1));
+    ma_sub(Imm32(offset), rm);
+    return offset;
+}
+
 bool
 MacroAssemblerARMCompat::buildFakeExitFrame(const Register &scratch, uint32_t *offset)
 {
     DebugOnly<uint32_t> initialDepth = framePushed();
     uint32_t descriptor = MakeFrameDescriptor(framePushed(), IonFrame_OptimizedJS);
 
     Push(Imm32(descriptor)); // descriptor_
 
--- a/js/src/ion/arm/MacroAssembler-arm.h
+++ b/js/src/ion/arm/MacroAssembler-arm.h
@@ -325,16 +325,24 @@ class MacroAssemblerARM : public Assembl
     // calls an Ion function, assumes that the stack is untouched (8 byte alinged)
     void ma_callIon(const Register reg);
     // callso an Ion function, assuming that sp has already been decremented
     void ma_callIonNoPush(const Register reg);
     // calls an ion function, assuming that the stack is currently not 8 byte aligned
     void ma_callIonHalfPush(const Register reg);
 
     void ma_call(void *dest);
+
+    // Float registers can only be loaded/stored in continuous runs
+    // when using vstm/vldm.
+    // This function breaks set into continuous runs and loads/stores
+    // them at [rm]. rm will be modified, but returned to its initial value.
+    // Returns the offset from [dm] for the logical next load/store.
+    int32_t transferMultipleByRuns(FloatRegisterSet set, LoadStore ls,
+                                   Register rm, DTMMode mode);
 };
 
 class MacroAssemblerARMCompat : public MacroAssemblerARM
 {
     // Number of bytes the stack is adjusted inside a call to C. Calls to C may
     // not be nested.
     bool inCall_;
     uint32_t args_;
--- a/js/xpconnect/shell/Makefile.in
+++ b/js/xpconnect/shell/Makefile.in
@@ -47,23 +47,16 @@ LIBS		= \
 ifdef JS_SHARED_LIBRARY
 LIBS +=	$(MOZ_JS_LIBS)
 endif
 
 LIBS +=	$(NSPR_LIBS)
 
 NSDISTMODE = copy
 
-ifdef _MSC_VER
-ifeq ($(OS_TEST),x86_64)
-# set stack to 2MB on x64 build.  See bug 582910
-WIN32_EXE_LDFLAGS += -STACK:2097152
-endif
-endif
-
 ifeq ($(OS_TEST),ia64)
 LIBS += $(JEMALLOC_LIBS)
 endif
 include $(topsrcdir)/config/config.mk
 
 ifdef _MSC_VER
 # Always enter a Windows program through wmain, whether or not we're
 # a console application.
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -5300,20 +5300,20 @@ nsCSSFrameConstructor::AddFrameConstruct
       // Nothing to do here; suppressed text inside SVG
       return;
     }
   } else {
     Element* element = aContent->AsElement();
 
     // Don't create frames for non-SVG element children of SVG elements.
     if (aNameSpaceID != kNameSpaceID_SVG &&
-        aParentFrame &&
-        IsFrameForSVG(aParentFrame) &&
-        !aParentFrame->IsFrameOfType(nsIFrame::eSVGForeignObject)
-        ) {
+        ((aParentFrame &&
+          IsFrameForSVG(aParentFrame) &&
+          !aParentFrame->IsFrameOfType(nsIFrame::eSVGForeignObject)) ||
+         (aFlags & ITEM_IS_WITHIN_SVG_TEXT))) {
       SetAsUndisplayedContent(aItems, element, styleContext,
                               isGeneratedContent);
       return;
     }
 
     data = FindHTMLData(element, aTag, aNameSpaceID, aParentFrame,
                         styleContext);
     if (!data) {
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -1600,21 +1600,24 @@ nsDisplayBackgroundImage::AppendBackgrou
   nscolor color;
   if (!nsCSSRendering::IsCanvasFrame(aFrame) && bg) {
     bool drawBackgroundImage;
     color =
       nsCSSRendering::DetermineBackgroundColor(presContext, bgSC, aFrame,
                                                drawBackgroundImage, drawBackgroundColor);
   }
 
-  // Even if we don't actually have a background color to paint, we still need
-  // to create the item because it's used for hit testing.
-  aList->AppendNewToTop(
-      new (aBuilder) nsDisplayBackgroundColor(aBuilder, aFrame, bg,
-                                              drawBackgroundColor ? color : NS_RGBA(0, 0, 0, 0)));
+  // Even if we don't actually have a background color to paint, we may still need
+  // to create an item for hit testing.
+  if ((drawBackgroundColor && color != NS_RGBA(0,0,0,0)) ||
+      aBuilder->IsForEventDelivery()) {
+    aList->AppendNewToTop(
+        new (aBuilder) nsDisplayBackgroundColor(aBuilder, aFrame, bg,
+                                                drawBackgroundColor ? color : NS_RGBA(0, 0, 0, 0)));
+  }
 
   if (isThemed) {
     nsDisplayBackgroundImage* bgItem =
       new (aBuilder) nsDisplayBackgroundImage(aBuilder, aFrame, 0, isThemed, nullptr);
     nsresult rv = aList->AppendNewToTop(bgItem);
     if (rv != NS_OK) {
       return rv;
     }
--- a/layout/reftests/css-gradients/reftest.list
+++ b/layout/reftests/css-gradients/reftest.list
@@ -119,17 +119,17 @@ fails-if(!d2d) == aja-linear-2d.html aja
 fuzzy-if(!contentSameGfxBackendAsCanvas,1,19999) fails-if(Android) == aja-linear-3a.html aja-linear-3-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,1,19999) fails-if(Android) == aja-linear-3b.html aja-linear-3-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,2,20000) fails-if(Android) == aja-linear-4a.html aja-linear-4-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,2,20000) fails-if(Android) == aja-linear-4b.html aja-linear-4-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,2,20000) fails-if(Android) == aja-linear-5a.html aja-linear-5-ref.html
 fuzzy-if(!contentSameGfxBackendAsCanvas,2,16477) fails-if(Android) == aja-linear-6a.html aja-linear-6-ref.html # bug 526708
 fails == aja-linear-6b.html aja-linear-6-ref.html # bug 522607
 skip-if(B2G) == height-dependence-1.html height-dependence-1-ref.html
-skip-if(B2G) == height-dependence-2.html height-dependence-2-ref.html
+skip-if(B2G) fuzzy-if(cocoaWidget,1,40000) == height-dependence-2.html height-dependence-2-ref.html
 skip-if(B2G) == height-dependence-3.html height-dependence-3-ref.html
 
 fails-if(d2d) == linear-onestopposition-1.html linear-onestopposition-1-ref.html # bug 638664
 == linear-onestopposition-1.html linear-onestopposition-1-ref2.html
 fails-if(d2d) fails-if(cocoaWidget) == radial-onestopposition-1a.html radial-onestopposition-1-ref.html # bug 638664
 fails-if(d2d) fails-if(cocoaWidget) == radial-onestopposition-1b.html radial-onestopposition-1-ref.html # bug 638664
 fails-if(d2d) fails-if(cocoaWidget) == radial-onestopposition-1c.html radial-onestopposition-1-ref.html # bug 638664
 == repeating-linear-onestopposition-1.html orange-square.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/text/display-none-4.svg
@@ -0,0 +1,9 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="700" height="200" viewBox="0 0 700 200"
+     style="font: 16px sans-serif">
+  <text x="100" y="100">hello</text>
+  <text x="100" y="200"><textPath display="none">f</textPath></text>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/text/ignore-invalid-child-2-ref.svg
@@ -0,0 +1,12 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="700" height="200">
+  <text x="100" y="100" style="font: 16px sans-serif">
+    <tspan>
+      ab
+      ef
+    </tspan>
+  </text>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/text/ignore-invalid-child-2.svg
@@ -0,0 +1,13 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="700" height="200">
+  <text x="100" y="100" style="font: 16px sans-serif">
+    <tspan>
+      ab
+      <progress xmlns="http://www.w3.org/1999/xhtml">cd</progress>
+      ef
+    </tspan>
+  </text>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/text/pseudo-first-letter-2-ref.svg
@@ -0,0 +1,7 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="700" height="200">
+  <text x="100" y="100" style="font: 16px sans-serif">&#x0301;t</text>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/text/pseudo-first-letter-2.svg
@@ -0,0 +1,10 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="700" height="200">
+  <style>
+    text::first-letter { font-size: 32px }
+  </style>
+  <text x="100" y="100" style="font: 16px sans-serif">&#x0301;t</text>
+</svg>
--- a/layout/reftests/svg/text/reftest.list
+++ b/layout/reftests/svg/text/reftest.list
@@ -94,16 +94,17 @@ HTTP(../..) == simple-transform-rotate.s
 == multiple-chunks-multiple-dx-rtl.svg multiple-chunks-multiple-dx-rtl-ref.svg
 == multiple-chunks-multiple-dx.svg multiple-chunks-multiple-dx-ref.svg
 == multiple-chunks-rtl.svg multiple-chunks-rtl-ref.svg
 == multiple-chunks.svg multiple-chunks-ref.svg
 
 == display-none-1.svg simple.svg
 == display-none-2.svg simple.svg
 == display-none-3.svg simple.svg
+== display-none-4.svg simple.svg
 
 == simple-multiline.svg simple-multiline-ref.svg
 == simple-multiline-number.svg simple-multiline-number-ref.svg
 == simple-multiline-pc.svg simple-multiline-pc-ref.svg
 == simple-multiline-anchor-end.svg simple-multiline-anchor-end-ref.svg
 
 == textpath.svg textpath-ref.svg
 == textpath-a.svg textpath-a-ref.svg
@@ -128,20 +129,22 @@ HTTP(../..) == simple-transform-rotate.s
 == ignore-overflow-scroll.svg ignore-prop-ref.svg
 == ignore-text-align.svg ignore-prop-ref.svg
 == ignore-text-align-2.svg ignore-text-align-2-ref.svg
 
 # pseudo-elements
 == pseudo-first-line.svg pseudo-first-line-ref.svg
 == pseudo-first-line-2.svg pseudo-first-line-2-ref.svg
 == pseudo-first-letter.svg pseudo-first-letter-ref.svg
+== pseudo-first-letter-2.svg pseudo-first-letter-2-ref.svg
 == ignore-before-after.svg ignore-prop-ref.svg
 
 # invalid child nodes
 == ignore-invalid-child.svg ignore-invalid-child-ref.svg
+== ignore-invalid-child-2.svg ignore-invalid-child-2-ref.svg
 
 # text inside a link
 == link-surrounding.svg simple.svg
 
 # dynamic document changes
 == dynamic-font-size.svg dynamic-font-size-ref.svg
 == dynamic-dominant-baseline.svg dynamic-dominant-baseline-ref.svg
 == dynamic-multiple-x.svg dynamic-multiple-x-ref.svg
--- a/layout/svg/nsSVGTextFrame2.cpp
+++ b/layout/svg/nsSVGTextFrame2.cpp
@@ -268,21 +268,17 @@ IsTextContentElement(nsIContent* aConten
 static bool
 IsNonEmptyTextFrame(nsIFrame* aFrame)
 {
   nsTextFrame* textFrame = do_QueryFrame(aFrame);
   if (!textFrame) {
     return false;
   }
 
-  nsIContent* content = textFrame->GetContent();
-  NS_ASSERTION(content && content->IsNodeOfType(nsINode::eTEXT),
-               "unexpected content type for nsTextFrame");
-
-  return static_cast<nsTextNode*>(content)->TextLength() != 0;
+  return textFrame->GetContentLength() != 0;
 }
 
 /**
  * Takes an nsIFrame and if it is a text frame that has some text content,
  * returns it as an nsTextFrame and its corresponding nsTextNode.
  *
  * @param aFrame The frame to look at.
  * @param aTextFrame aFrame as an nsTextFrame (output).
@@ -1435,16 +1431,19 @@ TextNodeCorrespondenceRecorder::Traverse
  * current nsTextFrame:
  *
  *   * how many undisplayed characters came just before it
  *   * its position (in app units) relative to the nsSVGTextFrame2's anonymous
  *     block frame
  *   * what nsInlineFrame corresponding to a <textPath> element it is a
  *     descendant of
  *   * what computed dominant-baseline value applies to it
+ *
+ * Note that any text frames that are empty -- whose ContentLength() is 0 --
+ * will be skipped over.
  */
 class TextFrameIterator
 {
 public:
   /**
    * Constructs a TextFrameIterator for the specified nsSVGTextFrame2
    * with an optional frame subtree to restrict iterated text frames to.
    */
@@ -4419,19 +4418,19 @@ nsSVGTextFrame2::DoGlyphPositioning()
     return;
   }
 
   nsPresContext* presContext = PresContext();
 
   // Get the x, y, dx, dy, rotate values for the subtree.
   nsTArray<gfxPoint> deltas;
   if (!ResolvePositions(deltas)) {
-    // We shouldn't reach here because DetermineCharPositions should have been
-    // empty if we fail to resolve any positions.
-    NS_NOTREACHED("unexpected result from ResolvePositions");
+    // If ResolvePositions returned false, it means that there were some
+    // characters in the DOM but none of them are displayed.  Clear out
+    // mPositions so that we don't attempt to do any painting later.
     mPositions.Clear();
     return;
   }
 
   // XXX We might be able to do less work when there is at most a single
   // x/y/dx/dy position.
 
   // Truncate the positioning arrays to the actual number of characters present.
--- a/mobile/xul/installer/package-manifest.in
+++ b/mobile/xul/installer/package-manifest.in
@@ -123,17 +123,16 @@
 #endif
 
 ; [Components]
 @BINPATH@/components/components.manifest
 @BINPATH@/components/alerts.xpt
 #ifdef ACCESSIBILITY
 #ifdef XP_WIN32
 @BINPATH@/AccessibleMarshal.dll
-@BINPATH@/components/accessibility-msaa.xpt
 #endif
 @BINPATH@/components/accessibility.xpt
 #endif
 @BINPATH@/components/appshell.xpt
 @BINPATH@/components/appstartup.xpt
 @BINPATH@/components/autocomplete.xpt
 @BINPATH@/components/autoconfig.xpt
 @BINPATH@/components/browsercompsbase.xpt
--- a/modules/libbz2/src/Makefile.in
+++ b/modules/libbz2/src/Makefile.in
@@ -38,18 +38,12 @@ CSRCS		= \
 HOST_CSRCS	= $(CSRCS)
 
 EXPORTS		= \
 		bzlib.h \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
-ifdef CROSS_COMPILE
-ifdef HOST_NSPR_MDCPUCFG
-HOST_CFLAGS    += -DMDCPUCFG=$(HOST_NSPR_MDCPUCFG)
-endif
-endif
-
 # The intermediate (.ii/.s) files for host and target can have the same name...
 # disable parallel builds
 .NOTPARALLEL:
 
--- a/modules/libmar/src/Makefile.in
+++ b/modules/libmar/src/Makefile.in
@@ -34,17 +34,11 @@ CSRCS		= \
 
 EXPORTS		= \
 		mar.h \
 		mar_cmdline.h \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
-ifdef CROSS_COMPILE
-ifdef HOST_NSPR_MDCPUCFG
-HOST_CFLAGS     += -DMDCPUCFG=$(HOST_NSPR_MDCPUCFG)
-endif
-endif
-
 # The intermediate (.ii/.s) files for host and target can have the same name...
 # disable parallel builds
 .NOTPARALLEL:
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -705,17 +705,17 @@ pref("dom.min_timeout_value", 4);
 // And for background windows
 pref("dom.min_background_timeout_value", 1000);
 
 // Use the new DOM bindings (only affects any scopes created after the pref is
 // changed)
 pref("dom.experimental_bindings", true);
 
 // Run content XBL in a separate scope.
-pref("dom.xbl_scopes", false);
+pref("dom.xbl_scopes", true);
 
 // Don't use new input types
 pref("dom.experimental_forms", false);
 
 // Don't enable <input type=range> yet:
 pref("dom.experimental_forms_range", false);
 
 // Allocation Threshold for Workers
--- a/testing/marionette/marionette-listener.js
+++ b/testing/marionette/marionette-listener.js
@@ -293,22 +293,21 @@ function resetValues() {
 /*
  * Marionette Methods
  */
 
 /**
  * Returns a content sandbox that can be used by the execute_foo functions.
  */
 function createExecuteContentSandbox(aWindow, timeout) {
-  let sandbox = new Cu.Sandbox(aWindow);
+  let sandbox = new Cu.Sandbox(aWindow, {sandboxPrototype: aWindow});
   sandbox.global = sandbox;
   sandbox.window = aWindow;
   sandbox.document = sandbox.window.document;
   sandbox.navigator = sandbox.window.navigator;
-  sandbox.__proto__ = sandbox.window;
   sandbox.testUtils = utils;
 
   let marionette = new Marionette(this, aWindow, "content",
                                   marionetteLogObj, marionettePerf,
                                   timeout, marionetteTestName);
   sandbox.marionette = marionette;
   marionette.exports.forEach(function(fn) {
     try {
--- a/toolkit/components/social/FrameWorker.jsm
+++ b/toolkit/components/social/FrameWorker.jsm
@@ -125,22 +125,28 @@ FrameWorker.prototype = {
     // copy the window apis onto the sandbox namespace only functions or
     // objects that are naturally a part of an iframe, I'm assuming they are
     // safe to import this way
     let workerAPI = ['WebSocket', 'localStorage', 'atob', 'btoa',
                      'clearInterval', 'clearTimeout', 'dump',
                      'setInterval', 'setTimeout', 'XMLHttpRequest',
                      'MozBlobBuilder', 'FileReader', 'Blob',
                      'location'];
+    // Bug 798660 - XHR and WebSocket have issues in a sandbox and need
+    // to be unwrapped to work
+    let needsWaive = ['XMLHttpRequest', 'WebSocket'];
+    // Methods need to be bound with the proper |this|.
+    let needsBind = ['atob', 'btoa', 'dump', 'setInterval', 'clearInterval',
+                     'setTimeout', 'clearTimeout'];
     workerAPI.forEach(function(fn) {
       try {
-        // Bug 798660 - XHR and WebSocket have issues in a sandbox and need
-        // to be unwrapped to work
-        if (fn == "XMLHttpRequest" || fn == "WebSocket")
+        if (needsWaive.indexOf(fn) != -1)
           sandbox[fn] = XPCNativeWrapper.unwrap(workerWindow)[fn];
+        else if (needsBind.indexOf(fn) != -1)
+          sandbox[fn] = workerWindow[fn].bind(workerWindow);
         else
           sandbox[fn] = workerWindow[fn];
       }
       catch(e) {
         Cu.reportError("FrameWorker: failed to import API "+fn+"\n"+e+"\n");
       }
     });
     // the "navigator" object in a worker is a subset of the full navigator;
--- a/toolkit/mozapps/shared/CertUtils.jsm
+++ b/toolkit/mozapps/shared/CertUtils.jsm
@@ -103,17 +103,17 @@ this.validateCert =
       }
     }
 
     if (!error)
       break;
   }
 
   if (error) {
-    errors.forEach(Cu.reportError);
+    errors.forEach(Cu.reportError.bind(Cu));
     const certCheckErr = "Certificate checks failed. See previous errors " +
                          "for details.";
     Cu.reportError(certCheckErr);
     throw new Ce(certCheckErr, Cr.NS_ERROR_ILLEGAL_VALUE);
   }
 }
 
 /**
--- a/toolkit/toolkit-tiers.mk
+++ b/toolkit/toolkit-tiers.mk
@@ -1,17 +1,23 @@
 # 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/.
 
 ifdef LIBXUL_SDK
 $(error toolkit-tiers.mk is not compatible with --enable-libxul-sdk=)
 endif
 
-include $(topsrcdir)/config/nspr/build.mk
+TIERS += nspr
+
+ifndef MOZ_NATIVE_NSPR
+tier_nspr_staticdirs += nsprpub
+tier_nspr_dirs += config/nspr
+endif
+
 include $(topsrcdir)/config/js/build.mk
 
 TIERS += platform
 
 ifdef NS_TRACE_MALLOC
 tier_platform_dirs = tools/trace-malloc/lib
 endif
 
--- a/tools/update-packaging/build.mk
+++ b/tools/update-packaging/build.mk
@@ -1,13 +1,11 @@
 # 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/nspr/build.mk
-
 TIERS += app
 
 tier_app_dirs += \
 	modules/libbz2 \
 	modules/libmar \
 	other-licenses/bsdiff \
 	$(NULL)
--- a/webapprt/win/Makefile.in
+++ b/webapprt/win/Makefile.in
@@ -108,13 +108,9 @@ webapprt.$(OBJ_SUFFIX): $(DEPTH)/config/
 #
 # The default heap size is 1MB on Win32.
 # The heap will grow if need be.
 #
 # Set it to 256k.  See bug 127069.
 #
 ifndef GNU_CC
 LDFLAGS += /HEAP:0x40000
-ifeq ($(OS_TEST),x86_64)
-# set stack to 2MB on x64 build.  See bug 582910
-LDFLAGS += -STACK:2097152
 endif
-endif
--- a/xulrunner/app/Makefile.in
+++ b/xulrunner/app/Makefile.in
@@ -100,20 +100,16 @@ ifeq ($(OS_ARCH),WINNT)
 #
 # The default heap size is 1MB on Win32.
 # The heap will grow if need be.
 #
 # Set it to 256k.  See bug 127069.
 #
 ifndef GNU_CC
 LDFLAGS += /HEAP:0x40000
-ifeq ($(OS_TEST),x86_64)
-# set stack to 2MB on x64 build.  See bug 582910
-LDFLAGS += -STACK:2097152
-endif
 endif
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 libs::
 	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default16.png $(DIST)/bin/chrome/icons/default
 	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default32.png $(DIST)/bin/chrome/icons/default
 	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default48.png $(DIST)/bin/chrome/icons/default