Bug 790978 - Convert MutationObserver to webidl, r=bz
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Tue, 18 Dec 2012 16:50:52 +0200
changeset 125483 e1427a1f27c4d62cfa70aac8b64a2831db4b8af6
parent 125482 fd8fd1a7aecd8b8242bccf77ae48a19df5ee6fe4
child 125484 9de611848111237f46893ccf838fdaa878374523
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs790978
milestone20.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
Bug 790978 - Convert MutationObserver to webidl, r=bz
content/base/src/nsDOMMutationObserver.cpp
content/base/src/nsDOMMutationObserver.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
dom/base/nsDOMClassInfoClasses.h
dom/bindings/Bindings.conf
dom/imptests/failures/webapps/DOMCore/tests/approved/test_interfaces.html.json
dom/interfaces/core/Makefile.in
dom/interfaces/core/nsIDOMMutationObserver.idl
dom/webidl/MutationObserver.webidl
dom/webidl/WebIDL.mk
js/xpconnect/src/dictionary_helper_gen.conf
js/xpconnect/src/dom_quickstubs.qsconf
layout/build/nsLayoutModule.cpp
--- a/content/base/src/nsDOMMutationObserver.cpp
+++ b/content/base/src/nsDOMMutationObserver.cpp
@@ -2,164 +2,119 @@
 /* vim: set sw=4 ts=8 et 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 "nsDOMMutationObserver.h"        
 #include "nsDOMClassInfoID.h"
 #include "nsError.h"
-#include "nsIClassInfo.h"
-#include "nsIXPCScriptable.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsContentUtils.h"
 #include "nsThreadUtils.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsTextFragment.h"
 #include "jsapi.h"
 #include "nsServiceManagerUtils.h"
-#include "DictionaryHelpers.h"
 
-nsCOMArray<nsIDOMMutationObserver>*
+nsTArray<nsRefPtr<nsDOMMutationObserver> >*
   nsDOMMutationObserver::sScheduledMutationObservers = nullptr;
 
-nsIDOMMutationObserver* nsDOMMutationObserver::sCurrentObserver = nullptr;
+nsDOMMutationObserver* nsDOMMutationObserver::sCurrentObserver = nullptr;
 
 uint32_t nsDOMMutationObserver::sMutationLevel = 0;
 uint64_t nsDOMMutationObserver::sCount = 0;
 
-nsAutoTArray<nsCOMArray<nsIDOMMutationObserver>, 4>*
+nsAutoTArray<nsTArray<nsRefPtr<nsDOMMutationObserver> >, 4>*
 nsDOMMutationObserver::sCurrentlyHandlingObservers = nullptr;
 
+nsINodeList*
+nsDOMMutationRecord::AddedNodes()
+{
+  if (!mAddedNodes) {
+    mAddedNodes = new nsSimpleContentList(mTarget);
+  }
+  return mAddedNodes;
+}
+
+nsINodeList*
+nsDOMMutationRecord::RemovedNodes()
+{
+  if (!mRemovedNodes) {
+    mRemovedNodes = new nsSimpleContentList(mTarget);
+  }
+  return mRemovedNodes;
+}
+
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMMutationRecord)
 
-DOMCI_DATA(MutationRecord, nsDOMMutationRecord)
-
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMMutationRecord)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMMutationRecord)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MutationRecord)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMMutationRecord)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMMutationRecord)
 
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMMutationRecord)
+  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMMutationRecord)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mTarget)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mPreviousSibling)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mNextSibling)
   tmp->mAddedNodes = nullptr;
   tmp->mRemovedNodes = nullptr;
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMMutationRecord)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTarget)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPreviousSibling)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNextSibling)
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mAddedNodes");
   cb.NoteXPCOMChild(static_cast<nsIDOMNodeList*>(tmp->mAddedNodes));
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRemovedNodes");
   cb.NoteXPCOMChild(static_cast<nsIDOMNodeList*>(tmp->mRemovedNodes));
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
-NS_IMETHODIMP
-nsDOMMutationRecord::GetType(nsAString& aType)
-{
-  aType = mType;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMMutationRecord::GetTarget(nsIDOMNode** aTarget)
-{
-  nsCOMPtr<nsIDOMNode> n = do_QueryInterface(mTarget);
-  n.forget(aTarget);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMMutationRecord::GetAddedNodes(nsIDOMNodeList** aAddedNodes)
-{
-  if (!mAddedNodes && mTarget) {
-    mAddedNodes = new nsSimpleContentList(mTarget);
-  }
-  NS_IF_ADDREF(*aAddedNodes = mAddedNodes);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMMutationRecord::GetRemovedNodes(nsIDOMNodeList** aRemovedNodes)
-{
-  if (!mRemovedNodes && mTarget) {
-    mRemovedNodes = new nsSimpleContentList(mTarget);
-  }
-  NS_IF_ADDREF(*aRemovedNodes = mRemovedNodes);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMMutationRecord::GetPreviousSibling(nsIDOMNode** aPreviousSibling)
-{
-  nsCOMPtr<nsIDOMNode> n = do_QueryInterface(mPreviousSibling);
-  *aPreviousSibling = n.forget().get();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMMutationRecord::GetNextSibling(nsIDOMNode** aNextSibling)
-{
-  nsCOMPtr<nsIDOMNode> n = do_QueryInterface(mNextSibling);
-  *aNextSibling = n.forget().get();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMMutationRecord::GetAttributeName(nsAString& aAttrName)
-{
-  aAttrName = mAttrName;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMMutationRecord::GetAttributeNamespace(nsAString& aAttrNamespace)
-{
-  aAttrNamespace = mAttrNamespace;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMMutationRecord::GetOldValue(nsAString& aPrevValue)
-{
-  aPrevValue = mPrevValue;
-  return NS_OK;
-}
-
 // Observer
 
 NS_IMPL_ADDREF(nsMutationReceiver)
 NS_IMPL_RELEASE(nsMutationReceiver)
 
 NS_INTERFACE_MAP_BEGIN(nsMutationReceiver)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
   NS_INTERFACE_MAP_ENTRY(nsMutationReceiver)
 NS_INTERFACE_MAP_END
 
+nsMutationReceiver::nsMutationReceiver(nsINode* aTarget,
+                                       nsDOMMutationObserver* aObserver)
+: nsMutationReceiverBase(aTarget, aObserver)
+{
+  mTarget->BindObject(aObserver);
+}
+
 void
 nsMutationReceiver::Disconnect(bool aRemoveFromObserver)
 {
   if (mRegisterTarget) {
     mRegisterTarget->RemoveMutationObserver(this);
     mRegisterTarget = nullptr;
   }
 
   mParent = nullptr;
   nsINode* target = mTarget;
   mTarget = nullptr;
-  nsIDOMMutationObserver* observer = mObserver;
+  nsDOMMutationObserver* observer = mObserver;
   mObserver = nullptr;
   RemoveClones();
 
   if (target && observer) {
     if (aRemoveFromObserver) {
       static_cast<nsDOMMutationObserver*>(observer)->RemoveReceiver(this);
     }
     // UnbindObject may delete 'this'!
@@ -382,49 +337,42 @@ void nsMutationReceiver::NodeWillBeDestr
   NS_ASSERTION(!mParent, "Shouldn't have mParent here!");
   Disconnect(true);
 }
 
 // Observer
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMMutationObserver)
 
-DOMCI_DATA(MutationObserver, nsDOMMutationObserver)
-
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMMutationObserver)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMutationObserver)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMMutationObserver)
-  NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MutationObserver)
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMMutationObserver)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMMutationObserver)
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMMutationObserver)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMMutationObserver)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mScriptContext)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
   for (int32_t i = 0; i < tmp->mReceivers.Count(); ++i) {
     tmp->mReceivers[i]->Disconnect(false);
   }
   tmp->mReceivers.Clear();
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingMutations)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallback)
   // No need to handle mTransientReceivers
   NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMMutationObserver)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScriptContext)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReceivers)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingMutations)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallback)
   // No need to handle mTransientReceivers
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 nsMutationReceiver*
@@ -500,151 +448,128 @@ nsDOMMutationObserver::ScheduleForRun()
   mWaitingForRun = true;
   RescheduleForRun();
 }
 
 void
 nsDOMMutationObserver::RescheduleForRun()
 {
   if (!sScheduledMutationObservers) {
-    sScheduledMutationObservers = new nsCOMArray<nsIDOMMutationObserver>;
+    sScheduledMutationObservers = new nsTArray<nsRefPtr<nsDOMMutationObserver> >;
   }
 
   bool didInsert = false;
-  for (int32_t i = 0; i < sScheduledMutationObservers->Count(); ++i) {
+  for (uint32_t i = 0; i < sScheduledMutationObservers->Length(); ++i) {
     if (static_cast<nsDOMMutationObserver*>((*sScheduledMutationObservers)[i])
           ->mId > mId) {
-      sScheduledMutationObservers->InsertObjectAt(this, i);
+      sScheduledMutationObservers->InsertElementAt(i, this);
       didInsert = true;
       break;
     }
   }
   if (!didInsert) {
-    sScheduledMutationObservers->AppendObject(this);
+    sScheduledMutationObservers->AppendElement(this);
   }
 }
 
-NS_IMETHODIMP
-nsDOMMutationObserver::Observe(nsIDOMNode* aTarget,
-                               const JS::Value& aOptions,
-                               JSContext* aCx)
+void
+nsDOMMutationObserver::Observe(nsINode& aTarget,
+                               const mozilla::dom::MutationObserverInit& aOptions,
+                               mozilla::ErrorResult& aRv)
 {
-  nsCOMPtr<nsINode> target = do_QueryInterface(aTarget);
-  NS_ENSURE_STATE(target);
 
-  mozilla::dom::MutationObserverInit d;
-  nsresult rv = d.Init(aCx, &aOptions);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  NS_ENSURE_TRUE(d.childList || d.attributes || d.characterData,
-                 NS_ERROR_DOM_SYNTAX_ERR);
-  NS_ENSURE_TRUE(!d.attributeOldValue || d.attributes,
-                 NS_ERROR_DOM_SYNTAX_ERR);
-  NS_ENSURE_TRUE(!d.characterDataOldValue || d.characterData,
-                 NS_ERROR_DOM_SYNTAX_ERR);
+  if (!(aOptions.childList || aOptions.attributes || aOptions.characterData)) {
+    aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+    return;
+  }
+  if (aOptions.attributeOldValue && !aOptions.attributes) {
+    aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+    return;
+  }
+  if (aOptions.characterDataOldValue && !aOptions.characterData) {
+    aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+    return;
+  }
 
   nsCOMArray<nsIAtom> filters;
   bool allAttrs = true;
-  if (!d.attributeFilter.isUndefined()) {
+  if (aOptions.attributeFilter.WasPassed()) {
     allAttrs = false;
-    rv = nsContentUtils::JSArrayToAtomArray(aCx, d.attributeFilter, filters);
-    NS_ENSURE_SUCCESS(rv, rv);
-    NS_ENSURE_TRUE(filters.Count() == 0 || d.attributes,
-                   NS_ERROR_DOM_SYNTAX_ERR);
+    const mozilla::dom::Sequence<nsString>& filtersAsString =
+      aOptions.attributeFilter.Value();
+    uint32_t len = filtersAsString.Length();
+
+    if (len != 0 && !aOptions.attributes) {
+      aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+      return;
+    }
+    if (!filters.SetCapacity(len)) {
+      aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
+      return;
+    }
+
+    for (uint32_t i = 0; i < len; ++i) {
+      nsCOMPtr<nsIAtom> a = do_GetAtom(filtersAsString[i]);
+      filters.AppendObject(a);
+    }
   }
 
-  nsMutationReceiver* r = GetReceiverFor(target, true);
-  r->SetChildList(d.childList);
-  r->SetAttributes(d.attributes);
-  r->SetCharacterData(d.characterData);
-  r->SetSubtree(d.subtree);
-  r->SetAttributeOldValue(d.attributeOldValue);
-  r->SetCharacterDataOldValue(d.characterDataOldValue);
+  nsMutationReceiver* r = GetReceiverFor(&aTarget, true);
+  r->SetChildList(aOptions.childList);
+  r->SetAttributes(aOptions.attributes);
+  r->SetCharacterData(aOptions.characterData);
+  r->SetSubtree(aOptions.subtree);
+  r->SetAttributeOldValue(aOptions.attributeOldValue);
+  r->SetCharacterDataOldValue(aOptions.characterDataOldValue);
   r->SetAttributeFilter(filters);
   r->SetAllAttributes(allAttrs);
   r->RemoveClones();
 
 #ifdef DEBUG
   for (int32_t i = 0; i < mReceivers.Count(); ++i) {
     NS_WARN_IF_FALSE(mReceivers[i]->Target(),
                      "All the receivers should have a target!");
   }
 #endif
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP
+void
 nsDOMMutationObserver::Disconnect()
 {
   for (int32_t i = 0; i < mReceivers.Count(); ++i) {
     mReceivers[i]->Disconnect(false);
   }
   mReceivers.Clear();
   mCurrentMutations.Clear();
   mPendingMutations.Clear();
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDOMMutationObserver::TakeRecords(nsIVariant** aRetVal)
+void
+nsDOMMutationObserver::TakeRecords(
+                         nsTArray<nsRefPtr<nsDOMMutationRecord> >& aRetVal)
 {
-  *aRetVal = TakeRecords().get();
-  return NS_OK;
+  aRetVal.Clear();
+  mPendingMutations.SwapElements(aRetVal);
 }
 
-already_AddRefed<nsIVariant>
-nsDOMMutationObserver::TakeRecords()
+// static
+already_AddRefed<nsDOMMutationObserver>
+nsDOMMutationObserver::Constructor(nsISupports* aGlobal,
+                                   mozilla::dom::MutationCallback& aCb,
+                                   mozilla::ErrorResult& aRv)
 {
-  nsCOMPtr<nsIWritableVariant> mutations =
-    do_CreateInstance("@mozilla.org/variant;1");
-  int32_t len = mPendingMutations.Count();
-  if (len == 0) {
-    mutations->SetAsEmptyArray();
-  } else {
-    nsTArray<nsIDOMMutationRecord*> mods(len);
-    for (int32_t i = 0; i < len; ++i) {
-      mods.AppendElement(mPendingMutations[i]);
-    }
-
-    mutations->SetAsArray(nsIDataType::VTYPE_INTERFACE,
-                          &NS_GET_IID(nsIDOMMutationRecord),
-                          mods.Length(),
-                          const_cast<void*>(
-                            static_cast<const void*>(mods.Elements())));
-    mPendingMutations.Clear();
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal);
+  if (!window) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
   }
-  return mutations.forget();
-}
-
-NS_IMETHODIMP
-nsDOMMutationObserver::Initialize(nsISupports* aOwner, JSContext* cx,
-                                  JSObject* obj, uint32_t argc, jsval* argv)
-{
-  mOwner = do_QueryInterface(aOwner);
-  if (!mOwner) {
-    NS_WARNING("Unexpected nsIJSNativeInitializer owner");
-    return NS_OK;
-  }
-  nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aOwner);
-  NS_ENSURE_STATE(sgo);
-  mScriptContext = sgo->GetContext();
-  NS_ENSURE_STATE(mScriptContext);
-  
-  NS_ENSURE_STATE(argc >= 1);
-  NS_ENSURE_STATE(!JSVAL_IS_PRIMITIVE(argv[0]));
-
-  nsCOMPtr<nsISupports> tmp;
-  nsContentUtils::XPConnect()->WrapJS(cx, JSVAL_TO_OBJECT(argv[0]),
-                                      NS_GET_IID(nsIMutationObserverCallback),
-                                      getter_AddRefs(tmp));
-  mCallback = do_QueryInterface(tmp);
-  NS_ENSURE_STATE(mCallback);
-  
-  return NS_OK;
+  MOZ_ASSERT(window->IsInnerWindow());
+  nsRefPtr<nsDOMMutationObserver> observer =
+    new nsDOMMutationObserver(window.forget(), aCb);
+  return observer.forget();
 }
 
 void
 nsDOMMutationObserver::HandleMutation()
 {
   NS_ASSERTION(nsContentUtils::IsSafeToRunScript(), "Whaat!");
   NS_ASSERTION(mCurrentMutations.IsEmpty(),
                "Still generating MutationRecords?");
@@ -652,33 +577,33 @@ nsDOMMutationObserver::HandleMutation()
   mWaitingForRun = false;
 
   for (int32_t i = 0; i < mReceivers.Count(); ++i) {
     mReceivers[i]->RemoveClones();
   }
   mTransientReceivers.Clear();
 
   nsPIDOMWindow* outer = mOwner->GetOuterWindow();
-  if (!mPendingMutations.Count() || !outer ||
+  if (!mPendingMutations.Length() || !outer ||
       outer->GetCurrentInnerWindow() != mOwner) {
     mPendingMutations.Clear();
     return;
   }
-  nsCxPusher pusher;
-  nsCOMPtr<nsIDOMEventTarget> et = do_QueryInterface(mOwner);
-  if (!mCallback || !pusher.Push(et)) {
-    mPendingMutations.Clear();
-    return;
+
+  nsTArray<nsRefPtr<nsDOMMutationRecord> > mutationsArray;
+  TakeRecords(mutationsArray);
+  mozilla::dom::Sequence<mozilla::dom::OwningNonNull<nsDOMMutationRecord> >
+    mutations;
+  uint32_t len = mutationsArray.Length();
+  NS_ENSURE_TRUE_VOID(mutations.SetCapacity(len));
+  for (uint32_t i = 0; i < len; ++i) {
+    *mutations.AppendElement() = mutationsArray[i].forget();
   }
-
-  nsCOMPtr<nsIVariant> mutations = TakeRecords();
-  nsAutoMicroTask mt;
-  sCurrentObserver = this; // For 'this' handling.
-  mCallback->HandleMutations(mutations, this);
-  sCurrentObserver = nullptr;
+  mozilla::ErrorResult rv;
+  mCallback->Call(this, mutations, *this, rv);
 }
 
 class AsyncMutationHandler : public nsRunnable
 {
 public:
   NS_IMETHOD Run()
   {
     nsDOMMutationObserver::HandleMutations();
@@ -699,40 +624,40 @@ nsDOMMutationObserver::HandleMutationsIn
     // after previous mutations are handled. But in case some
     // callback calls a sync API, which spins the eventloop, we need to still
     // process other mutations happening during that sync call.
     // This does *not* catch all cases, but should work for stuff running
     // in separate tabs.
     return;
   }
 
-  nsCOMArray<nsIDOMMutationObserver>* suppressedObservers = nullptr;
+  nsTArray<nsRefPtr<nsDOMMutationObserver> >* suppressedObservers = nullptr;
 
   while (sScheduledMutationObservers) {
-    nsCOMArray<nsIDOMMutationObserver>* observers = sScheduledMutationObservers;
+    nsTArray<nsRefPtr<nsDOMMutationObserver> >* observers = sScheduledMutationObservers;
     sScheduledMutationObservers = nullptr;
-    for (int32_t i = 0; i < observers->Count(); ++i) {
+    for (uint32_t i = 0; i < observers->Length(); ++i) {
       sCurrentObserver = static_cast<nsDOMMutationObserver*>((*observers)[i]);
       if (!sCurrentObserver->Suppressed()) {
         sCurrentObserver->HandleMutation();
       } else {
         if (!suppressedObservers) {
-          suppressedObservers = new nsCOMArray<nsIDOMMutationObserver>;
+          suppressedObservers = new nsTArray<nsRefPtr<nsDOMMutationObserver> >;
         }
-        if (suppressedObservers->IndexOf(sCurrentObserver) < 0) {
-          suppressedObservers->AppendObject(sCurrentObserver);
+        if (!suppressedObservers->Contains(sCurrentObserver)) {
+          suppressedObservers->AppendElement(sCurrentObserver);
         }
       }
     }
     delete observers;
   }
 
   if (suppressedObservers) {
-    for (int32_t i = 0; i < suppressedObservers->Count(); ++i) {
-      static_cast<nsDOMMutationObserver*>(suppressedObservers->ObjectAt(i))->
+    for (uint32_t i = 0; i < suppressedObservers->Length(); ++i) {
+      static_cast<nsDOMMutationObserver*>(suppressedObservers->ElementAt(i))->
         RescheduleForRun();
     }
     delete suppressedObservers;
     suppressedObservers = nullptr;
   }
   sCurrentObserver = nullptr;
 }
 
@@ -742,53 +667,53 @@ nsDOMMutationObserver::CurrentRecord(con
   NS_ASSERTION(sMutationLevel > 0, "Unexpected mutation level!");
 
   while (mCurrentMutations.Length() < sMutationLevel) {
     mCurrentMutations.AppendElement(static_cast<nsDOMMutationRecord*>(nullptr));
   }
 
   uint32_t last = sMutationLevel - 1;
   if (!mCurrentMutations[last]) {
-    nsDOMMutationRecord* r = new nsDOMMutationRecord(aType);
+    nsDOMMutationRecord* r = new nsDOMMutationRecord(aType, GetParentObject());
     mCurrentMutations[last] = r;
-    mPendingMutations.AppendObject(r);
+    mPendingMutations.AppendElement(r);
     ScheduleForRun();
   }
 
   NS_ASSERTION(mCurrentMutations[last]->mType.Equals(aType),
                "Unexpected MutationRecord type!");
 
   return mCurrentMutations[last];
 }
 
 nsDOMMutationObserver::~nsDOMMutationObserver()
 {
   for (int32_t i = 0; i < mReceivers.Count(); ++i) {
     mReceivers[i]->RemoveClones();
   }
-}                                   
+}
 
 void
 nsDOMMutationObserver::EnterMutationHandling()
 {
   ++sMutationLevel;
 }
 
 // Leave the current mutation level (there can be several levels if in case
 // of nested calls to the nsIMutationObserver methods).
 // The most recent mutation record is removed from mCurrentMutations, so
 // that is doesn't get modified anymore by receivers.
 void
 nsDOMMutationObserver::LeaveMutationHandling()
 {
   if (sCurrentlyHandlingObservers &&
       sCurrentlyHandlingObservers->Length() == sMutationLevel) {
-    nsCOMArray<nsIDOMMutationObserver>& obs =
+    nsTArray<nsRefPtr<nsDOMMutationObserver> >& obs =
       sCurrentlyHandlingObservers->ElementAt(sMutationLevel - 1);
-    for (int32_t i = 0; i < obs.Count(); ++i) {
+    for (uint32_t i = 0; i < obs.Length(); ++i) {
       nsDOMMutationObserver* o =
         static_cast<nsDOMMutationObserver*>(obs[i]);
       if (o->mCurrentMutations.Length() == sMutationLevel) {
         // It is already in pending mutations.
         o->mCurrentMutations.RemoveElementAt(sMutationLevel - 1);
       }
     }
     sCurrentlyHandlingObservers->RemoveElementAt(sMutationLevel - 1);
@@ -798,27 +723,27 @@ nsDOMMutationObserver::LeaveMutationHand
 
 void
 nsDOMMutationObserver::AddCurrentlyHandlingObserver(nsDOMMutationObserver* aObserver)
 {
   NS_ASSERTION(sMutationLevel > 0, "Unexpected mutation level!");
 
   if (!sCurrentlyHandlingObservers) {
     sCurrentlyHandlingObservers =
-      new nsAutoTArray<nsCOMArray<nsIDOMMutationObserver>, 4>;
+      new nsAutoTArray<nsTArray<nsRefPtr<nsDOMMutationObserver> >, 4>;
   }
 
   while (sCurrentlyHandlingObservers->Length() < sMutationLevel) {
     sCurrentlyHandlingObservers->InsertElementAt(
       sCurrentlyHandlingObservers->Length());
   }
 
   uint32_t last = sMutationLevel - 1;
-  if (sCurrentlyHandlingObservers->ElementAt(last).IndexOf(aObserver) < 0) {
-    sCurrentlyHandlingObservers->ElementAt(last).AppendObject(aObserver);
+  if (!sCurrentlyHandlingObservers->ElementAt(last).Contains(aObserver)) {
+    sCurrentlyHandlingObservers->ElementAt(last).AppendElement(aObserver);
   }
 }
 
 void
 nsDOMMutationObserver::Shutdown()
 {
   delete sCurrentlyHandlingObservers;
   sCurrentlyHandlingObservers = nullptr;
@@ -884,18 +809,19 @@ nsAutoMutationBatch::Done()
     }
     if (wantsChildList && (mRemovedNodes.Length() || mAddedNodes.Length())) {
       nsRefPtr<nsSimpleContentList> addedList =
         new nsSimpleContentList(mBatchTarget);
       for (uint32_t i = 0; i < mAddedNodes.Length(); ++i) {
         addedList->AppendElement(mAddedNodes[i]);
       }
       nsDOMMutationRecord* m =
-        new nsDOMMutationRecord(NS_LITERAL_STRING("childList"));
-      ob->mPendingMutations.AppendObject(m);
+        new nsDOMMutationRecord(NS_LITERAL_STRING("childList"),
+                                ob->GetParentObject());
+      ob->mPendingMutations.AppendElement(m);
       m->mTarget = mBatchTarget;
       m->mRemovedNodes = removedList;
       m->mAddedNodes = addedList;
       m->mPreviousSibling = mPrevSibling;
       m->mNextSibling = mNextSibling;
     }
     // Always schedule the observer so that transient receivers are
     // removed correctly.
--- a/content/base/src/nsDOMMutationObserver.h
+++ b/content/base/src/nsDOMMutationObserver.h
@@ -2,58 +2,112 @@
 /* vim: set sw=4 ts=8 et tw=80 : */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsDOMMutationObserver_h
 #define nsDOMMutationObserver_h
 
-#include "nsIDOMMutationObserver.h"
 #include "nsCycleCollectionParticipant.h"
-#include "nsIJSNativeInitializer.h"
 #include "nsPIDOMWindow.h"
 #include "nsIScriptContext.h"
 #include "nsStubMutationObserver.h"
 #include "nsCOMArray.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
 #include "nsIVariant.h"
 #include "nsContentList.h"
 #include "mozilla/dom/Element.h"
 #include "nsClassHashtable.h"
 #include "nsNodeUtils.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsWrapperCache.h"
+#include "mozilla/dom/MutationObserverBinding.h"
 
 class nsDOMMutationObserver;
 
-class nsDOMMutationRecord : public nsIDOMMutationRecord
+class nsDOMMutationRecord : public nsISupports,
+                            public nsWrapperCache
 {
 public:
-  nsDOMMutationRecord(const nsAString& aType) : mType(aType)
+  nsDOMMutationRecord(const nsAString& aType, nsISupports* aOwner)
+  : mType(aType), mOwner(aOwner)
   {
     mAttrName.SetIsVoid(PR_TRUE);
     mAttrNamespace.SetIsVoid(PR_TRUE);
     mPrevValue.SetIsVoid(PR_TRUE);
+    SetIsDOMBinding();
   }
   virtual ~nsDOMMutationRecord() {}
+
+  nsISupports* GetParentObject() const
+  {
+    return mOwner;
+  }
+
+  virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
+                               bool* aTriedToWrap)
+  {
+    return mozilla::dom::MutationRecordBinding::Wrap(aCx, aScope, this,
+                                                     aTriedToWrap);
+  }
+
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMMutationRecord)
-  NS_DECL_NSIDOMMUTATIONRECORD
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMMutationRecord)
+
+  void GetType(nsString& aRetVal) const
+  {
+    aRetVal = mType;
+  }
+
+  nsINode* GetTarget() const
+  {
+    return mTarget;
+  }
+
+  nsINodeList* AddedNodes();
+
+  nsINodeList* RemovedNodes();
+
+  nsINode* GetPreviousSibling() const
+  {
+    return mPreviousSibling;
+  }
+
+  nsINode* GetNextSibling() const
+  {
+    return mNextSibling;
+  }
+
+  void GetAttributeName(nsString& aRetVal) const
+  {
+    aRetVal = mAttrName;
+  }
+
+  void GetAttributeNamespace(nsString& aRetVal) const
+  {
+    aRetVal = mAttrNamespace;
+  }
+
+  void GetOldValue(nsString& aRetVal) const
+  {
+    aRetVal = mPrevValue;
+  }
 
   nsCOMPtr<nsINode>             mTarget;
   nsString                      mType;
   nsString                      mAttrName;
   nsString                      mAttrNamespace;
   nsString                      mPrevValue;
   nsRefPtr<nsSimpleContentList> mAddedNodes;
   nsRefPtr<nsSimpleContentList> mRemovedNodes;
   nsCOMPtr<nsINode>             mPreviousSibling;
   nsCOMPtr<nsINode>             mNextSibling;
+  nsCOMPtr<nsISupports>         mOwner;
 };
  
 // Base class just prevents direct access to
 // members to make sure we go through getters/setters.
 class nsMutationReceiverBase : public nsStubMutationObserver
 {
 public:
   virtual ~nsMutationReceiverBase() { }
@@ -138,17 +192,17 @@ public:
   }
 
   void RemoveClone(nsMutationReceiverBase* aClone)
   {
     mTransientReceivers.RemoveObject(aClone);
   }
   
 protected:
-  nsMutationReceiverBase(nsINode* aTarget, nsIDOMMutationObserver* aObserver)
+  nsMutationReceiverBase(nsINode* aTarget, nsDOMMutationObserver* aObserver)
   : mTarget(aTarget), mObserver(aObserver), mRegisterTarget(aTarget)
   {
     mRegisterTarget->AddMutationObserver(this);
     mRegisterTarget->SetMayHaveDOMMutationObserver();
     mRegisterTarget->OwnerDoc()->SetMayHaveDOMMutationObservers();
   }
 
   nsMutationReceiverBase(nsINode* aRegisterTarget,
@@ -176,27 +230,27 @@ protected:
       return true;
     }
 
     if (aNameSpaceID != kNameSpaceID_None) {
       return false;
     }
 
     nsCOMArray<nsIAtom>& filters = AttributeFilter();
-    for (int32_t i = 0; i < filters.Count(); ++i) {         
+    for (int32_t i = 0; i < filters.Count(); ++i) {
       if (filters[i] == aAttr) {
         return true;
       }
     }
     return false;
   }
 
   // The target for the MutationObserver.observe() method.
   nsINode*                           mTarget;
-  nsIDOMMutationObserver*            mObserver;
+  nsDOMMutationObserver*             mObserver;
   nsRefPtr<nsMutationReceiverBase>   mParent; // Cleared after microtask.
   // The node to which Gecko-internal nsIMutationObserver was registered to.
   // This is different than mTarget when dealing with transient observers.
   nsINode*                           mRegisterTarget;
   nsCOMArray<nsMutationReceiverBase> mTransientReceivers;
   // While we have transient receivers, keep the original mutation receiver
   // alive so it doesn't go away and disconnect all its transient receivers.
   nsCOMPtr<nsINode>                  mKungFuDeathGrip;
@@ -215,21 +269,17 @@ private:
 
 #define NS_MUTATION_OBSERVER_IID \
 { 0xe628f313, 0x8129, 0x4f90, \
   { 0x8e, 0xc3, 0x85, 0xe8, 0x28, 0x22, 0xe7, 0xab } }
 
 class nsMutationReceiver : public nsMutationReceiverBase
 {
 public:
-  nsMutationReceiver(nsINode* aTarget, nsIDOMMutationObserver* aObserver)
-  : nsMutationReceiverBase(aTarget, aObserver)
-  {
-    mTarget->BindObject(aObserver);
-  }
+  nsMutationReceiver(nsINode* aTarget, nsDOMMutationObserver* aObserver);
 
   nsMutationReceiver(nsINode* aRegisterTarget, nsMutationReceiverBase* aParent)
   : nsMutationReceiverBase(aRegisterTarget, aParent)
   {
     NS_ASSERTION(!static_cast<nsMutationReceiver*>(aParent)->GetParent(),
                  "Shouldn't create deep observer hierarchies!");
     aParent->AddClone(this);
   }
@@ -284,80 +334,68 @@ public:
     // We can reuse AttributeWillChange implementation.
     AttributeWillChange(aDocument, aElement, aNameSpaceID, aAttribute,
                         nsIDOMMutationEvent::MODIFICATION);
   }
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsMutationReceiver, NS_MUTATION_OBSERVER_IID)
 
-class nsDOMMutationObserver : public nsIDOMMutationObserver,
-                              public nsIJSNativeInitializer,
+class nsDOMMutationObserver : public nsISupports,
                               public nsWrapperCache
 {
 public:
-  nsDOMMutationObserver() : mWaitingForRun(false), mId(++sCount)
+  nsDOMMutationObserver(already_AddRefed<nsPIDOMWindow> aOwner,
+                        mozilla::dom::MutationCallback& aCb)
+  : mOwner(aOwner), mCallback(&aCb), mWaitingForRun(false), mId(++sCount)
   {
     mTransientReceivers.Init();
+    SetIsDOMBinding();
   }
   virtual ~nsDOMMutationObserver();
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDOMMutationObserver,
-                                                         nsIDOMMutationObserver)
-  NS_DECL_NSIDOMMUTATIONOBSERVER
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMMutationObserver)
 
-  NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
-                        uint32_t argc, jsval* argv);
+  static already_AddRefed<nsDOMMutationObserver>
+  Constructor(nsISupports* aGlobal, mozilla::dom::MutationCallback& aCb,
+              mozilla::ErrorResult& aRv);
 
-  void GetParentObject(nsIScriptGlobalObject** aParentObject)
+  virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
+                               bool* aTriedToWrap)
   {
-    if (mOwner) {
-      CallQueryInterface(mOwner, aParentObject);
-    } else {
-      *aParentObject = nullptr;
-    }
+    return mozilla::dom::MutationObserverBinding::Wrap(aCx, aScope,
+                                                       this, aTriedToWrap);
   }
 
-  static nsDOMMutationObserver* FromSupports(nsISupports* aSupports)
+  nsISupports* GetParentObject() const
   {
-    nsIDOMMutationObserver* mutationObserver =
-      static_cast<nsIDOMMutationObserver*>(aSupports);
-#ifdef DEBUG
-    {
-      nsCOMPtr<nsIDOMMutationObserver> mutationObserver_qi =
-        do_QueryInterface(aSupports);
+    return mOwner;
+  }
 
-      // If this assertion fires the QI implementation for the object in
-      // question doesn't use the nsIDOMMutationObserver pointer as the
-      // nsISupports pointer. That must be fixed, or we'll crash...
-      NS_ASSERTION(mutationObserver_qi == mutationObserver, "Uh, fix QI!");
-    }
-#endif
+  void Observe(nsINode& aTarget,
+               const mozilla::dom::MutationObserverInit& aOptions,
+               mozilla::ErrorResult& aRv);
 
-    return static_cast<nsDOMMutationObserver*>(mutationObserver);
-  }
+  void Disconnect();
+
+  void TakeRecords(nsTArray<nsRefPtr<nsDOMMutationRecord> >& aRetVal);
 
   void HandleMutation();
 
   // static methods
   static void HandleMutations()
   {
     if (sScheduledMutationObservers) {
       HandleMutationsInternal();
     }
   }
 
   static void EnterMutationHandling();
   static void LeaveMutationHandling();
 
-  static nsIDOMMutationObserver* CurrentObserver()
-  {
-    return sCurrentObserver;
-  }
-
   static void Shutdown();
 protected:
   friend class nsMutationReceiver;
   friend class nsAutoMutationBatch;
   nsMutationReceiver* GetReceiverFor(nsINode* aNode, bool aMayCreate);
   void RemoveReceiver(nsMutationReceiver* aReceiver);
 
   already_AddRefed<nsIVariant> TakeRecords();
@@ -378,39 +416,38 @@ protected:
     }
     return false;
   }
 
   static void HandleMutationsInternal();
 
   static void AddCurrentlyHandlingObserver(nsDOMMutationObserver* aObserver);
 
-  nsCOMPtr<nsIScriptContext>                         mScriptContext;
   nsCOMPtr<nsPIDOMWindow>                            mOwner;
 
   nsCOMArray<nsMutationReceiver>                     mReceivers;
   nsClassHashtable<nsISupportsHashKey,
-                   nsCOMArray<nsMutationReceiver> >  mTransientReceivers;  
+                   nsCOMArray<nsMutationReceiver> >  mTransientReceivers;
   // MutationRecords which are being constructed.
   nsAutoTArray<nsDOMMutationRecord*, 4>              mCurrentMutations;
   // MutationRecords which will be handed to the callback at the end of
   // the microtask.
-  nsCOMArray<nsDOMMutationRecord>                    mPendingMutations;
-  nsCOMPtr<nsIMutationObserverCallback>              mCallback;
+  nsTArray<nsRefPtr<nsDOMMutationRecord> >           mPendingMutations;
+  nsRefPtr<mozilla::dom::MutationCallback>           mCallback;
 
   bool                                               mWaitingForRun;
 
   uint64_t                                           mId;
 
   static uint64_t                                    sCount;
-  static nsCOMArray<nsIDOMMutationObserver>*         sScheduledMutationObservers;
-  static nsIDOMMutationObserver*                     sCurrentObserver;
+  static nsTArray<nsRefPtr<nsDOMMutationObserver> >* sScheduledMutationObservers;
+  static nsDOMMutationObserver*                      sCurrentObserver;
 
   static uint32_t                                    sMutationLevel;
-  static nsAutoTArray<nsCOMArray<nsIDOMMutationObserver>, 4>*
+  static nsAutoTArray<nsTArray<nsRefPtr<nsDOMMutationObserver> >, 4>*
                                                      sCurrentlyHandlingObservers;
 };
 
 class nsAutoMutationBatch
 {
 public:
   nsAutoMutationBatch()
   : mPreviousBatch(nullptr), mBatchTarget(nullptr), mRemovalDone(false),
@@ -532,17 +569,9 @@ private:
 inline
 nsDOMMutationObserver*
 nsMutationReceiverBase::Observer()
 {
   return mParent ?
     mParent->Observer() : static_cast<nsDOMMutationObserver*>(mObserver);
 }
 
-#define NS_DOMMUTATIONOBSERVER_CID           \
- { /* b66b9490-52f7-4f2a-b998-dbb1d59bc13e */ \
-  0xb66b9490, 0x52f7, 0x4f2a,                 \
-  { 0xb9, 0x98, 0xdb, 0xb1, 0xd5, 0x9b, 0xc1, 0x3e } }
-
-#define NS_DOMMUTATIONOBSERVER_CONTRACTID \
-  "@mozilla.org/dommutationobserver;1"
-
 #endif
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -458,17 +458,16 @@
 #include "mozilla/dom/indexedDB/IDBKeyRange.h"
 #include "mozilla/dom/indexedDB/IDBIndex.h"
 
 using mozilla::dom::indexedDB::IDBWrapperCache;
 
 #include "nsIDOMMediaQueryList.h"
 
 #include "nsDOMTouchEvent.h"
-#include "nsDOMMutationObserver.h"
 
 #include "nsWrapperCacheInlines.h"
 #include "mozilla/dom/HTMLCollectionBinding.h"
 
 #include "nsIDOMBatteryManager.h"
 #include "BatteryManager.h"
 #include "nsIDOMPowerManager.h"
 #include "nsIDOMWakeLock.h"
@@ -1588,21 +1587,16 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(MozCSSKeyframesRule, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(CSSPageRule, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MediaQueryList, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(MutationObserver, nsDOMMutationObserverSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
-                           nsIXPCScriptable::WANT_ADDPROPERTY)
-  NS_DEFINE_CLASSINFO_DATA(MutationRecord, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
 #ifdef MOZ_B2G_RIL
   NS_DEFINE_CLASSINFO_DATA(Telephony, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(TelephonyCall, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(CallEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -1684,17 +1678,16 @@ static nsDOMClassInfoData sClassInfoData
     return rv;                                                                  \
   }
 
 NS_DEFINE_CONTRACT_CTOR(FileReader, NS_FILEREADER_CONTRACTID)
 NS_DEFINE_CONTRACT_CTOR(ArchiveReader, NS_ARCHIVEREADER_CONTRACTID)
 NS_DEFINE_CONTRACT_CTOR(XSLTProcessor,
                         "@mozilla.org/document-transformer;1?type=xslt")
 NS_DEFINE_CONTRACT_CTOR(EventSource, NS_EVENTSOURCE_CONTRACTID)
-NS_DEFINE_CONTRACT_CTOR(MutationObserver, NS_DOMMUTATIONOBSERVER_CONTRACTID)
 #ifdef MOZ_SYS_MSG
 NS_DEFINE_CONTRACT_CTOR(MozActivity, NS_DOMACTIVITY_CONTRACTID)
 #endif
 
 #undef NS_DEFINE_CONTRACT_CTOR
 
 #define NS_DEFINE_EVENT_CTOR(_class)                        \
   static nsresult                                           \
@@ -1746,17 +1739,16 @@ static const nsConstructorFuncMapData kC
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(_event_interface)
 #include "GeneratedEvents.h"
 #undef MOZ_GENERATED_EVENT_LIST
   NS_DEFINE_CONSTRUCTOR_FUNC_DATA(MozSmsFilter, sms::SmsFilter::NewSmsFilter)
   NS_DEFINE_CONSTRUCTOR_FUNC_DATA(FileReader, FileReaderCtor)
   NS_DEFINE_CONSTRUCTOR_FUNC_DATA(ArchiveReader, ArchiveReaderCtor)
   NS_DEFINE_CONSTRUCTOR_FUNC_DATA(XSLTProcessor, XSLTProcessorCtor)
   NS_DEFINE_CONSTRUCTOR_FUNC_DATA(EventSource, EventSourceCtor)
-  NS_DEFINE_CONSTRUCTOR_FUNC_DATA(MutationObserver, MutationObserverCtor)
 #ifdef MOZ_SYS_MSG
   NS_DEFINE_CONSTRUCTOR_FUNC_DATA(MozActivity, MozActivityCtor)
 #endif
 };
 #undef NS_DEFINE_CONSTRUCTOR_FUNC_DATA
 #undef NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA
 
 nsIXPConnect *nsDOMClassInfo::sXPConnect = nullptr;
@@ -2363,20 +2355,16 @@ nsDOMClassInfo::Init()
   NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
 
   nsresult rv = CallGetService(nsIXPConnect::GetCID(), &sXPConnect);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIXPCFunctionThisTranslator> elt = new nsEventListenerThisTranslator();
   sXPConnect->SetFunctionThisTranslator(NS_GET_IID(nsIDOMEventListener), elt);
 
-  nsCOMPtr<nsIXPCFunctionThisTranslator> mctl = new nsMutationCallbackThisTranslator();
-  sXPConnect->SetFunctionThisTranslator(NS_GET_IID(nsIMutationObserverCallback),
-                                        mctl);
-
   nsCOMPtr<nsIScriptSecurityManager> sm =
     do_GetService("@mozilla.org/scriptsecuritymanager;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   sSecMan = sm;
   NS_ADDREF(sSecMan);
 
   nsCOMPtr<nsIThreadJSContextStack> stack =
@@ -4234,24 +4222,16 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(CSSPageRule, nsIDOMCSSPageRule)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSPageRule)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(MediaQueryList, nsIDOMMediaQueryList)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMediaQueryList)
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(MutationObserver, nsIDOMMutationObserver)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMMutationObserver)
-  DOM_CLASSINFO_MAP_END
-
-  DOM_CLASSINFO_MAP_BEGIN(MutationRecord, nsIDOMMutationRecord)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMMutationRecord)
-  DOM_CLASSINFO_MAP_END
-
 #ifdef MOZ_B2G_RIL
   DOM_CLASSINFO_MAP_BEGIN(MozWifiStatusChangeEvent, nsIDOMMozWifiStatusChangeEvent)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozWifiStatusChangeEvent)
      DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(MozWifiConnectionInfoEvent, nsIDOMMozWifiConnectionInfoEvent)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozWifiConnectionInfoEvent)
@@ -7838,47 +7818,16 @@ nsEventTargetSH::AddProperty(nsIXPConnec
 void
 nsEventTargetSH::PreserveWrapper(nsISupports *aNative)
 {
   nsDOMEventTargetHelper *target =
     nsDOMEventTargetHelper::FromSupports(aNative);
   nsContentUtils::PreserveWrapper(aNative, target);
 }
 
-// MutationObserver helper
-
-NS_IMETHODIMP
-nsDOMMutationObserverSH::PreCreate(nsISupports* aNativeObj, JSContext* aCx,
-                                   JSObject* aGlobalObj, JSObject** aParentObj)
-{
-  nsDOMMutationObserver* mutationObserver =
-    nsDOMMutationObserver::FromSupports(aNativeObj);
-  nsCOMPtr<nsIScriptGlobalObject> native_parent;
-  mutationObserver->GetParentObject(getter_AddRefs(native_parent));
-  *aParentObj = native_parent ? native_parent->GetGlobalJSObject() : aGlobalObj;
-  return *aParentObj ? NS_OK : NS_ERROR_FAILURE;
-}
-
-NS_IMETHODIMP
-nsDOMMutationObserverSH::AddProperty(nsIXPConnectWrappedNative* aWrapper,
-                                     JSContext* aCx, JSObject* aObj, jsid aId,
-                                     jsval* aVp, bool* aRetVal)
-{
-  nsDOMMutationObserverSH::PreserveWrapper(GetNative(aWrapper, aObj));
-  return NS_OK;
-}
-
-void
-nsDOMMutationObserverSH::PreserveWrapper(nsISupports* aNative)
-{
-  nsDOMMutationObserver* mutationObserver =
-    nsDOMMutationObserver::FromSupports(aNative);
-  nsContentUtils::PreserveWrapper(aNative, mutationObserver);
-}
-
 // IDBFactory helper
 
 /* static */
 template<nsresult (*func)(JSContext *, unsigned, jsval *, bool), bool aDelete>
 JSBool
 IDBFNativeShim(JSContext *cx, unsigned argc, jsval *vp)
 {
   nsresult rv = (*func)(cx, argc, vp, aDelete);
@@ -10246,32 +10195,16 @@ nsEventListenerThisTranslator::Translate
   NS_ENSURE_TRUE(event, NS_ERROR_UNEXPECTED);
 
   nsCOMPtr<nsIDOMEventTarget> target;
   event->GetCurrentTarget(getter_AddRefs(target));
   target.forget(_retval);
   return NS_OK;
 }
 
-NS_INTERFACE_MAP_BEGIN(nsMutationCallbackThisTranslator)
-  NS_INTERFACE_MAP_ENTRY(nsIXPCFunctionThisTranslator)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_ADDREF(nsMutationCallbackThisTranslator)
-NS_IMPL_RELEASE(nsMutationCallbackThisTranslator)
-
-NS_IMETHODIMP
-nsMutationCallbackThisTranslator::TranslateThis(nsISupports *aInitialThis,
-                                                nsISupports **_retval)
-{
-  NS_IF_ADDREF(*_retval = nsDOMMutationObserver::CurrentObserver());
-  return NS_OK;
-}
-
 NS_IMETHODIMP
 nsDOMConstructorSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
                               JSObject *globalObj, JSObject **parentObj)
 {
   nsDOMConstructor *wrapped = static_cast<nsDOMConstructor *>(nativeObj);
 
 #ifdef DEBUG
   {
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -332,40 +332,16 @@ public:
   virtual void PreserveWrapper(nsISupports *aNative);
 
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   {
     return new nsEventTargetSH(aData);
   }
 };
 
-class nsDOMMutationObserverSH : public nsDOMGenericSH
-{
-protected:
-  nsDOMMutationObserverSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
-  {
-  }
-
-  virtual ~nsDOMMutationObserverSH()
-  {
-  }
-public:
-  NS_IMETHOD PreCreate(nsISupports* aNativeObj, JSContext* aCx,
-                       JSObject* aGlobalObj, JSObject** aParentObj);
-  NS_IMETHOD AddProperty(nsIXPConnectWrappedNative* aWrapper, JSContext* aCx,
-                         JSObject* aObj, jsid aId, jsval* aVp, bool* aRetval);
-
-  virtual void PreserveWrapper(nsISupports* aNative);
-
-  static nsIClassInfo* doCreate(nsDOMClassInfoData* aData)
-  {
-    return new nsDOMMutationObserverSH(aData);
-  }
-};
-
 // Window scriptable helper
 
 class nsWindowSH : public nsDOMGenericSH
 {
 protected:
   nsWindowSH(nsDOMClassInfoData *aData) : nsDOMGenericSH(aData)
   {
   }
@@ -1227,34 +1203,16 @@ public:
 
   // nsISupports
   NS_DECL_ISUPPORTS
 
   // nsIXPCFunctionThisTranslator
   NS_DECL_NSIXPCFUNCTIONTHISTRANSLATOR
 };
 
-class nsMutationCallbackThisTranslator : public nsIXPCFunctionThisTranslator
-{
-public:
-  nsMutationCallbackThisTranslator()
-  {
-  }
-
-  virtual ~nsMutationCallbackThisTranslator()
-  {
-  }
-
-  // nsISupports
-  NS_DECL_ISUPPORTS
-
-  // nsIXPCFunctionThisTranslator
-  NS_DECL_NSIXPCFUNCTIONTHISTRANSLATOR
-};
-
 class nsDOMConstructorSH : public nsDOMGenericSH
 {
 protected:
   nsDOMConstructorSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
   {
   }
 
 public:
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -458,19 +458,16 @@ DOMCI_CLASS(TouchEvent)
 
 DOMCI_CLASS(MozCSSKeyframeRule)
 DOMCI_CLASS(MozCSSKeyframesRule)
 
 DOMCI_CLASS(CSSPageRule)
 
 DOMCI_CLASS(MediaQueryList)
 
-DOMCI_CLASS(MutationObserver)
-DOMCI_CLASS(MutationRecord)
-
 #ifdef MOZ_B2G_RIL
 DOMCI_CLASS(Telephony)
 DOMCI_CLASS(TelephonyCall)
 DOMCI_CLASS(CallEvent)
 DOMCI_CLASS(MozVoicemail)
 DOMCI_CLASS(MozVoicemailEvent)
 DOMCI_CLASS(MozIccManager)
 DOMCI_CLASS(MozStkCommandEvent)
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -342,16 +342,28 @@ DOMInterfaces = {
 {
     'nativeType': 'nsIChannel',
     'notflattened': True
 },
 {
     'workers': True,
 }],
 
+ 
+'MutationObserver': {
+    'nativeType': 'nsDOMMutationObserver',
+},
+
+'MutationRecord': {
+    'nativeType': 'nsDOMMutationRecord',
+    'headerFile': 'nsDOMMutationObserver.h',
+    'resultNotAddRefed': [ 'target', 'addedNodes', 'removedNodes',
+                           'previousSibling', 'nextSibling' ]
+},
+
 'Node': {
     'nativeType': 'nsINode',
     'hasXPConnectImpls': True,
     'hasInstanceInterface': 'nsIDOMNode',
     'resultNotAddRefed': [ 'ownerDocument', 'parentNode', 'parentElement',
                            'childNodes', 'firstChild', 'lastChild',
                            'previousSibling', 'nextSibling', 'insertBefore',
                            'appendChild', 'replaceChild', 'removeChild',
--- a/dom/imptests/failures/webapps/DOMCore/tests/approved/test_interfaces.html.json
+++ b/dom/imptests/failures/webapps/DOMCore/tests/approved/test_interfaces.html.json
@@ -61,36 +61,20 @@
   "Event interface: new CustomEvent(\"foo\") must inherit property \"timeStamp\" with the proper type (14)": true,
   "Event interface: calling initEvent(DOMString,boolean,boolean) on new CustomEvent(\"foo\") with too few arguments must throw TypeError": true,
   "EventTarget interface: operation addEventListener(DOMString,EventListener,boolean)": true,
   "EventTarget interface: operation removeEventListener(DOMString,EventListener,boolean)": true,
   "EventListener interface: existence and properties of interface object": true,
   "EventListener interface: existence and properties of interface prototype object": true,
   "EventListener interface: existence and properties of interface prototype object's \"constructor\" property": true,
   "EventListener interface: operation handleEvent(Event)": true,
-  "MutationObserver interface: existence and properties of interface object": true,
-  "MutationObserver interface constructor": true,
-  "MutationObserver interface: existence and properties of interface prototype object": true,
-  "MutationObserver interface: existence and properties of interface prototype object's \"constructor\" property": true,
   "MutationCallback interface: existence and properties of interface object": true,
   "MutationCallback interface: existence and properties of interface prototype object": true,
   "MutationCallback interface: existence and properties of interface prototype object's \"constructor\" property": true,
   "MutationCallback interface: operation handleEvent(MutationRecord,MutationObserver)": true,
-  "MutationRecord interface: existence and properties of interface object": true,
-  "MutationRecord interface: existence and properties of interface prototype object": true,
-  "MutationRecord interface: existence and properties of interface prototype object's \"constructor\" property": true,
-  "MutationRecord interface: attribute type": true,
-  "MutationRecord interface: attribute target": true,
-  "MutationRecord interface: attribute addedNodes": true,
-  "MutationRecord interface: attribute removedNodes": true,
-  "MutationRecord interface: attribute previousSibling": true,
-  "MutationRecord interface: attribute nextSibling": true,
-  "MutationRecord interface: attribute attributeName": true,
-  "MutationRecord interface: attribute attributeNamespace": true,
-  "MutationRecord interface: attribute oldValue": true,
   "Node interface: operation cloneNode(boolean)": true,
   "Document interface: existence and properties of interface object": true,
   "Document interface constructor": true,
   "Document interface: existence and properties of interface prototype object": true,
   "Document interface: existence and properties of interface prototype object's \"constructor\" property": true,
   "Document interface: attribute implementation": true,
   "Document interface: attribute URL": true,
   "Document interface: attribute documentURI": true,
--- a/dom/interfaces/core/Makefile.in
+++ b/dom/interfaces/core/Makefile.in
@@ -35,16 +35,15 @@ XPIDLSRCS =                             
 	nsIDOMDOMStringList.idl			\
 	nsIDOMXMLDocument.idl			\
 	nsIDOMUserDataHandler.idl		\
 	nsIDOMNSEditableElement.idl		\
 	nsIDOMNodeSelector.idl			\
 	nsIDOMDOMTokenList.idl			\
 	nsIDOMDOMSettableTokenList.idl	\
 	nsIInlineEventHandlers.idl              \
-	nsIDOMMutationObserver.idl              \
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 XPIDL_FLAGS += \
   -I$(topsrcdir)/dom/interfaces/base \
   $(NULL)
deleted file mode 100644
--- a/dom/interfaces/core/nsIDOMMutationObserver.idl
+++ /dev/null
@@ -1,72 +0,0 @@
-/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
-/* 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 "domstubs.idl"
-interface nsIVariant;
-
-[scriptable, uuid(2fa4716f-405a-449b-954b-ae570c170364)]
-interface nsIDOMMutationRecord : nsISupports
-{
-  /**
-   * type is on of childList, attribute, characterData.
-   */
-  readonly attribute DOMString       type;
-  
-  /**
-   * Target of the change.
-   * If an attribute is changed, target is the element,
-   * if an element is added or removed, target is the node
-   * which was added or removed.
-   * If text is changed, target is the CharacterData node which was changed.
-   */
-  readonly attribute nsIDOMNode      target;
-
-  readonly attribute nsIDOMNodeList  addedNodes;
-  readonly attribute nsIDOMNodeList  removedNodes;
-
-  readonly attribute nsIDOMNode      previousSibling;
-  readonly attribute nsIDOMNode      nextSibling;
-  
-  /**
-   * The name of the attribute which was changed, or null.
-   */
-  readonly attribute DOMString       attributeName;
-  readonly attribute DOMString       attributeNamespace;
-
-  /*
-   * The previous value of the attribute or CharacterData node, or null.
-   *
-   * If a new attribute is added, or attribute values aren't reported,
-   * prevValue is null.
-   */
-  readonly attribute DOMString       oldValue;
-};
-
-dictionary MutationObserverInit
-{
-  boolean childList;
-  boolean attributes;
-  boolean characterData;
-  boolean subtree;
-  boolean attributeOldValue;
-  boolean characterDataOldValue;
-  jsval   attributeFilter; // DOMString[]
-};
-
-//[Constructor(in nsIMutationCallback aDoneCallback)]
-[scriptable, builtinclass, uuid(573105b5-d64e-468f-959f-87eebf93913e)]
-interface nsIDOMMutationObserver : nsISupports
-{
-  [implicit_jscontext]
-  void observe(in nsIDOMNode aTarget, in jsval aOptions);
-  void disconnect();
-  nsIVariant takeRecords();
-};
-
-[scriptable, function, uuid(5b52ce60-2210-42f0-842b-7f9f03d62f85)]
-interface nsIMutationObserverCallback : nsISupports
-{
-  void handleMutations(in nsIVariant aRecords, in nsIDOMMutationObserver aObserver);
-};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/MutationObserver.webidl
@@ -0,0 +1,42 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * The origin of this IDL file is
+ * http://dom.spec.whatwg.org
+ */
+
+interface MutationRecord {
+  readonly attribute DOMString type;
+  // .target is not nullable per the spec, but in order to prevent crashes,
+  // if there are GC/CC bugs in Gecko, we let the property to be null.
+  readonly attribute Node? target;
+  readonly attribute NodeList addedNodes;
+  readonly attribute NodeList removedNodes;
+  readonly attribute Node? previousSibling;
+  readonly attribute Node? nextSibling;
+  readonly attribute DOMString? attributeName;
+  readonly attribute DOMString? attributeNamespace;
+  readonly attribute DOMString? oldValue;
+};
+
+[Constructor(MutationCallback mutationCallback)]
+interface MutationObserver {
+  [Throws]
+  void observe(Node target, optional MutationObserverInit options);
+  void disconnect();
+  sequence<MutationRecord> takeRecords();
+};
+
+callback MutationCallback = void (sequence<MutationRecord> mutations, MutationObserver observer);
+
+dictionary MutationObserverInit {
+  boolean childList = false;
+  boolean attributes = false;
+  boolean characterData = false;
+  boolean subtree = false;
+  boolean attributeOldValue = false;
+  boolean characterDataOldValue = false;
+  sequence<DOMString> attributeFilter;
+};
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -43,16 +43,17 @@ webidl_files = \
   FormData.webidl \
   Function.webidl \
   GainNode.webidl \
   HTMLCollection.webidl \
   HTMLElement.webidl \
   HTMLOptionsCollection.webidl \
   HTMLPropertiesCollection.webidl \
   ImageData.webidl \
+  MutationObserver.webidl \
   Node.webidl \
   NodeFilter.webidl \
   NodeList.webidl \
   PaintRequestList.webidl \
   PannerNode.webidl \
   Performance.webidl \
   PerformanceNavigation.webidl \
   PerformanceTiming.webidl \
--- a/js/xpconnect/src/dictionary_helper_gen.conf
+++ b/js/xpconnect/src/dictionary_helper_gen.conf
@@ -5,17 +5,16 @@
 # Dictionary interface name, interface file name
 dictionaries = [
      [ 'EventInit', 'nsIDOMEvent.idl' ],
      [ 'UIEventInit', 'nsIDOMUIEvent.idl' ],
      [ 'MouseEventInit', 'nsIDOMMouseEvent.idl' ],
      [ 'WheelEventInit', 'nsIDOMWheelEvent.idl' ],
      [ 'IDBObjectStoreParameters', 'nsIIDBDatabase.idl' ],
      [ 'IDBIndexParameters', 'nsIIDBObjectStore.idl' ],
-     [ 'MutationObserverInit', 'nsIDOMMutationObserver.idl' ],
      [ 'GeoPositionOptions', 'nsIDOMGeoGeolocation.idl' ],
      [ 'DOMFileMetadataParameters', 'nsIDOMLockedFile.idl' ],
      [ 'XMLHttpRequestParameters', 'nsIXMLHttpRequest.idl' ],
      [ 'DeviceStorageEnumerationParameters', 'nsIDOMDeviceStorage.idl' ],
      [ 'CameraSize', 'nsIDOMCameraManager.idl' ],
      [ 'CameraRegion', 'nsIDOMCameraManager.idl' ],
      [ 'CameraPosition', 'nsIDOMCameraManager.idl' ],
      [ 'CameraSelector', 'nsIDOMCameraManager.idl' ],
--- a/js/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/xpconnect/src/dom_quickstubs.qsconf
@@ -97,17 +97,16 @@ members = [
     'nsIDOMDocument.URL',
     'nsIDOMNamedNodeMap.item',
     'nsIDOMNamedNodeMap.length',
     'nsIDOMNodeSelector.querySelector',
     'nsIDOMNodeSelector.querySelectorAll',
     'nsIDOMText.splitText',
     'nsIDOMDOMStringList.*',
     'nsIDOMXULDocument.getBoxObjectFor',
-    'nsIDOMMutationRecord.*',
 
     # dom/interfaces/css
     'nsIDOMElementCSSInlineStyle.*',
     'nsIDOMRect.*',
 
     # dom/interfaces/events
     'nsIDOMEventTarget.addEventListener',
     'nsIDOMEventTarget.removeEventListener',
@@ -393,18 +392,16 @@ irregularFilenames = {
 
     'nsIDOMBlob': 'nsIDOMFile',
 
     'nsIIndexedDatabaseUsageCallback': 'nsIIndexedDatabaseManager',
 
     'nsIDOMTouch': 'nsIDOMTouchEvent',
     'nsIDOMTouchList': 'nsIDOMTouchEvent',
 
-    'nsIDOMMutationRecord': 'nsIDOMMutationObserver',
-
     'nsITelephoneCallback': 'nsITelephone',
     }
 
 customIncludes = [
     'nsINode.h',
     'nsIContent.h',
     'nsIDocument.h',
     'nsCSSPropertiesQS.h',
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -125,18 +125,16 @@ using mozilla::system::nsVolumeService;
 #ifdef MOZ_B2G_FM
 #include "FMRadio.h"
 using mozilla::dom::fm::FMRadio;
 #endif
 
 #include "AudioChannelAgent.h"
 using mozilla::dom::AudioChannelAgent;
 
-#include "nsDOMMutationObserver.h"
-
 // Editor stuff
 #include "nsEditorCID.h"
 #include "nsEditor.h"
 #include "nsPlaintextEditor.h"
 #include "nsEditorController.h" //CID
 
 #include "nsHTMLEditor.h"
 #include "nsTextServicesDocument.h"
@@ -290,17 +288,16 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR
 #ifdef MOZ_B2G_RIL
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(SystemWorkerManager,
                                          SystemWorkerManager::FactoryCreate)
 #endif
 #ifdef MOZ_B2G_BT
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(BluetoothService,
                                          BluetoothService::FactoryCreate)
 #endif
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMMutationObserver)
 
 #ifdef MOZ_WIDGET_GONK
 NS_GENERIC_FACTORY_CONSTRUCTOR(AudioManager)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsVolumeService)
 #endif
 
 #ifdef MOZ_B2G_FM
 NS_GENERIC_FACTORY_CONSTRUCTOR(FMRadio)
@@ -821,17 +818,16 @@ NS_DEFINE_NAMED_CID(NS_CHILDPROCESSMESSA
 NS_DEFINE_NAMED_CID(NSCHANNELPOLICY_CID);
 NS_DEFINE_NAMED_CID(NS_SCRIPTSECURITYMANAGER_CID);
 NS_DEFINE_NAMED_CID(NS_PRINCIPAL_CID);
 NS_DEFINE_NAMED_CID(NS_SYSTEMPRINCIPAL_CID);
 NS_DEFINE_NAMED_CID(NS_NULLPRINCIPAL_CID);
 NS_DEFINE_NAMED_CID(NS_SECURITYNAMESET_CID);
 NS_DEFINE_NAMED_CID(THIRDPARTYUTIL_CID);
 NS_DEFINE_NAMED_CID(NS_STRUCTUREDCLONECONTAINER_CID);
-NS_DEFINE_NAMED_CID(NS_DOMMUTATIONOBSERVER_CID);
 NS_DEFINE_NAMED_CID(NS_DEVICE_SENSORS_CID);
 
 #ifndef MOZ_WIDGET_GONK
 #if defined(ANDROID) || defined(MOZ_PLATFORM_MAEMO)
 NS_DEFINE_NAMED_CID(NS_HAPTICFEEDBACK_CID);
 #endif
 #endif
 NS_DEFINE_NAMED_CID(SMS_SERVICE_CID);
@@ -1108,17 +1104,16 @@ static const mozilla::Module::CIDEntry k
   { &kNS_DEVICE_SENSORS_CID, false, NULL, nsDeviceSensorsConstructor },
 #ifndef MOZ_WIDGET_GONK
 #if defined(ANDROID) || defined(MOZ_PLATFORM_MAEMO)
   { &kNS_HAPTICFEEDBACK_CID, false, NULL, nsHapticFeedbackConstructor },
 #endif
 #endif
   { &kTHIRDPARTYUTIL_CID, false, NULL, ThirdPartyUtilConstructor },
   { &kNS_STRUCTUREDCLONECONTAINER_CID, false, NULL, nsStructuredCloneContainerConstructor },
-  { &kNS_DOMMUTATIONOBSERVER_CID, false, NULL, nsDOMMutationObserverConstructor },
   { &kSMS_SERVICE_CID, false, NULL, nsISmsServiceConstructor },
   { &kSMS_DATABASE_SERVICE_CID, false, NULL, nsISmsDatabaseServiceConstructor },
   { &kNS_POWERMANAGERSERVICE_CID, false, NULL, nsIPowerManagerServiceConstructor },
   { &kOSFILECONSTANTSSERVICE_CID, true, NULL, OSFileConstantsServiceConstructor },
   { &kNS_ALARMHALSERVICE_CID, false, NULL, nsIAlarmHalServiceConstructor },
   { &kTCPSOCKETCHILD_CID, false, NULL, TCPSocketChildConstructor },
   { &kNS_TIMESERVICE_CID, false, NULL, nsITimeServiceConstructor },
 #ifdef MOZ_WIDGET_GONK
@@ -1252,17 +1247,16 @@ static const mozilla::Module::ContractID
   { NS_DEVICE_SENSORS_CONTRACTID, &kNS_DEVICE_SENSORS_CID },
 #ifndef MOZ_WIDGET_GONK
 #if defined(ANDROID) || defined(MOZ_PLATFORM_MAEMO)
   { "@mozilla.org/widget/hapticfeedback;1", &kNS_HAPTICFEEDBACK_CID },
 #endif
 #endif
   { THIRDPARTYUTIL_CONTRACTID, &kTHIRDPARTYUTIL_CID },
   { NS_STRUCTUREDCLONECONTAINER_CONTRACTID, &kNS_STRUCTUREDCLONECONTAINER_CID },
-  { NS_DOMMUTATIONOBSERVER_CONTRACTID, &kNS_DOMMUTATIONOBSERVER_CID },
   { SMS_SERVICE_CONTRACTID, &kSMS_SERVICE_CID },
   { SMS_DATABASE_SERVICE_CONTRACTID, &kSMS_DATABASE_SERVICE_CID },
   { POWERMANAGERSERVICE_CONTRACTID, &kNS_POWERMANAGERSERVICE_CID },
   { OSFILECONSTANTSSERVICE_CONTRACTID, &kOSFILECONSTANTSSERVICE_CID },
   { ALARMHALSERVICE_CONTRACTID, &kNS_ALARMHALSERVICE_CID },
   { "@mozilla.org/tcp-socket-child;1", &kTCPSOCKETCHILD_CID },
   { TIMESERVICE_CONTRACTID, &kNS_TIMESERVICE_CID },
 #ifdef MOZ_WIDGET_GONK