Merge Mozilla-Inbound to Mozilla-Central
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 25 Oct 2013 10:12:00 +0200
changeset 165876 186e834d87dc7b95ccb5f7b51bee6620932584f1
parent 165733 5a9ac6fed6ff179b0b91d4ef9a11cb014471a6e3 (current diff)
parent 165875 f030f97fcf107fbd5da84b1bea47a3580426bc29 (diff)
child 165917 dff9376142682cf42e11dcbebaa28c123f2ceabc
child 170488 93f754a03d3775ef012f184dbd654c0e3ad12197
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge Mozilla-Inbound to Mozilla-Central
content/media/webaudio/Makefile.in
dom/audiochannel/Makefile.in
dom/dom-config.mk
dom/wifi/Makefile.in
extensions/cookie/Makefile.in
image/decoders/icon/android/Makefile.in
ipc/chromium/chromium-config.mk
ipc/netd/Makefile.in
ipc/nfc/Makefile.in
ipc/ril/Makefile.in
ipc/unixsocket/Makefile.in
media/libvorbis/bug719612.patch
media/libvorbis/bug722924.patch
mobile/android/base/tests/robocop_x86.ini
modules/libjar/Makefile.in
toolkit/components/diskspacewatcher/Makefile.in
--- a/CLOBBER
+++ b/CLOBBER
@@ -13,9 +13,9 @@
 #          |               |
 #          O <-- Clobber   O  <-- Clobber
 #
 # Note: The description below will be part of the error message shown to users.
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
-Bug 899574 needed a clobber on every platform because we can't have nice things
+Bug 922160 needs a clobber due to WebIDL binding dependency issues (bug 928195).
--- a/accessible/src/atk/moz.build
+++ b/accessible/src/atk/moz.build
@@ -6,17 +6,17 @@
 
 MODULE = 'accessibility'
 
 EXPORTS.mozilla.a11y += [
     'AccessibleWrap.h',
     'HyperTextAccessibleWrap.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'AccessibleWrap.cpp',
     'ApplicationAccessibleWrap.cpp',
     'AtkSocketAccessible.cpp',
     'DocAccessibleWrap.cpp',
     'nsMaiHyperlink.cpp',
     'nsMaiInterfaceAction.cpp',
     'nsMaiInterfaceComponent.cpp',
     'nsMaiInterfaceDocument.cpp',
--- a/accessible/src/base/moz.build
+++ b/accessible/src/base/moz.build
@@ -25,17 +25,17 @@ EXPORTS.mozilla.a11y += [
     'States.h',
 ]
 
 if CONFIG['MOZ_DEBUG']:
     EXPORTS.mozilla.a11y += [
         'Logging.h',
     ]
 
-CPP_SOURCES += [
+SOURCES += [
     'AccCollector.cpp',
     'AccEvent.cpp',
     'AccGroupInfo.cpp',
     'AccIterator.cpp',
     'ARIAMap.cpp',
     'ARIAStateMap.cpp',
     'Asserts.cpp',
     'DocManager.cpp',
@@ -53,17 +53,17 @@ CPP_SOURCES += [
     'SelectionManager.cpp',
     'StyleInfo.cpp',
     'TextAttrs.cpp',
     'TextUpdater.cpp',
     'TreeWalker.cpp',
 ]
 
 if a11y_log:
-    CPP_SOURCES += [
+    SOURCES += [
         'Logging.cpp',
     ]
 
 LIBRARY_NAME = 'accessibility_base_s'
 
 LIBXUL_LIBRARY = True
 
 LOCAL_INCLUDES += [
--- a/accessible/src/generic/moz.build
+++ b/accessible/src/generic/moz.build
@@ -7,17 +7,17 @@
 MODULE = 'accessibility'
 
 EXPORTS.mozilla.a11y += [
     'Accessible.h',
     'DocAccessible.h',
     'HyperTextAccessible.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'Accessible.cpp',
     'ApplicationAccessible.cpp',
     'ARIAGridAccessible.cpp',
     'BaseAccessibles.cpp',
     'DocAccessible.cpp',
     'FormControlAccessible.cpp',
     'HyperTextAccessible.cpp',
     'ImageAccessible.cpp',
--- a/accessible/src/html/HTMLFormControlAccessible.cpp
+++ b/accessible/src/html/HTMLFormControlAccessible.cpp
@@ -301,16 +301,31 @@ HTMLTextFieldAccessible::NativeRole()
   if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
                             nsGkAtoms::password, eIgnoreCase)) {
     return roles::PASSWORD_TEXT;
   }
   
   return roles::ENTRY;
 }
 
+already_AddRefed<nsIPersistentProperties>
+HTMLTextFieldAccessible::NativeAttributes()
+{
+  nsCOMPtr<nsIPersistentProperties> attributes =
+    HyperTextAccessibleWrap::NativeAttributes();
+
+  // Expose type for text input elements as it gives some useful context,
+  // especially for mobile.
+  nsAutoString type;
+  if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, type))
+    nsAccUtils::SetAccAttr(attributes, nsGkAtoms::textInputType, type);
+
+  return attributes.forget();
+}
+
 ENameValueFlag
 HTMLTextFieldAccessible::NativeName(nsString& aName)
 {
   ENameValueFlag nameFlag = Accessible::NativeName(aName);
   if (!aName.IsEmpty())
     return nameFlag;
 
   if (mContent->GetBindingParent()) {
--- a/accessible/src/html/HTMLFormControlAccessible.h
+++ b/accessible/src/html/HTMLFormControlAccessible.h
@@ -126,16 +126,17 @@ public:
   // HyperTextAccessible
   virtual already_AddRefed<nsIEditor> GetEditor() const;
 
   // Accessible
   virtual void Value(nsString& aValue);
   virtual void ApplyARIAState(uint64_t* aState) const;
   virtual mozilla::a11y::role NativeRole();
   virtual uint64_t NativeState();
+  virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
 
   // ActionAccessible
   virtual uint8_t ActionCount();
 
   // Widgets
   virtual bool IsWidget() const;
   virtual Accessible* ContainerWidget() const;
 
--- a/accessible/src/html/moz.build
+++ b/accessible/src/html/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
-CPP_SOURCES += [
+SOURCES += [
     'HTMLCanvasAccessible.cpp',
     'HTMLElementAccessibles.cpp',
     'HTMLFormControlAccessible.cpp',
     'HTMLImageMapAccessible.cpp',
     'HTMLLinkAccessible.cpp',
     'HTMLListAccessible.cpp',
     'HTMLSelectAccessible.cpp',
     'HTMLTableAccessible.cpp',
--- a/accessible/src/jsat/OutputGenerator.jsm
+++ b/accessible/src/jsat/OutputGenerator.jsm
@@ -199,16 +199,34 @@ this.OutputGenerator = {
     if (!landmark) {
       return;
     }
 
     aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? 'unshift' : 'push'](
       landmark);
   },
 
+  /**
+   * Adds an entry type attribute to the description if available.
+   * @param {Array} aDesc Description array.
+   * @param {nsIAccessible} aAccessible current accessible object.
+   * @param {String} aRoleStr aAccessible's role string.
+   */
+  _addType: function _addType(aDesc, aAccessible, aRoleStr) {
+    if (aRoleStr !== 'entry') {
+      return;
+    }
+
+    let typeName = Utils.getAttributes(aAccessible)['text-input-type'];
+    if (!typeName) {
+      return;
+    }
+    aDesc.push(gStringBundle.GetStringFromName('textInputType_' + typeName));
+  },
+
   get outputOrder() {
     if (!this._utteranceOrder) {
       this._utteranceOrder = new PrefCache('accessibility.accessfu.utterance');
     }
     return typeof this._utteranceOrder.value === 'number' ?
       this._utteranceOrder.value : this.defaultOutputOrder;
   },
 
@@ -301,18 +319,20 @@ this.OutputGenerator = {
 
   objectOutputFunctions: {
     _generateBaseOutput: function _generateBaseOutput(aAccessible, aRoleStr, aStates, aFlags) {
       let output = [];
 
       if (aFlags & INCLUDE_DESC) {
         let desc = this._getLocalizedStates(aStates);
         let roleStr = this._getLocalizedRole(aRoleStr);
-        if (roleStr)
+        if (roleStr) {
+          this._addType(desc, aAccessible, aRoleStr);
           desc.push(roleStr);
+        }
         output.push(desc.join(' '));
       }
 
       if (aFlags & INCLUDE_VALUE) {
         let value = aAccessible.value;
         if (value) {
           output[this.outputOrder === OUTPUT_DESC_FIRST ?
                  'push' : 'unshift'](value);
--- a/accessible/src/mac/moz.build
+++ b/accessible/src/mac/moz.build
@@ -12,17 +12,17 @@ EXPORTS += [
 
 EXPORTS.mozilla.a11y += [
     'AccessibleWrap.h',
     'HyperTextAccessibleWrap.h',
 ]
 
 LIBRARY_NAME = 'accessibility_toolkit_s'
 
-CMMSRCS += [
+SOURCES += [
     'AccessibleWrap.mm',
     'DocAccessibleWrap.mm',
     'MacUtils.mm',
     'mozAccessible.mm',
     'mozActionElements.mm',
     'mozDocAccessible.mm',
     'mozHTMLAccessible.mm',
     'mozTextAccessible.mm',
--- a/accessible/src/other/moz.build
+++ b/accessible/src/other/moz.build
@@ -6,17 +6,17 @@
 
 MODULE = 'accessibility'
 
 EXPORTS.mozilla.a11y += [
     'AccessibleWrap.h',
     'HyperTextAccessibleWrap.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'AccessibleWrap.cpp',
     'Platform.cpp',
 ]
 
 LIBRARY_NAME = 'accessibility_toolkit_s'
 
 LIBXUL_LIBRARY = True
 
--- a/accessible/src/windows/ia2/ia2Accessible.cpp
+++ b/accessible/src/windows/ia2/ia2Accessible.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=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 "AccessibleWrap.h"
 
 #include "Accessible2_i.c"
+#include "Accessible2_2_i.c"
 #include "AccessibleRole.h"
 #include "AccessibleStates.h"
 
 #include "Compatibility.h"
 #include "ia2AccessibleRelation.h"
 #include "IUnknownImpl.h"
 #include "nsCoreUtils.h"
 #include "nsIAccessibleTypes.h"
@@ -30,18 +31,22 @@ using namespace mozilla::a11y;
 STDMETHODIMP
 ia2Accessible::QueryInterface(REFIID iid, void** ppv)
 {
   if (!ppv)
     return E_INVALIDARG;
 
   *ppv = nullptr;
 
-  if (IID_IAccessible2 == iid && !Compatibility::IsIA2Off()) {
+  if (IID_IAccessible2_2 == iid)
+    *ppv = static_cast<IAccessible2_2*>(this);
+  else if (IID_IAccessible2 == iid && !Compatibility::IsIA2Off())
     *ppv = static_cast<IAccessible2*>(this);
+
+  if (*ppv) {
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
   return E_NOINTERFACE;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -518,16 +523,99 @@ ia2Accessible::get_attributes(BSTR* aAtt
   // characters ":;=,\".
   nsCOMPtr<nsIPersistentProperties> attributes = acc->Attributes();
   return ConvertToIA2Attributes(attributes, aAttributes);
 
   A11Y_TRYBLOCK_END
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+// IAccessible2_2
+
+STDMETHODIMP
+ia2Accessible::get_attribute(BSTR name, VARIANT* aAttribute)
+{
+  A11Y_TRYBLOCK_BEGIN
+
+  if (!aAttribute)
+    return E_INVALIDARG;
+
+  return E_NOTIMPL;
+
+  A11Y_TRYBLOCK_END
+}
+
+STDMETHODIMP
+ia2Accessible::get_accessibleWithCaret(IUnknown** aAccessible,
+                                       long* aCaretOffset)
+{
+  A11Y_TRYBLOCK_BEGIN
+
+  if (!aAccessible || !aCaretOffset)
+    return E_INVALIDARG;
+
+  *aAccessible = nullptr;
+  *aCaretOffset = -1;
+  return E_NOTIMPL;
+
+  A11Y_TRYBLOCK_END
+}
+
+STDMETHODIMP
+ia2Accessible::get_relationTargetsOfType(BSTR aType,
+                                         long aMaxTargets,
+                                         IUnknown*** aTargets,
+                                         long* aNTargets)
+{
+  A11Y_TRYBLOCK_BEGIN
+
+  if (!aTargets || !aNTargets)
+    return E_INVALIDARG;
+  *aNTargets = 0;
+
+  Maybe<RelationType> relationType;
+  for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs); idx++) {
+    if (wcscmp(aType, sRelationTypePairs[idx].second) == 0) {
+      relationType.construct(sRelationTypePairs[idx].first);
+      break;
+    }
+  }
+  if (relationType.empty())
+    return E_INVALIDARG;
+
+  AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
+  if (acc->IsDefunct())
+    return CO_E_OBJNOTCONNECTED;
+
+  Relation rel = acc->RelationByType(relationType.ref());
+
+  nsTArray<Accessible*> targets;
+  Accessible* target = nullptr;
+  while ((target = rel.Next()) &&
+         static_cast<long>(targets.Length()) <= aMaxTargets)
+    targets.AppendElement(target);
+
+  *aNTargets = targets.Length();
+  *aTargets = static_cast<IUnknown**>(
+    ::CoTaskMemAlloc(sizeof(IUnknown*) * *aNTargets));
+  if (!*aTargets)
+    return E_OUTOFMEMORY;
+
+  for (int32_t i = 0; i < *aNTargets; i++) {
+    AccessibleWrap* target= static_cast<AccessibleWrap*>(targets[i]);
+    (*aTargets)[i] = static_cast<IAccessible2*>(target);
+    (*aTargets)[i]->AddRef();
+  }
+
+  return S_OK;
+
+  A11Y_TRYBLOCK_END
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // Helpers
 
 HRESULT
 ia2Accessible::ConvertToIA2Attributes(nsIPersistentProperties* aAttributes,
                                       BSTR* aIA2Attributes)
 {
   *aIA2Attributes = nullptr;
 
--- a/accessible/src/windows/ia2/ia2Accessible.h
+++ b/accessible/src/windows/ia2/ia2Accessible.h
@@ -4,22 +4,22 @@
  * 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 mozilla_a11y_ia2Accessible_h_
 #define mozilla_a11y_ia2Accessible_h_
 
 #include "nsISupports.h"
 
-#include "Accessible2.h"
+#include "Accessible2_2.h"
 
 namespace mozilla {
 namespace a11y {
 
-class ia2Accessible : public IAccessible2
+class ia2Accessible : public IAccessible2_2
 {
 public:
 
   // IUnknown
   STDMETHODIMP QueryInterface(REFIID, void**);
 
   // IAccessible2
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_nRelations(
@@ -82,16 +82,31 @@ public:
     /* [retval][out] */ long* indexInParent);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_locale(
     /* [retval][out] */ IA2Locale* locale);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_attributes(
     /* [retval][out] */ BSTR* attributes);
 
+  // IAccessible2_2
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_attribute(
+    /* [in] */ BSTR name,
+    /* [out, retval] */ VARIANT* attribute);
+
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_accessibleWithCaret(
+    /* [out] */ IUnknown** accessible,
+    /* [out, retval] */ long* caretOffset);
+
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_relationTargetsOfType(
+    /* [in] */ BSTR type,
+    /* [in] */ long maxTargets,
+    /* [out, size_is(,*nTargets)] */ IUnknown*** targets,
+    /* [out, retval] */ long* nTargets
+  );
 
   // Helper method
   static HRESULT ConvertToIA2Attributes(nsIPersistentProperties* aAttributes,
                                         BSTR* aIA2Attributes);
 };
 
 } // namespace a11y
 } // namespace mozilla
--- a/accessible/src/windows/ia2/moz.build
+++ b/accessible/src/windows/ia2/moz.build
@@ -12,17 +12,17 @@ EXPORTS += [
     'ia2AccessibleComponent.h',
     'ia2AccessibleEditableText.h',
     'ia2AccessibleHyperlink.h',
     'ia2AccessibleHypertext.h',
     'ia2AccessibleText.h',
     'ia2AccessibleValue.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'ia2Accessible.cpp',
     'ia2AccessibleAction.cpp',
     'ia2AccessibleComponent.cpp',
     'ia2AccessibleEditableText.cpp',
     'ia2AccessibleHyperlink.cpp',
     'ia2AccessibleHypertext.cpp',
     'ia2AccessibleImage.cpp',
     'ia2AccessibleRelation.cpp',
--- a/accessible/src/windows/msaa/Makefile.in
+++ b/accessible/src/windows/msaa/Makefile.in
@@ -1,10 +1,9 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 ifneq ($(A11Y_LOG),0)
   DEFINES += -DA11Y_LOG
 endif
--- a/accessible/src/windows/msaa/moz.build
+++ b/accessible/src/windows/msaa/moz.build
@@ -11,17 +11,17 @@ EXPORTS += [
 ]
 
 EXPORTS.mozilla.a11y += [
     'AccessibleWrap.h',
     'Compatibility.h',
     'HyperTextAccessibleWrap.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'AccessibleWrap.cpp',
     'ApplicationAccessibleWrap.cpp',
     'ARIAGridAccessibleWrap.cpp',
     'Compatibility.cpp',
     'DocAccessibleWrap.cpp',
     'EnumVariant.cpp',
     'HTMLTableAccessibleWrap.cpp',
     'HTMLWin32ObjectAccessible.cpp',
@@ -31,17 +31,17 @@ CPP_SOURCES += [
     'nsWinUtils.cpp',
     'Platform.cpp',
     'RootAccessibleWrap.cpp',
     'ServiceProvider.cpp',
     'TextLeafAccessibleWrap.cpp',
 ]
 
 if CONFIG['MOZ_XUL']:
-    CPP_SOURCES += [
+    SOURCES += [
         'XULListboxAccessibleWrap.cpp',
         'XULMenuAccessibleWrap.cpp',
         'XULTreeGridAccessibleWrap.cpp',
     ]
 
 LIBXUL_LIBRARY = True
 
 LOCAL_INCLUDES += [
@@ -56,8 +56,10 @@ LOCAL_INCLUDES += [
     '../sdn',
     '../uia',
 ]
 
 LIBRARY_NAME = 'accessibility_toolkit_msaa_s'
 
 EXPORT_LIBRARY = True
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/accessible/src/windows/sdn/moz.build
+++ b/accessible/src/windows/sdn/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
-CPP_SOURCES += [
+SOURCES += [
     'sdnAccessible.cpp',
     'sdnDocAccessible.cpp',
     'sdnTextAccessible.cpp',
 ]
 
 LIBXUL_LIBRARY = True
 
 LOCAL_INCLUDES += [
--- a/accessible/src/windows/uia/moz.build
+++ b/accessible/src/windows/uia/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
-CPP_SOURCES += [
+SOURCES += [
     'uiaRawElmProvider.cpp',
 ]
 
 LIBXUL_LIBRARY = True
 
 LOCAL_INCLUDES += [
     '../../base',
     '../../generic',
--- a/accessible/src/xpcom/moz.build
+++ b/accessible/src/xpcom/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
-CPP_SOURCES += [
+SOURCES += [
     'nsAccessibleRelation.cpp',
     'xpcAccessibleTable.cpp',
     'xpcAccessibleTableCell.cpp',
 ]
 
 LIBRARY_NAME = 'accessibility_xpcom_s'
 
 LIBXUL_LIBRARY = True
--- a/accessible/src/xul/moz.build
+++ b/accessible/src/xul/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
-CPP_SOURCES += [
+SOURCES += [
     'XULAlertAccessible.cpp',
     'XULColorPickerAccessible.cpp',
     'XULComboboxAccessible.cpp',
     'XULElementAccessibles.cpp',
     'XULFormControlAccessible.cpp',
     'XULListboxAccessible.cpp',
     'XULMenuAccessible.cpp',
     'XULSelectControlAccessible.cpp',
--- a/accessible/tests/mochitest/attributes/test_obj.html
+++ b/accessible/tests/mochitest/attributes/test_obj.html
@@ -92,16 +92,25 @@ https://bugzilla.mozilla.org/show_bug.cg
       testAbsentAttrs("labelledby", {"labelledby" : "label"});
 
       // container that has no default live attribute
       testAttrs("liveGroup", {"live" : "polite"}, true);
       testAttrs("liveGroupChild", {"container-live" : "polite"}, true);
       testAttrs("liveGroup", {"container-live-role" : "group"}, true);
       testAttrs("liveGroupChild", {"container-live-role" : "group"}, true);
 
+      // text input type
+      testAbsentAttrs("button", { "text-input-type": "button"});
+      testAbsentAttrs("checkbox", { "text-input-type": "checkbox"});
+      testAbsentAttrs("radio", { "text-input-type": "radio"});
+      testAttrs("email", {"text-input-type" : "email"}, true);
+      testAttrs("search", {"text-input-type" : "search"}, true);
+      testAttrs("tel", {"text-input-type" : "tel"}, true);
+      testAttrs("url", {"text-input-type" : "url"}, true);
+
       // html
       testAttrs("radio", {"checkable" : "true"}, true); 
       testAttrs("checkbox", {"checkable" : "true"}, true); 
       testAttrs("draggable", {"draggable" : "true"}, true);
       testAttrs("th1", { "abbr": "SS#" }, true);
       testAttrs("th2", { "abbr": "SS#" }, true);
       testAttrs("th2", { "axis": "social" }, true);
 
@@ -218,16 +227,23 @@ https://bugzilla.mozilla.org/show_bug.cg
   <div id="label" role="checkbox" aria-label="foo"></div>
   <div id="labelledby" role="checkbox" aria-labelledby="label"></div>
 
   <!-- unusual live case -->
   <div id="liveGroup" role="group" aria-live="polite">
     excuse <div id="liveGroupChild">me</div>
   </div>
 
+  <!-- text input type -->
+  <input id="button" type="button"/>
+  <input id="email" type="email"/>
+  <input id="search" type="search"/>
+  <input id="tel" type="tel"/>
+  <input id="url" type="url"/>
+
   <!-- html -->
   <input id="radio" type="radio"/>
   <input id="checkbox" type="checkbox"/>
   <div id="draggable" draggable="true">Draggable div</div>
   <table>
     <tr>
       <th id="th1"><abbr title="Social Security Number">SS#</abbr></th>
       <th id="th2" abbr="SS#" axis="social">Social Security Number</th>
--- a/accessible/tests/mochitest/jsat/test_utterance_order.html
+++ b/accessible/tests/mochitest/jsat/test_utterance_order.html
@@ -79,16 +79,39 @@ https://bugzilla.mozilla.org/show_bug.cg
             "link", "Bananas", "link", "Peaches", "Last item", "link", "Plums"
           ], [
             "Apples", "link", "First item", "Bananas", "link", "Peaches",
             "link", "Plums", "link", "Last item", "list 4 items",
             "Column 1 Row 1", "Fruits and vegetables",
             "table with 1 column and 1 row"
           ]]
         }, {
+          accOrElmOrID: "email",
+          expected: [
+            ["e-mail entry", "test@example.com"],
+            ["test@example.com", "e-mail entry"]
+          ]
+        }, {
+          accOrElmOrID: "search",
+          expected: [
+            ["search entry", "This is a search"],
+            ["This is a search", "search entry"]
+          ]
+        }, {
+          accOrElmOrID: "tel",
+          expected: [
+            ["telephone entry", "555-5555"], ["555-5555", "telephone entry"]
+          ]
+        }, {
+          accOrElmOrID: "url",
+          expected: [
+            ["URL entry", "http://example.com"],
+            ["http://example.com", "URL entry"]
+          ]
+        }, {
           // Test pivot to list from li_one.
           accOrElmOrID: "list",
           oldAccOrElmOrID: "li_one",
           expected: [
             ["list 1 item", "First item", "1.", "list one"],
             ["1.", "list one", "First item", "list 1 item"]
           ]
         }, {
@@ -271,11 +294,15 @@ https://bugzilla.mozilla.org/show_bug.cg
       <form id="form1">
         <label id="label1"><input id="input1" type="checkbox">Orange</label>
         <input id="input2" type="checkbox"><label id="label2" for="input2">Blue</label>
       </form>
       <label id="label3">First name: <input id="input3" value="Joe"></label>
       <label id="label4">Points:
         <input id="input4" type="range" name="points" min="1" max="10" value="3">
       </label>
+      <input id="email" type="email" value="test@example.com" />
+      <input id="search" type="search" value="This is a search" />
+      <input id="tel" type="tel" value="555-5555" />
+      <input id="url" type="url" value="http://example.com" />
     </div>
   </body>
 </html>
--- a/b2g/app/moz.build
+++ b/b2g/app/moz.build
@@ -4,11 +4,11 @@
 # 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/.
 
 if not CONFIG['LIBXUL_SDK']:
     if CONFIG['GAIADIR']:
         PROGRAM = CONFIG['MOZ_APP_NAME'] + "-bin"
     else:
         PROGRAM = CONFIG['MOZ_APP_NAME']
-    CPP_SOURCES += [
+    SOURCES += [
         'nsBrowserApp.cpp',
     ]
--- a/b2g/gaia/moz.build
+++ b/b2g/gaia/moz.build
@@ -2,11 +2,11 @@
 # vim: set filetype=python:
 # 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/.
 
 PROGRAM = CONFIG['MOZ_APP_NAME']
 
 if CONFIG['OS_ARCH'] == 'WINNT':
-    CPP_SOURCES += [
+    SOURCES += [
         'run-b2g.cpp',
     ]
--- a/browser/app/moz.build
+++ b/browser/app/moz.build
@@ -3,11 +3,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/.
 
 DIRS += ['profile/extensions']
 
 PROGRAM = CONFIG['MOZ_APP_NAME']
 
-CPP_SOURCES += [
+SOURCES += [
     'nsBrowserApp.cpp',
 ]
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -583,17 +583,17 @@ pref("browser.gesture.pinch.in.shift", "
 #endif
 pref("browser.gesture.twist.latched", false);
 pref("browser.gesture.twist.threshold", 0);
 pref("browser.gesture.twist.right", "cmd_gestureRotateRight");
 pref("browser.gesture.twist.left", "cmd_gestureRotateLeft");
 pref("browser.gesture.twist.end", "cmd_gestureRotateEnd");
 pref("browser.gesture.tap", "cmd_fullZoomReset");
 
-pref("browser.snapshots.limit", 5);
+pref("browser.snapshots.limit", 0);
 
 // 0: Nothing happens
 // 1: Scrolling contents
 // 2: Go back or go forward, in your history
 // 3: Zoom in or out.
 #ifdef XP_MACOSX
 // On OS X, if the wheel has one axis only, shift+wheel comes through as a
 // horizontal scroll event. Thus, we can't assign anything other than normal
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2150,17 +2150,17 @@ function losslessDecodeURI(aURI) {
   // object replacement character) (bug 452979, bug 909264)
   value = value.replace(/[\u0000-\u001f\u007f-\u00a0\u2028\u2029\ufffc]/g,
                         encodeURIComponent);
 
   // Encode default ignorable characters (bug 546013)
   // except ZWNJ (U+200C) and ZWJ (U+200D) (bug 582186).
   // This includes all bidirectional formatting characters.
   // (RFC 3987 sections 3.2 and 4.1 paragraph 6)
-  value = value.replace(/[\u00ad\u034f\u115f-\u1160\u17b4-\u17b5\u180b-\u180d\u200b\u200e-\u200f\u202a-\u202e\u2060-\u206f\u3164\ufe00-\ufe0f\ufeff\uffa0\ufff0-\ufff8]|\ud834[\udd73-\udd7a]|[\udb40-\udb43][\udc00-\udfff]/g,
+  value = value.replace(/[\u00ad\u034f\u061c\u115f-\u1160\u17b4-\u17b5\u180b-\u180d\u200b\u200e-\u200f\u202a-\u202e\u2060-\u206f\u3164\ufe00-\ufe0f\ufeff\uffa0\ufff0-\ufff8]|\ud834[\udd73-\udd7a]|[\udb40-\udb43][\udc00-\udfff]/g,
                         encodeURIComponent);
   return value;
 }
 
 function UpdateUrlbarSearchSplitterState()
 {
   var splitter = document.getElementById("urlbar-search-splitter");
   var urlbar = document.getElementById("urlbar-container");
--- a/browser/components/about/moz.build
+++ b/browser/components/about/moz.build
@@ -5,14 +5,14 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MODULE = 'browserabout'
 
 EXPORTS.mozilla.browser += [
     'AboutRedirector.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'AboutRedirector.cpp',
 ]
 
 LIBRARY_NAME = 'browserabout_s'
 
--- a/browser/components/build/moz.build
+++ b/browser/components/build/moz.build
@@ -5,16 +5,16 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MODULE = 'browsercomps'
 
 EXPORTS += [
     'nsBrowserCompsCID.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'nsModule.cpp',
 ]
 
 LIBRARY_NAME = 'browsercomps'
 
 IS_COMPONENT = True
 
--- a/browser/components/dirprovider/moz.build
+++ b/browser/components/dirprovider/moz.build
@@ -5,17 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MODULE = 'browserdir'
 
 EXPORTS.mozilla.browser += [
     'DirectoryProvider.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'DirectoryProvider.cpp',
 ]
 
 LIBRARY_NAME = 'browserdir_s'
 
 XPCSHELL_TESTS_MANIFESTS += [
     'tests/unit/xpcshell.ini',
 ]
--- a/browser/components/feeds/src/moz.build
+++ b/browser/components/feeds/src/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'browser_feeds'
 
-CPP_SOURCES += [
+SOURCES += [
     'nsFeedSniffer.cpp',
 ]
 
 EXTRA_COMPONENTS += [
     'BrowserFeeds.manifest',
     'FeedConverter.js',
     'WebContentConverter.js',
 ]
--- a/browser/components/migration/src/moz.build
+++ b/browser/components/migration/src/moz.build
@@ -2,17 +2,17 @@
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'migration'
 
 if CONFIG['OS_ARCH'] == 'WINNT':
-    CPP_SOURCES += [
+    SOURCES += [
         'nsIEHistoryEnumerator.cpp',
     ]
 
 EXTRA_COMPONENTS += [
     'FirefoxProfileMigrator.js',
     'ProfileMigrator.js',
 ]
 
--- a/browser/components/shell/src/moz.build
+++ b/browser/components/shell/src/moz.build
@@ -2,27 +2,27 @@
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'shellservice'
 
 if CONFIG['OS_ARCH'] == 'WINNT':
-    CPP_SOURCES += [
+    SOURCES += [
         'nsWindowsShellService.cpp',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
-    CPP_SOURCES += [
+    SOURCES += [
         'nsMacShellService.cpp',
     ]
 elif CONFIG['MOZ_WIDGET_GTK']:
-    CPP_SOURCES += [
+    SOURCES += [
         'nsGNOMEShellService.cpp',
     ]
 
-if CPP_SOURCES:
+if SOURCES:
     LIBRARY_NAME = 'shellservice_s'
 
 EXTRA_COMPONENTS += [
     'nsSetDefaultBrowser.js',
     'nsSetDefaultBrowser.manifest',
 ]
--- a/browser/metro/shell/commandexecutehandler/moz.build
+++ b/browser/metro/shell/commandexecutehandler/moz.build
@@ -1,15 +1,15 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 PROGRAM = 'CommandExecuteHandler'
 
-CPP_SOURCES += [
+SOURCES += [
     'CEHHelper.cpp',
     'CommandExecuteHandler.cpp',
 ]
 
 # We want this exe in dist/bin
 DIST_SUBDIR = ''
--- a/browser/metro/shell/linktool/moz.build
+++ b/browser/metro/shell/linktool/moz.build
@@ -1,13 +1,13 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 PROGRAM = 'linktool'
 
-CPP_SOURCES += [
+SOURCES += [
     'linktool.cpp',
 ]
 
 DIST_SUBDIR = 'metro/install'
--- a/browser/metro/shell/testing/moz.build
+++ b/browser/metro/shell/testing/moz.build
@@ -1,14 +1,14 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 PROGRAM = 'metrotestharness'
 
-CPP_SOURCES += [
+SOURCES += [
     'metrotestharness.cpp',
 ]
 
 # We want this exe in dist/bin
 DIST_SUBDIR = ''
--- a/build/autoconf/android.m4
+++ b/build/autoconf/android.m4
@@ -33,21 +33,16 @@ MOZ_ARG_WITH_STRING(android-version,
 [  --with-android-version=VER
                           android platform version, default] MIN_ANDROID_VERSION,
     android_version=$withval)
 
 if test $android_version -lt MIN_ANDROID_VERSION ; then
     AC_MSG_ERROR([--with-android-version must be at least MIN_ANDROID_VERSION.])
 fi
 
-MOZ_ARG_WITH_STRING(android-platform,
-[  --with-android-platform=DIR
-                           location of platform dir],
-    android_platform=$withval)
-
 case "$target" in
 arm-linux*-android*|*-linuxandroid*)
     android_tool_prefix="arm-linux-androideabi"
     ;;
 i?86-*android*)
     android_tool_prefix="i686-linux-android"
     ;;
 mipsel-*android*)
@@ -111,39 +106,36 @@ case "$target" in
         else
             AC_MSG_RESULT([$android_toolchain])
         fi
         NSPR_CONFIGURE_ARGS="$NSPR_CONFIGURE_ARGS --with-android-toolchain=$android_toolchain"
     fi
 
     NSPR_CONFIGURE_ARGS="$NSPR_CONFIGURE_ARGS --with-android-version=$android_version"
 
-    if test -z "$android_platform" ; then
-        AC_MSG_CHECKING([for android platform directory])
+    AC_MSG_CHECKING([for android platform directory])
 
-        case "$target_cpu" in
-        arm)
-            target_name=arm
-            ;;
-        i?86)
-            target_name=x86
-            ;;
-        mipsel)
-            target_name=mips
-            ;;
-        esac
+    case "$target_cpu" in
+    arm)
+        target_name=arm
+        ;;
+    i?86)
+        target_name=x86
+        ;;
+    mipsel)
+        target_name=mips
+        ;;
+    esac
 
-        android_platform="$android_ndk"/platforms/android-"$android_version"/arch-"$target_name"
+    android_platform="$android_ndk"/platforms/android-"$android_version"/arch-"$target_name"
 
-        if test -d "$android_platform" ; then
-            AC_MSG_RESULT([$android_platform])
-        else
-            AC_MSG_ERROR([not found. You have to specify --with-android-platform=/path/to/ndk/platform.])
-        fi
-        NSPR_CONFIGURE_ARGS="$NSPR_CONFIGURE_ARGS --with-android-platform=$android_platform"
+    if test -d "$android_platform" ; then
+        AC_MSG_RESULT([$android_platform])
+    else
+        AC_MSG_ERROR([not found. Please check your NDK. With the current configuration, it should be in $android_platform])
     fi
 
     dnl Old NDK support. If minimum requirement is changed to NDK r8b,
     dnl please remove this.
     case "$target_cpu" in
     i?86)
         if ! test -e "$android_toolchain"/bin/"$android_tool_prefix"-gcc; then
             dnl Old NDK toolchain name
--- a/build/mobile/robocop/Makefile.in
+++ b/build/mobile/robocop/Makefile.in
@@ -49,17 +49,16 @@ manifest_TARGET   := AndroidManifest.xml
 
 # Install robocop configs and helper
 INSTALL_TARGETS += robocop
 robocop_TARGET  := libs
 robocop_DEST    := $(CURDIR)
 robocop_FILES   := \
   $(TESTPATH)/robocop.ini \
   $(TESTPATH)/robocop_autophone.ini \
-  $(TESTPATH)/robocop_x86.ini \
   $(NULL)
 robocop-deps := $(notdir $(robocop_FILES))
 
 MOCHITEST_ROBOCOP_FILES := \
   $(wildcard $(TESTPATH)/*.html) \
   $(wildcard $(TESTPATH)/*.jpg) \
   $(wildcard $(TESTPATH)/*.sjs) \
   $(wildcard $(TESTPATH)/test*.js) \
--- a/build/unix/elfhack/moz.build
+++ b/build/unix/elfhack/moz.build
@@ -2,22 +2,22 @@
 # vim: set filetype=python:
 # 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/.
 
 NO_DIST_INSTALL = True
 DIRS += ['inject']
 
-CSRCS += [
+SOURCES += [
     'test-array.c',
     'test-ctors.c',
 ]
 
 if not CONFIG['CROSS_COMPILE']:
-    CSRCS += [
+    SOURCES += [
         'dummy.c',
     ]
 
-HOST_CPPSRCS += [
+HOST_SOURCES += [
     'elf.cpp',
     'elfhack.cpp',
 ]
--- a/build/unix/stdc++compat/moz.build
+++ b/build/unix/stdc++compat/moz.build
@@ -3,16 +3,16 @@
 # 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/.
 
 MODULE = 'build'
 
 if CONFIG['MOZ_LIBSTDCXX_TARGET_VERSION']:
     LIBRARY_NAME = 'stdc++compat'
-    CPP_SOURCES += ['stdc++compat.cpp']
+    SOURCES += ['stdc++compat.cpp']
 
 if CONFIG['MOZ_LIBSTDCXX_HOST_VERSION']:
     HOST_LIBRARY_NAME = 'host_stdc++compat'
-    HOST_CPPSRCS += [
+    HOST_SOURCES += [
         'stdc++compat.cpp',
     ]
 
--- a/build/win32/crashinjectdll/moz.build
+++ b/build/win32/crashinjectdll/moz.build
@@ -1,12 +1,12 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
-CPP_SOURCES += [
+SOURCES += [
     'crashinjectdll.cpp',
 ]
 
 LIBRARY_NAME = 'crashinjectdll'
 
--- a/build/win32/moz.build
+++ b/build/win32/moz.build
@@ -6,11 +6,11 @@
 
 if CONFIG['_MSC_VER'] and CONFIG['OS_TEST'] != 'x86_64':
     TEST_DIRS += ['vmwarerecordinghelper']
 
 TEST_DIRS += ['crashinjectdll']
 
 if CONFIG['ENABLE_TESTS']:
     PROGRAM = 'crashinject'
-    CPP_SOURCES += [
+    SOURCES += [
         'crashinject.cpp',
     ]
--- a/build/win32/vmwarerecordinghelper/moz.build
+++ b/build/win32/vmwarerecordinghelper/moz.build
@@ -1,12 +1,12 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
-CPP_SOURCES += [
+SOURCES += [
     'vmwarerecordinghelper.cpp',
 ]
 
 LIBRARY_NAME = 'vmwarerecordinghelper'
 
--- a/caps/src/moz.build
+++ b/caps/src/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'caps'
 
-CPP_SOURCES += [
+SOURCES += [
     'nsJSPrincipals.cpp',
     'nsNullPrincipal.cpp',
     'nsNullPrincipalURI.cpp',
     'nsPrincipal.cpp',
     'nsScriptSecurityManager.cpp',
     'nsSecurityManagerFactory.cpp',
     'nsSystemPrincipal.cpp',
 ]
--- a/chrome/src/Makefile.in
+++ b/chrome/src/Makefile.in
@@ -1,15 +1,14 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 LOCAL_INCLUDES += \
 		-I$(topsrcdir)/netwerk/protocol/res \
 		-I$(topsrcdir)/netwerk/base/src \
 		$(NULL)
 
 ifdef MOZ_ENABLE_GTK
 CXXFLAGS          += $(TK_CFLAGS)
--- a/chrome/src/moz.build
+++ b/chrome/src/moz.build
@@ -5,21 +5,23 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MODULE = 'chrome'
 
 EXPORTS.mozilla.chrome += [
     'RegistryMessageUtils.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'nsChromeProtocolHandler.cpp',
     'nsChromeRegistry.cpp',
     'nsChromeRegistryChrome.cpp',
     'nsChromeRegistryContent.cpp',
 ]
 
 LIBXUL_LIBRARY = True
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'chrome_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/config/config.mk
+++ b/config/config.mk
@@ -211,18 +211,18 @@ endif
 endif
 
 OS_CONFIG	:= $(OS_ARCH)$(OS_RELEASE)
 
 MOZ_UNICHARUTIL_LIBS = $(LIBXUL_DIST)/lib/$(LIB_PREFIX)unicharutil_s.$(LIB_SUFFIX)
 MOZ_WIDGET_SUPPORT_LIBS    = $(DIST)/lib/$(LIB_PREFIX)widgetsupport_s.$(LIB_SUFFIX)
 
 ifdef _MSC_VER
-CC_WRAPPER = $(call py_action,cl)
-CXX_WRAPPER = $(call py_action,cl)
+CC_WRAPPER ?= $(call py_action,cl)
+CXX_WRAPPER ?= $(call py_action,cl)
 endif # _MSC_VER
 
 CC := $(CC_WRAPPER) $(CC)
 CXX := $(CXX_WRAPPER) $(CXX)
 MKDIR ?= mkdir
 SLEEP ?= sleep
 TOUCH ?= touch
 
--- a/config/milestone.pl
+++ b/config/milestone.pl
@@ -50,17 +50,17 @@ if (!defined($OBJDIR)) { $OBJDIR = '.'; 
 $MILESTONE_FILE  = "$TOPSRCDIR/config/milestone.txt";
 @MILESTONE_PARTS = (0, 0, 0, 0);
 
 #
 # Grab milestone (top line of $MILESTONE_FILE that starts with a digit)
 #
 my $milestone = Moz::Milestone::getOfficialMilestone($MILESTONE_FILE);
 
-if (defined(@TEMPLATE_FILE)) {
+if (@TEMPLATE_FILE) {
   my $TFILE;
 
   foreach $TFILE (@TEMPLATE_FILE) {
     my $BUILT_FILE = "$OBJDIR/$TFILE";
     $TFILE = "$SRCDIR/$TFILE.tmpl";
 
     if (-e $TFILE) {
 
--- a/config/moz.build
+++ b/config/moz.build
@@ -11,12 +11,12 @@ CONFIGURE_SUBST_FILES += [
     'doxygen.cfg',
     'emptyvars.mk',
     'makefiles/test/Makefile',
     'tests/makefiles/autodeps/Makefile',
     'tests/src-simple/Makefile',
 ]
 
 if CONFIG['HOST_OS_ARCH'] != 'WINNT':
-    HOST_CSRCS += [
+    HOST_SOURCES += [
         'nsinstall.c',
         'pathsub.c',
     ]
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -314,21 +314,21 @@ CPPOBJS = $(notdir $(addsuffix .$(OBJ_SU
 CMOBJS = $(notdir $(CMSRCS:.m=.$(OBJ_SUFFIX)))
 CMMOBJS = $(notdir $(CMMSRCS:.mm=.$(OBJ_SUFFIX)))
 ASOBJS = $(notdir $(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX)))
 ifndef OBJS
 _OBJS = $(COBJS) $(SOBJS) $(CPPOBJS) $(CMOBJS) $(CMMOBJS) $(ASOBJS)
 OBJS = $(strip $(_OBJS))
 endif
 
-HOST_COBJS = $(addprefix host_,$(HOST_CSRCS:.c=.$(OBJ_SUFFIX)))
+HOST_COBJS = $(addprefix host_,$(notdir $(HOST_CSRCS:.c=.$(OBJ_SUFFIX))))
 # HOST_CPPOBJS can have different extensions (eg: .cpp, .cc)
-HOST_CPPOBJS = $(addprefix host_,$(addsuffix .$(OBJ_SUFFIX),$(basename $(HOST_CPPSRCS))))
-HOST_CMOBJS = $(addprefix host_,$(HOST_CMSRCS:.m=.$(OBJ_SUFFIX)))
-HOST_CMMOBJS = $(addprefix host_,$(HOST_CMMSRCS:.mm=.$(OBJ_SUFFIX)))
+HOST_CPPOBJS = $(addprefix host_,$(notdir $(addsuffix .$(OBJ_SUFFIX),$(basename $(HOST_CPPSRCS)))))
+HOST_CMOBJS = $(addprefix host_,$(notdir $(HOST_CMSRCS:.m=.$(OBJ_SUFFIX))))
+HOST_CMMOBJS = $(addprefix host_,$(notdir $(HOST_CMMSRCS:.mm=.$(OBJ_SUFFIX))))
 ifndef HOST_OBJS
 _HOST_OBJS = $(HOST_COBJS) $(HOST_CPPOBJS) $(HOST_CMOBJS) $(HOST_CMMOBJS)
 HOST_OBJS = $(strip $(_HOST_OBJS))
 endif
 
 ALL_TRASH = \
 	$(GARBAGE) $(TARGETS) $(OBJS) $(PROGOBJS) LOGS TAGS a.out \
 	$(filter-out $(ASFILES),$(OBJS:.$(OBJ_SUFFIX)=.s)) $(OBJS:.$(OBJ_SUFFIX)=.ii) \
@@ -1009,20 +1009,20 @@ endef
 endif # Sun Studio on Solaris
 
 # The object file is in the current directory, and the source file can be any
 # relative path. This macro adds the dependency obj: src for each source file.
 # This dependency must be first for the $< flag to work correctly, and the
 # rules that have commands for these targets must not list any other
 # prerequisites, or they will override the $< variable.
 define src_objdep
-$(basename $(notdir $1)).$(OBJ_SUFFIX): $1 $(call mkdir_deps,$(MDDEPDIR))
+$(basename $2$(notdir $1)).$(OBJ_SUFFIX): $1 $$(call mkdir_deps,$$(MDDEPDIR))
 endef
 $(foreach f,$(CSRCS) $(SSRCS) $(CPPSRCS) $(CMSRCS) $(CMMSRCS) $(ASFILES),$(eval $(call src_objdep,$(f))))
-$(foreach f,$(HOST_CSRCS) $(HOST_CPPSRCS) $(HOST_CMSRCS) $(HOST_CMMSRCS),$(eval host_$(call src_objdep,$(f))))
+$(foreach f,$(HOST_CSRCS) $(HOST_CPPSRCS) $(HOST_CMSRCS) $(HOST_CMMSRCS),$(eval $(call src_objdep,$(f),host_)))
 
 $(OBJS) $(HOST_OBJS) $(PROGOBJS) $(HOST_PROGOBJS): $(GLOBAL_DEPS)
 
 # Rules for building native targets must come first because of the host_ prefix
 $(HOST_COBJS):
 	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
--- a/content/base/public/Element.h
+++ b/content/base/public/Element.h
@@ -1460,25 +1460,29 @@ NS_IMETHOD GetChildElementCount(uint32_t
   *aChildElementCount = Element::ChildElementCount();                         \
   return NS_OK;                                                               \
 }                                                                             \
 NS_IMETHOD MozRemove() MOZ_FINAL                                              \
 {                                                                             \
   nsINode::Remove();                                                          \
   return NS_OK;                                                               \
 }                                                                             \
+using nsINode::GetOnmouseenter;                                               \
+using nsINode::SetOnmouseenter;                                               \
 NS_IMETHOD GetOnmouseenter(JSContext* cx, JS::Value* aOnmouseenter) MOZ_FINAL \
 {                                                                             \
   return Element::GetOnmouseenter(cx, aOnmouseenter);                         \
 }                                                                             \
 NS_IMETHOD SetOnmouseenter(JSContext* cx,                                     \
                            const JS::Value& aOnmouseenter) MOZ_FINAL          \
 {                                                                             \
   return Element::SetOnmouseenter(cx, aOnmouseenter);                         \
 }                                                                             \
+using nsINode::GetOnmouseleave;                                               \
+using nsINode::SetOnmouseleave;                                               \
 NS_IMETHOD GetOnmouseleave(JSContext* cx, JS::Value* aOnmouseleave) MOZ_FINAL \
 {                                                                             \
   return Element::GetOnmouseleave(cx, aOnmouseleave);                         \
 }                                                                             \
 NS_IMETHOD SetOnmouseleave(JSContext* cx,                                     \
                            const JS::Value& aOnmouseleave) MOZ_FINAL          \
 {                                                                             \
   return Element::SetOnmouseleave(cx, aOnmouseleave);                         \
--- a/content/base/public/nsHostObjectProtocolHandler.h
+++ b/content/base/public/nsHostObjectProtocolHandler.h
@@ -25,16 +25,17 @@ namespace mozilla {
 namespace dom {
 class MediaSource;
 }
 }
 
 class nsHostObjectProtocolHandler : public nsIProtocolHandler
 {
 public:
+  nsHostObjectProtocolHandler();
   virtual ~nsHostObjectProtocolHandler() {}
   NS_DECL_ISUPPORTS
 
   // nsIProtocolHandler methods, except for GetScheme which is only defined
   // in subclasses.
   NS_IMETHOD GetDefaultPort(int32_t *aDefaultPort) MOZ_OVERRIDE;
   NS_IMETHOD GetProtocolFlags(uint32_t *aProtocolFlags) MOZ_OVERRIDE;
   NS_IMETHOD NewURI(const nsACString & aSpec, const char * aOriginCharset, nsIURI *aBaseURI, nsIURI * *_retval) MOZ_OVERRIDE;
--- a/content/base/src/Makefile.in
+++ b/content/base/src/Makefile.in
@@ -5,17 +5,16 @@
 
 ifdef MOZ_WEBRTC
 LOCAL_INCLUDES += \
 		-I$(topsrcdir)/netwerk/sctp/datachannel \
 		$(NULL)
 endif
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 LOCAL_INCLUDES += \
   -I$(topsrcdir)/caps/include \
   -I$(topsrcdir)/content/events/src \
   -I$(topsrcdir)/content/html/content/src \
   -I$(topsrcdir)/content/html/document/src \
   -I$(topsrcdir)/content/xbl/src \
   -I$(topsrcdir)/content/xml/content/src \
--- a/content/base/src/moz.build
+++ b/content/base/src/moz.build
@@ -35,24 +35,24 @@ EXPORTS += [
     'nsTextFragment.h',
 ]
 
 if CONFIG['MOZ_WEBRTC']:
     EXPORTS += [
         'nsDOMDataChannel.h',
         'nsDOMDataChannelDeclarations.h',
     ]
-    CPP_SOURCES += [
+    SOURCES += [
         'nsDOMDataChannel.cpp',
     ]
 
 # Are we targeting x86-32 or x86-64?  If so, we want to include SSE2 code for
 # nsTextFragment.cpp
 if CONFIG['INTEL_ARCHITECTURE']:
-    CPP_SOURCES += [
+    SOURCES += [
         'nsTextFragmentSSE2.cpp',
     ]
 
 EXPORTS.mozilla.dom += [
     'Attr.h',
     'Comment.h',
     'DocumentFragment.h',
     'DocumentType.h',
@@ -61,17 +61,17 @@ EXPORTS.mozilla.dom += [
     'DOMRect.h',
     'EventSource.h',
     'Link.h',
     'NodeIterator.h',
     'Text.h',
     'TreeWalker.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'Attr.cpp',
     'ChildIterator.cpp',
     'Comment.cpp',
     'DirectionalityUtils.cpp',
     'DocumentFragment.cpp',
     'DocumentType.cpp',
     'DOMImplementation.cpp',
     'DOMParser.cpp',
@@ -177,8 +177,10 @@ EXTRA_JS_MODULES += [
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'gkconbase_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -662,17 +662,29 @@ nsresult
 nsContentUtils::Atob(const nsAString& aAsciiBase64String,
                      nsAString& aBinaryData)
 {
   if (!Is8bit(aAsciiBase64String)) {
     aBinaryData.Truncate();
     return NS_ERROR_DOM_INVALID_CHARACTER_ERR;
   }
 
-  nsresult rv = Base64Decode(aAsciiBase64String, aBinaryData);
+  const PRUnichar* start = aAsciiBase64String.BeginReading();
+  const PRUnichar* end = aAsciiBase64String.EndReading();
+  nsString trimmedString;
+  if (!trimmedString.SetCapacity(aAsciiBase64String.Length(), fallible_t())) {
+    return NS_ERROR_DOM_INVALID_CHARACTER_ERR;
+  }
+  while (start < end) {
+    if (!nsContentUtils::IsHTMLWhitespace(*start)) {
+      trimmedString.Append(*start);
+    }
+    start++;
+  }
+  nsresult rv = Base64Decode(trimmedString, aBinaryData);
   if (NS_FAILED(rv) && rv == NS_ERROR_INVALID_ARG) {
     return NS_ERROR_DOM_INVALID_CHARACTER_ERR;
   }
   return rv;
 }
 
 bool
 nsContentUtils::IsAutocompleteEnabled(nsIDOMHTMLInputElement* aInput)
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -20,17 +20,16 @@
 #include "nsVoidArray.h"
 #include "nsTArray.h"
 #include "nsIDOMXMLDocument.h"
 #include "nsIDOMDocumentXBL.h"
 #include "nsStubDocumentObserver.h"
 #include "nsIDOMStyleSheetList.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIContent.h"
-#include "nsEventListenerManager.h"
 #include "nsIPrincipal.h"
 #include "nsIParser.h"
 #include "nsBindingManager.h"
 #include "nsINodeInfo.h"
 #include "nsInterfaceHashtable.h"
 #include "nsJSThingHashtable.h"
 #include "nsIBoxObject.h"
 #include "nsPIBoxObject.h"
@@ -63,16 +62,17 @@
 #include "imgIRequest.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/DOMImplementation.h"
 #include "nsIDOMTouchEvent.h"
 #include "nsDataHashtable.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Attributes.h"
 #include "nsIDOMXPathEvaluator.h"
+#include "jsfriendapi.h"
 
 #define XML_DECLARATION_BITS_DECLARATION_EXISTS   (1 << 0)
 #define XML_DECLARATION_BITS_ENCODING_EXISTS      (1 << 1)
 #define XML_DECLARATION_BITS_STANDALONE_EXISTS    (1 << 2)
 #define XML_DECLARATION_BITS_STANDALONE_YES       (1 << 3)
 
 
 class nsEventListenerManager;
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -412,27 +412,27 @@ JSONCreator(const jschar* aBuf, uint32_t
 }
 
 static bool
 GetParamsForMessage(JSContext* aCx,
                     const JS::Value& aJSON,
                     JSAutoStructuredCloneBuffer& aBuffer,
                     StructuredCloneClosure& aClosure)
 {
-  if (WriteStructuredClone(aCx, aJSON, aBuffer, aClosure)) {
+  JS::Rooted<JS::Value> v(aCx, aJSON);
+  if (WriteStructuredClone(aCx, v, aBuffer, aClosure)) {
     return true;
   }
   JS_ClearPendingException(aCx);
 
   // Not clonable, try JSON
   //XXX This is ugly but currently structured cloning doesn't handle
   //    properly cases when interface is implemented in JS and used
   //    as a dictionary.
   nsAutoString json;
-  JS::Rooted<JS::Value> v(aCx, aJSON);
   NS_ENSURE_TRUE(JS_Stringify(aCx, &v, JS::NullPtr(), JS::NullHandleValue,
                               JSONCreator, &json), false);
   NS_ENSURE_TRUE(!json.IsEmpty(), false);
 
   JS::Rooted<JS::Value> val(aCx, JS::NullValue());
   NS_ENSURE_TRUE(JS_ParseJSON(aCx, static_cast<const jschar*>(json.get()),
                               json.Length(), &val), false);
 
@@ -848,17 +848,17 @@ nsFrameMessageManager::ReceiveMessage(ns
             return NS_ERROR_UNEXPECTED;
           }
         }
 
         JS::RootedValue cpowsv(ctx, JS::ObjectValue(*cpows));
 
         JS::Rooted<JS::Value> json(ctx, JS::NullValue());
         if (aCloneData && aCloneData->mDataLength &&
-            !ReadStructuredClone(ctx, *aCloneData, json.address())) {
+            !ReadStructuredClone(ctx, *aCloneData, &json)) {
           JS_ClearPendingException(ctx);
           return NS_OK;
         }
         JS::Rooted<JSString*> jsMessage(ctx,
           JS_NewUCStringCopyN(ctx,
                               static_cast<const jschar*>(aMessage.BeginReading()),
                               aMessage.Length()));
         NS_ENSURE_TRUE(jsMessage, NS_ERROR_OUT_OF_MEMORY);
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -2176,16 +2176,17 @@ GK_ATOM(select1, "select1")
 GK_ATOM(setsize, "setsize")
 GK_ATOM(spelling, "spelling")
 GK_ATOM(spinbutton, "spinbutton")
 GK_ATOM(status, "status")
 GK_ATOM(tableCellIndex, "table-cell-index")
 GK_ATOM(tablist, "tablist")
 GK_ATOM(textAlign, "text-align")
 GK_ATOM(textIndent, "text-indent")
+GK_ATOM(textInputType, "text-input-type")
 GK_ATOM(textLineThroughColor, "text-line-through-color")
 GK_ATOM(textLineThroughStyle, "text-line-through-style")
 GK_ATOM(textPosition, "text-position")
 GK_ATOM(textUnderlineColor, "text-underline-color")
 GK_ATOM(textUnderlineStyle, "text-underline-style")
 GK_ATOM(timer, "timer")
 GK_ATOM(toolbarname, "toolbarname")
 GK_ATOM(toolbarseparator, "toolbarseparator")
--- a/content/base/src/nsHostObjectProtocolHandler.cpp
+++ b/content/base/src/nsHostObjectProtocolHandler.cpp
@@ -1,33 +1,67 @@
+/* -*- 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 "nsHostObjectProtocolHandler.h"
 #include "nsHostObjectURI.h"
 #include "nsError.h"
 #include "nsClassHashtable.h"
 #include "nsNetUtil.h"
 #include "nsIPrincipal.h"
 #include "nsIDOMFile.h"
 #include "nsIDOMMediaStream.h"
 #include "mozilla/dom/MediaSource.h"
+#include "nsIMemoryReporter.h"
 
 // -----------------------------------------------------------------------
 // Hash table
 struct DataInfo
 {
   // mObject is expected to be an nsIDOMBlob, nsIDOMMediaStream, or MediaSource
   nsCOMPtr<nsISupports> mObject;
   nsCOMPtr<nsIPrincipal> mPrincipal;
 };
 
 static nsClassHashtable<nsCStringHashKey, DataInfo>* gDataTable;
 
+// Memory reporting for the hash table.
+namespace mozilla {
+
+class HostObjectURLsReporter MOZ_FINAL : public MemoryUniReporter
+{
+ public:
+  HostObjectURLsReporter()
+    : MemoryUniReporter("host-object-urls",
+                        KIND_OTHER, UNITS_COUNT,
+                        "The number of host objects stored for access via URLs "
+                        "(e.g. blobs passed to URL.createObjectURL).")
+    {}
+ private:
+  int64_t Amount() MOZ_OVERRIDE
+  {
+    return gDataTable ? gDataTable->Count() : 0;
+  }
+};
+
+}
+
+nsHostObjectProtocolHandler::nsHostObjectProtocolHandler()
+{
+  static bool initialized = false;
+
+  if (!initialized) {
+    initialized = true;
+    NS_RegisterMemoryReporter(new mozilla::HostObjectURLsReporter());
+  }
+}
+
 nsresult
 nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aScheme,
                                           nsISupports* aObject,
                                           nsIPrincipal* aPrincipal,
                                           nsACString& aUri)
 {
   nsresult rv = GenerateURIString(aScheme, aUri);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/content/base/src/nsTextFragment.cpp
+++ b/content/base/src/nsTextFragment.cpp
@@ -418,15 +418,15 @@ nsTextFragment::UpdateBidiFlag(const PRU
       PRUnichar ch1 = *cp++;
       uint32_t utf32Char = ch1;
       if (NS_IS_HIGH_SURROGATE(ch1) &&
           cp < end &&
           NS_IS_LOW_SURROGATE(*cp)) {
         PRUnichar ch2 = *cp++;
         utf32Char = SURROGATE_TO_UCS4(ch1, ch2);
       }
-      if (UTF32_CHAR_IS_BIDI(utf32Char) || IS_BIDI_CONTROL_CHAR(utf32Char)) {
+      if (UTF32_CHAR_IS_BIDI(utf32Char) || IsBidiControl(utf32Char)) {
         mState.mIsBidi = true;
         break;
       }
     }
   }
 }
--- a/content/base/test/mochitest.ini
+++ b/content/base/test/mochitest.ini
@@ -478,16 +478,17 @@ support-files =
 [test_bug698381.html]
 [test_bug698384.html]
 [test_bug702439.html]
 [test_bug702439.html^headers^]
 [test_bug704063.html]
 [test_bug707142.html]
 [test_bug708620.html]
 [test_bug711047.html]
+[test_bug711180.html]
 [test_bug717511.html]
 [test_bug719533.html]
 [test_bug726364.html]
 [test_bug737087.html]
 [test_bug737565.html]
 [test_bug737612.html]
 [test_bug738108.html]
 [test_bug744830.html]
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug711180.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=711180
+-->
+<head>
+  <title>Test for Bug 711180</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=711180">Mozilla Bug 711180</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 711180 **/
+is(atob("aQ=="), atob("\t a\rQ\n=\f="), "Base64 space removal");
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -5,17 +5,16 @@
 
 ifdef MOZ_WEBGL
 LOCAL_INCLUDES += \
 	-I$(topsrcdir)/js/xpconnect/wrappers \
 	$(NULL)
 endif
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 CXXFLAGS	+= $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
 
 INCLUDES	+= \
 		-I$(srcdir)/../../../layout/xul/base/src \
 		-I$(srcdir)/../../../layout/style \
 		-I$(srcdir)/../../../layout/generic \
 		-I$(srcdir)/../../base/src \
--- a/content/canvas/src/moz.build
+++ b/content/canvas/src/moz.build
@@ -10,28 +10,28 @@ EXPORTS.mozilla.dom += [
     'CanvasGradient.h',
     'CanvasPattern.h',
     'CanvasRenderingContext2D.h',
     'CanvasUtils.h',
     'ImageData.h',
     'TextMetrics.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'CanvasImageCache.cpp',
     'CanvasRenderingContext2D.cpp',
     'CanvasUtils.cpp',
     'DocumentRendererChild.cpp',
     'DocumentRendererParent.cpp',
     'ImageData.cpp',
     'ImageEncoder.cpp',
 ]
 
 if CONFIG['MOZ_WEBGL']:
-    CPP_SOURCES += [
+    SOURCES += [
         'WebGL1Context.cpp',
         'WebGL2Context.cpp',
         'WebGLActiveInfo.cpp',
         'WebGLBuffer.cpp',
         'WebGLContext.cpp',
         'WebGLContextAsyncQueries.cpp',
         'WebGLContextBuffers.cpp',
         'WebGLContextExtensions.cpp',
@@ -68,20 +68,22 @@ if CONFIG['MOZ_WEBGL']:
         'WebGLShader.cpp',
         'WebGLShaderPrecisionFormat.cpp',
         'WebGLTexelConversions.cpp',
         'WebGLTexture.cpp',
         'WebGLUniformLocation.cpp',
         'WebGLVertexArray.cpp',
     ]
 else:
-    CPP_SOURCES += [
+    SOURCES += [
         'WebGLContextNotSupported.cpp',
     ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'gkconcvs_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/content/events/src/Makefile.in
+++ b/content/events/src/Makefile.in
@@ -1,15 +1,14 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 LOCAL_INCLUDES	+= \
              -I$(srcdir)/../../base/src \
              -I$(srcdir)/../../html/content/src \
              -I$(srcdir)/../../xul/content/src \
              -I$(srcdir)/../../xml/content/src \
              -I$(srcdir)/../../../dom/base \
              -I$(srcdir)/../../../dom/settings \
--- a/content/events/src/moz.build
+++ b/content/events/src/moz.build
@@ -17,17 +17,17 @@ EXPORTS += [
 
 EXPORTS.mozilla.dom += [
     'Touch.h',
 ]
 
 if CONFIG['MOZ_WEBSPEECH']:
     EXPORTS.mozilla.dom += ['SpeechRecognitionError.h']
 
-CPP_SOURCES += [
+SOURCES += [
     'DOMWheelEvent.cpp',
     'EventTarget.cpp',
     'nsAsyncDOMEvent.cpp',
     'nsContentEventHandler.cpp',
     'nsDOMAnimationEvent.cpp',
     'nsDOMBeforeUnloadEvent.cpp',
     'nsDOMClipboardEvent.cpp',
     'nsDOMCommandEvent.cpp',
@@ -60,18 +60,20 @@ CPP_SOURCES += [
     'nsIMEStateManager.cpp',
     'nsPaintRequest.cpp',
     'nsPrivateTextRange.cpp',
     'TextComposition.cpp',
     'Touch.cpp',
 ]
 
 if CONFIG['MOZ_WEBSPEECH']:
-    CPP_SOURCES += ['SpeechRecognitionError.cpp']
+    SOURCES += ['SpeechRecognitionError.cpp']
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'gkconevents_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -903,18 +903,18 @@ nsEventListenerManager::CompileEventHand
     context->BindCompiledEventHandler(mTarget, scope, handler, &boundHandler);
     if (!boundHandler) {
       listener->ForgetHandler();
     } else if (listener->EventName() == nsGkAtoms::onerror && win) {
       nsRefPtr<OnErrorEventHandlerNonNull> handlerCallback =
         new OnErrorEventHandlerNonNull(boundHandler);
       listener->SetHandler(handlerCallback);
     } else if (listener->EventName() == nsGkAtoms::onbeforeunload && win) {
-      nsRefPtr<BeforeUnloadEventHandlerNonNull> handlerCallback =
-        new BeforeUnloadEventHandlerNonNull(boundHandler);
+      nsRefPtr<OnBeforeUnloadEventHandlerNonNull> handlerCallback =
+        new OnBeforeUnloadEventHandlerNonNull(boundHandler);
       listener->SetHandler(handlerCallback);
     } else {
       nsRefPtr<EventHandlerNonNull> handlerCallback =
         new EventHandlerNonNull(boundHandler);
       listener->SetHandler(handlerCallback);
     }
   }
 
@@ -1250,17 +1250,17 @@ nsEventListenerManager::SetEventHandler(
   // handlers.
   SetEventHandlerInternal(nullptr, JS::NullPtr(), nsGkAtoms::onerror,
                           EmptyString(), nsEventHandler(aHandler),
                           !mIsMainThreadELM ||
                           !nsContentUtils::IsCallerChrome());
 }
 
 void
-nsEventListenerManager::SetEventHandler(BeforeUnloadEventHandlerNonNull* aHandler)
+nsEventListenerManager::SetEventHandler(OnBeforeUnloadEventHandlerNonNull* aHandler)
 {
   if (!aHandler) {
     RemoveEventHandler(nsGkAtoms::onbeforeunload, EmptyString());
     return;
   }
 
   // Untrusted events are always permitted for non-chrome script
   // handlers.
--- a/content/events/src/nsEventListenerManager.h
+++ b/content/events/src/nsEventListenerManager.h
@@ -455,17 +455,17 @@ public:
   /**
    * Set the "inline" event listener for aEventName to aHandler.  If
    * aHandler is null, this will actually remove the event listener
    */
   void SetEventHandler(nsIAtom* aEventName,
                        const nsAString& aTypeString,
                        mozilla::dom::EventHandlerNonNull* aHandler);
   void SetEventHandler(mozilla::dom::OnErrorEventHandlerNonNull* aHandler);
-  void SetEventHandler(mozilla::dom::BeforeUnloadEventHandlerNonNull* aHandler);
+  void SetEventHandler(mozilla::dom::OnBeforeUnloadEventHandlerNonNull* aHandler);
 
   /**
    * Get the value of the "inline" event listener for aEventName.
    * This may cause lazy compilation if the listener is uncompiled.
    *
    * Note: It's the caller's responsibility to make sure to call the right one
    * of these methods.  In particular, "onerror" events use
    * OnErrorEventHandlerNonNull for some event targets and EventHandlerNonNull
@@ -479,21 +479,21 @@ public:
     return handler ? handler->EventHandler() : nullptr;
   }
   mozilla::dom::OnErrorEventHandlerNonNull* GetOnErrorEventHandler()
   {
     const nsEventHandler* handler =
       GetEventHandlerInternal(nsGkAtoms::onerror, EmptyString());
     return handler ? handler->OnErrorEventHandler() : nullptr;
   }
-  mozilla::dom::BeforeUnloadEventHandlerNonNull* GetOnBeforeUnloadEventHandler()
+  mozilla::dom::OnBeforeUnloadEventHandlerNonNull* GetOnBeforeUnloadEventHandler()
   {
     const nsEventHandler* handler =
       GetEventHandlerInternal(nsGkAtoms::onbeforeunload, EmptyString());
-    return handler ? handler->BeforeUnloadEventHandler() : nullptr;
+    return handler ? handler->OnBeforeUnloadEventHandler() : nullptr;
   }
 
 protected:
   /**
    * Helper method for implementing the various Get*EventHandler above.  Will
    * return null if we don't have an event handler for this event name.
    */
   const nsEventHandler* GetEventHandlerInternal(nsIAtom* aEventName,
--- a/content/html/content/src/HTMLBodyElement.cpp
+++ b/content/html/content/src/HTMLBodyElement.cpp
@@ -534,17 +534,17 @@ HTMLBodyElement::IsEventAttributeName(ns
     nsCOMPtr<nsISupports> supports = do_QueryInterface(win);                   \
     nsGlobalWindow* globalWin = nsGlobalWindow::FromSupports(supports);        \
     return globalWin->SetOn##name_(handler);                                   \
   }                                                                            \
   FORWARDED_EVENT_HELPER(name_, HTMLBodyElement, type_, type_*)
 #define WINDOW_EVENT(name_, id_, type_, struct_)                               \
   WINDOW_EVENT_HELPER(name_, EventHandlerNonNull)
 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                         \
-  WINDOW_EVENT_HELPER(name_, BeforeUnloadEventHandlerNonNull)
+  WINDOW_EVENT_HELPER(name_, OnBeforeUnloadEventHandlerNonNull)
 #include "nsEventNameList.h" // IWYU pragma: keep
 #undef BEFOREUNLOAD_EVENT
 #undef WINDOW_EVENT
 #undef WINDOW_EVENT_HELPER
 #undef ERROR_EVENT
 #undef FORWARDED_EVENT
 #undef FORWARDED_EVENT_HELPER
 #undef EVENT
--- a/content/html/content/src/HTMLBodyElement.h
+++ b/content/html/content/src/HTMLBodyElement.h
@@ -8,17 +8,17 @@
 #include "mozilla/Attributes.h"
 #include "nsGenericHTMLElement.h"
 #include "nsIDOMHTMLBodyElement.h"
 #include "nsIStyleRule.h"
 
 namespace mozilla {
 namespace dom {
 
-class BeforeUnloadEventHandlerNonNull;
+class OnBeforeUnloadEventHandlerNonNull;
 class HTMLBodyElement;
 
 class BodyRule: public nsIStyleRule
 {
 public:
   BodyRule(HTMLBodyElement* aPart);
   virtual ~BodyRule();
 
@@ -59,17 +59,17 @@ public:
   NS_IMETHOD GetOn##name_(JSContext *cx, JS::Value *vp);                \
   NS_IMETHOD SetOn##name_(JSContext *cx, const JS::Value &v);
 #define WINDOW_EVENT_HELPER(name_, type_)                               \
   type_* GetOn##name_();                                                \
   void SetOn##name_(type_* handler);
 #define WINDOW_EVENT(name_, id_, type_, struct_)                        \
   WINDOW_EVENT_HELPER(name_, EventHandlerNonNull)
 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                  \
-  WINDOW_EVENT_HELPER(name_, BeforeUnloadEventHandlerNonNull)
+  WINDOW_EVENT_HELPER(name_, OnBeforeUnloadEventHandlerNonNull)
 #include "nsEventNameList.h" // IWYU pragma: keep
 #undef BEFOREUNLOAD_EVENT
 #undef WINDOW_EVENT
 #undef WINDOW_EVENT_HELPER
 #undef FORWARDED_EVENT
 #undef EVENT
 
   void GetText(nsString& aText)
@@ -130,19 +130,16 @@ public:
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual already_AddRefed<nsIEditor> GetAssociatedEditor() MOZ_OVERRIDE;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   virtual bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
 
-private:
-  nsresult GetColorHelper(nsIAtom* aAtom, nsAString& aColor);
-
 protected:
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   nsRefPtr<BodyRule> mContentStyleRule;
 };
 
 } // namespace dom
--- a/content/html/content/src/HTMLFrameSetElement.cpp
+++ b/content/html/content/src/HTMLFrameSetElement.cpp
@@ -393,17 +393,17 @@ HTMLFrameSetElement::IsEventAttributeNam
     nsCOMPtr<nsISupports> supports = do_QueryInterface(win);                   \
     nsGlobalWindow* globalWin = nsGlobalWindow::FromSupports(supports);        \
     return globalWin->SetOn##name_(handler);                                   \
   }                                                                            \
   FORWARDED_EVENT_HELPER(name_, HTMLFrameSetElement, type_, type_*)
 #define WINDOW_EVENT(name_, id_, type_, struct_)                               \
   WINDOW_EVENT_HELPER(name_, EventHandlerNonNull)
 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                         \
-  WINDOW_EVENT_HELPER(name_, BeforeUnloadEventHandlerNonNull)
+  WINDOW_EVENT_HELPER(name_, OnBeforeUnloadEventHandlerNonNull)
 #include "nsEventNameList.h" // IWYU pragma: keep
 #undef BEFOREUNLOAD_EVENT
 #undef WINDOW_EVENT
 #undef WINDOW_EVENT_HELPER
 #undef ERROR_EVENT
 #undef FORWARDED_EVENT
 #undef FORWARDED_EVENT_HELPER
 #undef EVENT
--- a/content/html/content/src/HTMLFrameSetElement.h
+++ b/content/html/content/src/HTMLFrameSetElement.h
@@ -35,17 +35,17 @@ struct nsFramesetSpec {
  */
 #define NS_MAX_FRAMESET_SPEC_COUNT 16000
 
 //----------------------------------------------------------------------
 
 namespace mozilla {
 namespace dom {
 
-class BeforeUnloadEventHandlerNonNull;
+class OnBeforeUnloadEventHandlerNonNull;
 
 class HTMLFrameSetElement MOZ_FINAL : public nsGenericHTMLElement,
                                       public nsIDOMHTMLFrameSetElement
 {
 public:
   HTMLFrameSetElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo),
       mNumRows(0),
@@ -89,17 +89,17 @@ public:
   NS_IMETHOD GetOn##name_(JSContext *cx, JS::Value *vp);                \
   NS_IMETHOD SetOn##name_(JSContext *cx, const JS::Value &v);
 #define WINDOW_EVENT_HELPER(name_, type_)                               \
   type_* GetOn##name_();                                                \
   void SetOn##name_(type_* handler);
 #define WINDOW_EVENT(name_, id_, type_, struct_)                        \
   WINDOW_EVENT_HELPER(name_, EventHandlerNonNull)
 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                  \
-  WINDOW_EVENT_HELPER(name_, BeforeUnloadEventHandlerNonNull)
+  WINDOW_EVENT_HELPER(name_, OnBeforeUnloadEventHandlerNonNull)
 #include "nsEventNameList.h" // IWYU pragma: keep
 #undef BEFOREUNLOAD_EVENT
 #undef WINDOW_EVENT
 #undef WINDOW_EVENT_HELPER
 #undef FORWARDED_EVENT
 #undef EVENT
 
   // These override the SetAttr methods in nsGenericHTMLElement (need
--- a/content/html/content/src/HTMLUnknownElement.cpp
+++ b/content/html/content/src/HTMLUnknownElement.cpp
@@ -1,16 +1,17 @@
 /* -*- 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 "nsDocument.h"
 #include "mozilla/dom/HTMLUnknownElement.h"
 #include "mozilla/dom/HTMLElementBinding.h"
+#include "jsapi.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Unknown)
 
 namespace mozilla {
 namespace dom {
 
 JSObject*
 HTMLUnknownElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
--- a/content/html/content/src/Makefile.in
+++ b/content/html/content/src/Makefile.in
@@ -1,15 +1,14 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 INCLUDES	+= \
 		-I$(srcdir)/../../document/src \
 		-I$(srcdir)/../../../base/src \
 		-I$(srcdir)/../../../events/src \
 		-I$(srcdir)/../../../xbl/src \
 		-I$(srcdir)/../../../xul/content/src \
 		-I$(srcdir)/../../../../layout/forms \
--- a/content/html/content/src/moz.build
+++ b/content/html/content/src/moz.build
@@ -72,17 +72,17 @@ EXPORTS.mozilla.dom += [
     'HTMLUnknownElement.h',
     'MediaError.h',
     'TextTrackManager.h',
     'TimeRanges.h',
     'UndoManager.h',
     'ValidityState.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'HTMLAnchorElement.cpp',
     'HTMLAreaElement.cpp',
     'HTMLAudioElement.cpp',
     'HTMLBodyElement.cpp',
     'HTMLBRElement.cpp',
     'HTMLButtonElement.cpp',
     'HTMLCanvasElement.cpp',
     'HTMLDataElement.cpp',
@@ -159,8 +159,10 @@ CPP_SOURCES += [
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'gkconhtmlcon_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/content/html/document/src/HTMLAllCollection.cpp
+++ b/content/html/document/src/HTMLAllCollection.cpp
@@ -4,16 +4,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/HTMLAllCollection.h"
 
 #include "mozilla/HoldDropJSObjects.h"
 #include "nsDOMClassInfo.h"
 #include "nsHTMLDocument.h"
+#include "jsapi.h"
+#include "js/GCAPI.h"
 
 namespace mozilla {
 namespace dom {
 
 HTMLAllCollection::HTMLAllCollection(nsHTMLDocument* aDocument)
   : mDocument(aDocument)
 {
   MOZ_ASSERT(mDocument);
--- a/content/html/document/src/moz.build
+++ b/content/html/document/src/moz.build
@@ -10,17 +10,17 @@ EXPORTS += [
     'nsIHTMLDocument.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'HTMLAllCollection.h',
     'ImageDocument.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'HTMLAllCollection.cpp',
     'ImageDocument.cpp',
     'MediaDocument.cpp',
     'nsHTMLContentSink.cpp',
     'nsHTMLDocument.cpp',
     'PluginDocument.cpp',
     'VideoDocument.cpp',
 ]
--- a/content/mathml/content/src/Makefile.in
+++ b/content/mathml/content/src/Makefile.in
@@ -1,11 +1,10 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 INCLUDES += \
   -I$(srcdir)/../../../base/src \
   $(NULL)
--- a/content/mathml/content/src/moz.build
+++ b/content/mathml/content/src/moz.build
@@ -1,19 +1,21 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'content'
 
-CPP_SOURCES += [
+SOURCES += [
     'nsMathMLElement.cpp',
     'nsMathMLElementFactory.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'gkcontentmathml_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/content/media/AudioStream.cpp
+++ b/content/media/AudioStream.cpp
@@ -48,17 +48,19 @@ StaticMutex AudioStream::mMutex;
 uint32_t AudioStream::mPreferredSampleRate = 0;
 
 /**
  * When MOZ_DUMP_AUDIO is set in the environment (to anything),
  * we'll drop a series of files in the current working directory named
  * dumped-audio-<nnn>.wav, one per nsBufferedAudioStream created, containing
  * the audio for the stream including any skips due to underruns.
  */
+#if defined(MOZ_CUBEB)
 static int gDumpedAudioCount = 0;
+#endif
 
 static int PrefChanged(const char* aPref, void* aClosure)
 {
   if (strcmp(aPref, PREF_VOLUME_SCALE) == 0) {
     nsAdoptingString value = Preferences::GetString(aPref);
     MutexAutoLock lock(*gAudioPrefsLock);
     if (value.IsEmpty()) {
       gVolumeScale = 1.0;
@@ -73,23 +75,23 @@ static int PrefChanged(const char* aPref
     gCubebLatencyPrefSet = Preferences::HasUserValue(aPref);
     uint32_t value = Preferences::GetUint(aPref, CUBEB_NORMAL_LATENCY_MS);
     MutexAutoLock lock(*gAudioPrefsLock);
     gCubebLatency = std::min<uint32_t>(std::max<uint32_t>(value, 1), 1000);
   }
   return 0;
 }
 
+#if defined(MOZ_CUBEB)
 static double GetVolumeScale()
 {
   MutexAutoLock lock(*gAudioPrefsLock);
   return gVolumeScale;
 }
 
-#if defined(MOZ_CUBEB)
 static cubeb* gCubebContext;
 
 static cubeb* GetCubebContext()
 {
   MutexAutoLock lock(*gAudioPrefsLock);
   if (gCubebContext ||
       cubeb_init(&gCubebContext, "AudioStream") == CUBEB_OK) {
     return gCubebContext;
@@ -461,16 +463,17 @@ int AudioStream::PreferredSampleRate()
     }
 #endif
     mPreferredSampleRate = fallbackSampleRate;
   }
 
   return mPreferredSampleRate;
 }
 
+#if defined(MOZ_CUBEB)
 static void SetUint16LE(uint8_t* aDest, uint16_t aValue)
 {
   aDest[0] = aValue & 0xFF;
   aDest[1] = aValue >> 8;
 }
 
 static void SetUint32LE(uint8_t* aDest, uint32_t aValue)
 {
@@ -530,17 +533,16 @@ WriteDumpFile(FILE* aDumpFile, AudioStre
   uint8_t* output = buf.Elements();
   for (uint32_t i = 0; i < samples; ++i) {
     SetUint16LE(output + i*2, int16_t(input[i]*32767.0f));
   }
   fwrite(output, 2, samples, aDumpFile);
   fflush(aDumpFile);
 }
 
-#if defined(MOZ_CUBEB)
 BufferedAudioStream::BufferedAudioStream()
   : mMonitor("BufferedAudioStream"), mLostFrames(0), mDumpFile(nullptr),
     mVolume(1.0), mBytesPerFrame(0), mState(INITIALIZED)
 {
   AsyncLatencyLogger::Get(true)->AddRef();
 }
 
 BufferedAudioStream::~BufferedAudioStream()
--- a/content/media/Makefile.in
+++ b/content/media/Makefile.in
@@ -1,14 +1,13 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 ifdef MOZ_OMX_DECODER
 DEFINES += -DMOZ_OMX_DECODER
 endif
 
 LOCAL_INCLUDES  += \
   -I$(topsrcdir)/content/base/src \
   -I$(topsrcdir)/layout/generic \
--- a/content/media/MediaDecoderReader.cpp
+++ b/content/media/MediaDecoderReader.cpp
@@ -79,18 +79,18 @@ IsYV12Format(const VideoData::YCbCrBuffe
     aYPlane.mWidth / 2 == aCbPlane.mWidth &&
     aYPlane.mHeight / 2 == aCbPlane.mHeight &&
     aCbPlane.mWidth == aCrPlane.mWidth &&
     aCbPlane.mHeight == aCrPlane.mHeight;
 }
 
 bool
 VideoInfo::ValidateVideoRegion(const nsIntSize& aFrame,
-                                 const nsIntRect& aPicture,
-                                 const nsIntSize& aDisplay)
+                               const nsIntRect& aPicture,
+                               const nsIntSize& aDisplay)
 {
   return
     aFrame.width <= PlanarYCbCrImage::MAX_DIMENSION &&
     aFrame.height <= PlanarYCbCrImage::MAX_DIMENSION &&
     aFrame.width * aFrame.height <= MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT &&
     aFrame.width * aFrame.height != 0 &&
     aPicture.width <= PlanarYCbCrImage::MAX_DIMENSION &&
     aPicture.x < PlanarYCbCrImage::MAX_DIMENSION &&
@@ -101,69 +101,78 @@ VideoInfo::ValidateVideoRegion(const nsI
     aPicture.width * aPicture.height <= MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT &&
     aPicture.width * aPicture.height != 0 &&
     aDisplay.width <= PlanarYCbCrImage::MAX_DIMENSION &&
     aDisplay.height <= PlanarYCbCrImage::MAX_DIMENSION &&
     aDisplay.width * aDisplay.height <= MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT &&
     aDisplay.width * aDisplay.height != 0;
 }
 
-VideoData::  VideoData(int64_t aOffset, int64_t aTime, int64_t aEndTime, int64_t aTimecode)
-  : mOffset(aOffset),
-    mTime(aTime),
-    mEndTime(aEndTime),
+VideoData::VideoData(int64_t aOffset, int64_t aTime, int64_t aDuration, int64_t aTimecode)
+  : MediaData(VIDEO_FRAME, aOffset, aTime, aDuration),
     mTimecode(aTimecode),
     mDuplicate(true),
     mKeyframe(false)
 {
   MOZ_COUNT_CTOR(VideoData);
-  NS_ASSERTION(aEndTime >= aTime, "Frame must start before it ends.");
+  NS_ASSERTION(mDuration >= 0, "Frame must have non-negative duration.");
 }
 
 VideoData::VideoData(int64_t aOffset,
-          int64_t aTime,
-          int64_t aEndTime,
-          bool aKeyframe,
-          int64_t aTimecode,
-          nsIntSize aDisplay)
-  : mDisplay(aDisplay),
-    mOffset(aOffset),
-    mTime(aTime),
-    mEndTime(aEndTime),
+                     int64_t aTime,
+                     int64_t aDuration,
+                     bool aKeyframe,
+                     int64_t aTimecode,
+                     nsIntSize aDisplay)
+  : MediaData(VIDEO_FRAME, aOffset, aTime, aDuration),
+    mDisplay(aDisplay),
     mTimecode(aTimecode),
     mDuplicate(false),
     mKeyframe(aKeyframe)
 {
   MOZ_COUNT_CTOR(VideoData);
-  NS_ASSERTION(aEndTime >= aTime, "Frame must start before it ends.");
+  NS_ASSERTION(mDuration >= 0, "Frame must have non-negative duration.");
 }
 
 VideoData::~VideoData()
 {
   MOZ_COUNT_DTOR(VideoData);
 }
 
+/* static */
+VideoData* VideoData::ShallowCopyUpdateDuration(VideoData* aOther,
+                                                int64_t aDuration)
+{
+  VideoData* v = new VideoData(aOther->mOffset,
+                               aOther->mTime,
+                               aDuration,
+                               aOther->mKeyframe,
+                               aOther->mTimecode,
+                               aOther->mDisplay);
+  v->mImage = aOther->mImage;
+  return v;
+}
 
 VideoData* VideoData::Create(VideoInfo& aInfo,
                              ImageContainer* aContainer,
                              Image* aImage,
                              int64_t aOffset,
                              int64_t aTime,
-                             int64_t aEndTime,
+                             int64_t aDuration,
                              const YCbCrBuffer& aBuffer,
                              bool aKeyframe,
                              int64_t aTimecode,
                              nsIntRect aPicture)
 {
   if (!aImage && !aContainer) {
     // Create a dummy VideoData with no image. This gives us something to
     // send to media streams if necessary.
     nsAutoPtr<VideoData> v(new VideoData(aOffset,
                                          aTime,
-                                         aEndTime,
+                                         aDuration,
                                          aKeyframe,
                                          aTimecode,
                                          aInfo.mDisplay));
     return v.forget();
   }
 
   // The following situation should never happen unless there is a bug
   // in the decoder
@@ -194,17 +203,17 @@ VideoData* VideoData::Create(VideoInfo& 
     // The specified picture dimensions can't be contained inside the video
     // frame, we'll stomp memory if we try to copy it. Fail.
     NS_WARNING("Overflowing picture rect");
     return nullptr;
   }
 
   nsAutoPtr<VideoData> v(new VideoData(aOffset,
                                        aTime,
-                                       aEndTime,
+                                       aDuration,
                                        aKeyframe,
                                        aTimecode,
                                        aInfo.mDisplay));
   const YCbCrBuffer::Plane &Y = aBuffer.mPlanes[0];
   const YCbCrBuffer::Plane &Cb = aBuffer.mPlanes[1];
   const YCbCrBuffer::Plane &Cr = aBuffer.mPlanes[2];
 
   if (!aImage) {
@@ -253,77 +262,77 @@ VideoData* VideoData::Create(VideoInfo& 
 
   return v.forget();
 }
 
 VideoData* VideoData::Create(VideoInfo& aInfo,
                              ImageContainer* aContainer,
                              int64_t aOffset,
                              int64_t aTime,
-                             int64_t aEndTime,
+                             int64_t aDuration,
                              const YCbCrBuffer& aBuffer,
                              bool aKeyframe,
                              int64_t aTimecode,
                              nsIntRect aPicture)
 {
-  return Create(aInfo, aContainer, nullptr, aOffset, aTime, aEndTime, aBuffer,
+  return Create(aInfo, aContainer, nullptr, aOffset, aTime, aDuration, aBuffer,
                 aKeyframe, aTimecode, aPicture);
 }
 
 VideoData* VideoData::Create(VideoInfo& aInfo,
                              Image* aImage,
                              int64_t aOffset,
                              int64_t aTime,
-                             int64_t aEndTime,
+                             int64_t aDuration,
                              const YCbCrBuffer& aBuffer,
                              bool aKeyframe,
                              int64_t aTimecode,
                              nsIntRect aPicture)
 {
-  return Create(aInfo, nullptr, aImage, aOffset, aTime, aEndTime, aBuffer,
+  return Create(aInfo, nullptr, aImage, aOffset, aTime, aDuration, aBuffer,
                 aKeyframe, aTimecode, aPicture);
 }
 
 VideoData* VideoData::CreateFromImage(VideoInfo& aInfo,
                                       ImageContainer* aContainer,
                                       int64_t aOffset,
                                       int64_t aTime,
-                                      int64_t aEndTime,
+                                      int64_t aDuration,
                                       const nsRefPtr<Image>& aImage,
                                       bool aKeyframe,
                                       int64_t aTimecode,
                                       nsIntRect aPicture)
 {
   nsAutoPtr<VideoData> v(new VideoData(aOffset,
                                        aTime,
-                                       aEndTime,
+                                       aDuration,
                                        aKeyframe,
                                        aTimecode,
                                        aInfo.mDisplay));
   v->mImage = aImage;
   return v.forget();
 }
 
 #ifdef MOZ_OMX_DECODER
 VideoData* VideoData::Create(VideoInfo& aInfo,
                              ImageContainer* aContainer,
                              int64_t aOffset,
                              int64_t aTime,
-                             int64_t aEndTime,
+                             int64_t aDuration,
                              mozilla::layers::GraphicBufferLocked* aBuffer,
                              bool aKeyframe,
                              int64_t aTimecode,
                              nsIntRect aPicture)
 {
   if (!aContainer) {
     // Create a dummy VideoData with no image. This gives us something to
     // send to media streams if necessary.
     nsAutoPtr<VideoData> v(new VideoData(aOffset,
                                          aTime,
-                                         aEndTime,
+                                         aDuration,
                                          aKeyframe,
                                          aTimecode,
                                          aInfo.mDisplay));
     return v.forget();
   }
 
   // The following situations could be triggered by invalid input
   if (aPicture.width <= 0 || aPicture.height <= 0) {
@@ -340,17 +349,17 @@ VideoData* VideoData::Create(VideoInfo& 
     // The specified picture dimensions can't be contained inside the video
     // frame, we'll stomp memory if we try to copy it. Fail.
     NS_WARNING("Overflowing picture rect");
     return nullptr;
   }
 
   nsAutoPtr<VideoData> v(new VideoData(aOffset,
                                        aTime,
-                                       aEndTime,
+                                       aDuration,
                                        aKeyframe,
                                        aTimecode,
                                        aInfo.mDisplay));
 
   ImageFormat format = GRALLOC_PLANAR_YCBCR;
   v->mImage = aContainer->CreateImage(&format, 1);
   if (!v->mImage) {
     return nullptr;
@@ -496,17 +505,17 @@ nsresult MediaDecoderReader::DecodeToTar
         if (video) {
           VideoQueue().PushFront(video.forget());
         }
         break;
       }
       video = VideoQueue().PeekFront();
       // If the frame end time is less than the seek target, we won't want
       // to display this frame after the seek, so discard it.
-      if (video && video->mEndTime <= aTarget) {
+      if (video && video->GetEndTime() <= aTarget) {
         if (startTime == -1) {
           startTime = video->mTime;
         }
         VideoQueue().PopFront();
       } else {
         video.forget();
         break;
       }
--- a/content/media/MediaDecoderReader.h
+++ b/content/media/MediaDecoderReader.h
@@ -89,67 +89,94 @@ public:
   {
     return HasVideo() || HasAudio();
   }
 
   VideoInfo mVideo;
   AudioInfo mAudio;
 };
 
+// Container that holds media samples.
+class MediaData {
+public:
+
+  enum Type {
+    AUDIO_SAMPLES = 0,
+    VIDEO_FRAME = 1
+  };
+
+  MediaData(Type aType,
+            int64_t aOffset,
+            int64_t aTimestamp,
+            int64_t aDuration)
+    : mType(aType),
+      mOffset(aOffset),
+      mTime(aTimestamp),
+      mDuration(aDuration)
+  {}
+
+  virtual ~MediaData() {}
+
+  // Type of contained data.
+  const Type mType;
+
+  // Approximate byte offset where this data was demuxed from its media.
+  const int64_t mOffset;
+
+  // Start time of sample, in microseconds.
+  const int64_t mTime;
+
+  // Duration of sample, in microseconds.
+  const int64_t mDuration;
+
+  int64_t GetEndTime() const { return mTime + mDuration; }
+
+};
+
 // Holds chunk a decoded audio frames.
-class AudioData {
+class AudioData : public MediaData {
 public:
 
   AudioData(int64_t aOffset,
             int64_t aTime,
             int64_t aDuration,
             uint32_t aFrames,
             AudioDataValue* aData,
             uint32_t aChannels)
-  : mOffset(aOffset),
-    mTime(aTime),
-    mDuration(aDuration),
+  : MediaData(AUDIO_SAMPLES, aOffset, aTime, aDuration),
     mFrames(aFrames),
     mChannels(aChannels),
     mAudioData(aData)
   {
     MOZ_COUNT_CTOR(AudioData);
   }
 
   ~AudioData()
   {
     MOZ_COUNT_DTOR(AudioData);
   }
 
   // If mAudioBuffer is null, creates it from mAudioData.
   void EnsureAudioBuffer();
 
-  int64_t GetEnd() { return mTime + mDuration; }
-
-  // Approximate byte offset of the end of the page on which this chunk
-  // ends.
-  const int64_t mOffset;
-
-  int64_t mTime; // Start time of data in usecs.
-  const int64_t mDuration; // In usecs.
   const uint32_t mFrames;
   const uint32_t mChannels;
   // At least one of mAudioBuffer/mAudioData must be non-null.
   // mChannels channels, each with mFrames frames
   nsRefPtr<SharedBuffer> mAudioBuffer;
   // mFrames frames, each with mChannels values
   nsAutoArrayPtr<AudioDataValue> mAudioData;
 };
 
 namespace layers {
 class GraphicBufferLocked;
 }
 
 // Holds a decoded video frame, in YCbCr format. These are queued in the reader.
-class VideoData {
+class VideoData : public MediaData {
 public:
   typedef layers::ImageContainer ImageContainer;
   typedef layers::Image Image;
 
   // YCbCr data obtained from decoding the video. The index's are:
   //   0 = Y
   //   1 = Cb
   //   2 = Cr
@@ -174,111 +201,113 @@ public:
   // Returns nsnull if an error occurs. This may indicate that memory couldn't
   // be allocated to create the VideoData object, or it may indicate some
   // problem with the input data (e.g. negative stride).
   static VideoData* Create(VideoInfo& aInfo,
                            ImageContainer* aContainer,
                            Image* aImage,
                            int64_t aOffset,
                            int64_t aTime,
-                           int64_t aEndTime,
+                           int64_t aDuration,
                            const YCbCrBuffer &aBuffer,
                            bool aKeyframe,
                            int64_t aTimecode,
                            nsIntRect aPicture);
 
   // Variant that always makes a copy of aBuffer
   static VideoData* Create(VideoInfo& aInfo,
                            ImageContainer* aContainer,
                            int64_t aOffset,
                            int64_t aTime,
-                           int64_t aEndTime,
+                           int64_t aDuration,
                            const YCbCrBuffer &aBuffer,
                            bool aKeyframe,
                            int64_t aTimecode,
                            nsIntRect aPicture);
 
   // Variant to create a VideoData instance given an existing aImage
   static VideoData* Create(VideoInfo& aInfo,
                            Image* aImage,
                            int64_t aOffset,
                            int64_t aTime,
-                           int64_t aEndTime,
+                           int64_t aDuration,
                            const YCbCrBuffer &aBuffer,
                            bool aKeyframe,
                            int64_t aTimecode,
                            nsIntRect aPicture);
 
   static VideoData* Create(VideoInfo& aInfo,
                            ImageContainer* aContainer,
                            int64_t aOffset,
                            int64_t aTime,
-                           int64_t aEndTime,
+                           int64_t aDuration,
                            layers::GraphicBufferLocked* aBuffer,
                            bool aKeyframe,
                            int64_t aTimecode,
                            nsIntRect aPicture);
 
   static VideoData* CreateFromImage(VideoInfo& aInfo,
                                     ImageContainer* aContainer,
                                     int64_t aOffset,
                                     int64_t aTime,
-                                    int64_t aEndTime,
+                                    int64_t aDuration,
                                     const nsRefPtr<Image>& aImage,
                                     bool aKeyframe,
                                     int64_t aTimecode,
                                     nsIntRect aPicture);
 
+  // Creates a new VideoData identical to aOther, but with a different
+  // specified duration. All data from aOther is copied into the new
+  // VideoData. The new VideoData's mImage field holds a reference to
+  // aOther's mImage, i.e. the Image is not copied. This function is useful
+  // in reader backends that can't determine the duration of a VideoData
+  // until the next frame is decoded, i.e. it's a way to change the const
+  // duration field on a VideoData.
+  static VideoData* ShallowCopyUpdateDuration(VideoData* aOther,
+                                              int64_t aDuration);
+
   // Constructs a duplicate VideoData object. This intrinsically tells the
   // player that it does not need to update the displayed frame when this
   // frame is played; this frame is identical to the previous.
   static VideoData* CreateDuplicate(int64_t aOffset,
                                     int64_t aTime,
-                                    int64_t aEndTime,
+                                    int64_t aDuration,
                                     int64_t aTimecode)
   {
-    return new VideoData(aOffset, aTime, aEndTime, aTimecode);
+    return new VideoData(aOffset, aTime, aDuration, aTimecode);
   }
 
   ~VideoData();
 
-  int64_t GetEnd() { return mEndTime; }
-
   // Dimensions at which to display the video frame. The picture region
   // will be scaled to this size. This is should be the picture region's
   // dimensions scaled with respect to its aspect ratio.
-  nsIntSize mDisplay;
-
-  // Approximate byte offset of the end of the frame in the media.
-  int64_t mOffset;
-
-  // Start time of frame in microseconds.
-  int64_t mTime;
-
-  // End time of frame in microseconds.
-  int64_t mEndTime;
+  const nsIntSize mDisplay;
 
   // Codec specific internal time code. For Ogg based codecs this is the
   // granulepos.
-  int64_t mTimecode;
+  const int64_t mTimecode;
 
   // This frame's image.
   nsRefPtr<Image> mImage;
 
   // When true, denotes that this frame is identical to the frame that
   // came before; it's a duplicate. mBuffer will be empty.
-  bool mDuplicate;
-  bool mKeyframe;
+  const bool mDuplicate;
+  const bool mKeyframe;
 
 public:
-  VideoData(int64_t aOffset, int64_t aTime, int64_t aEndTime, int64_t aTimecode);
+  VideoData(int64_t aOffset,
+            int64_t aTime,
+            int64_t aDuration,
+            int64_t aTimecode);
 
   VideoData(int64_t aOffset,
             int64_t aTime,
-            int64_t aEndTime,
+            int64_t aDuration,
             bool aKeyframe,
             int64_t aTimecode,
             nsIntSize aDisplay);
 
 };
 
 // Thread and type safe wrapper around nsDeque.
 template <class T>
@@ -395,17 +424,17 @@ template <class T> class MediaQueue : pr
   // Elements whose start time is before aTime are ignored.
   void GetElementsAfter(int64_t aTime, nsTArray<T*>* aResult) {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     if (!GetSize())
       return;
     int32_t i;
     for (i = GetSize() - 1; i > 0; --i) {
       T* v = static_cast<T*>(ObjectAt(i));
-      if (v->GetEnd() < aTime)
+      if (v->GetEndTime() < aTime)
         break;
     }
     // Elements less than i have a end time before aTime. It's also possible
     // that the element at i has a end time before aTime, but that's OK.
     for (; i < GetSize(); ++i) {
       aResult->AppendElement(static_cast<T*>(ObjectAt(i)));
     }
   }
--- a/content/media/MediaDecoderStateMachine.cpp
+++ b/content/media/MediaDecoderStateMachine.cpp
@@ -549,17 +549,17 @@ void MediaDecoderStateMachine::SendStrea
                OnStateMachineThread(), "Should be on decode thread or state machine thread");
   mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   if (aAudio->mTime <= aStream->mLastAudioPacketTime) {
     // ignore packet that we've already processed
     return;
   }
   aStream->mLastAudioPacketTime = aAudio->mTime;
-  aStream->mLastAudioPacketEndTime = aAudio->GetEnd();
+  aStream->mLastAudioPacketEndTime = aAudio->GetEndTime();
 
   // This logic has to mimic AudioLoop closely to make sure we write
   // the exact same silences
   CheckedInt64 audioWrittenOffset = UsecsToFrames(mInfo.mAudio.mRate,
       aStream->mInitialTime + mStartTime) + aStream->mAudioFramesWritten;
   CheckedInt64 frameOffset = UsecsToFrames(mInfo.mAudio.mRate, aAudio->mTime);
   if (!audioWrittenOffset.isValid() || !frameOffset.isValid())
     return;
@@ -687,24 +687,24 @@ void MediaDecoderStateMachine::SendStrea
                            v->mTime - (stream->mNextVideoTime + mStartTime)));
         // Write last video frame to catch up. mLastVideoImage can be null here
         // which is fine, it just means there's no video.
         WriteVideoToMediaStream(stream->mLastVideoImage,
           v->mTime - (stream->mNextVideoTime + mStartTime), stream->mLastVideoImageDisplaySize,
             &output);
         stream->mNextVideoTime = v->mTime - mStartTime;
       }
-      if (stream->mNextVideoTime + mStartTime < v->mEndTime) {
+      if (stream->mNextVideoTime + mStartTime < v->GetEndTime()) {
         LOG(PR_LOG_DEBUG, ("%p Decoder writing video frame %lld to MediaStream %p for %lld ms",
                            mDecoder.get(), v->mTime, mediaStream,
-                           v->mEndTime - (stream->mNextVideoTime + mStartTime)));
+                           v->GetEndTime() - (stream->mNextVideoTime + mStartTime)));
         WriteVideoToMediaStream(v->mImage,
-            v->mEndTime - (stream->mNextVideoTime + mStartTime), v->mDisplay,
+            v->GetEndTime() - (stream->mNextVideoTime + mStartTime), v->mDisplay,
             &output);
-        stream->mNextVideoTime = v->mEndTime - mStartTime;
+        stream->mNextVideoTime = v->GetEndTime() - mStartTime;
         stream->mLastVideoImage = v->mImage;
         stream->mLastVideoImageDisplaySize = v->mDisplay;
       } else {
         LOG(PR_LOG_DEBUG, ("%p Decoder skipping writing video frame %lld to MediaStream",
                            mDecoder.get(), v->mTime));
       }
     }
     if (output.GetDuration() > 0) {
@@ -737,17 +737,17 @@ void MediaDecoderStateMachine::SendStrea
       if (!a)
         break;
       // Packet times are not 100% reliable so this may discard packets that
       // actually contain data for mCurrentFrameTime. This means if someone might
       // create a new output stream and we actually don't have the audio for the
       // very start. That's OK, we'll play silence instead for a brief moment.
       // That's OK. Seeking to this time would have a similar issue for such
       // badly muxed resources.
-      if (a->GetEnd() >= minLastAudioPacketTime) {
+      if (a->GetEndTime() >= minLastAudioPacketTime) {
         mReader->AudioQueue().PushFront(a.forget());
         break;
       }
     }
 
     if (finished) {
       mAudioCompleted = true;
       UpdateReadyState();
@@ -2053,17 +2053,17 @@ void MediaDecoderStateMachine::DecodeSee
                               seekTime <= audio->mTime + audio->mDuration),
                     "Seek target should lie inside the first audio block after seek");
       int64_t startTime = (audio && audio->mTime < seekTime) ? audio->mTime : seekTime;
       mAudioStartTime = startTime;
       mPlayDuration = startTime - mStartTime;
       if (HasVideo()) {
         VideoData* video = mReader->VideoQueue().PeekFront();
         if (video) {
-          NS_ASSERTION((video->mTime <= seekTime && seekTime <= video->mEndTime) ||
+          NS_ASSERTION((video->mTime <= seekTime && seekTime <= video->GetEndTime()) ||
                         mReader->VideoQueue().IsFinished(),
             "Seek target should lie inside the first frame after seek, unless it's the last frame.");
           {
             ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
             RenderVideoFrame(video, TimeStamp::Now());
           }
           nsCOMPtr<nsIRunnable> event =
             NS_NewRunnableMethod(mDecoder, &MediaDecoder::Invalidate);
@@ -2491,17 +2491,17 @@ void MediaDecoderStateMachine::AdvanceFr
   NS_ASSERTION(clock_time >= mStartTime, "Should have positive clock time.");
   nsAutoPtr<VideoData> currentFrame;
 #ifdef PR_LOGGING
   int32_t droppedFrames = 0;
 #endif
   if (mReader->VideoQueue().GetSize() > 0) {
     VideoData* frame = mReader->VideoQueue().PeekFront();
     while (mRealTime || clock_time >= frame->mTime) {
-      mVideoFrameEndTime = frame->mEndTime;
+      mVideoFrameEndTime = frame->GetEndTime();
       currentFrame = frame;
 #ifdef PR_LOGGING
       if (!PR_GetEnv("MOZ_QUIET")) {
         LOG(PR_LOG_DEBUG, ("%p Decoder discarding video frame %lld", mDecoder.get(), frame->mTime));
         if (droppedFrames++) {
           LOG(PR_LOG_DEBUG, ("%p Decoder discarding video frame %lld (%d so far)",
             mDecoder.get(), frame->mTime, droppedFrames - 1));
         }
@@ -2567,17 +2567,17 @@ void MediaDecoderStateMachine::AdvanceFr
       ScheduleStateMachine();
       return;
     }
     MediaDecoder::FrameStatistics& frameStats = mDecoder->GetFrameStatistics();
     frameStats.NotifyPresentedFrame();
     double frameDelay = double(clock_time - currentFrame->mTime) / USECS_PER_S;
     NS_ASSERTION(frameDelay >= 0.0, "Frame should never be displayed early.");
     frameStats.NotifyFrameDelay(frameDelay);
-    remainingTime = currentFrame->mEndTime - clock_time;
+    remainingTime = currentFrame->GetEndTime() - clock_time;
     currentFrame = nullptr;
   }
 
   // Cap the current time to the larger of the audio and video end time.
   // This ensures that if we're running off the system clock, we don't
   // advance the clock to after the media end time.
   if (mVideoFrameEndTime != -1 || mAudioEndTime != -1) {
     // These will be non -1 if we've displayed a video frame, or played an audio frame.
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -494,26 +494,28 @@ MediaStreamGraphImpl::UpdateStreamOrderF
       } while (iter && iter != stream);
     }
     if (cycleFound && !delayNodePresent) {
       // If we have detected a cycle, the previous loop should exit with stream
       // == iter, or the node is connected to itself. Go back in the cycle and
       // mute all nodes we find, or just mute the node itself.
       if (!iter) {
         // The node is connected to itself.
+        // There can't be a non-AudioNodeStream here, because only AudioNodes
+        // can be self-connected.
         iter = aStack->getLast();
+        MOZ_ASSERT(iter->AsAudioNodeStream());
         iter->AsAudioNodeStream()->Mute();
       } else {
         MOZ_ASSERT(iter);
         do {
-          // There can't be non-AudioNodeStream here, MediaStreamAudio{Source,
-          // Destination}Node are connected to regular MediaStreams, but they can't be
-          // in a cycle (there is no content API to do so).
-          MOZ_ASSERT(iter->AsAudioNodeStream());
-          iter->AsAudioNodeStream()->Mute();
+          AudioNodeStream* nodeStream = iter->AsAudioNodeStream();
+          if (nodeStream) {
+            nodeStream->Mute();
+          }
         } while((iter = iter->getNext()));
       }
     }
     return;
   }
   ProcessedMediaStream* ps = stream->AsProcessedStream();
   if (ps) {
     aStack->insertBack(stream);
@@ -1479,18 +1481,18 @@ MediaStreamGraphImpl::RunInStableState()
         mLifecycleState = LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN;
         nsCOMPtr<nsIRunnable> event = new MediaStreamGraphShutDownRunnable(this);
         NS_DispatchToMainThread(event);
       }
     } else {
       if (mLifecycleState <= LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP) {
         MessageBlock* block = mMessageQueue.AppendElement();
         block->mMessages.SwapElements(mCurrentTaskMessageQueue);
-        block->mGraphUpdateIndex = mGraphUpdatesSent;
-        ++mGraphUpdatesSent;
+        block->mGraphUpdateIndex = mNextGraphUpdateIndex;
+        ++mNextGraphUpdateIndex;
         EnsureNextIterationLocked(lock);
       }
 
       if (mLifecycleState == LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP) {
         mLifecycleState = LIFECYCLE_RUNNING;
         // Revive the MediaStreamGraph since we have more messages going to it.
         // Note that we need to put messages into its queue before reviving it,
         // or it might exit immediately.
@@ -1915,16 +1917,50 @@ MediaStream::RemoveListener(MediaStreamL
   // If the stream is destroyed the Listeners have or will be
   // removed.
   if (!IsDestroyed()) {
     GraphImpl()->AppendMessage(new Message(this, aListener));
   }
 }
 
 void
+MediaStream::RunAfterPendingUpdates(nsRefPtr<nsIRunnable> aRunnable)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MediaStreamGraphImpl* graph = GraphImpl();
+
+  // Special case when a non-realtime graph has not started, to ensure the
+  // runnable will run in finite time.
+  if (!(graph->mRealtime || graph->mNonRealtimeProcessing)) {
+    aRunnable->Run();
+  }
+
+  class Message : public ControlMessage {
+  public:
+    explicit Message(MediaStream* aStream,
+                     already_AddRefed<nsIRunnable> aRunnable)
+      : ControlMessage(aStream)
+      , mRunnable(aRunnable) {}
+    virtual void Run() MOZ_OVERRIDE
+    {
+      mStream->Graph()->
+        DispatchToMainThreadAfterStreamStateUpdate(mRunnable.forget());
+    }
+    virtual void RunDuringShutdown() MOZ_OVERRIDE
+    {
+      mRunnable->Run();
+    }
+  private:
+    nsRefPtr<nsIRunnable> mRunnable;
+  };
+
+  graph->AppendMessage(new Message(this, aRunnable.forget()));
+}
+
+void
 MediaStream::SetTrackEnabledImpl(TrackID aTrackID, bool aEnabled)
 {
   if (aEnabled) {
     mDisabledTrackIDs.RemoveElement(aTrackID);
   } else {
     if (!mDisabledTrackIDs.Contains(aTrackID)) {
       mDisabledTrackIDs.AppendElement(aTrackID);
     }
--- a/content/media/MediaStreamGraph.h
+++ b/content/media/MediaStreamGraph.h
@@ -341,16 +341,30 @@ public:
   }
   // It's safe to call this even if aListener is not currently a listener;
   // the call will be ignored.
   void RemoveMainThreadListener(MainThreadMediaStreamListener* aListener)
   {
     NS_ASSERTION(NS_IsMainThread(), "Call only on main thread");
     mMainThreadListeners.RemoveElement(aListener);
   }
+  /**
+   * Ensure a runnable will run on the main thread after running all pending
+   * updates that were sent from the graph thread or will be sent before the
+   * graph thread receives the next graph update.
+   *
+   * If the graph has been shutdown or destroyed, or if it is non-realtime
+   * and has not started, then the runnable will be run
+   * synchronously/immediately.  (There are no pending updates in these
+   * situations.)
+   *
+   * Main thread only.
+   */
+  void RunAfterPendingUpdates(nsRefPtr<nsIRunnable> aRunnable);
+
   // Signal that the client is done with this MediaStream. It will be deleted later.
   virtual void Destroy();
   // Returns the main-thread's view of how much data has been processed by
   // this stream.
   StreamTime GetCurrentTime()
   {
     NS_ASSERTION(NS_IsMainThread(), "Call only on main thread");
     return mMainThreadCurrentTime;
@@ -1014,55 +1028,49 @@ public:
   AudioNodeStream* CreateAudioNodeStream(AudioNodeEngine* aEngine,
                                          AudioNodeStreamKind aKind,
                                          TrackRate aSampleRate = 0);
 
   AudioNodeExternalInputStream*
   CreateAudioNodeExternalInputStream(AudioNodeEngine* aEngine,
                                      TrackRate aSampleRate = 0);
 
-  /**
-   * Returns the number of graph updates sent. This can be used to track
-   * whether a given update has been processed by the graph thread and reflected
-   * in main-thread stream state.
-   */
-  int64_t GetCurrentGraphUpdateIndex() { return mGraphUpdatesSent; }
-
   bool IsNonRealtime() const;
   /**
    * Start processing non-realtime for a specific number of ticks.
    */
   void StartNonRealtimeProcessing(uint32_t aTicksToProcess);
 
   /**
    * Media graph thread only.
    * Dispatches a runnable that will run on the main thread after all
    * main-thread stream state has been next updated.
-   * Should only be called during MediaStreamListener callbacks.
+   * Should only be called during MediaStreamListener callbacks or during
+   * ProcessedMediaStream::ProduceOutput().
    */
   void DispatchToMainThreadAfterStreamStateUpdate(already_AddRefed<nsIRunnable> aRunnable)
   {
     *mPendingUpdateRunnables.AppendElement() = aRunnable;
   }
 
 protected:
   MediaStreamGraph()
-    : mGraphUpdatesSent(1)
+    : mNextGraphUpdateIndex(1)
   {
     MOZ_COUNT_CTOR(MediaStreamGraph);
   }
   ~MediaStreamGraph()
   {
     MOZ_COUNT_DTOR(MediaStreamGraph);
   }
 
   // Media graph thread only
   nsTArray<nsCOMPtr<nsIRunnable> > mPendingUpdateRunnables;
 
   // Main thread only
-  // The number of updates we have sent to the media graph thread. We start
-  // this at 1 just to ensure that 0 is usable as a special value.
-  int64_t mGraphUpdatesSent;
+  // The number of updates we have sent to the media graph thread + 1.
+  // We start this at 1 just to ensure that 0 is usable as a special value.
+  int64_t mNextGraphUpdateIndex;
 };
 
 }
 
 #endif /* MOZILLA_MEDIASTREAMGRAPH_H_ */
--- a/content/media/MediaStreamGraphImpl.h
+++ b/content/media/MediaStreamGraphImpl.h
@@ -67,21 +67,21 @@ struct StreamUpdate {
   int64_t mGraphUpdateIndex;
   nsRefPtr<MediaStream> mStream;
   StreamTime mNextMainThreadCurrentTime;
   bool mNextMainThreadFinished;
 };
 
 /**
  * This represents a message passed from the main thread to the graph thread.
- * A ControlMessage always references a particular affected stream.
+ * A ControlMessage always has a weak reference a particular affected stream.
  */
 class ControlMessage {
 public:
-  ControlMessage(MediaStream* aStream) : mStream(aStream)
+  explicit ControlMessage(MediaStream* aStream) : mStream(aStream)
   {
     MOZ_COUNT_CTOR(ControlMessage);
   }
   // All these run on the graph thread
   virtual ~ControlMessage()
   {
     MOZ_COUNT_DTOR(ControlMessage);
   }
--- a/content/media/apple/moz.build
+++ b/content/media/apple/moz.build
@@ -6,17 +6,17 @@
 
 MODULE = 'content'
 
 EXPORTS += [
     'AppleDecoder.h',
     'AppleMP3Reader.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'AppleDecoder.cpp',
     'AppleMP3Reader.cpp',
 ]
 
 LIBRARY_NAME = 'gkconapplemedia_s'
 
 FAIL_ON_WARNINGS = True
 
--- a/content/media/dash/moz.build
+++ b/content/media/dash/moz.build
@@ -8,17 +8,17 @@ MODULE = 'content'
 
 EXPORTS += [
     'DASHDecoder.h',
     'DASHReader.h',
     'DASHRepDecoder.h',
     'DASHRepReader.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'DASHDecoder.cpp',
     'DASHReader.cpp',
     'DASHRepDecoder.cpp',
 ]
 
 LIBRARY_NAME = 'gkcondash_s'
 
 LIBXUL_LIBRARY = True
--- a/content/media/directshow/DirectShowDecoder.cpp
+++ b/content/media/directshow/DirectShowDecoder.cpp
@@ -3,16 +3,19 @@
 /* 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 "DirectShowDecoder.h"
 #include "DirectShowReader.h"
 #include "MediaDecoderStateMachine.h"
 #include "mozilla/Preferences.h"
+#include "WinUtils.h"
+
+using namespace mozilla::widget;
 
 namespace mozilla {
 
 MediaDecoderStateMachine* DirectShowDecoder::CreateStateMachine()
 {
   return new MediaDecoderStateMachine(this, new DirectShowReader(this));
 }
 
@@ -39,17 +42,18 @@ DirectShowDecoder::GetSupportedCodecs(co
 
   return false;
 }
 
 /* static */
 bool
 DirectShowDecoder::IsEnabled()
 {
-  return Preferences::GetBool("media.directshow.enabled");
+  return (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION) &&
+          Preferences::GetBool("media.directshow.enabled");
 }
 
 DirectShowDecoder::DirectShowDecoder()
 {
   MOZ_COUNT_CTOR(DirectShowDecoder);
 }
 
 DirectShowDecoder::~DirectShowDecoder()
--- a/content/media/directshow/moz.build
+++ b/content/media/directshow/moz.build
@@ -9,30 +9,30 @@ MODULE = 'content'
 EXPORTS += [
     'AudioSinkFilter.h',
     'AudioSinkInputPin.h',
     'DirectShowDecoder.h',
     'DirectShowReader.h',
     'DirectShowUtils.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'AudioSinkFilter.cpp',
     'AudioSinkInputPin.cpp',
     'DirectShowDecoder.cpp',
     'DirectShowReader.cpp',
     'DirectShowUtils.cpp',
     'SampleSink.cpp',
     'SourceFilter.cpp',
 ]
 
 # If WebRTC isn't being built, we need to compile the DirectShow base classes so that
 # they're available at link time.
 if not CONFIG['MOZ_WEBRTC']:
-    CPP_SOURCES += [ '%s/%s' % (TOPSRCDIR, p) for p in [
+    SOURCES += [ '%s/%s' % (TOPSRCDIR, p) for p in [
         'media/webrtc/trunk/webrtc/modules/video_capture/windows/BaseFilter.cpp',
         'media/webrtc/trunk/webrtc/modules/video_capture/windows/BaseInputPin.cpp',
         'media/webrtc/trunk/webrtc/modules/video_capture/windows/BasePin.cpp',
         'media/webrtc/trunk/webrtc/modules/video_capture/windows/MediaType.cpp',
     ]]
 
 FAIL_ON_WARNINGS = True
 
--- a/content/media/encoder/moz.build
+++ b/content/media/encoder/moz.build
@@ -7,23 +7,23 @@
 MODULE = 'content'
 
 EXPORTS += [
     'ContainerWriter.h',
     'MediaEncoder.h',
     'TrackEncoder.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'MediaEncoder.cpp',
     'TrackEncoder.cpp',
 ]
 
 if CONFIG['MOZ_OPUS']:
     EXPORTS += ['OpusTrackEncoder.h']
-    CPP_SOURCES += ['OpusTrackEncoder.cpp']
+    SOURCES += ['OpusTrackEncoder.cpp']
 
 LIBRARY_NAME = 'gkconencoder_s'
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
--- a/content/media/gstreamer/GStreamerReader.cpp
+++ b/content/media/gstreamer/GStreamerReader.cpp
@@ -554,35 +554,37 @@ bool GStreamerReader::DecodeVideoFrame(b
   int64_t timestamp = GST_BUFFER_TIMESTAMP(buffer);
   {
     ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
     timestamp = gst_segment_to_stream_time(&mVideoSegment,
                                            GST_FORMAT_TIME, timestamp);
   }
   NS_ASSERTION(GST_CLOCK_TIME_IS_VALID(timestamp),
                "frame has invalid timestamp");
-  int64_t nextTimestamp = timestamp = GST_TIME_AS_USECONDS(timestamp);
-  if (GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(buffer)))
-    nextTimestamp += GST_TIME_AS_USECONDS(GST_BUFFER_DURATION(buffer));
-  else if (fpsNum && fpsDen)
-    /* add 1-frame duration */
-    nextTimestamp += gst_util_uint64_scale(GST_USECOND, fpsNum, fpsDen);
 
+  timestamp = GST_TIME_AS_USECONDS(timestamp);
   if (timestamp < aTimeThreshold) {
     LOG(PR_LOG_DEBUG, ("skipping frame %" GST_TIME_FORMAT
                        " threshold %" GST_TIME_FORMAT,
                        GST_TIME_ARGS(timestamp), GST_TIME_ARGS(aTimeThreshold)));
     gst_buffer_unref(buffer);
     return true;
   }
 
   if (!buffer)
     /* no more frames */
     return false;
 
+  int64_t duration = 0;
+  if (GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(buffer)))
+    duration = GST_TIME_AS_USECONDS(GST_BUFFER_DURATION(buffer));
+  else if (fpsNum && fpsDen)
+    /* 1-frame duration */
+    duration = gst_util_uint64_scale(GST_USECOND, fpsNum, fpsDen);
+
   nsRefPtr<PlanarYCbCrImage> image;
   GstMozVideoBufferData* bufferdata = reinterpret_cast<GstMozVideoBufferData*>
       GST_IS_MOZ_VIDEO_BUFFER(buffer)?gst_moz_video_buffer_get_data(GST_MOZ_VIDEO_BUFFER(buffer)):nullptr;
 
   if(bufferdata)
     image = bufferdata->mImage;
 
   if (!image) {
@@ -616,20 +618,19 @@ bool GStreamerReader::DecodeVideoFrame(b
         i, height);
     b.mPlanes[i].mWidth = gst_video_format_get_component_width(format,
         i, width);
     b.mPlanes[i].mOffset = 0;
     b.mPlanes[i].mSkip = 0;
   }
 
   isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT);
-  /* XXX ? */
-  int64_t offset = 0;
+  int64_t offset = mDecoder->GetResource()->Tell(); // Estimate location in media.
   VideoData* video = VideoData::Create(mInfo.mVideo, image, offset,
-                                       timestamp, nextTimestamp, b,
+                                       timestamp, duration, b,
                                        isKeyframe, -1, mPicture);
   mVideoQueue.Push(video);
   gst_buffer_unref(buffer);
 
   return true;
 }
 
 nsresult GStreamerReader::Seek(int64_t aTarget,
--- a/content/media/gstreamer/moz.build
+++ b/content/media/gstreamer/moz.build
@@ -8,17 +8,17 @@ MODULE = 'content'
 
 EXPORTS += [
     'GStreamerDecoder.h',
     'GStreamerFormatHelper.h',
     'GStreamerLoader.h',
     'GStreamerReader.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'GStreamerDecoder.cpp',
     'GStreamerFormatHelper.cpp',
     'GStreamerLoader.cpp',
     'GStreamerMozVideoBuffer.cpp',
     'GStreamerReader.cpp',
 ]
 
 LIBRARY_NAME = 'gkcongstreamer_s'
--- a/content/media/mediasource/moz.build
+++ b/content/media/mediasource/moz.build
@@ -15,17 +15,17 @@ EXPORTS += [
 ]
 
 EXPORTS.mozilla.dom += [
     'MediaSource.h',
     'SourceBuffer.h',
     'SourceBufferList.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'MediaSource.cpp',
     'MediaSourceDecoder.cpp',
     'SourceBuffer.cpp',
     'SourceBufferList.cpp',
     'SourceBufferResource.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
--- a/content/media/moz.build
+++ b/content/media/moz.build
@@ -101,17 +101,17 @@ EXPORTS.mozilla.dom += [
     'TextTrackCueList.h',
     'TextTrackList.h',
     'TextTrackRegion.h',
     'TextTrackRegionList.h',
     'VideoPlaybackQuality.h',
     'VideoStreamTrack.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'AudioAvailableEventManager.cpp',
     'AudioChannelFormat.cpp',
     'AudioNodeEngine.cpp',
     'AudioNodeExternalInputStream.cpp',
     'AudioNodeStream.cpp',
     'AudioSegment.cpp',
     'AudioStream.cpp',
     'AudioStreamTrack.cpp',
@@ -144,18 +144,20 @@ CPP_SOURCES += [
     'VideoStreamTrack.cpp',
     'VideoUtils.cpp',
     'WebVTTListener.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['BUILD_ARM_NEON']:
-    CPP_SOURCES += [
+    SOURCES += [
         'AudioNodeEngineNEON.cpp',
     ]
 
 LIBXUL_LIBRARY = True
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'gkconmedia_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/content/media/ogg/OggReader.cpp
+++ b/content/media/ogg/OggReader.cpp
@@ -798,17 +798,17 @@ nsresult OggReader::DecodeTheora(ogg_pac
     // The end time of this frame is already before the current playback
     // position. It will never be displayed, don't bother enqueing it.
     return NS_OK;
   }
 
   if (ret == TH_DUPFRAME) {
     VideoData* v = VideoData::CreateDuplicate(mDecoder->GetResource()->Tell(),
                                               time,
-                                              endTime,
+                                              endTime - time,
                                               aPacket->granulepos);
     mVideoQueue.Push(v);
   } else if (ret == 0) {
     th_ycbcr_buffer buffer;
     ret = th_decode_ycbcr_out(mTheoraState->mCtx, buffer);
     NS_ASSERTION(ret == 0, "th_decode_ycbcr_out failed");
     bool isKeyframe = th_packet_iskeyframe(aPacket) == 1;
     VideoData::YCbCrBuffer b;
@@ -819,17 +819,17 @@ nsresult OggReader::DecodeTheora(ogg_pac
       b.mPlanes[i].mStride = buffer[i].stride;
       b.mPlanes[i].mOffset = b.mPlanes[i].mSkip = 0;
     }
 
     VideoData *v = VideoData::Create(mInfo.mVideo,
                                      mDecoder->GetImageContainer(),
                                      mDecoder->GetResource()->Tell(),
                                      time,
-                                     endTime,
+                                     endTime - time,
                                      b,
                                      isKeyframe,
                                      aPacket->granulepos,
                                      mPicture);
     if (!v) {
       // There may be other reasons for this error, but for
       // simplicity just assume the worst case: out of memory.
       NS_WARNING("Failed to allocate memory for video frame");
--- a/content/media/ogg/moz.build
+++ b/content/media/ogg/moz.build
@@ -8,17 +8,17 @@ MODULE = 'content'
 
 EXPORTS += [
     'OggCodecState.h',
     'OggDecoder.h',
     'OggReader.h',
     'OggWriter.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'OggCodecState.cpp',
     'OggDecoder.cpp',
     'OggReader.cpp',
     'OggWriter.cpp',
 ]
 
 LIBRARY_NAME = 'gkconogg_s'
 
--- a/content/media/omx/Makefile.in
+++ b/content/media/omx/Makefile.in
@@ -1,14 +1,13 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 INCLUDES	+= \
  		-I$(srcdir)/mediaresourcemanager \
 		-I$(topsrcdir)/ipc/chromium/src \
 		-I$(srcdir)/../../base/src \
 		-I$(srcdir)/../../html/content/src \
 		-I$(ANDROID_SOURCE)/dalvik/libnativehelper/include/nativehelper \
 		-I$(ANDROID_SOURCE)/frameworks/base/include/ \
--- a/content/media/omx/MediaOmxReader.cpp
+++ b/content/media/omx/MediaOmxReader.cpp
@@ -257,27 +257,27 @@ bool MediaOmxReader::DecodeVideoFrame(bo
       b.mPlanes[2].mWidth = frame.Cr.mWidth;
       b.mPlanes[2].mOffset = frame.Cr.mOffset;
       b.mPlanes[2].mSkip = frame.Cr.mSkip;
 
       v = VideoData::Create(mInfo.mVideo,
                             mDecoder->GetImageContainer(),
                             pos,
                             frame.mTimeUs,
-                            frame.mTimeUs+1, // We don't know the end time.
+                            1, // We don't know the duration.
                             b,
                             frame.mKeyFrame,
                             -1,
                             picture);
     } else {
       v = VideoData::Create(mInfo.mVideo,
                             mDecoder->GetImageContainer(),
                             pos,
                             frame.mTimeUs,
-                            frame.mTimeUs+1, // We don't know the end time.
+                            1, // We don't know the duration.
                             frame.mGraphicBuffer,
                             frame.mKeyFrame,
                             -1,
                             picture);
     }
 
     if (!v) {
       NS_WARNING("Unable to create VideoData");
--- a/content/media/omx/mediaresourcemanager/Makefile.in
+++ b/content/media/omx/mediaresourcemanager/Makefile.in
@@ -1,16 +1,15 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 INCLUDES	+= \
 	        -I$(srcdir)/ \
 		-I$(ANDROID_SOURCE)/frameworks/base/include/ \
 		-I$(ANDROID_SOURCE)/frameworks/base/include/binder/ \
 		-I$(ANDROID_SOURCE)/frameworks/base/include/utils/ \
 		-I$(ANDROID_SOURCE)/frameworks/base/include/media/ \
 		-I$(ANDROID_SOURCE)/frameworks/base/include/media/stagefright/openmax \
--- a/content/media/omx/mediaresourcemanager/moz.build
+++ b/content/media/omx/mediaresourcemanager/moz.build
@@ -1,18 +1,20 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'content'
 
-CPP_SOURCES += [
+SOURCES += [
     'IMediaResourceManagerClient.cpp',
     'IMediaResourceManagerDeathNotifier.cpp',
     'IMediaResourceManagerService.cpp',
     'MediaResourceManagerClient.cpp',
     'MediaResourceManagerService.cpp',
 ]
 
 LIBRARY_NAME = 'mediaresourcemanager'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/content/media/omx/moz.build
+++ b/content/media/omx/moz.build
@@ -6,29 +6,31 @@
 
 MODULE = 'content'
 
 EXPORTS += [
     'MediaOmxDecoder.h',
     'MediaOmxReader.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'MediaOmxDecoder.cpp',
     'MediaOmxReader.cpp',
     'OMXCodecProxy.cpp',
     'OmxDecoder.cpp',
 ]
 
 if CONFIG['MOZ_RTSP']:
     EXPORTS += [
         'RtspOmxDecoder.h',
         'RtspOmxReader.h',
     ]
-    CPP_SOURCES += [
+    SOURCES += [
         'RtspOmxDecoder.cpp',
         'RtspOmxReader.cpp',
     ]
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'gkconomx_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/content/media/plugins/MediaPluginReader.cpp
+++ b/content/media/plugins/MediaPluginReader.cpp
@@ -21,18 +21,17 @@ typedef mozilla::layers::Image Image;
 MediaPluginReader::MediaPluginReader(AbstractMediaDecoder *aDecoder,
                                      const nsACString& aContentType) :
   MediaDecoderReader(aDecoder),
   mType(aContentType),
   mPlugin(nullptr),
   mHasAudio(false),
   mHasVideo(false),
   mVideoSeekTimeUs(-1),
-  mAudioSeekTimeUs(-1),
-  mLastVideoFrame(nullptr)
+  mAudioSeekTimeUs(-1)
 {
 }
 
 MediaPluginReader::~MediaPluginReader()
 {
   ResetDecode();
 }
 
@@ -99,58 +98,57 @@ nsresult MediaPluginReader::ReadMetadata
  *aTags = nullptr;
   return NS_OK;
 }
 
 // Resets all state related to decoding, emptying all buffers etc.
 nsresult MediaPluginReader::ResetDecode()
 {
   if (mLastVideoFrame) {
-    delete mLastVideoFrame;
     mLastVideoFrame = nullptr;
   }
   if (mPlugin) {
     GetMediaPluginHost()->DestroyDecoder(mPlugin);
     mPlugin = nullptr;
   }
 
   return NS_OK;
 }
 
 bool MediaPluginReader::DecodeVideoFrame(bool &aKeyframeSkip,
-                                           int64_t aTimeThreshold)
+                                         int64_t aTimeThreshold)
 {
   // Record number of frames decoded and parsed. Automatically update the
   // stats counters using the AutoNotifyDecoded stack-based class.
   uint32_t parsed = 0, decoded = 0;
   AbstractMediaDecoder::AutoNotifyDecoded autoNotify(mDecoder, parsed, decoded);
 
   // Throw away the currently buffered frame if we are seeking.
   if (mLastVideoFrame && mVideoSeekTimeUs != -1) {
-    delete mLastVideoFrame;
     mLastVideoFrame = nullptr;
   }
 
   ImageBufferCallback bufferCallback(mDecoder->GetImageContainer());
   nsRefPtr<Image> currentImage;
 
   // Read next frame
   while (true) {
     MPAPI::VideoFrame frame;
     if (!mPlugin->ReadVideo(mPlugin, &frame, mVideoSeekTimeUs, &bufferCallback)) {
       // We reached the end of the video stream. If we have a buffered
       // video frame, push it the video queue using the total duration
       // of the video as the end time.
       if (mLastVideoFrame) {
         int64_t durationUs;
         mPlugin->GetDuration(mPlugin, &durationUs);
-        mLastVideoFrame->mEndTime = (durationUs > mLastVideoFrame->mTime)
-                                  ? durationUs
-                                  : mLastVideoFrame->mTime;
-        mVideoQueue.Push(mLastVideoFrame);
+        if (durationUs < mLastVideoFrame->mTime) {
+          durationUs = 0;
+        }
+        mVideoQueue.Push(VideoData::ShallowCopyUpdateDuration(mLastVideoFrame,
+                                                              durationUs));
         mLastVideoFrame = nullptr;
       }
       return false;
     }
     mVideoSeekTimeUs = -1;
 
     if (aKeyframeSkip) {
       // Disable keyframe skipping for now as
@@ -167,17 +165,17 @@ bool MediaPluginReader::DecodeVideoFrame
 
     if (frame.mSize == 0)
       return true;
 
     currentImage = bufferCallback.GetImage();
     int64_t pos = mDecoder->GetResource()->Tell();
     nsIntRect picture = mPicture;
  
-    VideoData *v;
+    nsAutoPtr<VideoData> v;
     if (currentImage) {
       gfxIntSize frameSize = currentImage->GetSize();
       if (frameSize.width != mInitialFrame.width ||
           frameSize.height != mInitialFrame.height) {
         // Frame size is different from what the container reports. This is legal,
         // and we will preserve the ratio of the crop rectangle as it
         // was reported relative to the picture size reported by the container.
         picture.x = (mPicture.x * frameSize.width) / mInitialFrame.width;
@@ -185,17 +183,17 @@ bool MediaPluginReader::DecodeVideoFrame
         picture.width = (frameSize.width * mPicture.width) / mInitialFrame.width;
         picture.height = (frameSize.height * mPicture.height) / mInitialFrame.height;
       }
 
       v = VideoData::CreateFromImage(mInfo.mVideo,
                                      mDecoder->GetImageContainer(),
                                      pos,
                                      frame.mTimeUs,
-                                     frame.mTimeUs+1, // We don't know the end time.
+                                     1, // We don't know the duration yet.
                                      currentImage,
                                      frame.mKeyFrame,
                                      -1,
                                      picture);
     } else {
       // Assume YUV
       VideoData::YCbCrBuffer b;
       b.mPlanes[0].mData = static_cast<uint8_t *>(frame.Y.mData);
@@ -231,17 +229,17 @@ bool MediaPluginReader::DecodeVideoFrame
         picture.height = (frame.Y.mHeight * mPicture.height) / mInitialFrame.height;
       }
 
       // This is the approximate byte position in the stream.
       v = VideoData::Create(mInfo.mVideo,
                             mDecoder->GetImageContainer(),
                             pos,
                             frame.mTimeUs,
-                            frame.mTimeUs+1, // We don't know the end time.
+                            1, // We don't know the duration yet.
                             b,
                             frame.mKeyFrame,
                             -1,
                             picture);
     }
  
     if (!v) {
       return false;
@@ -254,28 +252,31 @@ bool MediaPluginReader::DecodeVideoFrame
     // buffered in MediaPluginReader and push it into the queue as soon
     // we read the following frame so we can use that frame's start time as
     // the end time of the buffered frame.
     if (!mLastVideoFrame) {
       mLastVideoFrame = v;
       continue;
     }
 
-    mLastVideoFrame->mEndTime = v->mTime;
+    // Calculate the duration as the timestamp of the current frame minus the
+    // timestamp of the previous frame. We can then return the previously
+    // decoded frame, and it will have a valid timestamp.
+    int64_t duration = v->mTime - mLastVideoFrame->mTime;
+    mLastVideoFrame = VideoData::ShallowCopyUpdateDuration(mLastVideoFrame, duration);
 
     // We have the start time of the next frame, so we can push the previous
     // frame into the queue, except if the end time is below the threshold,
     // in which case it wouldn't be displayed anyway.
-    if (mLastVideoFrame->mEndTime < aTimeThreshold) {
-      delete mLastVideoFrame;
+    if (mLastVideoFrame->GetEndTime() < aTimeThreshold) {
       mLastVideoFrame = nullptr;
       continue;
     }
 
-    mVideoQueue.Push(mLastVideoFrame);
+    mVideoQueue.Push(mLastVideoFrame.forget());
 
     // Buffer the current frame we just decoded.
     mLastVideoFrame = v;
 
     break;
   }
 
   return true;
--- a/content/media/plugins/MediaPluginReader.h
+++ b/content/media/plugins/MediaPluginReader.h
@@ -5,16 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 #if !defined(MediaPluginReader_h_)
 #define MediaPluginReader_h_
 
 #include "mozilla/Attributes.h"
 #include "MediaResource.h"
 #include "MediaDecoderReader.h"
 #include "ImageContainer.h"
+#include "nsAutoPtr.h"
 #include "mozilla/layers/SharedRGBImage.h"
  
 #include "MPAPI.h"
 
 class nsACString;
 
 namespace mozilla {
 
@@ -33,17 +34,17 @@ class MediaPluginReader : public MediaDe
   nsCString mType;
   MPAPI::Decoder *mPlugin;
   bool mHasAudio;
   bool mHasVideo;
   nsIntRect mPicture;
   nsIntSize mInitialFrame;
   int64_t mVideoSeekTimeUs;
   int64_t mAudioSeekTimeUs;
-  VideoData *mLastVideoFrame;
+  nsAutoPtr<VideoData> mLastVideoFrame;
 public:
   MediaPluginReader(AbstractMediaDecoder* aDecoder,
                     const nsACString& aContentType);
   ~MediaPluginReader();
 
   virtual nsresult Init(MediaDecoderReader* aCloneDonor);
   virtual nsresult ResetDecode();
 
--- a/content/media/plugins/moz.build
+++ b/content/media/plugins/moz.build
@@ -9,17 +9,17 @@ MODULE = 'content'
 EXPORTS += [
     'MediaPluginDecoder.h',
     'MediaPluginHost.h',
     'MediaPluginReader.h',
     'MediaResourceServer.h',
     'MPAPI.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'MediaPluginDecoder.cpp',
     'MediaPluginHost.cpp',
     'MediaPluginReader.cpp',
     'MediaResourceServer.cpp',
 ]
 
 LIBRARY_NAME = 'gkconmediaplugins_s'
 
--- a/content/media/raw/RawReader.cpp
+++ b/content/media/raw/RawReader.cpp
@@ -206,17 +206,17 @@ bool RawReader::DecodeVideoFrame(bool &a
   b.mPlanes[2].mHeight = mMetadata.frameHeight / 2;
   b.mPlanes[2].mWidth = mMetadata.frameWidth / 2;
   b.mPlanes[2].mOffset = b.mPlanes[2].mSkip = 0;
 
   VideoData *v = VideoData::Create(mInfo.mVideo,
                                    mDecoder->GetImageContainer(),
                                    -1,
                                    currentFrameTime,
-                                   currentFrameTime + (USECS_PER_S / mFrameRate),
+                                   (USECS_PER_S / mFrameRate),
                                    b,
                                    1, // In raw video every frame is a keyframe
                                    -1,
                                    mPicture);
   if (!v)
     return false;
 
   mVideoQueue.Push(v);
@@ -260,17 +260,17 @@ nsresult RawReader::Seek(int64_t aTime, 
       ReentrantMonitorAutoEnter autoMonitor(mDecoder->GetReentrantMonitor());
       if (mDecoder->IsShutdown()) {
         mCurrentFrame = frame;
         return NS_ERROR_FAILURE;
       }
     }
 
     nsAutoPtr<VideoData> video(mVideoQueue.PeekFront());
-    if (video && video->mEndTime < aTime) {
+    if (video && video->GetEndTime() < aTime) {
       mVideoQueue.PopFront();
       video = nullptr;
     } else {
       video.forget();
     }
   }
 
   return NS_OK;
--- a/content/media/raw/moz.build
+++ b/content/media/raw/moz.build
@@ -7,17 +7,17 @@
 MODULE = 'content'
 
 EXPORTS += [
     'RawDecoder.h',
     'RawReader.h',
     'RawStructs.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'RawDecoder.cpp',
     'RawReader.cpp',
 ]
 
 LIBRARY_NAME = 'gkconraw_s'
 
 FAIL_ON_WARNINGS = True
 
new file mode 100644
--- /dev/null
+++ b/content/media/test/crashtests/926619.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<script>
+
+function boom()
+{
+  var ac = new window.AudioContext();
+
+  var _ChannelMergerNode = ac.createChannelMerger(4);
+
+  var _MediaStreamAudioDestinationNode = ac.createMediaStreamDestination();
+  var _MediaStream = _MediaStreamAudioDestinationNode.stream;
+  var _MediaStreamAudioSourceNode = ac.createMediaStreamSource(_MediaStream);
+
+  _ChannelMergerNode.connect(_MediaStreamAudioDestinationNode, 0, 0);
+  _MediaStreamAudioSourceNode.connect(_ChannelMergerNode, 0, 0);
+}
+
+</script>
+</head>
+<body onload="boom();"></body>
+</html>
--- a/content/media/test/crashtests/crashtests.list
+++ b/content/media/test/crashtests/crashtests.list
@@ -54,12 +54,13 @@ test-pref(media.webvtt.enabled,true) loa
 load 907986-1.html
 load 907986-2.html
 load 907986-3.html
 load 907986-4.html
 load 910171-1.html
 load 920987.html
 load 925619-1.html
 load 925619-2.html
+load 926619.html
 load offline-buffer-source-ended-1.html
 skip-if(B2G) load oscillator-ended-1.html # intermittent B2G timeouts, bug 920338
 skip-if(B2G) load oscillator-ended-2.html # intermittent B2G timeouts, bug 920338
 test-pref(media.mediasource.enabled,true) load 926665.html
--- a/content/media/wave/moz.build
+++ b/content/media/wave/moz.build
@@ -6,17 +6,17 @@
 
 MODULE = 'content'
 
 EXPORTS += [
     'WaveDecoder.h',
     'WaveReader.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'WaveDecoder.cpp',
     'WaveReader.cpp',
 ]
 
 LIBRARY_NAME = 'gkconwave_s'
 
 FAIL_ON_WARNINGS = True
 
--- a/content/media/webaudio/AudioNode.cpp
+++ b/content/media/webaudio/AudioNode.cpp
@@ -171,17 +171,16 @@ AudioNode::Connect(AudioNode& aDestinati
     ProcessedMediaStream* ps =
       static_cast<ProcessedMediaStream*>(aDestination.mStream.get());
     MOZ_ASSERT(aInput <= UINT16_MAX, "Unexpected large input port number");
     MOZ_ASSERT(aOutput <= UINT16_MAX, "Unexpected large output port number");
     input->mStreamPort =
       ps->AllocateInputPort(mStream, MediaInputPort::FLAG_BLOCK_INPUT,
                             static_cast<uint16_t>(aInput),
                             static_cast<uint16_t>(aOutput));
-    aDestination.NotifyInputConnected();
   }
 
   // This connection may have connected a panner and a source.
   Context()->UpdatePannerSource();
 }
 
 void
 AudioNode::Connect(AudioParam& aDestination, uint32_t aOutput,
@@ -264,26 +263,51 @@ AudioNode::SendTimelineParameterToStream
 void
 AudioNode::Disconnect(uint32_t aOutput, ErrorResult& aRv)
 {
   if (aOutput >= NumberOfOutputs()) {
     aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
     return;
   }
 
+  // An upstream node may be starting to play on the graph thread, and the
+  // engine for a downstream node may be sending a PlayingRefChangeHandler
+  // ADDREF message to this (main) thread.  Wait for a round trip before
+  // releasing nodes, to give engines receiving sound now time to keep their
+  // nodes alive.
+  class RunnableRelease : public nsRunnable {
+  public:
+    explicit RunnableRelease(already_AddRefed<AudioNode> aNode)
+      : mNode(aNode) {}
+
+    NS_IMETHODIMP Run() MOZ_OVERRIDE
+    {
+      mNode = nullptr;
+      return NS_OK;
+    }
+  private:
+    nsRefPtr<AudioNode> mNode;
+  };
+
   for (int32_t i = mOutputNodes.Length() - 1; i >= 0; --i) {
     AudioNode* dest = mOutputNodes[i];
     for (int32_t j = dest->mInputNodes.Length() - 1; j >= 0; --j) {
       InputNode& input = dest->mInputNodes[j];
       if (input.mInputNode == this && input.mOutputPort == aOutput) {
+        // Destroying the InputNode here sends a message to the graph thread
+        // to disconnect the streams, which should be sent before the
+        // RunAfterPendingUpdates() call below.
         dest->mInputNodes.RemoveElementAt(j);
         // Remove one instance of 'dest' from mOutputNodes. There could be
         // others, and it's not correct to remove them all since some of them
         // could be for different output ports.
+        nsRefPtr<nsIRunnable> runnable =
+          new RunnableRelease(mOutputNodes[i].forget());
         mOutputNodes.RemoveElementAt(i);
+        mStream->RunAfterPendingUpdates(runnable.forget());
         break;
       }
     }
   }
 
   for (int32_t i = mOutputParams.Length() - 1; i >= 0; --i) {
     AudioParam* dest = mOutputParams[i];
     for (int32_t j = dest->InputNodes().Length() - 1; j >= 0; --j) {
--- a/content/media/webaudio/AudioNode.h
+++ b/content/media/webaudio/AudioNode.h
@@ -61,17 +61,31 @@ private:
  * The DOM object representing a Web Audio AudioNode.
  *
  * Each AudioNode has a MediaStream representing the actual
  * real-time processing and output of this AudioNode.
  *
  * We track the incoming and outgoing connections to other AudioNodes.
  * Outgoing connections have strong ownership.  Also, AudioNodes that will
  * produce sound on their output even when they have silent or no input ask
- * the AudioContext to keep them alive until the context is finished.
+ * the AudioContext to keep playing or tail-time references to keep them alive
+ * until the context is finished.
+ *
+ * Explicit disconnections will only remove references from output nodes after
+ * the graph is notified and the main thread receives a reply.  Similarly,
+ * nodes with playing or tail-time references release these references only
+ * after receiving notification from their engine on the graph thread that
+ * playing has stopped.  Engines notifying the main thread that they have
+ * finished do so strictly *after* producing and returning their last block.
+ * In this way, an engine that receives non-null input knows that the input
+ * comes from nodes that are still alive and will keep their output nodes
+ * alive for at least as long as it takes to process messages from the graph
+ * thread.  i.e. the engine receiving non-null input knows that its node is
+ * still alive, and will still be alive when it receives a message from the
+ * engine.
  */
 class AudioNode : public nsDOMEventTargetHelper,
                   public EnableWebAudioCheck
 {
 protected:
   // You can only use refcounting to delete this object
   virtual ~AudioNode();
 
@@ -180,18 +194,16 @@ public:
   }
   const nsTArray<nsRefPtr<AudioParam> >& OutputParams() const
   {
     return mOutputParams;
   }
 
   void RemoveOutputParam(AudioParam* aParam);
 
-  virtual void NotifyInputConnected() {}
-
   // MarkActive() asks the context to keep the AudioNode alive until the
   // context is finished.  This takes care of "playing" references and
   // "tail-time" references.
   void MarkActive() { Context()->RegisterActiveNode(this); }
   // Active nodes call MarkInactive() when they have finished producing sound
   // for the foreseeable future.
   // Do not call MarkInactive from a node destructor.  If the destructor is
   // called, then the node is already inactive.
--- a/content/media/webaudio/BiquadFilterNode.cpp
+++ b/content/media/webaudio/BiquadFilterNode.cpp
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "BiquadFilterNode.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "AudioDestinationNode.h"
+#include "PlayingRefChangeHandler.h"
 #include "WebAudioUtils.h"
 #include "blink/Biquad.h"
 #include "mozilla/Preferences.h"
 #include "AudioParamTimeline.h"
 
 namespace mozilla {
 namespace dom {
 
@@ -136,40 +137,76 @@ public:
     }
   }
 
   virtual void ProduceAudioBlock(AudioNodeStream* aStream,
                                  const AudioChunk& aInput,
                                  AudioChunk* aOutput,
                                  bool* aFinished) MOZ_OVERRIDE
   {
+    float inputBuffer[WEBAUDIO_BLOCK_SIZE];
+
     if (aInput.IsNull()) {
-      aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
-      return;
+      bool hasTail = false;
+      for (uint32_t i = 0; i < mBiquads.Length(); ++i) {
+        if (mBiquads[i].hasTail()) {
+          hasTail = true;
+          break;
+        }
+      }
+      if (!hasTail) {
+        if (!mBiquads.IsEmpty()) {
+          mBiquads.Clear();
+
+          nsRefPtr<PlayingRefChangeHandler> refchanged =
+            new PlayingRefChangeHandler(aStream, PlayingRefChangeHandler::RELEASE);
+          aStream->Graph()->
+            DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget());
+        }
+
+        aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
+        return;
+      }
+
+      PodArrayZero(inputBuffer);
+
+    } else if(mBiquads.Length() != aInput.mChannelData.Length()){
+      if (mBiquads.IsEmpty()) {
+        nsRefPtr<PlayingRefChangeHandler> refchanged =
+          new PlayingRefChangeHandler(aStream, PlayingRefChangeHandler::ADDREF);
+        aStream->Graph()->
+          DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget());
+      } else { // Help people diagnose bug 924718
+        NS_WARNING("BiquadFilterNode channel count changes may produce audio glitches");
+      }
+
+      // Adjust the number of biquads based on the number of channels
+      mBiquads.SetLength(aInput.mChannelData.Length());
     }
 
-    // Adjust the number of biquads based on the number of channels
-    const uint32_t numberOfChannels = aInput.mChannelData.Length();
-    mBiquads.SetLength(numberOfChannels);
-
+    uint32_t numberOfChannels = mBiquads.Length();
     AllocateAudioBlock(numberOfChannels, aOutput);
 
     TrackTicks pos = aStream->GetCurrentPosition();
 
     double freq = mFrequency.GetValueAtTime(pos);
     double q = mQ.GetValueAtTime(pos);
     double gain = mGain.GetValueAtTime(pos);
     double detune = mDetune.GetValueAtTime(pos);
 
-    float inputBuffer[WEBAUDIO_BLOCK_SIZE];
     for (uint32_t i = 0; i < numberOfChannels; ++i) {
-      auto input = static_cast<const float*>(aInput.mChannelData[i]);
-      if (aInput.mVolume != 1.0) {
-        AudioBlockCopyChannelWithScale(input, aInput.mVolume, inputBuffer);
+      const float* input;
+      if (aInput.IsNull()) {
         input = inputBuffer;
+      } else {
+        input = static_cast<const float*>(aInput.mChannelData[i]);
+        if (aInput.mVolume != 1.0) {
+          AudioBlockCopyChannelWithScale(input, aInput.mVolume, inputBuffer);
+          input = inputBuffer;
+        }
       }
       SetParamsOnBiquad(mBiquads[i], aStream->SampleRate(), mType, freq, q, gain, detune);
 
       mBiquads[i].process(input,
                           static_cast<float*>(const_cast<void*>(aOutput->mChannelData[i])),
                           aInput.GetDuration());
     }
   }
--- a/content/media/webaudio/ConvolverNode.cpp
+++ b/content/media/webaudio/ConvolverNode.cpp
@@ -19,26 +19,25 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED_1(Con
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ConvolverNode)
 NS_INTERFACE_MAP_END_INHERITING(AudioNode)
 
 NS_IMPL_ADDREF_INHERITED(ConvolverNode, AudioNode)
 NS_IMPL_RELEASE_INHERITED(ConvolverNode, AudioNode)
 
 class ConvolverNodeEngine : public AudioNodeEngine
 {
-  typedef PlayingRefChangeHandler<ConvolverNode> PlayingRefChanged;
+  typedef PlayingRefChangeHandler PlayingRefChanged;
 public:
   ConvolverNodeEngine(AudioNode* aNode, bool aNormalize)
     : AudioNodeEngine(aNode)
     , mBufferLength(0)
     , mLeftOverData(INT32_MIN)
     , mSampleRate(0.0f)
     , mUseBackgroundThreads(!aNode->Context()->IsOffline())
     , mNormalize(aNormalize)
-    , mSeenInput(false)
   {
   }
 
   enum Parameters {
     BUFFER_LENGTH,
     SAMPLE_RATE,
     NORMALIZE
   };
@@ -87,100 +86,94 @@ public:
     // If the reverb is single-threaded and processes entirely in the real-time audio thread,
     // it's important not to make this too high.  In this case 8192 is a good value.
     // But, the Reverb object is multi-threaded, so we want this as high as possible without losing too much accuracy.
     // Very large FFTs will have worse phase errors. Given these constraints 32768 is a good compromise.
     const size_t MaxFFTSize = 32768;
 
     if (!mBuffer || !mBufferLength || !mSampleRate) {
       mReverb = nullptr;
-      mSeenInput = false;
       mLeftOverData = INT32_MIN;
       return;
     }
 
     mReverb = new WebCore::Reverb(mBuffer, mBufferLength,
                                   WEBAUDIO_BLOCK_SIZE,
                                   MaxFFTSize, 2, mUseBackgroundThreads,
                                   mNormalize, mSampleRate);
   }
 
   virtual void ProduceAudioBlock(AudioNodeStream* aStream,
                                  const AudioChunk& aInput,
                                  AudioChunk* aOutput,
                                  bool* aFinished)
   {
-    if (!mSeenInput && aInput.IsNull()) {
-      aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
-      return;
-    }
     if (!mReverb) {
       *aOutput = aInput;
       return;
     }
 
-    mSeenInput = true;
     AudioChunk input = aInput;
     if (aInput.IsNull()) {
-      AllocateAudioBlock(1, &input);
-      WriteZeroesToAudioBlock(&input, 0, WEBAUDIO_BLOCK_SIZE);
-
-      mLeftOverData -= WEBAUDIO_BLOCK_SIZE;
-      if (mLeftOverData <= 0) {
-        // Note: this keeps spamming the main thread with messages as long
-        // as there is nothing to play. This isn't great, but it avoids
-        // problems with some messages being ignored when they're rejected by
-        // ConvolverNode::AcceptPlayingRefRelease.
-        mLeftOverData = 0;
-        nsRefPtr<PlayingRefChanged> refchanged =
-          new PlayingRefChanged(aStream, PlayingRefChanged::RELEASE);
-        NS_DispatchToMainThread(refchanged);
+      if (mLeftOverData > 0) {
+        mLeftOverData -= WEBAUDIO_BLOCK_SIZE;
+        AllocateAudioBlock(1, &input);
+        WriteZeroesToAudioBlock(&input, 0, WEBAUDIO_BLOCK_SIZE);
+      } else {
+        if (mLeftOverData != INT32_MIN) {
+          mLeftOverData = INT32_MIN;
+          nsRefPtr<PlayingRefChanged> refchanged =
+            new PlayingRefChanged(aStream, PlayingRefChanged::RELEASE);
+          aStream->Graph()->
+            DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget());
+        }
+        aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
+        return;
       }
     } else {
       if (aInput.mVolume != 1.0f) {
         // Pre-multiply the input's volume
         uint32_t numChannels = aInput.mChannelData.Length();
         AllocateAudioBlock(numChannels, &input);
         for (uint32_t i = 0; i < numChannels; ++i) {
           const float* src = static_cast<const float*>(aInput.mChannelData[i]);
           float* dest = static_cast<float*>(const_cast<void*>(input.mChannelData[i]));
           AudioBlockCopyChannelWithScale(src, aInput.mVolume, dest);
         }
       }
 
       if (mLeftOverData <= 0) {
         nsRefPtr<PlayingRefChanged> refchanged =
           new PlayingRefChanged(aStream, PlayingRefChanged::ADDREF);
-        NS_DispatchToMainThread(refchanged);
+        aStream->Graph()->
+          DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget());
       }
-      mLeftOverData = mBufferLength + WEBAUDIO_BLOCK_SIZE;
+      mLeftOverData = mBufferLength;
       MOZ_ASSERT(mLeftOverData > 0);
     }
     AllocateAudioBlock(2, aOutput);
 
     mReverb->process(&input, aOutput, WEBAUDIO_BLOCK_SIZE);
   }
 
 private:
   nsRefPtr<ThreadSharedFloatArrayBufferList> mBuffer;
   nsAutoPtr<WebCore::Reverb> mReverb;
   int32_t mBufferLength;
   int32_t mLeftOverData;
   float mSampleRate;
   bool mUseBackgroundThreads;
   bool mNormalize;
-  bool mSeenInput;
 };
 
 ConvolverNode::ConvolverNode(AudioContext* aContext)
   : AudioNode(aContext,
               2,
               ChannelCountMode::Clamped_max,
               ChannelInterpretation::Speakers)
-  , mMediaStreamGraphUpdateIndexAtLastInputConnection(0)
   , mNormalize(true)
 {
   ConvolverNodeEngine* engine = new ConvolverNodeEngine(this, mNormalize);
   mStream = aContext->Graph()->CreateAudioNodeStream(engine, MediaStreamGraph::INTERNAL_STREAM);
 }
 
 JSObject*
 ConvolverNode::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
--- a/content/media/webaudio/ConvolverNode.h
+++ b/content/media/webaudio/ConvolverNode.h
@@ -8,18 +8,16 @@
 #define ConvolverNode_h_
 
 #include "AudioNode.h"
 #include "AudioBuffer.h"
 
 namespace mozilla {
 namespace dom {
 
-template <class T> class PlayingRefChangeHandler;
-
 class ConvolverNode : public AudioNode
 {
 public:
   explicit ConvolverNode(AudioContext* aContext);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ConvolverNode, AudioNode);
 
@@ -51,31 +49,18 @@ public:
   virtual void SetChannelCountModeValue(ChannelCountMode aMode, ErrorResult& aRv) MOZ_OVERRIDE
   {
     if (aMode == ChannelCountMode::Max) {
       aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
       return;
     }
     AudioNode::SetChannelCountModeValue(aMode, aRv);
   }
-  virtual void NotifyInputConnected() MOZ_OVERRIDE
-  {
-    mMediaStreamGraphUpdateIndexAtLastInputConnection =
-      mStream->Graph()->GetCurrentGraphUpdateIndex();
-  }
-  bool AcceptPlayingRefRelease(int64_t aLastGraphUpdateIndexProcessed) const
-  {
-    // Reject any requests to release the playing ref if the request was issued
-    // before the MediaStreamGraph was aware of the most-recently-added input
-    // connection.
-    return aLastGraphUpdateIndexProcessed >= mMediaStreamGraphUpdateIndexAtLastInputConnection;
-  }
 
 private:
-  int64_t mMediaStreamGraphUpdateIndexAtLastInputConnection;
   nsRefPtr<AudioBuffer> mBuffer;
   bool mNormalize;
 };
 
 
 } //end namespace dom
 } //end namespace mozilla
 
--- a/content/media/webaudio/DelayNode.cpp
+++ b/content/media/webaudio/DelayNode.cpp
@@ -22,17 +22,17 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED_1(Del
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DelayNode)
 NS_INTERFACE_MAP_END_INHERITING(AudioNode)
 
 NS_IMPL_ADDREF_INHERITED(DelayNode, AudioNode)
 NS_IMPL_RELEASE_INHERITED(DelayNode, AudioNode)
 
 class DelayNodeEngine : public AudioNodeEngine
 {
-  typedef PlayingRefChangeHandler<DelayNode> PlayingRefChanged;
+  typedef PlayingRefChangeHandler PlayingRefChanged;
 public:
   DelayNodeEngine(AudioNode* aNode, AudioDestinationNode* aDestination,
                   int aMaxDelayFrames)
     : AudioNodeEngine(aNode)
     , mSource(nullptr)
     , mDestination(static_cast<AudioNodeStream*> (aDestination->Stream()))
     // Keep the default value in sync with the default value in DelayNode::DelayNode.
     , mDelay(0.f)
@@ -79,37 +79,39 @@ public:
   {
     MOZ_ASSERT(mSource == aStream, "Invalid source stream");
     MOZ_ASSERT(aStream->SampleRate() == mDestination->SampleRate());
 
     const uint32_t numChannels = aInput.IsNull() ?
                                  mProcessor.BufferChannelCount() :
                                  aInput.mChannelData.Length();
 
-    bool playedBackAllLeftOvers = false;
     if (!aInput.IsNull()) {
       if (mLeftOverData <= 0) {
         nsRefPtr<PlayingRefChanged> refchanged =
           new PlayingRefChanged(aStream, PlayingRefChanged::ADDREF);
-        NS_DispatchToMainThread(refchanged);
+        aStream->Graph()->
+          DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget());
       }
       mLeftOverData = mProcessor.MaxDelayFrames();
-    } else if (mLeftOverData != INT32_MIN) {
+    } else if (mLeftOverData > 0) {
       mLeftOverData -= WEBAUDIO_BLOCK_SIZE;
-      if (mLeftOverData <= 0) {
-        // Continue spamming the main thread with messages until we are destroyed.
-        // This isn't great, but it ensures a message will get through even if
-        // some are ignored by DelayNode::AcceptPlayingRefRelease
-        mLeftOverData = 0;
-        playedBackAllLeftOvers = true;
+    } else {
+      if (mLeftOverData != INT32_MIN) {
+        mLeftOverData = INT32_MIN;
+        // Delete our buffered data now we no longer need it
+        mProcessor.Reset();
 
         nsRefPtr<PlayingRefChanged> refchanged =
           new PlayingRefChanged(aStream, PlayingRefChanged::RELEASE);
-        NS_DispatchToMainThread(refchanged);
+        aStream->Graph()->
+          DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget());
       }
+      *aOutput = aInput;
+      return;
     }
 
     AllocateAudioBlock(numChannels, aOutput);
 
     AudioChunk input = aInput;
     if (!aInput.IsNull() && aInput.mVolume != 1.0f) {
       // Pre-multiply the input's volume
       AllocateAudioBlock(numChannels, &input);
@@ -146,39 +148,32 @@ public:
         float delayAtTick = mDelay.GetValueAtTime(tick, counter) * sampleRate;
         float delayAtTickClamped = inCycle ? std::max(static_cast<float>(WEBAUDIO_BLOCK_SIZE), delayAtTick) :
                                              delayAtTick;
         computedDelay[counter] = delayAtTickClamped;
       }
       mProcessor.Process(computedDelay, inputChannels, outputChannels,
                          numChannels, WEBAUDIO_BLOCK_SIZE);
     }
-
-
-    if (playedBackAllLeftOvers) {
-      // Delete our buffered data once we no longer need it
-      mProcessor.Reset();
-    }
   }
 
   AudioNodeStream* mSource;
   AudioNodeStream* mDestination;
   AudioParamTimeline mDelay;
   DelayProcessor mProcessor;
   // How much data we have in our buffer which needs to be flushed out when our inputs
   // finish.
   int32_t mLeftOverData;
 };
 
 DelayNode::DelayNode(AudioContext* aContext, double aMaxDelay)
   : AudioNode(aContext,
               2,
               ChannelCountMode::Max,
               ChannelInterpretation::Speakers)
-  , mMediaStreamGraphUpdateIndexAtLastInputConnection(0)
   , mDelay(new AudioParam(MOZ_THIS_IN_INITIALIZER_LIST(),
                           SendDelayToStream, 0.0f))
 {
   DelayNodeEngine* engine =
     new DelayNodeEngine(this, aContext->Destination(),
                         ceil(aContext->SampleRate() * aMaxDelay));
   mStream = aContext->Graph()->CreateAudioNodeStream(engine, MediaStreamGraph::INTERNAL_STREAM);
   engine->SetSourceStream(static_cast<AudioNodeStream*> (mStream.get()));
--- a/content/media/webaudio/DelayNode.h
+++ b/content/media/webaudio/DelayNode.h
@@ -9,17 +9,16 @@
 
 #include "AudioNode.h"
 #include "AudioParam.h"
 
 namespace mozilla {
 namespace dom {
 
 class AudioContext;
-template <class T> class PlayingRefChangeHandler;
 
 class DelayNode : public AudioNode
 {
 public:
   DelayNode(AudioContext* aContext, double aMaxDelay);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DelayNode, AudioNode)
@@ -32,35 +31,21 @@ public:
     return mDelay;
   }
 
   virtual const DelayNode* AsDelayNode() const MOZ_OVERRIDE
   {
     return this;
   }
 
-  virtual void NotifyInputConnected() MOZ_OVERRIDE
-  {
-    mMediaStreamGraphUpdateIndexAtLastInputConnection =
-      mStream->Graph()->GetCurrentGraphUpdateIndex();
-  }
-  bool AcceptPlayingRefRelease(int64_t aLastGraphUpdateIndexProcessed) const
-  {
-    // Reject any requests to release the playing ref if the request was issued
-    // before the MediaStreamGraph was aware of the most-recently-added input
-    // connection.
-    return aLastGraphUpdateIndexProcessed >= mMediaStreamGraphUpdateIndexAtLastInputConnection;
-  }
-
 private:
   static void SendDelayToStream(AudioNode* aNode);
   friend class DelayNodeEngine;
 
 private:
-  int64_t mMediaStreamGraphUpdateIndexAtLastInputConnection;
   nsRefPtr<AudioParam> mDelay;
 };
 
 }
 }
 
 #endif
 
deleted file mode 100644
--- a/content/media/webaudio/Makefile.in
+++ /dev/null
@@ -1,6 +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/.
-
-include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/content/media/webaudio/PannerNode.cpp
+++ b/content/media/webaudio/PannerNode.cpp
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "PannerNode.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "AudioListener.h"
 #include "AudioBufferSourceNode.h"
+#include "PlayingRefChangeHandler.h"
 #include "blink/HRTFPanner.h"
 #include "blink/HRTFDatabaseLoader.h"
 
 using WebCore::HRTFDatabaseLoader;
 using WebCore::HRTFPanner;
 
 namespace mozilla {
 namespace dom {
@@ -38,60 +39,57 @@ NS_IMPL_ADDREF_INHERITED(PannerNode, Aud
 NS_IMPL_RELEASE_INHERITED(PannerNode, AudioNode)
 
 class PannerNodeEngine : public AudioNodeEngine
 {
 public:
   explicit PannerNodeEngine(AudioNode* aNode)
     : AudioNodeEngine(aNode)
     // Please keep these default values consistent with PannerNode::PannerNode below.
-    , mPanningModel(PanningModelType::HRTF)
     , mPanningModelFunction(&PannerNodeEngine::HRTFPanningFunction)
-    , mDistanceModel(DistanceModelType::Inverse)
     , mDistanceModelFunction(&PannerNodeEngine::InverseGainFunction)
     , mPosition()
     , mOrientation(1., 0., 0.)
     , mVelocity()
     , mRefDistance(1.)
     , mMaxDistance(10000.)
     , mRolloffFactor(1.)
     , mConeInnerAngle(360.)
     , mConeOuterAngle(360.)
     , mConeOuterGain(0.)
     // These will be initialized when a PannerNode is created, so just initialize them
     // to some dummy values here.
     , mListenerDopplerFactor(0.)
     , mListenerSpeedOfSound(0.)
+    , mLeftOverData(INT_MIN)
   {
     // HRTFDatabaseLoader needs to be fetched on the main thread.
     TemporaryRef<HRTFDatabaseLoader> loader =
       HRTFDatabaseLoader::createAndLoadAsynchronouslyIfNecessary(aNode->Context()->SampleRate());
     mHRTFPanner = new HRTFPanner(aNode->Context()->SampleRate(), loader);
   }
 
   virtual void SetInt32Parameter(uint32_t aIndex, int32_t aParam) MOZ_OVERRIDE
   {
     switch (aIndex) {
     case PannerNode::PANNING_MODEL:
-      mPanningModel = PanningModelType(aParam);
-      switch (mPanningModel) {
+      switch (PanningModelType(aParam)) {
         case PanningModelType::Equalpower:
           mPanningModelFunction = &PannerNodeEngine::EqualPowerPanningFunction;
           break;
         case PanningModelType::HRTF:
           mPanningModelFunction = &PannerNodeEngine::HRTFPanningFunction;
           break;
         default:
           NS_NOTREACHED("We should never see the alternate names here");
           break;
       }
       break;
     case PannerNode::DISTANCE_MODEL:
-      mDistanceModel = DistanceModelType(aParam);
-      switch (mDistanceModel) {
+      switch (DistanceModelType(aParam)) {
         case DistanceModelType::Inverse:
           mDistanceModelFunction = &PannerNodeEngine::InverseGainFunction;
           break;
         case DistanceModelType::Linear:
           mDistanceModelFunction = &PannerNodeEngine::LinearGainFunction;
           break;
         case DistanceModelType::Exponential:
           mDistanceModelFunction = &PannerNodeEngine::ExponentialGainFunction;
@@ -135,16 +133,45 @@ public:
     }
   }
 
   virtual void ProduceAudioBlock(AudioNodeStream* aStream,
                                  const AudioChunk& aInput,
                                  AudioChunk* aOutput,
                                  bool *aFinished) MOZ_OVERRIDE
   {
+    if (aInput.IsNull()) {
+      // mLeftOverData != INT_MIN means that the panning model was HRTF and a
+      // tail-time reference was added.  Even if the model is now equalpower,
+      // the reference will need to be removed.
+      if (mLeftOverData > 0) {
+        mLeftOverData -= WEBAUDIO_BLOCK_SIZE;
+      } else {
+        if (mLeftOverData != INT_MIN) {
+          mLeftOverData = INT_MIN;
+          mHRTFPanner->reset();
+
+          nsRefPtr<PlayingRefChangeHandler> refchanged =
+            new PlayingRefChangeHandler(aStream, PlayingRefChangeHandler::RELEASE);
+          aStream->Graph()->
+            DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget());
+        }
+        *aOutput = aInput;
+        return;
+      }
+    } else if (mPanningModelFunction == &PannerNodeEngine::HRTFPanningFunction) {
+      if (mLeftOverData == INT_MIN) {
+        nsRefPtr<PlayingRefChangeHandler> refchanged =
+          new PlayingRefChangeHandler(aStream, PlayingRefChangeHandler::ADDREF);
+        aStream->Graph()->
+          DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget());
+      }
+      mLeftOverData = mHRTFPanner->maxTailFrames();
+    }
+
     (this->*mPanningModelFunction)(aInput, aOutput);
   }
 
   void ComputeAzimuthAndElevation(float& aAzimuth, float& aElevation);
   void DistanceAndConeGain(AudioChunk* aChunk, float aGain);
   float ComputeConeGain();
   // Compute how much the distance contributes to the gain reduction.
   float ComputeDistanceGain();
@@ -157,20 +184,18 @@ public:
   void EqualPowerPanningFunction(const AudioChunk& aInput, AudioChunk* aOutput);
   void HRTFPanningFunction(const AudioChunk& aInput, AudioChunk* aOutput);
 
   float LinearGainFunction(float aDistance);
   float InverseGainFunction(float aDistance);
   float ExponentialGainFunction(float aDistance);
 
   nsAutoPtr<HRTFPanner> mHRTFPanner;
-  PanningModelType mPanningModel;
   typedef void (PannerNodeEngine::*PanningModelFunction)(const AudioChunk& aInput, AudioChunk* aOutput);
   PanningModelFunction mPanningModelFunction;
-  DistanceModelType mDistanceModel;
   typedef float (PannerNodeEngine::*DistanceModelFunction)(float aDistance);
   DistanceModelFunction mDistanceModelFunction;
   ThreeDPoint mPosition;
   ThreeDPoint mOrientation;
   ThreeDPoint mVelocity;
   double mRefDistance;
   double mMaxDistance;
   double mRolloffFactor;
@@ -178,16 +203,17 @@ public:
   double mConeOuterAngle;
   double mConeOuterGain;
   ThreeDPoint mListenerPosition;
   ThreeDPoint mListenerFrontVector;
   ThreeDPoint mListenerRightVector;
   ThreeDPoint mListenerVelocity;
   double mListenerDopplerFactor;
   double mListenerSpeedOfSound;
+  int mLeftOverData;
 };
 
 PannerNode::PannerNode(AudioContext* aContext)
   : AudioNode(aContext,
               2,
               ChannelCountMode::Clamped_max,
               ChannelInterpretation::Speakers)
   // Please keep these default values consistent with PannerNodeEngine::PannerNodeEngine above.
@@ -278,21 +304,16 @@ PannerNodeEngine::HRTFPanningFunction(co
 
   mHRTFPanner->pan(azimuth, elevation, &input, aOutput, WEBAUDIO_BLOCK_SIZE);
 }
 
 void
 PannerNodeEngine::EqualPowerPanningFunction(const AudioChunk& aInput,
                                             AudioChunk* aOutput)
 {
-  if (aInput.IsNull()) {
-    *aOutput = aInput;
-    return;
-  }
-
   float azimuth, elevation, gainL, gainR, normalizedAzimuth, distanceGain, coneGain;
   int inputChannels = aInput.mChannelData.Length();
 
   // If both the listener are in the same spot, and no cone gain is specified,
   // this node is noop.
   if (mListenerPosition == mPosition &&
       mConeInnerAngle == 360 &&
       mConeOuterAngle == 360) {
--- a/content/media/webaudio/PlayingRefChangeHandler.h
+++ b/content/media/webaudio/PlayingRefChangeHandler.h
@@ -8,52 +8,48 @@
 #define PlayingRefChangeHandler_h__
 
 #include "nsThreadUtils.h"
 #include "AudioNodeStream.h"
 
 namespace mozilla {
 namespace dom {
 
-template<class NodeType>
 class PlayingRefChangeHandler : public nsRunnable
 {
 public:
   enum ChangeType { ADDREF, RELEASE };
   PlayingRefChangeHandler(AudioNodeStream* aStream, ChangeType aChange)
-    : mLastProcessedGraphUpdateIndex(aStream->GetProcessingGraphUpdateIndex())
-    , mStream(aStream)
+    : mStream(aStream)
     , mChange(aChange)
   {
   }
 
   NS_IMETHOD Run()
   {
-    nsRefPtr<NodeType> node;
+    nsRefPtr<AudioNode> node;
     {
       // No need to keep holding the lock for the whole duration of this
       // function, since we're holding a strong reference to it, so if
       // we can obtain the reference, we will hold the node alive in
       // this function.
       MutexAutoLock lock(mStream->Engine()->NodeMutex());
-      node = static_cast<NodeType*>(mStream->Engine()->Node());
+      node = mStream->Engine()->Node();
     }
     if (node) {
       if (mChange == ADDREF) {
         node->MarkActive();
-      } else if (mChange == RELEASE &&
-                 node->AcceptPlayingRefRelease(mLastProcessedGraphUpdateIndex)) {
+      } else if (mChange == RELEASE) {
         node->MarkInactive();
       }
     }
     return NS_OK;
   }
 
 private:
-  int64_t mLastProcessedGraphUpdateIndex;
   nsRefPtr<AudioNodeStream> mStream;
   ChangeType mChange;
 };
 
 }
 }
 
 #endif
--- a/content/media/webaudio/blink/Biquad.h
+++ b/content/media/webaudio/blink/Biquad.h
@@ -61,16 +61,20 @@ public:
     // Set the biquad coefficients given a single zero (other zero will be conjugate)
     // and a single pole (other pole will be conjugate)
     void setZeroPolePairs(const Complex& zero, const Complex& pole);
 
     // Set the biquad coefficients given a single pole (other pole will be conjugate)
     // (The zeroes will be the inverse of the poles)
     void setAllpassPole(const Complex& pole);
 
+    // Return true iff the next output block will contain sound even with
+    // silent input.
+    bool hasTail() const { return m_y1 || m_y2 || m_x1 || m_x2; }
+
     // Resets filter state
     void reset();
 
     // Filter response at a set of n frequencies. The magnitude and
     // phase response are returned in magResponse and phaseResponse.
     // The phase response is in radians.
     void getFrequencyResponse(int nFrequencies,
                               const float* frequency,
--- a/content/media/webaudio/blink/HRTFPanner.cpp
+++ b/content/media/webaudio/blink/HRTFPanner.cpp
@@ -42,19 +42,18 @@ const double MaxDelayTimeSeconds = 0.002
 const int UninitializedAzimuth = -1;
 const unsigned RenderingQuantum = 128;
 
 HRTFPanner::HRTFPanner(float sampleRate, mozilla::TemporaryRef<HRTFDatabaseLoader> databaseLoader)
     : m_databaseLoader(databaseLoader)
     , m_sampleRate(sampleRate)
     , m_crossfadeSelection(CrossfadeSelection1)
     , m_azimuthIndex1(UninitializedAzimuth)
-    , m_elevation1(0)
     , m_azimuthIndex2(UninitializedAzimuth)
-    , m_elevation2(0)
+    // m_elevation1 and m_elevation2 are initialized in pan()
     , m_crossfadeX(0)
     , m_crossfadeIncr(0)
     , m_convolverL1(HRTFElevation::fftSizeForSampleRate(sampleRate))
     , m_convolverR1(m_convolverL1.fftSize())
     , m_convolverL2(m_convolverL1.fftSize())
     , m_convolverR2(m_convolverL1.fftSize())
     , m_delayLineL(ceilf(MaxDelayTimeSeconds * sampleRate),
                    WebAudioUtils::ComputeSmoothingRate(0.02, sampleRate))
@@ -72,16 +71,22 @@ HRTFPanner::HRTFPanner(float sampleRate,
 
 HRTFPanner::~HRTFPanner()
 {
     MOZ_COUNT_DTOR(HRTFPanner);
 }
 
 void HRTFPanner::reset()
 {
+    m_azimuthIndex1 = UninitializedAzimuth;
+    m_azimuthIndex2 = UninitializedAzimuth;
+    // m_elevation1 and m_elevation2 are initialized in pan()
+    m_crossfadeSelection = CrossfadeSelection1;
+    m_crossfadeX = 0.0f;
+    m_crossfadeIncr = 0.0f;
     m_convolverL1.reset();
     m_convolverR1.reset();
     m_convolverL2.reset();
     m_convolverR2.reset();
     m_delayLineL.Reset();
     m_delayLineR.Reset();
 }
 
@@ -280,24 +285,21 @@ void HRTFPanner::pan(double desiredAzimu
                 m_crossfadeSelection = CrossfadeSelection1;
                 m_crossfadeX = 0;
                 m_crossfadeIncr = 0;
             }
         }
     }
 }
 
-double HRTFPanner::tailTime() const
+int HRTFPanner::maxTailFrames() const
 {
-    // Because HRTFPanner is implemented with a DelayKernel and a FFTConvolver, the tailTime of the HRTFPanner
-    // is the sum of the tailTime of the DelayKernel and the tailTime of the FFTConvolver, which is MaxDelayTimeSeconds
-    // and fftSize() / 2, respectively.
-    return MaxDelayTimeSeconds + (fftSize() / 2) / static_cast<double>(sampleRate());
-}
-
-double HRTFPanner::latencyTime() const
-{
-    // The latency of a FFTConvolver is also fftSize() / 2, and is in addition to its tailTime of the
-    // same value.
-    return (fftSize() / 2) / static_cast<double>(sampleRate());
+    // Although the ideal tail time would be the length of the impulse
+    // response, there is additional tail time from the approximations in the
+    // implementation.  Because HRTFPanner is implemented with a DelayKernel
+    // and a FFTConvolver, the tailTime of the HRTFPanner is the sum of the
+    // tailTime of the DelayKernel and the tailTime of the FFTConvolver.
+    // The FFTConvolver has a tail time of fftSize(), including latency of
+    // fftSize()/2.
+    return m_delayLineL.MaxDelayFrames() + fftSize();
 }
 
 } // namespace WebCore
--- a/content/media/webaudio/blink/HRTFPanner.h
+++ b/content/media/webaudio/blink/HRTFPanner.h
@@ -46,18 +46,17 @@ public:
     // framesToProcess must be a power of 2 and greater than 128
     void pan(double azimuth, double elevation, const AudioChunk* inputBus, AudioChunk* outputBus, mozilla::TrackTicks framesToProcess);
     void reset();
 
     size_t fftSize() const { return m_convolverL1.fftSize(); }
 
     float sampleRate() const { return m_sampleRate; }
 
-    double tailTime() const;
-    double latencyTime() const;
+    int maxTailFrames() const;
 
 private:
     // Given an azimuth angle in the range -180 -> +180, returns the corresponding azimuth index for the database,
     // and azimuthBlend which is an interpolation value from 0 -> 1.
     int calculateDesiredAzimuthIndexAndBlend(double azimuth, double& azimuthBlend);
 
     mozilla::RefPtr<HRTFDatabaseLoader> m_databaseLoader;
 
--- a/content/media/webaudio/blink/Makefile.in
+++ b/content/media/webaudio/blink/Makefile.in
@@ -1,8 +1,7 @@
 # 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/.
 
 LOCAL_INCLUDES += -I$(topsrcdir)/content/media/webaudio
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/content/media/webaudio/blink/moz.build
+++ b/content/media/webaudio/blink/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'content'
 
-CPP_SOURCES += [
+SOURCES += [
     'Biquad.cpp',
     'DirectConvolver.cpp',
     'DynamicsCompressor.cpp',
     'DynamicsCompressorKernel.cpp',
     'FFTConvolver.cpp',
     'HRTFDatabase.cpp',
     'HRTFDatabaseLoader.cpp',
     'HRTFElevation.cpp',
@@ -25,8 +25,10 @@ CPP_SOURCES += [
     'ReverbInputBuffer.cpp',
     'ZeroPole.cpp',
 ]
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'gkconwebaudio_blink_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/content/media/webaudio/moz.build
+++ b/content/media/webaudio/moz.build
@@ -45,17 +45,17 @@ EXPORTS.mozilla.dom += [
     'OfflineAudioCompletionEvent.h',
     'OscillatorNode.h',
     'PannerNode.h',
     'PeriodicWave.h',
     'ScriptProcessorNode.h',
     'WaveShaperNode.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'AnalyserNode.cpp',
     'AudioBuffer.cpp',
     'AudioBufferSourceNode.cpp',
     'AudioContext.cpp',
     'AudioDestinationNode.cpp',
     'AudioListener.cpp',
     'AudioNode.cpp',
     'AudioParam.cpp',
@@ -85,8 +85,10 @@ CPP_SOURCES += [
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'gkconwebaudio_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/content/media/webaudio/test/mochitest.ini
+++ b/content/media/webaudio/test/mochitest.ini
@@ -42,16 +42,17 @@ support-files =
 [test_audioParamLinearRamp.html]
 [test_audioParamSetCurveAtTime.html]
 [test_audioParamSetCurveAtTimeZeroDuration.html]
 [test_audioParamSetTargetAtTime.html]
 [test_audioParamSetValueAtTime.html]
 [test_audioParamTimelineDestinationOffset.html]
 [test_badConnect.html]
 [test_biquadFilterNode.html]
+[test_biquadFilterNodeWithGain.html]
 [test_bug808374.html]
 [test_bug827541.html]
 [test_bug839753.html]
 [test_bug845960.html]
 [test_bug856771.html]
 [test_bug866570.html]
 [test_bug866737.html]
 [test_bug867089.html]
@@ -71,16 +72,17 @@ support-files =
 [test_convolverNode_mono_mono.html]
 [test_currentTime.html]
 [test_decodeMultichannel.html]
 [test_delayNode.html]
 [test_delayNodeAtMax.html]
 [test_delayNodeCycles.html]
 [test_delayNodeSmallMaxDelay.html]
 [test_delayNodeTailIncrease.html]
+[test_delayNodeTailWithDisconnect.html]
 [test_delayNodeTailWithGain.html]
 [test_delayNodeTailWithReconnect.html]
 [test_delayNodeWithGain.html]
 [test_dynamicsCompressorNode.html]
 [test_gainNode.html]
 [test_gainNodeInLoop.html]
 [test_maxChannelCount.html]
 [test_mediaDecoding.html]
@@ -95,16 +97,17 @@ support-files =
 [test_offlineDestinationChannelCountMore.html]
 [test_oscillatorNode.html]
 [test_oscillatorNode2.html]
 [test_oscillatorNodeStart.html]
 [test_oscillatorTypeChange.html]
 [test_pannerNode.html]
 [test_pannerNodeAbove.html]
 [test_pannerNodeChannelCount.html]
+[test_pannerNodeTail.html]
 [test_pannerNode_equalPower.html]
 [test_periodicWave.html]
 [test_scriptProcessorNode.html]
 [test_scriptProcessorNodeChannelCount.html]
 [test_scriptProcessorNodeZeroInputOutput.html]
 [test_singleSourceDest.html]
 [test_waveShaper.html]
 [test_waveShaperNoCurve.html]
new file mode 100644
--- /dev/null
+++ b/content/media/webaudio/test/test_biquadFilterNodeWithGain.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test BiquadFilterNode after a GainNode and tail - Bugs 924286 and 924288</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test">
+<script src="webaudio.js" type="text/javascript"></script>
+<script class="testbody" type="text/javascript">
+
+const signalLength = 2048;
+
+var gTest = {
+  length: signalLength,
+  numberOfChannels: 1,
+  createGraph: function(context) {
+    // Two oscillators scheduled sequentially
+    var signalDuration = signalLength / context.sampleRate;
+    var osc1 = context.createOscillator();
+    osc1.type = "square";
+    osc1.start(0);
+    osc1.stop(signalDuration / 2);
+    var osc2 = context.createOscillator();
+    osc2.start(signalDuration / 2);
+    osc2.stop(signalDuration);
+
+    // Comparing a biquad on each source with one on both sources checks that
+    // the biquad on the first source doesn't shut down early.
+    var biquad1 = context.createBiquadFilter();
+    osc1.connect(biquad1);
+    var biquad2 = context.createBiquadFilter();
+    osc2.connect(biquad2);
+
+    var gain = context.createGain();
+    gain.gain.value = -1;
+    osc1.connect(gain);
+    osc2.connect(gain);
+
+    var biquadWithGain = context.createBiquadFilter();
+    gain.connect(biquadWithGain);
+
+    // The output of biquadWithGain should be the inverse of the sum of the
+    // outputs of biquad1 and biquad2, so blend them together and expect
+    // silence.
+    var blend = context.createGain();
+    biquad1.connect(blend);
+    biquad2.connect(blend);
+    biquadWithGain.connect(blend);
+
+    return blend;
+  },
+};
+
+runTest();
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/webaudio/test/test_delayNodeTailWithDisconnect.html
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test tail time lifetime of DelayNode after input is disconnected</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="webaudio.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// Web Audio doesn't provide a means to precisely time disconnect()s but we
+// can test that the output of delay nodes matches the output from their
+// sources before they are disconnected.
+
+SimpleTest.waitForExplicitFinish();
+
+const signalLength = 128;
+const bufferSize = 4096;
+const sourceCount = bufferSize / signalLength;
+// Delay should be long enough to allow CC to run
+var delayBufferCount = 20;
+const delayLength = delayBufferCount * bufferSize;
+
+var sourceOutput = new Float32Array(bufferSize);
+var delayOutputCount = 0;
+var sources = [];
+
+function onDelayOutput(e) {
+  if (delayOutputCount < delayBufferCount) {
+    delayOutputCount++;
+    return;
+  }
+
+  compareBuffers(e.inputBuffer.getChannelData(0), sourceOutput);
+  e.target.onaudioprocess = null;
+  SimpleTest.finish();
+}
+
+function onSourceOutput(e) {
+  // Record the first buffer
+  e.inputBuffer.copyFromChannel(sourceOutput, 0);
+  e.target.onaudioprocess = null;
+}
+
+function disconnectSources() {
+  dump("disconnecting\n")
+  for (var i = 0; i < sourceCount; ++i) {
+    sources[i].disconnect();
+  }
+
+  SpecialPowers.forceGC();
+  SpecialPowers.forceCC();
+  dump("forced GC\n");
+}
+
+function startTest() {
+  var ctx = new AudioContext();
+
+  var sourceProcessor = ctx.createScriptProcessor(bufferSize, 1, 0);
+  sourceProcessor.onaudioprocess = onSourceOutput;
+  // Keep audioprocess events going after source disconnect.
+  sourceProcessor.connect(ctx.destination);
+
+  var delayProcessor = ctx.createScriptProcessor(bufferSize, 1, 0);
+  delayProcessor.onaudioprocess = onDelayOutput;
+  // Work around bug 916387.
+  delayProcessor.connect(ctx.destination);
+
+  var delayDuration = delayLength / ctx.sampleRate;
+  for (var i = 0; i < sourceCount; ++i) {
+    var delay = ctx.createDelay(delayDuration);
+    delay.delayTime.value = delayDuration;
+    delay.connect(delayProcessor);
+
+    var source = ctx.createOscillator();
+    source.frequency.value = 440 + 10 * i
+    source.start(i * signalLength / ctx.sampleRate);
+    source.stop((i + 1) * signalLength / ctx.sampleRate);
+    source.connect(delay);
+    source.connect(sourceProcessor);
+
+    sources[i] = source;
+  }
+
+  // Assuming the above Web Audio operations have already scheduled an event
+  // to run in stable state and start the graph thread, schedule a subsequent
+  // event to disconnect the sources, which will remove main thread connection
+  // references before it knows the graph thread has started using the source
+  // streams.
+  SimpleTest.executeSoon(disconnectSources);
+};
+
+startTest();
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/webaudio/test/test_pannerNodeTail.html
@@ -0,0 +1,203 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test tail time lifetime of PannerNode</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="webaudio.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// This tests that a PannerNode does not release its reference before
+// it finishes emitting sound.
+//
+// The PannerNode tail time is short, so, when a PannerNode is destroyed on
+// the main thread, it is unlikely to notify the graph thread before the tail
+// time expires.  However, by adding DelayNodes downstream from the
+// PannerNodes, the graph thread can have enough time to notice that a
+// DelayNode has been destroyed.
+//
+// In the current implementation, DelayNodes will take a tail-time reference
+// immediately when they receive the first block of sound from an upstream
+// node, so this test connects the downstream DelayNodes while the upstream
+// nodes are finishing, and then runs GC (on the main thread) before the
+// DelayNodes receive any input (on the graph thread).
+//
+// Web Audio doesn't provide a means to precisely time connect()s but we can
+// test that the output of delay nodes matches the output from a reference
+// PannerNodes that we know will not be GCed.
+//
+// Another set of delay nodes is added upstream to ensure that the source node
+// has removed its self-reference after dispatching its "ended" event.
+
+SimpleTest.waitForExplicitFinish();
+
+const blockSize = 128;
+// bufferSize should be long enough that to allow an audioprocess event to be
+// sent to the main thread and a connect message to return to the graph
+// thread.
+const bufferSize = 4096;
+const pannerCount = bufferSize / blockSize;
+// sourceDelayBufferCount should be long enough to allow the source node
+// onended to finish.  Because of the way blocks are processed in sets on
+// the graph thread, this also affects when the graph thread receives the
+// disconnect.
+const sourceDelayBufferCount = 3;
+var gotEnded = false;
+// ccDelayLength should be long enough to allow CC to run
+var ccDelayBufferCount = 20;
+const ccDelayLength = ccDelayBufferCount * bufferSize;
+
+var testPanners = [];
+var referencePanner;
+var referenceProcessCount = 0;
+var referenceOutput = [new Float32Array(bufferSize),
+                       new Float32Array(bufferSize)];
+var testProcessor;
+var testProcessCount = 0;
+
+function onReferenceOutput(e) {
+  switch(referenceProcessCount) {
+
+  case sourceDelayBufferCount - 1:
+    // The panners are about to finish.
+    if (!gotEnded) {
+      todo(false, "Oscillator hasn't ended.  Increase sourceDelayBufferCount?");
+    }
+
+    // Connect each PannerNode output to a downstream DelayNode,
+    // and connect ScriptProcessors to compare test and reference panners.
+    var ctx = e.target.context;
+    var delayDuration = ccDelayLength / ctx.sampleRate;
+    for (var i = 0; i < pannerCount; ++i) {
+      var delay = ctx.createDelay(delayDuration);
+      delay.delayTime.value = delayDuration;
+      delay.connect(testProcessor);
+      testPanners[i].connect(delay);
+    }
+    testProcessor = null;
+    testPanners = null;
+
+    referencePanner.connect(e.target);
+
+    // Assuming the above operations have already scheduled an event to run in
+    // stable state and ask the graph thread to make connections, schedule a
+    // subsequent event to run cycle collection, which should not collect
+    // panners that are still producing sound.
+    SimpleTest.executeSoon(function() {
+      SpecialPowers.forceGC();
+      SpecialPowers.forceCC();
+    });
+
+    break;
+
+  case sourceDelayBufferCount:
+    // Record this buffer during which PannerNode outputs were connected.
+    for (var i = 0; i < 2; ++i) {
+      e.inputBuffer.copyFromChannel(referenceOutput[i], i);
+    }
+    e.target.onaudioprocess = null;
+    e.target.disconnect();
+
+    for (var i = 0; i < referenceOutput[0].length; ++i) {
+      if (referenceOutput[0][i] != 0.0) {
+        return; // good - a connection must have been received by the graph
+      }
+    }
+    // If the buffer is silent, there is probably not much point just
+    // increasing the buffer size, because, with the buffer size already
+    // significantly larger than panner tail time, it demonstrates that the
+    // lag between threads is much greater than the tail time.
+    todo(false, "Connections not detected.");
+  }
+
+  referenceProcessCount++;
+}
+
+function onTestOutput(e) {
+  if (testProcessCount < sourceDelayBufferCount + ccDelayBufferCount) {
+    testProcessCount++;
+    return;
+  }
+
+  for (var i = 0; i < 2; ++i) {
+    compareBuffers(e.inputBuffer.getChannelData(i), referenceOutput[i]);
+  }
+  e.target.onaudioprocess = null;
+  e.target.disconnect();
+  SimpleTest.finish();
+}
+
+function startTest() {
+  var ctx = new AudioContext();
+  // Place the listener to the side of the origin, where the panners are
+  // positioned, to maximize delay in one ear.
+  ctx.listener.setPosition(1,0,0);
+
+  // 0.002 is MaxDelayTimeSeconds in HRTFpanner.cpp
+  // and 512 is fftSize() at 48 kHz.
+  const expectedPannerTailTime = 0.002 * ctx.sampleRate + 512;
+
+  // Create some PannerNodes downstream from DelayNodes with delays long
+  // enough for their source oscillator to finish, dispatch its "ended" event
+  // and release its playing reference.  The DelayNodes should expire their
+  // tail-time references before the PannerNodes and so only the PannerNode
+  // lifetimes depends on their tail-time references.  Many DelayNodes are
+  // created and timed to finish at different times so that one PannerNode
+  // will be finishing the block processed immediately after the connect is
+  // received.
+  var oscillator = ctx.createOscillator();
+  oscillator.start(0);
+  // Just short of blockSize here to avoid rounding into the next block
+  oscillator.stop((blockSize - 1) / ctx.sampleRate);
+  oscillator.onended = function(e) {
+    gotEnded = true;
+  };
+
+  // The panner effect is linear so only one reference panner is required.
+  // This also checks that the individual panners don't chop their output too
+  // soon.
+  referencePanner = ctx.createPanner();
+
+  // Time the first test panner to finish just before downstream DelayNodes
+  // are about the be connected.  Note that DelayNode lifetime depends on
+  // maxDelayTime so set that equal to the delay.
+  var delayDuration =
+    (sourceDelayBufferCount * bufferSize
+     - expectedPannerTailTime - 2 * blockSize) / ctx.sampleRate;
+
+  for (var i = 0; i < pannerCount; ++i) {
+    var delay = ctx.createDelay(delayDuration);
+    delay.delayTime.value = delayDuration;
+    oscillator.connect(delay);
+    delay.connect(referencePanner)
+
+    var panner = ctx.createPanner();
+    delay.connect(panner)
+    testPanners[i] = panner;
+
+    delayDuration += blockSize / ctx.sampleRate;
+  }
+
+  // Create a ScriptProcessor now to use as a timer to trigger connection of
+  // downstream nodes.  It will also be used to record reference output.
+  var referenceProcessor = ctx.createScriptProcessor(bufferSize, 2, 0);
+  referenceProcessor.onaudioprocess = onReferenceOutput;
+  // Start audioprocess events before source delays are connected.
+  referenceProcessor.connect(ctx.destination);
+
+  // The test ScriptProcessor will record output of testPanners. 
+  // Create it now so that it is synchronized with the referenceProcessor.
+  testProcessor = ctx.createScriptProcessor(bufferSize, 2, 0);
+  testProcessor.onaudioprocess = onTestOutput;
+  // Start audioprocess events before source delays are connected.
+  testProcessor.connect(ctx.destination);
+}
+
+startTest();
+</script>
+</pre>
+</body>
+</html>
--- a/content/media/webm/WebMReader.cpp
+++ b/content/media/webm/WebMReader.cpp
@@ -901,17 +901,17 @@ bool WebMReader::DecodeVideoFrame(bool &
         picture.width = (img->d_w * mPicture.width) / mInitialFrame.width;
         picture.height = (img->d_h * mPicture.height) / mInitialFrame.height;
       }
 
       VideoData *v = VideoData::Create(mInfo.mVideo,
                                        mDecoder->GetImageContainer(),
                                        holder->mOffset,
                                        tstamp_usecs,
-                                       next_tstamp / NS_PER_USEC,
+                                       (next_tstamp / NS_PER_USEC) - tstamp_usecs,
                                        b,
                                        si.is_kf,
                                        -1,
                                        picture);
       if (!v) {
         return false;
       }
       parsed++;
--- a/content/media/webm/moz.build
+++ b/content/media/webm/moz.build
@@ -6,17 +6,17 @@
 
 MODULE = 'content'
 
 EXPORTS += [
     'WebMDecoder.h',
     'WebMReader.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'WebMBufferedParser.cpp',
     'WebMDecoder.cpp',
     'WebMReader.cpp',
 ]
 
 LIBRARY_NAME = 'gkconwebm_s'
 
 FAIL_ON_WARNINGS = True
--- a/content/media/webrtc/Makefile.in
+++ b/content/media/webrtc/Makefile.in
@@ -2,17 +2,16 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 ifeq ($(OS_ARCH),WINNT)
 OS_CXXFLAGS += -DNOMINMAX
 endif
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 ifdef MOZ_WEBRTC
 LOCAL_INCLUDES += \
   -I$(topsrcdir)/media/webrtc/trunk \
   -I$(topsrcdir)/media/webrtc/signaling/src/common \
   -I$(topsrcdir)/media/webrtc/signaling/src/common/browser_logging \
   -I$(topsrcdir)/dom/base \
   -I$(topsrcdir)/dom/camera \
--- a/content/media/webrtc/moz.build
+++ b/content/media/webrtc/moz.build
@@ -10,26 +10,28 @@ MODULE = 'content'
 
 EXPORTS += [
     'MediaEngine.h',
     'MediaEngineDefault.h',
 ]
 
 if CONFIG['MOZ_WEBRTC']:
     EXPORTS += ['MediaEngineWebRTC.h']
-    CPP_SOURCES += [
+    SOURCES += [
         'MediaEngineTabVideoSource.cpp',
         'MediaEngineWebRTC.cpp',
         'MediaEngineWebRTCAudio.cpp',
         'MediaEngineWebRTCVideo.cpp',
     ]
 XPIDL_SOURCES += [
         'nsITabSource.idl'
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'MediaEngineDefault.cpp',
 ]
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'gkconwebrtc_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/content/media/webspeech/recognition/Makefile.in
+++ b/content/media/webspeech/recognition/Makefile.in
@@ -1,7 +1,5 @@
 # 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)/dom/dom-config.mk
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/content/media/webspeech/recognition/moz.build
+++ b/content/media/webspeech/recognition/moz.build
@@ -20,17 +20,17 @@ EXPORTS.mozilla.dom += [
     'SpeechRecognition.h',
     'SpeechRecognitionAlternative.h',
     'SpeechRecognitionResult.h',
     'SpeechRecognitionResultList.h',
     'SpeechStreamListener.h',
     'test/FakeSpeechRecognitionService.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'EnableWebSpeechRecognitionCheck.cpp',
     'endpointer.cc',
     'energy_endpointer.cc',
     'energy_endpointer_params.cc',
     'SpeechGrammar.cpp',
     'SpeechGrammarList.cpp',
     'SpeechRecognition.cpp',
     'SpeechRecognitionAlternative.cpp',
@@ -39,8 +39,13 @@ CPP_SOURCES += [
     'SpeechStreamListener.cpp',
     'test/FakeSpeechRecognitionService.cpp',
 ]
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'gkconwebspeechrecognition_s'
 
+LOCAL_INCLUDES += [
+    '/dom/base',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
--- a/content/media/webspeech/synth/Makefile.in
+++ b/content/media/webspeech/synth/Makefile.in
@@ -1,14 +1,12 @@
 # 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)/dom/dom-config.mk
 
 VPATH += \
   $(srcdir)/ipc \
   $(NULL)
 
 LOCAL_INCLUDES += $(VPATH:%=-I%)
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/content/media/webspeech/synth/moz.build
+++ b/content/media/webspeech/synth/moz.build
@@ -22,17 +22,17 @@ if CONFIG['MOZ_WEBSPEECH']:
         'ipc/SpeechSynthesisParent.h',
         'nsSpeechTask.h',
         'nsSynthVoiceRegistry.h',
         'SpeechSynthesis.h',
         'SpeechSynthesisUtterance.h',
         'SpeechSynthesisVoice.h',
     ]
 
-    CPP_SOURCES += [
+    SOURCES += [
         'EnableSpeechSynthesisCheck.cpp',
         'ipc/SpeechSynthesisChild.cpp',
         'ipc/SpeechSynthesisParent.cpp',
         'nsSpeechTask.cpp',
         'nsSynthVoiceRegistry.cpp',
         'SpeechSynthesis.cpp',
         'SpeechSynthesisUtterance.cpp',
         'SpeechSynthesisVoice.cpp',
@@ -49,8 +49,10 @@ IPDL_SOURCES += [
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'gkconwebspeechsynth_s'
 
 EXPORT_LIBRARY = True
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/content/media/webspeech/synth/pico/Makefile.in
+++ b/content/media/webspeech/synth/pico/Makefile.in
@@ -1,9 +1,5 @@
 # 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 $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/dom/dom-config.mk
-
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/content/media/webspeech/synth/pico/moz.build
+++ b/content/media/webspeech/synth/pico/moz.build
@@ -1,17 +1,19 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'synthpico'
 
-CPP_SOURCES += [
+SOURCES += [
     'nsPicoService.cpp',
     'PicoModule.cpp'
 ]
 
 LIBRARY_NAME = 'synthpico'
 LIBXUL_LIBRARY = True
 EXPORT_LIBRARY = True
 FAIL_ON_WARNINGS = True
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/content/media/wmf/WMFReader.cpp
+++ b/content/media/wmf/WMFReader.cpp
@@ -840,17 +840,17 @@ WMFReader::CreateBasicVideoFrame(IMFSamp
   b.mPlanes[2].mWidth = halfWidth;
   b.mPlanes[2].mOffset = 0;
   b.mPlanes[2].mSkip = 0;
 
   VideoData *v = VideoData::Create(mInfo.mVideo,
                                    mDecoder->GetImageContainer(),
                                    aOffsetBytes,
                                    aTimestampUsecs,
-                                   aTimestampUsecs + aDurationUsecs,
+                                   aDurationUsecs,
                                    b,
                                    false,
                                    -1,
                                    mPictureRegion);
   if (twoDBuffer) {
     twoDBuffer->Unlock2D();
   } else {
     buffer->Unlock();
@@ -883,17 +883,17 @@ WMFReader::CreateD3DVideoFrame(IMFSample
                                   getter_AddRefs(image));
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
   NS_ENSURE_TRUE(image, E_FAIL);
 
   VideoData *v = VideoData::CreateFromImage(mInfo.mVideo,
                                             mDecoder->GetImageContainer(),
                                             aOffsetBytes,
                                             aTimestampUsecs,
-                                            aTimestampUsecs + aDurationUsecs,
+                                            aDurationUsecs,
                                             image.forget(),
                                             false,
                                             -1,
                                             mPictureRegion);
 
   NS_ENSURE_TRUE(v, E_FAIL);
   *aOutVideoData = v;
 
--- a/content/media/wmf/moz.build
+++ b/content/media/wmf/moz.build
@@ -7,17 +7,17 @@
 MODULE = 'content'
 
 EXPORTS += [
     'WMF.h',
     'WMFDecoder.h',
     'WMFReader.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'DXVA2Manager.cpp',
     'WMFByteStream.cpp',
     'WMFDecoder.cpp',
     'WMFReader.cpp',
     'WMFSourceReaderCallback.cpp',
     'WMFUtils.cpp',
 ]
 
--- a/content/smil/moz.build
+++ b/content/smil/moz.build
@@ -29,17 +29,17 @@ EXPORTS += [
     'nsSMILTimedElement.h',
     'nsSMILTimeValue.h',
     'nsSMILTimeValueSpec.h',
     'nsSMILTimeValueSpecParams.h',
     'nsSMILTypes.h',
     'nsSMILValue.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'nsDOMTimeEvent.cpp',
     'nsSMILAnimationController.cpp',
     'nsSMILAnimationFunction.cpp',
     'nsSMILCompositor.cpp',
     'nsSMILCSSProperty.cpp',
     'nsSMILCSSValueType.cpp',
     'nsSMILFloatType.cpp',
     'nsSMILInstanceTime.cpp',
--- a/content/svg/content/src/Makefile.in
+++ b/content/svg/content/src/Makefile.in
@@ -1,15 +1,14 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 INCLUDES += 	\
 		-I$(srcdir)/../../../xml/content/src \
 		-I$(srcdir)/../../../../dom \
 		-I$(srcdir)/../../../base/src \
 		-I$(srcdir)/../../../../layout/generic \
 		-I$(srcdir)/../../../../layout/xul/base/src \
 		-I$(srcdir)/../../../../layout/svg \
--- a/content/svg/content/src/SVGPathData.cpp
+++ b/content/svg/content/src/SVGPathData.cpp
@@ -1,26 +1,33 @@
 /* -*- 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 "SVGPathData.h"
+
+#include "gfx2DGlue.h"
 #include "gfxPlatform.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/Types.h"
+#include "mozilla/gfx/Point.h"
+#include "mozilla/RefPtr.h"
 #include "nsError.h"
 #include "nsString.h"
 #include "nsSVGPathDataParser.h"
 #include "nsSVGPathGeometryElement.h" // for nsSVGMark
 #include <stdarg.h>
 #include "SVGContentUtils.h"
 #include "SVGPathSegUtils.h"
 #include "gfxContext.h"
 #include <algorithm>
 
 using namespace mozilla;
+using namespace mozilla::gfx;
 
 static bool IsMoveto(uint16_t aSegType)
 {
   return aSegType == PATHSEG_MOVETO_ABS ||
          aSegType == PATHSEG_MOVETO_REL;
 }
 
 nsresult
@@ -232,26 +239,306 @@ ApproximateZeroLengthSubpathSquareCaps(c
 
   const gfxSize tinyAdvance = aCtx->DeviceToUser(gfxSize(2.0/256.0, 0.0));
 
   aCtx->MoveTo(aPoint);
   aCtx->LineTo(aPoint + gfxPoint(tinyAdvance.width, tinyAdvance.height));
   aCtx->MoveTo(aPoint);
 }
 
+static void
+ApproximateZeroLengthSubpathSquareCaps(const Point& aPoint,
+                                       DrawTarget* aDT,
+                                       PathBuilder* aPB)
+{
+  // Cairo's fixed point fractional part is 8 bits wide, so its device space
+  // coordinate granularity is 1/256 pixels. However, to prevent user space
+  // |aPoint| and |aPoint + tinyAdvance| being rounded to the same device
+  // coordinates, we double this for |tinyAdvance|:
+
+  Matrix currentTransform = aDT->GetTransform();
+  currentTransform.Invert();
+  Size tinyAdvance = currentTransform * Size(2.0/256.0, 0.0);
+
+  aPB->MoveTo(aPoint);
+  aPB->LineTo(aPoint + Point(tinyAdvance.width, tinyAdvance.height));
+  aPB->MoveTo(aPoint);
+}
+
+#define MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS_TO_DT               \
+  do {                                                                        \
+    if (capsAreSquare && !subpathHasLength && subpathContainsNonArc &&        \
+        SVGPathSegUtils::IsValidType(prevSegType) &&                          \
+        (!IsMoveto(prevSegType) ||                                            \
+         segType == PATHSEG_CLOSEPATH)) {                                     \
+      ApproximateZeroLengthSubpathSquareCaps(segStart, aDT, builder);         \
+    }                                                                         \
+  } while(0)
+
 #define MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS                     \
   do {                                                                        \
     if (capsAreSquare && !subpathHasLength && subpathContainsNonArc &&        \
         SVGPathSegUtils::IsValidType(prevSegType) &&                          \
         (!IsMoveto(prevSegType) ||                                            \
          segType == PATHSEG_CLOSEPATH)) {                                     \
       ApproximateZeroLengthSubpathSquareCaps(segStart, aCtx);                 \
     }                                                                         \
   } while(0)
 
+TemporaryRef<Path>
+SVGPathData::ConstructPath(DrawTarget *aDT,
+                           FillRule aFillRule,
+                           CapStyle aCapStyle) const
+{
+  if (mData.IsEmpty() || !IsMoveto(SVGPathSegUtils::DecodeType(mData[0]))) {
+    return nullptr; // paths without an initial moveto are invalid
+  }
+
+  RefPtr<PathBuilder> builder = aDT->CreatePathBuilder(aFillRule);
+
+  bool capsAreSquare = aCapStyle == CAP_SQUARE;
+  bool subpathHasLength = false;  // visual length
+  bool subpathContainsNonArc = false;
+
+  uint32_t segType     = PATHSEG_UNKNOWN;
+  uint32_t prevSegType = PATHSEG_UNKNOWN;
+  Point pathStart(0.0, 0.0); // start point of [sub]path
+  Point segStart(0.0, 0.0);
+  Point segEnd;
+  Point cp1, cp2;            // previous bezier's control points
+  Point tcp1, tcp2;          // temporaries
+
+  // Regarding cp1 and cp2: If the previous segment was a cubic bezier curve,
+  // then cp2 is its second control point. If the previous segment was a
+  // quadratic curve, then cp1 is its (only) control point.
+
+  uint32_t i = 0;
+  while (i < mData.Length()) {
+    segType = SVGPathSegUtils::DecodeType(mData[i++]);
+    uint32_t argCount = SVGPathSegUtils::ArgCountForType(segType);
+
+    switch (segType)
+    {
+    case PATHSEG_CLOSEPATH:
+      // set this early to allow drawing of square caps for "M{x},{y} Z":
+      subpathContainsNonArc = true;
+      MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS_TO_DT;
+      segEnd = pathStart;
+      builder->Close();
+      break;
+
+    case PATHSEG_MOVETO_ABS:
+      MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS_TO_DT;
+      pathStart = segEnd = Point(mData[i], mData[i+1]);
+      builder->MoveTo(segEnd);
+      subpathHasLength = false;
+      subpathContainsNonArc = false;
+      break;
+
+    case PATHSEG_MOVETO_REL:
+      MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS_TO_DT;
+      pathStart = segEnd = segStart + Point(mData[i], mData[i+1]);
+      builder->MoveTo(segEnd);
+      subpathHasLength = false;
+      subpathContainsNonArc = false;
+      break;
+
+    case PATHSEG_LINETO_ABS:
+      segEnd = Point(mData[i], mData[i+1]);
+      builder->LineTo(segEnd);
+      if (!subpathHasLength) {
+        subpathHasLength = (segEnd != segStart);
+      }
+      subpathContainsNonArc = true;
+      break;
+
+    case PATHSEG_LINETO_REL:
+      segEnd = segStart + Point(mData[i], mData[i+1]);
+      builder->LineTo(segEnd);
+      if (!subpathHasLength) {
+        subpathHasLength = (segEnd != segStart);
+      }
+      subpathContainsNonArc = true;
+      break;
+
+    case PATHSEG_CURVETO_CUBIC_ABS:
+      cp1 = Point(mData[i], mData[i+1]);
+      cp2 = Point(mData[i+2], mData[i+3]);
+      segEnd = Point(mData[i+4], mData[i+5]);
+      builder->BezierTo(cp1, cp2, segEnd);
+      if (!subpathHasLength) {
+        subpathHasLength = (segEnd != segStart || segEnd != cp1 || segEnd != cp2);
+      }
+      subpathContainsNonArc = true;
+      break;
+
+    case PATHSEG_CURVETO_CUBIC_REL:
+      cp1 = segStart + Point(mData[i], mData[i+1]);
+      cp2 = segStart + Point(mData[i+2], mData[i+3]);
+      segEnd = segStart + Point(mData[i+4], mData[i+5]);
+      builder->BezierTo(cp1, cp2, segEnd);
+      if (!subpathHasLength) {
+        subpathHasLength = (segEnd != segStart || segEnd != cp1 || segEnd != cp2);
+      }
+      subpathContainsNonArc = true;
+      break;
+
+    case PATHSEG_CURVETO_QUADRATIC_ABS:
+      cp1 = Point(mData[i], mData[i+1]);
+      // Convert quadratic curve to cubic curve:
+      tcp1 = segStart + (cp1 - segStart) * 2 / 3;
+      segEnd = Point(mData[i+2], mData[i+3]); // set before setting tcp2!
+      tcp2 = cp1 + (segEnd - cp1) / 3;
+      builder->BezierTo(tcp1, tcp2, segEnd);
+      if (!subpathHasLength) {
+        subpathHasLength = (segEnd != segStart || segEnd != cp1);
+      }
+      subpathContainsNonArc = true;
+      break;
+
+    case PATHSEG_CURVETO_QUADRATIC_REL:
+      cp1 = segStart + Point(mData[i], mData[i+1]);
+      // Convert quadratic curve to cubic curve:
+      tcp1 = segStart + (cp1 - segStart) * 2 / 3;
+      segEnd = segStart + Point(mData[i+2], mData[i+3]); // set before setting tcp2!
+      tcp2 = cp1 + (segEnd - cp1) / 3;
+      builder->BezierTo(tcp1, tcp2, segEnd);
+      if (!subpathHasLength) {
+        subpathHasLength = (segEnd != segStart || segEnd != cp1);
+      }
+      subpathContainsNonArc = true;
+      break;
+
+    case PATHSEG_ARC_ABS:
+    case PATHSEG_ARC_REL:
+    {
+      Point radii(mData[i], mData[i+1]);
+      segEnd = Point(mData[i+5], mData[i+6]);
+      if (segType == PATHSEG_ARC_REL) {
+        segEnd += segStart;
+      }
+      if (segEnd != segStart) {
+        if (radii.x == 0.0f || radii.y == 0.0f) {
+          builder->LineTo(segEnd);
+        } else {
+          nsSVGArcConverter converter(segStart, segEnd, radii, mData[i+2],
+                                      mData[i+3] != 0, mData[i+4] != 0);
+          while (converter.GetNextSegment(&cp1, &cp2, &segEnd)) {
+            builder->BezierTo(cp1, cp2, segEnd);
+          }
+        }
+      }
+      if (!subpathHasLength) {
+        subpathHasLength = (segEnd != segStart);
+      }
+      break;
+    }
+
+    case PATHSEG_LINETO_HORIZONTAL_ABS:
+      segEnd = Point(mData[i], segStart.y);
+      builder->LineTo(segEnd);
+      if (!subpathHasLength) {
+        subpathHasLength = (segEnd != segStart);
+      }
+      subpathContainsNonArc = true;
+      break;
+
+    case PATHSEG_LINETO_HORIZONTAL_REL:
+      segEnd = segStart + Point(mData[i], 0.0f);
+      builder->LineTo(segEnd);
+      if (!subpathHasLength) {
+        subpathHasLength = (segEnd != segStart);
+      }
+      subpathContainsNonArc = true;
+      break;
+
+    case PATHSEG_LINETO_VERTICAL_ABS:
+      segEnd = Point(segStart.x, mData[i]);
+      builder->LineTo(segEnd);
+      if (!subpathHasLength) {
+        subpathHasLength = (segEnd != segStart);
+      }
+      subpathContainsNonArc = true;
+      break;
+
+    case PATHSEG_LINETO_VERTICAL_REL:
+      segEnd = segStart + Point(0.0f, mData[i]);
+      builder->LineTo(segEnd);
+      if (!subpathHasLength) {
+        subpathHasLength = (segEnd != segStart);
+      }
+      subpathContainsNonArc = true;
+      break;
+
+    case PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
+      cp1 = SVGPathSegUtils::IsCubicType(prevSegType) ? segStart * 2 - cp2 : segStart;
+      cp2 = Point(mData[i],   mData[i+1]);
+      segEnd = Point(mData[i+2], mData[i+3]);
+      builder->BezierTo(cp1, cp2, segEnd);
+      if (!subpathHasLength) {
+        subpathHasLength = (segEnd != segStart || segEnd != cp1 || segEnd != cp2);
+      }
+      subpathContainsNonArc = true;
+      break;
+
+    case PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
+      cp1 = SVGPathSegUtils::IsCubicType(prevSegType) ? segStart * 2 - cp2 : segStart;
+      cp2 = segStart + Point(mData[i], mData[i+1]);
+      segEnd = segStart + Point(mData[i+2], mData[i+3]);
+      builder->BezierTo(cp1, cp2, segEnd);
+      if (!subpathHasLength) {
+        subpathHasLength = (segEnd != segStart || segEnd != cp1 || segEnd != cp2);
+      }
+      subpathContainsNonArc = true;
+      break;
+
+    case PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
+      cp1 = SVGPathSegUtils::IsQuadraticType(prevSegType) ? segStart * 2 - cp1 : segStart;
+      // Convert quadratic curve to cubic curve:
+      tcp1 = segStart + (cp1 - segStart) * 2 / 3;
+      segEnd = Point(mData[i], mData[i+1]); // set before setting tcp2!
+      tcp2 = cp1 + (segEnd - cp1) / 3;
+      builder->BezierTo(tcp1, tcp2, segEnd);
+      if (!subpathHasLength) {
+        subpathHasLength = (segEnd != segStart || segEnd != cp1);
+      }
+      subpathContainsNonArc = true;
+      break;
+
+    case PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
+      cp1 = SVGPathSegUtils::IsQuadraticType(prevSegType) ? segStart * 2 - cp1 : segStart;
+      // Convert quadratic curve to cubic curve:
+      tcp1 = segStart + (cp1 - segStart) * 2 / 3;
+      segEnd = segStart + Point(mData[i], mData[i+1]); // changed before setting tcp2!
+      tcp2 = cp1 + (segEnd - cp1) / 3;
+      builder->BezierTo(tcp1, tcp2, segEnd);
+      if (!subpathHasLength) {
+        subpathHasLength = (segEnd != segStart || segEnd != cp1);
+      }
+      subpathContainsNonArc = true;
+      break;
+
+    default:
+      NS_NOTREACHED("Bad path segment type");
+      return nullptr; // according to spec we'd use everything up to the bad seg anyway
+    }
+    i += argCount;
+    prevSegType = segType;
+    segStart = segEnd;
+  }
+
+  NS_ABORT_IF_FALSE(i == mData.Length(), "Very, very bad - mData corrupt");
+  NS_ABORT_IF_FALSE(prevSegType == segType,
+                    "prevSegType should be left at the final segType");
+
+  MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS_TO_DT;
+
+  return builder->Finish();
+}
+
 void
 SVGPathData::ConstructPath(gfxContext *aCtx) const
 {
   if (mData.IsEmpty() || !IsMoveto(SVGPathSegUtils::DecodeType(mData[0]))) {
     return; // paths without an initial moveto are invalid
   }
 
   bool capsAreSquare = aCtx->CurrentLineCap() == gfxContext::LINE_CAP_SQUARE;
@@ -374,24 +661,31 @@ SVGPathData::ConstructPath(gfxContext *a
       segEnd = gfxPoint(mData[i+5], mData[i+6]);
       if (segType == PATHSEG_ARC_REL) {
         segEnd += segStart;
       }
       if (segEnd != segStart) {
         if (radii.x == 0.0f || radii.y == 0.0f) {
           aCtx->LineTo(segEnd);
         } else {
-          nsSVGArcConverter converter(segStart, segEnd, radii, mData[i+2],
+          nsSVGArcConverter converter(ToPoint(segStart), ToPoint(segEnd),
+                                      ToPoint(radii), mData[i+2],
                                       mData[i+3] != 0, mData[i+4] != 0);
-          while (converter.GetNextSegment(&cp1, &cp2, &segEnd)) {
-            aCtx->CurveTo(cp1, cp2, segEnd);
+          Point cp1, cp2, segEnd_;
+          while (converter.GetNextSegment(&cp1, &cp2, &segEnd_)) {
+            aCtx->CurveTo(ThebesPoint(cp1), ThebesPoint(cp2), ThebesPoint(segEnd_));
           }
+          segEnd = ThebesPoint(segEnd_);
         }
       }
       if (!subpathHasLength) {
+        // Round to make sure the current comparison doesn't fail due to
+        // precision issues:
+        // XXX kill after all code is converted to float precision
+        segStart = ThebesPoint(ToPoint(segStart));
         subpathHasLength = (segEnd != segStart);
       }
       break;
     }
 
     case PATHSEG_LINETO_HORIZONTAL_ABS:
       segEnd = gfxPoint(mData[i], segStart.y);
       aCtx->LineTo(segEnd);
--- a/content/svg/content/src/SVGPathData.h
+++ b/content/svg/content/src/SVGPathData.h
@@ -6,16 +6,18 @@
 #ifndef MOZILLA_SVGPATHDATA_H__
 #define MOZILLA_SVGPATHDATA_H__
 
 #include "nsCOMPtr.h"
 #include "nsDebug.h"
 #include "nsIContent.h"
 #include "nsINode.h"
 #include "nsIWeakReferenceUtils.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/RefPtr.h"
 #include "nsSVGElement.h"
 #include "nsTArray.h"
 
 #include <string.h>
 
 class gfxContext;
 class gfxPath;
 class nsSVGPathDataParserToInternal; // IWYU pragma: keep
@@ -75,16 +77,21 @@ class SVGPathData
 {
   friend class SVGAnimatedPathSegList;
   friend class DOMSVGPathSegList;
   friend class DOMSVGPathSeg;
   friend class ::nsSVGPathDataParserToInternal;
   // nsSVGPathDataParserToInternal will not keep wrappers in sync, so consumers
   // are responsible for that!
 
+  typedef gfx::DrawTarget DrawTarget;
+  typedef gfx::Path Path;
+  typedef gfx::FillRule FillRule;
+  typedef gfx::CapStyle CapStyle;
+
 public:
   typedef const float* const_iterator;
 
   SVGPathData(){}
   ~SVGPathData(){}
 
   // Only methods that don't make/permit modification to this list are public.
   // Only our friend classes can access methods that may change us.
@@ -149,16 +156,19 @@ public:
    * Returns true, except on OOM, in which case returns false.
    */
   bool GetDistancesFromOriginToEndsOfVisibleSegments(nsTArray<double> *aArray) const;
 
   already_AddRefed<gfxPath>
   ToPath(const gfxMatrix& aMatrix) const;
 
   void ConstructPath(gfxContext *aCtx) const;
+  TemporaryRef<Path> ConstructPath(DrawTarget* aDT,
+                                   FillRule aFillRule,
+                                   CapStyle aCapStyle) const;
 
   const_iterator begin() const { return mData.Elements(); }
   const_iterator end() const { return mData.Elements() + mData.Length(); }
 
   // Access to methods that can modify objects of this type is deliberately
   // limited. This is to reduce the chances of someone modifying objects of
   // this type without taking the necessary steps to keep DOM wrappers in sync.
   // If you need wider access to these methods, consider adding a method to
--- a/content/svg/content/src/SVGPathSegUtils.cpp
+++ b/content/svg/content/src/SVGPathSegUtils.cpp
@@ -1,18 +1,21 @@
 /* -*- 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 "SVGPathSegUtils.h"
+
+#include "gfx2DGlue.h"
 #include "nsSVGPathDataParser.h"
 #include "nsTextFormatter.h"
 
 using namespace mozilla;
+using namespace mozilla::gfx;
 
 static const float PATH_SEG_LENGTH_TOLERANCE = 0.0000001f;
 static const uint32_t MAX_RECURSION = 10;
 
 
 /* static */ void
 SVGPathSegUtils::GetValueAsString(const float* aSeg, nsAString& aValue)
 {
@@ -75,41 +78,41 @@ SVGPathSegUtils::GetValueAsString(const 
   //
   if (aValue[aValue.Length() - 1] == PRUnichar('\0')) {
     aValue.SetLength(aValue.Length() - 1);
   }
 }
 
 
 static float
-CalcDistanceBetweenPoints(const gfxPoint& aP1, const gfxPoint& aP2)
+CalcDistanceBetweenPoints(const Point& aP1, const Point& aP2)
 {
   return NS_hypot(aP2.x - aP1.x, aP2.y - aP1.y);
 }
 
 
 static void
-SplitQuadraticBezier(const gfxPoint* aCurve, gfxPoint* aLeft, gfxPoint* aRight)
+SplitQuadraticBezier(const Point* aCurve, Point* aLeft, Point* aRight)
 {
   aLeft[0].x = aCurve[0].x;
   aLeft[0].y = aCurve[0].y;
   aRight[2].x = aCurve[2].x;
   aRight[2].y = aCurve[2].y;
   aLeft[1].x = (aCurve[0].x + aCurve[1].x) / 2;
   aLeft[1].y = (aCurve[0].y + aCurve[1].y) / 2;
   aRight[1].x = (aCurve[1].x + aCurve[2].x) / 2;
   aRight[1].y = (aCurve[1].y + aCurve[2].y) / 2;
   aLeft[2].x = aRight[0].x = (aLeft[1].x + aRight[1].x) / 2;
   aLeft[2].y = aRight[0].y = (aLeft[1].y + aRight[1].y) / 2;
 }
 
 static void
-SplitCubicBezier(const gfxPoint* aCurve, gfxPoint* aLeft, gfxPoint* aRight)
+SplitCubicBezier(const Point* aCurve, Point* aLeft, Point* aRight)
 {
-  gfxPoint tmp;
+  Point tmp;
   tmp.x = (aCurve[1].x + aCurve[2].x) / 4;
   tmp.y = (aCurve[1].y + aCurve[2].y) / 4;
   aLeft[0].x = aCurve[0].x;
   aLeft[0].y = aCurve[0].y;
   aRight[3].x = aCurve[3].x;
   aRight[3].y = aCurve[3].y;
   aLeft[1].x = (aCurve[0].x + aCurve[1].x) / 2;
   aLeft[1].y = (aCurve[0].y + aCurve[1].y) / 2;
@@ -119,50 +122,50 @@ SplitCubicBezier(const gfxPoint* aCurve,
   aLeft[2].y = aLeft[1].y / 2 + tmp.y;
   aRight[1].x = aRight[2].x / 2 + tmp.x;
   aRight[1].y = aRight[2].y / 2 + tmp.y;
   aLeft[3].x = aRight[0].x = (aLeft[2].x + aRight[1].x) / 2;
   aLeft[3].y = aRight[0].y = (aLeft[2].y + aRight[1].y) / 2;
 }
 
 static gfxFloat
-CalcBezLengthHelper(gfxPoint* aCurve, uint32_t aNumPts,
+CalcBezLengthHelper(const Point* aCurve, uint32_t aNumPts,
                     uint32_t aRecursionCount,
-                    void (*aSplit)(const gfxPoint*, gfxPoint*, gfxPoint*))
+                    void (*aSplit)(const Point*, Point*, Point*))
 {
-  gfxPoint left[4];
-  gfxPoint right[4];
+  Point left[4];
+  Point right[4];
   gfxFloat length = 0, dist;
   for (uint32_t i = 0; i < aNumPts - 1; i++) {
     length += CalcDistanceBetweenPoints(aCurve[i], aCurve[i+1]);
   }
   dist = CalcDistanceBetweenPoints(aCurve[0], aCurve[aNumPts - 1]);
   if (length - dist > PATH_SEG_LENGTH_TOLERANCE &&
       aRecursionCount < MAX_RECURSION) {
     aSplit(aCurve, left, right);
     ++aRecursionCount;
     return CalcBezLengthHelper(left, aNumPts, aRecursionCount, aSplit) +
            CalcBezLengthHelper(right, aNumPts, aRecursionCount, aSplit);
   }
   return length;
 }
 
 static inline gfxFloat
-CalcLengthOfCubicBezier(const gfxPoint& aPos, const gfxPoint &aCP1,
-                        const gfxPoint& aCP2, const gfxPoint &aTo)
+CalcLengthOfCubicBezier(const Point& aPos, const Point &aCP1,
+                        const Point& aCP2, const Point &aTo)
 {
-  gfxPoint curve[4] = { aPos, aCP1, aCP2, aTo };
+  Point curve[4] = { aPos, aCP1, aCP2, aTo };
   return CalcBezLengthHelper(curve, 4, 0, SplitCubicBezier);
 }
 
 static inline gfxFloat
-CalcLengthOfQuadraticBezier(const gfxPoint& aPos, const gfxPoint& aCP,
-                            const gfxPoint& aTo)
+CalcLengthOfQuadraticBezier(const Point& aPos, const Point& aCP,
+                            const Point& aTo)
 {
-  gfxPoint curve[3] = { aPos, aCP, aTo };
+  Point curve[3] = { aPos, aCP, aTo };
   return CalcBezLengthHelper(curve, 3, 0, SplitQuadraticBezier);
 }
 
 
 static void
 TraverseClosePath(const float* aArgs, SVGPathTraversalState& aState)
 {
   if (aState.ShouldUpdateLengthAndControlPoints()) {
@@ -170,59 +173,59 @@ TraverseClosePath(const float* aArgs, SV
     aState.cp1 = aState.cp2 = aState.start;
   }
   aState.pos = aState.start;
 }
 
 static void
 TraverseMovetoAbs(const float* aArgs, SVGPathTraversalState& aState)
 {
-  aState.start = aState.pos = gfxPoint(aArgs[0], aArgs[1]);
+  aState.start = aState.pos = Point(aArgs[0], aArgs[1]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
     // aState.length is unchanged, since move commands don't affect path length.
     aState.cp1 = aState.cp2 = aState.start;
   }
 }
 
 static void
 TraverseMovetoRel(const float* aArgs, SVGPathTraversalState& aState)
 {
-  aState.start = aState.pos += gfxPoint(aArgs[0], aArgs[1]);
+  aState.start = aState.pos += Point(aArgs[0], aArgs[1]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
     // aState.length is unchanged, since move commands don't affect path length.
     aState.cp1 = aState.cp2 = aState.start;
   }
 }
 
 static void
 TraverseLinetoAbs(const float* aArgs, SVGPathTraversalState& aState)
 {
-  gfxPoint to(aArgs[0], aArgs[1]);
+  Point to(aArgs[0], aArgs[1]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
     aState.length += CalcDistanceBetweenPoints(aState.pos, to);
     aState.cp1 = aState.cp2 = to;
   }
   aState.pos = to;
 }
 
 static void
 TraverseLinetoRel(const float* aArgs, SVGPathTraversalState& aState)
 {
-  gfxPoint to = aState.pos + gfxPoint(aArgs[0], aArgs[1]);
+  Point to = aState.pos + Point(aArgs[0], aArgs[1]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
     aState.length += CalcDistanceBetweenPoints(aState.pos, to);
     aState.cp1 = aState.cp2 = to;
   }
   aState.pos = to;
 }
 
 static void
 TraverseLinetoHorizontalAbs(const float* aArgs, SVGPathTraversalState& aState)
 {
-  gfxPoint to(aArgs[0], aState.pos.y);
+  Point to(aArgs[0], aState.pos.y);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
     aState.length += fabs(to.x - aState.pos.x);
     aState.cp1 = aState.cp2 = to;
   }
   aState.pos = to;
 }
 
 static void
@@ -233,17 +236,17 @@ TraverseLinetoHorizontalRel(const float*
     aState.length += fabs(aArgs[0]);
     aState.cp1 = aState.cp2 = aState.pos;
   }
 }
 
 static void
 TraverseLinetoVerticalAbs(const float* aArgs, SVGPathTraversalState& aState)
 {
-  gfxPoint to(aState.pos.x, aArgs[0]);
+  Point to(aState.pos.x, aArgs[0]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
     aState.length += fabs(to.y - aState.pos.y);
     aState.cp1 = aState.cp2 = to;
   }
   aState.pos = to;
 }
 
 static void
@@ -254,153 +257,151 @@ TraverseLinetoVerticalRel(const float* a
     aState.length += fabs(aArgs[0]);
     aState.cp1 = aState.cp2 = aState.pos;
   }
 }
 
 static void
 TraverseCurvetoCubicAbs(const float* aArgs, SVGPathTraversalState& aState)
 {
-  gfxPoint to(aArgs[4], aArgs[5]);
+  Point to(aArgs[4], aArgs[5]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
-    gfxPoint cp1(aArgs[0], aArgs[1]);
-    gfxPoint cp2(aArgs[2], aArgs[3]);
+    Point cp1(aArgs[0], aArgs[1]);
+    Point cp2(aArgs[2], aArgs[3]);
     aState.length += (float)CalcLengthOfCubicBezier(aState.pos, cp1, cp2, to);
     aState.cp2 = cp2;
     aState.cp1 = to;
   }
   aState.pos = to;
 }
 
 static void
 TraverseCurvetoCubicSmoothAbs(const float* aArgs, SVGPathTraversalState& aState)
 {
-  gfxPoint to(aArgs[2], aArgs[3]);
+  Point to(aArgs[2], aArgs[3]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
-    gfxPoint cp1 = aState.pos - (aState.cp2 - aState.pos);
-    gfxPoint cp2(aArgs[0], aArgs[1]);
+    Point cp1 = aState.pos - (aState.cp2 - aState.pos);
+    Point cp2(aArgs[0], aArgs[1]);
     aState.length += (float)CalcLengthOfCubicBezier(aState.pos, cp1, cp2, to);
     aState.cp2 = cp2;
     aState.cp1 = to;
   }
   aState.pos = to;
 }
 
 static void
 TraverseCurvetoCubicRel(const float* aArgs, SVGPathTraversalState& aState)
 {
-  gfxPoint to = aState.pos + gfxPoint(aArgs[4], aArgs[5]);
+  Point to = aState.pos + Point(aArgs[4], aArgs[5]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
-    gfxPoint cp1 = aState.pos + gfxPoint(aArgs[0], aArgs[1]);
-    gfxPoint cp2 = aState.pos + gfxPoint(aArgs[2], aArgs[3]);
+    Point cp1 = aState.pos + Point(aArgs[0], aArgs[1]);
+    Point cp2 = aState.pos + Point(aArgs[2], aArgs[3]);
     aState.length += (float)CalcLengthOfCubicBezier(aState.pos, cp1, cp2, to);
     aState.cp2 = cp2;
     aState.cp1 = to;
   }
   aState.pos = to;
 }
 
 static void
 TraverseCurvetoCubicSmoothRel(const float* aArgs, SVGPathTraversalState& aState)
 {
-  gfxPoint to = aState.pos + gfxPoint(aArgs[2], aArgs[3]);
+  Point to = aState.pos + Point(aArgs[2], aArgs[3]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
-    gfxPoint cp1 = aState.pos - (aState.cp2 - aState.pos);
-    gfxPoint cp2 = aState.pos + gfxPoint(aArgs[0], aArgs[1]);
+    Point cp1 = aState.pos - (aState.cp2 - aState.pos);
+    Point cp2 = aState.pos + Point(aArgs[0], aArgs[1]);
     aState.length += (float)CalcLengthOfCubicBezier(aState.pos, cp1, cp2, to);
     aState.cp2 = cp2;
     aState.cp1 = to;
   }
   aState.pos = to;
 }
 
 static void
 TraverseCurvetoQuadraticAbs(const float* aArgs, SVGPathTraversalState& aState)
 {
-  gfxPoint to(aArgs[2], aArgs[3]);
+  Point to(aArgs[2], aArgs[3]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
-    gfxPoint cp(aArgs[0], aArgs[1]);
+    Point cp(aArgs[0], aArgs[1]);
     aState.length += (float)CalcLengthOfQuadraticBezier(aState.pos, cp, to);
     aState.cp1 = cp;
     aState.cp2 = to;
   }
   aState.pos = to;
 }
 
 static void
 TraverseCurvetoQuadraticSmoothAbs(const float* aArgs,
                                   SVGPathTraversalState& aState)
 {
-  gfxPoint to(aArgs[0], aArgs[1]);
+  Point to(aArgs[0], aArgs[1]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
-    gfxPoint cp = aState.pos - (aState.cp1 - aState.pos);
+    Point cp = aState.pos - (aState.cp1 - aState.pos);
     aState.length += (float)CalcLengthOfQuadraticBezier(aState.pos, cp, to);
     aState.cp1 = cp;
     aState.cp2 = to;
   }
   aState.pos = to;
 }
 
 static void
 TraverseCurvetoQuadraticRel(const float* aArgs, SVGPathTraversalState& aState)
 {
-  gfxPoint to = aState.pos + gfxPoint(aArgs[2], aArgs[3]);
+  Point to = aState.pos + Point(aArgs[2], aArgs[3]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
-    gfxPoint cp = aState.pos + gfxPoint(aArgs[0], aArgs[1]);
+    Point cp = aState.pos + Point(aArgs[0], aArgs[1]);
     aState.length += (float)CalcLengthOfQuadraticBezier(aState.pos, cp, to);
     aState.cp1 = cp;
     aState.cp2 = to;
   }
   aState.pos = to;
 }
 
 static void
 TraverseCurvetoQuadraticSmoothRel(const float* aArgs,
                                   SVGPathTraversalState& aState)
 {
-  gfxPoint to = aState.pos + gfxPoint(aArgs[0], aArgs[1]);
+  Point to = aState.pos + Point(aArgs[0], aArgs[1]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
-    gfxPoint cp = aState.pos - (aState.cp1 - aState.pos);
+    Point cp = aState.pos - (aState.cp1 - aState.pos);
     aState.length += (float)CalcLengthOfQuadraticBezier(aState.pos, cp, to);
     aState.cp1 = cp;
     aState.cp2 = to;
   }
   aState.pos = to;
 }
 
 static void
 TraverseArcAbs(const float* aArgs, SVGPathTraversalState& aState)
 {
-  gfxPoint to(aArgs[5], aArgs[6]);
+  Point to(aArgs[5], aArgs[6]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
     float dist = 0;
-    gfxPoint radii(aArgs[0], aArgs[1]);
-    gfxPoint bez[4] = { aState.pos, gfxPoint(0, 0),
-                        gfxPoint(0, 0), gfxPoint(0, 0) };
+    Point radii(aArgs[0], aArgs[1]);
+    Point bez[4] = { aState.pos, Point(0, 0), Point(0, 0), Point(0, 0) };
     nsSVGArcConverter converter(aState.pos, to, radii, aArgs[2],
                                 aArgs[3] != 0, aArgs[4] != 0);
     while (converter.GetNextSegment(&bez[1], &bez[2], &bez[3])) {
       dist += CalcBezLengthHelper(bez, 4, 0, SplitCubicBezier);
       bez[0] = bez[3];
     }
     aState.length += dist;
     aState.cp1 = aState.cp2 = to;
   }
   aState.pos = to;
 }
 
 static void
 TraverseArcRel(const float* aArgs, SVGPathTraversalState& aState)
 {
-  gfxPoint to = aState.pos + gfxPoint(aArgs[5], aArgs[6]);
+  Point to = aState.pos + Point(aArgs[5], aArgs[6]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
     float dist = 0;
-    gfxPoint radii(aArgs[0], aArgs[1]);
-    gfxPoint bez[4] = { aState.pos, gfxPoint(0, 0),
-                        gfxPoint(0, 0), gfxPoint(0, 0) };
+    Point radii(aArgs[0], aArgs[1]);
+    Point bez[4] = { aState.pos, Point(0, 0), Point(0, 0), Point(0, 0) };
     nsSVGArcConverter converter(aState.pos, to, radii, aArgs[2],
                                 aArgs[3] != 0, aArgs[4] != 0);
     while (converter.GetNextSegment(&bez[1], &bez[2], &bez[3])) {
       dist += CalcBezLengthHelper(bez, 4, 0, SplitCubicBezier);
       bez[0] = bez[3];
     }
     aState.length += dist;
     aState.cp1 = aState.cp2 = to;
--- a/content/svg/content/src/SVGPathSegUtils.h
+++ b/content/svg/content/src/SVGPathSegUtils.h
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_SVGPATHSEGUTILS_H__
 #define MOZILLA_SVGPATHSEGUTILS_H__
 
 #include "gfxPoint.h"
+#include "mozilla/gfx/Point.h"
 #include "nsDebug.h"
 #include "nsMemory.h"
 
 namespace mozilla {
 
 // Path Segment Types
 static const unsigned short PATHSEG_UNKNOWN                      = 0;
 static const unsigned short PATHSEG_CLOSEPATH                    = 1;
@@ -41,43 +42,45 @@ static const unsigned short PATHSEG_CURV
 
 /**
  * Code that works with path segments can use an instance of this class to
  * store/provide information about the start of the current subpath and the
  * last path segment (if any).
  */
 struct SVGPathTraversalState
 {
+  typedef gfx::Point Point;
+
   enum TraversalMode {
     eUpdateAll,
     eUpdateOnlyStartAndCurrentPos
   };
 
   SVGPathTraversalState()
     : start(0.0, 0.0)
     , pos(0.0, 0.0)
     , cp1(0.0, 0.0)
     , cp2(0.0, 0.0)
     , length(0.0)
     , mode(eUpdateAll)
   {}
 
   bool ShouldUpdateLengthAndControlPoints() { return mode == eUpdateAll; }
 
-  gfxPoint start; // start point of current sub path (reset each moveto)
+  Point start; // start point of current sub path (reset each moveto)
 
-  gfxPoint pos;   // current position (end point of previous segment)
+  Point pos;   // current position (end point of previous segment)
 
-  gfxPoint cp1;   // quadratic control point - if the previous segment was a
-                  // quadratic bezier curve then this is set to the absolute
-                  // position of its control point, otherwise its set to pos
+  Point cp1;   // quadratic control point - if the previous segment was a
+               // quadratic bezier curve then this is set to the absolute
+               // position of its control point, otherwise its set to pos
 
-  gfxPoint cp2;   // cubic control point - if the previous segment was a cubic
-                  // bezier curve then this is set to the absolute position of
-                  // its second control point, otherwise it's set to pos
+  Point cp2;   // cubic control point - if the previous segment was a cubic
+               // bezier curve then this is set to the absolute position of
+               // its second control point, otherwise it's set to pos
 
   float length;   // accumulated path length
 
   TraversalMode mode;  // indicates what to track while traversing a path
 };
 
 
 /**
--- a/content/svg/content/src/moz.build
+++ b/content/svg/content/src/moz.build
@@ -94,17 +94,17 @@ EXPORTS.mozilla.dom += [
     'SVGTransform.h',
     'SVGTransformableElement.h',
     'SVGTSpanElement.h',
     'SVGUseElement.h',
     'SVGViewElement.h',
     'SVGZoomEvent.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'DOMSVGAnimatedLengthList.cpp',
     'DOMSVGAnimatedNumberList.cpp',
     'DOMSVGLength.cpp',
     'DOMSVGLengthList.cpp',
     'DOMSVGNumber.cpp',
     'DOMSVGNumberList.cpp',
     'DOMSVGPathSeg.cpp',
     'DOMSVGPathSegList.cpp',
@@ -246,8 +246,10 @@ CPP_SOURCES += [
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'gkcontentsvg_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/content/svg/content/src/nsSVGPathDataParser.cpp
+++ b/content/svg/content/src/nsSVGPathDataParser.cpp
@@ -1,21 +1,24 @@
 /* -*- 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 "nsSVGPathDataParser.h"
+
+#include "mozilla/gfx/Point.h"
 #include "nsSVGDataParser.h"
 #include "SVGPathData.h"
 #include "SVGPathSegUtils.h"
 #include <stdlib.h>
 #include <math.h>
 
 using namespace mozilla;
+using namespace mozilla::gfx;
 
 nsresult nsSVGPathDataParser::Match()
 {
   return MatchSvgPath();
 }
 
 //----------------------------------------------------------------------
 
@@ -837,19 +840,19 @@ CalcVectorAngle(double ux, double uy, do
   double ta = atan2(uy, ux);
   double tb = atan2(vy, vx);
   if (tb >= ta)
     return tb-ta;
   return 2 * M_PI - (ta-tb);
 }
 
 
-nsSVGArcConverter::nsSVGArcConverter(const gfxPoint &from,
-                                     const gfxPoint &to,
-                                     const gfxPoint &radii,
+nsSVGArcConverter::nsSVGArcConverter(const Point& from,
+                                     const Point& to,
+                                     const Point& radii,
                                      double angle,
                                      bool largeArcFlag,
                                      bool sweepFlag)
 {
   const double radPerDeg = M_PI/180.0;
   mSegIndex = 0;
 
   if (from == to) {
@@ -909,17 +912,17 @@ nsSVGArcConverter::nsSVGArcConverter(con
   mNumSegs = static_cast<int>(ceil(fabs(dtheta/(M_PI/2.0))));
   mDelta = dtheta/mNumSegs;
   mT = 8.0/3.0 * sin(mDelta/4.0) * sin(mDelta/4.0) / sin(mDelta/2.0);
 
   mFrom = from;
 }
 
 bool
-nsSVGArcConverter::GetNextSegment(gfxPoint *cp1, gfxPoint *cp2, gfxPoint *to)
+nsSVGArcConverter::GetNextSegment(Point* cp1, Point* cp2, Point* to)
 {
   if (mSegIndex == mNumSegs) {
     return false;
   }
   
   double cosTheta1 = cos(mTheta);
   double sinTheta1 = sin(mTheta);
   double theta2 = mTheta + mDelta;
--- a/content/svg/content/src/nsSVGPathDataParser.h
+++ b/content/svg/content/src/nsSVGPathDataParser.h
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __NS_SVGPATHDATAPARSER_H__
 #define __NS_SVGPATHDATAPARSER_H__
 
 #include "mozilla/Attributes.h"
+#include "mozilla/gfx/Point.h"
 #include "gfxPoint.h"
 #include "nsSVGDataParser.h"
 
 namespace mozilla {
 class SVGPathData;
 }
 
 ////////////////////////////////////////////////////////////////////////
@@ -104,30 +105,32 @@ protected:
                                  float* r1, float* r2, float* angle,
                                  bool* largeArcFlag, bool* sweepFlag);
   bool IsTokenEllipticalArcArgStarter();
   
  };
 
 class nsSVGArcConverter
 {
+  typedef mozilla::gfx::Point Point;
+
 public:
-  nsSVGArcConverter(const gfxPoint &from,
-                    const gfxPoint &to,
-                    const gfxPoint &radii,
+  nsSVGArcConverter(const Point& from,
+                    const Point& to,
+                    const Point& radii,
                     double angle,
                     bool largeArcFlag,
                     bool sweepFlag);
-  bool GetNextSegment(gfxPoint *cp1, gfxPoint *cp2, gfxPoint *to);
+  bool GetNextSegment(Point* cp1, Point* cp2, Point* to);
 protected:
   int32_t mNumSegs, mSegIndex;
   double mTheta, mDelta, mT;
   double mSinPhi, mCosPhi;
   double mRx, mRy;
-  gfxPoint mFrom, mC;
+  Point mFrom, mC;
 };
 
 class nsSVGPathDataParserToInternal : public nsSVGPathDataParser
 {
 public:
   nsSVGPathDataParserToInternal(mozilla::SVGPathData *aList)
     : mPathSegList(aList)
   {}
--- a/content/svg/document/src/moz.build
+++ b/content/svg/document/src/moz.build
@@ -5,17 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MODULE = 'content'
 
 EXPORTS.mozilla.dom += [
     'SVGDocument.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'SVGDocument.cpp',
 ]
 
 LIBRARY_NAME = 'gkconsvgdoc_s'
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
--- a/content/xbl/src/moz.build
+++ b/content/xbl/src/moz.build
@@ -11,17 +11,17 @@ EXPORTS += [
     'nsXBLBinding.h',
     'nsXBLService.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'XBLChildrenElement.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'nsBindingManager.cpp',
     'nsXBLBinding.cpp',
     'nsXBLContentSink.cpp',
     'nsXBLDocumentInfo.cpp',
     'nsXBLEventHandler.cpp',
     'nsXBLProtoImpl.cpp',
     'nsXBLProtoImplField.cpp',
     'nsXBLProtoImplMethod.cpp',
--- a/content/xbl/src/nsXBLPrototypeBinding.cpp
+++ b/content/xbl/src/nsXBLPrototypeBinding.cpp
@@ -993,35 +993,65 @@ nsXBLPrototypeBinding::Read(nsIObjectInp
       previousHandler->SetNextHandler(handler);
     }
     else {
       SetPrototypeHandlers(handler);
     }
     previousHandler = handler;
   } while (1);
 
+  if (mBinding) {
+    while (true) {
+      XBLBindingSerializeDetails type;
+      rv = aStream->Read8(&type);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      if (type != XBLBinding_Serialize_Attribute) {
+        break;
+      }
+
+      int32_t attrNamespace;
+      rv = ReadNamespace(aStream, attrNamespace);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      nsAutoString attrPrefix, attrName, attrValue;
+      rv = aStream->ReadString(attrPrefix);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      rv = aStream->ReadString(attrName);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      rv = aStream->ReadString(attrValue);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      nsCOMPtr<nsIAtom> atomPrefix = do_GetAtom(attrPrefix);
+      nsCOMPtr<nsIAtom> atomName = do_GetAtom(attrName);
+      mBinding->SetAttr(attrNamespace, atomName, atomPrefix, attrValue, false);
+    }
+  }
+
   // Finally, read in the resources.
-  do {
+  while (true) {
     XBLBindingSerializeDetails type;
     rv = aStream->Read8(&type);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (type == XBLBinding_Serialize_NoMoreItems)
       break;
 
     NS_ASSERTION((type & XBLBinding_Serialize_Mask) == XBLBinding_Serialize_Stylesheet ||
                  (type & XBLBinding_Serialize_Mask) == XBLBinding_Serialize_Image, "invalid resource type");
 
     nsAutoString src;
     rv = aStream->ReadString(src);
     NS_ENSURE_SUCCESS(rv, rv);
 
     AddResource(type == XBLBinding_Serialize_Stylesheet ? nsGkAtoms::stylesheet :
                                                           nsGkAtoms::image, src);
-  } while (1);
+  }
 
   if (isFirstBinding) {
     aDocInfo->SetFirstPrototypeBinding(this);
   }
 
   cleanup.Disconnect();
   return NS_OK;
 }
@@ -1121,16 +1151,49 @@ nsXBLPrototypeBinding::Write(nsIObjectOu
     NS_ENSURE_SUCCESS(rv, rv);
 
     handler = handler->GetNextHandler();
   }
 
   aStream->Write8(XBLBinding_Serialize_NoMoreItems);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  if (mBinding) {
+    uint32_t attributes = mBinding->GetAttrCount();
+    nsAutoString attrValue;
+    for (uint32_t i = 0; i < attributes; ++i) {
+      const nsAttrName* attr = mBinding->GetAttrNameAt(i);
+      nsDependentAtomString attrName = attr->LocalName();
+      mBinding->GetAttr(attr->NamespaceID(), attr->LocalName(), attrValue);
+      rv = aStream->Write8(XBLBinding_Serialize_Attribute);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      rv = WriteNamespace(aStream, attr->NamespaceID());
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      nsIAtom* prefix = attr->GetPrefix();
+      nsAutoString prefixString;
+      if (prefix) {
+        prefix->ToString(prefixString);
+      }
+
+      rv = aStream->WriteWStringZ(prefixString.get());
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      rv = aStream->WriteWStringZ(attrName.get());
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      rv = aStream->WriteWStringZ(attrValue.get());
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+  }
+
+  aStream->Write8(XBLBinding_Serialize_NoMoreItems);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   // Write out the resources
   if (mResources) {
     rv = mResources->Write(aStream);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // Write out an end mark at the end.
   return aStream->Write8(XBLBinding_Serialize_NoMoreItems);
--- a/content/xbl/src/nsXBLSerialize.h
+++ b/content/xbl/src/nsXBLSerialize.h
@@ -10,17 +10,17 @@
 #include "nsIObjectOutputStream.h"
 #include "nsINameSpaceManager.h"
 #include "js/TypeDecls.h"
 
 typedef uint8_t XBLBindingSerializeDetails;
 
 // A version number to ensure we don't load cached data in a different
 // file format.
-#define XBLBinding_Serialize_Version 0x00000002
+#define XBLBinding_Serialize_Version 0x00000003
 
 // Set for the first binding in a document
 #define XBLBinding_Serialize_IsFirstBinding 1
 
 // Set to indicate that nsXBLPrototypeBinding::mInheritStyle should be true
 #define XBLBinding_Serialize_InheritStyle 2
 
 // Set to indicate that nsXBLPrototypeBinding::mChromeOnlyContent should be true
@@ -40,16 +40,17 @@ typedef uint8_t XBLBindingSerializeDetai
 #define XBLBinding_Serialize_SetterProperty 3
 #define XBLBinding_Serialize_GetterSetterProperty 4
 #define XBLBinding_Serialize_Method 5
 #define XBLBinding_Serialize_Constructor 6
 #define XBLBinding_Serialize_Destructor 7
 #define XBLBinding_Serialize_Handler 8
 #define XBLBinding_Serialize_Image 9
 #define XBLBinding_Serialize_Stylesheet 10
+#define XBLBinding_Serialize_Attribute 0xA
 #define XBLBinding_Serialize_Mask 0x0F
 #define XBLBinding_Serialize_ReadOnly 0x80
 
 // Appears at the end of the list of insertion points to indicate that there
 // are no more. 
 #define XBLBinding_Serialize_NoMoreInsertionPoints 0xFFFFFFFF
 
 // When serializing content nodes, a single-byte namespace id is written out
--- a/content/xbl/src/nsXBLService.cpp
+++ b/content/xbl/src/nsXBLService.cpp
@@ -41,16 +41,17 @@
 #include "nsIPresShell.h"
 #include "nsIDocumentObserver.h"
 #include "nsFrameManager.h"
 #include "nsStyleContext.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIScriptError.h"
 #include "nsXBLSerialize.h"
 #include "nsDOMEvent.h"
+#include "nsEventListenerManager.h"
 
 #ifdef MOZ_XUL
 #include "nsXULPrototypeCache.h"
 #endif
 #include "nsIDOMEventListener.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/Attributes.h"
--- a/content/xml/content/src/moz.build
+++ b/content/xml/content/src/moz.build
@@ -8,17 +8,17 @@ MODULE = 'content'
 
 EXPORTS.mozilla.dom += [
     'CDATASection.h',
     'nsXMLElement.h',
     'ProcessingInstruction.h',
     'XMLStylesheetProcessingInstruction.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'CDATASection.cpp',
     'nsXMLElement.cpp',
     'ProcessingInstruction.cpp',
     'XMLStylesheetProcessingInstruction.cpp',
 ]
 
 LIBRARY_NAME = 'gkconxmlcon_s'
 
--- a/content/xml/document/src/moz.build
+++ b/content/xml/document/src/moz.build
@@ -5,17 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MODULE = 'content'
 
 EXPORTS.mozilla.dom += [
     'XMLDocument.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'nsXMLContentSink.cpp',
     'nsXMLFragmentContentSink.cpp',
     'nsXMLPrettyPrinter.cpp',
     'XMLDocument.cpp',
 ]
 
 LIBRARY_NAME = 'gkconxmldoc_s'
 
--- a/content/xslt/src/base/moz.build
+++ b/content/xslt/src/base/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'transformiix'
 
-CPP_SOURCES += [
+SOURCES += [
     'txDouble.cpp',
     'txExpandedNameMap.cpp',
     'txList.cpp',
     'txNamespaceMap.cpp',
     'txURIUtils.cpp',
 ]
 
 LIBRARY_NAME = 'txbase_s'
--- a/content/xslt/src/xml/moz.build
+++ b/content/xslt/src/xml/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'transformiix'
 
-CPP_SOURCES += [
+SOURCES += [
     'txXMLParser.cpp',
     'txXMLUtils.cpp',
 ]
 
 LIBRARY_NAME = 'txxml_s'
 
 FAIL_ON_WARNINGS = True
 
--- a/content/xslt/src/xpath/moz.build
+++ b/content/xslt/src/xpath/moz.build
@@ -5,17 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MODULE = 'transformiix'
 
 EXPORTS.mozilla.dom += [
     'XPathEvaluator.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'nsXPathExpression.cpp',
     'nsXPathNSResolver.cpp',
     'nsXPathResult.cpp',
     'txBooleanExpr.cpp',
     'txBooleanResult.cpp',
     'txCoreFunctionCall.cpp',
     'txErrorExpr.cpp',
     'txExpr.cpp',
--- a/content/xslt/src/xslt/moz.build
+++ b/content/xslt/src/xslt/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'transformiix'
 
-CPP_SOURCES += [
+SOURCES += [
     'txBufferingHandler.cpp',
     'txCurrentFunctionCall.cpp',
     'txDocumentFunctionCall.cpp',
     'txExecutionState.cpp',
     'txEXSLTFunctions.cpp',
     'txFormatNumberFunctionCall.cpp',
     'txGenerateIdFunctionCall.cpp',
     'txInstructions.cpp',
--- a/content/xul/content/src/moz.build
+++ b/content/xul/content/src/moz.build
@@ -5,17 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MODULE = 'xul'
 
 if CONFIG['MOZ_XUL']:
     LIBXUL_LIBRARY = True
     MSVC_ENABLE_PGO = True
 
-    CPP_SOURCES += [
+    SOURCES += [
         'nsXULContextMenuBuilder.cpp',
         'nsXULElement.cpp',
         'nsXULPopupListener.cpp',
     ]
     LIBRARY_NAME = 'gkconxulcon_s'
 
 FAIL_ON_WARNINGS = True
 
--- a/content/xul/document/src/moz.build
+++ b/content/xul/document/src/moz.build
@@ -1,22 +1,22 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'xuldoc'
 
-CPP_SOURCES += [
+SOURCES += [
     'nsXULControllers.cpp',
 ]
 
 if CONFIG['MOZ_XUL']:
-    CPP_SOURCES += [
+    SOURCES += [
         'nsXULCommandDispatcher.cpp',
         'nsXULContentSink.cpp',
         'nsXULPrototypeCache.cpp',
         'nsXULPrototypeDocument.cpp',
         'XULDocument.cpp',
     ]
 
 LIBRARY_NAME = 'gkconxuldoc_s'
--- a/content/xul/templates/src/moz.build
+++ b/content/xul/templates/src/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'xultmpl'
 
-CPP_SOURCES += [
+SOURCES += [
     'nsContentSupportMap.cpp',
     'nsContentTestNode.cpp',
     'nsInstantiationNode.cpp',
     'nsRDFBinding.cpp',
     'nsRDFConInstanceTestNode.cpp',
     'nsRDFConMemberTestNode.cpp',
     'nsRDFPropertyTestNode.cpp',
     'nsRDFQuery.cpp',
--- a/db/sqlite3/src/moz.build
+++ b/db/sqlite3/src/moz.build
@@ -7,12 +7,12 @@
 MODULE = 'sqlite3'
 
 EXPORTS += [
     'sqlite3.h',
 ]
 
 LIBRARY_NAME = 'mozsqlite3'
 
-CSRCS += [
+SOURCES += [
     'sqlite3.c',
 ]
 
--- a/docshell/base/Makefile.in
+++ b/docshell/base/Makefile.in
@@ -3,17 +3,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/.
 
 ifdef MOZ_TOOLKIT_SEARCH
 DEFINES += -DMOZ_TOOLKIT_SEARCH
 endif
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 LOCAL_INCLUDES += \
   -I$(srcdir)/../shistory/src \
   -I$(topsrcdir)/dom/base \
   -I$(topsrcdir)/layout/base \
   -I$(topsrcdir)/xpcom/ds \
   -I$(topsrcdir)/layout/generic \
   -I$(topsrcdir)/layout/xul/base/src \
--- a/docshell/base/moz.build
+++ b/docshell/base/moz.build
@@ -42,17 +42,17 @@ EXPORTS += [
     'SerializedLoadContext.h',
 ]
 
 EXPORTS.mozilla += [
     'IHistory.h',
     'LoadContext.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'LoadContext.cpp',
     'nsAboutRedirector.cpp',
     'nsDefaultURIFixup.cpp',
     'nsDocShell.cpp',
     'nsDocShellEditorData.cpp',
     'nsDocShellEnumerator.cpp',
     'nsDocShellLoadInfo.cpp',
     'nsDocShellTransferableHooks.cpp',
@@ -65,8 +65,10 @@ CPP_SOURCES += [
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'basedocshell_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/docshell/build/moz.build
+++ b/docshell/build/moz.build
@@ -5,17 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MODULE = 'docshell'
 
 EXPORTS += [
     'nsDocShellCID.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'nsDocShellModule.cpp',
 ]
 
 LIBRARY_NAME = 'docshell'
 
 LIBXUL_LIBRARY = True
 
 LOCAL_INCLUDES += [
--- a/docshell/shistory/src/moz.build
+++ b/docshell/shistory/src/moz.build
@@ -5,17 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MODULE = 'shistory'
 
 EXPORTS += [
     'nsSHEntryShared.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'nsSHEntry.cpp',
     'nsSHEntryShared.cpp',
     'nsSHistory.cpp',
     'nsSHTransaction.cpp',
 ]
 
 LIBRARY_NAME = 'shistory_s'
 
--- a/dom/activities/src/moz.build
+++ b/dom/activities/src/moz.build
@@ -5,17 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MODULE = 'dom'
 
 EXPORTS.mozilla.dom += [
     'Activity.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'Activity.cpp',
 ]
 
 EXTRA_COMPONENTS += [
     'Activities.manifest',
     'ActivityMessageConfigurator.js',
     'ActivityOptions.js',
     'ActivityProxy.js',
--- a/dom/alarm/Makefile.in
+++ b/dom/alarm/Makefile.in
@@ -1,9 +1,6 @@
 # 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)/dom/dom-config.mk
-
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/alarm/moz.build
+++ b/dom/alarm/moz.build
@@ -14,17 +14,17 @@ XPIDL_SOURCES += [
 XPIDL_MODULE = 'dom_alarm'
 
 MODULE = 'dom'
 
 EXPORTS.mozilla.dom.alarm += [
     'AlarmHalService.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'AlarmHalService.cpp',
 ]
 
 EXTRA_COMPONENTS += [
     'AlarmsManager.js',
     'AlarmsManager.manifest',
 ]
 
@@ -34,8 +34,10 @@ EXTRA_JS_MODULES += [
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'domalarm_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/apps/src/Makefile.in
+++ b/dom/apps/src/Makefile.in
@@ -1,10 +1,9 @@
 # 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/.
 
 LOCAL_INCLUDES += \
   -I$(topsrcdir)/js/xpconnect/wrappers \
   $(NULL)
 
-include $(topsrcdir)/dom/dom-config.mk
 include $(topsrcdir)/config/rules.mk
--- a/dom/apps/src/moz.build
+++ b/dom/apps/src/moz.build
@@ -3,17 +3,17 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS.mozilla.dom += [
     'InterAppComm.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'InterAppComm.cpp',
 ]
 
 EXTRA_COMPONENTS += [
     'AppsService.js',
     'AppsService.manifest',
     'InterAppComm.manifest',
     'InterAppCommService.js',
deleted file mode 100644
--- a/dom/audiochannel/Makefile.in
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2012 Mozilla Foundation and Mozilla contributors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/audiochannel/moz.build
+++ b/dom/audiochannel/moz.build
@@ -16,22 +16,24 @@ MODULE = 'dom'
 
 EXPORTS += [
     'AudioChannelAgent.h',
     'AudioChannelCommon.h',
     'AudioChannelService.h',
     'AudioChannelServiceChild.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'AudioChannelAgent.cpp',
     'AudioChannelService.cpp',
     'AudioChannelServiceChild.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'domaudiochannel_s'
 
 EXPORT_LIBRARY = True
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/base/Makefile.in
+++ b/dom/base/Makefile.in
@@ -1,28 +1,25 @@
 # 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)/dom/dom-config.mk
-
 ifdef MOZ_JSDEBUGGER
 DEFINES += -DMOZ_JSDEBUGGER
 endif
 
 ifdef MOZ_B2G_RIL
 DEFINES += -DMOZ_B2G_RIL
 endif
 
 ifdef MOZ_B2G_FM
 DEFINES += -DMOZ_B2G_FM
 endif
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 LOCAL_INCLUDES += \
 		-I$(topsrcdir)/js/xpconnect/src \
 		-I$(topsrcdir)/js/xpconnect/wrappers \
 		-I$(topsrcdir)/xpcom/ds \
 		$(NULL)
 
 ifdef MOZ_X11
--- a/dom/base/MessagePort.cpp
+++ b/dom/base/MessagePort.cpp
@@ -240,18 +240,17 @@ PostMessageRunnable::Run()
 
   // Deserialize the structured clone data
   JS::Rooted<JS::Value> messageData(cx);
   {
     StructuredCloneInfo scInfo;
     scInfo.mEvent = this;
     scInfo.mPort = mPort;
 
-    if (!buffer.read(cx, messageData.address(), &kPostMessageCallbacks,
-                     &scInfo)) {
+    if (!buffer.read(cx, &messageData, &kPostMessageCallbacks, &scInfo)) {
       return NS_ERROR_DOM_DATA_CLONE_ERR;
     }
   }
 
   // Create the event
   nsIDocument* doc = mPort->GetOwner()->GetExtantDoc();
   if (!doc) {
     return NS_OK;
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -58,17 +58,17 @@ EXPORTS.mozilla.dom += [
     'MessageChannel.h',
     'MessagePort.h',
     'MessagePortList.h',
     'ScreenOrientation.h',
     'StructuredCloneTags.h',
     'URL.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'BarProps.cpp',
     'CompositionStringSynthesizer.cpp',
     'Crypto.cpp',
     'DOMCursor.cpp',
     'DOMError.cpp',
     'DOMException.cpp',
     'DOMRequest.cpp',
     'MessageChannel.cpp',
@@ -120,8 +120,34 @@ EXTRA_JS_MODULES += [
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'jsdombase_s'
 
+LOCAL_INCLUDES += [
+    '../battery',
+    '../bluetooth',
+    '../icc/src',
+    '../media',
+    '../network/src',
+    '../src/geolocation',
+    '../src/storage',
+    '../time',
+    '/content/base/src',
+    '/content/events/src',
+    '/content/html/document/src',
+    '/content/xbl/src',
+    '/content/xul/document/src',
+    '/layout/generic',
+    '/layout/style',
+    '/layout/xul/base/src',
+]
+
+if CONFIG['MOZ_B2G_RIL']:
+    LOCAL_INCLUDES += [
+        '../fmradio',
+        '../system/gonk',
+    ]
+
+include('/ipc/chromium/chromium-config.mozbuild')
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -3872,17 +3872,17 @@ nsGlobalWindow::GetApplicationCache(nsID
   NS_IF_ADDREF(*aApplicationCache = mApplicationCache);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::GetCrypto(nsIDOMCrypto** aCrypto)
 {
-  FORWARD_TO_OUTER(GetCrypto, (aCrypto), NS_ERROR_NOT_INITIALIZED);
+  FORWARD_TO_INNER(GetCrypto, (aCrypto), NS_ERROR_NOT_INITIALIZED);
 
   if (!mCrypto) {
 #ifndef MOZ_DISABLE_CRYPTOLEGACY
     if (XRE_GetProcessType() != GeckoProcessType_Content) {
       nsresult rv;
       mCrypto = do_CreateInstance(NS_CRYPTO_CONTRACTID, &rv);
       NS_ENSURE_SUCCESS(rv, rv);
     } else
@@ -5766,36 +5766,35 @@ nsGlobalWindow::Blur()
   // If dom.disable_window_flip == true, then content should not be allowed
   // to call this function (this would allow popunders, bug 369306)
   if (!CanSetProperty("dom.disable_window_flip")) {
     return NS_OK;
   }
 
   // If embedding apps don't implement nsIEmbeddingSiteWindow, we
   // shouldn't throw exceptions to web content.
-  nsresult rv = NS_OK;
 
   nsCOMPtr<nsIDocShellTreeOwner> treeOwner = GetTreeOwner();
   nsCOMPtr<nsIEmbeddingSiteWindow> siteWindow(do_GetInterface(treeOwner));
   if (siteWindow) {
     // This method call may cause mDocShell to become nullptr.
-    rv = siteWindow->Blur();
+    siteWindow->Blur();
 
     // if the root is focused, clear the focus
     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
     if (fm && mDoc) {
       nsCOMPtr<nsIDOMElement> element;
       fm->GetFocusedElementForWindow(this, false, nullptr, getter_AddRefs(element));
       nsCOMPtr<nsIContent> content = do_QueryInterface(element);
       if (content == mDoc->GetRootElement())
         fm->ClearFocus(this);
     }
   }
 
-  return rv;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::Back()
 {
   FORWARD_TO_OUTER(Back, (), NS_ERROR_NOT_INITIALIZED);
 
   nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
@@ -6973,18 +6972,17 @@ PostMessageEvent::Run()
 
   // Deserialize the structured clone data
   JS::Rooted<JS::Value> messageData(cx);
   {
     StructuredCloneInfo scInfo;
     scInfo.event = this;
     scInfo.window = targetWindow;
 
-    if (!buffer.read(cx, messageData.address(), &kPostMessageCallbacks,
-                     &scInfo)) {
+    if (!buffer.read(cx, &messageData, &kPostMessageCallbacks, &scInfo)) {
       return NS_ERROR_DOM_DATA_CLONE_ERR;
     }
   }
 
   // Create the event
   nsIDocument* doc = targetWindow->mDoc;
   if (!doc)
     return NS_OK;
@@ -7124,17 +7122,19 @@ nsGlobalWindow::PostMessageMoz(const JS:
   StructuredCloneInfo scInfo;
   scInfo.event = event;
   scInfo.window = this;
 
   nsIPrincipal* principal = GetPrincipal();
   if (NS_FAILED(callerPrin->Subsumes(principal, &scInfo.subsumes)))
     return NS_ERROR_DOM_DATA_CLONE_ERR;
 
-  if (!buffer.write(aCx, aMessage, aTransfer, &kPostMessageCallbacks, &scInfo))
+  JS::Rooted<JS::Value> message(aCx, aMessage);
+  JS::Rooted<JS::Value> transfer(aCx, aTransfer);
+  if (!buffer.write(aCx, message, transfer, &kPostMessageCallbacks, &scInfo))
     return NS_ERROR_DOM_DATA_CLONE_ERR;
 
   event->SetJSData(buffer);
 
   return NS_DispatchToCurrentThread(event);
 }
 
 class nsCloseEvent : public nsRunnable {
@@ -12117,38 +12117,38 @@ nsGlobalWindow::DisableNetworkEvent(uint
     elm->SetEventHandler(handler);                                           \
     return NS_OK;                                                            \
   }
 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                       \
   NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx,                  \
                                              JS::Value *vp) {                \
     nsEventListenerManager *elm = GetExistingListenerManager();              \
     if (elm) {                                                               \
-      BeforeUnloadEventHandlerNonNull* h =                                   \
+      OnBeforeUnloadEventHandlerNonNull* h =                                 \
         elm->GetOnBeforeUnloadEventHandler();                                \
       if (h) {                                                               \
         *vp = JS::ObjectValue(*h->Callable());                               \
         return NS_OK;                                                        \
       }                                                                      \
     }                                                                        \
     *vp = JSVAL_NULL;                                                        \
     return NS_OK;                                                            \
   }                                                                          \
   NS_IMETHODIMP nsGlobalWindow::SetOn##name_(JSContext *cx,                  \
                                              const JS::Value &v) {           \
     nsEventListenerManager *elm = GetOrCreateListenerManager();              \
     if (!elm) {                                                              \
       return NS_ERROR_OUT_OF_MEMORY;                                         \
     }                                                                        \
                                                                              \
-    nsRefPtr<BeforeUnloadEventHandlerNonNull> handler;                       \
+    nsRefPtr<OnBeforeUnloadEventHandlerNonNull> handler;                     \
     JSObject *callable;                                                      \
     if (v.isObject() &&                                                      \
         JS_ObjectIsCallable(cx, callable = &v.toObject())) {                 \
-      handler = new BeforeUnloadEventHandlerNonNull(callable);               \
+      handler = new OnBeforeUnloadEventHandlerNonNull(callable);             \
     }                                                                        \
     elm->SetEventHandler(handler);                                           \
     return NS_OK;                                                            \
   }
 #define WINDOW_ONLY_EVENT EVENT
 #define TOUCH_EVENT EVENT
 #include "nsEventNameList.h"
 #undef TOUCH_EVENT
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -735,22 +735,22 @@ public:
   void SetOn##name_(mozilla::dom::OnErrorEventHandlerNonNull* handler)        \
   {                                                                           \
     nsEventListenerManager *elm = GetOrCreateListenerManager();               \
     if (elm) {                                                                \
       elm->SetEventHandler(handler);                                          \
     }                                                                         \
   }
 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                        \
-  mozilla::dom::BeforeUnloadEventHandlerNonNull* GetOn##name_()               \
+  mozilla::dom::OnBeforeUnloadEventHandlerNonNull* GetOn##name_()             \
   {                                                                           \
     nsEventListenerManager *elm = GetExistingListenerManager();               \
     return elm ? elm->GetOnBeforeUnloadEventHandler() : nullptr;              \
   }                                                                           \
-  void SetOn##name_(mozilla::dom::BeforeUnloadEventHandlerNonNull* handler)   \
+  void SetOn##name_(mozilla::dom::OnBeforeUnloadEventHandlerNonNull* handler) \
   {                                                                           \
     nsEventListenerManager *elm = GetOrCreateListenerManager();               \
     if (elm) {                                                                \
       elm->SetEventHandler(handler);                                          \
     }                                                                         \
   }
 #define WINDOW_ONLY_EVENT EVENT
 #define TOUCH_EVENT EVENT
--- a/dom/base/nsIJSEventListener.h
+++ b/dom/base/nsIJSEventListener.h
@@ -16,18 +16,18 @@
 #define NS_IJSEVENTLISTENER_IID \
 { 0x92f9212b, 0xa6aa, 0x4867, \
   { 0x93, 0x8a, 0x56, 0xbe, 0x17, 0x67, 0x4f, 0xd4 } }
 
 class nsEventHandler
 {
 public:
   typedef mozilla::dom::EventHandlerNonNull EventHandlerNonNull;
-  typedef mozilla::dom::BeforeUnloadEventHandlerNonNull
-    BeforeUnloadEventHandlerNonNull;
+  typedef mozilla::dom::OnBeforeUnloadEventHandlerNonNull
+    OnBeforeUnloadEventHandlerNonNull;
   typedef mozilla::dom::OnErrorEventHandlerNonNull OnErrorEventHandlerNonNull;
   typedef mozilla::dom::CallbackFunction CallbackFunction;
 
   enum HandlerType {
     eUnset = 0,
     eNormal = 0x1,
     eOnError = 0x2,
     eOnBeforeUnload = 0x3,
@@ -43,17 +43,17 @@ public:
     Assign(aHandler, eNormal);
   }
 
   nsEventHandler(OnErrorEventHandlerNonNull* aHandler)
   {
     Assign(aHandler, eOnError);
   }
 
-  nsEventHandler(BeforeUnloadEventHandlerNonNull* aHandler)
+  nsEventHandler(OnBeforeUnloadEventHandlerNonNull* aHandler)
   {
     Assign(aHandler, eOnBeforeUnload);
   }
 
   nsEventHandler(const nsEventHandler& aOther)
   {
     if (aOther.HasEventHandler()) {
       // Have to make sure we take our own ref
@@ -94,23 +94,23 @@ public:
   }
 
   void SetHandler(EventHandlerNonNull* aHandler)
   {
     ReleaseHandler();
     Assign(aHandler, eNormal);
   }
 
-  BeforeUnloadEventHandlerNonNull* BeforeUnloadEventHandler() const
+  OnBeforeUnloadEventHandlerNonNull* OnBeforeUnloadEventHandler() const
   {
     MOZ_ASSERT(Type() == eOnBeforeUnload);
-    return reinterpret_cast<BeforeUnloadEventHandlerNonNull*>(Ptr());
+    return reinterpret_cast<OnBeforeUnloadEventHandlerNonNull*>(Ptr());
   }
 
-  void SetHandler(BeforeUnloadEventHandlerNonNull* aHandler)
+  void SetHandler(OnBeforeUnloadEventHandlerNonNull* aHandler)
   {
     ReleaseHandler();
     Assign(aHandler, eOnBeforeUnload);
   }
 
   OnErrorEventHandlerNonNull* OnErrorEventHandler() const
   {
     MOZ_ASSERT(Type() == eOnError);
@@ -232,17 +232,17 @@ public:
     mHandler.SetHandler(aHandler);
     mContext = aContext;
     UpdateScopeObject(aScopeObject);
   }
   void SetHandler(mozilla::dom::EventHandlerNonNull* aHandler)
   {
     mHandler.SetHandler(aHandler);
   }
-  void SetHandler(mozilla::dom::BeforeUnloadEventHandlerNonNull* aHandler)
+  void SetHandler(mozilla::dom::OnBeforeUnloadEventHandlerNonNull* aHandler)
   {
     mHandler.SetHandler(aHandler);
   }
   void SetHandler(mozilla::dom::OnErrorEventHandlerNonNull* aHandler)
   {
     mHandler.SetHandler(aHandler);
   }
 
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1039,20 +1039,22 @@ nsJSContext::JSObjectFromInterface(nsISu
   NS_ENSURE_SUCCESS(rv, rv);
 
   JSObject* obj = v.toObjectOrNull();
   if (obj) {
     JS::ExposeObjectToActiveJS(obj);
   }
 
 #ifdef DEBUG
+  JS::Rooted<JSObject*> rootedObj(cx, obj);
   nsCOMPtr<nsISupports> targetSupp = do_QueryInterface(aTarget);
   nsCOMPtr<nsISupports> native =
-    nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, obj);
+    nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, rootedObj);
   NS_ASSERTION(native == targetSupp, "Native should be the target!");
+  obj = rootedObj;
 #endif
 
   *aRet = obj;
   return NS_OK;
 }
 
 nsresult
 nsJSContext::BindCompiledEventHandler(nsISupports* aTarget,
--- a/dom/base/nsStructuredCloneContainer.cpp
+++ b/dom/base/nsStructuredCloneContainer.cpp
@@ -47,17 +47,18 @@ nsStructuredCloneContainer::InitFromJSVa
 
   // Make sure that we serialize in the right context.
   MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
   JS::Rooted<JS::Value> jsData(aCx, aData);
   JS_WrapValue(aCx, jsData.address());
 
   uint64_t* jsBytes = nullptr;
   bool success = JS_WriteStructuredClone(aCx, jsData, &jsBytes, &mSize,
-                                         nullptr, nullptr, JSVAL_VOID);
+                                         nullptr, nullptr,
+                                         JS::UndefinedHandleValue);
   NS_ENSURE_STATE(success);
   NS_ENSURE_STATE(jsBytes);
 
   // Copy jsBytes into our own buffer.
   mData = (uint64_t*) malloc(mSize);
   if (!mData) {
     mSize = 0;
     mVersion = 0;
@@ -106,18 +107,17 @@ nsStructuredCloneContainer::DeserializeT
   NS_ENSURE_STATE(mData);
   NS_ENSURE_ARG_POINTER(aData);
   *aData = nullptr;
 
   // Deserialize to a JS::Value.
   JS::Rooted<JS::Value> jsStateObj(aCx);
   bool hasTransferable = false;
   bool success = JS_ReadStructuredClone(aCx, mData, mSize, mVersion,
-                                        jsStateObj.address(), nullptr,
-                                        nullptr) &&
+                                        &jsStateObj, nullptr, nullptr) &&
                  JS_StructuredCloneHasTransferables(mData, mSize,
                                                     &hasTransferable);
   // We want to be sure that mData doesn't contain transferable objects
   MOZ_ASSERT(!hasTransferable);
   NS_ENSURE_STATE(success && !hasTransferable);
 
   // Now wrap the JS::Value as an nsIVariant.
   nsCOMPtr<nsIVariant> varStateObj;
--- a/dom/base/nsWindowRoot.h
+++ b/dom/base/nsWindowRoot.h
@@ -11,19 +11,19 @@ class nsPIDOMWindow;
 class nsIDOMEventListener;
 class nsEventListenerManager;
 class nsIDOMEvent;
 class nsEventChainPreVisitor;
 class nsEventChainPostVisitor;
 
 #include "mozilla/Attributes.h"
 #include "nsIDOMEventTarget.h"
-#include "nsEventListenerManager.h"
 #include "nsPIWindowRoot.h"
 #include "nsCycleCollectionParticipant.h"
+#include "nsAutoPtr.h"
 
 class nsWindowRoot : public nsPIWindowRoot
 {
 public:
   nsWindowRoot(nsPIDOMWindow* aWindow);
   virtual ~nsWindowRoot();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
--- a/dom/battery/Makefile.in
+++ b/dom/battery/Makefile.in
@@ -1,12 +1,10 @@
 # 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)/dom/dom-config.mk
 
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/content/events/src \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/battery/moz.build
+++ b/dom/battery/moz.build
@@ -6,18 +6,20 @@
 
 TEST_DIRS += ['test']
 
 EXPORTS.mozilla.dom.battery += [
     'Constants.h',
     'Types.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'BatteryManager.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'dom_battery_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1636,17 +1636,19 @@ class AttrDefiner(PropertyDefiner):
             else:
                 accessor = ("genericLenientGetter" if attr.hasLenientThis()
                             else "genericGetter")
                 jitinfo = "&%s_getterinfo" % attr.identifier.name
             return "{ JS_CAST_NATIVE_TO(%s, JSPropertyOp), %s }" % \
                    (accessor, jitinfo)
 
         def setter(attr):
-            if attr.readonly and attr.getExtendedAttribute("PutForwards") is None:
+            if (attr.readonly and
+                attr.getExtendedAttribute("PutForwards") is None and
+                attr.getExtendedAttribute("Replaceable") is None):
                 return "JSOP_NULLWRAPPER"
             if self.static:
                 accessor = 'set_' + attr.identifier.name
                 jitinfo = "nullptr"
             else:
                 accessor = ("genericLenientSetter" if attr.hasLenientThis()
                             else "genericSetter")
                 jitinfo = "&%s_setterinfo" % attr.identifier.name
@@ -3928,17 +3930,17 @@ class CGArgumentConverter(CGThing):
         variadicConversion += ("\n"
                                "  }\n"
                                "}")
         return variadicConversion
 
 sequenceWrapLevel = 0
 
 def getWrapTemplateForType(type, descriptorProvider, result, successCode,
-                           isCreator, exceptionCode, typedArraysAreStructs):
+                           returnsNewObject, exceptionCode, typedArraysAreStructs):
     """
     Reflect a C++ value stored in "result", of IDL type "type" into JS.  The
     "successCode" is the code to run once we have successfully done the
     conversion and must guarantee that execution of the conversion template
     stops once the successCode has executed (e.g. by doing a 'return', or by
     doing a 'break' if the entire conversion template is inside a block that
     the 'break' will exit).
 
@@ -4015,17 +4017,17 @@ def getWrapTemplateForType(type, descrip
     if type.isArray():
         raise TypeError("Can't handle array return values yet")
 
     if type.isSequence():
         if type.nullable():
             # Nullable sequences are Nullable< nsTArray<T> >
             (recTemplate, recInfall) = getWrapTemplateForType(type.inner, descriptorProvider,
                                                               "%s.Value()" % result, successCode,
-                                                              isCreator, exceptionCode,
+                                                              returnsNewObject, exceptionCode,
                                                               typedArraysAreStructs)
             return ("""
 if (%s.IsNull()) {
 %s
 }
 %s""" % (result, CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define(), recTemplate), recInfall)
 
         # Now do non-nullable sequences.  Our success code is just to break to
@@ -4037,17 +4039,17 @@ if (%s.IsNull()) {
         sequenceWrapLevel += 1
         innerTemplate = wrapForType(
             type.inner, descriptorProvider,
             {
                 'result' :  "%s[%s]" % (result, index),
                 'successCode': "break;",
                 'jsvalRef': "tmp",
                 'jsvalHandle': "&tmp",
-                'isCreator': isCreator,
+                'returnsNewObject': returnsNewObject,
                 'exceptionCode': exceptionCode,
                 'obj': "returnArray"
                 }
             )
         sequenceWrapLevel -= 1
         innerTemplate = CGIndenter(CGGeneric(innerTemplate), 6).define()
         return (("""
 uint32_t length = %s.Length();
@@ -4084,18 +4086,18 @@ if (!returnArray) {
         else:
             wrappingCode = ""
 
         if not descriptor.interface.isExternal() and not descriptor.skipGen:
             if descriptor.wrapperCache:
                 assert descriptor.nativeOwnership != 'owned'
                 wrapMethod = "WrapNewBindingObject"
             else:
-                if not isCreator:
-                    raise MethodNotCreatorError(descriptor.interface.identifier.name)
+                if not returnsNewObject:
+                    raise MethodNotNewObjectError(descriptor.interface.identifier.name)
                 if descriptor.nativeOwnership == 'owned':
                     wrapMethod = "WrapNewBindingNonWrapperCachedOwnedObject"
                 else:
                     wrapMethod = "WrapNewBindingNonWrapperCachedObject"
             wrap = "%s(cx, ${obj}, %s, ${jsvalHandle})" % (wrapMethod, result)
             if not descriptor.hasXPConnectImpls:
                 # Can only fail to wrap as a new-binding object
                 # if they already threw an exception.
@@ -4198,17 +4200,17 @@ if (!returnArray) {
     if not (type.isUnion() or type.isPrimitive() or type.isDictionary() or
             type.isDate() or
             (type.isSpiderMonkeyInterface() and typedArraysAreStructs)):
         raise TypeError("Need to learn to wrap %s" % type)
 
     if type.nullable():
         (recTemplate, recInfal) = getWrapTemplateForType(type.inner, descriptorProvider,
                                                          "%s.Value()" % result, successCode,
-                                                         isCreator, exceptionCode,
+                                                         returnsNewObject, exceptionCode,
                                                          typedArraysAreStructs)
         return ("if (%s.IsNull()) {\n" % result +
                 CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define() + "\n" +
                 "}\n" + recTemplate, recInfal)
 
     if type.isSpiderMonkeyInterface():
         assert typedArraysAreStructs
         # See comments in WrapNewBindingObject explaining why we need
@@ -4271,47 +4273,48 @@ def wrapForType(type, descriptorProvider
                              the name
       * 'successCode' (optional): the code to run once we have successfully
                                   done the conversion, if not supplied 'return
                                   true;' will be used as the code.  The
                                   successCode must ensure that once it runs no
                                   more of the conversion template will be
                                   executed (e.g. by doing a 'return' or 'break'
                                   as appropriate).
-      * 'isCreator' (optional): If true, we're wrapping for the return value of
-                                a [Creator] method.  Assumed false if not set.
+      * 'returnsNewObject' (optional): If true, we're wrapping for the return
+                                       value of a [NewObject] method.  Assumed
+                                       false if not set.
       * 'exceptionCode' (optional): Code to run when a JS exception is thrown.
                                     The default is "return false;".  The code
                                     passed here must return.
     """
     wrap = getWrapTemplateForType(type, descriptorProvider,
                                   templateValues.get('result', 'result'),
                                   templateValues.get('successCode', None),
-                                  templateValues.get('isCreator', False),
+                                  templateValues.get('returnsNewObject', False),
                                   templateValues.get('exceptionCode',
                                                      "return false;"),
                                   templateValues.get('typedArraysAreStructs',
                                                      False))[0]
 
     defaultValues = {'obj': 'obj'}
     return string.Template(wrap).substitute(defaultValues, **templateValues)
 
 def infallibleForMember(member, type, descriptorProvider):
     """
     Determine the fallibility of changing a C++ value of IDL type "type" into
-    JS for the given attribute. Apart from isCreator, all the defaults are used,
-    since the fallbility does not change based on the boolean values,
+    JS for the given attribute. Apart from returnsNewObject, all the defaults
+    are used, since the fallbility does not change based on the boolean values,
     and the template will be discarded.
 
     CURRENT ASSUMPTIONS:
         We assume that successCode for wrapping up return values cannot contain
         failure conditions.
     """
     return getWrapTemplateForType(type, descriptorProvider, 'result', None,\
-                                  memberIsCreator(member), "return false;",
+                                  memberReturnsNewObject(member), "return false;",
                                   False)[1]
 
 def leafTypeNeedsCx(type, retVal):
     return (type.isAny() or type.isObject() or
             (retVal and type.isSpiderMonkeyInterface()))
 
 def leafTypeNeedsScopeObject(type, retVal):
     return retVal and type.isSpiderMonkeyInterface()
@@ -4579,17 +4582,17 @@ def getUnionMemberName(type):
     if type.isGeckoInterface():
         return type.inner.identifier.name
     if type.isEnum():
         return type.inner.identifier.name
     if type.isArray() or type.isSequence():
         return str(type)
     return type.name
 
-class MethodNotCreatorError(Exception):
+class MethodNotNewObjectError(Exception):
     def __init__(self, typename):
         self.typename = typename
 
 # A counter for making sure that when we're wrapping up things in
 # nested sequences we don't use the same variable name to iterate over
 # different sequences.
 sequenceWrapLevel = 0
 
@@ -4853,36 +4856,36 @@ if (!${obj}) {
 
     def getArguments(self):
         return [(a, "arg" + str(i)) for (i, a) in enumerate(self.arguments)]
 
     def isFallible(self):
         return not 'infallible' in self.extendedAttributes
 
     def wrap_return_value(self):
-        isCreator = memberIsCreator(self.idlNode)
-        if isCreator:
+        returnsNewObject = memberReturnsNewObject(self.idlNode)
+        if returnsNewObject:
             # We better be returning addrefed things!
             assert(isResultAlreadyAddRefed(self.extendedAttributes) or
-                   # Creators can return raw pointers to owned objects
+                   # NewObject can return raw pointers to owned objects
                    (self.returnType.isGeckoInterface() and
                     self.descriptor.getDescriptor(self.returnType.unroll().inner.identifier.name).nativeOwnership == 'owned') or
                    # Workers use raw pointers for new-object return
                    # values or something
                    self.descriptor.getDescriptor(self.returnType.unroll().inner.identifier.name).nativeOwnership == 'worker')
 
         resultTemplateValues = { 'jsvalRef': 'args.rval()',
                                  'jsvalHandle': 'args.rval()',
-                                 'isCreator': isCreator}
+                                 'returnsNewObject': returnsNewObject}
         try:
             return wrapForType(self.returnType, self.descriptor,
                                resultTemplateValues)
-        except MethodNotCreatorError, err:
-            assert not isCreator
-            raise TypeError("%s being returned from non-creator method or property %s.%s" %
+        except MethodNotNewObjectError, err:
+            assert not returnsNewObject
+            raise TypeError("%s being returned from non-NewObject method or property %s.%s" %
                             (err.typename,
                              self.descriptor.interface.identifier.name,
                              self.idlNode.identifier.name))
 
     def getErrorReport(self):
         jsImplemented = ""
         if self.descriptor.interface.isJSImplemented():
             jsImplemented = ", true"
@@ -5789,18 +5792,41 @@ if (!JS_GetProperty(cx, obj, "%s", &v)) 
 }
 
 if (!v.isObject()) {
   return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "%s.%s");
 }
 
 return JS_SetProperty(cx, &v.toObject(), "%s", args[0]);""" % (attrName, self.descriptor.interface.identifier.name, attrName, forwardToAttrName))).define()
 
-def memberIsCreator(member):
-    return member.getExtendedAttribute("Creator") is not None
+class CGSpecializedReplaceableSetter(CGSpecializedSetter):
+    """
+    A class for generating the code for a specialized attribute setter with
+    Replaceable that the JIT can call with lower overhead.
+    """
+    def __init__(self, descriptor, attr):
+        CGSpecializedSetter.__init__(self, descriptor, attr)
+
+    def definition_body(self):
+        attrName = self.attr.identifier.name
+        return CGIndenter(CGGeneric("""JS::Rooted<JSPropertyDescriptor> desc(cx);
+desc.object().set(obj);
+desc.setEnumerable();
+desc.value().set(args[0]);
+
+JS::Rooted<jsid> id(cx);
+if (!InternJSString(cx, id.get(), "%s")) {
+  return false;
+}
+
+bool b;
+return js_DefineOwnProperty(cx, obj, id, desc, &b);""" % attrName)).define()
+
+def memberReturnsNewObject(member):
+    return member.getExtendedAttribute("NewObject") is not None
 
 class CGMemberJITInfo(CGThing):
     """
     A class for generating the JITInfo for a property that points to
     our specialized getter and setter.
     """
     def __init__(self, descriptor, member):
         self.member = member
@@ -5843,17 +5869,19 @@ class CGMemberJITInfo(CGThing):
                            self.member.getExtendedAttribute("Constant"))
             getterpure = getterconst or self.member.getExtendedAttribute("Pure")
             assert (getterinfal or (not getterconst and not getterpure))
 
             getterinfal = getterinfal and infallibleForMember(self.member, self.member.type, self.descriptor)
             result = self.defineJitInfo(getterinfo, getter, "Getter",
                                         getterinfal, getterconst, getterpure,
                                         [self.member.type])
-            if not self.member.readonly or self.member.getExtendedAttribute("PutForwards") is not None:
+            if (not self.member.readonly or
+                self.member.getExtendedAttribute("PutForwards") is not None or
+                self.member.getExtendedAttribute("Replaceable") is not None):
                 setterinfo = ("%s_setterinfo" % self.member.identifier.name)
                 # Actually a JSJitSetterOp, but JSJitGetterOp is first in the
                 # union.
                 setter = ("(JSJitGetterOp)set_%s" % self.member.identifier.name)
                 # Setters are always fallible, since they have to do a typed unwrap.
                 result += self.defineJitInfo(setterinfo, setter, "Setter",
                                              False, False, False,
                                              [BuiltinTypes[IDLBuiltinType.Types.void]])
@@ -7965,16 +7993,19 @@ class CGDescriptor(CGThing):
                         cgThings.append(CGSpecializedSetter(descriptor, m))
                         if m.hasLenientThis():
                             hasLenientSetter = True
                         else:
                             hasSetter = True
                 elif m.getExtendedAttribute("PutForwards"):
                     cgThings.append(CGSpecializedForwardingSetter(descriptor, m))
                     hasSetter = True
+                elif m.getExtendedAttribute("Replaceable"):
+                    cgThings.append(CGSpecializedReplaceableSetter(descriptor, m))
+                    hasSetter = True
                 if (not m.isStatic() and
                     descriptor.interface.hasInterfacePrototypeObject()):
                     cgThings.append(CGMemberJITInfo(descriptor, m))
         if hasJsonifier:
             cgThings.append(CGJsonifierMethod(descriptor, jsonifierMethod))
             cgThings.append(CGMemberJITInfo(descriptor, jsonifierMethod))
         if hasMethod: cgThings.append(CGGenericMethod(descriptor))
         if hasGetter: cgThings.append(CGGenericGetter(descriptor))
@@ -8533,17 +8564,17 @@ if (""",
             {
                 'result' : "currentValue",
                 'successCode' : ("if (!%s) {\n"
                                  "  return false;\n"
                                  "}\n"
                                  "break;" % propDef),
                 'jsvalRef': "temp",
                 'jsvalHandle': "&temp",
-                'isCreator': False,
+                'returnsNewObject': False,
                 'obj': "parentObject",
                 'typedArraysAreStructs': True
             })
         conversion = CGGeneric(innerTemplate)
         conversion = CGWrapper(conversion,
                                pre=("JS::Rooted<JS::Value> temp(cx);\n"
                                     "%s const & currentValue = %s;\n" %
                                     (declType.define(), memberData)
@@ -9129,17 +9160,17 @@ class CGNativeMember(ClassMethod):
                 if nativeType[0] == "dom":
                     nativeType.pop(0)
             result = CGGeneric("::".join(nativeType))
             if self.resultAlreadyAddRefed:
                 if isMember:
                     holder = "nsRefPtr"
                 else:
                     holder = "already_AddRefed"
-                if memberIsCreator(self.member):
+                if memberReturnsNewObject(self.member):
                     warning = ""
                 else:
                     warning = "// Mark this as resultNotAddRefed to return raw pointers\n"
                 result = CGWrapper(result,
                                    pre=("%s%s<" % (warning, holder)),
                                    post=">")
             else:
                 result = CGWrapper(result, post="*")
@@ -10094,20 +10125,20 @@ class FakeMember():
         self.treatUndefinedAs = self.treatNullAs = "Default"
     def isStatic(self):
         return False
     def isAttr(self):
         return False
     def isMethod(self):
         return False
     def getExtendedAttribute(self, name):
-        # Claim to be a [Creator] so we can avoid the "mark this
+        # Claim to be a [NewObject] so we can avoid the "mark this
         # resultNotAddRefed" comments CGNativeMember codegen would
         # otherwise stick in.
-        if name == "Creator":
+        if name == "NewObject":
             return True
         return None
 
 class CallbackMember(CGNativeMember):
     def __init__(self, sig, name, descriptorProvider, needThisHandling, rethrowContentException=False):
         """
         needThisHandling is True if we need to be able to accept a specified
         thisObj, False otherwise.
@@ -10253,17 +10284,17 @@ class CallbackMember(CGNativeMember):
                 'result' : result,
                 'successCode' : "continue;" if arg.variadic else "break;",
                 'jsvalRef' : "argv.handleAt(%s)" % jsvalIndex,
                 'jsvalHandle' : "argv.handleAt(%s)" % jsvalIndex,
                 # XXXbz we don't have anything better to use for 'obj',
                 # really...  It's OK to use CallbackPreserveColor because
                 # CallSetup already handled the unmark-gray bits for us.
                 'obj' : 'CallbackPreserveColor()',
-                'isCreator': False,
+                'returnsNewObject': False,
                 'exceptionCode' : self.exceptionCode
                 })
         if arg.variadic:
             conversion = string.Template(
                 "for (uint32_t idx = 0; idx < ${arg}.Length(); ++idx) {\n" +
                 CGIndenter(CGGeneric(conversion)).define() + "\n"
                 "}\n"
                 "break;").substitute({ "arg": arg.identifier.name })
--- a/dom/bindings/Makefile.in
+++ b/dom/bindings/Makefile.in
@@ -1,15 +1,12 @@
 # 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/.
 
-# Need this to find all our DOM source files.
-include $(topsrcdir)/dom/dom-config.mk
-
 webidl_base = $(topsrcdir)/dom/webidl
 # Generated by moz.build
 include webidlsrcs.mk
 
 binding_include_path := mozilla/dom
 webidl_files += $(generated_events_webidl_files)
 all_webidl_files = $(webidl_files) $(generated_webidl_files) $(preprocessed_webidl_files)
 
@@ -114,17 +111,16 @@ globalgen_headers_FILES := \
   UnionConversions.h \
   UnionTypes.h \
   $(NULL)
 globalgen_headers_DEST = $(ABS_DIST)/include/mozilla/dom
 globalgen_headers_TARGET := export
 INSTALL_TARGETS += globalgen_headers
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 ifdef GNU_CC
 CXXFLAGS += -Wno-uninitialized
 endif
 
 # If you change bindinggen_dependencies here, change it in
 # dom/bindings/test/Makefile.in too.
 bindinggen_dependencies := \
--- a/dom/bindings/moz.build
+++ b/dom/bindings/moz.build
@@ -38,8 +38,25 @@ FAIL_ON_WARNINGS = True
 LIBXUL_LIBRARY = True
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'dombindings_s'
 
 EXPORT_LIBRARY = True
 
+LOCAL_INCLUDES += [
+    '../bluetooth',
+    '../camera',
+    '../file',
+    '../src/geolocation',
+    '../workers',
+    '/content/base/src',
+    '/content/events/src',
+    '/content/html/document/src',
+    '/content/media/webaudio',
+    '/content/svg/content/src',
+    '/content/xbl/src',
+    '/layout/style',
+    '/layout/xul/tree',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -919,22 +919,22 @@ class IDLInterface(IDLObjectWithScope):
                     name = attr.value()
                     allowForbidden = False
 
                 methodIdentifier = IDLUnresolvedIdentifier(self.location, name,
                                                            allowForbidden=allowForbidden)
 
                 method = IDLMethod(self.location, methodIdentifier, retType,
                                    args, static=True)
-                # Constructors are always Creators and are always
+                # Constructors are always NewObject and are always
                 # assumed to be able to throw (since there's no way to
                 # indicate otherwise) and never have any other
                 # extended attributes.
                 method.addExtendedAttributes(
-                    [IDLExtendedAttribute(self.location, ("Creator",)),
+                    [IDLExtendedAttribute(self.location, ("NewObject",)),
                      IDLExtendedAttribute(self.location, ("Throws",))])
 
 
                 if identifier == "Constructor":
                     method.resolve(self)
                 else:
                     # We need to detect conflicts for NamedConstructors across
                     # interfaces. We first call resolve on the parentScope,
@@ -2755,17 +2755,17 @@ class IDLAttribute(IDLInterfaceMember):
               identifier == "SetterThrows" or
               identifier == "Pure" or
               identifier == "Throws" or
               identifier == "GetterThrows" or
               identifier == "ChromeOnly" or
               identifier == "SameObject" or
               identifier == "Constant" or
               identifier == "Func" or
-              identifier == "Creator"):
+              identifier == "NewObject"):
             # Known attributes that we don't need to do anything with here
             pass
         else:
             raise WebIDLError("Unknown extended attribute %s on attribute" % identifier,
                               [attr.location])
         IDLInterfaceMember.handleExtendedAttribute(self, attr)
 
     def resolve(self, parentScope):
@@ -3303,17 +3303,17 @@ class IDLMethod(IDLInterfaceMember, IDLS
             if not sig[0].isVoid():
                 raise WebIDLError("[LenientFloat] used on a non-void method",
                                   [attr.location, self.location])
             if not any(arg.type.includesRestrictedFloat() for arg in sig[1]):
                 raise WebIDLError("[LenientFloat] used on an operation with no "
                                   "restricted float type arguments",
                                   [attr.location, self.location])
         elif (identifier == "Throws" or
-              identifier == "Creator" or
+              identifier == "NewObject" or
               identifier == "ChromeOnly" or
               identifier == "Pref" or
               identifier == "Func" or
               identifier == "WebGLHandlesContextLoss"):
             # Known attributes that we don't need to do anything with here
             pass
         else:
             raise WebIDLError("Unknown extended attribute %s on method" % identifier,
--- a/dom/bindings/test/Makefile.in
+++ b/dom/bindings/test/Makefile.in
@@ -5,20 +5,17 @@
 # Do NOT export this library.  We don't actually want our test code
 # being added to libxul or anything.
 
 # pymake can't handle descending into dom/bindings several times simultaneously
 ifdef .PYMAKE
 .NOTPARALLEL:
 endif
 
-# Need this to find all our DOM source files.
-include $(topsrcdir)/dom/dom-config.mk
-
-# And need this for $(test_webidl_files) and $(preprocessed_test_webidl_files)
+# Need this for $(test_webidl_files)
 include ../webidlsrcs.mk
 
 # But the webidl actually lives in our parent dir
 test_webidl_files := $(addprefix ../,$(test_webidl_files))
 # Store the actual locations of our source preprocessed files, so we
 # can depend on them sanely.
 source_preprocessed_test_webidl_files := $(addprefix $(srcdir)/,$(preprocessed_test_webidl_files))
 preprocessed_test_webidl_files := $(addprefix ../,$(preprocessed_test_webidl_files))
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -228,27 +228,27 @@ interface TestInterface {
   attribute TestInterface nonNullSelf;
   attribute TestInterface? nullableSelf;
   // Optional arguments
   void passOptionalSelf(optional TestInterface? arg);
   void passOptionalNonNullSelf(optional TestInterface arg);
   void passOptionalSelfWithDefault(optional TestInterface? arg = null);
 
   // Non-wrapper-cache interface types
-  [Creator]
+  [NewObject]
   TestNonWrapperCacheInterface receiveNonWrapperCacheInterface();
-  [Creator]
+  [NewObject]
   TestNonWrapperCacheInterface? receiveNullableNonWrapperCacheInterface();
-  [Creator]
+  [NewObject]
   sequence<TestNonWrapperCacheInterface> receiveNonWrapperCacheInterfaceSequence();
-  [Creator]
+  [NewObject]
   sequence<TestNonWrapperCacheInterface?> receiveNullableNonWrapperCacheInterfaceSequence();
-  [Creator]
+  [NewObject]
   sequence<TestNonWrapperCacheInterface>? receiveNonWrapperCacheInterfaceNullableSequence();
-  [Creator]
+  [NewObject]
   sequence<TestNonWrapperCacheInterface?>? receiveNullableNonWrapperCacheInterfaceNullableSequence();
 
   // Non-castable interface types
   IndirectlyImplementedInterface receiveOther();
   IndirectlyImplementedInterface? receiveNullableOther();
   IndirectlyImplementedInterface receiveWeakOther();
   IndirectlyImplementedInterface? receiveWeakNullableOther();
   void passOther(IndirectlyImplementedInterface arg);
--- a/dom/bindings/test/TestExampleGen.webidl
+++ b/dom/bindings/test/TestExampleGen.webidl
@@ -124,27 +124,27 @@ interface TestExampleInterface {
   attribute TestInterface nonNullSelf;
   attribute TestInterface? nullableSelf;
   // Optional arguments
   void passOptionalSelf(optional TestInterface? arg);
   void passOptionalNonNullSelf(optional TestInterface arg);
   void passOptionalSelfWithDefault(optional TestInterface? arg = null);
 
   // Non-wrapper-cache interface types
-  [Creator]
+  [NewObject]
   TestNonWrapperCacheInterface receiveNonWrapperCacheInterface();
-  [Creator]
+  [NewObject]
   TestNonWrapperCacheInterface? receiveNullableNonWrapperCacheInterface();
-  [Creator]
+  [NewObject]
   sequence<TestNonWrapperCacheInterface> receiveNonWrapperCacheInterfaceSequence();
-  [Creator]
+  [NewObject]
   sequence<TestNonWrapperCacheInterface?> receiveNullableNonWrapperCacheInterfaceSequence();
-  [Creator]
+  [NewObject]
   sequence<TestNonWrapperCacheInterface>? receiveNonWrapperCacheInterfaceNullableSequence();
-  [Creator]
+  [NewObject]
   sequence<TestNonWrapperCacheInterface?>? receiveNullableNonWrapperCacheInterfaceNullableSequence();
 
   // Non-castable interface types
   IndirectlyImplementedInterface receiveOther();
   IndirectlyImplementedInterface? receiveNullableOther();
   IndirectlyImplementedInterface receiveWeakOther();
   IndirectlyImplementedInterface? receiveWeakNullableOther();
   void passOther(IndirectlyImplementedInterface arg);
--- a/dom/bindings/test/TestJSImplGen.webidl
+++ b/dom/bindings/test/TestJSImplGen.webidl
@@ -140,28 +140,28 @@ interface TestJSImplInterface {
   attribute TestJSImplInterface nonNullSelf;
   attribute TestJSImplInterface? nullableSelf;
   // Optional arguments
   void passOptionalSelf(optional TestJSImplInterface? arg);
   void passOptionalNonNullSelf(optional TestJSImplInterface arg);
   void passOptionalSelfWithDefault(optional TestJSImplInterface? arg = null);
 
   // Non-wrapper-cache interface types
-  [Creator]
+  [NewObject]
   TestNonWrapperCacheInterface receiveNonWrapperCacheInterface();
-  [Creator]
+  [NewObject]
   TestNonWrapperCacheInterface? receiveNullableNonWrapperCacheInterface();
 
-  [Creator]
+  [NewObject]
   sequence<TestNonWrapperCacheInterface> receiveNonWrapperCacheInterfaceSequence();
-  [Creator]
+  [NewObject]
   sequence<TestNonWrapperCacheInterface?> receiveNullableNonWrapperCacheInterfaceSequence();
-  [Creator]
+  [NewObject]
   sequence<TestNonWrapperCacheInterface>? receiveNonWrapperCacheInterfaceNullableSequence();
-  [Creator]
+  [NewObject]
   sequence<TestNonWrapperCacheInterface?>? receiveNullableNonWrapperCacheInterfaceNullableSequence();
 
   // Non-castable interface types
   IndirectlyImplementedInterface receiveOther();
   IndirectlyImplementedInterface? receiveNullableOther();
   // Callback interface ignores 'resultNotAddRefed'. See bug 843272.
   //IndirectlyImplementedInterface receiveWeakOther();
   //IndirectlyImplementedInterface? receiveWeakNullableOther();
--- a/dom/bluetooth/Makefile.in
+++ b/dom/bluetooth/Makefile.in
@@ -7,18 +7,16 @@
 #     http://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-include $(topsrcdir)/dom/dom-config.mk
-
 VPATH += $(srcdir)/ipc
 
 ifneq (,$(MOZ_B2G_BT))
 
 
 ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
 VPATH += \
   $(srcdir)/linux \
@@ -46,9 +44,8 @@ endif
 
 # Add VPATH to LOCAL_INCLUDES so we are going to include the correct backend
 # subdirectory.
 LOCAL_INCLUDES += $(VPATH:%=-I%)
 
 endif # MOZ_B2G_BT
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/bluetooth/moz.build
+++ b/dom/bluetooth/moz.build
@@ -20,17 +20,17 @@ if CONFIG['MOZ_B2G_BT']:
     LIBRARY_NAME = 'dombluetooth_s'
     XPIDL_MODULE = 'dom_bluetooth'
     XPIDL_SOURCES += [
         'nsIDOMBluetoothDevice.idl',
         'nsIDOMBluetoothDeviceEvent.idl',
         'nsIDOMBluetoothStatusChangedEvent.idl',
     ]
 
-    CPP_SOURCES += [
+    SOURCES += [
         'BluetoothA2dpManager.cpp',
         'BluetoothAdapter.cpp',
         'BluetoothDevice.cpp',
         'BluetoothHfpManager.cpp',
         'BluetoothHidManager.cpp',
         'BluetoothManager.cpp',
         'BluetoothOppManager.cpp',
         'BluetoothProfileController.cpp',
@@ -43,33 +43,33 @@ if CONFIG['MOZ_B2G_BT']:
         'BluetoothUuid.cpp',
         'ipc/BluetoothChild.cpp',
         'ipc/BluetoothParent.cpp',
         'ipc/BluetoothServiceChildProcess.cpp',
         'ObexBase.cpp'
     ]
 
     if CONFIG['MOZ_B2G_RIL']:
-        CPP_SOURCES += [
+        SOURCES += [
             'BluetoothRilListener.cpp',
         ]
 
     if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
         if CONFIG['MOZ_B2G_BT_BLUEZ']:
-            CPP_SOURCES += [
+            SOURCES += [
                'gonk/BluetoothGonkService.cpp',
                'linux/BluetoothDBusService.cpp',
             ]
         if CONFIG['MOZ_B2G_BT_BLUEDROID']:
-            CPP_SOURCES += [
+            SOURCES += [
                 'BluetoothServiceBluedroid.cpp',
             ]
     else:
         if CONFIG['MOZ_ENABLE_DBUS']:
-            CPP_SOURCES += [
+            SOURCES += [
                  'linux/BluetoothDBusService.cpp',
             ]
 
 EXPORTS.mozilla.dom.bluetooth.ipc += [
     'ipc/BluetoothMessageUtils.h',
 ]
 
 EXPORTS.mozilla.dom.bluetooth += [
@@ -79,8 +79,15 @@ EXPORTS.mozilla.dom.bluetooth += [
 IPDL_SOURCES += [
     'ipc/BluetoothTypes.ipdlh',
     'ipc/PBluetooth.ipdl',
     'ipc/PBluetoothRequest.ipdl',
 ]
 
 FAIL_ON_WARNINGS = True
 
+LOCAL_INCLUDES += [
+    '../base',
+    '../network/src',
+    '../system/gonk',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
--- a/dom/browser-element/Makefile.in
+++ b/dom/browser-element/Makefile.in
@@ -1,16 +1,12 @@
 # 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)/dom/dom-config.mk
-
-
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 INCLUDES	+= \
 		-I$(topsrcdir)/dom/base \
 		-I$(topsrcdir)/dom/ \
 		-I$(topsrcdir)/dom/ipc \
 		-I$(topsrcdir)/content/base/src \
 		$(NULL)
--- a/dom/browser-element/moz.build
+++ b/dom/browser-element/moz.build
@@ -9,17 +9,17 @@ TEST_DIRS += ['mochitest']
 XPIDL_MODULE = 'dom_browserelement'
 
 MODULE = 'dom'
 
 EXPORTS.mozilla += [
     'BrowserElementParent.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'BrowserElementParent.cpp',
 ]
 
 EXTRA_COMPONENTS += [
     'BrowserElementParent.js',
     'BrowserElementParent.manifest',
 ]
 
@@ -29,8 +29,14 @@ EXTRA_JS_MODULES += [
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'dom_browserelement_s'
 
+LOCAL_INCLUDES += [
+    '../bluetooth',
+    '/content/html/content/src',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
--- a/dom/camera/Makefile.in
+++ b/dom/camera/Makefile.in
@@ -1,7 +1,5 @@
 # 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)/dom/dom-config.mk
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/camera/moz.build
+++ b/dom/camera/moz.build
@@ -17,39 +17,44 @@ MODULE = 'dom'
 
 EXPORTS += [
     'CameraCommon.h',
     'CameraPreviewMediaStream.h',
     'DOMCameraManager.h',
     'GonkCameraControl.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'CameraControlImpl.cpp',
     'CameraPreviewMediaStream.cpp',
     'CameraRecorderProfiles.cpp',
     'DOMCameraCapabilities.cpp',
     'DOMCameraControl.cpp',
     'DOMCameraManager.cpp',
     'DOMCameraPreview.cpp',
 ]
 
 if CONFIG['MOZ_B2G_CAMERA']:
-    CPP_SOURCES += [
+    SOURCES += [
         'GonkCameraControl.cpp',
         'GonkCameraHwMgr.cpp',
         'GonkCameraManager.cpp',
         'GonkCameraSource.cpp',
         'GonkRecorder.cpp',
         'GonkRecorderProfiles.cpp',
     ]
 else:
-    CPP_SOURCES += [
+    SOURCES += [
         'FallbackCameraControl.cpp',
         'FallbackCameraManager.cpp',
     ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'domcamera_s'
 
+LOCAL_INCLUDES += [
+    '../base',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
--- a/dom/cellbroadcast/src/moz.build
+++ b/dom/cellbroadcast/src/moz.build
@@ -5,17 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPIDL_MODULE = 'dom_cellbroadcast'
 
 EXPORTS.mozilla.dom += [
     'CellBroadcast.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'CellBroadcast.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'dom_cellbroadcast_s'
--- a/dom/devicestorage/Makefile.in
+++ b/dom/devicestorage/Makefile.in
@@ -1,15 +1,13 @@
 # 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)/dom/dom-config.mk
 
 LOCAL_INCLUDES = \
 		-I$(topsrcdir)/dom/base \
 		-I$(topsrcdir)/dom/ipc \
 		-I$(topsrcdir)/content/base/src \
 		-I$(topsrcdir)/content/events/src \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/devicestorage/ipc/Makefile.in
+++ b/dom/devicestorage/ipc/Makefile.in
@@ -1,8 +1,7 @@
 # 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/.
 
 MOCHITEST_FILES := ../test/devicestorage_common.js
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/devicestorage/ipc/moz.build
+++ b/dom/devicestorage/ipc/moz.build
@@ -1,8 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MOCHITEST_MANIFESTS += ['mochitest.ini']
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/devicestorage/moz.build
+++ b/dom/devicestorage/moz.build
@@ -15,24 +15,26 @@ EXPORTS += [
     'nsDeviceStorage.h',
 ]
 
 EXPORTS.mozilla.dom.devicestorage += [
     'DeviceStorageRequestChild.h',
     'DeviceStorageRequestParent.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'DeviceStorageRequestChild.cpp',
     'DeviceStorageRequestParent.cpp',
     'nsDeviceStorage.cpp',
 ]
 
 IPDL_SOURCES += [
     'PDeviceStorageRequest.ipdl',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'domdevicestorage_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
deleted file mode 100644
--- a/dom/dom-config.mk
+++ /dev/null
@@ -1,61 +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/.
-
-DOM_SRCDIRS = \
-  dom/base \
-  dom/battery \
-  dom/encoding \
-  dom/file \
-  dom/power \
-  dom/push \
-  dom/quota \
-  dom/media \
-  dom/network/src \
-  dom/phonenumberutils \
-  dom/alarm \
-  dom/src/events \
-  dom/src/storage \
-  dom/src/offline \
-  dom/src/geolocation \
-  dom/src/notification \
-  dom/workers \
-  dom/time \
-  content/xbl/src \
-  content/xul/document/src \
-  content/events/src \
-  content/base/src \
-  content/html/content/src \
-  content/html/document/src \
-  content/media/mediasource \
-  content/media/webaudio \
-  content/svg/content/src \
-  layout/generic \
-  layout/style \
-  layout/xul/base/src \
-  layout/xul/tree \
-  dom/camera \
-  $(NULL)
-
-ifdef MOZ_B2G_RIL
-DOM_SRCDIRS += \
-  dom/system/gonk \
-  dom/wifi \
-  $(NULL)
-endif
-
-ifdef MOZ_B2G_FM
-DOM_SRCDIRS += \
-  dom/fmradio \
-  $(NULL)
-endif
-
-ifdef MOZ_B2G_BT
-DOM_SRCDIRS += dom/bluetooth
-endif
-
-ifdef MOZ_WEBSPEECH
-DOM_SRCDIRS += content/media/webspeech
-endif
-
-LOCAL_INCLUDES += $(DOM_SRCDIRS:%=-I$(topsrcdir)/%)
--- a/dom/encoding/Makefile.in
+++ b/dom/encoding/Makefile.in
@@ -1,17 +1,16 @@
 # 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/.
 
 LOCAL_INCLUDES = \
 	-I$(topsrcdir)/intl/locale/src \
 	$(NULL)
 
-include $(topsrcdir)/dom/dom-config.mk
 include $(topsrcdir)/config/rules.mk
 
 EncodingUtils.$(OBJ_SUFFIX): labelsencodings.properties.h
 
 PROPS2ARRAYS = $(topsrcdir)/intl/locale/src/props2arrays.py
 labelsencodings.properties.h: $(PROPS2ARRAYS) labelsencodings.properties
 	$(PYTHON) $^ $@
 
--- a/dom/encoding/moz.build
+++ b/dom/encoding/moz.build
@@ -9,17 +9,17 @@ TEST_DIRS += ['test']
 MODULE = 'dom'
 
 EXPORTS.mozilla.dom += [
     'EncodingUtils.h',
     'TextDecoder.h',
     'TextEncoder.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'EncodingUtils.cpp',
     'TextDecoder.cpp',
     'TextEncoder.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
--- a/dom/file/moz.build
+++ b/dom/file/moz.build
@@ -30,17 +30,17 @@ EXPORTS.mozilla.dom.file += [
     'File.h',
     'FileCommon.h',
     'FileHandle.h',
     'FileHelper.h',
     'FileService.h',
     'LockedFile.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'ArchiveEvent.cpp',
     'ArchiveReader.cpp',
     'ArchiveRequest.cpp',
     'ArchiveZipEvent.cpp',
     'ArchiveZipFile.cpp',
     'AsyncHelper.cpp',
     'DOMFileHandle.cpp',
     'DOMFileRequest.cpp',
--- a/dom/fmradio/Makefile.in
+++ b/dom/fmradio/Makefile.in
@@ -1,9 +1,6 @@
 # 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)/dom/dom-config.mk
+include $(topsrcdir)/config/rules.mk
 
-include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
-
--- a/dom/fmradio/ipc/Makefile.in
+++ b/dom/fmradio/ipc/Makefile.in
@@ -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/.
 
 LOCAL_INCLUDES += \
   -I$(topsrcdir)/dom/fmradio \
   $(NULL)
 
-include $(topsrcdir)/dom/dom-config.mk
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
--- a/dom/fmradio/ipc/moz.build
+++ b/dom/fmradio/ipc/moz.build
@@ -6,20 +6,25 @@
 
 EXPORTS.mozilla.dom += [
     'FMRadioChild.h',
     'FMRadioParent.h',
     'FMRadioRequestChild.h',
     'FMRadioRequestParent.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'FMRadioChild.cpp',
     'FMRadioParent.cpp',
     'FMRadioRequestChild.cpp',
     'FMRadioRequestParent.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 LIBRARY_NAME   = 'domfmradio_s'
 
+LOCAL_INCLUDES += [
+    '/dom/base',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
--- a/dom/fmradio/moz.build
+++ b/dom/fmradio/moz.build
@@ -12,24 +12,29 @@ if CONFIG['MOZ_B2G_FM']:
     MODULE = 'dom'
 
     EXPORTS.mozilla.dom += [
         'FMRadio.h',
         'FMRadioCommon.h',
         'FMRadioService.h',
     ]
 
-    CPP_SOURCES += [
+    SOURCES += [
         'FMRadio.cpp',
         'FMRadioService.cpp',
     ]
 
     LIBXUL_LIBRARY = True
 
     LIBRARY_NAME = 'domfmradio_s'
 
 IPDL_SOURCES += [
     'ipc/PFMRadio.ipdl',
     'ipc/PFMRadioRequest.ipdl',
 ]
 
 FAIL_ON_WARNINGS = True
 
+LOCAL_INCLUDES += [
+    '../base',
+    '../system/gonk',
+]
+include('/ipc/chromium/chromium-config.mozbuild')
--- a/dom/gamepad/Makefile.in
+++ b/dom/gamepad/Makefile.in
@@ -2,9 +2,8 @@
 # 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/.
 
 LOCAL_INCLUDES += \
   -I$(topsrcdir)/dom/base \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/gamepad/moz.build
+++ b/dom/gamepad/moz.build
@@ -5,20 +5,22 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS.mozilla.dom += [
     'Gamepad.h',
     'GamepadButton.h',
     'GamepadService.h',
     ]
 
-CPP_SOURCES = [
+SOURCES = [
     'Gamepad.cpp',
     'GamepadButton.cpp',
     'GamepadService.cpp',
     ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'domgamepad_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/icc/src/Makefile.in
+++ b/dom/icc/src/Makefile.in
@@ -1,14 +1,9 @@
 # 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/.
 
-VPATH            = $(srcdir)
-
-include $(topsrcdir)/dom/dom-config.mk
-
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/content/events/src \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/icc/src/moz.build
+++ b/dom/icc/src/moz.build
@@ -4,19 +4,21 @@
 # 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/.
 
 EXPORTS.mozilla.dom += [
     'IccManager.h',
     'StkCommandEvent.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'IccManager.cpp',
     'StkCommandEvent.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'dom_icc_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/imptests/failures/html/html/webappapis/atob/test_base64.html.json
+++ b/dom/imptests/failures/html/html/webappapis/atob/test_base64.html.json
@@ -1,14 +1,4 @@
 {
   "btoa(null) == \"bnVsbA==\"": true,
-  "atob(\" abcd\") == \"i\u00b7\\x1d\"": true,
-  "atob(\"abcd \") == \"i\u00b7\\x1d\"": true,
-  "atob(\"ab\\tcd\") == \"i\u00b7\\x1d\"": true,
-  "atob(\"ab\\ncd\") == \"i\u00b7\\x1d\"": true,
-  "atob(\"ab\\fcd\") == \"i\u00b7\\x1d\"": true,
-  "atob(\"ab\\rcd\") == \"i\u00b7\\x1d\"": true,
-  "atob(\"ab cd\") == \"i\u00b7\\x1d\"": true,
-  "atob(\"ab\\t\\n\\f\\r cd\") == \"i\u00b7\\x1d\"": true,
-  "atob(\" \\t\\n\\f\\r ab\\t\\n\\f\\r cd\\t\\n\\f\\r \") == \"i\u00b7\\x1d\"": true,
-  "atob(\"ab\\t\\n\\f\\r =\\t\\n\\f\\r =\\t\\n\\f\\r \") == \"i\"": true,
   "atob(null) == \"\u009e\u00e9e\"": true
 }
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -1335,17 +1335,17 @@ IDBObjectStore::DeserializeValue(JSConte
   JSAutoRequest ar(aCx);
 
   JSStructuredCloneCallbacks callbacks = {
     IDBObjectStore::StructuredCloneReadCallback<MainThreadDeserializationTraits>,
     nullptr,
     nullptr
   };
 
-  return buffer.read(aCx, aValue.address(), &callbacks, &aCloneReadInfo);
+  return buffer.read(aCx, aValue, &callbacks, &aCloneReadInfo);
 }
 
 // static
 bool
 IDBObjectStore::SerializeValue(JSContext* aCx,
                                StructuredCloneWriteInfo& aCloneWriteInfo,
                                JS::Handle<JS::Value> aValue)
 {
@@ -4537,17 +4537,17 @@ CreateIndexHelper::InsertDataFromObjectS
 
     JSStructuredCloneCallbacks callbacks = {
       IDBObjectStore::StructuredCloneReadCallback<CreateIndexDeserializationTraits>,
       nullptr,
       nullptr
     };
 
     JS::Rooted<JS::Value> clone(cx);
-    if (!buffer.read(cx, clone.address(), &callbacks, &cloneReadInfo)) {
+    if (!buffer.read(cx, &clone, &callbacks, &cloneReadInfo)) {
       NS_WARNING("Failed to deserialize structured clone data!");
       return NS_ERROR_DOM_DATA_CLONE_ERR;
     }
 
     nsTArray<IndexUpdateInfo> updateInfo;
     rv = IDBObjectStore::AppendIndexUpdateInfo(mIndex->Id(),
                                                mIndex->GetKeyPath(),
                                                mIndex->IsUnique(),
--- a/dom/indexedDB/Makefile.in
+++ b/dom/indexedDB/Makefile.in
@@ -10,9 +10,8 @@ LOCAL_INCLUDES = \
   -I$(topsrcdir)/dom/base \
   -I$(topsrcdir)/dom/src/storage \
   -I$(topsrcdir)/dom/quota \
   -I$(topsrcdir)/xpcom/build \
   $(NULL)
 
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/indexedDB/ipc/Makefile.in
+++ b/dom/indexedDB/ipc/Makefile.in
@@ -3,17 +3,16 @@
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 LOCAL_INCLUDES += \
   -I$(topsrcdir)/dom/indexedDB \
   -I$(topsrcdir)/content/events/src \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 xpcshell_tests = unit
 
 # Copy all the normal xpcshell tests from the regular unit directory.
 copy-xpcshell-tests:
 	$(call install_cmd,$(wildcard $(topsrcdir)/dom/indexedDB/test/unit/test_*.js) \
 		$(testxpcobjdir)/$(relativesrcdir)/$(xpcshell_tests))
 
--- a/dom/indexedDB/ipc/moz.build
+++ b/dom/indexedDB/ipc/moz.build
@@ -8,17 +8,17 @@ MODULE = 'dom'
 
 EXPORTS.mozilla.dom.indexedDB += [
     'SerializationHelpers.h',
 ]
 
 # Need to enable these tests sometime soon.
 #XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
 
-CPP_SOURCES += [
+SOURCES += [
     'IndexedDBChild.cpp',
     'IndexedDBParent.cpp',
 ]
 
 IPDL_SOURCES += [
     'IndexedDBParams.ipdlh',
     'PIndexedDB.ipdl',
     'PIndexedDBCursor.ipdl',
@@ -33,8 +33,10 @@ IPDL_SOURCES += [
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'dom_indexeddb_ipc_s'
 
 MOCHITEST_MANIFESTS += ['mochitest.ini']
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/indexedDB/moz.build
+++ b/dom/indexedDB/moz.build
@@ -32,17 +32,17 @@ EXPORTS.mozilla.dom.indexedDB += [
     'IDBTransaction.h',
     'IDBWrapperCache.h',
     'IndexedDatabase.h',
     'IndexedDatabaseManager.h',
     'Key.h',
     'KeyPath.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'AsyncConnectionHelper.cpp',
     'CheckPermissionsHelper.cpp',
     'Client.cpp',
     'DatabaseInfo.cpp',
     'FileInfo.cpp',
     'FileManager.cpp',
     'IDBCursor.cpp',
     'IDBDatabase.cpp',
@@ -63,8 +63,10 @@ CPP_SOURCES += [
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'dom_indexeddb_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/ipc/Makefile.in
+++ b/dom/ipc/Makefile.in
@@ -1,14 +1,13 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 LOCAL_INCLUDES += \
 	-I$(srcdir)/../../content/base/src \
 	-I$(srcdir)/../../content/events/src \
 	-I$(srcdir)/../../docshell/base \
 	-I$(topsrcdir)/chrome/src \
 	-I$(topsrcdir)/uriloader/exthandler \
 	-I$(srcdir)/../../netwerk/base/src \
--- a/dom/ipc/StructuredCloneUtils.cpp
+++ b/dom/ipc/StructuredCloneUtils.cpp
@@ -157,26 +157,27 @@ JSStructuredCloneCallbacks gCallbacks = 
 
 } // anonymous namespace
 
 namespace mozilla {
 namespace dom {
 
 bool
 ReadStructuredClone(JSContext* aCx, uint64_t* aData, size_t aDataLength,
-                    const StructuredCloneClosure& aClosure, JS::Value* aClone)
+                    const StructuredCloneClosure& aClosure,
+                    JS::MutableHandle<JS::Value> aClone)
 {
   void* closure = &const_cast<StructuredCloneClosure&>(aClosure);
   return !!JS_ReadStructuredClone(aCx, aData, aDataLength,
                                   JS_STRUCTURED_CLONE_VERSION, aClone,
                                   &gCallbacks, closure);
 }
 
 bool
-WriteStructuredClone(JSContext* aCx, const JS::Value& aSource,
+WriteStructuredClone(JSContext* aCx, JS::Handle<JS::Value> aSource,
                      JSAutoStructuredCloneBuffer& aBuffer,
                      StructuredCloneClosure& aClosure)
 {
   return aBuffer.write(aCx, aSource, &gCallbacks, &aClosure);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/ipc/StructuredCloneUtils.h
+++ b/dom/ipc/StructuredCloneUtils.h
@@ -31,27 +31,28 @@ StructuredCloneData
   StructuredCloneData() : mData(nullptr), mDataLength(0) {}
   uint64_t* mData;
   size_t mDataLength;
   StructuredCloneClosure mClosure;
 };
 
 bool
 ReadStructuredClone(JSContext* aCx, uint64_t* aData, size_t aDataLength,
-                    const StructuredCloneClosure& aClosure, JS::Value* aClone);
+                    const StructuredCloneClosure& aClosure,
+                    JS::MutableHandle<JS::Value> aClone);
 
 inline bool
 ReadStructuredClone(JSContext* aCx, const StructuredCloneData& aData,
-                    JS::Value* aClone)
+                    JS::MutableHandle<JS::Value> aClone)
 {
   return ReadStructuredClone(aCx, aData.mData, aData.mDataLength,
                              aData.mClosure, aClone);
 }
 
 bool
-WriteStructuredClone(JSContext* aCx, const JS::Value& aSource,
+WriteStructuredClone(JSContext* aCx, JS::Handle<JS::Value> aSource,
                      JSAutoStructuredCloneBuffer& aBuffer,
                      StructuredCloneClosure& aClosure);
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_StructuredCloneUtils_h
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -897,17 +897,17 @@ TabChild::GetDimensions(uint32_t aFlags,
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TabChild::SetFocus()
 {
-  NS_NOTREACHED("TabChild::SetFocus not supported in TabChild");
+  NS_WARNING("TabChild::SetFocus not supported in TabChild");
 
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 TabChild::GetVisibility(bool* aVisibility)
 {
   *aVisibility = true;
@@ -943,17 +943,17 @@ TabChild::GetSiteWindow(void** aSiteWind
   NS_NOTREACHED("TabChild::GetSiteWindow not supported in TabChild");
 
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 TabChild::Blur()
 {
-  NS_NOTREACHED("TabChild::Blur not supported in TabChild");
+  NS_WARNING("TabChild::Blur not supported in TabChild");
 
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 TabChild::FocusNextElement()
 {
   SendMoveFocus(true);
--- a/dom/ipc/moz.build
+++ b/dom/ipc/moz.build
@@ -34,17 +34,17 @@ EXPORTS.mozilla.dom += [
 ]
 
 EXPORTS.mozilla += [
     'AppProcessChecker.h',
     'PreallocatedProcessManager.h',
     'ProcessPriorityManager.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'AppProcessChecker.cpp',
     'Blob.cpp',
     'ContentChild.cpp',
     'ContentParent.cpp',
     'ContentProcess.cpp',
     'CrashReporterChild.cpp',
     'CrashReporterParent.cpp',
     'PermissionMessageUtils.cpp',
@@ -74,8 +74,10 @@ IPDL_SOURCES += [
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'domipc_s'
 
 EXPORT_LIBRARY = True
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/locales/en-US/chrome/accessibility/AccessFu.properties
+++ b/dom/locales/en-US/chrome/accessibility/AccessFu.properties
@@ -67,16 +67,22 @@ note           =       note
 figure         =       figure
 definitionlist =       definition list
 term           =       term
 definition     =       definition
 
 # More sophisticated roles which are not actual numeric roles
 textarea       =       text area
 
+# Text input types
+textInputType_email  =       e-mail
+textInputType_search =       search
+textInputType_tel    =       telephone
+textInputType_url    =       URL
+
 # More sophisticated object descriptions
 headingLevel   =       heading level %S
 
 # more sophisticated list announcement
 listStart      =       First item
 listEnd        =       Last item
 # LOCALIZATION NOTE (listItemsCount): Semi-colon list of plural forms.
 # See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
--- a/dom/media/Makefile.in
+++ b/dom/media/Makefile.in
@@ -1,16 +1,12 @@
 # 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)/dom/dom-config.mk
-
-
 ifdef MOZ_WEBRTC
 LOCAL_INCLUDES += \
   -I$(topsrcdir)/media/webrtc/trunk \
   -I$(topsrcdir)/media/webrtc/signaling/src/common \
   $(NULL)
 endif
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/media/bridge/moz.build
+++ b/dom/media/bridge/moz.build
@@ -5,17 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPIDL_SOURCES += [
     'IPeerConnection.idl',
 ]
 
 MODULE = 'peerconnection'
 
-CPP_SOURCES += [
+SOURCES += [
     'MediaModule.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '/ipc/chromium/src',
     '/media/mtransport',
     '/media/webrtc/signaling/include',
     '/media/webrtc/signaling/src/common/time_profiling',
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -22,32 +22,38 @@ MODULE = 'dom'
 EXPORTS.mozilla.dom += [
     'GetUserMediaRequest.h',
 ]
 
 EXPORTS.mozilla += [
     'MediaManager.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'GetUserMediaRequest.cpp',
     'MediaManager.cpp',
 ]
 
 EXTRA_COMPONENTS += [
     'PeerConnection.js',
     'PeerConnection.manifest',
 ]
 
 if CONFIG['MOZ_B2G']:
     EXPORTS.mozilla += [
         'MediaPermissionGonk.h',
     ]
-    CPP_SOURCES += [
+    SOURCES += [
         'MediaPermissionGonk.cpp',
     ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'dom_media_s'
 
+LOCAL_INCLUDES += [
+    '../base',
+    '../camera',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
--- a/dom/mobilemessage/src/Makefile.in
+++ b/dom/mobilemessage/src/Makefile.in
@@ -1,7 +1,5 @@
 # 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)/dom/dom-config.mk
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/mobilemessage/src/moz.build
+++ b/dom/mobilemessage/src/moz.build
@@ -9,17 +9,17 @@ EXPORTS.mozilla.dom.mobilemessage += [
     'ipc/SmsChild.h',
     'ipc/SmsParent.h',
     'MobileMessageService.h', # Required by nsLayoutModule.cpp
     'SmsServicesFactory.h',   # Required by nsLayoutModule.cpp
     'Types.h',                # Required by IPDL SmsTypes.h
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
-    CPP_SOURCES += [
+    SOURCES += [
         'android/MmsService.cpp',
         'android/MobileMessageDatabaseService.cpp',
         'android/SmsService.cpp',
     ]
 elif CONFIG['MOZ_B2G_RIL']:
     EXTRA_JS_MODULES = [
         'gonk/mms_consts.js',
         'gonk/MmsPduHelper.jsm',
@@ -27,35 +27,35 @@ elif CONFIG['MOZ_B2G_RIL']:
         'gonk/WspPduHelper.jsm',
     ]
     EXTRA_COMPONENTS += [
         'gonk/MmsService.js',
         'gonk/MmsService.manifest',
         'gonk/MobileMessageDatabaseService.js',
         'gonk/MobileMessageDatabaseService.manifest',
     ]
-    CPP_SOURCES += [
+    SOURCES += [
         'gonk/SmsService.cpp',
     ]
 else:
-    CPP_SOURCES += [
+    SOURCES += [
         'fallback/MmsService.cpp',
         'fallback/MobileMessageDatabaseService.cpp',
         'fallback/SmsService.cpp',
     ]
 
 EXPORTS.mozilla.dom += [
     'MmsMessage.h',
     'MobileMessageManager.h',
     'SmsFilter.h',
     'SmsMessage.h',
     'SmsSegmentInfo.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'Constants.cpp',
     'ipc/SmsChild.cpp',
     'ipc/SmsIPCService.cpp',
     'ipc/SmsParent.cpp',
     'MmsMessage.cpp',
     'MobileMessageCallback.cpp',
     'MobileMessageCursorCallback.cpp',
     'MobileMessageManager.cpp',
@@ -77,8 +77,13 @@ IPDL_SOURCES += [
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'dom_mobilemessage_s'
 
+LOCAL_INCLUDES += [
+    '/dom/base',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
--- a/dom/network/src/Makefile.in
+++ b/dom/network/src/Makefile.in
@@ -1,14 +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/.
 
-VPATH            = $(srcdir)
 
-include $(topsrcdir)/dom/dom-config.mk
 
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/content/events/src \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/network/src/TCPSocket.js
+++ b/dom/network/src/TCPSocket.js
@@ -474,19 +474,16 @@ TCPSocket.prototype = {
         // Clean up our socket
         this.close();
       }
     }
   },
 
   // nsIDOMTCPSocket
   open: function ts_open(host, port, options) {
-    if (!this.initWindowless())
-      return null;
-
     this._inChild = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
                        .processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
     LOG("content process: " + (this._inChild ? "true" : "false"));
 
     // in the testing case, init won't be called and
     // hasPrivileges will be null. We want to proceed to test.
     if (this._hasPrivileges !== true && this._hasPrivileges !== null) {
       throw new Error("TCPSocket does not have permission in this context.\n");
@@ -561,19 +558,16 @@ TCPSocket.prototype = {
     if (this._multiplexStream.count == 0) {
       this._activateTLS();
     } else {
       this._waitingForStartTLS = true;
     }
   },
 
   listen: function ts_listen(localPort, options, backlog) {
-    if (!this.initWindowless())
-      return null;
-
     // in the testing case, init won't be called and
     // hasPrivileges will be null. We want to proceed to test.
     if (this._hasPrivileges !== true && this._hasPrivileges !== null) {
       throw new Error("TCPSocket does not have permission in this context.\n");
     }
 
     let that = new TCPServerSocket(this.useWin || this);
 
--- a/dom/network/src/moz.build
+++ b/dom/network/src/moz.build
@@ -8,26 +8,26 @@ EXPORTS.mozilla.dom.network += [
     'Constants.h',
     'TCPServerSocketChild.h',
     'TCPServerSocketParent.h',
     'TCPSocketChild.h',
     'TCPSocketParent.h',
     'Types.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'Connection.cpp',
     'TCPServerSocketChild.cpp',
     'TCPServerSocketParent.cpp',
     'TCPSocketChild.cpp',
     'TCPSocketParent.cpp',
 ]
 
 if CONFIG['MOZ_B2G_RIL']:
-    CPP_SOURCES += [
+    SOURCES += [
         'MobileConnection.cpp',
     ]
     EXTRA_JS_MODULES = [
         'NetworkStatsDB.jsm',
         'NetworkStatsService.jsm',
     ]
 
 EXTRA_COMPONENTS += [
@@ -54,8 +54,10 @@ IPDL_SOURCES += [
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'dom_network_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/network/tests/unit/test_tcpserversocket.js
+++ b/dom/network/tests/unit/test_tcpserversocket.js
@@ -197,17 +197,17 @@ function connectSock() {
 function openSockInClosingServer() {
   var success = makeSuccessCase('clientnotopen');
   var options = { binaryType: 'arraybuffer' };
   
   sock = TCPSocket.open(
     '127.0.0.1', PORT, options);
 
   sock.onopen = makeFailureCase('open');
-  sock.onerror = success();
+  sock.onerror = success;
 }
 
 /**
  * Test that sending a small amount of data works, and that buffering
  * does not take place for this small amount of data.
  */
 
 function sendDataToServer() {
@@ -295,18 +295,9 @@ add_test(sendDataToServer);
 
 add_test(cleanup);
 
 function run_test() {
   if (!gInChild)
     Services.prefs.setBoolPref('dom.mozTCPSocket.enabled', true);
 
   run_next_test();
-
-  do_timeout(10000, function() {
-    if (server) {
-      server.close();
-    }
-
-    do_throw(
-      "The test should never take this long unless the system is hosed.");
-  });
 }
--- a/dom/plugins/base/Makefile.in
+++ b/dom/plugins/base/Makefile.in
@@ -17,13 +17,11 @@ LOCAL_INCLUDES += \
   -I$(topsrcdir)/widget/xpwidgets \
   -I$(topsrcdir)/xpcom/base/ \
   -I$(topsrcdir)/gfx/skia/include/core \
   -I$(topsrcdir)/gfx/skia/include/config \
   $(MOZ_CAIRO_CFLAGS) \
   $(MOZ_PIXMAN_CFLAGS) \
   $(NULL)
 
-include $(topsrcdir)/dom/dom-config.mk
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 CXXFLAGS         += $(TK_CFLAGS)
--- a/dom/plugins/base/android/Makefile.in
+++ b/dom/plugins/base/android/Makefile.in
@@ -11,9 +11,8 @@ LOCAL_INCLUDES += \
   -I$(topsrcdir)/gfx/gl \
   $(MOZ_CAIRO_CFLAGS) \
   $(MOZ_PIXMAN_CFLAGS) \
   $(NULL)
 
 DEFINES += -DMOZ_APP_NAME='"$(MOZ_APP_NAME)"'
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/plugins/base/android/moz.build
+++ b/dom/plugins/base/android/moz.build
@@ -6,17 +6,17 @@
 
 MODULE = 'plugin'
 
 EXPORTS += [
     'android_npapi.h',
     'ANPKeyCodes.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'ANPAudio.cpp',
     'ANPBitmap.cpp',
     'ANPEvent.cpp',
     'ANPLog.cpp',
     'ANPMatrix.cpp',
     'ANPNativeWindow.cpp',
     'ANPOpenGL.cpp',
     'ANPSurface.cpp',
@@ -28,8 +28,10 @@ CPP_SOURCES += [
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'gkpluginandroid_s'
 
 EXPORT_LIBRARY = True
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/plugins/base/moz.build
+++ b/dom/plugins/base/moz.build
@@ -37,60 +37,60 @@ EXPORTS += [
     'nsPluginsDir.h',
     'nsPluginTags.h',
 ]
 
 EXPORTS.mozilla += [
     'PluginPRLibrary.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'nsJSNPRuntime.cpp',
     'nsNPAPIPlugin.cpp',
     'nsNPAPIPluginInstance.cpp',
     'nsNPAPIPluginStreamListener.cpp',
     'nsPluginHost.cpp',
     'nsPluginInstanceOwner.cpp',
     'nsPluginModule.cpp',
     'nsPluginPlayPreviewInfo.cpp',
     'nsPluginStreamListenerPeer.cpp',
     'nsPluginTags.cpp',
     'PluginPRLibrary.cpp',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
-    CPP_SOURCES += [
+    SOURCES += [
         'nsPluginDirServiceProvider.cpp',
         'nsPluginNativeWindowWin.cpp',
         'nsPluginsDirWin.cpp',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'os2':
-    CPP_SOURCES += [
+    SOURCES += [
         'nsPluginNativeWindowOS2.cpp',
         'nsPluginsDirOS2.cpp',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
-    CPP_SOURCES += [
+    SOURCES += [
         'nsPluginNativeWindow.cpp',
         'nsPluginsDirDarwin.cpp',
     ]
 else:
-    CPP_SOURCES += [
+    SOURCES += [
         'nsPluginsDirUnix.cpp',
     ]
     if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk2':
-        CPP_SOURCES += [
+        SOURCES += [
             'nsPluginNativeWindowGtk2.cpp',
         ]
     elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
-        CPP_SOURCES += [
+        SOURCES += [
             'nsPluginNativeWindowQt.cpp',
         ]
     else:
-        CPP_SOURCES += [
+        SOURCES += [
             'nsPluginNativeWindow.cpp',
         ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android':
     # android_npapi.h extends the NPNVariable and NPPVariable enums
     # using #defines, which results in Wswitch warnings in gcc-4.6.
     # Therefore, enable FAIL_ON_WARNINGS only on non-Android platforms.
     FAIL_ON_WARNINGS = True
@@ -98,8 +98,16 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'andr
 LIBXUL_LIBRARY = True
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'gkplugin'
 
 EXPORT_LIBRARY = True
 
+LOCAL_INCLUDES += [
+    '/content/base/src',
+    '/dom/base',
+    '/layout/generic',
+    '/layout/xul/base/src',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
--- a/dom/plugins/ipc/Makefile.in
+++ b/dom/plugins/ipc/Makefile.in
@@ -16,15 +16,14 @@ LOCAL_INCLUDES = \
 ifeq (WINNT,$(OS_ARCH))
 LOCAL_INCLUDES += \
   -I$(srcdir)/hangui \
   -I$(topsrcdir)/widget/shared \
   $(NULL)
 endif
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 CXXFLAGS += $(TK_CFLAGS)
 
 DEFINES += -DFORCE_PR_LOG
 
 CXXFLAGS += $(MOZ_CAIRO_CFLAGS)
--- a/dom/plugins/ipc/hangui/Makefile.in
+++ b/dom/plugins/ipc/hangui/Makefile.in
@@ -12,13 +12,12 @@ DEFINES += \
 
 STL_FLAGS = \
   -D_HAS_EXCEPTIONS=0 \
   $(NULL)
 
 MOZ_GLUE_LDFLAGS =
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 ifdef GNU_CC
 WIN32_EXE_LDFLAGS = -municode
 endif
--- a/dom/plugins/ipc/hangui/moz.build
+++ b/dom/plugins/ipc/hangui/moz.build
@@ -3,12 +3,14 @@
 # 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/.
 
 FAIL_ON_WARNINGS = True
 
 PROGRAM = 'plugin-hang-ui'
 
-CPP_SOURCES += [
+SOURCES += [
     'MiniShmChild.cpp',
     'PluginHangUIChild.cpp',
 ]
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/plugins/ipc/interpose/moz.build
+++ b/dom/plugins/ipc/interpose/moz.build
@@ -1,13 +1,13 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 LIBRARY_NAME = 'plugin_child_interpose'
 
-CMMSRCS += [ "%s.mm" % (LIBRARY_NAME) ]
+SOURCES += [ "%s.mm" % (LIBRARY_NAME) ]
 
-CMMSRCS += [
+SOURCES += [
     'plugin_child_quirks.mm',
 ]
--- a/dom/plugins/ipc/moz.build
+++ b/dom/plugins/ipc/moz.build
@@ -43,35 +43,35 @@ EXPORTS.mozilla.plugins += [
     'StreamNotifyChild.h',
     'StreamNotifyParent.h',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     EXPORTS.mozilla.plugins += [
         'PluginSurfaceParent.h',
     ]
-    CPP_SOURCES += [
+    SOURCES += [
         'COMMessageFilter.cpp',
         'MiniShmParent.cpp',
         'PluginHangUIParent.cpp',
         'PluginSurfaceParent.cpp',
     ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     EXPORTS.mozilla.plugins += [
         'PluginInterposeOSX.h',
     ]
 
 if CONFIG['MOZ_ENABLE_QT']:
-    CPP_SOURCES += [
+    SOURCES += [
         'moc_NestedLoopTimer.cpp',
         'NestedLoopTimer.cpp',
     ]
 
-CPP_SOURCES += [
+SOURCES += [
     'BrowserStreamChild.cpp',
     'BrowserStreamParent.cpp',
     'ChildAsyncCall.cpp',
     'ChildTimer.cpp',
     'PluginBackgroundDestroyer.cpp',
     'PluginIdentifierChild.cpp',
     'PluginIdentifierParent.cpp',
     'PluginInstanceChild.cpp',
@@ -83,17 +83,17 @@ CPP_SOURCES += [
     'PluginProcessParent.cpp',
     'PluginScriptableObjectChild.cpp',
     'PluginScriptableObjectParent.cpp',
     'PluginStreamChild.cpp',
     'PluginStreamParent.cpp',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
-    CMMSRCS += [
+    SOURCES += [
         'PluginInterposeOSX.mm',
         'PluginUtilsOSX.mm',
     ]
 
 IPDL_SOURCES += [
     'PBrowserStream.ipdl',
     'PPluginBackgroundDestroyer.ipdl',
     'PPluginIdentifier.ipdl',
@@ -108,8 +108,10 @@ IPDL_SOURCES += [
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'domplugins_s'
 
 EXPORT_LIBRARY = True
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/plugins/test/testplugin/nptest_gtk2.cpp
+++ b/dom/plugins/test/testplugin/nptest_gtk2.cpp
@@ -40,16 +40,17 @@
 #ifdef MOZ_X11
 #include <gdk/gdkx.h>
 #include <X11/extensions/shape.h>
 #endif
 #include <glib.h>
 #include <gtk/gtk.h>
 #include <unistd.h>
 
+#include "mozilla/NullPtr.h"
 #include "mozilla/IntentionalCrash.h"
 
  using namespace std;
 
 struct _PlatformData {
 #ifdef MOZ_X11
   Display* display;
   Visual* visual;
--- a/dom/plugins/test/testplugin/nptest_utils.cpp
+++ b/dom/plugins/test/testplugin/nptest_utils.cpp
@@ -28,16 +28,17 @@
  * 
  * ***** END LICENSE BLOCK ***** */
 
 #include "nptest_utils.h"
 
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
+#include "mozilla/NullPtr.h"
 
 NPUTF8*
 createCStringFromNPVariant(const NPVariant* variant)
 {
   size_t length = NPVARIANT_TO_STRING(*variant).UTF8Length;
   NPUTF8* result = (NPUTF8*)malloc(length + 1);
   memcpy(result, NPVARIANT_TO_STRING(*variant).UTF8Characters, length);
   result[length] = '\0';
--- a/dom/plugins/test/testplugin/testplugin.mozbuild
+++ b/dom/plugins/test/testplugin/testplugin.mozbuild
@@ -1,42 +1,42 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 NO_DIST_INSTALL = True
 
-CPP_SOURCES += [ '%s/%s' % (relative_path, p) for p in [
+SOURCES += [ '%s/%s' % (relative_path, p) for p in [
     'nptest.cpp',
     'nptest_utils.cpp',
 ]]
 
-CPP_SOURCES += [
+SOURCES += [
     'nptest_name.cpp',
 ]
 
 toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
 if toolkit == 'cocoa':
-    CMMSRCS += [
+    SOURCES += [
         relative_path + '/nptest_macosx.mm'
     ]
 elif toolkit == 'gtk2':
-    CPP_SOURCES += [
+    SOURCES += [
         relative_path + '/nptest_gtk2.cpp',
     ]
 elif toolkit == 'android':
-    CPP_SOURCES += [
+    SOURCES += [
         relative_path + '/nptest_droid.cpp',
     ]
 elif toolkit == 'os2':
-    CPP_SOURCES += [
+    SOURCES += [
         relative_path + '/nptest_os2.cpp',
     ]
 elif toolkit == 'qt':
-    CPP_SOURCES += [
+    SOURCES += [
         relative_path + '/nptest_qt.cpp',
     ]
 elif toolkit == 'windows':
-    CPP_SOURCES += [
+    SOURCES += [
         relative_path + '/nptest_windows.cpp',
     ]
--- a/dom/power/Makefile.in
+++ b/dom/power/Makefile.in
@@ -1,8 +1,6 @@
 # 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)/dom/dom-config.mk
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/power/moz.build
+++ b/dom/power/moz.build
@@ -19,20 +19,22 @@ EXPORTS.mozilla.dom += [
     'PowerManager.h',
 ]
 
 EXPORTS.mozilla.dom.power += [
     'PowerManagerService.h',
     'Types.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'PowerManager.cpp',
     'PowerManagerService.cpp',
     'WakeLock.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'dom_power_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/promise/moz.build
+++ b/dom/promise/moz.build
@@ -9,17 +9,17 @@ TEST_DIRS += ['tests']
 XPIDL_MODULE = 'dom_promise'
 
 MODULE = 'dom'
 
 EXPORTS.mozilla.dom += [
     'Promise.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'Promise.cpp',
     'PromiseCallback.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
--- a/dom/quota/Makefile.in
+++ b/dom/quota/Makefile.in
@@ -1,12 +1,10 @@
 # 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)/dom/dom-config.mk
 
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/caps/include \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/quota/moz.build
+++ b/dom/quota/moz.build
@@ -28,23 +28,25 @@ EXPORTS.mozilla.dom.quota += [
     'QuotaCommon.h',
     'QuotaManager.h',
     'QuotaObject.h',
     'StoragePrivilege.h',
     'UsageInfo.h',
     'Utilities.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'CheckQuotaHelper.cpp',
     'FileStreams.cpp',
     'QuotaManager.cpp',
     'QuotaObject.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'domquota_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/src/events/moz.build
+++ b/dom/src/events/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'dom'
 
-CPP_SOURCES += [
+SOURCES += [
     'nsJSEventListener.cpp',
 ]
 
 LIBRARY_NAME = 'jsdomevents_s'
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
--- a/dom/src/events/nsJSEventListener.cpp
+++ b/dom/src/events/nsJSEventListener.cpp
@@ -204,18 +204,18 @@ nsJSEventListener::HandleEvent(nsIDOMEve
       aEvent->PreventDefault();
     }
     return NS_OK;
   }
 
   if (mHandler.Type() == nsEventHandler::eOnBeforeUnload) {
     MOZ_ASSERT(mEventName == nsGkAtoms::onbeforeunload);
 
-    nsRefPtr<BeforeUnloadEventHandlerNonNull> handler =
-      mHandler.BeforeUnloadEventHandler();
+    nsRefPtr<OnBeforeUnloadEventHandlerNonNull> handler =
+      mHandler.OnBeforeUnloadEventHandler();
     ErrorResult rv;
     nsString retval;
     handler->Call(mTarget, *(aEvent->InternalDOMEvent()), retval, rv);
     if (rv.Failed()) {
       return rv.ErrorCode();
     }
 
     nsCOMPtr<nsIDOMBeforeUnloadEvent> beforeUnload = do_QueryInterface(aEvent);
--- a/dom/src/geolocation/Makefile.in
+++ b/dom/src/geolocation/Makefile.in
@@ -23,9 +23,8 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),gonk)
 LOCAL_INCLUDES  += -I$(topsrcdir)/dom/system/gonk
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
 LOCAL_INCLUDES  += -I$(topsrcdir)/dom/system/mac
 endif
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/src/geolocation/moz.build
+++ b/dom/src/geolocation/moz.build
@@ -6,19 +6,21 @@
 
 MODULE = 'dom'
 
 EXPORTS += [
     'nsGeoPosition.h',
     'nsGeoPositionIPCSerialiser.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'nsGeolocation.cpp',
     'nsGeoPosition.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'jsdomgeolocation_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/src/geolocation/nsGeolocation.cpp
+++ b/dom/src/geolocation/nsGeolocation.cpp
@@ -72,17 +72,17 @@ class nsGeolocationRequest
                        const GeoPositionCallback& aCallback,
                        const GeoPositionErrorCallback& aErrorCallback,
                        PositionOptions* aOptions,
                        bool aWatchPositionRequest = false,
                        int32_t aWatchId = 0);
   void Shutdown();
 
   void SendLocation(nsIDOMGeoPosition* location);
-  bool WantsHighAccuracy() {return mOptions && mOptions->mEnableHighAccuracy;}
+  bool WantsHighAccuracy() {return !mShutdown && mOptions && mOptions->mEnableHighAccuracy;}
   void SetTimeoutTimer();
   nsIPrincipal* GetPrincipal();
 
   ~nsGeolocationRequest();
 
   virtual bool Recv__delete__(const bool& allow) MOZ_OVERRIDE;
   virtual void IPDLRelease() MOZ_OVERRIDE { Release(); }
 
@@ -440,17 +440,17 @@ nsGeolocationRequest::Allow()
   // if the user has specified a maximumAge, return a cached value.
 
   uint32_t maximumAge = 0;
   if (mOptions) {
     if (mOptions->mMaximumAge > 0) {
       maximumAge = mOptions->mMaximumAge;
     }
   }
-  gs->SetHigherAccuracy(mOptions && mOptions->mEnableHighAccuracy);
+  gs->UpdateAccuracy(WantsHighAccuracy());
 
   bool canUseCache = lastPosition && maximumAge > 0 &&
     (PRTime(PR_Now() / PR_USEC_PER_MSEC) - maximumAge <=
     PRTime(cachedPositionTime));
 
   if (canUseCache) {
     // okay, we can return a cached position
     // getCurrentPosition requests serviced by the cache
@@ -580,22 +580,22 @@ nsGeolocationRequest::Shutdown()
   MOZ_ASSERT(!mShutdown, "request shutdown twice");
   mShutdown = true;
 
   if (mTimeoutTimer) {
     mTimeoutTimer->Cancel();
     mTimeoutTimer = nullptr;
   }
 
-  // This should happen last, to ensure that this request isn't taken into consideration
-  // when deciding whether existing requests still require high accuracy.
+  // If there are no other high accuracy requests, the geolocation service will
+  // notify the provider to switch to the default accuracy.
   if (mOptions && mOptions->mEnableHighAccuracy) {
     nsRefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService();
     if (gs) {
-      gs->SetHigherAccuracy(false);
+      gs->UpdateAccuracy();
     }
   }
 }
 
 bool nsGeolocationRequest::Recv__delete__(const bool& allow)
 {
   if (allow) {
     (void) Allow();
@@ -897,19 +897,19 @@ nsGeolocationService::HighAccuracyReques
     if (mGeolocators[i]->HighAccuracyRequested()) {
       return true;
     }
   }
   return false;
 }
 
 void
-nsGeolocationService::SetHigherAccuracy(bool aEnable)
+nsGeolocationService::UpdateAccuracy(bool aForceHigh)
 {
-  bool highRequired = aEnable || HighAccuracyRequested();
+  bool highRequired = aForceHigh || HighAccuracyRequested();
 
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     ContentChild* cpc = ContentChild::GetSingleton();
     cpc->SendSetGeolocationHigherAccuracy(highRequired);
     return;
   }
 
   if (!mHigherAccuracy && highRequired) {
@@ -1057,16 +1057,17 @@ void
 Geolocation::Shutdown()
 {
   // Release all callbacks
   mPendingCallbacks.Clear();
   mWatchingCallbacks.Clear();
 
   if (mService) {
     mService->RemoveLocator(this);
+    mService->UpdateAccuracy();
   }
 
   mService = nullptr;
   mPrincipal = nullptr;
 }
 
 nsIDOMWindow*
 Geolocation::GetParentObject() const {
--- a/dom/src/geolocation/nsGeolocation.h
+++ b/dom/src/geolocation/nsGeolocation.h
@@ -80,18 +80,18 @@ public:
   nsresult StartDevice(nsIPrincipal* aPrincipal);
 
   // Stop the started geolocation device (gps, nmea, etc.)
   void     StopDevice();
 
   // create, or reinitalize the callback timer
   void     SetDisconnectTimer();
 
-  // request higher accuracy, if possible
-  void     SetHigherAccuracy(bool aEnable);
+  // Update the accuracy and notify the provider if changed
+  void     UpdateAccuracy(bool aForceHigh = false);
   bool     HighAccuracyRequested();
 
 private:
 
   ~nsGeolocationService();
 
   // Disconnect timer.  When this timer expires, it clears all pending callbacks
   // and closes down the provider, unless we are watching a point, and in that
--- a/dom/src/json/moz.build
+++ b/dom/src/json/moz.build
@@ -7,17 +7,17 @@
 TEST_DIRS += ['test']
 
 MODULE = 'dom'
 
 EXPORTS += [
     'nsJSON.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'nsJSON.cpp',
 ]
 
 LIBRARY_NAME = 'json_s'
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
--- a/dom/src/jsurl/moz.build
+++ b/dom/src/jsurl/moz.build
@@ -7,17 +7,17 @@
 TEST_DIRS += ['test']
 
 MODULE = 'jsurl'
 
 EXPORTS += [
     'nsJSProtocolHandler.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'nsJSProtocolHandler.cpp',
 ]
 
 LIBRARY_NAME = 'jsurl_s'
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
--- a/dom/src/notification/Makefile.in
+++ b/dom/src/notification/Makefile.in
@@ -5,9 +5,8 @@
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/dom/base \
   -I$(topsrcdir)/dom/ipc \
   -I$(topsrcdir)/content/base/src \
   -I$(topsrcdir)/content/events/src \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/src/notification/moz.build
+++ b/dom/src/notification/moz.build
@@ -15,19 +15,21 @@ EXTRA_JS_MODULES += [
     'NotificationDB.jsm'
 ]
 
 EXPORTS.mozilla.dom += [
     'DesktopNotification.h',
     'Notification.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'DesktopNotification.cpp',
     'Notification.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'jsdomnotification_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/src/offline/moz.build
+++ b/dom/src/offline/moz.build
@@ -4,17 +4,17 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MODULE = 'dom'
 
 EXPORTS += [
     'nsDOMOfflineResourceList.h',
 ]
-CPP_SOURCES += [
+SOURCES += [
     'nsDOMOfflineResourceList.cpp',
 ]
 
 LIBRARY_NAME = 'jsdomoffline_s'
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
--- a/dom/src/storage/Makefile.in
+++ b/dom/src/storage/Makefile.in
@@ -7,9 +7,8 @@ LOCAL_INCLUDES = \
                 -I$(topsrcdir)/dom/base \
 		-I$(topsrcdir)/content/events/src
 
 ifdef ENABLE_TESTS
 DEFINES += -DDOM_STORAGE_TESTS
 endif
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/src/storage/moz.build
+++ b/dom/src/storage/moz.build
@@ -5,17 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MODULE = 'dom'
 
 EXPORTS.mozilla.dom += [
     'DOMStorageIPC.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'DOMStorage.cpp',
     'DOMStorageCache.cpp',
     'DOMStorageDBThread.cpp',
     'DOMStorageIPC.cpp',
     'DOMStorageManager.cpp',
     'DOMStorageObserver.cpp',
 ]
 
@@ -26,8 +26,10 @@ IPDL_SOURCES += [
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'jsdomstorage_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/system/Makefile.in
+++ b/dom/system/Makefile.in
@@ -8,9 +8,8 @@ DEFINES += -DDLL_PREFIX=\"$(DLL_PREFIX)\
 LOCAL_INCLUDES += \
   -I$(topsrcdir)/content/events/src \
   -I$(topsrcdir)/dom/base \
   -I$(topsrcdir)/dom/bindings \
   -I$(topsrcdir)/js/xpconnect/loader \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/system/NetworkGeolocationProvider.js
+++ b/dom/system/NetworkGeolocationProvider.js
@@ -68,16 +68,19 @@ function WifiGeoPositionProvider() {
   try {
     gUseScanning = Services.prefs.getBoolPref("geo.wifi.scan");
   } catch (e) {}
 
   this.wifiService = null;
   this.timer = null;
   this.hasSeenWiFi = false;
   this.started = false;
+  // this is only used when logging is enabled, to debug interactions with the
+  // geolocation service
+  this.highAccuracy = false;
 }
 
 WifiGeoPositionProvider.prototype = {
   classID:          Components.ID("{77DA64D3-7458-4920-9491-86CC9914F904}"),
   QueryInterface:   XPCOMUtils.generateQI([Ci.nsIGeolocationProvider,
                                            Ci.nsIWifiListener,
                                            Ci.nsITimerCallback]),
   startup:  function() {
@@ -127,20 +130,22 @@ WifiGeoPositionProvider.prototype = {
       this.timer.cancel();
       this.timer = null;
     }
 
     this.started = false;
   },
 
   setHighAccuracy: function(enable) {
+    this.highAccuracy = enable;
+    LOG("setting highAccuracy to " + (this.highAccuracy?"TRUE":"FALSE"));
   },
 
   onChange: function(accessPoints) {
-    LOG("onChange called");
+    LOG("onChange called, highAccuracy = " + (this.highAccuracy?"TRUE":"FALSE"));
     this.hasSeenWiFi = true;
 
     let url = Services.urlFormatter.formatURLPref("geo.wifi.uri");
 
     function isPublic(ap) {
         let mask = "_nomap"
         let result = ap.ssid.indexOf(mask, ap.ssid.length - mask.length) == -1;
         if (result != -1) {
--- a/dom/system/android/Makefile.in
+++ b/dom/system/android/Makefile.in
@@ -2,9 +2,8 @@
 # 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/.
 
 LOCAL_INCLUDES  += -I$(topsrcdir)/dom/src/geolocation \
                      -I$(topsrcdir)/content/events/src
                      $(NULL)
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/system/android/moz.build
+++ b/dom/system/android/moz.build
@@ -1,21 +1,23 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'dom'
 
-CPP_SOURCES += [
+SOURCES += [
     'AndroidLocationProvider.cpp',
     'nsHapticFeedback.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'domsystemandroid_s'
 
 EXPORT_LIBRARY = True
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/system/gonk/Makefile.in
+++ b/dom/system/gonk/Makefile.in
@@ -7,18 +7,16 @@
 #     http://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-include $(topsrcdir)/dom/dom-config.mk
-
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/dom/base \
   -I$(topsrcdir)/dom/src/geolocation \
   -I$(topsrcdir)/dom/wifi \
   -I$(topsrcdir)/dom/bluetooth \
   -I$(topsrcdir)/content/events/src \
   $(NULL)
 
@@ -26,9 +24,8 @@ LOCAL_INCLUDES = \
 WORKER_FILES := worker_buf.js \
   $(NULL)
 
 INSTALL_TARGETS += WORKER
 
 WORKER_DEST = $(FINAL_TARGET)/modules/workers
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/system/gonk/moz.build
+++ b/dom/system/gonk/moz.build
@@ -32,17 +32,17 @@ XPIDL_MODULE = 'dom_system_gonk'
 MODULE = 'dom'
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
     EXPORTS += [
         'GonkGPSGeolocationProvider.h',
         'nsVolume.h',
         'nsVolumeService.h',
     ]
-    CPP_SOURCES += [
+    SOURCES += [
         'AudioChannelManager.cpp',
         'AudioManager.cpp',
         'AutoMounter.cpp',
         'AutoMounterSetting.cpp',
         'GonkGPSGeolocationProvider.cpp',
         'nsVolume.cpp',
         'nsVolumeMountLock.cpp',
         'nsVolumeService.cpp',
@@ -54,17 +54,17 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk
         'VolumeManager.cpp',
         'VolumeServiceIOThread.cpp',
         'VolumeServiceTest.cpp',
     ]
 
 if CONFIG['ENABLE_TESTS']:
     XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell.ini']
 
-CPP_SOURCES += [
+SOURCES += [
     'SystemWorkerManager.cpp',
 ]
 
 EXTRA_COMPONENTS += [
     'NetworkInterfaceListService.js',
     'NetworkInterfaceListService.manifest',
     'NetworkManager.js',
     'NetworkManager.manifest',
@@ -81,8 +81,10 @@ EXTRA_JS_MODULES += [
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'domsystemgonk_s'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/system/mac/CoreLocationLocationProvider.mm
+++ b/dom/system/mac/CoreLocationLocationProvider.mm
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCOMPtr.h"
 #include "nsGeoPosition.h"
 #include "nsIConsoleService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIDOMGeoPositionError.h"
 #include "CoreLocationLocationProvider.h"
+#include "nsCocoaFeatures.h"
 #include "prtime.h"
 
 #include <CoreLocation/CLError.h>
 #include <CoreLocation/CLLocation.h>
 #include <CoreLocation/CLLocationManager.h>
 #include <CoreLocation/CLLocationManagerDelegate.h>
 
 #include <objc/objc.h>
@@ -129,16 +130,22 @@ NS_IMPL_ISUPPORTS1(CoreLocationLocationP
 CoreLocationLocationProvider::CoreLocationLocationProvider()
   : mCLObjects(nullptr)
 {
 }
 
 bool
 CoreLocationLocationProvider::IsCoreLocationAvailable()
 {
+#if !defined(MAC_OS_X_VERSION_10_9) || \
+    MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_9
+  if (nsCocoaFeatures::OnMavericksOrLater()) {
+    return false;
+  }
+
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
   @try {
     NSBundle * bundle = [[[NSBundle alloc] initWithPath:@"/System/Library/Frameworks/CoreWLAN.framework"] autorelease];
     if (!bundle) {
       [pool release];
       return false;
     }
@@ -152,16 +159,17 @@ CoreLocationLocationProvider::IsCoreLoca
     if ([[[CWI_class interface] interfaceState] intValue] == kCWInterfaceStateRunning) {
       [pool release];
       return true;
     }
   }
   @catch(NSException *e) {
   }
   [pool release];
+#endif
   return false;
 }
 
 NS_IMETHODIMP
 CoreLocationLocationProvider::Startup()
 {
   if (!mCLObjects) {
     nsAutoPtr<CoreLocationObjects> clObjs(new CoreLocationObjects());
--- a/dom/system/mac/Makefile.in
+++ b/dom/system/mac/Makefile.in
@@ -1,9 +1,8 @@
 # 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/.
 
 LOCAL_INCLUDES  += -I$(topsrcdir)/dom/src/geolocation \
                    $(NULL)
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/system/mac/moz.build
+++ b/dom/system/mac/moz.build
@@ -1,18 +1,20 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'dom'
 
-CMMSRCS += ['CoreLocationLocationProvider.mm']
+SOURCES += ['CoreLocationLocationProvider.mm']
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'domsystemmac_s'
 
 EXPORT_LIBRARY = True
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/system/moz.build
+++ b/dom/system/moz.build
@@ -31,17 +31,17 @@ MODULE = 'dom'
 EXPORTS += [
     'nsDeviceSensors.h',
 ]
 
 EXPORTS.mozilla += [
     'OSFileConstants.h',
 ]
 
-CPP_SOURCES += [
+SOURCES += [
     'nsDeviceSensors.cpp',
     'OSFileConstants.cpp',
 ]
 
 # On Systems that have build in geolocation providers,
 # we really do not need these.
 if CONFIG['OS_TARGET'] != 'Android' or CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
     EXTRA_COMPONENTS += [
@@ -52,8 +52,10 @@ if CONFIG['OS_TARGET'] != 'Android' or C
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'domsystem_s'
 
 EXPORT_LIBRARY = True
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/system/unix/Makefile.in
+++ b/dom/system/unix/Makefile.in
@@ -4,9 +4,8 @@
 
 ifdef MOZ_ENABLE_QTMOBILITY
 LOCAL_INCLUDES  += $(MOZ_QT_CFLAGS) \
                    -I$(topsrcdir)/dom/src/geolocation \
                    $(NULL)
 endif
 
 include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/system/unix/moz.build
+++ b/dom/system/unix/moz.build
@@ -2,21 +2,23 @@
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'dom'
 
 if CONFIG['MOZ_ENABLE_QTMOBILITY']:
-    CPP_SOURCES += [
+    SOURCES += [
         'moc_QTMLocationProvider.cpp',
         'QTMLocationProvider.cpp',
     ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'domsystemunix_s'
 
 EXPORT_LIBRARY = True
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/dom/system/windows/moz.build
+++ b/dom/system/windows/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'dom'
 
-CPP_SOURCES += [
+SOURCES += [
     'nsHapticFeedback.cpp',
 ]
 
 # We fire the nsDOMDeviceAcceleration
 LOCAL_INCLUDES += [
     '/content/events/src',
 ]
 
--- a/dom/telephony/Makefile.in
+++ b/dom/telephony/Makefile.in
@@ -1,7 +1,5 @@
 # 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/.