Merge inbound to mozilla-central. a=merge
authorNoemi Erli <nerli@mozilla.com>
Mon, 01 Oct 2018 12:41:32 +0300
changeset 438941 cc0bf89a7eebcc6e7a0da4275eeb19c88f886127
parent 438940 4d1100cb4561921a56da3ce37ad189cea9e3212c (current diff)
parent 438932 4e879c661c84d27e657d10425229232f9798c7cd (diff)
child 438942 f9a8321c1ed7a38a3e9e5eb06506b875ddad2dd4
child 438970 ae8dab184763bbd5038e0faf0e66cec57cd3d42e
push id108449
push usernerli@mozilla.com
push dateMon, 01 Oct 2018 09:48:26 +0000
treeherdermozilla-inbound@f9a8321c1ed7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone64.0a1
first release with
nightly linux32
cc0bf89a7eeb / 64.0a1 / 20181001100147 / files
nightly linux64
cc0bf89a7eeb / 64.0a1 / 20181001100147 / files
nightly mac
cc0bf89a7eeb / 64.0a1 / 20181001100147 / files
nightly win32
cc0bf89a7eeb / 64.0a1 / 20181001100147 / files
nightly win64
cc0bf89a7eeb / 64.0a1 / 20181001100147 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
--- a/devtools/client/canvasdebugger/test/browser_canvas-frontend-call-list.js
+++ b/devtools/client/canvasdebugger/test/browser_canvas-frontend-call-list.js
@@ -48,17 +48,17 @@ async function ifTestingSupported() {
 
     is($(".call-item-index", item.target).getAttribute("value"), index,
       "The item's gutter label has the correct text.");
 
     if (context) {
       is($(".call-item-context", item.target).getAttribute("value"), context,
         "The item's context label has the correct text.");
     } else {
-      is($(".call-item-context", item.target) + "", "[object XULElement]",
+      is($(".call-item-context", item.target) + "", "[object XULTextElement]",
         "The item's context label should not be available.");
     }
 
     is($(".call-item-name", item.target).getAttribute("value"), name,
       "The item's name label has the correct text.");
     is($(".call-item-args", item.target).getAttribute("value"), args,
       "The item's args label has the correct text.");
     is($(".call-item-location", item.target).getAttribute("value"), location,
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -49,16 +49,17 @@
 #include "mozilla/dom/HTMLObjectElementBinding.h"
 #include "mozilla/dom/HTMLEmbedElement.h"
 #include "mozilla/dom/HTMLElementBinding.h"
 #include "mozilla/dom/HTMLEmbedElementBinding.h"
 #include "mozilla/dom/XULElementBinding.h"
 #include "mozilla/dom/XULFrameElementBinding.h"
 #include "mozilla/dom/XULMenuElementBinding.h"
 #include "mozilla/dom/XULPopupElementBinding.h"
+#include "mozilla/dom/XULTextElementBinding.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/ResolveSystemBinding.h"
 #include "mozilla/dom/WebIDLGlobalNameHash.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerScope.h"
 #include "mozilla/dom/XrayExpandoClass.h"
 #include "mozilla/dom/XULScrollElementBinding.h"
 #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
@@ -3865,20 +3866,23 @@ HTMLConstructor(JSContext* aCx, unsigned
   // Steps 4 and 5 do some sanity checks on our callee.  We add to those a
   // determination of what sort of element we're planning to construct.
   // Technically, this should happen (implicitly) in step 8, but this
   // determination is side-effect-free, so it's OK.
   int32_t ns = definition->mNamespaceID;
 
   constructorGetterCallback cb = nullptr;
   if (ns == kNameSpaceID_XUL) {
-    if (definition->mLocalName == nsGkAtoms::menupopup ||
-        definition->mLocalName == nsGkAtoms::popup ||
-        definition->mLocalName == nsGkAtoms::panel ||
-        definition->mLocalName == nsGkAtoms::tooltip) {
+    if (definition->mLocalName == nsGkAtoms::description ||
+        definition->mLocalName == nsGkAtoms::label) {
+      cb = XULTextElement_Binding::GetConstructorObject;
+    } else if (definition->mLocalName == nsGkAtoms::menupopup ||
+               definition->mLocalName == nsGkAtoms::popup ||
+               definition->mLocalName == nsGkAtoms::panel ||
+               definition->mLocalName == nsGkAtoms::tooltip) {
       cb = XULPopupElement_Binding::GetConstructorObject;
     } else if (definition->mLocalName == nsGkAtoms::iframe ||
                 definition->mLocalName == nsGkAtoms::browser ||
                 definition->mLocalName == nsGkAtoms::editor) {
       cb = XULFrameElement_Binding::GetConstructorObject;
     } else if (definition->mLocalName == nsGkAtoms::menu ||
                definition->mLocalName == nsGkAtoms::menulist) {
       cb = XULMenuElement_Binding::GetConstructorObject;
new file mode 100644
--- /dev/null
+++ b/dom/chrome-webidl/XULTextElement.webidl
@@ -0,0 +1,12 @@
+
+/* -*- Mode: IDL; 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/.
+ */
+
+[HTMLConstructor, Func="IsChromeOrXBL"]
+interface XULTextElement : XULElement {
+  attribute boolean disabled;
+  attribute DOMString value;
+};
--- a/dom/chrome-webidl/moz.build
+++ b/dom/chrome-webidl/moz.build
@@ -46,17 +46,18 @@ WEBIDL_FILES = [
     'MozStorageStatementRow.webidl',
     'PrecompiledScript.webidl',
     'PromiseDebugging.webidl',
     'StructuredCloneHolder.webidl',
     'WebExtensionContentScript.webidl',
     'WebExtensionPolicy.webidl',
     'XULFrameElement.webidl',
     'XULMenuElement.webidl',
-    'XULScrollElement.webidl'
+    'XULScrollElement.webidl',
+    'XULTextElement.webidl'
 ]
 
 if CONFIG['MOZ_PLACES']:
     WEBIDL_FILES += [
         'PlacesEvent.webidl',
         'PlacesObservers.webidl',
     ]
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -3206,16 +3206,35 @@ TabChild::InvalidateLayers()
   MOZ_ASSERT(mPuppetWidget);
   RefPtr<LayerManager> lm = mPuppetWidget->GetLayerManager();
   MOZ_ASSERT(lm);
 
   FrameLayerBuilder::InvalidateAllLayers(lm);
 }
 
 void
+TabChild::SchedulePaint()
+{
+  nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
+  if (!docShell) {
+    return;
+  }
+
+  // We don't use TabChildBase::GetPresShell() here because that would create
+  // a content viewer if one doesn't exist yet. Creating a content viewer can
+  // cause JS to run, which we want to avoid. nsIDocShell::GetPresShell
+  // returns null if no content viewer exists yet.
+  if (nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell()) {
+    if (nsIFrame* root = presShell->GetRootFrame()) {
+      root->SchedulePaint();
+    }
+  }
+}
+
+void
 TabChild::ReinitRendering()
 {
   MOZ_ASSERT(mLayersId.IsValid());
 
   // Before we establish a new PLayerTransaction, we must connect our layer tree
   // id, CompositorBridge, and the widget compositor all together again.
   // Normally this happens in TabParent before TabChild is given rendering
   // information.
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -535,16 +535,17 @@ public:
                     const TimeStamp& aCompositeStart,
                     const TimeStamp& aCompositeEnd);
 
   void DidRequestComposite(const TimeStamp& aCompositeReqStart,
                            const TimeStamp& aCompositeReqEnd);
 
   void ClearCachedResources();
   void InvalidateLayers();
+  void SchedulePaint();
   void ReinitRendering();
   void ReinitRenderingForDeviceReset();
 
   static inline TabChild* GetFrom(nsIDOMWindow* aWindow)
   {
     nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
     nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(webNav);
     return GetFrom(docShell);
--- a/dom/tests/mochitest/chrome/chrome.ini
+++ b/dom/tests/mochitest/chrome/chrome.ini
@@ -49,16 +49,17 @@ tags = openwindow
 skip-if = os != 'mac'
 [test_bug1224790-2.xul]
 tags = openwindow
 skip-if = os != 'mac'
 [test_callback_wrapping.xul]
 [test_clonewrapper.xul]
 [test_cyclecollector.xul]
 [test_docshell_swap.xul]
+[test_elements_proto.xul]
 [test_focus.xul]
 skip-if = os == 'linux' && !debug # bug 1296622
 [test_focus_docnav.xul]
 [test_focus_switchbinding.xul]
 [test_focused_link_scroll.xul]
 [test_fullscreen.xul]
 tags = fullscreen
 # disabled on linux for timeouts--bug-867745
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/chrome/test_elements_proto.xul
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+
+<window title="Mozilla Bug 861493"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  </body>
+
+  <script type="application/javascript">
+  <![CDATA[
+    const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+
+    SimpleTest.waitForExplicitFinish();
+
+    addLoadEvent(() => {
+      is(Object.getPrototypeOf(document.createElementNS(XUL_NS, "label")),
+         XULTextElement.prototype,
+        `<label> should be of XULTextElement type`);
+
+      is(Object.getPrototypeOf(document.createElementNS(XUL_NS, "description")),
+         XULTextElement.prototype,
+        `<description> should be of XULTextElement type`);
+
+      SimpleTest.finish();
+    });
+  ]]>
+  </script>
+</window>
--- a/dom/tests/mochitest/general/test_interfaces.js
+++ b/dom/tests/mochitest/general/test_interfaces.js
@@ -1258,16 +1258,18 @@ var interfaceNamesInGlobalScope =
     {name: "XULFrameElement", insecureContext: true, xbl: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "XULMenuElement", insecureContext: true, xbl: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "XULPopupElement", insecureContext: true, xbl: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "XULScrollElement", insecureContext: true, xbl: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
+    {name: "XULTextElement", insecureContext: true, xbl: true},
+// IMPORTANT: Do not change this list without review from a DOM peer!
   ];
 // IMPORTANT: Do not change the list above without review from a DOM peer!
 
 function createInterfaceMap(isXBLScope) {
   var interfaceMap = {};
 
   function addInterfaces(interfaces)
   {
new file mode 100644
--- /dev/null
+++ b/dom/xul/XULTextElement.cpp
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/dom/Element.h"
+#include "mozilla/dom/ToJSValue.h"
+#include "nsCOMPtr.h"
+#include "nsIPresShell.h"
+#include "nsIContent.h"
+#include "nsPresContext.h"
+#include "nsBox.h"
+#include "nsIScrollableFrame.h"
+#include "mozilla/dom/XULTextElement.h"
+#include "mozilla/dom/XULTextElementBinding.h"
+
+namespace mozilla {
+namespace dom {
+
+JSObject*
+XULTextElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return XULTextElement_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/xul/XULTextElement.h
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef XULTextElement_h__
+#define XULTextElement_h__
+
+#include "nsXULElement.h"
+
+namespace mozilla {
+namespace dom {
+
+
+class XULTextElement final : public nsXULElement
+{
+public:
+  explicit XULTextElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsXULElement(std::move(aNodeInfo))
+  {
+  }
+
+  bool Disabled()
+  {
+    return GetXULBoolAttr(nsGkAtoms::disabled);
+  }
+  MOZ_CAN_RUN_SCRIPT void SetDisabled(bool aValue)
+  {
+    SetXULBoolAttr(nsGkAtoms::disabled, aValue);
+  }
+  void GetValue(DOMString& aValue) const
+  {
+    GetXULAttr(nsGkAtoms::value, aValue);
+  }
+  MOZ_CAN_RUN_SCRIPT void SetValue(const nsAString& aValue)
+  {
+    SetAttr(kNameSpaceID_None, nsGkAtoms::value, aValue, true);
+  }
+
+protected:
+  virtual ~XULTextElement() {}
+  JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) final;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // XULTextElement_h
--- a/dom/xul/moz.build
+++ b/dom/xul/moz.build
@@ -21,32 +21,34 @@ if CONFIG['MOZ_XUL']:
         'nsXULSortService.h',
     ]
 
     EXPORTS.mozilla.dom += [
         'XULFrameElement.h',
         'XULMenuElement.h',
         'XULPopupElement.h',
         'XULScrollElement.h',
+        'XULTextElement.h'
     ]
 
     UNIFIED_SOURCES += [
         'nsXULCommandDispatcher.cpp',
         'nsXULContentSink.cpp',
         'nsXULContentUtils.cpp',
         'nsXULElement.cpp',
         'nsXULPopupListener.cpp',
         'nsXULPrototypeCache.cpp',
         'nsXULPrototypeDocument.cpp',
         'nsXULSortService.cpp',
         'XULDocument.cpp',
         'XULFrameElement.cpp',
         'XULMenuElement.cpp',
         'XULPopupElement.cpp',
         'XULScrollElement.cpp',
+        'XULTextElement.cpp'
     ]
 
 XPIDL_SOURCES += [
     'nsIController.idl',
     'nsIControllers.idl',
 ]
 
 XPIDL_MODULE = 'xul'
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -141,16 +141,21 @@ nsXULElement* NS_NewBasicXULElement(alre
 {
     return new nsXULElement(std::move(aNodeInfo));
 }
 
  /* static */
 nsXULElement* nsXULElement::Construct(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
 {
   RefPtr<mozilla::dom::NodeInfo> nodeInfo = aNodeInfo;
+  if (nodeInfo->Equals(nsGkAtoms::label) ||
+      nodeInfo->Equals(nsGkAtoms::description)) {
+    return new XULTextElement(nodeInfo.forget());
+  }
+
   if (nodeInfo->Equals(nsGkAtoms::menupopup) ||
       nodeInfo->Equals(nsGkAtoms::popup) ||
       nodeInfo->Equals(nsGkAtoms::panel) ||
       nodeInfo->Equals(nsGkAtoms::tooltip)) {
     return NS_NewXULPopupElement(nodeInfo.forget());
   }
 
   if (nodeInfo->Equals(nsGkAtoms::iframe) ||
--- a/dom/xul/nsXULElement.h
+++ b/dom/xul/nsXULElement.h
@@ -414,16 +414,21 @@ public:
     {
         GetAttr(kNameSpaceID_None, aName, aResult);
     }
     void SetXULAttr(nsAtom* aName, const nsAString& aValue,
                     mozilla::ErrorResult& aError)
     {
         SetAttr(aName, aValue, aError);
     }
+    bool GetXULBoolAttr(nsAtom* aName) const
+    {
+        return AttrValueIs(kNameSpaceID_None, aName,
+                           NS_LITERAL_STRING("true"), eCaseMatters);
+    }
     void SetXULBoolAttr(nsAtom* aName, bool aValue)
     {
         if (aValue) {
             SetAttr(kNameSpaceID_None, aName, NS_LITERAL_STRING("true"), true);
         } else {
             UnsetAttr(kNameSpaceID_None, aName, true);
         }
     }
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -191,16 +191,22 @@ GPUProcessManager::DisableGPUProcess(con
   // correctly. We cannot re-enter DisableGPUProcess from this call because we
   // know that it is disabled in the config above.
   EnsureProtocolsReady();
 
   // If we disable the GPU process during reinitialization after a previous
   // crash, then we need to tell the content processes again, because they
   // need to rebind to the UI process.
   HandleProcessLost();
+
+  // On Windows, always fallback to software.
+  // The assumption is that something in the graphics driver is crashing.
+#if XP_WIN
+  FallbackToSoftware("GPU Process is disabled, fallback to software solution.");
+#endif
 }
 
 bool
 GPUProcessManager::EnsureGPUReady()
 {
   if (mProcess && !mProcess->IsConnected()) {
     if (!mProcess->WaitForLaunch()) {
       // If this fails, we should have fired OnProcessLaunchComplete and
@@ -496,37 +502,39 @@ GPUProcessManager::OnRemoteProcessDevice
 
   auto newTime = TimeStamp::Now();
   auto delta = (int32_t)(newTime - mDeviceResetLastTime).ToMilliseconds();
   mDeviceResetLastTime = newTime;
 
   if (ShouldLimitDeviceResets(mDeviceResetCount, delta)) {
     DestroyProcess();
     DisableGPUProcess("GPU processed experienced too many device resets");
-
-    // Reaches the limited TDR attempts, fallback to software solution.
-    gfxConfig::SetFailed(Feature::HW_COMPOSITING,
-      FeatureStatus::Blocked,
-      "Too many attemps of D3D11 creation, fallback to software solution.");
-    gfxConfig::SetFailed(Feature::D3D11_COMPOSITING,
-      FeatureStatus::Blocked,
-      "Too many attemps of D3D11 creation, fallback to software solution.");
-    gfxConfig::SetFailed(Feature::DIRECT2D,
-      FeatureStatus::Blocked,
-      "Too many attemps of D3D11 creation, fallback to software solution.");
-
     HandleProcessLost();
     return;
   }
 
   RebuildRemoteSessions();
   NotifyListenersOnCompositeDeviceReset();
 }
 
 void
+GPUProcessManager::FallbackToSoftware(const char* aMessage)
+{
+  gfxConfig::SetFailed(Feature::HW_COMPOSITING,
+    FeatureStatus::Blocked,
+    aMessage);
+  gfxConfig::SetFailed(Feature::D3D11_COMPOSITING,
+    FeatureStatus::Blocked,
+    aMessage);
+  gfxConfig::SetFailed(Feature::DIRECT2D,
+    FeatureStatus::Blocked,
+    aMessage);
+}
+
+void
 GPUProcessManager::NotifyListenersOnCompositeDeviceReset()
 {
   for (const auto& listener : mListeners) {
     listener->OnCompositorDeviceReset();
   }
 }
 
 void
--- a/gfx/ipc/GPUProcessManager.h
+++ b/gfx/ipc/GPUProcessManager.h
@@ -206,16 +206,18 @@ private:
   // Called from InProcessCompositorSession. We track in process sessino so we can
   // notify their owning widgets that the session must be restarted
   void RegisterInProcessSession(InProcessCompositorSession* aSession);
   void UnregisterInProcessSession(InProcessCompositorSession* aSession);
 
   void RebuildRemoteSessions();
   void RebuildInProcessSessions();
 
+  void FallbackToSoftware(const char* aMessage);
+
 private:
   GPUProcessManager();
 
   // Permanently disable the GPU process and record a message why.
   void DisableGPUProcess(const char* aMessage);
 
   // Shutdown the GPU process.
   void CleanShutdown();
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -556,16 +556,22 @@ WebRenderLayerManager::ClearCachedResour
   WrBridge()->EndClearCachedResources();
 }
 
 void
 WebRenderLayerManager::WrUpdated()
 {
   mWebRenderCommandBuilder.ClearCachedResources();
   DiscardLocalImages();
+
+  if (mWidget) {
+    if (dom::TabChild* tabChild = mWidget->GetOwningTabChild()) {
+      tabChild->SchedulePaint();
+    }
+  }
 }
 
 dom::TabGroup*
 WebRenderLayerManager::GetTabGroup()
 {
   if (mWidget) {
     if (dom::TabChild* tabChild = mWidget->GetOwningTabChild()) {
       return tabChild->TabGroup();
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -2265,18 +2265,17 @@ ScrollFrameHelper::AsyncScrollCallback(S
 
   aInstance->CompleteAsyncScroll(range);
 }
 
 void
 ScrollFrameHelper::CompleteAsyncScroll(const nsRect &aRange, nsAtom* aOrigin)
 {
   // Apply desired destination range since this is the last step of scrolling.
-  mAsyncSmoothMSDScroll = nullptr;
-  mAsyncScroll = nullptr;
+  RemoveObservers();
   AutoWeakFrame weakFrame(mOuter);
   ScrollToImpl(mDestination, aRange, aOrigin);
   if (!weakFrame.IsAlive()) {
     return;
   }
   // We are done scrolling, set our destination to wherever we actually ended
   // up scrolling to.
   mDestination = GetScrollPosition();
@@ -4929,23 +4928,32 @@ ScrollFrameHelper::Destroy(PostDestroyDa
     delete gScrollFrameActivityTracker;
     gScrollFrameActivityTracker = nullptr;
   }
 
   if (mScrollActivityTimer) {
     mScrollActivityTimer->Cancel();
     mScrollActivityTimer = nullptr;
   }
+  RemoveObservers();
+}
+
+void
+ScrollFrameHelper::RemoveObservers()
+{
   if (mAsyncScroll) {
     mAsyncScroll->RemoveObserver();
+    mAsyncScroll = nullptr;
   }
   if (mAsyncSmoothMSDScroll) {
     mAsyncSmoothMSDScroll->RemoveObserver();
-  }
-}
+    mAsyncSmoothMSDScroll = nullptr;
+  }
+}
+
 
 /**
  * Called when we want to update the scrollbar position, either because scrolling happened
  * or the user moved the scrollbar position and we need to undo that (e.g., when the user
  * clicks to scroll and we're using smooth scrolling, so we need to put the thumb back
  * to its initial position for the start of the smooth sequence).
  */
 void
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -685,16 +685,19 @@ protected:
   bool HasPerspective() const {
     return mOuter->ChildrenHavePerspective();
   }
   bool HasBgAttachmentLocal() const;
   uint8_t GetScrolledFrameDir() const;
 
   bool IsForTextControlWithNoScrollbars() const;
 
+  // Removes any RefreshDriver observers we might have registered.
+  void RemoveObservers();
+
   static void EnsureFrameVisPrefsCached();
   static bool sFrameVisPrefsCached;
   // The number of scrollports wide/high to expand when tracking frame visibility.
   static uint32_t sHorzExpandScrollPort;
   static uint32_t sVertExpandScrollPort;
   // The fraction of the scrollport we allow to scroll by before we schedule
   // an update of frame visibility.
   static int32_t sHorzScrollFraction;
--- a/netwerk/sctp/datachannel/DataChannel.cpp
+++ b/netwerk/sctp/datachannel/DataChannel.cpp
@@ -371,16 +371,17 @@ DataChannelConnection::Destroy()
 
   MutexAutoLock lock(mLock);
   // If we had a pending reset, we aren't waiting for it - clear the list so
   // we can deregister this DataChannelConnection without leaking.
   ClearResets();
 
   MOZ_ASSERT(mSTS);
   ASSERT_WEBRTC(NS_IsMainThread());
+  mListener = nullptr;
   // Finish Destroy on STS thread to avoid bug 876167 - once that's fixed,
   // the usrsctp_close() calls can move back here (and just proxy the
   // disconnect_all())
   RUN_ON_THREAD(mSTS, WrapRunnable(RefPtr<DataChannelConnection>(this),
                                    &DataChannelConnection::DestroyOnSTS,
                                    mSocket, mMasterSocket),
                 NS_DISPATCH_NORMAL);
 
--- a/toolkit/content/widgets/text.xml
+++ b/toolkit/content/widgets/text.xml
@@ -4,29 +4,17 @@
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 
 <bindings id="textBindings"
    xmlns="http://www.mozilla.org/xbl"
    xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    xmlns:html="http://www.w3.org/1999/xhtml">
 
-  <!-- bound to <description>s -->
-  <binding id="text-base">
-    <implementation>
-      <property name="disabled" onset="if (val) this.setAttribute('disabled', 'true');
-                                       else this.removeAttribute('disabled');
-                                       return val;"
-                                onget="return this.getAttribute('disabled') == 'true';"/>
-      <property name="value" onget="return this.getAttribute('value');"
-                             onset="this.setAttribute('value', val); return val;"/>
-    </implementation>
-  </binding>
-
-  <binding id="text-label" extends="chrome://global/content/bindings/text.xml#text-base">
+  <binding id="text-label">
     <implementation>
       <property name="accessKey">
         <getter>
           <![CDATA[
             var accessKey = this.getAttribute("accesskey");
             return accessKey ? accessKey[0] : null;
           ]]>
         </getter>
--- a/toolkit/content/xul.css
+++ b/toolkit/content/xul.css
@@ -95,20 +95,16 @@ page {
 /******** box *******/
 
 vbox {
   -moz-box-orient: vertical;
 }
 
 /********** label **********/
 
-description {
-  -moz-binding: url("chrome://global/content/bindings/text.xml#text-base");
-}
-
 label {
   -moz-binding: url("chrome://global/content/bindings/text.xml#text-label");
 }
 
 label.text-link, label[onclick] {
   -moz-binding: url("chrome://global/content/bindings/text.xml#text-link");
   -moz-user-focus: normal;
 }