Merge mozilla-central into services-central
authorGregory Szorc <gps@mozilla.com>
Tue, 19 Mar 2013 16:37:52 -0700
changeset 135841 8156df33b757083912751c01a13f460ee282b536
parent 135840 59e0077b197573aef92e27088354a622ec3008c8 (current diff)
parent 135835 126563fd3ba10dc52db44b92d051334d53b9cf2b (diff)
child 135842 3b49881ae41dff42e70c9302ad4b700a92359d02
child 135920 520b8e382b8bc4624c27d488b50bc0d5cd2f30a8
push id2452
push userlsblakk@mozilla.com
push dateMon, 13 May 2013 16:59:38 +0000
treeherdermozilla-beta@d4b152d29d8d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone22.0a1
first release with
nightly linux32
8156df33b757 / 22.0a1 / 20130320031103 / files
nightly linux64
8156df33b757 / 22.0a1 / 20130320031103 / files
nightly mac
8156df33b757 / 22.0a1 / 20130320031103 / files
nightly win32
8156df33b757 / 22.0a1 / 20130320031103 / files
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
Merge mozilla-central into services-central
content/html/content/public/nsHTMLAudioElement.h
content/html/content/public/nsHTMLMediaElement.h
content/html/content/public/nsHTMLVideoElement.h
content/html/content/src/nsHTMLAudioElement.cpp
content/html/content/src/nsHTMLMediaElement.cpp
content/html/content/src/nsHTMLVideoElement.cpp
js/src/tests/ecma_2/String/replace-001.js
--- a/b2g/chrome/content/forms.js
+++ b/b2g/chrome/content/forms.js
@@ -502,16 +502,18 @@ function isContentEditable(element) {
     return true;
 
   return element.ownerDocument && element.ownerDocument.designMode == "on";
 }
 
 function getJSON(element) {
   let type = element.type || "";
   let value = element.value || "";
+  let max = element.max || "";
+  let min = element.min || "";
 
   // Treat contenteditble element as a special text area field
   if (isContentEditable(element)) {
     type = "textarea";
     value = getContentEditableText(element);
   }
 
   // Until the input type=date/datetime/range have been implemented
@@ -545,17 +547,19 @@ function getJSON(element) {
   let range = getSelectionRange(element);
 
   return {
     "type": type.toLowerCase(),
     "choices": getListForElement(element),
     "value": value,
     "inputmode": inputmode,
     "selectionStart": range[0],
-    "selectionEnd": range[1]
+    "selectionEnd": range[1],
+    "max": max,
+    "min": min
   };
 }
 
 function getListForElement(element) {
   if (!(element instanceof HTMLSelectElement))
     return null;
 
   let optionIndex = 0;
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -147,16 +147,17 @@ endif
                  browser_bug710878.js \
                  browser_bug719271.js \
                  browser_bug724239.js \
                  browser_bug735471.js \
                  browser_bug743421.js \
                  browser_bug749738.js \
                  browser_bug763468_perwindowpb.js \
                  browser_bug767836_perwindowpb.js \
+                 browser_bug771331.js \
                  browser_bug783614.js \
                  browser_bug797677.js \
                  browser_bug816527.js \
                  browser_bug817947.js \
                  browser_bug822367.js \
                  browser_bug832435.js \
                  browser_canonizeURL.js \
                  browser_customize.js \
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_bug771331.js
@@ -0,0 +1,82 @@
+const HTML_NS = "http://www.w3.org/1999/xhtml";
+
+const INPUT_ID = "input1";
+const FORM1_ID = "form1";
+const FORM2_ID = "form2";
+const CHANGE_INPUT_ID = "input2";
+
+function test() {
+  waitForExplicitFinish();
+  let tab = gBrowser.selectedTab =
+	gBrowser.addTab("data:text/html;charset=utf-8," +
+			"<html><body>" +
+			"<form id='" + FORM1_ID + "'><input id='" + CHANGE_INPUT_ID + "'></form>" +
+			"<form id='" + FORM2_ID + "'></form>" +
+			"</body></html>");
+  tab.linkedBrowser.addEventListener("load", tabLoad, true);
+}
+
+function unexpectedContentEvent(evt) {
+  ok(false, "Received a " + evt.type + " event on content");
+}
+
+var gDoc = null;
+
+function tabLoad() {
+  let tab = gBrowser.selectedTab;
+  tab.linkedBrowser.removeEventListener("load", tabLoad, true);
+  gDoc = gBrowser.selectedBrowser.contentDocument;
+  // These events shouldn't escape to content.
+  gDoc.addEventListener("DOMFormHasPassword", unexpectedContentEvent, false);
+  gDoc.defaultView.setTimeout(test_inputAdd, 0);
+}
+
+function test_inputAdd() {
+  gBrowser.addEventListener("DOMFormHasPassword", test_inputAddHandler, false);
+  let input = gDoc.createElementNS(HTML_NS, "input");
+  input.setAttribute("type", "password");
+  input.setAttribute("id", INPUT_ID);
+  input.setAttribute("data-test", "unique-attribute");
+  gDoc.getElementById(FORM1_ID).appendChild(input);
+  info("Done appending the input element");
+}
+
+function test_inputAddHandler(evt) {
+  gBrowser.removeEventListener(evt.type, test_inputAddHandler, false);
+  is(evt.target.id, FORM1_ID,
+     evt.type + " event targets correct form element (added password element)");
+  gDoc.defaultView.setTimeout(test_inputChangeForm, 0);
+}
+
+function test_inputChangeForm() {
+  gBrowser.addEventListener("DOMFormHasPassword", test_inputChangeFormHandler, false);
+  let input = gDoc.getElementById(INPUT_ID);
+  input.setAttribute("form", FORM2_ID);
+}
+
+function test_inputChangeFormHandler(evt) {
+  gBrowser.removeEventListener(evt.type, test_inputChangeFormHandler, false);
+  is(evt.target.id, FORM2_ID,
+     evt.type + " event targets correct form element (changed form)");
+  gDoc.defaultView.setTimeout(test_inputChangesType, 0);
+}
+
+function test_inputChangesType() {
+  gBrowser.addEventListener("DOMFormHasPassword", test_inputChangesTypeHandler, false);
+  let input = gDoc.getElementById(CHANGE_INPUT_ID);
+  input.setAttribute("type", "password");
+}
+
+function test_inputChangesTypeHandler(evt) {
+  gBrowser.removeEventListener(evt.type, test_inputChangesTypeHandler, false);
+  is(evt.target.id, FORM1_ID,
+     evt.type + " event targets correct form element (changed type)");
+  gDoc.defaultView.setTimeout(completeTest, 0);
+}
+
+function completeTest() {
+  ok(true, "Test completed");
+  gDoc.removeEventListener("DOMFormHasPassword", unexpectedContentEvent, false);
+  gBrowser.removeCurrentTab();
+  finish();
+}
--- a/browser/config/mozconfigs/macosx-universal/nightly
+++ b/browser/config/mozconfigs/macosx-universal/nightly
@@ -4,16 +4,18 @@
 ac_add_options --enable-application=browser
 
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-codesighs
 ac_add_options --disable-install-strip
 ac_add_options --enable-signmar
 ac_add_options --enable-profiling
+ac_add_options --enable-instruments
+ac_add_options --enable-dtrace
 
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
--- a/browser/metro/base/content/bindings/grid.xml
+++ b/browser/metro/base/content/bindings/grid.xml
@@ -509,21 +509,16 @@
       <property name="backgroundimage"
                 onset="this._backgroundimage = val; this.setBackgroundImage();"
                 onget="return this._backgroundimage;" />
       <property name="selected"
                 onget="return this.getAttribute('selected') == 'true';" />
 
       <constructor>
         <![CDATA[
-          // Bindings don't get bound until the item is displayed,
-          // so we have to reset the background color/image when we get
-          // created.
-          this.setColor();
-          this.setBackgroundImage();
         ]]>
       </constructor>
 
       <property name="control">
         <getter><![CDATA[
           var parent = this.parentNode;
           while (parent) {
             if (parent instanceof Components.interfaces.nsIDOMXULSelectControlElement)
@@ -532,30 +527,30 @@
           }
           return null;
         ]]></getter>
       </property>
 
       <method name="setColor">
         <body>
           <![CDATA[
-            if (this.color != undefined) {
+            if (this._color != undefined) {
               this._box.parentNode.setAttribute("customColorPresent", "true");
               this._box.style.backgroundColor = this.color;
             } else {
               this._box.parentNode.removeAttribute("customColorPresent");
             }
           ]]>
         </body>
       </method>
 
       <method name="setBackgroundImage">
         <body>
           <![CDATA[
-            if (this.backgroundImage != undefined) {
+            if (this._backgroundImage != undefined) {
               this._box.parentNode.setAttribute("customImagePresent", "true");
               this._box.style.backgroundImage = this.backgroundImage;
             } else {
               this._box.parentNode.removeAttribute("customImagePresent");
               this._box.style.removeProperty("background-image");
             }
           ]]>
         </body>
--- a/browser/metro/base/content/bookmarks.js
+++ b/browser/metro/base/content/bookmarks.js
@@ -220,16 +220,19 @@ BookmarksView.prototype = {
   _gotIcon: function _gotIcon(aBookmarkId, aItem, aIconUri) {
     aItem.setAttribute("iconURI", aIconUri ? aIconUri.spec : "");
 
     let color = Bookmarks.getFaveIconPrimaryColor(aBookmarkId);
     if (color) {
       aItem.color = color;
       return;
     }
+    if (!aIconUri) {
+      return;
+    }
     let url = Services.io.newURI(aIconUri.spec.replace("moz-anno:favicon:",""), "", null)
     let ca = Components.classes["@mozilla.org/places/colorAnalyzer;1"]
                        .getService(Components.interfaces.mozIColorAnalyzer);
     ca.findRepresentativeColor(url, function (success, color) {
       let colorStr = Bookmarks.fixupColorFormat(color);
       Bookmarks.setFaveIconPrimaryColor(aBookmarkId, colorStr);
       aItem.color = colorStr;
     }, this);
--- a/browser/metro/base/content/browser-scripts.js
+++ b/browser/metro/base/content/browser-scripts.js
@@ -113,17 +113,16 @@ let ScriptContexts = {};
   ["PreferencesPanelView", "chrome://browser/content/preferences.js"],
   ["BookmarksStartView", "chrome://browser/content/bookmarks.js"],
   ["HistoryView", "chrome://browser/content/history.js"],
   ["HistoryStartView", "chrome://browser/content/history.js"],
   ["HistoryPanelView", "chrome://browser/content/history.js"],
   ["TopSitesView", "chrome://browser/content/TopSites.js"],
   ["TopSitesSnappedView", "chrome://browser/content/TopSites.js"],
   ["TopSitesStartView", "chrome://browser/content/TopSites.js"],
-  ["InputSourceHelper", "chrome://browser/content/input.js"],
   ["Sanitizer", "chrome://browser/content/sanitize.js"],
   ["SSLExceptions", "chrome://browser/content/exceptions.js"],
 #ifdef MOZ_SERVICES_SYNC
   ["WeaveGlue", "chrome://browser/content/sync.js"],
   ["SyncPairDevice", "chrome://browser/content/sync.js"],
   ["RemoteTabsView", "chrome://browser/content/RemoteTabs.js"],
   ["RemoteTabsPanelView", "chrome://browser/content/RemoteTabs.js"],
   ["RemoteTabsStartView", "chrome://browser/content/RemoteTabs.js"],
--- a/browser/metro/base/content/browser-ui.js
+++ b/browser/metro/base/content/browser-ui.js
@@ -1604,17 +1604,17 @@ var DialogUI = {
     xhr.open("GET", aSrc, false);
     xhr.overrideMimeType("text/xml");
     xhr.send(null);
     if (!xhr.responseXML)
       return null;
 
     let currentNode;
     let nodeIterator = xhr.responseXML.createNodeIterator(xhr.responseXML, NodeFilter.SHOW_TEXT, null, false);
-    while (currentNode = nodeIterator.nextNode()) {
+    while (!!(currentNode = nodeIterator.nextNode())) {
       let trimmed = currentNode.nodeValue.replace(/^\s\s*/, "").replace(/\s\s*$/, "");
       if (!trimmed.length)
         currentNode.parentNode.removeChild(currentNode);
     }
 
     let doc = xhr.responseXML.documentElement;
 
     let dialog  = null;
--- a/browser/metro/base/content/input.js
+++ b/browser/metro/base/content/input.js
@@ -1149,30 +1149,18 @@ var GestureModule = {
   }
 };
 
 /**
  * Helper to track when the user is using a precise pointing device (pen/mouse)
  * versus an imprecise one (touch).
  */
 var InputSourceHelper = {
-  _isPrecise: false,
-  _treatMouseAsTouch: false,
-  
-  get isPrecise() {
-    return this._isPrecise;
-  },
-  
-  get treatMouseAsTouch() {
-    return this._treatMouseAsTouch;
-  },
-
-  set treatMouseAsTouch(aVal) {
-    this._treatMouseAsTouch = aVal;
-  },
+  isPrecise: false,
+  treatMouseAsTouch: false,
 
   init: function ish_init() {
     // debug feature, make all input imprecise
     try {
       this.treatMouseAsTouch = Services.prefs.getBoolPref(kDebugMouseInputPref);
     } catch (e) {}
     if (!this.treatMouseAsTouch) {
       window.addEventListener("mousemove", this, true);
@@ -1181,36 +1169,36 @@ var InputSourceHelper = {
   },
   
   handleEvent: function ish_handleEvent(aEvent) {
     switch (aEvent.mozInputSource) {
       case Ci.nsIDOMMouseEvent.MOZ_SOURCE_MOUSE:
       case Ci.nsIDOMMouseEvent.MOZ_SOURCE_PEN:
       case Ci.nsIDOMMouseEvent.MOZ_SOURCE_ERASER:
       case Ci.nsIDOMMouseEvent.MOZ_SOURCE_CURSOR:
-        if (!this._isPrecise && !this.treatMouseAsTouch) {
-          this._isPrecise = true;
+        if (!this.isPrecise && !this.treatMouseAsTouch) {
+          this.isPrecise = true;
           this._fire("MozPrecisePointer");
         }
         break;
 
       case Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH:
-        if (this._isPrecise) {
-          this._isPrecise = false;
+        if (this.isPrecise) {
+          this.isPrecise = false;
           this._fire("MozImprecisePointer");
         }
         break;
     }
   },
   
   fireUpdate: function fireUpdate() {
     if (this.treatMouseAsTouch) {
       this._fire("MozImprecisePointer");
     } else {
-      if (this._isPrecise) {
+      if (this.isPrecise) {
         this._fire("MozPrecisePointer");
       } else {
         this._fire("MozImprecisePointer");
       }
     }
   },
 
   _fire: function (name) {
--- a/build/mobile/sutagent/android/DoCommand.java
+++ b/build/mobile/sutagent/android/DoCommand.java
@@ -3312,17 +3312,26 @@ private void CancelNotification()
 
     public String InstallApp(String sApp, OutputStream out)
         {
         String sRet = "";
         File    srcFile = new File(sApp);
 
         try
             {
-            pProc = Runtime.getRuntime().exec(this.getSuArgs("pm install -r " + sApp + " Cleanup;exit"));
+            // on android 4.2 and above, we want to pass the "-d" argument to pm so that version
+            // downgrades are allowed... (option unsupported in earlier versions)
+            String sPmCmd;
+
+            if (android.os.Build.VERSION.SDK_INT >= 17) { // JELLY_BEAN_MR1
+                sPmCmd = "pm install -r -d " + sApp + " Cleanup;exit";
+            } else {
+                sPmCmd = "pm install -r " + sApp + " Cleanup;exit";
+            }
+            pProc = Runtime.getRuntime().exec(this.getSuArgs(sPmCmd));
             RedirOutputThread outThrd3 = new RedirOutputThread(pProc, out);
             outThrd3.start();
             try {
                 outThrd3.joinAndStopRedirect(60000);
                 int nRet3 = pProc.exitValue();
                 sRet = "\ninstallation complete [" + nRet3 + "]";
                 }
             catch (IllegalThreadStateException itse) {
--- a/build/valgrind/cross-architecture.sup
+++ b/build/valgrind/cross-architecture.sup
@@ -288,17 +288,8 @@
 {
    Bug 824323
    Memcheck:Leak
    fun:malloc
    ...
    fun:_ZN7mozilla3dom7workers13WorkerPrivate9DoRunLoopEP9JSContext
    ...
 }
-{
-   Bug 824647
-   Memcheck:Leak
-   fun:malloc
-   ...
-   fun:_ZN12_GLOBAL__N_112HistogramGetEPKcjjjjPPN4base9HistogramE
-   fun:_ZN12_GLOBAL__N_113TelemetryImpl13HistogramFromERK19nsACString_internalS3_P9JSContextPN2JS5ValueE
-   ...
-}
--- a/configure.in
+++ b/configure.in
@@ -1721,16 +1721,28 @@ MOZ_ARG_ENABLE_BOOL(shark,
     MOZ_SHARK=1,
     MOZ_SHARK= )
 if test -n "$MOZ_SHARK"; then
     MOZ_PROFILING=1
     AC_DEFINE(MOZ_SHARK)
 fi
 
 dnl ========================================================
+dnl instruments
+dnl ========================================================
+MOZ_ARG_ENABLE_BOOL(instruments,
+[  --enable-instruments    Enable instruments remote profiling. Implies --enable-profiling.],
+    MOZ_INSTRUMENTS=1,
+    MOZ_INSTRUMENTS= )
+if test -n "$MOZ_INSTRUMENTS"; then
+    MOZ_PROFILING=1
+    AC_DEFINE(MOZ_INSTRUMENTS)
+fi
+
+dnl ========================================================
 dnl callgrind
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(callgrind,
 [  --enable-callgrind      Enable callgrind profiling. Implies --enable-profiling.],
     MOZ_CALLGRIND=1,
     MOZ_CALLGRIND= )
 if test -n "$MOZ_CALLGRIND"; then
     MOZ_PROFILING=1
@@ -8500,16 +8512,17 @@ AC_SUBST(MOZ_DEBUG_DISABLE_DEFS)
 AC_SUBST(MOZ_DEBUG_FLAGS)
 AC_SUBST(MOZ_DEBUG_LDFLAGS)
 AC_SUBST(WARNINGS_AS_ERRORS)
 AC_SUBST(MOZ_EXTENSIONS)
 AC_SUBST(MOZ_JSDEBUGGER)
 AC_SUBST(MOZ_ENABLE_PROFILER_SPS)
 AC_SUBST(MOZ_JPROF)
 AC_SUBST(MOZ_SHARK)
+AC_SUBST(MOZ_INSTRUMENTS)
 AC_SUBST(MOZ_CALLGRIND)
 AC_SUBST(MOZ_VTUNE)
 AC_SUBST(MOZ_ETW)
 AC_SUBST(MOZ_PROFILING)
 AC_SUBST(LIBICONV)
 AC_SUBST(MOZ_PLACES)
 AC_SUBST(MOZ_TOOLKIT_SEARCH)
 AC_SUBST(MOZ_FEEDS)
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -279,17 +279,17 @@ public:
   // - nsGenericHTMLFrameElement: mFrameLoader (bug 672539), mTitleChangedListener
   // - HTMLBodyElement:       mContentStyleRule
   // - HTMLDataListElement:   mOptions
   // - HTMLFieldSetElement:   mElements, mDependentElements, mFirstLegend
   // - nsHTMLFormElement:     many!
   // - HTMLFrameSetElement:   mRowSpecs, mColSpecs
   // - nsHTMLInputElement:    mInputData, mFiles, mFileList, mStaticDocfileList
   // - nsHTMLMapElement:      mAreas
-  // - nsHTMLMediaElement:    many!
+  // - HTMLMediaElement:      many!
   // - nsHTMLOutputElement:   mDefaultValue, mTokenList
   // - nsHTMLRowElement:      mCells
   // - nsHTMLSelectElement:   mOptions, mRestoreState
   // - nsHTMLTableElement:    mTBodies, mRows, mTableInheritedAttributes
   // - nsHTMLTableSectionElement: mRows
   // - nsHTMLTextAreaElement: mControllers, mState
   //
   // The following members don't need to be measured:
@@ -355,17 +355,17 @@ public:
     eCOMMENT             = 1 << 5,
     /** form control elements */
     eHTML_FORM_CONTROL   = 1 << 6,
     /** document fragments */
     eDOCUMENT_FRAGMENT   = 1 << 7,
     /** data nodes (comments, PIs, text). Nodes of this type always
      returns a non-null value for nsIContent::GetText() */
     eDATA_NODE           = 1 << 8,
-    /** nsHTMLMediaElement */
+    /** HTMLMediaElement */
     eMEDIA               = 1 << 9,
     /** animation elements */
     eANIMATION           = 1 << 10,
     /** filter elements that implement SVGFilterPrimitiveStandardAttributes */
     eFILTER              = 1 << 11
   };
 
   /**
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -163,17 +163,17 @@
 #include "nsWrapperCacheInlines.h"
 #include "nsXULPopupManager.h"
 #include "xpcprivate.h" // nsXPConnect
 
 #ifdef IBMBIDI
 #include "nsIBidiKeyboard.h"
 #endif
 #ifdef MOZ_MEDIA
-#include "nsHTMLMediaElement.h"
+#include "mozilla/dom/HTMLMediaElement.h"
 #endif
 
 extern "C" int MOZ_XMLTranslateEntity(const char* ptr, const char* end,
                                       const char** next, PRUnichar* result);
 extern "C" int MOZ_XMLCheckQName(const char* ptr, const char* end,
                                  int ns_aware, const char** colon);
 
 class imgLoader;
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -142,17 +142,17 @@
 #include "nsIDOMPageTransitionEvent.h"
 #include "nsJSUtils.h"
 #include "nsFrameLoader.h"
 #include "nsEscape.h"
 #include "nsObjectLoadingContent.h"
 #include "nsHtml5TreeOpExecutor.h"
 #include "nsIDOMElementReplaceEvent.h"
 #ifdef MOZ_MEDIA
-#include "nsHTMLMediaElement.h"
+#include "mozilla/dom/HTMLMediaElement.h"
 #endif // MOZ_MEDIA
 #ifdef MOZ_WEBRTC
 #include "IPeerConnection.h"
 #endif // MOZ_WEBRTC
 
 #include "mozAutoDocUpdate.h"
 #include "nsGlobalWindow.h"
 #include "mozilla/dom/EncodingUtils.h"
@@ -3974,17 +3974,17 @@ nsDocument::GetScopeObject() const
 }
 
 static void
 NotifyActivityChanged(nsIContent *aContent, void *aUnused)
 {
 #ifdef MOZ_MEDIA
   nsCOMPtr<nsIDOMHTMLMediaElement> domMediaElem(do_QueryInterface(aContent));
   if (domMediaElem) {
-    nsHTMLMediaElement* mediaElem = static_cast<nsHTMLMediaElement*>(aContent);
+    HTMLMediaElement* mediaElem = static_cast<HTMLMediaElement*>(aContent);
     mediaElem->NotifyOwnerDocumentActivityChanged();
   }
 #endif
   nsCOMPtr<nsIObjectLoadingContent> objectLoadingContent(do_QueryInterface(aContent));
   if (objectLoadingContent) {
     nsObjectLoadingContent* olc = static_cast<nsObjectLoadingContent*>(objectLoadingContent.get());
     olc->NotifyOwnerDocumentActivityChanged();
   }
@@ -8950,17 +8950,17 @@ nsDocument::AddImage(imgIRequest* aImage
 }
 
 static void
 NotifyAudioAvailableListener(nsIContent *aContent, void *aUnused)
 {
 #ifdef MOZ_MEDIA
   nsCOMPtr<nsIDOMHTMLMediaElement> domMediaElem(do_QueryInterface(aContent));
   if (domMediaElem) {
-    nsHTMLMediaElement* mediaElem = static_cast<nsHTMLMediaElement*>(aContent);
+    HTMLMediaElement* mediaElem = static_cast<HTMLMediaElement*>(aContent);
     mediaElem->NotifyAudioAvailableListener();
   }
 #endif
 }
 
 void
 nsDocument::NotifyAudioAvailableListener()
 {
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -20,17 +20,17 @@
 #include "nsPIDOMWindow.h"
 #include "nsDocument.h"
 #ifdef MOZ_XUL
 #include "nsXULElement.h"
 #endif
 #include "nsBindingManager.h"
 #include "nsGenericHTMLElement.h"
 #ifdef MOZ_MEDIA
-#include "nsHTMLMediaElement.h"
+#include "mozilla/dom/HTMLMediaElement.h"
 #endif // MOZ_MEDIA
 #include "nsWrapperCacheInlines.h"
 #include "nsObjectLoadingContent.h"
 #include "nsDOMMutationObserver.h"
 #include "mozilla/dom/BindingUtils.h"
 
 using namespace mozilla::dom;
 
@@ -503,17 +503,17 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
         }
       }
     }
 
     if (wasRegistered && oldDoc != newDoc) {
 #ifdef MOZ_MEDIA
       nsCOMPtr<nsIDOMHTMLMediaElement> domMediaElem(do_QueryInterface(aNode));
       if (domMediaElem) {
-        nsHTMLMediaElement* mediaElem = static_cast<nsHTMLMediaElement*>(aNode);
+        HTMLMediaElement* mediaElem = static_cast<HTMLMediaElement*>(aNode);
         mediaElem->NotifyOwnerDocumentActivityChanged();
       }
 #endif
       nsCOMPtr<nsIObjectLoadingContent> objectLoadingContent(do_QueryInterface(aNode));
       if (objectLoadingContent) {
         nsObjectLoadingContent* olc = static_cast<nsObjectLoadingContent*>(objectLoadingContent.get());
         olc->NotifyOwnerDocumentActivityChanged();
       }
--- a/content/base/src/nsScriptLoader.h
+++ b/content/base/src/nsScriptLoader.h
@@ -7,24 +7,24 @@
  * A class that handles loading and evaluation of <script> elements.
  */
 
 #ifndef __nsScriptLoader_h__
 #define __nsScriptLoader_h__
 
 #include "nsCOMPtr.h"
 #include "nsIScriptElement.h"
-#include "nsIURI.h"
 #include "nsCOMArray.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
 #include "nsIDocument.h"
 #include "nsIStreamLoader.h"
 
 class nsScriptLoadRequest;
+class nsIURI;
 
 //////////////////////////////////////////////////////////////
 // Script loader implementation
 //////////////////////////////////////////////////////////////
 
 class nsScriptLoader : public nsIStreamLoaderObserver
 {
   friend class nsScriptRequestProcessor;
--- a/content/base/src/nsStyleLinkElement.h
+++ b/content/base/src/nsStyleLinkElement.h
@@ -12,27 +12,27 @@
 
 #ifndef nsStyleLinkElement_h___
 #define nsStyleLinkElement_h___
 
 #include "nsCOMPtr.h"
 #include "nsIDOMLinkStyle.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsCSSStyleSheet.h"
-#include "nsIURI.h"
 #include "nsTArray.h"
 #include "mozilla/CORSMode.h"
 
 #define PREFETCH      0x00000001
 #define DNS_PREFETCH  0x00000002
 #define STYLESHEET    0x00000004
 #define NEXT          0x00000008
 #define ALTERNATE     0x00000010
 
 class nsIDocument;
+class nsIURI;
 
 class nsStyleLinkElement : public nsIDOMLinkStyle,
                            public nsIStyleSheetLinkingElement
 {
 public:
   nsStyleLinkElement();
   virtual ~nsStyleLinkElement();
 
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -88,17 +88,17 @@
 #include "mozilla/Telemetry.h"
 #include "mozilla/unused.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsJSUtils.h"
 #include "XPCQuickStubs.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/HTMLImageElement.h"
-#include "nsHTMLVideoElement.h"
+#include "mozilla/dom/HTMLVideoElement.h"
 #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 
 #ifdef USE_SKIA
 #include "GLContext.h"
 #include "GLContextProvider.h"
 #include "SurfaceTypes.h"
 #endif
 
@@ -1442,17 +1442,17 @@ CanvasRenderingContext2D::CreatePattern(
       nsRefPtr<CanvasPattern> pat =
         new CanvasPattern(srcSurf, repeatMode, htmlElement->NodePrincipal(), canvas->IsWriteOnly(), false);
 
       return pat.forget();
     }
   } else if (element.IsHTMLImageElement()) {
     htmlElement = &element.GetAsHTMLImageElement();
   } else {
-    htmlElement = element.GetAsHTMLVideoElement();
+    htmlElement = &element.GetAsHTMLVideoElement();
   }
 
   // The canvas spec says that createPattern should use the first frame
   // of animated images
   nsLayoutUtils::SurfaceFromElementResult res =
     nsLayoutUtils::SurfaceFromElement(htmlElement,
       nsLayoutUtils::SFE_WANT_FIRST_FRAME | nsLayoutUtils::SFE_WANT_NEW_SURFACE);
 
@@ -2935,17 +2935,17 @@ CanvasRenderingContext2D::DrawImage(cons
         imgSize = gfxIntSize(srcSurf->GetSize().width, srcSurf->GetSize().height);
       }
     }
   } else {
     if (image.IsHTMLImageElement()) {
       HTMLImageElement* img = &image.GetAsHTMLImageElement();
       element = img;
     } else {
-      nsHTMLVideoElement* video = image.GetAsHTMLVideoElement();
+      HTMLVideoElement* video = &image.GetAsHTMLVideoElement();
       element = video;
     }
 
     gfxASurface* imgsurf =
       CanvasImageCache::Lookup(element, mCanvasElement, &imgSize);
     if (imgsurf) {
       srcSurf = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mTarget, imgsurf);
     }
--- a/content/canvas/src/CanvasRenderingContext2D.h
+++ b/content/canvas/src/CanvasRenderingContext2D.h
@@ -6,17 +6,17 @@
 #define CanvasRenderingContext2D_h
 
 #include <vector>
 #include "nsIDOMCanvasRenderingContext2D.h"
 #include "nsICanvasRenderingContextInternal.h"
 #include "mozilla/RefPtr.h"
 #include "nsColor.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
-#include "nsHTMLVideoElement.h"
+#include "mozilla/dom/HTMLVideoElement.h"
 #include "CanvasUtils.h"
 #include "gfxFont.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/ImageData.h"
 #include "mozilla/dom/UnionTypes.h"
 #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 
 #define NS_CANVASGRADIENTAZURE_PRIVATE_IID \
--- a/content/canvas/test/crossorigin/test_video_crossorigin.html
+++ b/content/canvas/test/crossorigin/test_video_crossorigin.html
@@ -29,100 +29,100 @@ function createCanvas(width, height) {
 
 function testCanvasDrawImage(v) {
   var c = createCanvas(v.width, v.height);
   var ctx = c.getContext("2d");
   ctx.drawImage(v, 0, 0);
 
   try {
     var data = ctx.getImageData(0, 0, 1, 1);
-    ok(true, "drawImage '" + v.src + "' then getImageData with crossorigin='" + v.crossorigin + "' worked");
+    ok(true, "drawImage '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' worked");
   } catch(error) {
-    ok(!v.crossorigin && error.name === "SecurityError", "drawImage '" + v.src + "' then getImageData with crossorigin='" + v.crossorigin + "' failed");
+    ok(!v.crossOrigin && error.name === "SecurityError", "drawImage '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' failed");
     v.tainted = true;
   }
 }
 
 function testCanvasCreatePattern(v) {
   var c = createCanvas(v.width, v.height);
   var ctx = c.getContext("2d");
   ctx.fillStyle = ctx.createPattern(v, "");
   ctx.fillRect(0, 0, c.width, c.height);
 
   try {
     var data = ctx.getImageData(0, 0, 1, 1);
-    ok(true, "createPattern '" + v.src + "' then getImageData with crossorigin='" + v.crossorigin + "' worked");
+    ok(true, "createPattern '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' worked");
   } catch(error) {
-    ok(!v.crossorigin && error.name === "SecurityError", "createPattern '" + v.src + "' then getImageData with crossorigin='" + v.crossorigin + "' failed");
+    ok(!v.crossOrigin && error.name === "SecurityError", "createPattern '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' failed");
     v.tainted = true;
   }
 }
 
 function testWebGL(v) {
   var tex = gl.createTexture();
   gl.bindTexture(gl.TEXTURE_2D, tex);
 
   try {
     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, v);
-    ok(true, "createTexture from '" + v.src + "' with crossorigin='" + v.crossorigin + "' worked");
+    ok(true, "createTexture from '" + v.src + "' with crossOrigin='" + v.crossOrigin + "' worked");
   } catch (error) {
-    ok(!v.crossorigin && error.name === "SecurityError", "createTexture from '" + v.src + "' with crossorigin='" + v.crossorigin + "' failed");
+    ok(!v.crossOrigin && error.name === "SecurityError", "createTexture from '" + v.src + "' with crossOrigin='" + v.crossOrigin + "' failed");
     v.tainted = true;
   }
 }
 
 function testTaintedCanvas(v) {
   var c = createCanvas(v.width, v.height);
   var ctx = c.getContext("2d");
   ctx.drawImage(v, 0, 0);
 
   try {
     var data = ctx.getImageData(0, 0, 1, 1);
     ok(false, "changing the CORS mode should not allow reading data from remote videos");
   } catch (error) {
-    ok(error.name === "SecurityError", "changing the CORS mode, drawImage '" + v.src + "' then getImageData with crossorigin='" + v.crossorigin + "' failed");
+    ok(error.name === "SecurityError", "changing the CORS mode, drawImage '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' failed");
   }
 }
 
 function vidDataSuccess(e) {
-  ok(!e.target.error, "Load '" + e.target.src + "' with crossorigin='" + e.target.crossorigin + "'");
+  ok(!e.target.error, "Load '" + e.target.src + "' with crossOrigin='" + e.target.crossOrigin + "'");
 
   testCanvasDrawImage(e.target);
   testCanvasCreatePattern(e.target);
   if (gl) {
     testWebGL(e.target);
   }
   // If we change the CORS mode after loading the file without CORS it should still throw a security error
   if (e.target.tainted) {
-    e.target.crossorigin = "anonymous";
+    e.target.crossOrigin = "anonymous";
     testTaintedCanvas(e.target);
   }
 
   doneTest(e);
 }
 
 function vidLoadFailure(e) {
-  ok(false, "Load '" + e.target.src + "' with crossorigin='" + e.target.crossorigin + "'");
+  ok(false, "Load '" + e.target.src + "' with crossOrigin='" + e.target.crossOrigin + "'");
   doneTest(e);
 }
 
 function vidErrorSuccess(e) {
   ok(e.target.error.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED, 
-    "Load '" + e.target.src + "' with crossorigin='" + e.target.crossorigin + "'");
+    "Load '" + e.target.src + "' with crossOrigin='" + e.target.crossOrigin + "'");
   doneTest(e);
 }
 
 function startTest(test, token) {
   var v = document.createElement('video');
   if (test.cors === "just-crossOrigin-without-value") {
     var div = document.createElement('div');
-    div.innerHTML="<video crossorigin>";
+    div.innerHTML="<video crossOrigin>";
     v = div.children[0];
   } else if (test.cors !== "missing-value-default") {
-    v.crossorigin = test.cors;
+    v.crossOrigin = test.cors;
   }
   v.token = token;
   manager.started(token);
   v.autoplay = true;
   v.preload = "auto";
   v.style.display = "none";
   if (test.nameIntent === test.corsIntent || test.corsIntent === "none" ||
       (test.nameIntent === "use-credentials" && test.corsIntent === "anonymous")) {
rename from content/html/content/public/nsHTMLAudioElement.h
rename to content/html/content/public/HTMLAudioElement.h
--- a/content/html/content/public/nsHTMLAudioElement.h
+++ b/content/html/content/public/HTMLAudioElement.h
@@ -1,55 +1,78 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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/. */
-#if !defined(nsHTMLAudioElement_h__)
-#define nsHTMLAudioElement_h__
+#ifndef mozilla_dom_HTMLAudioElement_h
+#define mozilla_dom_HTMLAudioElement_h
 
 #include "nsIDOMHTMLAudioElement.h"
 #include "nsIJSNativeInitializer.h"
-#include "nsHTMLMediaElement.h"
+#include "mozilla/dom/HTMLMediaElement.h"
 
 typedef uint16_t nsMediaNetworkState;
 typedef uint16_t nsMediaReadyState;
 
-class nsHTMLAudioElement : public nsHTMLMediaElement,
-                           public nsIDOMHTMLAudioElement,
-                           public nsIJSNativeInitializer
+namespace mozilla {
+namespace dom {
+
+class HTMLAudioElement : public HTMLMediaElement,
+                         public nsIDOMHTMLAudioElement,
+                         public nsIJSNativeInitializer
 {
 public:
-  nsHTMLAudioElement(already_AddRefed<nsINodeInfo> aNodeInfo);
-  virtual ~nsHTMLAudioElement();
+  HTMLAudioElement(already_AddRefed<nsINodeInfo> aNodeInfo);
+  virtual ~HTMLAudioElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
 
   // nsIDOMHTMLMediaElement
-  using nsHTMLMediaElement::GetPaused;
-  NS_FORWARD_NSIDOMHTMLMEDIAELEMENT(nsHTMLMediaElement::)
+  using HTMLMediaElement::GetPaused;
+  NS_FORWARD_NSIDOMHTMLMEDIAELEMENT(HTMLMediaElement::)
 
   // nsIDOMHTMLAudioElement
   NS_DECL_NSIDOMHTMLAUDIOELEMENT
 
   // nsIJSNativeInitializer
   NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext,
                         JSObject* aObj, uint32_t argc, jsval* argv);
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
   virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel);
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
+
+  // WebIDL
+
+  static already_AddRefed<HTMLAudioElement> Audio(const GlobalObject& global,
+                                                  ErrorResult& aRv);
+  static already_AddRefed<HTMLAudioElement> Audio(const GlobalObject& global,
+                                                  const nsAString& src,
+                                                  ErrorResult& aRv);
+
+  void MozSetup(uint32_t aChannels, uint32_t aRate, ErrorResult& aRv);
+
+  uint32_t MozWriteAudio(JSContext* aCx, JS::Value aData, ErrorResult& aRv);
+
+  uint64_t MozCurrentSampleOffset(ErrorResult& aRv);
+
+protected:
+  virtual JSObject* WrapNode(JSContext* aCx, JSObject* aScope) MOZ_OVERRIDE;
 };
 
-#endif
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_HTMLAudioElement_h
rename from content/html/content/public/nsHTMLMediaElement.h
rename to content/html/content/public/HTMLMediaElement.h
--- a/content/html/content/public/nsHTMLMediaElement.h
+++ b/content/html/content/public/HTMLMediaElement.h
@@ -1,15 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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/. */
-#if !defined(nsHTMLMediaElement_h__)
-#define nsHTMLMediaElement_h__
+#ifndef mozilla_dom_HTMLMediaElement_h
+#define mozilla_dom_HTMLMediaElement_h
 
 #include "nsIDOMHTMLMediaElement.h"
 #include "nsGenericHTMLElement.h"
 #include "MediaDecoderOwner.h"
 #include "nsIChannel.h"
 #include "nsIHttpChannel.h"
 #include "nsThreadUtils.h"
 #include "nsIDOMRange.h"
@@ -22,51 +22,55 @@
 #include "DOMMediaStream.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/dom/TimeRanges.h"
 #include "nsIDOMWakeLock.h"
 #include "AudioChannelCommon.h"
 #include "DecoderTraits.h"
 #include "MediaMetadataManager.h"
 #include "AudioChannelAgent.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
 
 // Define to output information on decoding and painting framerate
 /* #define DEBUG_FRAME_RATE 1 */
 
 typedef uint16_t nsMediaNetworkState;
 typedef uint16_t nsMediaReadyState;
 
 namespace mozilla {
 class MediaResource;
 class MediaDecoder;
 }
 
-class nsHTMLMediaElement : public nsGenericHTMLElement,
-                           public nsIObserver,
-                           public mozilla::MediaDecoderOwner,
-                           public nsIAudioChannelAgentCallback
+namespace mozilla {
+namespace dom {
+
+class MediaError;
+
+class HTMLMediaElement : public nsGenericHTMLElement,
+                         public nsIObserver,
+                         public MediaDecoderOwner,
+                         public nsIAudioChannelAgentCallback
 {
 public:
   typedef mozilla::TimeStamp TimeStamp;
   typedef mozilla::layers::ImageContainer ImageContainer;
   typedef mozilla::VideoFrameContainer VideoFrameContainer;
   typedef mozilla::MediaStream MediaStream;
   typedef mozilla::MediaResource MediaResource;
   typedef mozilla::MediaDecoderOwner MediaDecoderOwner;
   typedef mozilla::MetadataTags MetadataTags;
-  typedef mozilla::AudioStream AudioStream;
-  typedef mozilla::MediaDecoder MediaDecoder;
-  typedef mozilla::DOMMediaStream DOMMediaStream;
 
-  mozilla::CORSMode GetCORSMode() {
+  CORSMode GetCORSMode() {
     return mCORSMode;
   }
 
-  nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo);
-  virtual ~nsHTMLMediaElement();
+  HTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo);
+  virtual ~HTMLMediaElement();
 
   /**
    * This is used when the browser is constructing a video element to play
    * a channel that we've already started loading. The src attribute and
    * <source> children are ignored.
    * @param aChannel the channel to use
    * @param aListener returns a stream listener that should receive
    * notifications for the stream
@@ -77,23 +81,23 @@ public:
   NS_DECL_NSIDOMHTMLMEDIAELEMENT
 
   NS_DECL_NSIOBSERVER
 
   NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLMediaElement,
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLMediaElement,
                                            nsGenericHTMLElement)
 
   virtual bool ParseAttribute(int32_t aNamespaceID,
-                                nsIAtom* aAttribute,
-                                const nsAString& aValue,
-                                nsAttrValue& aResult);
+                              nsIAtom* aAttribute,
+                              const nsAString& aValue,
+                              nsAttrValue& aResult);
   // SetAttr override.  C++ is stupid, so have to override both
   // overloaded methods.
   nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                    const nsAString& aValue, bool aNotify)
   {
     return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
   }
   virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
@@ -189,17 +193,17 @@ public:
   // the audio data sent to hardware and dispatch it in "mozaudioavailable"
   // events. This allows us to not perform the copy and thus reduce overhead
   // in the common case where we don't have a "MozAudioAvailable" listener.
   void NotifyAudioAvailableListener();
 
   // Called by the media decoder and the video frame to get the
   // ImageContainer containing the video data.
   virtual VideoFrameContainer* GetVideoFrameContainer() MOZ_FINAL MOZ_OVERRIDE;
-  ImageContainer* GetImageContainer();
+  layers::ImageContainer* GetImageContainer();
 
   // Called by the video frame to get the print surface, if this is
   // a static document and we're not actually playing video
   gfxASurface* GetPrintSurface() { return mPrintSurface; }
 
   // Dispatch events
   using nsGenericHTMLElement::DispatchEvent;
   virtual nsresult DispatchEvent(const nsAString& aName) MOZ_FINAL MOZ_OVERRIDE;
@@ -250,17 +254,17 @@ public:
   virtual void NotifyDecoderPrincipalChanged() MOZ_FINAL MOZ_OVERRIDE;
 
   // Update the visual size of the media. Called from the decoder on the
   // main thread when/if the size changes.
   void UpdateMediaSize(nsIntSize size);
 
   // Returns the CanPlayStatus indicating if we can handle the
   // full MIME type including the optional codecs parameter.
-  static mozilla::CanPlayStatus GetCanPlay(const nsAString& aType);
+  static CanPlayStatus GetCanPlay(const nsAString& aType);
 
   /**
    * Called when a child source element is added to this media element. This
    * may queue a task to run the select resource algorithm if appropriate.
    */
   void NotifyAddedSource();
 
   /**
@@ -291,17 +295,17 @@ public:
   already_AddRefed<nsILoadGroup> GetDocumentLoadGroup();
 
   /**
    * Returns true if the media has played or completed a seek.
    * Used by video frame to determine whether to paint the poster.
    */
   bool GetPlayedOrSeeked() const { return mHasPlayedOrSeeked; }
 
-  nsresult CopyInnerTo(mozilla::dom::Element* aDest);
+  nsresult CopyInnerTo(Element* aDest);
 
   /**
    * Sets the Accept header on the HTTP channel to the required
    * video or audio MIME types.
    */
   virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel) = 0;
 
   /**
@@ -313,39 +317,221 @@ public:
   /**
    * Fires a timeupdate event. If aPeriodic is true, the event will only
    * be fired if we've not fired a timeupdate event (for any reason) in the
    * last 250ms, as required by the spec when the current time is periodically
    * increasing during playback.
    */
   virtual void FireTimeUpdate(bool aPeriodic) MOZ_FINAL MOZ_OVERRIDE;
 
-  MediaStream* GetSrcMediaStream()
+  MediaStream* GetSrcMediaStream() const
   {
     NS_ASSERTION(mSrcStream, "Don't call this when not playing a stream");
     return mSrcStream->GetStream();
   }
 
+  // WebIDL
+
+  MediaError* GetError() const
+  {
+    return mError;
+  }
+
+  // XPCOM GetSrc() is OK
+  void SetSrc(const nsAString& aSrc, ErrorResult& aRv)
+  {
+    SetHTMLAttr(nsGkAtoms::src, aSrc, aRv);
+  }
+
+  // XPCOM GetCurrentSrc() is OK
+
+  // XPCOM GetCrossorigin() is OK
+  void SetCrossOrigin(const nsAString& aValue, ErrorResult& aRv)
+  {
+    SetHTMLAttr(nsGkAtoms::crossorigin, aValue, aRv);
+  }
+
+  uint16_t NetworkState() const
+  {
+    return mNetworkState;
+  }
+
+  // XPCOM GetPreload() is OK
+  void SetPreload(const nsAString& aValue, ErrorResult& aRv)
+  {
+    SetHTMLAttr(nsGkAtoms::preload, aValue, aRv);
+  }
+
+  already_AddRefed<TimeRanges> Buffered() const;
+
+  // XPCOM Load() is OK
+
+  // XPCOM CanPlayType() is OK
+
+  uint16_t ReadyState() const
+  {
+    return mReadyState;
+  }
+
+  bool Seeking() const;
+
+  double CurrentTime() const;
+
+  void SetCurrentTime(double aCurrentTime, ErrorResult& aRv);
+
+  double Duration() const;
+
+  bool Paused() const
+  {
+    return mPaused;
+  }
+
+  double DefaultPlaybackRate() const
+  {
+    return mDefaultPlaybackRate;
+  }
+
+  void SetDefaultPlaybackRate(double aDefaultPlaybackRate, ErrorResult& aRv);
+
+  double PlaybackRate() const
+  {
+    return mPlaybackRate;
+  }
+
+  void SetPlaybackRate(double aPlaybackRate, ErrorResult& aRv);
+
+  already_AddRefed<TimeRanges> Played();
+
+  already_AddRefed<TimeRanges> Seekable() const;
+
+  bool Ended();
+
+  bool Autoplay() const
+  {
+    return GetBoolAttr(nsGkAtoms::autoplay);
+  }
+
+  void SetAutoplay(bool aValue, ErrorResult& aRv)
+  {
+    SetHTMLBoolAttr(nsGkAtoms::autoplay, aValue, aRv);
+  }
+
+  bool Loop() const
+  {
+    return GetBoolAttr(nsGkAtoms::loop);
+  }
+
+  void SetLoop(bool aValue, ErrorResult& aRv)
+  {
+    SetHTMLBoolAttr(nsGkAtoms::loop, aValue, aRv);
+  }
+
+  void Play(ErrorResult& aRv);
+
+  void Pause(ErrorResult& aRv);
+
+  bool Controls() const
+  {
+    return GetBoolAttr(nsGkAtoms::controls);
+  }
+
+  void SetControls(bool aValue, ErrorResult& aRv)
+  {
+    SetHTMLBoolAttr(nsGkAtoms::controls, aValue, aRv);
+  }
+
+  double Volume() const
+  {
+    return mVolume;
+  }
+
+  void SetVolume(double aVolume, ErrorResult& aRv);
+
+  bool Muted() const
+  {
+    return mMuted;
+  }
+
+  // XPCOM SetMuted() is OK
+
+  bool DefaultMuted() const
+  {
+    return GetBoolAttr(nsGkAtoms::muted);
+  }
+
+  void SetDefaultMuted(bool aMuted, ErrorResult& aRv)
+  {
+    SetHTMLBoolAttr(nsGkAtoms::muted, aMuted, aRv);
+  }
+
+  already_AddRefed<DOMMediaStream> GetMozSrcObject() const;
+
+  void SetMozSrcObject(DOMMediaStream& aValue);
+
+  double InitialTime();
+
+  bool MozPreservesPitch() const
+  {
+    return mPreservesPitch;
+  }
+
+  // XPCOM MozPreservesPitch() is OK
+
+  bool MozAutoplayEnabled() const
+  {
+    return mAutoplayEnabled;
+  }
+
+  already_AddRefed<DOMMediaStream> MozCaptureStream(ErrorResult& aRv);
+
+  already_AddRefed<DOMMediaStream> MozCaptureStreamUntilEnded(ErrorResult& aRv);
+
+  bool MozAudioCaptured() const
+  {
+    return mAudioCaptured;
+  }
+
+  uint32_t GetMozChannels(ErrorResult& aRv) const;
+
+  uint32_t GetMozSampleRate(ErrorResult& aRv) const;
+
+  uint32_t GetMozFrameBufferLength(ErrorResult& aRv) const;
+
+  void SetMozFrameBufferLength(uint32_t aValue, ErrorResult& aRv);
+
+  JSObject* MozGetMetadata(JSContext* aCx, ErrorResult& aRv);
+
+  void MozLoadFrom(HTMLMediaElement& aOther, ErrorResult& aRv);
+
+  double MozFragmentEnd();
+
+  // XPCOM GetMozAudioChannelType() is OK
+
+  void SetMozAudioChannelType(const nsAString& aValue, ErrorResult& aRv)
+  {
+    SetHTMLAttr(nsGkAtoms::mozaudiochannel, aValue, aRv);
+  }
+
 protected:
   class MediaLoadListener;
   class StreamListener;
 
   virtual void GetItemValueText(nsAString& text);
   virtual void SetItemValueText(const nsAString& text);
 
   class WakeLockBoolWrapper {
   public:
     WakeLockBoolWrapper(bool val = false) : mValue(val), mOuter(NULL), mWakeLock(NULL) {}
-    void SetOuter(nsHTMLMediaElement* outer) { mOuter = outer; }
-    operator bool() { return mValue; }
+    void SetOuter(HTMLMediaElement* outer) { mOuter = outer; }
+    operator bool() const { return mValue; }
     WakeLockBoolWrapper& operator=(bool val);
     bool operator !() const { return !mValue; }
   private:
     bool mValue;
-    nsHTMLMediaElement* mOuter;
+    HTMLMediaElement* mOuter;
     nsCOMPtr<nsIDOMMozWakeLock> mWakeLock;
   };
 
   /**
    * Logs a warning message to the web console to report various failures.
    * aMsg is the localized message identifier, aParams is the parameters to
    * be substituted into the localized message, and aParamCount is the number
    * of parameters in aParams.
@@ -410,17 +596,17 @@ protected:
   /**
    * Call this before clearing mLoadingSrc.
    */
   void RemoveMediaElementFromURITable();
   /**
    * Call this to find a media element with the same NodePrincipal and mLoadingSrc
    * set to aURI, and with a decoder on which Load() has been called.
    */
-  nsHTMLMediaElement* LookupMediaElementURITable(nsIURI* aURI);
+  HTMLMediaElement* LookupMediaElementURITable(nsIURI* aURI);
 
   /**
    * Shutdown and clear mDecoder and maintain associated invariants.
    */
   void ShutdownDecoder();
   /**
    * Execute the initial steps of the load algorithm that ensure existing
    * loads are aborted, the element is emptied, and a new load ID is
@@ -590,19 +776,19 @@ protected:
 
   /**
    * Suspend (if aPauseForInactiveDocument) or resume element playback and
    * resource download.  If aSuspendEvents is true, event delivery is
    * suspended (and events queued) until the element is resumed.
    */
   void SuspendOrResumeElement(bool aPauseElement, bool aSuspendEvents);
 
-  // Get the nsHTMLMediaElement object if the decoder is being used from an
+  // Get the HTMLMediaElement object if the decoder is being used from an
   // HTML media element, and null otherwise.
-  virtual nsHTMLMediaElement* GetMediaElement() MOZ_FINAL MOZ_OVERRIDE
+  virtual HTMLMediaElement* GetMediaElement() MOZ_FINAL MOZ_OVERRIDE
   {
     return this;
   }
 
   // Return true if decoding should be paused
   virtual bool GetPaused() MOZ_FINAL MOZ_OVERRIDE
   {
     bool isPaused = false;
@@ -649,17 +835,17 @@ protected:
 
   // Holds a reference to the first channel we open to the media resource.
   // Once the decoder is created, control over the channel passes to the
   // decoder, and we null out this reference. We must store this in case
   // we need to cancel the channel before control of it passes to the decoder.
   nsCOMPtr<nsIChannel> mChannel;
 
   // Error attribute
-  nsCOMPtr<nsIDOMMediaError> mError;
+  nsRefPtr<MediaError> mError;
 
   // The current media load ID. This is incremented every time we start a
   // new load. Async events note the ID when they're first sent, and only fire
   // if the ID is unchanged when they come to fire.
   uint32_t mCurrentLoadID;
 
   // Points to the child source elements, used to iterate through the children
   // when selecting a resource to load.
@@ -766,17 +952,17 @@ protected:
   // Reference to the source element last returned by GetNextSource().
   // This is the child source element which we're trying to load from.
   nsCOMPtr<nsIContent> mSourceLoadCandidate;
 
   // An audio stream for writing audio directly from JS.
   nsAutoPtr<AudioStream> mAudioStream;
 
   // Range of time played.
-  mozilla::dom::TimeRanges mPlayed;
+  TimeRanges mPlayed;
 
   // Stores the time at the start of the current 'played' range.
   double mCurrentPlayRangeStart;
 
   // True if MozAudioAvailable events can be safely dispatched, based on
   // a media and element same-origin check.
   bool mAllowAudioData;
 
@@ -875,30 +1061,33 @@ protected:
   // load when the user initiates either playback or an explicit load is
   // stored in mPreloadURI.
   bool mSuspendedForPreloadNone;
 
   // True if a same-origin check has been done for the media element and resource.
   bool mMediaSecurityVerified;
 
   // The CORS mode when loading the media element
-  mozilla::CORSMode mCORSMode;
+  CORSMode mCORSMode;
 
   // True if the media has an audio track
   bool mHasAudio;
 
   // True if the media's channel's download has been suspended.
   bool mDownloadSuspendedByCache;
 
   // Audio Channel Type.
-  mozilla::dom::AudioChannelType mAudioChannelType;
+  AudioChannelType mAudioChannelType;
 
   // The audiochannel has been suspended.
   bool mChannelSuspended;
 
   // Is this media element playing?
   bool mPlayingThroughTheAudioChannel;
 
   // An agent used to join audio channel service.
   nsCOMPtr<nsIAudioChannelAgent> mAudioChannelAgent;
 };
 
-#endif
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_HTMLMediaElement_h
rename from content/html/content/public/nsHTMLVideoElement.h
rename to content/html/content/public/HTMLVideoElement.h
--- a/content/html/content/public/nsHTMLVideoElement.h
+++ b/content/html/content/public/HTMLVideoElement.h
@@ -1,43 +1,47 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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/. */
-#if !defined(nsHTMLVideoElement_h__)
-#define nsHTMLVideoElement_h__
+
+#ifndef mozilla_dom_HTMLVideoElement_h
+#define mozilla_dom_HTMLVideoElement_h
 
 #include "nsIDOMHTMLVideoElement.h"
-#include "nsHTMLMediaElement.h"
+#include "mozilla/dom/HTMLMediaElement.h"
 
-class nsHTMLVideoElement : public nsHTMLMediaElement,
-                           public nsIDOMHTMLVideoElement
+namespace mozilla {
+namespace dom {
+
+class HTMLVideoElement : public HTMLMediaElement,
+                         public nsIDOMHTMLVideoElement
 {
 public:
-  nsHTMLVideoElement(already_AddRefed<nsINodeInfo> aNodeInfo);
-  virtual ~nsHTMLVideoElement();
+  HTMLVideoElement(already_AddRefed<nsINodeInfo> aNodeInfo);
+  virtual ~HTMLVideoElement();
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(nsHTMLVideoElement, video)
+  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLVideoElement, video)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
 
   // nsIDOMHTMLMediaElement
-  using nsHTMLMediaElement::GetPaused;
-  NS_FORWARD_NSIDOMHTMLMEDIAELEMENT(nsHTMLMediaElement::)
+  using HTMLMediaElement::GetPaused;
+  NS_FORWARD_NSIDOMHTMLMEDIAELEMENT(HTMLMediaElement::)
 
   // nsIDOMHTMLVideoElement
   NS_DECL_NSIDOMHTMLVIDEOELEMENT
 
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult);
@@ -50,11 +54,67 @@ public:
   // If there is no video frame, returns NS_ERROR_FAILURE.
   nsresult GetVideoSize(nsIntSize* size);
 
   virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel);
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
+
+  // WebIDL
+
+  uint32_t Width() const
+  {
+    return GetIntAttr(nsGkAtoms::width, 0);
+  }
+
+  void SetWidth(uint32_t aValue, ErrorResult& aRv)
+  {
+    SetHTMLIntAttr(nsGkAtoms::width, aValue, aRv);
+  }
+
+  uint32_t Height() const
+  {
+    return GetIntAttr(nsGkAtoms::height, 0);
+  }
+
+  void SetHeight(uint32_t aValue, ErrorResult& aRv)
+  {
+    SetHTMLIntAttr(nsGkAtoms::height, aValue, aRv);
+  }
+
+  uint32_t VideoWidth() const
+  {
+    return mMediaSize.width == -1 ? 0 : mMediaSize.width;
+  }
+
+  uint32_t VideoHeight() const
+  {
+    return mMediaSize.height == -1 ? 0 : mMediaSize.height;
+  }
+
+  // XPCOM GetPoster is OK
+  void SetPoster(const nsAString& aValue, ErrorResult& aRv)
+  {
+    SetHTMLAttr(nsGkAtoms::poster, aValue, aRv);
+  }
+
+  uint32_t MozParsedFrames() const;
+
+  uint32_t MozDecodedFrames() const;
+
+  uint32_t MozPresentedFrames() const;
+
+  uint32_t MozPaintedFrames();
+
+  double MozFrameDelay();
+
+  bool MozHasAudio() const;
+
+protected:
+  virtual JSObject* WrapNode(JSContext* aCx, JSObject* aScope) MOZ_OVERRIDE;
 };
 
-#endif
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_HTMLVideoElement_h
--- a/content/html/content/public/Makefile.in
+++ b/content/html/content/public/Makefile.in
@@ -16,21 +16,21 @@ EXPORTS = \
 		nsIFormControl.h \
 		nsIForm.h \
 		nsIFormProcessor.h \
 		nsILink.h \
 		nsIRadioVisitor.h \
 		nsIRadioGroupContainer.h \
 		nsITextControlElement.h \
 		nsFormSubmission.h \
-		nsHTMLAudioElement.h \
-		nsHTMLMediaElement.h \
-		nsHTMLVideoElement.h \
 		nsIHTMLCollection.h \
 		$(NULL)
 
 EXPORTS_NAMESPACES = mozilla/dom
 
 EXPORTS_mozilla/dom = \
 		HTMLCanvasElement.h \
+		HTMLMediaElement.h \
+		HTMLAudioElement.h \
+		HTMLVideoElement.h \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
rename from content/html/content/src/nsHTMLAudioElement.cpp
rename to content/html/content/src/HTMLAudioElement.cpp
--- a/content/html/content/src/nsHTMLAudioElement.cpp
+++ b/content/html/content/src/HTMLAudioElement.cpp
@@ -1,87 +1,91 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/dom/HTMLAudioElement.h"
+#include "mozilla/dom/HTMLAudioElementBinding.h"
 #include "nsError.h"
 #include "nsIDOMHTMLAudioElement.h"
-#include "nsHTMLAudioElement.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsIDocument.h"
 #include "jsfriendapi.h"
 #include "nsContentUtils.h"
 #include "nsJSUtils.h"
 #include "AudioSampleFormat.h"
 #include "AudioChannelCommon.h"
 #include <algorithm>
 #include "mozilla/Preferences.h"
 
-using namespace mozilla;
-using namespace mozilla::dom;
+DOMCI_NODE_DATA(HTMLAudioElement, mozilla::dom::HTMLAudioElement)
 
 static bool
 IsAudioAPIEnabled()
 {
-  return Preferences::GetBool("media.audio_data.enabled", true);
+  return mozilla::Preferences::GetBool("media.audio_data.enabled", true);
 }
 
 nsGenericHTMLElement*
 NS_NewHTMLAudioElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                       FromParser aFromParser)
+                       mozilla::dom::FromParser aFromParser)
 {
   /*
-   * nsHTMLAudioElement's will be created without a nsINodeInfo passed in
+   * HTMLAudioElement's will be created without a nsINodeInfo passed in
    * if someone says "var audio = new Audio();" in JavaScript, in a case like
    * that we request the nsINodeInfo from the document's nodeinfo list.
    */
   nsCOMPtr<nsINodeInfo> nodeInfo(aNodeInfo);
   if (!nodeInfo) {
     nsCOMPtr<nsIDocument> doc =
       do_QueryInterface(nsContentUtils::GetDocumentFromCaller());
     NS_ENSURE_TRUE(doc, nullptr);
 
     nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::audio, nullptr,
                                                    kNameSpaceID_XHTML,
                                                    nsIDOMNode::ELEMENT_NODE);
     NS_ENSURE_TRUE(nodeInfo, nullptr);
   }
 
-  return new nsHTMLAudioElement(nodeInfo.forget());
+  return new mozilla::dom::HTMLAudioElement(nodeInfo.forget());
 }
 
-NS_IMPL_ADDREF_INHERITED(nsHTMLAudioElement, nsHTMLMediaElement)
-NS_IMPL_RELEASE_INHERITED(nsHTMLAudioElement, nsHTMLMediaElement)
+namespace mozilla {
+namespace dom {
 
-DOMCI_NODE_DATA(HTMLAudioElement, nsHTMLAudioElement)
+NS_IMPL_ADDREF_INHERITED(HTMLAudioElement, HTMLMediaElement)
+NS_IMPL_RELEASE_INHERITED(HTMLAudioElement, HTMLMediaElement)
 
-NS_INTERFACE_TABLE_HEAD(nsHTMLAudioElement)
-NS_HTML_CONTENT_INTERFACE_TABLE3(nsHTMLAudioElement, nsIDOMHTMLMediaElement,
+NS_INTERFACE_TABLE_HEAD(HTMLAudioElement)
+NS_HTML_CONTENT_INTERFACE_TABLE3(HTMLAudioElement, nsIDOMHTMLMediaElement,
                                  nsIDOMHTMLAudioElement, nsIJSNativeInitializer)
-NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLAudioElement,
-                                               nsHTMLMediaElement)
+NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(HTMLAudioElement,
+                                             HTMLMediaElement)
 NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLAudioElement)
 
-NS_IMPL_ELEMENT_CLONE(nsHTMLAudioElement)
+NS_IMPL_ELEMENT_CLONE(HTMLAudioElement)
 
 
-nsHTMLAudioElement::nsHTMLAudioElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-  : nsHTMLMediaElement(aNodeInfo)
+HTMLAudioElement::HTMLAudioElement(already_AddRefed<nsINodeInfo> aNodeInfo)
+  : HTMLMediaElement(aNodeInfo)
+{
+  SetIsDOMBinding();
+}
+
+HTMLAudioElement::~HTMLAudioElement()
 {
 }
 
-nsHTMLAudioElement::~nsHTMLAudioElement()
-{
-}
 
 NS_IMETHODIMP
-nsHTMLAudioElement::Initialize(nsISupports* aOwner, JSContext* aContext,
-                               JSObject *aObj, uint32_t argc, jsval *argv)
+HTMLAudioElement::Initialize(nsISupports* aOwner, JSContext* aContext,
+                             JSObject *aObj, uint32_t argc, jsval *argv)
 {
   // Audio elements created using "new Audio(...)" should have
   // 'preload' set to 'auto' (since the script must intend to
   // play the audio)
   nsresult rv = SetAttr(kNameSpaceID_None, nsGkAtoms::preload,
                         NS_LITERAL_STRING("auto"), true);
   if (NS_FAILED(rv))
     return rv;
@@ -100,134 +104,204 @@ nsHTMLAudioElement::Initialize(nsISuppor
   if (!str.init(aContext, jsstr))
     return NS_ERROR_FAILURE;
 
   // The only (optional) argument is the src of the audio (which must
   // be a URL string), used to initialize the 'src' attribute.
   return SetSrc(str);
 }
 
-NS_IMETHODIMP
-nsHTMLAudioElement::MozSetup(uint32_t aChannels, uint32_t aRate)
+already_AddRefed<HTMLAudioElement>
+HTMLAudioElement::Audio(const GlobalObject& aGlobal, ErrorResult& aRv)
+{
+  nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aGlobal.Get());
+  nsIDocument* doc;
+  if (!win || !(doc = win->GetExtantDoc())) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+
+  nsCOMPtr<nsINodeInfo> nodeInfo =
+    doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::audio, nullptr,
+                                        kNameSpaceID_XHTML,
+                                        nsIDOMNode::ELEMENT_NODE);
+  if (!nodeInfo) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+
+  nsRefPtr<HTMLAudioElement> audio = new HTMLAudioElement(nodeInfo.forget());
+  audio->SetHTMLAttr(nsGkAtoms::preload, NS_LITERAL_STRING("auto"), aRv);
+  if (aRv.Failed()) {
+    return nullptr;
+  }
+
+  return audio.forget();
+}
+
+already_AddRefed<HTMLAudioElement>
+HTMLAudioElement::Audio(const GlobalObject& aGlobal, const nsAString& aSrc, ErrorResult& aRv)
+{
+  nsRefPtr<HTMLAudioElement> audio = Audio(aGlobal, aRv);
+  if (audio) {
+    aRv = audio->SetSrc(aSrc);
+  }
+
+  return audio.forget();
+}
+
+void
+HTMLAudioElement::MozSetup(uint32_t aChannels, uint32_t aRate, ErrorResult& aRv)
 {
   if (!IsAudioAPIEnabled()) {
-    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+    aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    return;
   }
 
   // If there is already a src provided, don't setup another stream
   if (mDecoder) {
-    return NS_ERROR_FAILURE;
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
   }
 
   // MozWriteAudio divides by mChannels, so validate now.
   if (0 == aChannels) {
-    return NS_ERROR_FAILURE;
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
   }
 
   if (mAudioStream) {
     mAudioStream->Shutdown();
   }
 
   mAudioStream = AudioStream::AllocateStream();
-  nsresult rv = mAudioStream->Init(aChannels, aRate, mAudioChannelType);
-  if (NS_FAILED(rv)) {
+  aRv = mAudioStream->Init(aChannels, aRate, mAudioChannelType);
+  if (aRv.Failed()) {
     mAudioStream->Shutdown();
     mAudioStream = nullptr;
-    return rv;
+    return;
   }
 
   MetadataLoaded(aChannels, aRate, true, false, nullptr);
   mAudioStream->SetVolume(mVolume);
-
-  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLAudioElement::MozWriteAudio(const JS::Value& aData, JSContext* aCx, uint32_t* aRetVal)
+HTMLAudioElement::MozSetup(uint32_t aChannels, uint32_t aRate)
+{
+  ErrorResult rv;
+  MozSetup(aChannels, aRate, rv);
+  return rv.ErrorCode();
+}
+
+uint32_t
+HTMLAudioElement::MozWriteAudio(JSContext* aCx, JS::Value aData, ErrorResult& aRv)
 {
   if (!IsAudioAPIEnabled()) {
-    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+    aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    return 0;
   }
 
   if (!mAudioStream) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return 0;
   }
 
   if (!aData.isObject()) {
-    return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
+    aRv.Throw(NS_ERROR_DOM_TYPE_MISMATCH_ERR);
+    return 0;
   }
 
   JSObject* darray = &aData.toObject();
   JS::AutoObjectRooter tvr(aCx);
   JSObject* tsrc = NULL;
 
   // Allow either Float32Array or plain JS Array
   if (JS_IsFloat32Array(darray)) {
     tsrc = darray;
   } else if (JS_IsArrayObject(aCx, darray)) {
     JSObject* nobj = JS_NewFloat32ArrayFromArray(aCx, darray);
     if (!nobj) {
-      return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
+      aRv.Throw(NS_ERROR_DOM_TYPE_MISMATCH_ERR);
+      return 0;
     }
     tsrc = nobj;
   } else {
-    return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
+    aRv.Throw(NS_ERROR_DOM_TYPE_MISMATCH_ERR);
+    return 0;
   }
   tvr.setObject(tsrc);
 
   uint32_t dataLength = JS_GetTypedArrayLength(tsrc);
 
   // Make sure that we are going to write the correct amount of data based
   // on number of channels.
   if (dataLength % mChannels != 0) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return 0;
   }
 
   // Don't write more than can be written without blocking.
   uint32_t writeLen = std::min(mAudioStream->Available(), dataLength / mChannels);
 
   float* frames = JS_GetFloat32ArrayData(tsrc);
   // Convert the samples back to integers as we are using fixed point audio in
   // the AudioStream.
   // This could be optimized to avoid allocation and memcpy when
   // AudioDataValue is 'float', but it's not worth it for this deprecated API.
   nsAutoArrayPtr<AudioDataValue> audioData(new AudioDataValue[writeLen * mChannels]);
   ConvertAudioSamples(frames, audioData.get(), writeLen * mChannels);
-  nsresult rv = mAudioStream->Write(audioData.get(), writeLen);
-  if (NS_FAILED(rv)) {
-    return rv;
+  aRv = mAudioStream->Write(audioData.get(), writeLen);
+  if (aRv.Failed()) {
+    return 0;
   }
   mAudioStream->Start();
 
   // Return the actual amount written.
-  *aRetVal = writeLen * mChannels;
-  return rv;
+  return writeLen * mChannels;
 }
 
 NS_IMETHODIMP
-nsHTMLAudioElement::MozCurrentSampleOffset(uint64_t *aRetVal)
+HTMLAudioElement::MozWriteAudio(const JS::Value& aData, JSContext* aCx, uint32_t* aRetVal)
+{
+  ErrorResult rv;
+  *aRetVal = MozWriteAudio(aCx, aData, rv);
+  return rv.ErrorCode();
+}
+
+uint64_t
+HTMLAudioElement::MozCurrentSampleOffset(ErrorResult& aRv)
 {
   if (!IsAudioAPIEnabled()) {
-    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+    aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    return 0;
   }
 
   if (!mAudioStream) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return 0;
   }
 
   int64_t position = mAudioStream->GetPositionInFrames();
   if (position < 0) {
-    *aRetVal = 0;
-  } else {
-    *aRetVal = position * mChannels;
+    return 0;
   }
-  return NS_OK;
+
+  return position * mChannels;
 }
 
-nsresult nsHTMLAudioElement::SetAcceptHeader(nsIHttpChannel* aChannel)
+NS_IMETHODIMP
+HTMLAudioElement::MozCurrentSampleOffset(uint64_t *aRetVal)
+{
+  ErrorResult rv;
+  *aRetVal = MozCurrentSampleOffset(rv);
+  return rv.ErrorCode();
+}
+
+nsresult HTMLAudioElement::SetAcceptHeader(nsIHttpChannel* aChannel)
 {
     nsAutoCString value(
 #ifdef MOZ_WEBM
       "audio/webm,"
 #endif
 #ifdef MOZ_OGG
       "audio/ogg,"
 #endif
@@ -239,8 +313,17 @@ nsresult nsHTMLAudioElement::SetAcceptHe
       "application/ogg;q=0.7,"
 #endif
       "video/*;q=0.6,*/*;q=0.5");
 
     return aChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
                                       value,
                                       false);
 }
+
+JSObject*
+HTMLAudioElement::WrapNode(JSContext* aCx, JSObject* aScope)
+{
+  return HTMLAudioElementBinding::Wrap(aCx, aScope, this);
+}
+
+} // namespace dom
+} // namespace mozilla
rename from content/html/content/src/nsHTMLMediaElement.cpp
rename to content/html/content/src/HTMLMediaElement.cpp
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/HTMLMediaElement.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 "nsHTMLMediaElement.h"
+#include "mozilla/dom/HTMLMediaElement.h"
+#include "mozilla/dom/HTMLMediaElementBinding.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/Util.h"
 
 #include "base/basictypes.h"
 #include "nsIDOMHTMLMediaElement.h"
 #include "nsIDOMHTMLSourceElement.h"
 #include "TimeRanges.h"
 #include "nsGenericHTMLElement.h"
@@ -88,22 +89,22 @@ static PRLogModuleInfo* gMediaElementEve
 #include "nsIContentSecurityPolicy.h"
 #include "nsIChannelPolicy.h"
 #include "nsChannelPolicy.h"
 
 #include "mozilla/Preferences.h"
 
 #include "nsIPermissionManager.h"
 
-using namespace mozilla;
-using namespace mozilla::dom;
 using namespace mozilla::layers;
-
 using mozilla::net::nsMediaFragmentURIParser;
 
+namespace mozilla {
+namespace dom {
+
 // Number of milliseconds between timeupdate events as defined by spec
 #define TIMEUPDATE_MS 250
 
 // These constants are arbitrary
 // Minimum playbackRate for a media
 static const double MIN_PLAYBACKRATE = 0.25;
 // Maximum playbackRate for a media
 static const double MAX_PLAYBACKRATE = 5.0;
@@ -155,39 +156,39 @@ static const double THRESHOLD_LOW_PLAYBA
 // garbage collected while there are still event listeners that should
 // receive events. If we neglect to remove the self-reference then the element
 // just lives longer than it needs to.
 
 class nsMediaEvent : public nsRunnable
 {
 public:
 
-  nsMediaEvent(nsHTMLMediaElement* aElement) :
+  nsMediaEvent(HTMLMediaElement* aElement) :
     mElement(aElement),
     mLoadID(mElement->GetCurrentLoadID()) {}
   ~nsMediaEvent() {}
 
   NS_IMETHOD Run() = 0;
 
 protected:
   bool IsCancelled() {
     return mElement->GetCurrentLoadID() != mLoadID;
   }
 
-  nsRefPtr<nsHTMLMediaElement> mElement;
+  nsRefPtr<HTMLMediaElement> mElement;
   uint32_t mLoadID;
 };
 
 class nsAsyncEventRunner : public nsMediaEvent
 {
 private:
   nsString mName;
 
 public:
-  nsAsyncEventRunner(const nsAString& aName, nsHTMLMediaElement* aElement) :
+  nsAsyncEventRunner(const nsAString& aName, HTMLMediaElement* aElement) :
     nsMediaEvent(aElement), mName(aName)
   {
   }
 
   NS_IMETHOD Run()
   {
     // Silently cancel if our load has been cancelled.
     if (IsCancelled())
@@ -197,17 +198,17 @@ public:
   }
 };
 
 class nsSourceErrorEventRunner : public nsMediaEvent
 {
 private:
   nsCOMPtr<nsIContent> mSource;
 public:
-  nsSourceErrorEventRunner(nsHTMLMediaElement* aElement,
+  nsSourceErrorEventRunner(HTMLMediaElement* aElement,
                            nsIContent* aSource)
     : nsMediaEvent(aElement),
       mSource(aSource)
   {
   }
 
   NS_IMETHOD Run() {
     // Silently cancel if our load has been cancelled.
@@ -219,87 +220,87 @@ public:
                                                 NS_LITERAL_STRING("error"),
                                                 false,
                                                 false);
   }
 };
 
 /**
  * There is a reference cycle involving this class: MediaLoadListener
- * holds a reference to the nsHTMLMediaElement, which holds a reference
+ * holds a reference to the HTMLMediaElement, which holds a reference
  * to an nsIChannel, which holds a reference to this listener.
  * We break the reference cycle in OnStartRequest by clearing mElement.
  */
-class nsHTMLMediaElement::MediaLoadListener MOZ_FINAL : public nsIStreamListener,
-                                                        public nsIChannelEventSink,
-                                                        public nsIInterfaceRequestor,
-                                                        public nsIObserver
+class HTMLMediaElement::MediaLoadListener MOZ_FINAL : public nsIStreamListener,
+                                                      public nsIChannelEventSink,
+                                                      public nsIInterfaceRequestor,
+                                                      public nsIObserver
 {
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSICHANNELEVENTSINK
   NS_DECL_NSIOBSERVER
   NS_DECL_NSIINTERFACEREQUESTOR
 
 public:
-  MediaLoadListener(nsHTMLMediaElement* aElement)
+  MediaLoadListener(HTMLMediaElement* aElement)
     : mElement(aElement),
       mLoadID(aElement->GetCurrentLoadID())
   {
     NS_ABORT_IF_FALSE(mElement, "Must pass an element to call back");
   }
 
 private:
-  nsRefPtr<nsHTMLMediaElement> mElement;
+  nsRefPtr<HTMLMediaElement> mElement;
   nsCOMPtr<nsIStreamListener> mNextListener;
   uint32_t mLoadID;
 };
 
-NS_IMPL_ISUPPORTS5(nsHTMLMediaElement::MediaLoadListener, nsIRequestObserver,
+NS_IMPL_ISUPPORTS5(HTMLMediaElement::MediaLoadListener, nsIRequestObserver,
                    nsIStreamListener, nsIChannelEventSink,
                    nsIInterfaceRequestor, nsIObserver)
 
 NS_IMETHODIMP
-nsHTMLMediaElement::MediaLoadListener::Observe(nsISupports* aSubject,
-                                               const char* aTopic, const PRUnichar* aData)
+HTMLMediaElement::MediaLoadListener::Observe(nsISupports* aSubject,
+                                             const char* aTopic, const PRUnichar* aData)
 {
   nsContentUtils::UnregisterShutdownObserver(this);
 
   // Clear mElement to break cycle so we don't leak on shutdown
   mElement = nullptr;
   return NS_OK;
 }
 
-void nsHTMLMediaElement::ReportLoadError(const char* aMsg,
-                                         const PRUnichar** aParams,
-                                         uint32_t aParamCount)
+void HTMLMediaElement::ReportLoadError(const char* aMsg,
+                                       const PRUnichar** aParams,
+                                       uint32_t aParamCount)
 {
   nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
                                   "Media",
                                   OwnerDoc(),
                                   nsContentUtils::eDOM_PROPERTIES,
                                   aMsg,
                                   aParams,
                                   aParamCount);
 }
 
 
-NS_IMETHODIMP nsHTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
+NS_IMETHODIMP HTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
 {
   nsContentUtils::UnregisterShutdownObserver(this);
 
   if (!mElement) {
     // We've been notified by the shutdown observer, and are shutting down.
     return NS_BINDING_ABORTED;
   }
 
   // The element is only needed until we've had a chance to call
   // InitializeDecoderForChannel. So make sure mElement is cleared here.
-  nsRefPtr<nsHTMLMediaElement> element;
+  nsRefPtr<HTMLMediaElement> element;
   element.swap(mElement);
 
   if (mLoadID != element->GetCurrentLoadID()) {
     // The channel has been cancelled before we had a chance to create
     // a decoder. Abort, don't dispatch an "error" event, as the new load
     // may not be in an error state.
     return NS_BINDING_ABORTED;
   }
@@ -347,172 +348,195 @@ NS_IMETHODIMP nsHTMLMediaElement::MediaL
     // have otherwise succeeded), we abort the connection since we aren't
     // interested in keeping the channel alive ourselves.
     rv = NS_BINDING_ABORTED;
   }
 
   return rv;
 }
 
-NS_IMETHODIMP nsHTMLMediaElement::MediaLoadListener::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
-                                                                   nsresult aStatus)
+NS_IMETHODIMP HTMLMediaElement::MediaLoadListener::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
+                                                                 nsresult aStatus)
 {
   if (mNextListener) {
     return mNextListener->OnStopRequest(aRequest, aContext, aStatus);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLMediaElement::MediaLoadListener::OnDataAvailable(nsIRequest* aRequest,
-                                                       nsISupports* aContext,
-                                                       nsIInputStream* aStream,
-                                                       uint64_t aOffset,
-                                                       uint32_t aCount)
+HTMLMediaElement::MediaLoadListener::OnDataAvailable(nsIRequest* aRequest,
+                                                     nsISupports* aContext,
+                                                     nsIInputStream* aStream,
+                                                     uint64_t aOffset,
+                                                     uint32_t aCount)
 {
   if (!mNextListener) {
     NS_ERROR("Must have a chained listener; OnStartRequest should have canceled this request");
     return NS_BINDING_ABORTED;
   }
   return mNextListener->OnDataAvailable(aRequest, aContext, aStream, aOffset, aCount);
 }
 
-NS_IMETHODIMP nsHTMLMediaElement::MediaLoadListener::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
-                                                                            nsIChannel* aNewChannel,
-                                                                            uint32_t aFlags,
-                                                                            nsIAsyncVerifyRedirectCallback* cb)
+NS_IMETHODIMP HTMLMediaElement::MediaLoadListener::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
+                                                                          nsIChannel* aNewChannel,
+                                                                          uint32_t aFlags,
+                                                                          nsIAsyncVerifyRedirectCallback* cb)
 {
   // TODO is this really correct?? See bug #579329.
   if (mElement)
     mElement->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
   nsCOMPtr<nsIChannelEventSink> sink = do_QueryInterface(mNextListener);
   if (sink)
     return sink->AsyncOnChannelRedirect(aOldChannel, aNewChannel, aFlags, cb);
 
   cb->OnRedirectVerifyCallback(NS_OK);
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLMediaElement::MediaLoadListener::GetInterface(const nsIID & aIID, void **aResult)
+NS_IMETHODIMP HTMLMediaElement::MediaLoadListener::GetInterface(const nsIID & aIID, void **aResult)
 {
   return QueryInterface(aIID, aResult);
 }
 
-NS_IMPL_ADDREF_INHERITED(nsHTMLMediaElement, nsGenericHTMLElement)
-NS_IMPL_RELEASE_INHERITED(nsHTMLMediaElement, nsGenericHTMLElement)
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLMediaElement, nsGenericHTMLElement)
+NS_IMPL_ADDREF_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
+NS_IMPL_RELEASE_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSrcStream)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSrcAttrStream)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourcePointer)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoadBlockedDoc)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceLoadCandidate)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mError)
   for (uint32_t i = 0; i < tmp->mOutputStreams.Length(); ++i) {
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOutputStreams[i].mStream);
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLMediaElement, nsGenericHTMLElement)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
   if (tmp->mSrcStream) {
     // Need to EndMediaStreamPlayback to clear mStream and make sure everything
     // gets unhooked correctly.
     tmp->EndSrcMediaStreamPlayback();
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSrcAttrStream)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourcePointer)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoadBlockedDoc)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceLoadCandidate)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mError)
   for (uint32_t i = 0; i < tmp->mOutputStreams.Length(); ++i) {
     NS_IMPL_CYCLE_COLLECTION_UNLINK(mOutputStreams[i].mStream);
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsHTMLMediaElement)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLMediaElement)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
   NS_INTERFACE_MAP_ENTRY(nsIAudioChannelAgentCallback)
 NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
 
 // nsIDOMHTMLMediaElement
-NS_IMPL_URI_ATTR(nsHTMLMediaElement, Src, src)
-NS_IMPL_STRING_ATTR(nsHTMLMediaElement, Crossorigin, crossorigin)
-NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Controls, controls)
-NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Autoplay, autoplay)
-NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Loop, loop)
-NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, DefaultMuted, muted)
-NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLMediaElement, Preload, preload, NULL)
-NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLMediaElement, MozAudioChannelType, mozaudiochannel, "normal")
-
-NS_IMETHODIMP
-nsHTMLMediaElement::GetMozSrcObject(nsIDOMMediaStream** aStream)
+NS_IMPL_URI_ATTR(HTMLMediaElement, Src, src)
+NS_IMPL_STRING_ATTR(HTMLMediaElement, CrossOrigin, crossorigin)
+NS_IMPL_BOOL_ATTR(HTMLMediaElement, Controls, controls)
+NS_IMPL_BOOL_ATTR(HTMLMediaElement, Autoplay, autoplay)
+NS_IMPL_BOOL_ATTR(HTMLMediaElement, Loop, loop)
+NS_IMPL_BOOL_ATTR(HTMLMediaElement, DefaultMuted, muted)
+NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(HTMLMediaElement, Preload, preload, NULL)
+NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(HTMLMediaElement, MozAudioChannelType, mozaudiochannel, "normal")
+
+already_AddRefed<DOMMediaStream>
+HTMLMediaElement::GetMozSrcObject() const
 {
   NS_ASSERTION(!mSrcAttrStream || mSrcAttrStream->GetStream(),
                "MediaStream should have been set up properly");
   nsRefPtr<DOMMediaStream> stream = mSrcAttrStream;
-  stream.forget(aStream);
-  return NS_OK;
+  return stream.forget();
 }
 
 NS_IMETHODIMP
-nsHTMLMediaElement::SetMozSrcObject(nsIDOMMediaStream* aStream)
+HTMLMediaElement::GetMozSrcObject(nsIDOMMediaStream** aStream)
+{
+  nsRefPtr<DOMMediaStream> stream = GetMozSrcObject();
+  stream.forget(aStream);
+  return NS_OK;
+}
+
+void
+HTMLMediaElement::SetMozSrcObject(DOMMediaStream& aValue)
 {
-  mSrcAttrStream = static_cast<DOMMediaStream*>(aStream);
+  mSrcAttrStream = &aValue;
   Load();
+}
+
+NS_IMETHODIMP
+HTMLMediaElement::SetMozSrcObject(nsIDOMMediaStream* aStream)
+{
+  DOMMediaStream* stream = static_cast<DOMMediaStream*>(aStream);
+  SetMozSrcObject(*stream);
   return NS_OK;
 }
 
 /* readonly attribute nsIDOMHTMLMediaElement mozAutoplayEnabled; */
-NS_IMETHODIMP nsHTMLMediaElement::GetMozAutoplayEnabled(bool *aAutoplayEnabled)
+NS_IMETHODIMP HTMLMediaElement::GetMozAutoplayEnabled(bool *aAutoplayEnabled)
 {
   *aAutoplayEnabled = mAutoplayEnabled;
 
   return NS_OK;
 }
 
 /* readonly attribute nsIDOMMediaError error; */
-NS_IMETHODIMP nsHTMLMediaElement::GetError(nsIDOMMediaError * *aError)
+NS_IMETHODIMP HTMLMediaElement::GetError(nsIDOMMediaError * *aError)
 {
   NS_IF_ADDREF(*aError = mError);
 
   return NS_OK;
 }
 
 /* readonly attribute boolean ended; */
-NS_IMETHODIMP nsHTMLMediaElement::GetEnded(bool *aEnded)
+bool
+HTMLMediaElement::Ended()
 {
   if (mSrcStream) {
-    *aEnded = GetSrcMediaStream()->IsFinished();
-  } else if (mDecoder) {
-    *aEnded = mDecoder->IsEnded();
+    return GetSrcMediaStream()->IsFinished();
+  }
+
+  if (mDecoder) {
+    return mDecoder->IsEnded();
   }
+
+  return false;
+}
+
+NS_IMETHODIMP HTMLMediaElement::GetEnded(bool* aEnded)
+{
+  *aEnded = Ended();
   return NS_OK;
 }
 
 /* readonly attribute DOMString currentSrc; */
-NS_IMETHODIMP nsHTMLMediaElement::GetCurrentSrc(nsAString & aCurrentSrc)
+NS_IMETHODIMP HTMLMediaElement::GetCurrentSrc(nsAString & aCurrentSrc)
 {
   nsAutoCString src;
   GetCurrentSpec(src);
   aCurrentSrc = NS_ConvertUTF8toUTF16(src);
   return NS_OK;
 }
 
 /* readonly attribute unsigned short networkState; */
-NS_IMETHODIMP nsHTMLMediaElement::GetNetworkState(uint16_t *aNetworkState)
+NS_IMETHODIMP HTMLMediaElement::GetNetworkState(uint16_t* aNetworkState)
 {
-  *aNetworkState = mNetworkState;
-
+  *aNetworkState = NetworkState();
   return NS_OK;
 }
 
 nsresult
-nsHTMLMediaElement::OnChannelRedirect(nsIChannel *aChannel,
-                                      nsIChannel *aNewChannel,
-                                      uint32_t aFlags)
+HTMLMediaElement::OnChannelRedirect(nsIChannel* aChannel,
+                                    nsIChannel* aNewChannel,
+                                    uint32_t aFlags)
 {
   NS_ASSERTION(aChannel == mChannel, "Channels should match!");
   mChannel = aNewChannel;
 
   // Handle forwarding of Range header so that the intial detection
   // of seeking support (via result code 206) works across redirects.
   nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(aChannel);
   NS_ENSURE_STATE(http);
@@ -528,25 +552,25 @@ nsHTMLMediaElement::OnChannelRedirect(ns
 
     nsresult rv = http->SetRequestHeader(rangeHdr, rangeVal, false);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
-void nsHTMLMediaElement::ShutdownDecoder()
+void HTMLMediaElement::ShutdownDecoder()
 {
   RemoveMediaElementFromURITable();
   NS_ASSERTION(mDecoder, "Must have decoder to shut down");
   mDecoder->Shutdown();
   mDecoder = nullptr;
 }
 
-void nsHTMLMediaElement::AbortExistingLoads()
+void HTMLMediaElement::AbortExistingLoads()
 {
   // Abort any already-running instance of the resource selection algorithm.
   mLoadWaitStatus = NOT_WAITING;
 
   // Set a new load ID. This will cause events which were enqueued
   // with a different load ID to silently be cancelled.
   mCurrentLoadID++;
 
@@ -605,38 +629,38 @@ void nsHTMLMediaElement::AbortExistingLo
 
   // We may have changed mPaused, mAutoplaying, mNetworkState and other
   // things which can affect AddRemoveSelfReference
   AddRemoveSelfReference();
 
   mIsRunningSelectResource = false;
 }
 
-void nsHTMLMediaElement::NoSupportedMediaSourceError()
+void HTMLMediaElement::NoSupportedMediaSourceError()
 {
   NS_ASSERTION(mDelayingLoadEvent, "Load event not delayed during source selection?");
 
   mError = new MediaError(this, nsIDOMMediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
   mNetworkState = nsIDOMHTMLMediaElement::NETWORK_NO_SOURCE;
   DispatchAsyncEvent(NS_LITERAL_STRING("error"));
   // This clears mDelayingLoadEvent, so AddRemoveSelfReference will be called
   ChangeDelayLoadStatus(false);
 }
 
-typedef void (nsHTMLMediaElement::*SyncSectionFn)();
+typedef void (HTMLMediaElement::*SyncSectionFn)();
 
 // Runs a "synchronous section", a function that must run once the event loop
 // has reached a "stable state". See:
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#synchronous-section
 class nsSyncSection : public nsMediaEvent
 {
 private:
   SyncSectionFn mClosure;
 public:
-  nsSyncSection(nsHTMLMediaElement* aElement,
+  nsSyncSection(HTMLMediaElement* aElement,
                 SyncSectionFn aClosure) :
     nsMediaEvent(aElement),
     mClosure(aClosure)
   {
   }
 
   NS_IMETHOD Run() {
     // Silently cancel if our load has been cancelled.
@@ -647,86 +671,88 @@ public:
   }
 };
 
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 // Asynchronously awaits a stable state, whereupon aClosure runs on the main
 // thread. This adds an event which run aClosure to the appshell's list of
 // sections synchronous the next time control returns to the event loop.
-void AsyncAwaitStableState(nsHTMLMediaElement* aElement,
+void AsyncAwaitStableState(HTMLMediaElement* aElement,
                            SyncSectionFn aClosure)
 {
   nsCOMPtr<nsIRunnable> event = new nsSyncSection(aElement, aClosure);
   nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
   appShell->RunInStableState(event);
 }
 
-void nsHTMLMediaElement::QueueLoadFromSourceTask()
+void HTMLMediaElement::QueueLoadFromSourceTask()
 {
   ChangeDelayLoadStatus(true);
   mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
-  AsyncAwaitStableState(this, &nsHTMLMediaElement::LoadFromSourceChildren);
+  AsyncAwaitStableState(this, &HTMLMediaElement::LoadFromSourceChildren);
 }
 
-void nsHTMLMediaElement::QueueSelectResourceTask()
+void HTMLMediaElement::QueueSelectResourceTask()
 {
   // Don't allow multiple async select resource calls to be queued.
   if (mHaveQueuedSelectResource)
     return;
   mHaveQueuedSelectResource = true;
   mNetworkState = nsIDOMHTMLMediaElement::NETWORK_NO_SOURCE;
-  AsyncAwaitStableState(this, &nsHTMLMediaElement::SelectResourceWrapper);
+  AsyncAwaitStableState(this, &HTMLMediaElement::SelectResourceWrapper);
 }
 
 /* void load (); */
-NS_IMETHODIMP nsHTMLMediaElement::Load()
+NS_IMETHODIMP HTMLMediaElement::Load()
 {
   if (mIsRunningLoadMethod)
     return NS_OK;
+
   SetPlayedOrSeeked(false);
   mIsRunningLoadMethod = true;
   AbortExistingLoads();
   SetPlaybackRate(mDefaultPlaybackRate);
   QueueSelectResourceTask();
   ResetState();
   mIsRunningLoadMethod = false;
+
   return NS_OK;
 }
 
-void nsHTMLMediaElement::ResetState()
+void HTMLMediaElement::ResetState()
 {
   mMediaSize = nsIntSize(-1, -1);
   VideoFrameContainer* container = GetVideoFrameContainer();
   if (container) {
     container->Reset();
   }
 }
 
-static bool HasSourceChildren(nsIContent *aElement)
+static bool HasSourceChildren(nsIContent* aElement)
 {
   for (nsIContent* child = aElement->GetFirstChild();
        child;
        child = child->GetNextSibling()) {
     if (child->IsHTML(nsGkAtoms::source))
     {
       return true;
     }
   }
   return false;
 }
 
-void nsHTMLMediaElement::SelectResourceWrapper()
+void HTMLMediaElement::SelectResourceWrapper()
 {
   SelectResource();
   mIsRunningSelectResource = false;
   mHaveQueuedSelectResource = false;
 }
 
-void nsHTMLMediaElement::SelectResource()
+void HTMLMediaElement::SelectResource()
 {
   if (!mSrcAttrStream && !HasAttr(kNameSpaceID_None, nsGkAtoms::src) &&
       !HasSourceChildren(this)) {
     // The media element has neither a src attribute nor any source
     // element children, abort the load.
     mNetworkState = nsIDOMHTMLMediaElement::NETWORK_EMPTY;
     // This clears mDelayingLoadEvent, so AddRemoveSelfReference will be called
     ChangeDelayLoadStatus(false);
@@ -754,17 +780,17 @@ void nsHTMLMediaElement::SelectResource(
     nsCOMPtr<nsIURI> uri;
     nsresult rv = NewURIFromString(src, getter_AddRefs(uri));
     if (NS_SUCCEEDED(rv)) {
       LOG(PR_LOG_DEBUG, ("%p Trying load from src=%s", this, NS_ConvertUTF16toUTF8(src).get()));
       NS_ASSERTION(!mIsLoadingFromSourceChildren,
         "Should think we're not loading from source children by default");
 
       mLoadingSrc = uri;
-      if (mPreloadAction == nsHTMLMediaElement::PRELOAD_NONE) {
+      if (mPreloadAction == HTMLMediaElement::PRELOAD_NONE) {
         // preload:none media, suspend the load here before we make any
         // network requests.
         SuspendLoad();
         return;
       }
 
       rv = LoadResource();
       if (NS_SUCCEEDED(rv)) {
@@ -777,32 +803,32 @@ void nsHTMLMediaElement::SelectResource(
     NoSupportedMediaSourceError();
   } else {
     // Otherwise, the source elements will be used.
     mIsLoadingFromSourceChildren = true;
     LoadFromSourceChildren();
   }
 }
 
-void nsHTMLMediaElement::NotifyLoadError()
+void HTMLMediaElement::NotifyLoadError()
 {
   if (!mIsLoadingFromSourceChildren) {
     LOG(PR_LOG_DEBUG, ("NotifyLoadError(), no supported media error"));
     NoSupportedMediaSourceError();
   } else if (mSourceLoadCandidate) {
     DispatchAsyncSourceError(mSourceLoadCandidate);
     QueueLoadFromSourceTask();
   } else {
     NS_WARNING("Should know the source we were loading from!");
   }
 }
 
-void nsHTMLMediaElement::NotifyAudioAvailable(float* aFrameBuffer,
-                                              uint32_t aFrameBufferLength,
-                                              float aTime)
+void HTMLMediaElement::NotifyAudioAvailable(float* aFrameBuffer,
+                                            uint32_t aFrameBufferLength,
+                                            float aTime)
 {
   // Auto manage the memory for the frame buffer, so that if we add an early
   // return-on-error here in future, we won't forget to release the memory.
   // Otherwise we hand ownership of the memory over to the event created by
   // DispatchAudioAvailableEvent().
   nsAutoArrayPtr<float> frameBuffer(aFrameBuffer);
   // Do same-origin check on element and media before allowing MozAudioAvailable events.
   if (!mMediaSecurityVerified) {
@@ -811,17 +837,17 @@ void nsHTMLMediaElement::NotifyAudioAvai
     if (NS_FAILED(rv)) {
       mAllowAudioData = false;
     }
   }
 
   DispatchAudioAvailableEvent(frameBuffer.forget(), aFrameBufferLength, aTime);
 }
 
-void nsHTMLMediaElement::LoadFromSourceChildren()
+void HTMLMediaElement::LoadFromSourceChildren()
 {
   NS_ASSERTION(mDelayingLoadEvent,
                "Should delay load event (if in document) during load");
   NS_ASSERTION(mIsLoadingFromSourceChildren,
                "Must remember we're loading from source children");
 
   nsIDocument* parentDoc = OwnerDoc()->GetParentDocument();
   if (parentDoc) {
@@ -882,42 +908,42 @@ void nsHTMLMediaElement::LoadFromSourceC
       ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params));
       continue;
     }
 
     mLoadingSrc = uri;
     NS_ASSERTION(mNetworkState == nsIDOMHTMLMediaElement::NETWORK_LOADING,
                  "Network state should be loading");
 
-    if (mPreloadAction == nsHTMLMediaElement::PRELOAD_NONE) {
+    if (mPreloadAction == HTMLMediaElement::PRELOAD_NONE) {
       // preload:none media, suspend the load here before we make any
       // network requests.
       SuspendLoad();
       return;
     }
 
     if (NS_SUCCEEDED(LoadResource())) {
       return;
     }
 
     // If we fail to load, loop back and try loading the next resource.
     DispatchAsyncSourceError(child);
   }
   NS_NOTREACHED("Execution should not reach here!");
 }
 
-void nsHTMLMediaElement::SuspendLoad()
+void HTMLMediaElement::SuspendLoad()
 {
   mSuspendedForPreloadNone = true;
   mNetworkState = nsIDOMHTMLMediaElement::NETWORK_IDLE;
   DispatchAsyncEvent(NS_LITERAL_STRING("suspend"));
   ChangeDelayLoadStatus(false);
 }
 
-void nsHTMLMediaElement::ResumeLoad(PreloadAction aAction)
+void HTMLMediaElement::ResumeLoad(PreloadAction aAction)
 {
   NS_ASSERTION(mSuspendedForPreloadNone,
     "Must be halted for preload:none to resume from preload:none suspended load.");
   mSuspendedForPreloadNone = false;
   mPreloadAction = aAction;
   ChangeDelayLoadStatus(true);
   mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
   if (!mIsLoadingFromSourceChildren) {
@@ -934,91 +960,91 @@ void nsHTMLMediaElement::ResumeLoad(Prel
   }
 }
 
 static bool IsAutoplayEnabled()
 {
   return Preferences::GetBool("media.autoplay.enabled");
 }
 
-void nsHTMLMediaElement::UpdatePreloadAction()
+void HTMLMediaElement::UpdatePreloadAction()
 {
   PreloadAction nextAction = PRELOAD_UNDEFINED;
   // If autoplay is set, or we're playing, we should always preload data,
   // as we'll need it to play.
   if ((IsAutoplayEnabled() && HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay)) ||
       !mPaused)
   {
-    nextAction = nsHTMLMediaElement::PRELOAD_ENOUGH;
+    nextAction = HTMLMediaElement::PRELOAD_ENOUGH;
   } else {
     // Find the appropriate preload action by looking at the attribute.
     const nsAttrValue* val = mAttrsAndChildren.GetAttr(nsGkAtoms::preload,
                                                        kNameSpaceID_None);
     uint32_t preloadDefault =
       Preferences::GetInt("media.preload.default",
-                          nsHTMLMediaElement::PRELOAD_ATTR_METADATA);
+                          HTMLMediaElement::PRELOAD_ATTR_METADATA);
     uint32_t preloadAuto =
       Preferences::GetInt("media.preload.auto",
-                          nsHTMLMediaElement::PRELOAD_ENOUGH);
+                          HTMLMediaElement::PRELOAD_ENOUGH);
     if (!val) {
       // Attribute is not set. Use the preload action specified by the
       // media.preload.default pref, or just preload metadata if not present.
       nextAction = static_cast<PreloadAction>(preloadDefault);
     } else if (val->Type() == nsAttrValue::eEnum) {
       PreloadAttrValue attr = static_cast<PreloadAttrValue>(val->GetEnumValue());
-      if (attr == nsHTMLMediaElement::PRELOAD_ATTR_EMPTY ||
-          attr == nsHTMLMediaElement::PRELOAD_ATTR_AUTO)
+      if (attr == HTMLMediaElement::PRELOAD_ATTR_EMPTY ||
+          attr == HTMLMediaElement::PRELOAD_ATTR_AUTO)
       {
         nextAction = static_cast<PreloadAction>(preloadAuto);
-      } else if (attr == nsHTMLMediaElement::PRELOAD_ATTR_METADATA) {
-        nextAction = nsHTMLMediaElement::PRELOAD_METADATA;
-      } else if (attr == nsHTMLMediaElement::PRELOAD_ATTR_NONE) {
-        nextAction = nsHTMLMediaElement::PRELOAD_NONE;
+      } else if (attr == HTMLMediaElement::PRELOAD_ATTR_METADATA) {
+        nextAction = HTMLMediaElement::PRELOAD_METADATA;
+      } else if (attr == HTMLMediaElement::PRELOAD_ATTR_NONE) {
+        nextAction = HTMLMediaElement::PRELOAD_NONE;
       }
     } else {
       // Use the suggested "missing value default" of "metadata", or the value
       // specified by the media.preload.default, if present.
       nextAction = static_cast<PreloadAction>(preloadDefault);
     }
   }
 
   if ((mBegun || mIsRunningSelectResource) && nextAction < mPreloadAction) {
     // We've started a load or are already downloading, and the preload was
     // changed to a state where we buffer less. We don't support this case,
     // so don't change the preload behaviour.
     return;
   }
 
   mPreloadAction = nextAction;
-  if (nextAction == nsHTMLMediaElement::PRELOAD_ENOUGH) {
+  if (nextAction == HTMLMediaElement::PRELOAD_ENOUGH) {
     if (mSuspendedForPreloadNone) {
       // Our load was previouly suspended due to the media having preload
       // value "none". The preload value has changed to preload:auto, so
       // resume the load.
       ResumeLoad(PRELOAD_ENOUGH);
     } else {
       // Preload as much of the video as we can, i.e. don't suspend after
       // the first frame.
       StopSuspendingAfterFirstFrame();
     }
 
-  } else if (nextAction == nsHTMLMediaElement::PRELOAD_METADATA) {
+  } else if (nextAction == HTMLMediaElement::PRELOAD_METADATA) {
     // Ensure that the video can be suspended after first frame.
     mAllowSuspendAfterFirstFrame = true;
     if (mSuspendedForPreloadNone) {
       // Our load was previouly suspended due to the media having preload
       // value "none". The preload value has changed to preload:metadata, so
       // resume the load. We'll pause the load again after we've read the
       // metadata.
       ResumeLoad(PRELOAD_METADATA);
     }
   }
 }
 
-nsresult nsHTMLMediaElement::LoadResource()
+nsresult HTMLMediaElement::LoadResource()
 {
   NS_ASSERTION(mDelayingLoadEvent,
                "Should delay load event (if in document) during load");
 
   if (mChannel) {
     mChannel->Cancel(NS_BINDING_ABORTED);
     mChannel = nullptr;
   }
@@ -1036,17 +1062,17 @@ nsresult nsHTMLMediaElement::LoadResourc
   NS_ENSURE_SUCCESS(rv, rv);
   if (NS_CP_REJECTED(shouldLoad)) {
     return NS_ERROR_FAILURE;
   }
 
   // Set the media element's CORS mode only when loading a resource
   mCORSMode = AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
 
-  nsHTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc);
+  HTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc);
   if (other && other->mDecoder) {
     // Clone it.
     nsresult rv = InitializeDecoderAsClone(other->mDecoder);
     if (NS_SUCCEEDED(rv))
       return rv;
   }
 
   if (IsMediaStreamURI(mLoadingSrc)) {
@@ -1137,18 +1163,18 @@ nsresult nsHTMLMediaElement::LoadResourc
   mChannel = channel;
 
   // loadListener will be unregistered either on shutdown or when
   // OnStartRequest for the channel we just opened fires.
   nsContentUtils::RegisterShutdownObserver(loadListener);
   return NS_OK;
 }
 
-nsresult nsHTMLMediaElement::LoadWithChannel(nsIChannel *aChannel,
-                                             nsIStreamListener **aListener)
+nsresult HTMLMediaElement::LoadWithChannel(nsIChannel* aChannel,
+                                           nsIStreamListener** aListener)
 {
   NS_ENSURE_ARG_POINTER(aChannel);
   NS_ENSURE_ARG_POINTER(aListener);
 
   *aListener = nullptr;
 
   // Make sure we don't reenter during synchronous abort events.
   if (mIsRunningLoadMethod)
@@ -1168,202 +1194,262 @@ nsresult nsHTMLMediaElement::LoadWithCha
   }
 
   SetPlaybackRate(mDefaultPlaybackRate);
   DispatchAsyncEvent(NS_LITERAL_STRING("loadstart"));
 
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLMediaElement::MozLoadFrom(nsIDOMHTMLMediaElement* aOther)
+void
+HTMLMediaElement::MozLoadFrom(HTMLMediaElement& aOther, ErrorResult& aRv)
 {
-  NS_ENSURE_ARG_POINTER(aOther);
-
   // Make sure we don't reenter during synchronous abort events.
-  if (mIsRunningLoadMethod)
-    return NS_OK;
+  if (mIsRunningLoadMethod) {
+    return;
+  }
+
   mIsRunningLoadMethod = true;
   AbortExistingLoads();
   mIsRunningLoadMethod = false;
 
-  nsCOMPtr<nsIContent> content = do_QueryInterface(aOther);
-  nsHTMLMediaElement* other = static_cast<nsHTMLMediaElement*>(content.get());
-  if (!other || !other->mDecoder)
-    return NS_OK;
+  if (!aOther.mDecoder) {
+    return;
+  }
 
   ChangeDelayLoadStatus(true);
 
-  mLoadingSrc = other->mLoadingSrc;
-  nsresult rv = InitializeDecoderAsClone(other->mDecoder);
-  if (NS_FAILED(rv)) {
+  mLoadingSrc = aOther.mLoadingSrc;
+  aRv = InitializeDecoderAsClone(aOther.mDecoder);
+  if (aRv.Failed()) {
     ChangeDelayLoadStatus(false);
-    return rv;
+    return;
   }
 
   SetPlaybackRate(mDefaultPlaybackRate);
   DispatchAsyncEvent(NS_LITERAL_STRING("loadstart"));
-
-  return NS_OK;
+}
+
+NS_IMETHODIMP HTMLMediaElement::MozLoadFrom(nsIDOMHTMLMediaElement* aOther)
+{
+  NS_ENSURE_ARG_POINTER(aOther);
+
+  nsCOMPtr<nsIContent> content = do_QueryInterface(aOther);
+  HTMLMediaElement* other = static_cast<HTMLMediaElement*>(content.get());
+
+  if (!other) {
+    return NS_ERROR_FAILURE;
+  }
+
+  ErrorResult rv;
+  MozLoadFrom(*other, rv);
+
+  return rv.ErrorCode();
 }
 
 /* readonly attribute unsigned short readyState; */
-NS_IMETHODIMP nsHTMLMediaElement::GetReadyState(uint16_t *aReadyState)
+NS_IMETHODIMP HTMLMediaElement::GetReadyState(uint16_t* aReadyState)
 {
-  *aReadyState = mReadyState;
+  *aReadyState = ReadyState();
 
   return NS_OK;
 }
 
 /* readonly attribute boolean seeking; */
-NS_IMETHODIMP nsHTMLMediaElement::GetSeeking(bool *aSeeking)
+bool
+HTMLMediaElement::Seeking() const
 {
-  *aSeeking = mDecoder && mDecoder->IsSeeking();
-
+  return mDecoder && mDecoder->IsSeeking();
+}
+
+NS_IMETHODIMP HTMLMediaElement::GetSeeking(bool* aSeeking)
+{
+  *aSeeking = Seeking();
   return NS_OK;
 }
 
 /* attribute double currentTime; */
-NS_IMETHODIMP nsHTMLMediaElement::GetCurrentTime(double *aCurrentTime)
+double
+HTMLMediaElement::CurrentTime() const
 {
   if (mSrcStream) {
-    *aCurrentTime = MediaTimeToSeconds(GetSrcMediaStream()->GetCurrentTime());
-  } else if (mDecoder) {
-    *aCurrentTime = mDecoder->GetCurrentTime();
-  } else {
-    *aCurrentTime = 0.0;
+    return MediaTimeToSeconds(GetSrcMediaStream()->GetCurrentTime());
+  }
+
+  if (mDecoder) {
+    return mDecoder->GetCurrentTime();
   }
+
+  return 0.0;
+}
+
+NS_IMETHODIMP HTMLMediaElement::GetCurrentTime(double* aCurrentTime)
+{
+  *aCurrentTime = CurrentTime();
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLMediaElement::SetCurrentTime(double aCurrentTime)
+void
+HTMLMediaElement::SetCurrentTime(double aCurrentTime, ErrorResult& aRv)
 {
+  MOZ_ASSERT(aCurrentTime == aCurrentTime);
+
   StopSuspendingAfterFirstFrame();
 
   if (mSrcStream) {
     // do nothing since streams aren't seekable; we effectively clamp to
     // the current time.
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return;
   }
 
   if (mCurrentPlayRangeStart != -1.0) {
-    double rangeEndTime = 0;
-    GetCurrentTime(&rangeEndTime);
+    double rangeEndTime = CurrentTime();
     LOG(PR_LOG_DEBUG, ("%p Adding \'played\' a range : [%f, %f]", this, mCurrentPlayRangeStart, rangeEndTime));
     // Multiple seek without playing, or seek while playing.
     if (mCurrentPlayRangeStart != rangeEndTime) {
       mPlayed.Add(mCurrentPlayRangeStart, rangeEndTime);
     }
   }
 
   if (!mDecoder) {
     LOG(PR_LOG_DEBUG, ("%p SetCurrentTime(%f) failed: no decoder", this, aCurrentTime));
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return;
   }
 
   if (mReadyState == nsIDOMHTMLMediaElement::HAVE_NOTHING) {
     LOG(PR_LOG_DEBUG, ("%p SetCurrentTime(%f) failed: no source", this, aCurrentTime));
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
-  }
-
-  // Detect for a NaN and invalid values.
-  if (aCurrentTime != aCurrentTime) {
-    LOG(PR_LOG_DEBUG, ("%p SetCurrentTime(%f) failed: bad time", this, aCurrentTime));
-    return NS_ERROR_FAILURE;
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return;
   }
 
   // Clamp the time to [0, duration] as required by the spec.
   double clampedTime = std::max(0.0, aCurrentTime);
   double duration = mDecoder->GetDuration();
   if (duration >= 0) {
     clampedTime = std::min(clampedTime, duration);
   }
 
   mPlayingBeforeSeek = IsPotentiallyPlaying();
   // The media backend is responsible for dispatching the timeupdate
   // event if it changes the playback position as a result of the seek.
   LOG(PR_LOG_DEBUG, ("%p SetCurrentTime(%f) starting seek", this, aCurrentTime));
-  nsresult rv = mDecoder->Seek(clampedTime);
+  aRv = mDecoder->Seek(clampedTime);
   // Start a new range at position we seeked to.
   mCurrentPlayRangeStart = mDecoder->GetCurrentTime();
 
   // We changed whether we're seeking so we need to AddRemoveSelfReference.
   AddRemoveSelfReference();
-
-  return rv;
+}
+
+NS_IMETHODIMP HTMLMediaElement::SetCurrentTime(double aCurrentTime)
+{
+  // Detect for a NaN and invalid values.
+  if (aCurrentTime != aCurrentTime) {
+    LOG(PR_LOG_DEBUG, ("%p SetCurrentTime(%f) failed: bad time", this, aCurrentTime));
+    return NS_ERROR_FAILURE;
+  }
+
+  ErrorResult rv;
+  SetCurrentTime(aCurrentTime, rv);
+  return rv.ErrorCode();
 }
 
 /* readonly attribute double duration; */
-NS_IMETHODIMP nsHTMLMediaElement::GetDuration(double *aDuration)
+double
+HTMLMediaElement::Duration() const
 {
   if (mSrcStream) {
-    *aDuration = std::numeric_limits<double>::infinity();
-  } else if (mDecoder) {
-    *aDuration = mDecoder->GetDuration();
-  } else {
-    *aDuration = std::numeric_limits<double>::quiet_NaN();
+    return std::numeric_limits<double>::infinity();
+  }
+
+  if (mDecoder) {
+    return mDecoder->GetDuration();
   }
+
+  return std::numeric_limits<double>::quiet_NaN();
+}
+
+NS_IMETHODIMP HTMLMediaElement::GetDuration(double* aDuration)
+{
+  *aDuration = Duration();
   return NS_OK;
 }
 
-/* readonly attribute nsIDOMHTMLTimeRanges seekable; */
-NS_IMETHODIMP nsHTMLMediaElement::GetSeekable(nsIDOMTimeRanges** aSeekable)
+already_AddRefed<TimeRanges>
+HTMLMediaElement::Seekable() const
 {
   nsRefPtr<TimeRanges> ranges = new TimeRanges();
   if (mDecoder && mReadyState > nsIDOMHTMLMediaElement::HAVE_NOTHING) {
     mDecoder->GetSeekable(ranges);
   }
+  return ranges.forget();
+}
+
+/* readonly attribute nsIDOMHTMLTimeRanges seekable; */
+NS_IMETHODIMP HTMLMediaElement::GetSeekable(nsIDOMTimeRanges** aSeekable)
+{
+  nsRefPtr<TimeRanges> ranges = Seekable();
   ranges.forget(aSeekable);
   return NS_OK;
 }
 
-
 /* readonly attribute boolean paused; */
-NS_IMETHODIMP nsHTMLMediaElement::GetPaused(bool *aPaused)
+NS_IMETHODIMP HTMLMediaElement::GetPaused(bool* aPaused)
 {
-  *aPaused = mPaused;
+  *aPaused = Paused();
 
   return NS_OK;
 }
 
-/* readonly attribute nsIDOMHTMLTimeRanges played; */
-NS_IMETHODIMP nsHTMLMediaElement::GetPlayed(nsIDOMTimeRanges** aPlayed)
+already_AddRefed<TimeRanges>
+HTMLMediaElement::Played()
 {
-  TimeRanges* ranges = new TimeRanges();
-  NS_ADDREF(*aPlayed = ranges);
+  nsRefPtr<TimeRanges> ranges = new TimeRanges();
 
   uint32_t timeRangeCount = 0;
   mPlayed.GetLength(&timeRangeCount);
   for (uint32_t i = 0; i < timeRangeCount; i++) {
     double begin;
     double end;
     mPlayed.Start(i, &begin);
     mPlayed.End(i, &end);
     ranges->Add(begin, end);
   }
 
   if (mCurrentPlayRangeStart != -1.0) {
-    double now = 0.0;
-    GetCurrentTime(&now);
+    double now = CurrentTime();
     if (mCurrentPlayRangeStart != now) {
       ranges->Add(mCurrentPlayRangeStart, now);
     }
   }
 
   ranges->Normalize();
-
+  return ranges.forget();
+}
+
+/* readonly attribute nsIDOMHTMLTimeRanges played; */
+NS_IMETHODIMP HTMLMediaElement::GetPlayed(nsIDOMTimeRanges** aPlayed)
+{
+  nsRefPtr<TimeRanges> ranges = Played();
+  ranges.forget(aPlayed);
   return NS_OK;
 }
 
 /* void pause (); */
-NS_IMETHODIMP nsHTMLMediaElement::Pause()
+void
+HTMLMediaElement::Pause(ErrorResult& aRv)
 {
   if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
     LOG(PR_LOG_DEBUG, ("Loading due to Pause()"));
-    nsresult rv = Load();
-    NS_ENSURE_SUCCESS(rv, rv);
+    aRv = Load();
+    if (aRv.Failed()) {
+      return;
+    }
   } else if (mDecoder) {
     mDecoder->Pause();
   }
 
   bool oldPaused = mPaused;
   mPaused = true;
   mAutoplaying = false;
   // We changed mPaused and mAutoplaying which can affect AddRemoveSelfReference
@@ -1371,86 +1457,114 @@ NS_IMETHODIMP nsHTMLMediaElement::Pause(
 
   if (!oldPaused) {
     if (mSrcStream) {
       GetSrcMediaStream()->ChangeExplicitBlockerCount(1);
     }
     FireTimeUpdate(false);
     DispatchAsyncEvent(NS_LITERAL_STRING("pause"));
   }
-
-  return NS_OK;
+}
+
+NS_IMETHODIMP HTMLMediaElement::Pause()
+{
+  ErrorResult rv;
+  Pause(rv);
+  return rv.ErrorCode();
 }
 
 /* attribute double volume; */
-NS_IMETHODIMP nsHTMLMediaElement::GetVolume(double *aVolume)
+NS_IMETHODIMP HTMLMediaElement::GetVolume(double* aVolume)
 {
-  *aVolume = mVolume;
-
+  *aVolume = Volume();
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLMediaElement::SetVolume(double aVolume)
+void
+HTMLMediaElement::SetVolume(double aVolume, ErrorResult& aRv)
 {
-  if (!(aVolume >= 0.0 && aVolume <= 1.0))
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+  if (aVolume < 0.0 || aVolume > 1.0) {
+    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return;
+  }
 
   if (aVolume == mVolume)
-    return NS_OK;
+    return;
 
   mVolume = aVolume;
 
   if (!mMuted) {
     if (mDecoder) {
       mDecoder->SetVolume(mVolume);
     } else if (mAudioStream) {
       mAudioStream->SetVolume(mVolume);
     } else if (mSrcStream) {
       GetSrcMediaStream()->SetAudioOutputVolume(this, float(mVolume));
     }
   }
 
   DispatchAsyncEvent(NS_LITERAL_STRING("volumechange"));
-
-  return NS_OK;
+}
+
+NS_IMETHODIMP HTMLMediaElement::SetVolume(double aVolume)
+{
+  ErrorResult rv;
+  SetVolume(aVolume, rv);
+  return rv.ErrorCode();
+}
+
+uint32_t
+HTMLMediaElement::GetMozChannels(ErrorResult& aRv) const
+{
+  if (!mDecoder && !mAudioStream) {
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return 0;
+  }
+
+  return mChannels;
 }
 
 NS_IMETHODIMP
-nsHTMLMediaElement::GetMozChannels(uint32_t *aMozChannels)
+HTMLMediaElement::GetMozChannels(uint32_t* aMozChannels)
+{
+  ErrorResult rv;
+  *aMozChannels = GetMozChannels(rv);
+ return rv.ErrorCode();
+}
+
+uint32_t
+HTMLMediaElement::GetMozSampleRate(ErrorResult& aRv) const
 {
   if (!mDecoder && !mAudioStream) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return 0;
   }
 
-  *aMozChannels = mChannels;
-  return NS_OK;
+  return mRate;
 }
 
 NS_IMETHODIMP
-nsHTMLMediaElement::GetMozSampleRate(uint32_t *aMozSampleRate)
+HTMLMediaElement::GetMozSampleRate(uint32_t* aMozSampleRate)
 {
-  if (!mDecoder && !mAudioStream) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
-  }
-
-  *aMozSampleRate = mRate;
-  return NS_OK;
+  ErrorResult rv;
+  *aMozSampleRate = GetMozSampleRate(rv);
+  return rv.ErrorCode();
 }
 
 // Helper struct with arguments for our hash iterator.
 typedef struct {
   JSContext* cx;
   JSObject*  tags;
   bool error;
 } MetadataIterCx;
 
 PLDHashOperator
-nsHTMLMediaElement::BuildObjectFromTags(nsCStringHashKey::KeyType aKey,
-                                        nsCString aValue,
-                                        void* aUserArg)
+HTMLMediaElement::BuildObjectFromTags(nsCStringHashKey::KeyType aKey,
+                                      nsCString aValue,
+                                      void* aUserArg)
 {
   MetadataIterCx* args = static_cast<MetadataIterCx*>(aUserArg);
 
   nsString wideValue = NS_ConvertUTF8toUTF16(aValue);
   JSString* string = JS_NewUCStringCopyZ(args->cx, wideValue.Data());
   if (!string) {
     NS_WARNING("Failed to perform string copy");
     args->error = true;
@@ -1462,98 +1576,130 @@ nsHTMLMediaElement::BuildObjectFromTags(
     NS_WARNING("Failed to set metadata property");
     args->error = true;
     return PL_DHASH_STOP;
   }
 
   return PL_DHASH_NEXT;
 }
 
-NS_IMETHODIMP
-nsHTMLMediaElement::MozGetMetadata(JSContext* cx, JS::Value* aValue)
+JSObject*
+HTMLMediaElement::MozGetMetadata(JSContext* cx, ErrorResult& aRv)
 {
   if (mReadyState < nsIDOMHTMLMediaElement::HAVE_METADATA) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return nullptr;
   }
 
   JSObject* tags = JS_NewObject(cx, NULL, NULL, NULL);
   if (!tags) {
-    return NS_ERROR_FAILURE;
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
   }
   if (mTags) {
     MetadataIterCx iter = {cx, tags, false};
     mTags->EnumerateRead(BuildObjectFromTags, static_cast<void*>(&iter));
     if (iter.error) {
       NS_WARNING("couldn't create metadata object!");
-      return NS_ERROR_FAILURE;
+      aRv.Throw(NS_ERROR_FAILURE);
+      return nullptr;
     }
   }
-  *aValue = OBJECT_TO_JSVAL(tags);
-
-  return NS_OK;
+
+  return tags;
 }
 
 NS_IMETHODIMP
-nsHTMLMediaElement::GetMozFrameBufferLength(uint32_t *aMozFrameBufferLength)
+HTMLMediaElement::MozGetMetadata(JSContext* cx, JS::Value* aValue)
+{
+  ErrorResult rv;
+
+  JSObject* obj = MozGetMetadata(cx, rv);
+  if (!rv.Failed()) {
+    MOZ_ASSERT(obj);
+    *aValue = JS::ObjectValue(*obj);
+  }
+
+  return rv.ErrorCode();
+}
+
+uint32_t
+HTMLMediaElement::GetMozFrameBufferLength(ErrorResult& aRv) const
 {
   // The framebuffer (via MozAudioAvailable events) is only available
   // when reading vs. writing audio directly.
   if (!mDecoder) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return 0;
   }
 
-  *aMozFrameBufferLength = mDecoder->GetFrameBufferLength();
-  return NS_OK;
+  return mDecoder->GetFrameBufferLength();
 }
 
 NS_IMETHODIMP
-nsHTMLMediaElement::SetMozFrameBufferLength(uint32_t aMozFrameBufferLength)
+HTMLMediaElement::GetMozFrameBufferLength(uint32_t* aMozFrameBufferLength)
+{
+  ErrorResult rv;
+  *aMozFrameBufferLength = GetMozFrameBufferLength(rv);
+  return rv.ErrorCode();
+}
+
+void
+HTMLMediaElement::SetMozFrameBufferLength(uint32_t aMozFrameBufferLength, ErrorResult& aRv)
 {
-  if (!mDecoder)
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
-
-  return mDecoder->RequestFrameBufferLength(aMozFrameBufferLength);
+  if (!mDecoder) {
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return;
+  }
+
+  aRv = mDecoder->RequestFrameBufferLength(aMozFrameBufferLength);
+}
+
+NS_IMETHODIMP
+HTMLMediaElement::SetMozFrameBufferLength(uint32_t aMozFrameBufferLength)
+{
+  ErrorResult rv;
+  SetMozFrameBufferLength(aMozFrameBufferLength, rv);
+  return rv.ErrorCode();
 }
 
 /* attribute boolean muted; */
-NS_IMETHODIMP nsHTMLMediaElement::GetMuted(bool *aMuted)
+NS_IMETHODIMP HTMLMediaElement::GetMuted(bool* aMuted)
 {
-  *aMuted = mMuted;
-
+  *aMuted = Muted();
   return NS_OK;
 }
 
-void nsHTMLMediaElement::SetMutedInternal(bool aMuted)
+void HTMLMediaElement::SetMutedInternal(bool aMuted)
 {
   float effectiveVolume = aMuted ? 0.0f : float(mVolume);
 
   if (mDecoder) {
     mDecoder->SetVolume(effectiveVolume);
   } else if (mAudioStream) {
     mAudioStream->SetVolume(effectiveVolume);
   } else if (mSrcStream) {
     GetSrcMediaStream()->SetAudioOutputVolume(this, effectiveVolume);
   }
 }
 
-NS_IMETHODIMP nsHTMLMediaElement::SetMuted(bool aMuted)
+NS_IMETHODIMP HTMLMediaElement::SetMuted(bool aMuted)
 {
   if (aMuted == mMuted)
     return NS_OK;
 
   mMuted = aMuted;
   SetMutedInternal(aMuted);
 
   DispatchAsyncEvent(NS_LITERAL_STRING("volumechange"));
-
   return NS_OK;
 }
 
 already_AddRefed<DOMMediaStream>
-nsHTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded)
+HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded)
 {
   nsIDOMWindow* window = OwnerDoc()->GetInnerWindow();
   if (!window) {
     return nullptr;
   }
 
   OutputMediaStream* out = mOutputStreams.AppendElement();
   out->mStream = DOMMediaStream::CreateTrackUnionStream(window);
@@ -1570,97 +1716,117 @@ nsHTMLMediaElement::CaptureStreamInterna
     mDecoder->SetAudioCaptured(true);
     mDecoder->AddOutputStream(
         out->mStream->GetStream()->AsProcessedStream(), aFinishWhenEnded);
   }
   nsRefPtr<DOMMediaStream> result = out->mStream;
   return result.forget();
 }
 
-NS_IMETHODIMP nsHTMLMediaElement::MozCaptureStream(nsIDOMMediaStream** aStream)
+already_AddRefed<DOMMediaStream>
+HTMLMediaElement::MozCaptureStream(ErrorResult& aRv)
 {
-  *aStream = CaptureStreamInternal(false).get();
-  if (!*aStream) {
-    return NS_ERROR_FAILURE;
+  nsRefPtr<DOMMediaStream> stream = CaptureStreamInternal(false);
+  if (!stream) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
   }
-  return NS_OK;
+
+  return stream.forget();
 }
 
-NS_IMETHODIMP nsHTMLMediaElement::MozCaptureStreamUntilEnded(nsIDOMMediaStream** aStream)
+NS_IMETHODIMP HTMLMediaElement::MozCaptureStream(nsIDOMMediaStream** aStream)
 {
-  *aStream = CaptureStreamInternal(true).get();
-  if (!*aStream) {
-    return NS_ERROR_FAILURE;
+  ErrorResult rv;
+  *aStream = MozCaptureStream(rv).get();
+  return rv.ErrorCode();
+}
+
+already_AddRefed<DOMMediaStream>
+HTMLMediaElement::MozCaptureStreamUntilEnded(ErrorResult& aRv)
+{
+  nsRefPtr<DOMMediaStream> stream = CaptureStreamInternal(true);
+  if (!stream) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
   }
-  return NS_OK;
+
+  return stream.forget();
 }
 
-NS_IMETHODIMP nsHTMLMediaElement::GetMozAudioCaptured(bool *aCaptured)
+NS_IMETHODIMP HTMLMediaElement::MozCaptureStreamUntilEnded(nsIDOMMediaStream** aStream)
 {
-  *aCaptured = mAudioCaptured;
+  ErrorResult rv;
+  *aStream = MozCaptureStreamUntilEnded(rv).get();
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP HTMLMediaElement::GetMozAudioCaptured(bool* aCaptured)
+{
+  *aCaptured = MozAudioCaptured();
   return NS_OK;
 }
 
 class MediaElementSetForURI : public nsURIHashKey {
 public:
   MediaElementSetForURI(const nsIURI* aKey) : nsURIHashKey(aKey) {}
   MediaElementSetForURI(const MediaElementSetForURI& toCopy)
     : nsURIHashKey(toCopy), mElements(toCopy.mElements) {}
-  nsTArray<nsHTMLMediaElement*> mElements;
+  nsTArray<HTMLMediaElement*> mElements;
 };
 
 typedef nsTHashtable<MediaElementSetForURI> MediaElementURITable;
 // Elements in this table must have non-null mDecoder and mLoadingSrc, and those
 // can't change while the element is in the table. The table is keyed by
 // the element's mLoadingSrc. Each entry has a list of all elements with the
 // same mLoadingSrc.
 static MediaElementURITable* gElementTable;
 
 #ifdef DEBUG
 // Returns the number of times aElement appears in the media element table
 // for aURI. If this returns other than 0 or 1, there's a bug somewhere!
 static unsigned
-MediaElementTableCount(nsHTMLMediaElement* aElement, nsIURI* aURI)
+MediaElementTableCount(HTMLMediaElement* aElement, nsIURI* aURI)
 {
   if (!gElementTable || !aElement || !aURI) {
     return 0;
   }
   MediaElementSetForURI* entry = gElementTable->GetEntry(aURI);
   if (!entry) {
     return 0;
   }
   uint32_t count = 0;
   for (uint32_t i = 0; i < entry->mElements.Length(); ++i) {
-    nsHTMLMediaElement* elem = entry->mElements[i];
+    HTMLMediaElement* elem = entry->mElements[i];
     if (elem == aElement) {
       count++;
     }
   }
   return count;
 }
 #endif
 
 void
-nsHTMLMediaElement::AddMediaElementToURITable()
+HTMLMediaElement::AddMediaElementToURITable()
 {
   NS_ASSERTION(mDecoder && mDecoder->GetResource(), "Call this only with decoder Load called");
   NS_ASSERTION(MediaElementTableCount(this, mLoadingSrc) == 0,
     "Should not have entry for element in element table before addition");
   if (!gElementTable) {
     gElementTable = new MediaElementURITable();
     gElementTable->Init();
   }
   MediaElementSetForURI* entry = gElementTable->PutEntry(mLoadingSrc);
   entry->mElements.AppendElement(this);
   NS_ASSERTION(MediaElementTableCount(this, mLoadingSrc) == 1,
     "Should have a single entry for element in element table after addition");
 }
 
 void
-nsHTMLMediaElement::RemoveMediaElementFromURITable()
+HTMLMediaElement::RemoveMediaElementFromURITable()
 {
   NS_ASSERTION(MediaElementTableCount(this, mLoadingSrc) == 1,
     "Before remove, should have a single entry for element in element table");
   NS_ASSERTION(mDecoder, "Don't call this without decoder!");
   NS_ASSERTION(mLoadingSrc, "Can't have decoder without source!");
   if (!gElementTable)
     return;
   MediaElementSetForURI* entry = gElementTable->GetEntry(mLoadingSrc);
@@ -1673,42 +1839,42 @@ nsHTMLMediaElement::RemoveMediaElementFr
       delete gElementTable;
       gElementTable = nullptr;
     }
   }
   NS_ASSERTION(MediaElementTableCount(this, mLoadingSrc) == 0,
     "After remove, should no longer have an entry in element table");
 }
 
-nsHTMLMediaElement*
-nsHTMLMediaElement::LookupMediaElementURITable(nsIURI* aURI)
+HTMLMediaElement*
+HTMLMediaElement::LookupMediaElementURITable(nsIURI* aURI)
 {
   if (!gElementTable)
     return nullptr;
   MediaElementSetForURI* entry = gElementTable->GetEntry(aURI);
   if (!entry)
     return nullptr;
   for (uint32_t i = 0; i < entry->mElements.Length(); ++i) {
-    nsHTMLMediaElement* elem = entry->mElements[i];
+    HTMLMediaElement* elem = entry->mElements[i];
     bool equal;
     // Look for elements that have the same principal and CORS mode.
     // Ditto for anything else that could cause us to send different headers.
     if (NS_SUCCEEDED(elem->NodePrincipal()->Equals(NodePrincipal(), &equal)) && equal &&
         elem->mCORSMode == mCORSMode) {
       NS_ASSERTION(elem->mDecoder && elem->mDecoder->GetResource(), "Decoder gone");
       MediaResource* resource = elem->mDecoder->GetResource();
       if (resource->CanClone()) {
         return elem;
       }
     }
   }
   return nullptr;
 }
 
-nsHTMLMediaElement::nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo)
+HTMLMediaElement::HTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo),
     mSrcStreamListener(nullptr),
     mCurrentLoadID(0),
     mNetworkState(nsIDOMHTMLMediaElement::NETWORK_EMPTY),
     mReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING),
     mLoadWaitStatus(NOT_WAITING),
     mVolume(1.0),
     mChannels(0),
@@ -1763,17 +1929,17 @@ nsHTMLMediaElement::nsHTMLMediaElement(a
 #endif
 
   mPaused.SetOuter(this);
 
   RegisterFreezableElement();
   NotifyOwnerDocumentActivityChanged();
 }
 
-nsHTMLMediaElement::~nsHTMLMediaElement()
+HTMLMediaElement::~HTMLMediaElement()
 {
   NS_ASSERTION(!mHasSelfReference,
                "How can we be destroyed if we're still holding a self reference?");
 
   if (mVideoFrameContainer) {
     mVideoFrameContainer->ForgetElement();
   }
   UnregisterFreezableElement();
@@ -1791,41 +1957,41 @@ nsHTMLMediaElement::~nsHTMLMediaElement(
     mChannel->Cancel(NS_BINDING_ABORTED);
   }
   if (mAudioStream) {
     mAudioStream->Shutdown();
   }
 }
 
 void
-nsHTMLMediaElement::GetItemValueText(nsAString& aValue)
+HTMLMediaElement::GetItemValueText(nsAString& aValue)
 {
   // Can't call GetSrc because we don't have a JSContext
   GetURIAttr(nsGkAtoms::src, nullptr, aValue);
 }
 
 void
-nsHTMLMediaElement::SetItemValueText(const nsAString& aValue)
+HTMLMediaElement::SetItemValueText(const nsAString& aValue)
 {
   // Can't call SetSrc because we don't have a JSContext
   SetAttr(kNameSpaceID_None, nsGkAtoms::src, aValue, true);
 }
 
-void nsHTMLMediaElement::StopSuspendingAfterFirstFrame()
+void HTMLMediaElement::StopSuspendingAfterFirstFrame()
 {
   mAllowSuspendAfterFirstFrame = false;
   if (!mSuspendedAfterFirstFrame)
     return;
   mSuspendedAfterFirstFrame = false;
   if (mDecoder) {
     mDecoder->Resume(true);
   }
 }
 
-void nsHTMLMediaElement::SetPlayedOrSeeked(bool aValue)
+void HTMLMediaElement::SetPlayedOrSeeked(bool aValue)
 {
   if (aValue == mHasPlayedOrSeeked) {
     return;
   }
 
   mHasPlayedOrSeeked = aValue;
 
   // Force a reflow so that the poster frame hides or shows immediately.
@@ -1833,42 +1999,47 @@ void nsHTMLMediaElement::SetPlayedOrSeek
   if (!frame) {
     return;
   }
   frame->PresContext()->PresShell()->FrameNeedsReflow(frame,
                                                       nsIPresShell::eTreeChange,
                                                       NS_FRAME_IS_DIRTY);
 }
 
-NS_IMETHODIMP nsHTMLMediaElement::Play()
+void
+HTMLMediaElement::Play(ErrorResult& aRv)
 {
   StopSuspendingAfterFirstFrame();
   SetPlayedOrSeeked(true);
 
   if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
-    nsresult rv = Load();
-    NS_ENSURE_SUCCESS(rv, rv);
+    aRv = Load();
+    if (aRv.Failed()) {
+      return;
+    }
   }
   if (mSuspendedForPreloadNone) {
     ResumeLoad(PRELOAD_ENOUGH);
   }
   // Even if we just did Load() or ResumeLoad(), we could already have a decoder
   // here if we managed to clone an existing decoder.
   if (mDecoder) {
     if (mDecoder->IsEnded()) {
       SetCurrentTime(0);
     }
     if (!mPausedForInactiveDocumentOrChannel) {
-      nsresult rv = mDecoder->Play();
-      NS_ENSURE_SUCCESS(rv, rv);
+      aRv = mDecoder->Play();
+      if (aRv.Failed()) {
+        return;
+      }
     }
   }
 
   if (mCurrentPlayRangeStart == -1.0) {
-    GetCurrentTime(&mCurrentPlayRangeStart);
+    mCurrentPlayRangeStart = CurrentTime();
   }
 
   // TODO: If the playback has ended, then the user agent must set
   // seek to the effective start.
   if (mPaused) {
     if (mSrcStream) {
       GetSrcMediaStream()->ChangeExplicitBlockerCount(-1);
     }
@@ -1892,48 +2063,53 @@ NS_IMETHODIMP nsHTMLMediaElement::Play()
   SetPlaybackRate(mDefaultPlaybackRate);
 
   mPaused = false;
   mAutoplaying = false;
   // We changed mPaused and mAutoplaying which can affect AddRemoveSelfReference
   // and our preload status.
   AddRemoveSelfReference();
   UpdatePreloadAction();
-
-  return NS_OK;
 }
 
-nsHTMLMediaElement::WakeLockBoolWrapper& nsHTMLMediaElement::WakeLockBoolWrapper::operator=(bool val) {
+NS_IMETHODIMP HTMLMediaElement::Play()
+{
+  ErrorResult rv;
+  Play(rv);
+  return rv.ErrorCode();
+}
+
+HTMLMediaElement::WakeLockBoolWrapper& HTMLMediaElement::WakeLockBoolWrapper::operator=(bool val) {
   if (mValue == val)
     return *this;
   if (!mWakeLock && !val && mOuter) {
     nsCOMPtr<nsIPowerManagerService> pmService =
       do_GetService(POWERMANAGERSERVICE_CONTRACTID);
     NS_ENSURE_TRUE(pmService, *this);
 
     pmService->NewWakeLock(NS_LITERAL_STRING("Playing_media"), mOuter->OwnerDoc()->GetWindow(), getter_AddRefs(mWakeLock));
   } else if (mWakeLock && val) {
     mWakeLock->Unlock();
     mWakeLock = NULL;
   }
   mValue = val;
   return *this;
 }
 
-bool nsHTMLMediaElement::ParseAttribute(int32_t aNamespaceID,
-                                        nsIAtom* aAttribute,
-                                        const nsAString& aValue,
-                                        nsAttrValue& aResult)
+bool HTMLMediaElement::ParseAttribute(int32_t aNamespaceID,
+                                      nsIAtom* aAttribute,
+                                      const nsAString& aValue,
+                                      nsAttrValue& aResult)
 {
   // Mappings from 'preload' attribute strings to an enumeration.
   static const nsAttrValue::EnumTable kPreloadTable[] = {
-    { "",         nsHTMLMediaElement::PRELOAD_ATTR_EMPTY },
-    { "none",     nsHTMLMediaElement::PRELOAD_ATTR_NONE },
-    { "metadata", nsHTMLMediaElement::PRELOAD_ATTR_METADATA },
-    { "auto",     nsHTMLMediaElement::PRELOAD_ATTR_AUTO },
+    { "",         HTMLMediaElement::PRELOAD_ATTR_EMPTY },
+    { "none",     HTMLMediaElement::PRELOAD_ATTR_NONE },
+    { "metadata", HTMLMediaElement::PRELOAD_ATTR_METADATA },
+    { "auto",     HTMLMediaElement::PRELOAD_ATTR_AUTO },
     { 0 }
   };
 
   // Mappings from 'mozaudiochannel' attribute strings to an enumeration.
   static const nsAttrValue::EnumTable kMozAudioChannelAttributeTable[] = {
     { "normal",             AUDIO_CHANNEL_NORMAL },
     { "content",            AUDIO_CHANNEL_CONTENT },
     { "notification",       AUDIO_CHANNEL_NOTIFICATION },
@@ -1974,17 +2150,17 @@ bool nsHTMLMediaElement::ParseAttribute(
       return true;
     }
   }
 
   return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aResult);
 }
 
-bool nsHTMLMediaElement::CheckAudioChannelPermissions(const nsAString& aString)
+bool HTMLMediaElement::CheckAudioChannelPermissions(const nsAString& aString)
 {
 #ifdef MOZ_B2G
   // Only normal channel doesn't need permission.
   if (!aString.EqualsASCII("normal")) {
     nsCOMPtr<nsIPermissionManager> permissionManager =
       do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
     if (!permissionManager) {
       return false;
@@ -1996,42 +2172,42 @@ bool nsHTMLMediaElement::CheckAudioChann
     if (perm != nsIPermissionManager::ALLOW_ACTION) {
       return false;
     }
   }
 #endif
   return true;
 }
 
-void nsHTMLMediaElement::DoneCreatingElement()
+void HTMLMediaElement::DoneCreatingElement()
 {
    if (HasAttr(kNameSpaceID_None, nsGkAtoms::muted))
      mMuted = true;
 }
 
-bool nsHTMLMediaElement::IsHTMLFocusable(bool aWithMouse,
-                                         bool *aIsFocusable,
-                                         int32_t *aTabIndex)
+bool HTMLMediaElement::IsHTMLFocusable(bool aWithMouse,
+                                       bool* aIsFocusable,
+                                       int32_t* aTabIndex)
 {
   if (nsGenericHTMLElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
     return true;
   }
 
   *aIsFocusable = true;
   return false;
 }
 
-int32_t nsHTMLMediaElement::TabIndexDefault()
+int32_t HTMLMediaElement::TabIndexDefault()
 {
   return 0;
 }
 
-nsresult nsHTMLMediaElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
-                                     nsIAtom* aPrefix, const nsAString& aValue,
-                                     bool aNotify)
+nsresult HTMLMediaElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
+                                   nsIAtom* aPrefix, const nsAString& aValue,
+                                   bool aNotify)
 {
   nsresult rv =
     nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
                                   aNotify);
   if (NS_FAILED(rv))
     return rv;
   if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::src) {
     Load();
@@ -2048,18 +2224,18 @@ nsresult nsHTMLMediaElement::SetAttr(int
     } else if (aName == nsGkAtoms::preload) {
       UpdatePreloadAction();
     }
   }
 
   return rv;
 }
 
-nsresult nsHTMLMediaElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttr,
-                                       bool aNotify)
+nsresult HTMLMediaElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttr,
+                                     bool aNotify)
 {
   nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttr, aNotify);
   if (NS_FAILED(rv))
     return rv;
   if (aNotify && aNameSpaceID == kNameSpaceID_None) {
     if (aAttr == nsGkAtoms::autoplay) {
       // This attribute can affect AddRemoveSelfReference
       AddRemoveSelfReference();
@@ -2067,19 +2243,19 @@ nsresult nsHTMLMediaElement::UnsetAttr(i
     } else if (aAttr == nsGkAtoms::preload) {
       UpdatePreloadAction();
     }
   }
 
   return rv;
 }
 
-nsresult nsHTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
-                                        nsIContent* aBindingParent,
-                                        bool aCompileEventHandlers)
+nsresult HTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
+                                      nsIContent* aBindingParent,
+                                      bool aCompileEventHandlers)
 {
   nsresult rv = nsGenericHTMLElement::BindToTree(aDocument,
                                                  aParent,
                                                  aBindingParent,
                                                  aCompileEventHandlers);
   if (aDocument) {
     mAutoplayEnabled =
       IsAutoplayEnabled() && (!aDocument || !aDocument->IsStaticDocument()) &&
@@ -2094,27 +2270,27 @@ nsresult nsHTMLMediaElement::BindToTree(
       // "MozAudioAvailable" event dispatch.
       NotifyAudioAvailableListener();
     }
   }
 
   return rv;
 }
 
-void nsHTMLMediaElement::UnbindFromTree(bool aDeep,
-                                        bool aNullParent)
+void HTMLMediaElement::UnbindFromTree(bool aDeep,
+                                      bool aNullParent)
 {
   if (!mPaused && mNetworkState != nsIDOMHTMLMediaElement::NETWORK_EMPTY)
     Pause();
   nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
 }
 
 /* static */
 CanPlayStatus
-nsHTMLMediaElement::GetCanPlay(const nsAString& aType)
+HTMLMediaElement::GetCanPlay(const nsAString& aType)
 {
   nsContentTypeParser parser(aType);
   nsAutoString mimeType;
   nsresult rv = parser.GetType(mimeType);
   if (NS_FAILED(rv))
     return CANPLAY_NO;
 
   nsAutoString codecs;
@@ -2122,17 +2298,17 @@ nsHTMLMediaElement::GetCanPlay(const nsA
 
   NS_ConvertUTF16toUTF8 mimeTypeUTF8(mimeType);
   return DecoderTraits::CanHandleMediaType(mimeTypeUTF8.get(),
                                            NS_SUCCEEDED(rv),
                                            codecs);
 }
 
 NS_IMETHODIMP
-nsHTMLMediaElement::CanPlayType(const nsAString& aType, nsAString& aResult)
+HTMLMediaElement::CanPlayType(const nsAString& aType, nsAString& aResult)
 {
   switch (GetCanPlay(aType)) {
   case CANPLAY_NO:
     aResult.Truncate();
     break;
   case CANPLAY_YES:
     aResult.AssignLiteral("probably");
     break;
@@ -2144,17 +2320,17 @@ nsHTMLMediaElement::CanPlayType(const ns
 
   LOG(PR_LOG_DEBUG, ("%p CanPlayType(%s) = \"%s\"", this,
                      NS_ConvertUTF16toUTF8(aType).get(),
                      NS_ConvertUTF16toUTF8(aResult).get()));
 
   return NS_OK;
 }
 
-nsresult nsHTMLMediaElement::InitializeDecoderAsClone(MediaDecoder* aOriginal)
+nsresult HTMLMediaElement::InitializeDecoderAsClone(MediaDecoder* aOriginal)
 {
   NS_ASSERTION(mLoadingSrc, "mLoadingSrc must already be set");
   NS_ASSERTION(mDecoder == nullptr, "Shouldn't have a decoder");
 
   MediaResource* originalResource = aOriginal->GetResource();
   if (!originalResource)
     return NS_ERROR_FAILURE;
   nsRefPtr<MediaDecoder> decoder = aOriginal->Clone();
@@ -2179,18 +2355,18 @@ nsresult nsHTMLMediaElement::InitializeD
   if (!resource) {
     LOG(PR_LOG_DEBUG, ("%p Failed to cloned stream for decoder %p", this, decoder.get()));
     return NS_ERROR_FAILURE;
   }
 
   return FinishDecoderSetup(decoder, resource, nullptr, aOriginal);
 }
 
-nsresult nsHTMLMediaElement::InitializeDecoderForChannel(nsIChannel *aChannel,
-                                                         nsIStreamListener **aListener)
+nsresult HTMLMediaElement::InitializeDecoderForChannel(nsIChannel* aChannel,
+                                                       nsIStreamListener** aListener)
 {
   NS_ASSERTION(mLoadingSrc, "mLoadingSrc must already be set");
   NS_ASSERTION(mDecoder == nullptr, "Shouldn't have a decoder");
 
   nsAutoCString mimeType;
 
   aChannel->GetContentType(mimeType);
   NS_ASSERTION(!mimeType.IsEmpty(), "We should have the Content-Type.");
@@ -2212,20 +2388,20 @@ nsresult nsHTMLMediaElement::InitializeD
     return NS_ERROR_OUT_OF_MEMORY;
 
   // stream successfully created, the stream now owns the channel.
   mChannel = nullptr;
 
   return FinishDecoderSetup(decoder, resource, aListener, nullptr);
 }
 
-nsresult nsHTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder,
-                                                MediaResource* aStream,
-                                                nsIStreamListener **aListener,
-                                                MediaDecoder* aCloneDonor)
+nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder,
+                                              MediaResource* aStream,
+                                              nsIStreamListener** aListener,
+                                              MediaDecoder* aCloneDonor)
 {
   mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
 
   // Force a same-origin check before allowing events for this media resource.
   mMediaSecurityVerified = false;
 
   // The new stream has not been suspended by us.
   mPausedForInactiveDocumentOrChannel = false;
@@ -2279,23 +2455,23 @@ nsresult nsHTMLMediaElement::FinishDecod
 
   NS_ASSERTION(NS_SUCCEEDED(rv) == (MediaElementTableCount(this, mLoadingSrc) == 1),
     "Media element should have single table entry if decode initialized");
 
   mBegun = true;
   return rv;
 }
 
-class nsHTMLMediaElement::StreamListener : public MediaStreamListener {
+class HTMLMediaElement::StreamListener : public MediaStreamListener {
 public:
-  StreamListener(nsHTMLMediaElement* aElement) :
+  StreamListener(HTMLMediaElement* aElement) :
     mElement(aElement),
     mHaveCurrentData(false),
     mBlocked(false),
-    mMutex("nsHTMLMediaElement::StreamListener"),
+    mMutex("HTMLMediaElement::StreamListener"),
     mPendingNotifyOutput(false),
     mDidHaveCurrentData(false)
   {}
   void Forget() { mElement = nullptr; }
 
   // Main thread
   void DoNotifyFinished()
   {
@@ -2383,27 +2559,27 @@ public:
     mPendingNotifyOutput = true;
     nsCOMPtr<nsIRunnable> event =
       NS_NewRunnableMethod(this, &StreamListener::DoNotifyOutput);
     aGraph->DispatchToMainThreadAfterStreamStateUpdate(event.forget());
   }
 
 private:
   // These fields may only be accessed on the main thread
-  nsHTMLMediaElement* mElement;
+  HTMLMediaElement* mElement;
   bool mHaveCurrentData;
   bool mBlocked;
 
   // mMutex protects the fields below; they can be accessed on any thread
   Mutex mMutex;
   bool mPendingNotifyOutput;
   bool mDidHaveCurrentData;
 };
 
-void nsHTMLMediaElement::SetupSrcMediaStreamPlayback(DOMMediaStream* aStream)
+void HTMLMediaElement::SetupSrcMediaStreamPlayback(DOMMediaStream* aStream)
 {
   NS_ASSERTION(!mSrcStream && !mSrcStreamListener, "Should have been ended already");
 
   mSrcStream = aStream;
   // XXX if we ever support capturing the output of a media element which is
   // playing a stream, we'll need to add a CombineWithPrincipal call here.
   mSrcStreamListener = new StreamListener(this);
   GetSrcMediaStream()->AddListener(mSrcStreamListener);
@@ -2425,17 +2601,17 @@ void nsHTMLMediaElement::SetupSrcMediaSt
   DispatchAsyncEvent(NS_LITERAL_STRING("loadedmetadata"));
   DispatchAsyncEvent(NS_LITERAL_STRING("suspend"));
   mNetworkState = nsIDOMHTMLMediaElement::NETWORK_IDLE;
   AddRemoveSelfReference();
   // FirstFrameLoaded(false) will be called when the stream has current data,
   // to complete the setup by entering the HAVE_CURRENT_DATA state.
 }
 
-void nsHTMLMediaElement::EndSrcMediaStreamPlayback()
+void HTMLMediaElement::EndSrcMediaStreamPlayback()
 {
   GetSrcMediaStream()->RemoveListener(mSrcStreamListener);
   // Kill its reference to this element
   mSrcStreamListener->Forget();
   mSrcStreamListener = nullptr;
   GetSrcMediaStream()->RemoveAudioOutput(this);
   VideoFrameContainer* container = GetVideoFrameContainer();
   if (container) {
@@ -2446,17 +2622,17 @@ void nsHTMLMediaElement::EndSrcMediaStre
     GetSrcMediaStream()->ChangeExplicitBlockerCount(-1);
   }
   if (mPausedForInactiveDocumentOrChannel) {
     GetSrcMediaStream()->ChangeExplicitBlockerCount(-1);
   }
   mSrcStream = nullptr;
 }
 
-nsresult nsHTMLMediaElement::NewURIFromString(const nsAutoString& aURISpec, nsIURI** aURI)
+nsresult HTMLMediaElement::NewURIFromString(const nsAutoString& aURISpec, nsIURI** aURI)
 {
   NS_ENSURE_ARG_POINTER(aURI);
 
   *aURI = nullptr;
 
   nsCOMPtr<nsIDocument> doc = OwnerDoc();
 
   nsCOMPtr<nsIURI> baseURI = GetBaseURI();
@@ -2478,35 +2654,35 @@ nsresult nsHTMLMediaElement::NewURIFromS
     // decode it.
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
 
   uri.forget(aURI);
   return NS_OK;
 }
 
-void nsHTMLMediaElement::ProcessMediaFragmentURI()
+void HTMLMediaElement::ProcessMediaFragmentURI()
 {
   nsMediaFragmentURIParser parser(mLoadingSrc);
 
   if (mDecoder && parser.HasEndTime()) {
     mFragmentEnd = parser.GetEndTime();
   }
 
   if (parser.HasStartTime()) {
     SetCurrentTime(parser.GetStartTime());
     mFragmentStart = parser.GetStartTime();
   }
 }
 
-void nsHTMLMediaElement::MetadataLoaded(int aChannels,
-                                        int aRate,
-                                        bool aHasAudio,
-                                        bool aHasVideo,
-                                        const MetadataTags* aTags)
+void HTMLMediaElement::MetadataLoaded(int aChannels,
+                                      int aRate,
+                                      bool aHasAudio,
+                                      bool aHasVideo,
+                                      const MetadataTags* aTags)
 {
   mChannels = aChannels;
   mRate = aRate;
   mHasAudio = aHasAudio;
   mTags = aTags;
   ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
   DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
   DispatchAsyncEvent(NS_LITERAL_STRING("loadedmetadata"));
@@ -2518,29 +2694,29 @@ void nsHTMLMediaElement::MetadataLoaded(
   // If this element had a video track, but consists only of an audio track now,
   // delete the VideoFrameContainer. This happens when the src is changed to an
   // audio only file.
   if (!aHasVideo) {
     mVideoFrameContainer = nullptr;
   }
 }
 
-void nsHTMLMediaElement::FirstFrameLoaded(bool aResourceFullyLoaded)
+void HTMLMediaElement::FirstFrameLoaded(bool aResourceFullyLoaded)
 {
   ChangeReadyState(aResourceFullyLoaded ?
     nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA :
     nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA);
   ChangeDelayLoadStatus(false);
 
   NS_ASSERTION(!mSuspendedAfterFirstFrame, "Should not have already suspended");
 
   if (mDecoder && mAllowSuspendAfterFirstFrame && mPaused &&
       !aResourceFullyLoaded &&
       !HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) &&
-      mPreloadAction == nsHTMLMediaElement::PRELOAD_METADATA) {
+      mPreloadAction == HTMLMediaElement::PRELOAD_METADATA) {
     mSuspendedAfterFirstFrame = true;
     mDecoder->Suspend();
   } else if (mLoadedFirstFrame &&
              mDownloadSuspendedByCache &&
              mDecoder &&
              !mDecoder->IsEnded()) {
     // We've already loaded the first frame, and the decoder has signalled
     // that the download has been suspended by the media cache. So move
@@ -2550,17 +2726,17 @@ void nsHTMLMediaElement::FirstFrameLoade
     // that the download was suspended before the first frame was loaded.
     // Don't force this transition if the decoder is in ended state; the
     // readyState should remain at HAVE_CURRENT_DATA in this case.
     ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA);
     return;
   }
 }
 
-void nsHTMLMediaElement::ResourceLoaded()
+void HTMLMediaElement::ResourceLoaded()
 {
   NS_ASSERTION(!mSrcStream, "Don't call this for streams");
 
   mBegun = false;
   mNetworkState = nsIDOMHTMLMediaElement::NETWORK_IDLE;
   AddRemoveSelfReference();
   if (mReadyState >= nsIDOMHTMLMediaElement::HAVE_METADATA) {
     // MediaStream sources are put into HAVE_CURRENT_DATA state here on setup. If the
@@ -2570,22 +2746,22 @@ void nsHTMLMediaElement::ResourceLoaded(
                      : nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA);
   }
   // Ensure a progress event is dispatched at the end of download.
   DispatchAsyncEvent(NS_LITERAL_STRING("progress"));
   // The download has stopped.
   DispatchAsyncEvent(NS_LITERAL_STRING("suspend"));
 }
 
-void nsHTMLMediaElement::NetworkError()
+void HTMLMediaElement::NetworkError()
 {
   Error(nsIDOMMediaError::MEDIA_ERR_NETWORK);
 }
 
-void nsHTMLMediaElement::DecodeError()
+void HTMLMediaElement::DecodeError()
 {
   nsAutoString src;
   GetCurrentSrc(src);
   const PRUnichar* params[] = { src.get() };
   ReportLoadError("MediaLoadDecodeError", params, ArrayLength(params));
 
   if (mDecoder) {
     ShutdownDecoder();
@@ -2599,22 +2775,22 @@ void nsHTMLMediaElement::DecodeError()
     } else {
       NS_WARNING("Should know the source we were loading from!");
     }
   } else {
     Error(nsIDOMMediaError::MEDIA_ERR_DECODE);
   }
 }
 
-void nsHTMLMediaElement::LoadAborted()
+void HTMLMediaElement::LoadAborted()
 {
   Error(nsIDOMMediaError::MEDIA_ERR_ABORTED);
 }
 
-void nsHTMLMediaElement::Error(uint16_t aErrorCode)
+void HTMLMediaElement::Error(uint16_t aErrorCode)
 {
   NS_ASSERTION(aErrorCode == nsIDOMMediaError::MEDIA_ERR_DECODE ||
                aErrorCode == nsIDOMMediaError::MEDIA_ERR_NETWORK ||
                aErrorCode == nsIDOMMediaError::MEDIA_ERR_ABORTED,
                "Only use nsIDOMMediaError codes!");
   mError = new MediaError(this, aErrorCode);
   mBegun = false;
   DispatchAsyncEvent(NS_LITERAL_STRING("error"));
@@ -2623,17 +2799,17 @@ void nsHTMLMediaElement::Error(uint16_t 
     DispatchAsyncEvent(NS_LITERAL_STRING("emptied"));
   } else {
     mNetworkState = nsIDOMHTMLMediaElement::NETWORK_IDLE;
   }
   AddRemoveSelfReference();
   ChangeDelayLoadStatus(false);
 }
 
-void nsHTMLMediaElement::PlaybackEnded()
+void HTMLMediaElement::PlaybackEnded()
 {
   // We changed state which can affect AddRemoveSelfReference
   AddRemoveSelfReference();
 
   NS_ASSERTION(!mDecoder || mDecoder->IsEnded(),
                "Decoder fired ended, but not in ended state");
 
   // Discard all output streams that have finished now.
@@ -2654,68 +2830,68 @@ void nsHTMLMediaElement::PlaybackEnded()
   }
 
   Pause();
 
   FireTimeUpdate(false);
   DispatchAsyncEvent(NS_LITERAL_STRING("ended"));
 }
 
-void nsHTMLMediaElement::SeekStarted()
+void HTMLMediaElement::SeekStarted()
 {
   DispatchAsyncEvent(NS_LITERAL_STRING("seeking"));
   ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
   FireTimeUpdate(false);
 }
 
-void nsHTMLMediaElement::SeekCompleted()
+void HTMLMediaElement::SeekCompleted()
 {
   mPlayingBeforeSeek = false;
   SetPlayedOrSeeked(true);
   DispatchAsyncEvent(NS_LITERAL_STRING("seeked"));
   // We changed whether we're seeking so we need to AddRemoveSelfReference
   AddRemoveSelfReference();
 }
 
-void nsHTMLMediaElement::NotifySuspendedByCache(bool aIsSuspended)
+void HTMLMediaElement::NotifySuspendedByCache(bool aIsSuspended)
 {
   mDownloadSuspendedByCache = aIsSuspended;
 }
 
-void nsHTMLMediaElement::DownloadSuspended()
+void HTMLMediaElement::DownloadSuspended()
 {
   DispatchAsyncEvent(NS_LITERAL_STRING("progress"));
   if (mBegun) {
     mNetworkState = nsIDOMHTMLMediaElement::NETWORK_IDLE;
     AddRemoveSelfReference();
     DispatchAsyncEvent(NS_LITERAL_STRING("suspend"));
   }
 }
 
-void nsHTMLMediaElement::DownloadResumed(bool aForceNetworkLoading)
+void HTMLMediaElement::DownloadResumed(bool aForceNetworkLoading)
 {
   if (mBegun || aForceNetworkLoading) {
     mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
     AddRemoveSelfReference();
   }
 }
 
-void nsHTMLMediaElement::DownloadStalled()
+void HTMLMediaElement::DownloadStalled()
 {
   if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_LOADING) {
     DispatchAsyncEvent(NS_LITERAL_STRING("stalled"));
   }
 }
 
-bool nsHTMLMediaElement::ShouldCheckAllowOrigin()
+bool HTMLMediaElement::ShouldCheckAllowOrigin()
 {
   return mCORSMode != CORS_NONE;
 }
 
-void nsHTMLMediaElement::UpdateReadyStateForData(MediaDecoderOwner::NextFrameStatus aNextFrame)
+void HTMLMediaElement::UpdateReadyStateForData(MediaDecoderOwner::NextFrameStatus aNextFrame)
 {
   if (mReadyState < nsIDOMHTMLMediaElement::HAVE_METADATA) {
     // aNextFrame might have a next frame because the decoder can advance
     // on its own thread before ResourceLoaded or MetadataLoaded gets
     // a chance to run.
     // The arrival of more data can't change us out of this readyState.
     return;
   }
@@ -2774,17 +2950,17 @@ static const char* gReadyStateToString[]
   "HAVE_NOTHING",
   "HAVE_METADATA",
   "HAVE_CURRENT_DATA",
   "HAVE_FUTURE_DATA",
   "HAVE_ENOUGH_DATA"
 };
 #endif
 
-void nsHTMLMediaElement::ChangeReadyState(nsMediaReadyState aState)
+void HTMLMediaElement::ChangeReadyState(nsMediaReadyState aState)
 {
   nsMediaReadyState oldState = mReadyState;
   mReadyState = aState;
 
   if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY ||
       oldState == mReadyState) {
     return;
   }
@@ -2827,47 +3003,47 @@ void nsHTMLMediaElement::ChangeReadyStat
   }
 
   if (oldState < nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA &&
       mReadyState >= nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA) {
     DispatchAsyncEvent(NS_LITERAL_STRING("canplaythrough"));
   }
 }
 
-bool nsHTMLMediaElement::CanActivateAutoplay()
+bool HTMLMediaElement::CanActivateAutoplay()
 {
   return mAutoplaying &&
          mPaused &&
          HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) &&
          mAutoplayEnabled &&
          !IsEditable();
 }
 
-void nsHTMLMediaElement::NotifyAutoplayDataReady()
+void HTMLMediaElement::NotifyAutoplayDataReady()
 {
   if (CanActivateAutoplay()) {
     mPaused = false;
     // We changed mPaused which can affect AddRemoveSelfReference
     AddRemoveSelfReference();
 
     if (mDecoder) {
       SetPlayedOrSeeked(true);
       if (mCurrentPlayRangeStart == -1.0) {
-        GetCurrentTime(&mCurrentPlayRangeStart);
+        mCurrentPlayRangeStart = CurrentTime();
       }
       mDecoder->Play();
     } else if (mSrcStream) {
       SetPlayedOrSeeked(true);
       GetSrcMediaStream()->ChangeExplicitBlockerCount(-1);
     }
     DispatchAsyncEvent(NS_LITERAL_STRING("play"));
   }
 }
 
-VideoFrameContainer* nsHTMLMediaElement::GetVideoFrameContainer()
+VideoFrameContainer* HTMLMediaElement::GetVideoFrameContainer()
 {
   // If we have loaded the metadata, and the size of the video is still
   // (-1, -1), the media has no video. Don't go a create a video frame
   // container.
   if (mReadyState >= nsIDOMHTMLMediaElement::HAVE_METADATA &&
       mMediaSize == nsIntSize(-1, -1)) {
     return nullptr;
   }
@@ -2886,19 +3062,19 @@ VideoFrameContainer* nsHTMLMediaElement:
     return nullptr;
 
   mVideoFrameContainer =
     new VideoFrameContainer(this, LayerManager::CreateAsynchronousImageContainer());
 
   return mVideoFrameContainer;
 }
 
-nsresult nsHTMLMediaElement::DispatchAudioAvailableEvent(float* aFrameBuffer,
-                                                         uint32_t aFrameBufferLength,
-                                                         float aTime)
+nsresult HTMLMediaElement::DispatchAudioAvailableEvent(float* aFrameBuffer,
+                                                       uint32_t aFrameBufferLength,
+                                                       float aTime)
 {
   // Auto manage the memory for the frame buffer. If we fail and return
   // an error, this ensures we free the memory in the frame buffer. Otherwise
   // we hand off ownership of the frame buffer to the audioavailable event,
   // which frees the memory when it's destroyed.
   nsAutoArrayPtr<float> frameBuffer(aFrameBuffer);
 
   nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(OwnerDoc());
@@ -2915,17 +3091,17 @@ nsresult nsHTMLMediaElement::DispatchAud
                                                     false, false, frameBuffer.forget(), aFrameBufferLength,
                                                     aTime, mAllowAudioData);
   NS_ENSURE_SUCCESS(rv, rv);
 
   bool dummy;
   return target->DispatchEvent(event, &dummy);
 }
 
-nsresult nsHTMLMediaElement::DispatchEvent(const nsAString& aName)
+nsresult HTMLMediaElement::DispatchEvent(const nsAString& aName)
 {
   LOG_EVENT(PR_LOG_DEBUG, ("%p Dispatching event %s", this,
                           NS_ConvertUTF16toUTF8(aName).get()));
 
   // Save events that occur while in the bfcache. These will be dispatched
   // if the page comes out of the bfcache.
   if (mEventDeliveryPaused) {
     mPendingEvents.AppendElement(aName);
@@ -2934,88 +3110,88 @@ nsresult nsHTMLMediaElement::DispatchEve
 
   return nsContentUtils::DispatchTrustedEvent(OwnerDoc(),
                                               static_cast<nsIContent*>(this),
                                               aName,
                                               false,
                                               false);
 }
 
-nsresult nsHTMLMediaElement::DispatchAsyncEvent(const nsAString& aName)
+nsresult HTMLMediaElement::DispatchAsyncEvent(const nsAString& aName)
 {
   LOG_EVENT(PR_LOG_DEBUG, ("%p Queuing event %s", this,
             NS_ConvertUTF16toUTF8(aName).get()));
 
   nsCOMPtr<nsIRunnable> event = new nsAsyncEventRunner(aName, this);
   NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
   return NS_OK;
 }
 
-nsresult nsHTMLMediaElement::DispatchPendingMediaEvents()
+nsresult HTMLMediaElement::DispatchPendingMediaEvents()
 {
   NS_ASSERTION(!mEventDeliveryPaused,
                "Must not be in bfcache when dispatching pending media events");
 
   uint32_t count = mPendingEvents.Length();
   for (uint32_t i = 0; i < count; ++i) {
     DispatchAsyncEvent(mPendingEvents[i]);
   }
   mPendingEvents.Clear();
 
   return NS_OK;
 }
 
-bool nsHTMLMediaElement::IsPotentiallyPlaying() const
+bool HTMLMediaElement::IsPotentiallyPlaying() const
 {
   // TODO:
   //   playback has not stopped due to errors,
   //   and the element has not paused for user interaction
   return
     !mPaused &&
     (mReadyState == nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA ||
     mReadyState == nsIDOMHTMLMediaElement::HAVE_FUTURE_DATA) &&
     !IsPlaybackEnded();
 }
 
-bool nsHTMLMediaElement::IsPlaybackEnded() const
+bool HTMLMediaElement::IsPlaybackEnded() const
 {
   // TODO:
   //   the current playback position is equal to the effective end of the media resource.
   //   See bug 449157.
   return mNetworkState >= nsIDOMHTMLMediaElement::HAVE_METADATA &&
     mDecoder ? mDecoder->IsEnded() : false;
 }
 
-already_AddRefed<nsIPrincipal> nsHTMLMediaElement::GetCurrentPrincipal()
+already_AddRefed<nsIPrincipal> HTMLMediaElement::GetCurrentPrincipal()
 {
   if (mDecoder) {
     return mDecoder->GetCurrentPrincipal();
   }
   if (mSrcStream) {
     nsRefPtr<nsIPrincipal> principal = mSrcStream->GetPrincipal();
     return principal.forget();
   }
   return nullptr;
 }
 
-void nsHTMLMediaElement::NotifyDecoderPrincipalChanged()
+void HTMLMediaElement::NotifyDecoderPrincipalChanged()
 {
   for (uint32_t i = 0; i < mOutputStreams.Length(); ++i) {
     OutputMediaStream* ms = &mOutputStreams[i];
     nsRefPtr<nsIPrincipal> principal = GetCurrentPrincipal();
     ms->mStream->CombineWithPrincipal(principal);
   }
 }
 
-void nsHTMLMediaElement::UpdateMediaSize(nsIntSize size)
+void HTMLMediaElement::UpdateMediaSize(nsIntSize size)
 {
   mMediaSize = size;
 }
 
-void nsHTMLMediaElement::SuspendOrResumeElement(bool aPauseElement, bool aSuspendEvents)
+void HTMLMediaElement::SuspendOrResumeElement(bool aPauseElement, bool aSuspendEvents)
 {
   if (aPauseElement != mPausedForInactiveDocumentOrChannel) {
     mPausedForInactiveDocumentOrChannel = aPauseElement;
     if (aPauseElement) {
       if (mDecoder) {
         mDecoder->Pause();
         mDecoder->Suspend();
       } else if (mSrcStream) {
@@ -3034,17 +3210,17 @@ void nsHTMLMediaElement::SuspendOrResume
       if (mEventDeliveryPaused) {
         mEventDeliveryPaused = false;
         DispatchPendingMediaEvents();
       }
     }
   }
 }
 
-void nsHTMLMediaElement::NotifyOwnerDocumentActivityChanged()
+void HTMLMediaElement::NotifyOwnerDocumentActivityChanged()
 {
   nsIDocument* ownerDoc = OwnerDoc();
 #ifdef MOZ_B2G
   nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(OwnerDoc());
   if (domDoc) {
     bool hidden = false;
     domDoc->GetHidden(&hidden);
     // SetVisibilityState will update mChannelSuspended via the CanPlayChanged callback.
@@ -3056,17 +3232,17 @@ void nsHTMLMediaElement::NotifyOwnerDocu
   bool suspendEvents = !ownerDoc->IsActive() || !ownerDoc->IsVisible();
   bool pauseElement = suspendEvents || mChannelSuspended;
 
   SuspendOrResumeElement(pauseElement, suspendEvents);
 
   AddRemoveSelfReference();
 }
 
-void nsHTMLMediaElement::AddRemoveSelfReference()
+void HTMLMediaElement::AddRemoveSelfReference()
 {
   // XXX we could release earlier here in many situations if we examined
   // which event listeners are attached. Right now we assume there is a
   // potential listener for every event. We would also have to keep the
   // element alive if it was playing and producing audio output --- right now
   // that's covered by the !mPaused check.
   nsIDocument* ownerDoc = OwnerDoc();
 
@@ -3087,58 +3263,58 @@ void nsHTMLMediaElement::AddRemoveSelfRe
       // The observer service will hold a strong reference to us. This
       // will do to keep us alive. We need to know about shutdown so that
       // we can release our self-reference.
       nsContentUtils::RegisterShutdownObserver(this);
     } else {
       // Dispatch Release asynchronously so that we don't destroy this object
       // inside a call stack of method calls on this object
       nsCOMPtr<nsIRunnable> event =
-        NS_NewRunnableMethod(this, &nsHTMLMediaElement::DoRemoveSelfReference);
+        NS_NewRunnableMethod(this, &HTMLMediaElement::DoRemoveSelfReference);
       NS_DispatchToMainThread(event);
     }
   }
 
   UpdateAudioChannelPlayingState();
 }
 
-void nsHTMLMediaElement::DoRemoveSelfReference()
+void HTMLMediaElement::DoRemoveSelfReference()
 {
   // We don't need the shutdown observer anymore. Unregistering releases
   // its reference to us, which we were using as our self-reference.
   nsContentUtils::UnregisterShutdownObserver(this);
 }
 
-nsresult nsHTMLMediaElement::Observe(nsISupports* aSubject,
-                                     const char* aTopic, const PRUnichar* aData)
+nsresult HTMLMediaElement::Observe(nsISupports* aSubject,
+                                   const char* aTopic, const PRUnichar* aData)
 {
   NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
 
   if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
     mShuttingDown = true;
     AddRemoveSelfReference();
   }
   return NS_OK;
 }
 
 bool
-nsHTMLMediaElement::IsNodeOfType(uint32_t aFlags) const
+HTMLMediaElement::IsNodeOfType(uint32_t aFlags) const
 {
   return !(aFlags & ~(eCONTENT | eMEDIA));
 }
 
-void nsHTMLMediaElement::DispatchAsyncSourceError(nsIContent* aSourceElement)
+void HTMLMediaElement::DispatchAsyncSourceError(nsIContent* aSourceElement)
 {
   LOG_EVENT(PR_LOG_DEBUG, ("%p Queuing simple source error event", this));
 
   nsCOMPtr<nsIRunnable> event = new nsSourceErrorEventRunner(this, aSourceElement);
   NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
 }
 
-void nsHTMLMediaElement::NotifyAddedSource()
+void HTMLMediaElement::NotifyAddedSource()
 {
   // If a source element is inserted as a child of a media element
   // that has no src attribute and whose networkState has the value
   // NETWORK_EMPTY, the user agent must invoke the media element's
   // resource selection algorithm.
   if (!HasAttr(kNameSpaceID_None, nsGkAtoms::src) &&
       mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY)
   {
@@ -3147,17 +3323,17 @@ void nsHTMLMediaElement::NotifyAddedSour
 
   // A load was paused in the resource selection algorithm, waiting for
   // a new source child to be added, resume the resource selection algorithm.
   if (mLoadWaitStatus == WAITING_FOR_SOURCE) {
     QueueLoadFromSourceTask();
   }
 }
 
-nsIContent* nsHTMLMediaElement::GetNextSource()
+nsIContent* HTMLMediaElement::GetNextSource()
 {
   nsCOMPtr<nsIDOMNode> thisDomNode = do_QueryObject(this);
 
   mSourceLoadCandidate = nullptr;
 
   nsresult rv = NS_OK;
   if (!mSourcePointer) {
     // First time this has been run, create a selection to cover children.
@@ -3197,17 +3373,17 @@ nsIContent* nsHTMLMediaElement::GetNextS
       mSourceLoadCandidate = child;
       return child;
     }
   }
   NS_NOTREACHED("Execution should not reach here!");
   return nullptr;
 }
 
-void nsHTMLMediaElement::ChangeDelayLoadStatus(bool aDelay)
+void HTMLMediaElement::ChangeDelayLoadStatus(bool aDelay)
 {
   if (mDelayingLoadEvent == aDelay)
     return;
 
   mDelayingLoadEvent = aDelay;
 
   if (aDelay) {
     mLoadBlockedDoc = OwnerDoc();
@@ -3224,68 +3400,75 @@ void nsHTMLMediaElement::ChangeDelayLoad
       mLoadBlockedDoc = nullptr;
     }
   }
 
   // We changed mDelayingLoadEvent which can affect AddRemoveSelfReference
   AddRemoveSelfReference();
 }
 
-already_AddRefed<nsILoadGroup> nsHTMLMediaElement::GetDocumentLoadGroup()
+already_AddRefed<nsILoadGroup> HTMLMediaElement::GetDocumentLoadGroup()
 {
   if (!OwnerDoc()->IsActive()) {
     NS_WARNING("Load group requested for media element in inactive document.");
   }
   return OwnerDoc()->GetDocumentLoadGroup();
 }
 
 nsresult
-nsHTMLMediaElement::CopyInnerTo(Element* aDest)
+HTMLMediaElement::CopyInnerTo(Element* aDest)
 {
   nsresult rv = nsGenericHTMLElement::CopyInnerTo(aDest);
   NS_ENSURE_SUCCESS(rv, rv);
   if (aDest->OwnerDoc()->IsStaticDocument()) {
-    nsHTMLMediaElement* dest = static_cast<nsHTMLMediaElement*>(aDest);
+    HTMLMediaElement* dest = static_cast<HTMLMediaElement*>(aDest);
     if (mPrintSurface) {
       dest->mPrintSurface = mPrintSurface;
       dest->mMediaSize = mMediaSize;
     } else {
       nsIFrame* frame = GetPrimaryFrame();
       Element* element;
       if (frame && frame->GetType() == nsGkAtoms::HTMLVideoFrame &&
           static_cast<nsVideoFrame*>(frame)->ShouldDisplayPoster()) {
         nsIContent* content = static_cast<nsVideoFrame*>(frame)->GetPosterImage();
         element = content ? content->AsElement() : NULL;
       } else {
-        element = const_cast<nsHTMLMediaElement*>(this);
+        element = const_cast<HTMLMediaElement*>(this);
       }
 
       nsLayoutUtils::SurfaceFromElementResult res =
         nsLayoutUtils::SurfaceFromElement(element,
                                           nsLayoutUtils::SFE_WANT_NEW_SURFACE);
       dest->mPrintSurface = res.mSurface;
       dest->mMediaSize = nsIntSize(res.mSize.width, res.mSize.height);
     }
   }
   return rv;
 }
 
-nsresult nsHTMLMediaElement::GetBuffered(nsIDOMTimeRanges** aBuffered)
+already_AddRefed<TimeRanges>
+HTMLMediaElement::Buffered() const
 {
   nsRefPtr<TimeRanges> ranges = new TimeRanges();
   if (mReadyState > nsIDOMHTMLMediaElement::HAVE_NOTHING && mDecoder) {
     // If GetBuffered fails we ignore the error result and just return the
     // time ranges we found up till the error.
     mDecoder->GetBuffered(ranges);
   }
+  return ranges.forget();
+}
+
+nsresult HTMLMediaElement::GetBuffered(nsIDOMTimeRanges** aBuffered)
+{
+  nsRefPtr<TimeRanges> ranges = Buffered();
   ranges.forget(aBuffered);
   return NS_OK;
 }
 
-void nsHTMLMediaElement::SetRequestHeaders(nsIHttpChannel* aChannel)
+void HTMLMediaElement::SetRequestHeaders(nsIHttpChannel* aChannel)
 {
   // Send Accept header for video and audio types only (Bug 489071)
   SetAcceptHeader(aChannel);
 
   // Media elements are likely candidates for HTTP Pipeline head of line
   // blocking problems, so disable pipelines.
   nsLoadFlags loadflags;
   aChannel->GetLoadFlags(&loadflags);
@@ -3299,23 +3482,22 @@ void nsHTMLMediaElement::SetRequestHeade
   // See bug 614760.
   aChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept-Encoding"),
                              EmptyCString(), false);
 
   // Set the Referer header
   aChannel->SetReferrer(OwnerDoc()->GetDocumentURI());
 }
 
-void nsHTMLMediaElement::FireTimeUpdate(bool aPeriodic)
+void HTMLMediaElement::FireTimeUpdate(bool aPeriodic)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
 
   TimeStamp now = TimeStamp::Now();
-  double time = 0;
-  GetCurrentTime(&time);
+  double time = CurrentTime();
 
   // Fire a timeupdate event if this is not a periodic update (i.e. it's a
   // timeupdate event mandated by the spec), or if it's a periodic update
   // and TIMEUPDATE_MS has passed since the last timeupdate event fired and
   // the time has changed.
   if (!aPeriodic ||
       (mLastCurrentTime != time &&
        (mTimeUpdateTime.IsNull() ||
@@ -3327,55 +3509,65 @@ void nsHTMLMediaElement::FireTimeUpdate(
   if (mFragmentEnd >= 0.0 && time >= mFragmentEnd) {
     Pause();
     mFragmentEnd = -1.0;
     mFragmentStart = -1.0;
     mDecoder->SetFragmentEndTime(mFragmentEnd);
   }
 }
 
-void nsHTMLMediaElement::GetCurrentSpec(nsCString& aString)
+void HTMLMediaElement::GetCurrentSpec(nsCString& aString)
 {
   if (mLoadingSrc) {
     mLoadingSrc->GetSpec(aString);
   } else {
     aString.Truncate();
   }
 }
 
 /* attribute double initialTime; */
-NS_IMETHODIMP nsHTMLMediaElement::GetInitialTime(double *aTime)
+double
+HTMLMediaElement::InitialTime()
 {
   // If there is no start fragment then the initalTime is zero.
   // Clamp to duration if it is greater than duration.
-  double duration = 0.0;
-  nsresult rv = GetDuration(&duration);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *aTime = mFragmentStart < 0.0 ? 0.0 : mFragmentStart;
-  if (*aTime > duration) {
-    *aTime = duration;
+  double duration = Duration();
+
+  double time = mFragmentStart < 0.0 ? 0.0 : mFragmentStart;
+  if (time > duration) {
+    time = duration;
   }
+
+  return time;
+}
+
+NS_IMETHODIMP HTMLMediaElement::GetInitialTime(double* aTime)
+{
+  *aTime = InitialTime();
   return NS_OK;
 }
 
 /* attribute double mozFragmentEnd; */
-NS_IMETHODIMP nsHTMLMediaElement::GetMozFragmentEnd(double *aTime)
+double
+HTMLMediaElement::MozFragmentEnd()
 {
-  double duration = 0.0;
-  nsresult rv = GetDuration(&duration);
-  NS_ENSURE_SUCCESS(rv, rv);
+  double duration = Duration();
 
   // If there is no end fragment, or the fragment end is greater than the
   // duration, return the duration.
-  *aTime = (mFragmentEnd < 0.0 || mFragmentEnd > duration) ? duration : mFragmentEnd;
+  return (mFragmentEnd < 0.0 || mFragmentEnd > duration) ? duration : mFragmentEnd;
+}
+
+NS_IMETHODIMP HTMLMediaElement::GetMozFragmentEnd(double* aTime)
+{
+  *aTime = MozFragmentEnd();
   return NS_OK;
 }
 
-void nsHTMLMediaElement::NotifyAudioAvailableListener()
+void HTMLMediaElement::NotifyAudioAvailableListener()
 {
   if (mDecoder) {
     mDecoder->NotifyAudioAvailableListener();
   }
 }
 
 static double ClampPlaybackRate(double aPlaybackRate)
 {
@@ -3387,46 +3579,56 @@ static double ClampPlaybackRate(double a
   }
   if (Abs(aPlaybackRate) > MAX_PLAYBACKRATE) {
     return aPlaybackRate < 0 ? -MAX_PLAYBACKRATE : MAX_PLAYBACKRATE;
   }
   return aPlaybackRate;
 }
 
 /* attribute double defaultPlaybackRate; */
-NS_IMETHODIMP nsHTMLMediaElement::GetDefaultPlaybackRate(double* aDefaultPlaybackRate)
+NS_IMETHODIMP HTMLMediaElement::GetDefaultPlaybackRate(double* aDefaultPlaybackRate)
 {
-  *aDefaultPlaybackRate = mDefaultPlaybackRate;
+  *aDefaultPlaybackRate = DefaultPlaybackRate();
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLMediaElement::SetDefaultPlaybackRate(double aDefaultPlaybackRate)
+void
+HTMLMediaElement::SetDefaultPlaybackRate(double aDefaultPlaybackRate, ErrorResult& aRv)
 {
   if (aDefaultPlaybackRate < 0) {
-    return NS_ERROR_NOT_IMPLEMENTED;
+    aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+    return;
   }
 
   mDefaultPlaybackRate = ClampPlaybackRate(aDefaultPlaybackRate);
   DispatchAsyncEvent(NS_LITERAL_STRING("ratechange"));
-  return NS_OK;
+}
+
+NS_IMETHODIMP HTMLMediaElement::SetDefaultPlaybackRate(double aDefaultPlaybackRate)
+{
+  ErrorResult rv;
+  SetDefaultPlaybackRate(aDefaultPlaybackRate, rv);
+  return rv.ErrorCode();
 }
 
 /* attribute double playbackRate; */
-NS_IMETHODIMP nsHTMLMediaElement::GetPlaybackRate(double* aPlaybackRate)
+NS_IMETHODIMP HTMLMediaElement::GetPlaybackRate(double* aPlaybackRate)
 {
-  *aPlaybackRate = mPlaybackRate;
+  *aPlaybackRate = PlaybackRate();
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLMediaElement::SetPlaybackRate(double aPlaybackRate)
+void
+HTMLMediaElement::SetPlaybackRate(double aPlaybackRate, ErrorResult& aRv)
 {
   // Changing the playback rate of a media that has more than two channels is
   // not supported.
   if (aPlaybackRate < 0 || (mChannels > 2 && aPlaybackRate != 1.0)) {
-    return NS_ERROR_NOT_IMPLEMENTED;
+    aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+    return;
   }
 
   mPlaybackRate = ClampPlaybackRate(aPlaybackRate);
 
   if (!mMuted) {
     if (mPlaybackRate < 0 ||
         mPlaybackRate > THRESHOLD_HIGH_PLAYBACKRATE_AUDIO ||
         mPlaybackRate < THRESHOLD_LOW_PLAYBACKRATE_AUDIO) {
@@ -3435,44 +3637,50 @@ NS_IMETHODIMP nsHTMLMediaElement::SetPla
       SetMutedInternal(false);
     }
   }
 
   if (mDecoder) {
     mDecoder->SetPlaybackRate(mPlaybackRate);
   }
   DispatchAsyncEvent(NS_LITERAL_STRING("ratechange"));
-  return NS_OK;
+}
+
+NS_IMETHODIMP HTMLMediaElement::SetPlaybackRate(double aPlaybackRate)
+{
+  ErrorResult rv;
+  SetPlaybackRate(aPlaybackRate, rv);
+  return rv.ErrorCode();
 }
 
 /* attribute bool mozPreservesPitch; */
-NS_IMETHODIMP nsHTMLMediaElement::GetMozPreservesPitch(bool* aPreservesPitch)
+NS_IMETHODIMP HTMLMediaElement::GetMozPreservesPitch(bool* aPreservesPitch)
 {
-  *aPreservesPitch = mPreservesPitch;
+  *aPreservesPitch = MozPreservesPitch();
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLMediaElement::SetMozPreservesPitch(bool aPreservesPitch)
+NS_IMETHODIMP HTMLMediaElement::SetMozPreservesPitch(bool aPreservesPitch)
 {
   mPreservesPitch = aPreservesPitch;
   if (mDecoder) {
     mDecoder->SetPreservesPitch(mPreservesPitch);
   }
   return NS_OK;
 }
 
-ImageContainer* nsHTMLMediaElement::GetImageContainer()
+ImageContainer* HTMLMediaElement::GetImageContainer()
 {
   VideoFrameContainer* container = GetVideoFrameContainer();
   return container ? container->GetImageContainer() : nullptr;
 }
 
-nsresult nsHTMLMediaElement::UpdateChannelMuteState(bool aCanPlay)
+nsresult HTMLMediaElement::UpdateChannelMuteState(bool aCanPlay)
 {
-  // Only on B2G we mute the nsHTMLMediaElement following the rules of
+  // Only on B2G we mute the HTMLMediaElement following the rules of
   // AudioChannelService.
 #ifdef MOZ_B2G
   // We have to mute this channel:
   if (!aCanPlay && !mChannelSuspended) {
     mChannelSuspended = true;
     DispatchAsyncEvent(NS_LITERAL_STRING("mozinterruptbegin"));
   } else if (aCanPlay && mChannelSuspended) {
     mChannelSuspended = false;
@@ -3480,19 +3688,19 @@ nsresult nsHTMLMediaElement::UpdateChann
   }
 
   SuspendOrResumeElement(mChannelSuspended, false);
 #endif
 
   return NS_OK;
 }
 
-void nsHTMLMediaElement::UpdateAudioChannelPlayingState()
+void HTMLMediaElement::UpdateAudioChannelPlayingState()
 {
-  // The nsHTMLMediaElement is registered to the AudioChannelService only on B2G.
+  // The HTMLMediaElement is registered to the AudioChannelService only on B2G.
 #ifdef MOZ_B2G
   bool playingThroughTheAudioChannel =
      (!mPaused &&
       (HasAttr(kNameSpaceID_None, nsGkAtoms::loop) ||
        (mReadyState >= nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA &&
         !IsPlaybackEnded())));
   if (playingThroughTheAudioChannel != mPlayingThroughTheAudioChannel) {
     mPlayingThroughTheAudioChannel = playingThroughTheAudioChannel;
@@ -3520,15 +3728,18 @@ void nsHTMLMediaElement::UpdateAudioChan
       mAudioChannelAgent->StopPlaying();
       mAudioChannelAgent = nullptr;
     }
   }
 #endif
 }
 
 /* void canPlayChanged (in boolean canPlay); */
-NS_IMETHODIMP nsHTMLMediaElement::CanPlayChanged(bool canPlay)
+NS_IMETHODIMP HTMLMediaElement::CanPlayChanged(bool canPlay)
 {
   NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
 
   UpdateChannelMuteState(canPlay);
   return NS_OK;
 }
+
+} // namespace dom
+} // namespace mozilla
--- a/content/html/content/src/HTMLSourceElement.cpp
+++ b/content/html/content/src/HTMLSourceElement.cpp
@@ -65,17 +65,17 @@ HTMLSourceElement::BindToTree(nsIDocumen
                                                  aParent,
                                                  aBindingParent,
                                                  aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!aParent || !aParent->IsNodeOfType(nsINode::eMEDIA))
     return NS_OK;
 
-  nsHTMLMediaElement* media = static_cast<nsHTMLMediaElement*>(aParent);
+  HTMLMediaElement* media = static_cast<HTMLMediaElement*>(aParent);
   media->NotifyAddedSource();
 
   return NS_OK;
 }
 
 JSObject*
 HTMLSourceElement::WrapNode(JSContext* aCx, JSObject* aScope)
 {
--- a/content/html/content/src/HTMLSourceElement.h
+++ b/content/html/content/src/HTMLSourceElement.h
@@ -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/. */
 
 #ifndef mozilla_dom_HTMLSourceElement_h
 #define mozilla_dom_HTMLSourceElement_h
 
 #include "nsIDOMHTMLSourceElement.h"
 #include "nsGenericHTMLElement.h"
-#include "nsHTMLMediaElement.h"
+#include "mozilla/dom/HTMLMediaElement.h"
 
 namespace mozilla {
 namespace dom {
 
 class HTMLSourceElement : public nsGenericHTMLElement,
                           public nsIDOMHTMLSourceElement
 {
 public:
rename from content/html/content/src/nsHTMLVideoElement.cpp
rename to content/html/content/src/HTMLVideoElement.cpp
--- a/content/html/content/src/nsHTMLVideoElement.cpp
+++ b/content/html/content/src/HTMLVideoElement.cpp
@@ -3,17 +3,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Util.h"
 
 #include "nsIDOMHTMLVideoElement.h"
 #include "nsIDOMHTMLSourceElement.h"
-#include "nsHTMLVideoElement.h"
+#include "mozilla/dom/HTMLVideoElement.h"
+#include "mozilla/dom/HTMLVideoElementBinding.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsSize.h"
 #include "nsError.h"
 #include "nsNodeInfoManager.h"
 #include "plbase64.h"
 #include "nsNetUtil.h"
 #include "nsXPCOMStrings.h"
@@ -27,119 +28,119 @@
 
 #include "nsITimer.h"
 
 #include "nsEventDispatcher.h"
 #include "nsIDOMProgressEvent.h"
 #include "MediaError.h"
 #include "MediaDecoder.h"
 
-using namespace mozilla;
-using namespace mozilla::dom;
+NS_IMPL_NS_NEW_HTML_ELEMENT(Video)
+DOMCI_NODE_DATA(HTMLVideoElement, mozilla::dom::HTMLVideoElement)
 
-NS_IMPL_NS_NEW_HTML_ELEMENT(Video)
+namespace mozilla {
+namespace dom {
 
-NS_IMPL_ADDREF_INHERITED(nsHTMLVideoElement, nsHTMLMediaElement)
-NS_IMPL_RELEASE_INHERITED(nsHTMLVideoElement, nsHTMLMediaElement)
-
-DOMCI_NODE_DATA(HTMLVideoElement, nsHTMLVideoElement)
+NS_IMPL_ADDREF_INHERITED(HTMLVideoElement, HTMLMediaElement)
+NS_IMPL_RELEASE_INHERITED(HTMLVideoElement, HTMLMediaElement)
 
-NS_INTERFACE_TABLE_HEAD(nsHTMLVideoElement)
-  NS_HTML_CONTENT_INTERFACE_TABLE2(nsHTMLVideoElement, nsIDOMHTMLMediaElement, nsIDOMHTMLVideoElement)
-  NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLVideoElement,
-                                               nsHTMLMediaElement)
+NS_INTERFACE_TABLE_HEAD(HTMLVideoElement)
+  NS_HTML_CONTENT_INTERFACE_TABLE2(HTMLVideoElement, nsIDOMHTMLMediaElement, nsIDOMHTMLVideoElement)
+  NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(HTMLVideoElement,
+                                               HTMLMediaElement)
 NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLVideoElement)
 
-NS_IMPL_ELEMENT_CLONE(nsHTMLVideoElement)
+NS_IMPL_ELEMENT_CLONE(HTMLVideoElement)
 
 // nsIDOMHTMLVideoElement
-NS_IMPL_INT_ATTR(nsHTMLVideoElement, Width, width)
-NS_IMPL_INT_ATTR(nsHTMLVideoElement, Height, height)
+NS_IMPL_INT_ATTR(HTMLVideoElement, Width, width)
+NS_IMPL_INT_ATTR(HTMLVideoElement, Height, height)
 
 // nsIDOMHTMLVideoElement
 /* readonly attribute unsigned long videoWidth; */
-NS_IMETHODIMP nsHTMLVideoElement::GetVideoWidth(uint32_t *aVideoWidth)
+NS_IMETHODIMP HTMLVideoElement::GetVideoWidth(uint32_t *aVideoWidth)
 {
-  *aVideoWidth = mMediaSize.width == -1 ? 0 : mMediaSize.width;
+  *aVideoWidth = VideoWidth();
   return NS_OK;
 }
 
 /* readonly attribute unsigned long videoHeight; */
-NS_IMETHODIMP nsHTMLVideoElement::GetVideoHeight(uint32_t *aVideoHeight)
+NS_IMETHODIMP HTMLVideoElement::GetVideoHeight(uint32_t *aVideoHeight)
 {
-  *aVideoHeight = mMediaSize.height == -1 ? 0 : mMediaSize.height;
+  *aVideoHeight = VideoHeight();
   return NS_OK;
 }
 
-nsHTMLVideoElement::nsHTMLVideoElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-  : nsHTMLMediaElement(aNodeInfo)
+HTMLVideoElement::HTMLVideoElement(already_AddRefed<nsINodeInfo> aNodeInfo)
+  : HTMLMediaElement(aNodeInfo)
+{
+  SetIsDOMBinding();
+}
+
+HTMLVideoElement::~HTMLVideoElement()
 {
 }
 
-nsHTMLVideoElement::~nsHTMLVideoElement()
-{
-}
-
-nsresult nsHTMLVideoElement::GetVideoSize(nsIntSize* size)
+nsresult HTMLVideoElement::GetVideoSize(nsIntSize* size)
 {
   if (mMediaSize.width == -1 && mMediaSize.height == -1) {
     return NS_ERROR_FAILURE;
   }
 
   size->height = mMediaSize.height;
   size->width = mMediaSize.width;
   return NS_OK;
 }
 
 bool
-nsHTMLVideoElement::ParseAttribute(int32_t aNamespaceID,
-                                   nsIAtom* aAttribute,
-                                   const nsAString& aValue,
-                                   nsAttrValue& aResult)
+HTMLVideoElement::ParseAttribute(int32_t aNamespaceID,
+                                 nsIAtom* aAttribute,
+                                 const nsAString& aValue,
+                                 nsAttrValue& aResult)
 {
    if (aAttribute == nsGkAtoms::width || aAttribute == nsGkAtoms::height) {
      return aResult.ParseSpecialIntValue(aValue);
    }
 
-   return nsHTMLMediaElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
-                                             aResult);
+   return HTMLMediaElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
+                                           aResult);
 }
 
 static void
 MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                       nsRuleData* aData)
 {
   nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aData);
   nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
 }
 
 NS_IMETHODIMP_(bool)
-nsHTMLVideoElement::IsAttributeMapped(const nsIAtom* aAttribute) const
+HTMLVideoElement::IsAttributeMapped(const nsIAtom* aAttribute) const
 {
   static const MappedAttributeEntry attributes[] = {
     { &nsGkAtoms::width },
     { &nsGkAtoms::height },
     { nullptr }
   };
 
   static const MappedAttributeEntry* const map[] = {
     attributes,
     sCommonAttributeMap
   };
 
   return FindAttributeDependence(aAttribute, map);
 }
 
 nsMapRuleToAttributesFunc
-nsHTMLVideoElement::GetAttributeMappingFunction() const
+HTMLVideoElement::GetAttributeMappingFunction() const
 {
   return &MapAttributesIntoRule;
 }
 
-nsresult nsHTMLVideoElement::SetAcceptHeader(nsIHttpChannel* aChannel)
+nsresult HTMLVideoElement::SetAcceptHeader(nsIHttpChannel* aChannel)
 {
   nsAutoCString value(
 #ifdef MOZ_WEBM
       "video/webm,"
 #endif
 #ifdef MOZ_OGG
       "video/ogg,"
 #endif
@@ -149,53 +150,91 @@ nsresult nsHTMLVideoElement::SetAcceptHe
 #endif
       "audio/*;q=0.6,*/*;q=0.5");
 
   return aChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
                                     value,
                                     false);
 }
 
-NS_IMPL_URI_ATTR(nsHTMLVideoElement, Poster, poster)
+NS_IMPL_URI_ATTR(HTMLVideoElement, Poster, poster)
 
-NS_IMETHODIMP nsHTMLVideoElement::GetMozParsedFrames(uint32_t *aMozParsedFrames)
+uint32_t HTMLVideoElement::MozParsedFrames() const
 {
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  *aMozParsedFrames = mDecoder ? mDecoder->GetFrameStatistics().GetParsedFrames() : 0;
+  MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread.");
+  return mDecoder ? mDecoder->GetFrameStatistics().GetParsedFrames() : 0;
+}
+
+NS_IMETHODIMP HTMLVideoElement::GetMozParsedFrames(uint32_t *aMozParsedFrames)
+{
+  *aMozParsedFrames = MozParsedFrames();
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLVideoElement::GetMozDecodedFrames(uint32_t *aMozDecodedFrames)
+uint32_t HTMLVideoElement::MozDecodedFrames() const
 {
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  *aMozDecodedFrames = mDecoder ? mDecoder->GetFrameStatistics().GetDecodedFrames() : 0;
+  MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread.");
+  return mDecoder ? mDecoder->GetFrameStatistics().GetDecodedFrames() : 0;
+}
+
+NS_IMETHODIMP HTMLVideoElement::GetMozDecodedFrames(uint32_t *aMozDecodedFrames)
+{
+  *aMozDecodedFrames = MozDecodedFrames();
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLVideoElement::GetMozPresentedFrames(uint32_t *aMozPresentedFrames)
+uint32_t HTMLVideoElement::MozPresentedFrames() const
 {
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  *aMozPresentedFrames = mDecoder ? mDecoder->GetFrameStatistics().GetPresentedFrames() : 0;
+  MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread.");
+  return mDecoder ? mDecoder->GetFrameStatistics().GetPresentedFrames() : 0;
+}
+
+NS_IMETHODIMP HTMLVideoElement::GetMozPresentedFrames(uint32_t *aMozPresentedFrames)
+{
+  *aMozPresentedFrames = MozPresentedFrames();
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLVideoElement::GetMozPaintedFrames(uint32_t *aMozPaintedFrames)
+uint32_t HTMLVideoElement::MozPaintedFrames()
 {
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  ImageContainer* container = GetImageContainer();
-  *aMozPaintedFrames = container ? container->GetPaintCount() : 0;
+  MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread.");
+  layers::ImageContainer* container = GetImageContainer();
+  return container ? container->GetPaintCount() : 0;
+}
+
+NS_IMETHODIMP HTMLVideoElement::GetMozPaintedFrames(uint32_t *aMozPaintedFrames)
+{
+  *aMozPaintedFrames = MozPaintedFrames();
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLVideoElement::GetMozFrameDelay(double *aMozFrameDelay) {
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
+double HTMLVideoElement::MozFrameDelay()
+{
+  MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread.");
   VideoFrameContainer* container = GetVideoFrameContainer();
-  *aMozFrameDelay = container ?  container->GetFrameDelay() : 0;
+  return container ?  container->GetFrameDelay() : 0;
+}
+
+NS_IMETHODIMP HTMLVideoElement::GetMozFrameDelay(double *aMozFrameDelay) {
+  *aMozFrameDelay = MozFrameDelay();
   return NS_OK;
 }
 
+/* readonly attribute bool mozHasAudio */
+bool HTMLVideoElement::MozHasAudio() const
+{
+  MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread.");
+  return mHasAudio;
+}
 
-/* readonly attribute bool mozHasAudio */
-NS_IMETHODIMP nsHTMLVideoElement::GetMozHasAudio(bool *aHasAudio) {
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  *aHasAudio = mHasAudio;
+NS_IMETHODIMP HTMLVideoElement::GetMozHasAudio(bool *aHasAudio) {
+  *aHasAudio = MozHasAudio();
   return NS_OK;
 }
+
+JSObject*
+HTMLVideoElement::WrapNode(JSContext* aCx, JSObject* aScope)
+{
+  return HTMLVideoElementBinding::Wrap(aCx, aScope, this);
+}
+
+} // namespace dom
+} // namespace mozilla
--- a/content/html/content/src/Makefile.in
+++ b/content/html/content/src/Makefile.in
@@ -155,22 +155,22 @@ CPPSRCS		= \
 
 ifdef MOZ_MEDIA
 EXPORTS_mozilla/dom += \
 		HTMLSourceElement.h \
 		MediaError.h \
 		$(NULL)
 
 CPPSRCS		+= \
-		nsHTMLAudioElement.cpp \
-		nsHTMLMediaElement.cpp \
+		HTMLAudioElement.cpp \
+		HTMLMediaElement.cpp \
 		MediaError.cpp \
 		HTMLSourceElement.cpp \
 		TimeRanges.cpp \
-		nsHTMLVideoElement.cpp \
+		HTMLVideoElement.cpp \
 		$(NULL)
 endif
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/content/html/content/src/MediaError.cpp
+++ b/content/html/content/src/MediaError.cpp
@@ -16,17 +16,17 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaErr
 NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaError)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaError)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsIDOMMediaError)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMediaError)
 NS_INTERFACE_MAP_END
 
-MediaError::MediaError(nsHTMLMediaElement* aParent, uint16_t aCode)
+MediaError::MediaError(HTMLMediaElement* aParent, uint16_t aCode)
   : mParent(aParent)
   , mCode(aCode)
 {
   SetIsDOMBinding();
 }
 
 NS_IMETHODIMP MediaError::GetCode(uint16_t* aCode)
 {
--- a/content/html/content/src/MediaError.h
+++ b/content/html/content/src/MediaError.h
@@ -3,51 +3,51 @@
 /* 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_dom_MediaError_h
 #define mozilla_dom_MediaError_h
 
 #include "nsIDOMMediaError.h"
-#include "nsHTMLMediaElement.h"
+#include "mozilla/dom/HTMLMediaElement.h"
 #include "nsWrapperCache.h"
 #include "nsISupports.h"
 #include "mozilla/Attributes.h"
 
 namespace mozilla {
 namespace dom {
 
 class MediaError MOZ_FINAL : public nsIDOMMediaError,
                              public nsWrapperCache
 {
 public:
-  MediaError(nsHTMLMediaElement* aParent, uint16_t aCode);
+  MediaError(HTMLMediaElement* aParent, uint16_t aCode);
 
   // nsISupports
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaError)
 
   // nsIDOMMediaError
   NS_DECL_NSIDOMMEDIAERROR
 
-  nsHTMLMediaElement* GetParentObject() const
+  HTMLMediaElement* GetParentObject() const
   {
     return mParent;
   }
 
   virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope) MOZ_OVERRIDE;
 
   uint16_t Code() const
   {
     return mCode;
   }
 
 private:
-  nsRefPtr<nsHTMLMediaElement> mParent;
+  nsRefPtr<HTMLMediaElement> mParent;
 
   // Error code
   const uint16_t mCode;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/content/html/content/src/TimeRanges.cpp
+++ b/content/html/content/src/TimeRanges.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/TimeRanges.h"
 #include "mozilla/dom/TimeRangesBinding.h"
-#include "nsHTMLMediaElement.h"
+#include "mozilla/dom/HTMLMediaElement.h"
 #include "nsContentUtils.h"
 #include "nsDOMClassInfoID.h"
 #include "nsError.h"
 
 DOMCI_DATA(TimeRanges, mozilla::dom::TimeRanges)
 
 namespace mozilla {
 namespace dom {
--- a/content/html/content/src/nsHTMLFormElement.cpp
+++ b/content/html/content/src/nsHTMLFormElement.cpp
@@ -1085,16 +1085,30 @@ AssertDocumentOrder(const nsTArray<nsGen
       NS_ASSERTION(CompareFormControlPosition(aControls[i], aControls[i + 1],
                                               aForm) < 0,
                    "Form controls not ordered correctly");
     }
   }
 }
 #endif
 
+void
+nsHTMLFormElement::PostPasswordEvent()
+{
+  // Don't fire another add event if we have a pending add event.
+  if (mFormPasswordEvent.get()) {
+    return;
+  }
+
+  nsRefPtr<FormPasswordEvent> event =
+    new FormPasswordEvent(this, NS_LITERAL_STRING("DOMFormHasPassword"));
+  mFormPasswordEvent = event;
+  event->PostDOMEvent();
+}
+
 nsresult
 nsHTMLFormElement::AddElement(nsGenericHTMLFormElement* aChild,
                               bool aUpdateValidity, bool aNotify)
 {
   // If an element has a @form, we can assume it *might* be able to not have
   // a parent and still be in the form.
   NS_ASSERTION(aChild->HasAttr(kNameSpaceID_None, nsGkAtoms::form) ||
                aChild->GetParent(),
@@ -1152,22 +1166,24 @@ nsHTMLFormElement::AddElement(nsGenericH
 #endif
 
   int32_t type = aChild->GetType();
 
   //
   // If it is a password control, and the password manager has not yet been
   // initialized, initialize the password manager
   //
-  if (!gPasswordManagerInitialized && type == NS_FORM_INPUT_PASSWORD) {
-    // Initialize the password manager category
-    gPasswordManagerInitialized = true;
-    NS_CreateServicesFromCategory(NS_PASSWORDMANAGER_CATEGORY,
-                                  nullptr,
-                                  NS_PASSWORDMANAGER_CATEGORY);
+  if (type == NS_FORM_INPUT_PASSWORD) {
+    if (!gPasswordManagerInitialized) {
+      gPasswordManagerInitialized = true;
+      NS_CreateServicesFromCategory(NS_PASSWORDMANAGER_CATEGORY,
+                                    nullptr,
+                                    NS_PASSWORDMANAGER_CATEGORY);
+    }
+    PostPasswordEvent();
   }
  
   // Default submit element handling
   if (aChild->IsSubmitControl()) {
     // Update mDefaultSubmitElement, mFirstSubmitInElements,
     // mFirstSubmitNotInElements.
 
     nsGenericHTMLFormElement** firstSubmitSlot =
--- a/content/html/content/src/nsHTMLFormElement.h
+++ b/content/html/content/src/nsHTMLFormElement.h
@@ -9,25 +9,25 @@
 #include "nsCOMPtr.h"
 #include "nsIForm.h"
 #include "nsIFormControl.h"
 #include "nsFormSubmission.h"
 #include "nsGenericHTMLElement.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIWebProgressListener.h"
 #include "nsIRadioGroupContainer.h"
-#include "nsIURI.h"
 #include "nsIWeakReferenceUtils.h"
-#include "nsPIDOMWindow.h"
 #include "nsThreadUtils.h"
 #include "nsInterfaceHashtable.h"
 #include "nsDataHashtable.h"
+#include "nsAsyncDOMEvent.h"
 
 class nsFormControlList;
 class nsIMutableArray;
+class nsIURI;
 
 class nsHTMLFormElement : public nsGenericHTMLElement,
                           public nsIDOMHTMLFormElement,
                           public nsIWebProgressListener,
                           public nsIForm,
                           public nsIRadioGroupContainer
 {
 public:
@@ -236,16 +236,36 @@ public:
    * being invalid.
    *
    * @return Whether the submission of this form has been prevented because of
    * being invalid.
    */
   bool HasEverTriedInvalidSubmit() const { return mEverTriedInvalidSubmit; }
 
 protected:
+  void PostPasswordEvent();
+  void EventHandled() { mFormPasswordEvent = nullptr; }
+
+  class FormPasswordEvent : public nsAsyncDOMEvent
+  {
+  public:
+    FormPasswordEvent(nsHTMLFormElement* aEventNode,
+                      const nsAString& aEventType)
+      : nsAsyncDOMEvent(aEventNode, aEventType, true, true)
+    {}
+
+    NS_IMETHOD Run()
+    {
+      static_cast<nsHTMLFormElement*>(mEventNode.get())->EventHandled();
+      return nsAsyncDOMEvent::Run();
+    }
+  };
+
+  nsRefPtr<FormPasswordEvent> mFormPasswordEvent;
+
   class RemoveElementRunnable;
   friend class RemoveElementRunnable;
 
   class RemoveElementRunnable : public nsRunnable {
   public:
     RemoveElementRunnable(nsHTMLFormElement* aForm)
       : mForm(aForm)
     {}
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -348,16 +348,21 @@ MOCHITEST_FILES = \
 		test_mozaudiochannel.html \
 		test_style_attributes_reflection.html \
 		test_bug629801.html \
 		test_bug839371.html \
 		test_element_prototype.html \
 		test_formData.html \
 		$(NULL)
 
+ifdef MOZ_MEDIA
+MOCHITEST_FILES += \
+		test_mozLoadFrom.html \
+		$(NULL)
+endif
 
 MOCHITEST_BROWSER_FILES = \
 		browser_bug649778.js \
 		file_bug649778.html \
 		file_bug649778.html^headers^ \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_mozLoadFrom.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for mozLoadFrom</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script>
+
+try {
+  document.createElement("video").mozLoadFrom({});
+  ok(false, "This should be throw an exception");
+} catch(e) {
+  ok(true, "This should be throw an exception");
+}
+</script>
+</body>
+</html>
--- a/content/html/document/src/ImageDocument.cpp
+++ b/content/html/document/src/ImageDocument.cpp
@@ -5,16 +5,17 @@
 
 #include "MediaDocument.h"
 #include "nsRect.h"
 #include "nsHTMLDocument.h"
 #include "nsIImageDocument.h"
 #include "nsIImageLoadingContent.h"
 #include "nsGenericHTMLElement.h"
 #include "nsIDocumentInlines.h"
+#include "nsDOMTokenList.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMKeyEvent.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIDOMEventListener.h"
 #include "nsGkAtoms.h"
 #include "imgIRequest.h"
 #include "imgILoader.h"
@@ -114,16 +115,23 @@ protected:
   float GetRatio() {
     return std::min((float)mVisibleWidth / mImageWidth,
                   (float)mVisibleHeight / mImageHeight);
   }
 
   void ResetZoomLevel();
   float GetZoomLevel();
 
+  enum eModeClasses {
+    eNone,
+    eShrinkToFit,
+    eOverflowing
+  };
+  void SetModeClass(eModeClasses mode);
+
   nsresult OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage);
   nsresult OnStopRequest(imgIRequest *aRequest, nsresult aStatus);
 
   nsCOMPtr<nsIContent>          mImageContent;
 
   int32_t                       mVisibleWidth;
   int32_t                       mVisibleHeight;
   int32_t                       mImageWidth;
@@ -416,18 +424,17 @@ ImageDocument::ShrinkToFit()
   nsCOMPtr<nsIDOMHTMLImageElement> image = do_QueryInterface(mImageContent);
   image->SetWidth(std::max(1, NSToCoordFloor(GetRatio() * mImageWidth)));
   image->SetHeight(std::max(1, NSToCoordFloor(GetRatio() * mImageHeight)));
   
   // The view might have been scrolled when zooming in, scroll back to the
   // origin now that we're showing a shrunk-to-window version.
   (void) ScrollImageTo(0, 0, false);
 
-  imageContent->SetAttr(kNameSpaceID_None, nsGkAtoms::style,
-                        NS_LITERAL_STRING("cursor: -moz-zoom-in"), true);
+  SetModeClass(eShrinkToFit);
   
   mImageIsResized = true;
   
   UpdateTitleAndCharset();
 
   return NS_OK;
 }
 
@@ -469,21 +476,20 @@ ImageDocument::RestoreImage()
     return NS_OK;
   }
   // Keep image content alive while changing the attributes.
   nsCOMPtr<nsIContent> imageContent = mImageContent;
   imageContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::width, true);
   imageContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::height, true);
   
   if (mImageIsOverflowing) {
-    imageContent->SetAttr(kNameSpaceID_None, nsGkAtoms::style,
-                          NS_LITERAL_STRING("cursor: -moz-zoom-out"), true);
+    SetModeClass(eOverflowing);
   }
   else {
-    imageContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::style, true);
+    SetModeClass(eNone);
   }
   
   mImageIsResized = false;
   
   UpdateTitleAndCharset();
 
   return NS_OK;
 }
@@ -509,46 +515,67 @@ NS_IMETHODIMP
 ImageDocument::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aData)
 {
   if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
     nsCOMPtr<imgIContainer> image;
     aRequest->GetImage(getter_AddRefs(image));
     return OnStartContainer(aRequest, image);
   }
 
+  nsDOMTokenList* classList = mImageContent->AsElement()->GetClassList();
+  mozilla::ErrorResult rv;
   if (aType == imgINotificationObserver::DECODE_COMPLETE) {
     if (mImageContent) {
       // Update the background-color of the image only after the
       // image has been decoded to prevent flashes of just the
       // background-color.
-      mImageContent->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
-                             NS_LITERAL_STRING("decoded"), true);
+      classList->Add(NS_LITERAL_STRING("decoded"), rv);
+      NS_ENSURE_SUCCESS(rv.ErrorCode(), rv.ErrorCode());
     }
   }
 
   if (aType == imgINotificationObserver::DISCARD) {
     // mImageContent can be null if the document is already destroyed
     if (mImageContent) {
       // Remove any decoded-related styling when the image is unloaded.
-      mImageContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::_class,
-                               true);
+      classList->Remove(NS_LITERAL_STRING("decoded"), rv);
+      NS_ENSURE_SUCCESS(rv.ErrorCode(), rv.ErrorCode());
     }
   }
 
   if (aType == imgINotificationObserver::LOAD_COMPLETE) {
     uint32_t reqStatus;
     aRequest->GetImageStatus(&reqStatus);
     nsresult status =
         reqStatus & imgIRequest::STATUS_ERROR ? NS_ERROR_FAILURE : NS_OK;
     return OnStopRequest(aRequest, status);
   }
 
   return NS_OK;
 }
 
+void
+ImageDocument::SetModeClass(eModeClasses mode)
+{
+  nsDOMTokenList* classList = mImageContent->AsElement()->GetClassList();
+  mozilla::ErrorResult rv;
+
+  if (mode == eShrinkToFit) {
+    classList->Add(NS_LITERAL_STRING("shrinkToFit"), rv);
+  } else {
+    classList->Remove(NS_LITERAL_STRING("shrinkToFit"), rv);
+  }
+
+  if (mode == eOverflowing) {
+    classList->Add(NS_LITERAL_STRING("overflowing"), rv);
+  } else {
+    classList->Remove(NS_LITERAL_STRING("overflowing"), rv);
+  }
+}
+
 nsresult
 ImageDocument::OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage)
 {
   aImage->GetWidth(&mImageWidth);
   aImage->GetHeight(&mImageHeight);
   nsCOMPtr<nsIRunnable> runnable =
     NS_NewRunnableMethod(this, &ImageDocument::DefaultCheckOverflowing);
   nsContentUtils::AddScriptRunner(runnable);
--- a/content/html/document/src/VideoDocument.cpp
+++ b/content/html/document/src/VideoDocument.cpp
@@ -2,17 +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/. */
 
 #include "MediaDocument.h"
 #include "nsGkAtoms.h"
 #include "nsNodeInfoManager.h"
 #include "nsContentCreatorFunctions.h"
-#include "nsHTMLMediaElement.h"
+#include "mozilla/dom/HTMLMediaElement.h"
 #include "nsIDocumentInlines.h"
 #include "nsContentUtils.h"
 #include "mozilla/dom/Element.h"
 
 namespace mozilla {
 namespace dom {
 
 class VideoDocument : public MediaDocument
@@ -96,19 +96,19 @@ VideoDocument::CreateSyntheticVideoDocum
 
   // make content
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::video, nullptr,
                                            kNameSpaceID_XHTML,
                                            nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_FAILURE);
 
-  nsRefPtr<nsHTMLMediaElement> element =
-    static_cast<nsHTMLMediaElement*>(NS_NewHTMLVideoElement(nodeInfo.forget(),
-                                                            NOT_FROM_PARSER));
+  nsRefPtr<HTMLMediaElement> element =
+    static_cast<HTMLMediaElement*>(NS_NewHTMLVideoElement(nodeInfo.forget(),
+                                                          NOT_FROM_PARSER));
   if (!element)
     return NS_ERROR_OUT_OF_MEMORY;
   element->SetAutoplay(true);
   element->SetControls(true);
   element->LoadWithChannel(aChannel, aListener);
   UpdateTitle(aChannel);
 
   if (nsContentUtils::IsChildOfSameType(this)) {
--- a/content/media/MediaDecoder.cpp
+++ b/content/media/MediaDecoder.cpp
@@ -5,17 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MediaDecoder.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/MathAlgorithms.h"
 #include <limits>
 #include "nsNetUtil.h"
 #include "AudioStream.h"
-#include "nsHTMLVideoElement.h"
+#include "mozilla/dom/HTMLVideoElement.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsTArray.h"
 #include "VideoUtils.h"
 #include "MediaDecoderStateMachine.h"
 #include "mozilla/dom/TimeRanges.h"
 #include "nsContentUtils.h"
 #include "ImageContainer.h"
--- a/content/media/MediaDecoderOwner.h
+++ b/content/media/MediaDecoderOwner.h
@@ -2,22 +2,24 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 MediaDecoderOwner_h_
 #define MediaDecoderOwner_h_
 #include "AbstractMediaDecoder.h"
 
-class nsHTMLMediaElement;
-
 namespace mozilla {
 
 class VideoFrameContainer;
 
+namespace dom {
+class HTMLMediaElement;
+}
+
 class MediaDecoderOwner
 {
 public:
   // Called by the media decoder to indicate that the download has stalled
   // (no data has arrived for a while).
   virtual void DownloadStalled() = 0;
 
   // Dispatch a synchronous event to the decoder owner
@@ -29,19 +31,19 @@ public:
   /**
    * Fires a timeupdate event. If aPeriodic is true, the event will only
    * be fired if we've not fired a timeupdate event (for any reason) in the
    * last 250ms, as required by the spec when the current time is periodically
    * increasing during playback.
    */
   virtual void FireTimeUpdate(bool aPeriodic) = 0;
 
-  // Get the nsHTMLMediaElement object if the decoder is being used from an
+  // Get the HTMLMediaElement object if the decoder is being used from an
   // HTML media element, and null otherwise.
-  virtual nsHTMLMediaElement* GetMediaElement()
+  virtual dom::HTMLMediaElement* GetMediaElement()
   {
     return nullptr;
   }
 
   // Return true if decoding should be paused
   virtual bool GetPaused() = 0;
 
   /**
--- a/content/media/MediaDecoderReader.h
+++ b/content/media/MediaDecoderReader.h
@@ -9,17 +9,17 @@
 #include <nsDeque.h>
 #include "nsSize.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "MediaStreamGraph.h"
 #include "SharedBuffer.h"
 #include "ImageLayers.h"
 #include "AudioSampleFormat.h"
 #include "MediaResource.h"
-#include "nsHTMLMediaElement.h"
+#include "mozilla/dom/HTMLMediaElement.h"
 
 namespace mozilla {
 
 class AbstractMediaDecoder;
 
 // Stores info relevant to presenting media frames.
 class VideoInfo {
 public:
--- a/content/media/MediaResource.cpp
+++ b/content/media/MediaResource.cpp
@@ -18,17 +18,17 @@
 #include "nsIHttpChannel.h"
 #include "nsISeekableStream.h"
 #include "nsIInputStream.h"
 #include "nsIOutputStream.h"
 #include "nsIRequestObserver.h"
 #include "nsIStreamListener.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsCrossSiteListenerProxy.h"
-#include "nsHTMLMediaElement.h"
+#include "mozilla/dom/HTMLMediaElement.h"
 #include "nsError.h"
 #include "nsICachingChannel.h"
 #include "nsURILoader.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsContentUtils.h"
 #include "nsHostObjectProtocolHandler.h"
 #include <algorithm>
 
@@ -147,17 +147,17 @@ ChannelMediaResource::Listener::GetInter
 
 nsresult
 ChannelMediaResource::OnStartRequest(nsIRequest* aRequest)
 {
   NS_ASSERTION(mChannel.get() == aRequest, "Wrong channel!");
 
   MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
   NS_ENSURE_TRUE(owner, NS_ERROR_FAILURE);
-  nsHTMLMediaElement* element = owner->GetMediaElement();
+  HTMLMediaElement* element = owner->GetMediaElement();
   NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
   nsresult status;
   nsresult rv = aRequest->GetStatus(&status);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (element->ShouldCheckAllowOrigin()) {
     // If the request was cancelled by nsCORSListenerProxy due to failing
     // the CORS security check, send an error through to the media element.
@@ -605,17 +605,17 @@ nsresult ChannelMediaResource::OpenChann
     mChannel->SetNotificationCallbacks(mListener.get());
 
     nsCOMPtr<nsIStreamListener> listener = mListener.get();
 
     // Ensure that if we're loading cross domain, that the server is sending
     // an authorizing Access-Control header.
     MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
     NS_ENSURE_TRUE(owner, NS_ERROR_FAILURE);
-    nsHTMLMediaElement* element = owner->GetMediaElement();
+    HTMLMediaElement* element = owner->GetMediaElement();
     NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
     if (element->ShouldCheckAllowOrigin()) {
       nsRefPtr<nsCORSListenerProxy> crossSiteListener =
         new nsCORSListenerProxy(mListener,
                                 element->NodePrincipal(),
                                 false);
       nsresult rv = crossSiteListener->Init(mChannel);
       listener = crossSiteListener;
@@ -664,17 +664,17 @@ void ChannelMediaResource::SetupChannelH
     hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"), rangeString, false);
 
     // Send Accept header for video and audio types only (Bug 489071)
     NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
     MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
     if (!owner) {
       return;
     }
-    nsHTMLMediaElement* element = owner->GetMediaElement();
+    HTMLMediaElement* element = owner->GetMediaElement();
     if (!element) {
       return;
     }
     element->SetRequestHeaders(hc);
   } else {
     NS_ASSERTION(mOffset == 0, "Don't know how to seek on this channel type");
   }
 }
@@ -813,17 +813,17 @@ void ChannelMediaResource::Suspend(bool 
 {
   NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
 
   MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
   if (!owner) {
     // Shutting down; do nothing.
     return;
   }
-  nsHTMLMediaElement* element = owner->GetMediaElement();
+  HTMLMediaElement* element = owner->GetMediaElement();
   if (!element) {
     // Shutting down; do nothing.
     return;
   }
 
   if (mChannel) {
     if (aCloseImmediately && mCacheStream.IsTransportSeekable()) {
       // Kill off our channel right now, but don't tell anyone about it.
@@ -848,17 +848,17 @@ void ChannelMediaResource::Resume()
   NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
   NS_ASSERTION(mSuspendCount > 0, "Too many resumes!");
 
   MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
   if (!owner) {
     // Shutting down; do nothing.
     return;
   }
-  nsHTMLMediaElement* element = owner->GetMediaElement();
+  HTMLMediaElement* element = owner->GetMediaElement();
   if (!element) {
     // Shutting down; do nothing.
     return;
   }
 
   NS_ASSERTION(mSuspendCount > 0, "Resume without previous Suspend!");
   --mSuspendCount;
   if (mSuspendCount == 0) {
@@ -897,17 +897,17 @@ ChannelMediaResource::RecreateChannel()
     nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY |
     (mLoadInBackground ? nsIRequest::LOAD_BACKGROUND : 0);
 
   MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
   if (!owner) {
     // The decoder is being shut down, so don't bother opening a new channel
     return NS_OK;
   }
-  nsHTMLMediaElement* element = owner->GetMediaElement();
+  HTMLMediaElement* element = owner->GetMediaElement();
   if (!element) {
     // The decoder is being shut down, so don't bother opening a new channel
     return NS_OK;
   }
   nsCOMPtr<nsILoadGroup> loadGroup = element->GetDocumentLoadGroup();
   NS_ENSURE_TRUE(loadGroup, NS_ERROR_NULL_POINTER);
 
   nsresult rv = NS_NewChannel(getter_AddRefs(mChannel),
@@ -1425,17 +1425,17 @@ nsresult FileMediaResource::Open(nsIStre
     } else if (IsBlobURI(mURI)) {
       rv = NS_GetStreamForBlobURI(mURI, getter_AddRefs(mInput));
     }
   } else {
     // Ensure that we never load a local file from some page on a
     // web server.
     MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
     NS_ENSURE_TRUE(owner, NS_ERROR_FAILURE);
-    nsHTMLMediaElement* element = owner->GetMediaElement();
+    HTMLMediaElement* element = owner->GetMediaElement();
     NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
 
     rv = nsContentUtils::GetSecurityManager()->
            CheckLoadURIWithPrincipal(element->NodePrincipal(),
                                      mURI,
                                      nsIScriptSecurityManager::STANDARD);
     NS_ENSURE_SUCCESS(rv, rv);
 
@@ -1490,17 +1490,17 @@ MediaResource* FileMediaResource::CloneD
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
   MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
   if (!owner) {
     // The decoder is being shut down, so we can't clone
     return nullptr;
   }
-  nsHTMLMediaElement* element = owner->GetMediaElement();
+  HTMLMediaElement* element = owner->GetMediaElement();
   if (!element) {
     // The decoder is being shut down, so we can't clone
     return nullptr;
   }
   nsCOMPtr<nsILoadGroup> loadGroup = element->GetDocumentLoadGroup();
   NS_ENSURE_TRUE(loadGroup, nullptr);
 
   nsCOMPtr<nsIChannel> channel;
@@ -1605,17 +1605,17 @@ void BaseMediaResource::MoveLoadsToBackg
     return;
   }
 
   MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
   if (!owner) {
     NS_WARNING("Null owner in MediaResource::MoveLoadsToBackground()");
     return;
   }
-  nsHTMLMediaElement* element = owner->GetMediaElement();
+  HTMLMediaElement* element = owner->GetMediaElement();
   if (!element) {
     NS_WARNING("Null element in MediaResource::MoveLoadsToBackground()");
     return;
   }
 
   bool isPending = false;
   if (NS_SUCCEEDED(mChannel->IsPending(&isPending)) &&
       isPending) {
--- a/content/media/VideoFrameContainer.cpp
+++ b/content/media/VideoFrameContainer.cpp
@@ -1,27 +1,27 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 "VideoFrameContainer.h"
 
-#include "nsHTMLMediaElement.h"
+#include "mozilla/dom/HTMLMediaElement.h"
 #include "nsIFrame.h"
 #include "nsDisplayList.h"
 #include "nsSVGEffects.h"
 #include "ImageContainer.h"
 
 using namespace mozilla::layers;
 
 namespace mozilla {
 
-VideoFrameContainer::VideoFrameContainer(nsHTMLMediaElement* aElement,
+VideoFrameContainer::VideoFrameContainer(dom::HTMLMediaElement* aElement,
                                          already_AddRefed<ImageContainer> aContainer)
   : mElement(aElement),
     mImageContainer(aContainer), mMutex("nsVideoFrameContainer"),
     mIntrinsicSizeChanged(false), mImageSizeChanged(false),
     mNeedInvalidation(true)
 {
   NS_ASSERTION(aElement, "aElement must not be null");
   NS_ASSERTION(mImageContainer, "aContainer must not be null");
--- a/content/media/VideoFrameContainer.h
+++ b/content/media/VideoFrameContainer.h
@@ -9,19 +9,21 @@
 
 #include "mozilla/Mutex.h"
 #include "mozilla/TimeStamp.h"
 #include "nsISupportsImpl.h"
 #include "gfxPoint.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 
-class nsHTMLMediaElement;
+namespace mozilla {
 
-namespace mozilla {
+namespace dom {
+class HTMLMediaElement;
+}
 
 namespace layers {
 class Image;
 class ImageContainer;
 }
 
 /**
  * This object is used in the decoder backend threads and the main thread
@@ -29,22 +31,22 @@ class ImageContainer;
  * and an intrinsic size (see below).
  * This has to be a thread-safe object since it's accessed by resource decoders
  * and other off-main-thread components. So we can't put this state in the media
  * element itself ... well, maybe we could, but it could be risky and/or
  * confusing.
  */
 class VideoFrameContainer {
 public:
-  typedef mozilla::layers::ImageContainer ImageContainer;
-  typedef mozilla::layers::Image Image;
+  typedef layers::ImageContainer ImageContainer;
+  typedef layers::Image Image;
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoFrameContainer)
 
-  VideoFrameContainer(nsHTMLMediaElement* aElement,
+  VideoFrameContainer(dom::HTMLMediaElement* aElement,
                       already_AddRefed<ImageContainer> aContainer);
   ~VideoFrameContainer();
 
   // Call on any thread
   void SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage,
                        TimeStamp aTargetTime);
   void ClearCurrentFrame(bool aResetSize = false);
   // Reset the VideoFrameContainer
@@ -56,17 +58,17 @@ public:
   // Call on main thread
   void Invalidate();
   ImageContainer* GetImageContainer();
   void ForgetElement() { mElement = nullptr; }
 
 protected:
   // Non-addreffed pointer to the element. The element calls ForgetElement
   // to clear this reference when the element is destroyed.
-  nsHTMLMediaElement* mElement;
+  dom::HTMLMediaElement* mElement;
   nsRefPtr<ImageContainer> mImageContainer;
 
   // mMutex protects all the fields below.
   Mutex mMutex;
   // The intrinsic size is the ideal size which we should render the
   // ImageContainer's current Image at.
   // This can differ from the Image's actual size when the media resource
   // specifies that the Image should be stretched to have the correct aspect
--- a/content/media/dash/DASHDecoder.cpp
+++ b/content/media/dash/DASHDecoder.cpp
@@ -5,21 +5,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/. */
 
 /* DASH - Dynamic Adaptive Streaming over HTTP.
  *
  * DASH is an adaptive bitrate streaming technology where a multimedia file is
  * partitioned into one or more segments and delivered to a client using HTTP.
  *
- * Interaction with MediaDecoderStateMachine, nsHTMLMediaElement,
+ * Interaction with MediaDecoderStateMachine, HTMLMediaElement,
  * ChannelMediaResource and sub-decoders (WebMDecoder).
  *
  *
- *        MediaDecoderStateMachine      nsHTMLMediaElement
+ *        MediaDecoderStateMachine      HTMLMediaElement
  *               1 /           \ 1           / 1
  *                /             \           /
  *             1 /               \ 1       / 1
  * DASHReader ------ DASHDecoder ------------ ChannelMediaResource
  *          |1          1      1     |1      \1             (for MPD Manifest)
  *          |                        |        ------------
  *          |*                       |*                   \*
  *     WebMReader ------- DASHRepDecoder ------- ChannelMediaResource
@@ -76,17 +76,17 @@
  *     |DASHDecoder|->|LoadRepresentations|() starts download and decode.
  *
  *
  * 2 - Media Stream, Byte Range downloads.
  *
  * -- At this point the Segment media stream downloads are managed by
  *    individual |ChannelMediaResource|s and |WebMReader|s.
  *    A single |DASHDecoder| and |MediaDecoderStateMachine| manage them
- *    and communicate to |nsHTMLMediaElement|.
+ *    and communicate to |HTMLMediaElement|.
  *
  * Each |DASHRepDecoder| gets init range and index range from its MPD
  * |Representation|. |DASHRepDecoder| uses ChannelMediaResource to start the
  * byte range downloads, calling |OpenByteRange| with a |MediaByteRange|
  * object.
  * Once the init and index segments have been downloaded and |ReadMetadata| has
  * completed, each |WebMReader| notifies it's peer |DASHRepDecoder|.
  * Note: the decoder must wait until index data is parsed because it needs to
@@ -560,17 +560,17 @@ DASHDecoder::CreateVideoSubResource(nsIU
 
 nsresult
 DASHDecoder::CreateSubChannel(nsIURI* aUrl, nsIChannel** aChannel)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   NS_ENSURE_ARG(aUrl);
 
   NS_ENSURE_TRUE(mOwner, NS_ERROR_NULL_POINTER);
-  nsHTMLMediaElement* element = mOwner->GetMediaElement();
+  HTMLMediaElement* element = mOwner->GetMediaElement();
   NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER);
 
   nsCOMPtr<nsILoadGroup> loadGroup =
     element->GetDocumentLoadGroup();
   NS_ENSURE_TRUE(loadGroup, NS_ERROR_NULL_POINTER);
 
   // Check for a Content Security Policy to pass down to the channel
   // created to load the media content.
--- a/content/media/dash/DASHReader.cpp
+++ b/content/media/dash/DASHReader.cpp
@@ -191,17 +191,17 @@ DASHReader::ReadMetadata(VideoInfo* aInf
   *aTags = nullptr;
 
   // Get metadata from child readers.
   VideoInfo audioInfo, videoInfo;
 
   // Read metadata for all video streams.
   for (uint i = 0; i < mVideoReaders.Length(); i++) {
     // Use an nsAutoPtr here to ensure |tags| memory does not leak.
-    nsAutoPtr<nsHTMLMediaElement::MetadataTags> tags;
+    nsAutoPtr<HTMLMediaElement::MetadataTags> tags;
     rv = mVideoReaders[i]->ReadMetadata(&videoInfo, getter_Transfers(tags));
     NS_ENSURE_SUCCESS(rv, rv);
     // Use metadata from current video sub reader to populate aInfo.
     if (mVideoReaders[i] == mVideoReader) {
       mInfo.mHasVideo      = videoInfo.mHasVideo;
       mInfo.mDisplay       = videoInfo.mDisplay;
     }
   }
--- a/content/media/ogg/OggCodecState.h
+++ b/content/media/ogg/OggCodecState.h
@@ -12,17 +12,17 @@
 #include <tremor/ivorbiscodec.h>
 #else
 #include <vorbis/codec.h>
 #endif
 #ifdef MOZ_OPUS
 #include <opus/opus.h>
 #include "opus/opus_multistream.h"
 // For MOZ_SAMPLE_TYPE_*
-#include "nsHTMLMediaElement.h"
+#include "mozilla/dom/HTMLMediaElement.h"
 #include "MediaDecoderStateMachine.h"
 #include "MediaDecoderReader.h"
 #endif
 #include <nsAutoRef.h>
 #include <nsDeque.h>
 #include <nsTArray.h>
 #include <nsClassHashtable.h>
 #include "VideoUtils.h"
--- a/content/media/plugins/MediaPluginHost.cpp
+++ b/content/media/plugins/MediaPluginHost.cpp
@@ -2,17 +2,17 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "mozilla/Preferences.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/dom/TimeRanges.h"
 #include "MediaResource.h"
-#include "nsHTMLMediaElement.h"
+#include "mozilla/dom/HTMLMediaElement.h"
 #include "MediaPluginHost.h"
 #include "nsXPCOMStrings.h"
 #include "nsISeekableStream.h"
 #include "pratom.h"
 #include "MediaPluginReader.h"
 #include "nsIGfxInfo.h"
 #include "gfxCrashReporterUtils.h"
 #include "prmem.h"
--- a/content/media/test/file_access_controls.html
+++ b/content/media/test/file_access_controls.html
@@ -87,17 +87,17 @@ function eventHandler(event) {
   video.expectedResult = "<none>";
   nextTest();
 }
 
 function createVideo() {
   var v = document.createElement('video');
   v.addEventListener('loadeddata', eventHandler, false);
   v.addEventListener('error', eventHandler, false);
-  v.crossorigin = 'anonymous';
+  v.crossOrigin = 'anonymous';
   return v;
 }
 
 function load() {
   netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   opener.is(window.location.href,
             "http://example.org/tests/content/media/test/file_access_controls.html",
             "We must be on a example.org:80");
--- a/content/media/test/test_constants.html
+++ b/content/media/test/test_constants.html
@@ -151,25 +151,25 @@ is(HTMLElement.prototype.HAVE_NOTHING, u
 is(HTMLElement.prototype.HAVE_METADATA, undefined);
 is(HTMLElement.prototype.HAVE_CURRENT_DATA, undefined);
 is(HTMLElement.prototype.HAVE_FUTURE_DATA, undefined);
 is(HTMLElement.prototype.HAVE_ENOUGH_DATA, undefined);
 is(HTMLElement.prototype.MEDIA_ERR_ABORTED, undefined);
 is(HTMLElement.prototype.MEDIA_ERR_NETWORK, undefined);
 is(HTMLElement.prototype.MEDIA_ERR_DECODE, undefined);
 is(HTMLElement.prototype.MEDIA_ERR_SRC_NOT_SUPPORTED, undefined);
-todo_is(HTMLMediaElement.prototype.NETWORK_EMPTY, 0, "HTMLMediaElement.prototype.NETWORK_EMPTY");
-todo_is(HTMLMediaElement.prototype.NETWORK_IDLE, 1, "HTMLMediaElement.prototype.NETWORK_IDLE");
-todo_is(HTMLMediaElement.prototype.NETWORK_LOADING, 2, "HTMLMediaElement.prototype.NETWORK_LOADING");
-todo_is(HTMLMediaElement.prototype.NETWORK_NO_SOURCE, 3, "HTMLMediaElement.prototype.NETWORK_NO_SOURCE");
-todo_is(HTMLMediaElement.prototype.HAVE_NOTHING, 0, "HTMLMediaElement.prototype.HAVE_NOTHING");
-todo_is(HTMLMediaElement.prototype.HAVE_METADATA, 1, "HTMLMediaElement.prototype.HAVE_METADATA");
-todo_is(HTMLMediaElement.prototype.HAVE_CURRENT_DATA, 2, "HTMLMediaElement.prototype.HAVE_CURRENT_DATA");
-todo_is(HTMLMediaElement.prototype.HAVE_FUTURE_DATA, 3, "HTMLMediaElement.prototype.HAVE_FUTURE_DATA");
-todo_is(HTMLMediaElement.prototype.HAVE_ENOUGH_DATA, 4, "HTMLMediaElement.prototype.HAVE_ENOUGH_DATA");
+is(HTMLMediaElement.prototype.NETWORK_EMPTY, 0, "HTMLMediaElement.prototype.NETWORK_EMPTY");
+is(HTMLMediaElement.prototype.NETWORK_IDLE, 1, "HTMLMediaElement.prototype.NETWORK_IDLE");
+is(HTMLMediaElement.prototype.NETWORK_LOADING, 2, "HTMLMediaElement.prototype.NETWORK_LOADING");
+is(HTMLMediaElement.prototype.NETWORK_NO_SOURCE, 3, "HTMLMediaElement.prototype.NETWORK_NO_SOURCE");
+is(HTMLMediaElement.prototype.HAVE_NOTHING, 0, "HTMLMediaElement.prototype.HAVE_NOTHING");
+is(HTMLMediaElement.prototype.HAVE_METADATA, 1, "HTMLMediaElement.prototype.HAVE_METADATA");
+is(HTMLMediaElement.prototype.HAVE_CURRENT_DATA, 2, "HTMLMediaElement.prototype.HAVE_CURRENT_DATA");
+is(HTMLMediaElement.prototype.HAVE_FUTURE_DATA, 3, "HTMLMediaElement.prototype.HAVE_FUTURE_DATA");
+is(HTMLMediaElement.prototype.HAVE_ENOUGH_DATA, 4, "HTMLMediaElement.prototype.HAVE_ENOUGH_DATA");
 is(HTMLMediaElement.prototype.MEDIA_ERR_ABORTED, undefined, "HTMLMediaElement.prototype.MEDIA_ERR_ABORTED");
 is(HTMLMediaElement.prototype.MEDIA_ERR_NETWORK, undefined, "HTMLMediaElement.prototype.MEDIA_ERR_NETWORK");
 is(HTMLMediaElement.prototype.MEDIA_ERR_DECODE, undefined, "HTMLMediaElement.prototype.MEDIA_ERR_DECODE");
 is(HTMLMediaElement.prototype.MEDIA_ERR_SRC_NOT_SUPPORTED, undefined, "HTMLMediaElement.prototype.MEDIA_ERR_SRC_NOT_SUPPORTED");
 is(HTMLVideoElement.prototype.NETWORK_EMPTY, 0);
 is(HTMLVideoElement.prototype.NETWORK_IDLE, 1);
 is(HTMLVideoElement.prototype.NETWORK_LOADING, 2);
 is(HTMLVideoElement.prototype.NETWORK_NO_SOURCE, 3);
--- a/content/media/test/test_playback_rate.html
+++ b/content/media/test/test_playback_rate.html
@@ -28,17 +28,17 @@ function rangeCheck(lhs, rhs, threshold)
 
 function checkPlaybackRate(wallclock, media, expected, threshold) {
   if (rangeCheck(media / wallclock, expected, threshold)) {
     return true;
   }
   return false;
 }
 
-// Those value are expected to match those at the top of nsHTMLMediaElement.cpp.
+// Those value are expected to match those at the top of HTMLMediaElement.cpp.
 let VERY_SLOW_RATE = 0.1,
     SLOW_RATE = 0.25,
     FAST_RATE = 5,
     VERY_FAST_RATE = 20,
     NULL_RATE = 0.0;
 
 function ontimeupdate(e) {
   var t = e.target;
--- a/content/media/test/test_streams_srcObject.html
+++ b/content/media/test/test_streams_srcObject.html
@@ -23,17 +23,17 @@ function doTest() {
   is(b.mozSrcObject, null, "Initial srcObject is null");
   var stream = a.mozCaptureStream();
   b.mozSrcObject = stream;
   is(b.mozSrcObject, stream, "Stream set correctly");
   try {
     b.mozSrcObject = "invalid";
     ok(false, "Setting mozSrcObject to an invalid value should throw.");
   } catch (e) {
-    todo(e instanceof TypeError, "Exception should be a TypeError");
+    ok(e instanceof TypeError, "Exception should be a TypeError");
   }
   is(b.mozSrcObject, stream, "Stream not set to invalid value");
   is(b.src, newSrc, "src attribute not affected by setting srcObject");
   var step = 0;
   b.addEventListener("loadedmetadata", function() {
     if (step == 0) {
       is(b.currentSrc, "", "currentSrc set to empty string while playing srcObject");
       b.mozSrcObject = null;
--- a/content/media/test/test_volume.html
+++ b/content/media/test/test_volume.html
@@ -8,34 +8,34 @@
 <body>
 
 <video id='v1'></video><audio id='a1'></audio>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 function test(element, value, shouldThrow) {
-  var threw = false;
+  var threw = null;
   try {
     element.volume = value;
-  } catch (err if err.name == "IndexSizeError") {
-    threw = true;
+  } catch (ex) {
+    threw = ex.name;
   }
   is(shouldThrow, threw, "Case: " +element.id+ " setVolume=" + value);
 }
 
 
 var ids = new Array(document.getElementById('v1'), document.getElementById('a1'));
 
 for (i=0; i<ids.length; i++) {
   var element = ids[i];
-  test(element, 0.0, false);
-  test(element, 1.0, false);
-  test(element, -0.1, true);
-  test(element, 1.1, true);
-  test(element, undefined, true);
-  test(element, NaN, true);
+  test(element, 0.0, null);
+  test(element, 1.0, null);
+  test(element, -0.1, "IndexSizeError");
+  test(element, 1.1, "IndexSizeError");
+  test(element, undefined, "TypeError");
+  test(element, NaN, "TypeError");
 }  
  
 </script>
 </pre>
 </body>
 </html>
--- a/content/media/wave/WaveReader.cpp
+++ b/content/media/wave/WaveReader.cpp
@@ -135,17 +135,17 @@ nsresult WaveReader::ReadMetadata(VideoI
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
   bool loaded = LoadRIFFChunk();
   if (!loaded) {
     return NS_ERROR_FAILURE;
   }
 
-  nsAutoPtr<nsHTMLMediaElement::MetadataTags> tags;
+  nsAutoPtr<HTMLMediaElement::MetadataTags> tags;
 
   bool loadAllChunks = LoadAllChunks(tags);
   if (!loadAllChunks) {
     return NS_ERROR_FAILURE;
   }
 
   mInfo.mHasAudio = true;
   mInfo.mHasVideo = false;
@@ -526,17 +526,17 @@ WaveReader::GetNextChunk(uint32_t* aChun
   *aChunk = ReadUint32BE(&p);
   *aChunkSize = ReadUint32LE(&p);
 
   return true;
 }
 
 bool
 WaveReader::LoadListChunk(uint32_t aChunkSize,
-    nsAutoPtr<nsHTMLMediaElement::MetadataTags> &aTags)
+    nsAutoPtr<HTMLMediaElement::MetadataTags> &aTags)
 {
   // List chunks are always word (two byte) aligned.
   NS_ABORT_IF_FALSE(mDecoder->GetResource()->Tell() % 2 == 0,
                     "LoadListChunk called with unaligned resource");
 
   static const unsigned int MAX_CHUNK_SIZE = 1 << 16;
   PR_STATIC_ASSERT(MAX_CHUNK_SIZE < UINT_MAX / sizeof(char));
 
@@ -559,17 +559,17 @@ WaveReader::LoadListChunk(uint32_t aChun
     { 0x49415254, NS_LITERAL_CSTRING("artist") },   // IART
     { 0x49434d54, NS_LITERAL_CSTRING("comments") }, // ICMT
     { 0x49474e52, NS_LITERAL_CSTRING("genre") },    // IGNR
     { 0x494e414d, NS_LITERAL_CSTRING("name") },     // INAM
   };
 
   const char* const end = chunk.get() + aChunkSize;
 
-  aTags = new nsHTMLMediaElement::MetadataTags;
+  aTags = new HTMLMediaElement::MetadataTags;
   aTags->Init();
 
   while (p + 8 < end) {
     uint32_t id = ReadUint32BE(&p);
     // Uppercase tag id, inspired by GStreamer's Wave parser.
     id &= 0xDFDFDFDF;
 
     uint32_t length = ReadUint32LE(&p);
@@ -600,17 +600,17 @@ WaveReader::LoadListChunk(uint32_t aChun
       }
     }
   }
 
   return true;
 }
 
 bool
-WaveReader::LoadAllChunks(nsAutoPtr<nsHTMLMediaElement::MetadataTags> &aTags)
+WaveReader::LoadAllChunks(nsAutoPtr<HTMLMediaElement::MetadataTags> &aTags)
 {
   // Chunks are always word (two byte) aligned.
   NS_ABORT_IF_FALSE(mDecoder->GetResource()->Tell() % 2 == 0,
                     "LoadAllChunks called with unaligned resource");
 
   bool loadFormatChunk = false;
   bool findDataOffset = false;
 
--- a/content/media/wave/WaveReader.h
+++ b/content/media/wave/WaveReader.h
@@ -48,18 +48,18 @@ public:
   }
 
 private:
   bool ReadAll(char* aBuf, int64_t aSize, int64_t* aBytesRead = nullptr);
   bool LoadRIFFChunk();
   bool GetNextChunk(uint32_t* aChunk, uint32_t* aChunkSize);
   bool LoadFormatChunk(uint32_t aChunkSize);
   bool FindDataOffset(uint32_t aChunkSize);
-  bool LoadListChunk(uint32_t aChunkSize, nsAutoPtr<nsHTMLMediaElement::MetadataTags> &aTags);
-  bool LoadAllChunks(nsAutoPtr<nsHTMLMediaElement::MetadataTags> &aTags);
+  bool LoadListChunk(uint32_t aChunkSize, nsAutoPtr<dom::HTMLMediaElement::MetadataTags> &aTags);
+  bool LoadAllChunks(nsAutoPtr<dom::HTMLMediaElement::MetadataTags> &aTags);
 
   // Returns the number of seconds that aBytes represents based on the
   // current audio parameters.  e.g.  176400 bytes is 1 second at 16-bit
   // stereo 44.1kHz. The time is rounded to the nearest microsecond.
   double BytesToTime(int64_t aBytes) const;
 
   // Returns the number of bytes that aTime represents based on the current
   // audio parameters.  e.g.  1 second is 176400 bytes at 16-bit stereo
--- a/content/media/webaudio/AudioNode.cpp
+++ b/content/media/webaudio/AudioNode.cpp
@@ -166,17 +166,17 @@ AudioNode::Connect(AudioNode& aDestinati
   input->mInputPort = aInput;
   input->mOutputPort = aOutput;
   if (SupportsMediaStreams() && aDestination.mStream) {
     // Connect streams in the MediaStreamGraph
     MOZ_ASSERT(aDestination.mStream->AsProcessedStream());
     ProcessedMediaStream* ps =
       static_cast<ProcessedMediaStream*>(aDestination.mStream.get());
     input->mStreamPort =
-      ps->AllocateInputPort(mStream, MediaInputPort::FLAG_BLOCK_OUTPUT);
+      ps->AllocateInputPort(mStream, MediaInputPort::FLAG_BLOCK_INPUT);
   }
 }
 
 void
 AudioNode::SendDoubleParameterToStream(uint32_t aIndex, double aValue)
 {
   AudioNodeStream* ns = static_cast<AudioNodeStream*>(mStream.get());
   MOZ_ASSERT(ns, "How come we don't have a stream here?");
--- a/content/media/webaudio/MediaBufferDecoder.cpp
+++ b/content/media/webaudio/MediaBufferDecoder.cpp
@@ -392,17 +392,17 @@ MediaDecodeTask::CreateReader()
   BufferMediaResource* resource =
     new BufferMediaResource(static_cast<uint8_t*> (mBuffer),
                             mLength, mPrincipal, mContentType);
 
   MOZ_ASSERT(!mBufferDecoder);
   mBufferDecoder = new BufferDecoder(resource);
 
   // If you change this list to add support for new decoders, please consider
-  // updating nsHTMLMediaElement::CreateDecoder as well.
+  // updating HTMLMediaElement::CreateDecoder as well.
 
   mDecoderReader = DecoderTraits::CreateReader(mContentType, mBufferDecoder);
 
   if (!mDecoderReader) {
     return false;
   }
 
   nsresult rv = mDecoderReader->Init(nullptr);
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -1142,17 +1142,17 @@ nsDOMWindowUtils::GarbageCollect(nsICycl
   SAMPLE_LABEL("GC", "GarbageCollect");
   // Always permit this in debug builds.
 #ifndef DEBUG
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 #endif
 
-  nsJSContext::GarbageCollectNow(js::gcreason::DOM_UTILS);
+  nsJSContext::GarbageCollectNow(JS::gcreason::DOM_UTILS);
   nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::CycleCollect(nsICycleCollectorListener *aListener,
                                int32_t aExtraForgetSkippableCalls)
@@ -2791,17 +2791,17 @@ nsDOMWindowUtils::GetFileReferences(cons
 
 NS_IMETHODIMP
 nsDOMWindowUtils::IsIncrementalGCEnabled(JSContext* cx, bool* aResult)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
-  *aResult = js::IsIncrementalGCEnabled(JS_GetRuntime(cx));
+  *aResult = JS::IsIncrementalGCEnabled(JS_GetRuntime(cx));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::StartPCCountProfiling(JSContext* cx)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -2369,17 +2369,17 @@ nsGlobalWindow::SetNewDocument(nsIDocume
       mArgumentsOrigin = nullptr;
     }
 
     // Give the new inner window our chrome event handler (since it
     // doesn't have one).
     newInnerWindow->mChromeEventHandler = mChromeEventHandler;
   }
 
-  mContext->GC(js::gcreason::SET_NEW_DOCUMENT);
+  mContext->GC(JS::gcreason::SET_NEW_DOCUMENT);
   mContext->DidInitializeContext();
 
   if (newInnerWindow && !newInnerWindow->mHasNotifiedGlobalCreated && mDoc) {
     // We should probably notify. However if this is the, arguably bad,
     // situation when we're creating a temporary non-chrome-about-blank
     // document in a chrome docshell, don't notify just yet. Instead wait
     // until we have a real chrome doc.
     int32_t itemType = nsIDocShellTreeItem::typeContent;
@@ -2564,17 +2564,17 @@ nsGlobalWindow::DetachFromDocShell()
     // We got no new document after someone called
     // SetArguments(), drop our reference to the arguments.
     mArguments = nullptr;
     mArgumentsLast = nullptr;
     mArgumentsOrigin = nullptr;
   }
 
   if (mContext) {
-    mContext->GC(js::gcreason::SET_DOC_SHELL);
+    mContext->GC(JS::gcreason::SET_DOC_SHELL);
     mContext = nullptr;
   }
 
   mDocShell = nullptr; // Weak Reference
 
   NS_ASSERTION(!mNavigator, "Non-null mNavigator in outer window!");
 
   if (mFrames) {
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -2591,17 +2591,17 @@ nsJSContext::GarbageCollectNow(JS::gcrea
   // NS_MAX_COMPARTMENT_GC_COUNT times after the previous global GC.
   if (!sDisableExplicitCompartmentGC &&
       aShrinking != ShrinkingGC && aCompartment != NonCompartmentGC &&
       sCompartmentGCCount < NS_MAX_COMPARTMENT_GC_COUNT) {
     JS::PrepareForFullGC(nsJSRuntime::sRuntime);
     for (nsJSContext* cx = sContextList; cx; cx = cx->mNext) {
       if (!cx->mActive && cx->mContext) {
         if (JSObject* global = cx->GetNativeGlobal()) {
-          JS::SkipZoneForGC(js::GetObjectZone(global));
+          JS::SkipZoneForGC(JS::GetObjectZone(global));
         }
       }
       cx->mActive = false;
     }
     if (JS::IsGCScheduled(nsJSRuntime::sRuntime)) {
       if (aIncremental == IncrementalGC) {
         JS::IncrementalGC(nsJSRuntime::sRuntime, aReason, aSliceMillis);
       } else {
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -511,17 +511,17 @@ SetSystemOnlyWrapper(JSObject* obj, nsWr
 // If *vp is a gcthing and is not in the compartment of cx, wrap *vp
 // into the compartment of cx (typically by replacing it with an Xray or
 // cross-compartment wrapper around the original object).
 MOZ_ALWAYS_INLINE bool
 MaybeWrapValue(JSContext* cx, JS::Value* vp)
 {
   if (vp->isString()) {
     JSString* str = vp->toString();
-    if (js::GetGCThingZone(str) != js::GetContextZone(cx)) {
+    if (JS::GetGCThingZone(str) != js::GetContextZone(cx)) {
       return JS_WrapValue(cx, vp);
     }
     return true;
   }
 
   if (vp->isObject()) {
     JSObject* obj = &vp->toObject();
     if (js::GetObjectCompartment(obj) != js::GetContextCompartment(cx)) {
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -408,16 +408,20 @@ DOMInterfaces = {
 },
 
 'HTMLLabelElement': {
     'resultNotAddRefed': [
         'form', 'control'
     ],
 },
 
+'HTMLMediaElement': {
+    'concrete': False
+},
+
 'HTMLOListElement': {
     'nativeType' : 'mozilla::dom::HTMLSharedListElement'
 },
 
 'HTMLOptionsCollection': {
     'resultNotAddRefed': [ 'item' ],
 },
 
@@ -1320,17 +1324,16 @@ def addExternalIface(iface, nativeType=N
 # If you add one of these, you need to make sure nsDOMQS.h has the relevant
 # macros added for it
 def addExternalHTMLElement(element):
    nativeElement = 'ns' + element
    addExternalIface(element, nativeType=nativeElement,
                     headerFile=nativeElement + '.h')
 
 addExternalHTMLElement('HTMLFormElement')
-addExternalHTMLElement('HTMLVideoElement')
 addExternalIface('ActivityOptions', nativeType='nsIDOMMozActivityOptions',
                  headerFile='nsIDOMActivityOptions.h')
 addExternalIface('Attr')
 addExternalIface('CanvasGradient', headerFile='nsIDOMCanvasRenderingContext2D.h')
 addExternalIface('CanvasPattern', headerFile='nsIDOMCanvasRenderingContext2D.h')
 addExternalIface('Counter')
 addExternalIface('CSSRule')
 addExternalIface('DOMError')
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -7800,17 +7800,17 @@ class CGBindingImplClass(CGClass):
 
         # Invoke  CGClass.__init__ in any subclasses afterwards to do the actual codegen.
 
     def getWrapObjectBody(self):
         return None
 
     def getGetParentObjectReturnType(self):
         return ("// TODO: return something sensible here, and change the return type\n"
-                "%s*" % self.descriptor.name)
+                "%s*" % self.descriptor.nativeType.split('::')[-1])
 
     def getGetParentObjectBody(self):
         return None
 
     def deps(self):
         return self._deps
 
 
@@ -7820,68 +7820,70 @@ class CGExampleClass(CGBindingImplClass)
     """
     def __init__(self, descriptor):
         CGBindingImplClass.__init__(self, descriptor, CGExampleMethod, CGExampleGetter, CGExampleSetter)
 
         extradeclarations=(
             "public:\n"
             "  NS_DECL_CYCLE_COLLECTING_ISUPPORTS\n"
             "  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(%s)\n"
-            "\n" % descriptor.name)
-
-        CGClass.__init__(self, descriptor.name,
+            "\n" % descriptor.nativeType.split('::')[-1])
+
+        CGClass.__init__(self, descriptor.nativeType.split('::')[-1],
                          bases=[ClassBase("nsISupports /* Change nativeOwnership in the binding configuration if you don't want this */"),
                                 ClassBase("nsWrapperCache /* Change wrapperCache in the binding configuration if you don't want this */")],
                          constructors=[ClassConstructor([],
                                                         visibility="public")],
                          destructor=ClassDestructor(visibility="public"),
                          methods=self.methodDecls,
                          decorators="MOZ_FINAL",
                          extradeclarations=extradeclarations)
 
     def define(self):
         # Just override CGClass and do our own thing
         classImpl = """
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(${ifaceName})
-NS_IMPL_CYCLE_COLLECTING_ADDREF(${ifaceName})
-NS_IMPL_CYCLE_COLLECTING_RELEASE(${ifaceName})
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${ifaceName})
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(${nativeType})
+NS_IMPL_CYCLE_COLLECTING_ADDREF(${nativeType})
+NS_IMPL_CYCLE_COLLECTING_RELEASE(${nativeType})
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${nativeType})
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
-${ifaceName}::${ifaceName}()
+${nativeType}::${nativeType}()
 {
   SetIsDOMBinding();
 }
 
-${ifaceName}::~${ifaceName}()
+${nativeType}::~${nativeType}()
 {
 }
 """
         if self.descriptor.wrapperCache:
             classImpl += """
 JSObject*
-${ifaceName}::WrapObject(JSContext* aCx, JSObject* aScope)
+${nativeType}::WrapObject(JSContext* aCx, JSObject* aScope)
 {
   return ${ifaceName}Binding::Wrap(aCx, aScope, this);
 }
 
 """
         else:
             classImpl += """
 JSObject*
-${ifaceName}::WrapObject(JSContext* aCx, JSObject* aScope)
+${nativeType}::WrapObject(JSContext* aCx, JSObject* aScope)
 {
   return ${ifaceName}Binding::Wrap(aCx, aScope, this);
 }
 
 """
+
         return string.Template(classImpl).substitute(
-            { "ifaceName": self.descriptor.name }
+            { "ifaceName": self.descriptor.name,
+              "nativeType": self.descriptor.nativeType.split('::')[-1] }
             )
 
 
 class CGExampleRoot(CGThing):
     """
     Root codegen class for example implementation generation.  Instantiate the
     class and call declare or define to generate header or cpp code,
     respectively.
--- a/dom/bindings/Makefile.in
+++ b/dom/bindings/Makefile.in
@@ -121,16 +121,19 @@ EXPORTS_GENERATED_TARGET := webidl-expor
 INSTALL_TARGETS += EXPORTS_GENERATED
 
 ifdef GNU_CC
 CXXFLAGS += -Wno-uninitialized
 endif
 
 include $(topsrcdir)/config/rules.mk
 
+# edmorley is sick of clobbering everytime someone adds an interface
+$(CPPOBJS): PrototypeList.h
+
 # We need to create a separate target so we can ensure that the pickle is
 # done before generating headers.
 export:: ParserResults.pkl
 	$(MAKE) webidl-export
 
 # If you change bindinggen_dependencies here, change it in
 # dom/bindings/test/Makefile.in too.
 bindinggen_dependencies := \
--- a/dom/file/AsyncHelper.cpp
+++ b/dom/file/AsyncHelper.cpp
@@ -18,22 +18,20 @@ NS_IMPL_THREADSAFE_ISUPPORTS2(AsyncHelpe
 
 nsresult
 AsyncHelper::AsyncWork(nsIRequestObserver* aObserver, nsISupports* aCtxt)
 {
   nsresult rv;
 
   if (aObserver) {
     // build proxy for observer events
-    rv = NS_NewRequestObserverProxy(getter_AddRefs(mObserver), aObserver);
+    rv = NS_NewRequestObserverProxy(getter_AddRefs(mObserver), aObserver, aCtxt);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  mCtxt = aCtxt;
-
   FileService* service = FileService::GetOrCreate();
   NS_ENSURE_TRUE(service, NS_ERROR_FAILURE);
 
   nsIEventTarget* target = service->StreamTransportTarget();
 
   rv = target->Dispatch(this, NS_DISPATCH_NORMAL);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -41,23 +39,23 @@ AsyncHelper::AsyncWork(nsIRequestObserve
 }
 
 NS_IMETHODIMP
 AsyncHelper::Run()
 {
   NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
 
   if (mObserver) {
-    mObserver->OnStartRequest(this, mCtxt);
+    mObserver->OnStartRequest(this, nullptr);
   }
 
   mStatus = DoStreamWork(mStream);
 
   if (mObserver) {
-    mObserver->OnStopRequest(this, mCtxt, mStatus);
+    mObserver->OnStopRequest(this, nullptr, mStatus);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 AsyncHelper::GetName(nsACString& aName)
 {
--- a/dom/file/AsyncHelper.h
+++ b/dom/file/AsyncHelper.h
@@ -42,16 +42,15 @@ protected:
   { }
 
   virtual nsresult
   DoStreamWork(nsISupports* aStream) = 0;
 
 private:
   nsCOMPtr<nsISupports> mStream;
   nsCOMPtr<nsIRequestObserver> mObserver;
-  nsCOMPtr<nsISupports> mCtxt;
 
   nsresult mStatus;
 };
 
 END_FILE_NAMESPACE
 
 #endif // mozilla_dom_file_asynchelper_h__
--- a/dom/interfaces/html/nsIDOMHTMLMediaElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLMediaElement.idl
@@ -32,17 +32,17 @@ interface nsIDOMHTMLMediaElement : nsIDO
 {
   // error state
   readonly attribute nsIDOMMediaError error;
 
   // network state
            attribute DOMString src;
            attribute nsIDOMMediaStream mozSrcObject;
   readonly attribute DOMString currentSrc;
-           attribute DOMString crossorigin;
+           attribute DOMString crossOrigin;
   const unsigned short NETWORK_EMPTY = 0;
   const unsigned short NETWORK_IDLE = 1;
   const unsigned short NETWORK_LOADING = 2;
   const unsigned short NETWORK_NO_SOURCE = 3;
   readonly attribute unsigned short networkState;
            attribute DOMString preload;
   readonly attribute nsIDOMTimeRanges buffered;
   void load();
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1111,24 +1111,24 @@ ContentChild::RecvActivateA11y()
         do_GetService("@mozilla.org/accessibilityService;1");
 #endif
     return true;
 }
 
 bool
 ContentChild::RecvGarbageCollect()
 {
-    nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC);
+    nsJSContext::GarbageCollectNow(JS::gcreason::DOM_IPC);
     return true;
 }
 
 bool
 ContentChild::RecvCycleCollect()
 {
-    nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC);
+    nsJSContext::GarbageCollectNow(JS::gcreason::DOM_IPC);
     nsJSContext::CycleCollectNow();
     return true;
 }
 
 static void
 PreloadSlowThings()
 {
     // This fetches and creates all the built-in stylesheets.
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -138,17 +138,17 @@ IceCandidate.prototype = {
                                     flags: Ci.nsIClassInfo.DOM_OBJECT}),
 
   QueryInterface: XPCOMUtils.generateQI([
     Ci.nsIDOMRTCIceCandidate, Ci.nsIDOMGlobalObjectConstructor
   ]),
 
   constructor: function(win, candidateInitDict) {
     if (this._win) {
-      throw new Error("Constructor already called");
+      throw new Components.Exception("Constructor already called");
     }
     this._win = win;
     if (candidateInitDict !== undefined) {
       this.candidate = candidateInitDict.candidate || null;
       this.sdpMid = candidateInitDict.sdpMid || null;
       this.sdpMLineIndex = candidateInitDict.sdpMLineIndex === null ?
             null : candidateInitDict.sdpMLineIndex + 1;
     } else {
@@ -173,17 +173,17 @@ SessionDescription.prototype = {
                                     flags: Ci.nsIClassInfo.DOM_OBJECT}),
 
   QueryInterface: XPCOMUtils.generateQI([
     Ci.nsIDOMRTCSessionDescription, Ci.nsIDOMGlobalObjectConstructor
   ]),
 
   constructor: function(win, descriptionInitDict) {
     if (this._win) {
-      throw new Error("Constructor already called");
+      throw new Components.Exception("Constructor already called");
     }
     this._win = win;
     if (descriptionInitDict !== undefined) {
       this.type = descriptionInitDict.type || null;
       this.sdp = descriptionInitDict.sdp || null;
     } else {
       this.type = this.sdp = null;
     }
@@ -245,30 +245,30 @@ PeerConnection.prototype = {
     Ci.nsIDOMRTCPeerConnection,
     Ci.nsIDOMGlobalObjectConstructor,
     Ci.nsISupportsWeakReference
   ]),
 
   // Constructor is an explicit function, because of nsIDOMGlobalObjectConstructor.
   constructor: function(win, rtcConfig) {
     if (!Services.prefs.getBoolPref("media.peerconnection.enabled")) {
-      throw new Error("PeerConnection not enabled (did you set the pref?)");
+      throw new Components.Exception("PeerConnection not enabled (did you set the pref?)");
     }
     if (this._win) {
-      throw new Error("RTCPeerConnection constructor already called");
+      throw new Components.Exception("RTCPeerConnection constructor already called");
     }
     if (!rtcConfig ||
         !Services.prefs.getBoolPref("media.peerconnection.use_document_iceservers")) {
       rtcConfig = {iceServers:
         JSON.parse(Services.prefs.getCharPref("media.peerconnection.default_iceservers"))};
     }
     this._mustValidateRTCConfiguration(rtcConfig,
         "RTCPeerConnection constructor passed invalid RTCConfiguration");
     if (_globalPCList._networkdown) {
-      throw new Error("Can't create RTCPeerConnections when the network is down");
+      throw new Components.Exception("Can't create RTCPeerConnections when the network is down");
     }
 
     this._pc = Cc["@mozilla.org/peerconnection;1"].
              createInstance(Ci.IPeerConnection);
     this._observer = new PeerConnectionObserver(this);
 
     // Nothing starts until ICE gathering completes.
     this._queueOrRun({
@@ -339,33 +339,36 @@ PeerConnection.prototype = {
     function isArraylike(obj) {
       return isObject(obj) && ("length" in obj);
     }
     function nicerNewURI(uriStr, errorMsg) {
       let ios = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService);
       try {
         return ios.newURI(uriStr, null, null);
       } catch (e if (e.result == Cr.NS_ERROR_MALFORMED_URI)) {
-        throw new Error(errorMsg + " - malformed URI: " + uriStr);
+        throw new Components.Exception(errorMsg + " - malformed URI: " + uriStr,
+                                       Cr.NS_ERROR_MALFORMED_URI);
       }
     }
     function mustValidateServer(server) {
       let url = nicerNewURI(server.url, errorMsg);
       if (!(url.scheme in { stun:1, stuns:1, turn:1, turns:1 })) {
-        throw new Error (errorMsg + " - improper scheme: " + url.scheme);
+        throw new Components.Exception(errorMsg + " - improper scheme: " + url.scheme,
+                                       Cr.NS_ERROR_MALFORMED_URI);
       }
       if (server.credential && isObject(server.credential)) {
-        throw new Error (errorMsg + " - invalid credential");
+        throw new Components.Exception(errorMsg + " - invalid credential");
       }
     }
     if (!isObject(rtcConfig)) {
-      throw new Error (errorMsg);
+      throw new Components.Exception(errorMsg);
     }
     if (!isArraylike(rtcConfig.iceServers)) {
-      throw new Error (errorMsg + " - iceServers [] property not present");
+      throw new Components.Exception(errorMsg +
+                                     " - iceServers [] property not present");
     }
     let len = rtcConfig.iceServers.length;
     for (let i=0; i < len; i++) {
       mustValidateServer (rtcConfig.iceServers[i], errorMsg);
     }
   },
 
   /**
@@ -395,65 +398,67 @@ PeerConnection.prototype = {
     const OTHER_KNOWN_CONSTRAINTS = {
       VoiceActivityDetection:1,
       IceTransports:1,
       RequestIdentity:1
     };
     // Parse-aid: Testing for pilot error of missing outer block avoids
     // otherwise silent no-op since both mandatory and optional are optional
     if (!isObject(constraints) || Array.isArray(constraints)) {
-      throw new Error(errorMsg);
+      throw new Components.Exception(errorMsg);
     }
     if (constraints.mandatory) {
       // Testing for pilot error of using [] on mandatory here throws nicer msg
       // (arrays would throw in loop below regardless but with more cryptic msg)
       if (!isObject(constraints.mandatory) || Array.isArray(constraints.mandatory)) {
-        throw new Error(errorMsg + " - malformed mandatory constraints");
+        throw new Components.Exception(errorMsg + " - malformed mandatory constraints");
       }
       for (let constraint in constraints.mandatory) {
         if (!(constraint in SUPPORTED_CONSTRAINTS) &&
             constraints.mandatory.hasOwnProperty(constraint)) {
-          throw new Error (errorMsg + " - " +
-                           ((constraint in OTHER_KNOWN_CONSTRAINTS)?
-                            "unsupported" : "unknown") +
-                           " mandatory constraint: " + constraint);
+          throw new Components.Exception(errorMsg + " - " +
+                                         ((constraint in OTHER_KNOWN_CONSTRAINTS)?
+                                          "unsupported" : "unknown") +
+                                         " mandatory constraint: " + constraint);
         }
       }
     }
     if (constraints.optional) {
       if (!isArraylike(constraints.optional)) {
-        throw new Error(errorMsg + " - malformed optional constraint array");
+        throw new Components.Exception(errorMsg +
+                                       " - malformed optional constraint array");
       }
       let len = constraints.optional.length;
       for (let i = 0; i < len; i += 1) {
         if (!isObject(constraints.optional[i])) {
-          throw new Error(errorMsg + " - malformed optional constraint: " +
-                          constraints.optional[i]);
+          throw new Components.Exception(errorMsg +
+                                         " - malformed optional constraint: " +
+                                         constraints.optional[i]);
         }
         let constraints_per_entry = 0;
         for (let constraint in constraints.optional[i]) {
           if (constraints.optional[i].hasOwnProperty(constraint)) {
             if (constraints_per_entry) {
-              throw new Error (errorMsg +
-                               " - optional constraint must be single key/value pair");
+              throw new Components.Exception(errorMsg +
+                  " - optional constraint must be single key/value pair");
             }
             constraints_per_entry += 1;
           }
         }
       }
     }
   },
 
   // Ideally, this should be of the form _checkState(state),
   // where the state is taken from an enumeration containing
   // the valid peer connection states defined in the WebRTC
   // spec. See Bug 831756.
   _checkClosed: function() {
     if (this._closed) {
-      throw new Error ("Peer connection is closed");
+      throw new Components.Exception("Peer connection is closed");
     }
   },
 
   createOffer: function(onSuccess, onError, constraints) {
     if (!constraints) {
       constraints = {};
     }
 
@@ -530,19 +535,18 @@ PeerConnection.prototype = {
     switch (desc.type) {
       case "offer":
         type = Ci.IPeerConnection.kActionOffer;
         break;
       case "answer":
         type = Ci.IPeerConnection.kActionAnswer;
         break;
       default:
-        throw new Error(
-          "Invalid type " + desc.type + " provided to setLocalDescription"
-        );
+        throw new Components.Exception("Invalid type " + desc.type +
+                                       " provided to setLocalDescription");
         break;
     }
 
     this._queueOrRun({
       func: this._pc.setLocalDescription,
       args: [type, desc.sdp],
       wait: true,
       type: desc.type
@@ -560,19 +564,18 @@ PeerConnection.prototype = {
     switch (desc.type) {
       case "offer":
         type = Ci.IPeerConnection.kActionOffer;
         break;
       case "answer":
         type = Ci.IPeerConnection.kActionAnswer;
         break;
       default:
-        throw new Error(
-          "Invalid type " + desc.type + " provided to setRemoteDescription"
-        );
+        throw new Components.Exception("Invalid type " + desc.type +
+                                       " provided to setRemoteDescription");
         break;
     }
 
     this._queueOrRun({
       func: this._pc.setRemoteDescription,
       args: [type, desc.sdp],
       wait: true,
       type: desc.type
@@ -580,21 +583,21 @@ PeerConnection.prototype = {
   },
 
   updateIce: function(config, constraints, restart) {
     return Cr.NS_ERROR_NOT_IMPLEMENTED;
   },
 
   addIceCandidate: function(cand, onSuccess, onError) {
     if (!cand) {
-      throw new Error ("NULL candidate passed to addIceCandidate!");
+      throw new Components.Exception("NULL candidate passed to addIceCandidate!");
     }
 
     if (!cand.candidate || !cand.sdpMLineIndex) {
-      throw new Error ("Invalid candidate passed to addIceCandidate!");
+      throw new Components.Exception("Invalid candidate passed to addIceCandidate!");
     }
 
     this._onAddIceCandidateSuccess = onSuccess;
     this._onAddIceCandidateError = onError;
 
     this._queueOrRun({
       func: this._pc.addIceCandidate,
       args: [cand.candidate, cand.sdpMid || "", cand.sdpMLineIndex],
@@ -662,17 +665,17 @@ PeerConnection.prototype = {
     };
   },
 
   createDataChannel: function(label, dict) {
     this._checkClosed();
     if (dict &&
         dict.maxRetransmitTime != undefined &&
         dict.maxRetransmitNum != undefined) {
-      throw new Error("Both maxRetransmitTime and maxRetransmitNum cannot be provided");
+      throw new Components.Exception("Both maxRetransmitTime and maxRetransmitNum cannot be provided");
     }
 
     // Must determine the type where we still know if entries are undefined.
     let type;
     if (dict.maxRetransmitTime != undefined) {
       type = Ci.IPeerConnection.kDataChannelPartialReliableTimed;
     } else if (dict.maxRetransmitNum != undefined) {
       type = Ci.IPeerConnection.kDataChannelPartialReliableRexmit;
--- a/dom/mms/src/ril/MmsService.js
+++ b/dom/mms/src/ril/MmsService.js
@@ -34,31 +34,32 @@ const HTTP_STATUS_OK = 200;
 const CONFIG_SEND_REPORT_NEVER       = 0;
 const CONFIG_SEND_REPORT_DEFAULT_NO  = 1;
 const CONFIG_SEND_REPORT_DEFAULT_YES = 2;
 const CONFIG_SEND_REPORT_ALWAYS      = 3;
 
 const TIME_TO_BUFFER_MMS_REQUESTS    = 30000;
 const TIME_TO_RELEASE_MMS_CONNECTION = 30000;
 
-const PREF_RETRIEVAL_MODE = 'dom.mms.retrieval_mode';
-const RETRIEVAL_MODE_MANUAL = "manual";
+const PREF_RETRIEVAL_MODE      = 'dom.mms.retrieval_mode';
+const RETRIEVAL_MODE_MANUAL    = "manual";
 const RETRIEVAL_MODE_AUTOMATIC = "automatic";
-const RETRIEVAL_MODE_NEVER = "never";
+const RETRIEVAL_MODE_NEVER     = "never";
 
 
 //Internal const values.
-const DELIVERY_RECEIVED = "received";
+const DELIVERY_RECEIVED       = "received";
 const DELIVERY_NOT_DOWNLOADED = "not-downloaded";
-const DELIVERY_SENDING = "sending";
-const DELIVERY_SENT = "sent";
-const DELIVERY_ERROR = "error";
+const DELIVERY_SENDING        = "sending";
+const DELIVERY_SENT           = "sent";
+const DELIVERY_ERROR          = "error";
 
 const DELIVERY_STATUS_SUCCESS = "success";
 const DELIVERY_STATUS_PENDING = "pending";
+const DELIVERY_STATUS_ERROR   = "error";
 
 
 const MAX_RETRY_COUNT = Services.prefs.getIntPref("dom.mms.retrievalRetryCount");
 const DELAY_TIME_TO_RETRY = Services.prefs.getIntPref("dom.mms.retrievalRetryInterval");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gpps",
                                    "@mozilla.org/network/protocol-proxy-service;1",
                                    "nsIProtocolProxyService");
@@ -1053,16 +1054,17 @@ MmsService.prototype = {
           // For X-Mms-Report-Allowed
           let reportAllowed = this.getReportAllowed(this.confSendDeliveryReport,
                                                     wish);
 
           let transaction = new NotifyResponseTransaction(transactionId,
                                                           mmsStatus,
                                                           reportAllowed);
           transaction.run();
+          return;
         }
 
         this.retrieveMessage(url, (function responseNotify(mmsStatus,
                                                            retrievedMessage) {
           // `The absence of the field does not indicate any default
           // value.` So we go checking the same field in retrieved
           // message instead.
           if ((wish == null) && retrievedMessage) {
@@ -1077,16 +1079,17 @@ MmsService.prototype = {
           // If the mmsStatus is still MMS_PDU_STATUS_DEFERRED after retry, we
           // should not store into database.
           if (MMS.MMS_PDU_STATUS_RETRIEVED !== mmsStatus) {
             let transaction =
               new NotifyResponseTransaction(transactionId,
                                             mmsStatus,
                                             reportAllowed);
             transaction.run();
+            return;
           }
 
           savableMessage = this.mergeRetrievalConfirmation(retrievedMessage,
                                                            savableMessage);
 
           gMobileMessageDatabaseService.saveReceivedMessage(savableMessage,
             (function (rv, domMessage) {
               let success = Components.isSuccessCode(rv);
@@ -1105,17 +1108,16 @@ MmsService.prototype = {
                 return;
               }
 
               // Notifing new retrieved MMS message through notifyObservers.
               Services.obs.notifyObservers(domMessage, kMmsReceivedObserverTopic, null);
             }).bind(this)
           );
         }).bind(this));
-        return;
       }).bind(this)
     );
   },
 
   /**
    * Handle incoming M-Delivery.ind PDU.
    *
    * @param msg
@@ -1131,44 +1133,51 @@ MmsService.prototype = {
     // topics to MobileMessageManager.
     let messageId = msg.headers["message-id"];
     debug("handleDeliveryIndication: got delivery report for " + messageId);
   },
 
   createSavableFromParams: function createSavableFromParams(aParams) {
     debug("createSavableFromParams: aParams: " + JSON.stringify(aParams));
     let message = {};
+    let smil = aParams.smil;
 
     // |message.headers|
     let headers = message["headers"] = {};
     let receivers = aParams.receivers;
     if (receivers.length != 0) {
       let headersTo = headers["to"] = [];
       for (let i = 0; i < receivers.length; i++) {
         headersTo.push({"address": receivers[i], "type": "PLMN"});
       }
     }
     if (aParams.subject) {
       headers["subject"] = aParams.subject;
     }
 
     // |message.parts|
     let attachments = aParams.attachments;
-    if (attachments.length != 0 || aParams.smil) {
+    if (attachments.length != 0 || smil) {
       let parts = message["parts"] = [];
 
       // Set the SMIL part if needed.
-      if (aParams.smil) {
+      if (smil) {
         let part = {
           "headers": {
             "content-type": {
               "media": "application/smil",
+              "params": {
+                "name": "smil.xml"
+              }
             },
+            "content-length": smil.length,
+            "content-location": "smil.xml",
+            "content-id": "<smil>"
           },
-          "content": aParams.smil
+          "content": smil
         };
         parts.push(part);
       }
 
       // Set other parts for attachments if needed.
       for (let i = 0; i < attachments.length; i++) {
         let attachment = attachments[i];
         let content = attachment.content;
@@ -1208,18 +1217,18 @@ MmsService.prototype = {
 
     let self = this;
 
     let sendTransactionCb = function sendTransactionCb(aRecordId, aIsSentSuccess) {
       debug("The success status of sending transaction: " + aIsSentSuccess);
       gMobileMessageDatabaseService
         .setMessageDelivery(aRecordId,
                             null,
-                            aIsSentSuccess ? "sent" : "error",
-                            aIsSentSuccess ? null : "error",
+                            aIsSentSuccess ? DELIVERY_SENT : DELIVERY_ERROR,
+                            aIsSentSuccess ? null : DELIVERY_STATUS_ERROR,
                             function notifySetDeliveryResult(aRv, aDomMessage) {
         debug("Marking the delivery state/staus is done. Notify sent or failed.");
         if (!aIsSentSuccess) {
           aRequest.notifySendMessageFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
           Services.obs.notifyObservers(aDomMessage, kMmsFailedObserverTopic, null);
           return;
         }
         aRequest.notifyMessageSent(aDomMessage);
--- a/dom/mms/src/ril/WspPduHelper.jsm
+++ b/dom/mms/src/ril/WspPduHelper.jsm
@@ -2287,18 +2287,29 @@ this.PduHelper = {
         headers["content-type"] = contentType;
         headers["content-length"] = contentLen;
 
         headers = this.parseHeaders(data, headersEnd, headers);
 
         let octetArray = Octet.decodeMultiple(data, contentEnd);
         let content = null;
         if (octetArray) {
-          content = new Blob([octetArray],
-                             {type : headers["content-type"].media});
+          // If the content is a SMIL type, convert it to a string.
+          // We hope to save and expose the SMIL content as a string way.
+          if (headers["content-type"].media == "application/smil") {
+            let charset = headers["content-type"].params &&
+                          headers["content-type"].params.charset
+                        ? headers["content-type"].params.charset["charset"]
+                        : null;
+            content = this.decodeStringContent(octetArray, charset);
+          }
+          if (!content) {
+            content = new Blob([octetArray],
+                               {type : headers["content-type"].media});
+          }
         }
 
         parts[i] = {
           index: i,
           headers: headers,
           content: content,
         };
       } catch (e) {
--- a/dom/plugins/ipc/PluginHangUIParent.cpp
+++ b/dom/plugins/ipc/PluginHangUIParent.cpp
@@ -292,16 +292,20 @@ PluginHangUIParent::SendCancel()
   }
   cmd->mCode = PluginHangUICommand::HANGUI_CMD_CANCEL;
   return NS_SUCCEEDED(mMiniShm.Send());
 }
 
 bool
 PluginHangUIParent::RecvUserResponse(const unsigned int& aResponse)
 {
+  if (!mIsShowing && !(aResponse & HANGUI_USER_RESPONSE_CANCEL)) {
+    // Don't process a user response if a cancellation is already pending
+    return true;
+  }
   mLastUserResponse = aResponse;
   mResponseTicks = GetTickCount();
   mIsShowing = false;
   // responseCode: 1 = Stop, 2 = Continue, 3 = Cancel
   int responseCode;
   if (aResponse & HANGUI_USER_RESPONSE_STOP) {
     // User clicked Stop
     mModule->TerminateChildProcess(mMainThreadMessageLoop);
--- a/dom/webidl/CanvasRenderingContext2D.webidl
+++ b/dom/webidl/CanvasRenderingContext2D.webidl
@@ -10,17 +10,16 @@
  * Opera Software ASA. You are granted a license to use, reproduce
  * and create derivative works of this document.
  */
 
 interface CanvasGradient;
 interface CanvasPattern;
 interface HitRegionOptions;
 interface HTMLCanvasElement;
-interface HTMLVideoElement;
 interface TextMetrics;
 interface Window;
 
 enum CanvasWindingRule { "nonzero", "evenodd" };
 
 interface CanvasRenderingContext2D {
 
   // back-reference to the canvas.  Might be null if we're not
new file mode 100644
--- /dev/null
+++ b/dom/webidl/HTMLAudioElement.webidl
@@ -0,0 +1,32 @@
+/* -*- 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://www.whatwg.org/specs/web-apps/current-work/#the-audio-element
+ *
+ * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
+ * Opera Software ASA. You are granted a license to use, reproduce
+ * and create derivative works of this document.
+ */
+
+[NamedConstructor=Audio(),
+ NamedConstructor=Audio(DOMString src)]
+interface HTMLAudioElement : HTMLMediaElement {};
+
+partial interface HTMLAudioElement
+{
+  // Setup the audio stream for writing
+  [Throws]
+  void mozSetup(unsigned long channels, unsigned long rate);
+
+  // Write audio to the audio stream
+  [Throws]
+  unsigned long mozWriteAudio(any data);
+
+  // Get the current offset (measured in samples since the start) of the audio
+  // stream created using mozWriteAudio().
+  [Throws]
+  unsigned long long mozCurrentSampleOffset();
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/HTMLMediaElement.webidl
@@ -0,0 +1,180 @@
+/* -*- 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://www.whatwg.org/specs/web-apps/current-work/#media-elements
+ *
+ * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
+ * Opera Software ASA. You are granted a license to use, reproduce
+ * and create derivative works of this document.
+ */
+
+interface HTMLMediaElement : HTMLElement {
+
+  // error state
+  readonly attribute MediaError? error;
+
+  // network state
+  [SetterThrows]
+           attribute DOMString src;
+  readonly attribute DOMString currentSrc;
+
+  [SetterThrows]
+           attribute DOMString crossOrigin;
+  const unsigned short NETWORK_EMPTY = 0;
+  const unsigned short NETWORK_IDLE = 1;
+  const unsigned short NETWORK_LOADING = 2;
+  const unsigned short NETWORK_NO_SOURCE = 3;
+  readonly attribute unsigned short networkState;
+  [SetterThrows]
+           attribute DOMString preload;
+  [Creator]
+  readonly attribute TimeRanges buffered;
+  void load();
+  DOMString canPlayType(DOMString type);
+
+  // ready state
+  const unsigned short HAVE_NOTHING = 0;
+  const unsigned short HAVE_METADATA = 1;
+  const unsigned short HAVE_CURRENT_DATA = 2;
+  const unsigned short HAVE_FUTURE_DATA = 3;
+  const unsigned short HAVE_ENOUGH_DATA = 4;
+  readonly attribute unsigned short readyState;
+  readonly attribute boolean seeking;
+
+  // playback state
+  [SetterThrows]
+           attribute double currentTime;
+  // TODO: Bug 847375 - void fastSeek(double time);
+  readonly attribute unrestricted double duration;
+  // TODO: Bug 847376 - readonly attribute any startDate;
+  readonly attribute boolean paused;
+  [SetterThrows]
+           attribute double defaultPlaybackRate;
+  [SetterThrows]
+           attribute double playbackRate;
+  [Creator]
+  readonly attribute TimeRanges played;
+  [Creator]
+  readonly attribute TimeRanges seekable;
+  readonly attribute boolean ended;
+  [SetterThrows]
+           attribute boolean autoplay;
+  [SetterThrows]
+           attribute boolean loop;
+  [Throws]
+  void play();
+  [Throws]
+  void pause();
+
+  // TODO: Bug 847377 - mediaGroup and MediaController
+  // media controller
+  //         attribute DOMString mediaGroup;
+  //         attribute MediaController? controller;
+
+  // controls
+  [SetterThrows]
+           attribute boolean controls;
+  [SetterThrows]
+           attribute double volume;
+           attribute boolean muted;
+  [SetterThrows]
+           attribute boolean defaultMuted;
+
+  // TODO: Bug 847379
+  // tracks
+  //readonly attribute AudioTrackList audioTracks;
+  //readonly attribute VideoTrackList videoTracks;
+  //readonly attribute TextTrackList textTracks;
+  //TextTrack addTextTrack(DOMString kind, optional DOMString label, optional DOMString language);
+};
+
+// Mozilla extensions:
+partial interface HTMLMediaElement {
+  attribute MediaStream? mozSrcObject;
+  readonly attribute double initialTime;
+  attribute boolean mozPreservesPitch;
+  readonly attribute boolean mozAutoplayEnabled;
+
+  // Mozilla extension: stream capture
+  [Throws]
+  MediaStream mozCaptureStream();
+  [Throws]
+  MediaStream mozCaptureStreamUntilEnded();
+  readonly attribute boolean mozAudioCaptured;
+
+  // Mozilla extension: extra stream metadata information, used as part
+  // of MozAudioAvailable events and the mozWriteAudio() method.  The
+  // mozFrameBufferLength method allows for the size of the framebuffer
+  // used within MozAudioAvailable events to be changed.  The new size must
+  // be between 512 and 16384.  The default size, for a  media element with
+  // audio is (mozChannels * 1024).
+  [GetterThrows]
+  readonly attribute unsigned long mozChannels;
+  [GetterThrows]
+  readonly attribute unsigned long mozSampleRate;
+  [Throws]
+           attribute unsigned long mozFrameBufferLength;
+
+  // Mozilla extension: return embedded metadata from the stream as a
+  // JSObject with key:value pairs for each tag. This can be used by
+  // player interfaces to display the song title, artist, etc.
+  [Throws]
+  object? mozGetMetadata();
+
+  // Mozilla extension: load data from another media element. This is like
+  // load() but we don't run the resource selection algorithm; instead
+  // we just set our source to other's currentSrc. This is optimized
+  // so that this element will get access to all of other's cached/
+  // buffered data. In fact any future data downloaded by this element or
+  // other will be sharable by both elements.
+  [Throws]
+  void mozLoadFrom(HTMLMediaElement other);
+
+  // Mozilla extension: provides access to the fragment end time if
+  // the media element has a fragment URI for the currentSrc, otherwise
+  // it is equal to the media duration.
+  readonly attribute double mozFragmentEnd;
+
+  // Mozilla extension: an audio channel type for media elements.
+  // An exception is thrown if the app tries to change the audio channel type
+  // without the permission (manifest file for B2G apps).
+  // The supported values are:
+  // * normal (default value)
+  //   Automatically paused if "notification" or higher priority channel
+  //   is played
+  //   Use case: normal applications
+  // * content
+  //   Automatically paused if "notification" or higher priority channel
+  //   is played. Also paused if another app starts using "content"
+  //   channel. Using this channel never affects applications using
+  //   the "normal" channel.
+  //   Use case: video/audio players
+  // * notification
+  //   Automatically paused if "alarm" or higher priority channel is played.
+  //   Use case: New email, incoming SMS
+  // * alarm
+  //   Automatically paused if "telephony" or higher priority channel is
+  //   played.
+  //   User case: Alarm clock, calendar alarms
+  // * telephony
+  //   Automatically paused if "ringer" or higher priority
+  //   channel is played.
+  //   Use case: dialer, voip
+  // * ringer
+  //   Automatically paused if "publicnotification" or higher priority
+  //   channel is played.
+  //   Use case: dialer, voip
+  // * publicnotification
+  //   Always plays in speaker, even when headphones are plugged in.
+  //   Use case: Camera shutter sound.
+  [SetterThrows]
+  attribute DOMString mozAudioChannelType;
+
+  // In addition the media element has this new events:
+  // * onmozinterruptbegin - called when the media element is interrupted
+  //   because of the audiochannel manager.
+  // * onmozinterruptend - called when the interruption is concluded
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/HTMLVideoElement.webidl
@@ -0,0 +1,47 @@
+/* -*- 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://www.whatwg.org/specs/web-apps/current-work/#the-video-element
+ *
+ * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
+ * Opera Software ASA. You are granted a license to use, reproduce
+ * and create derivative works of this document.
+ */
+
+interface HTMLVideoElement : HTMLMediaElement {
+  [SetterThrows]
+           attribute unsigned long width;
+  [SetterThrows]
+           attribute unsigned long height;
+  readonly attribute unsigned long videoWidth;
+  readonly attribute unsigned long videoHeight;
+  [SetterThrows]
+           attribute DOMString poster;
+};
+
+partial interface HTMLVideoElement {
+  // A count of the number of video frames that have demuxed from the media
+  // resource. If we were playing perfectly, we'd be able to paint this many
+  // frames.
+  readonly attribute unsigned long mozParsedFrames;
+
+  // A count of the number of frames that have been decoded. We may drop
+  // frames if the decode is taking too much time.
+  readonly attribute unsigned long mozDecodedFrames;
+
+  // A count of the number of frames that have been presented to the rendering
+  // pipeline. We may drop frames if they arrive late at the renderer.
+  readonly attribute unsigned long mozPresentedFrames;
+
+  // Number of presented frames which were painted on screen.
+  readonly attribute unsigned long mozPaintedFrames;
+
+  // Time which the last painted video frame was late by, in seconds.
+  readonly attribute double mozFrameDelay;
+
+  // True if the video has an audio track available.
+  readonly attribute boolean mozHasAudio;
+};
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -64,16 +64,17 @@ webidl_files = \
   FileReaderSync.webidl \
   FileRequest.webidl \
   FormData.webidl \
   Function.webidl \
   GainNode.webidl \
   HTMLAnchorElement.webidl \
   HTMLAppletElement.webidl \
   HTMLAreaElement.webidl \
+  HTMLAudioElement.webidl \
   HTMLBaseElement.webidl \
   HTMLBodyElement.webidl \
   HTMLBRElement.webidl \
   HTMLButtonElement.webidl \
   HTMLCollection.webidl \
   HTMLDataElement.webidl \
   HTMLDataListElement.webidl \
   HTMLDirectoryElement.webidl \
@@ -91,16 +92,17 @@ webidl_files = \
   HTMLHRElement.webidl \
   HTMLHtmlElement.webidl \
   HTMLImageElement.webidl \
   HTMLLabelElement.webidl \
   HTMLLegendElement.webidl \
   HTMLLIElement.webidl \
   HTMLLinkElement.webidl \
   HTMLMapElement.webidl \
+  HTMLMediaElement.webidl \
   HTMLMenuElement.webidl \
   HTMLMenuItemElement.webidl \
   HTMLMetaElement.webidl \
   HTMLMeterElement.webidl \
   HTMLModElement.webidl \
   HTMLObjectElement.webidl \
   HTMLOListElement.webidl \
   HTMLOptGroupElement.webidl \
@@ -121,16 +123,17 @@ webidl_files = \
   HTMLTableColElement.webidl \
   HTMLTableElement.webidl \
   HTMLTableRowElement.webidl \
   HTMLTableSectionElement.webidl \
   HTMLTextAreaElement.webidl \
   HTMLTimeElement.webidl \
   HTMLTitleElement.webidl \
   HTMLUListElement.webidl \
+  HTMLVideoElement.webidl \
   IDBVersionChangeEvent.webidl \
   ImageData.webidl \
   InspectorUtils.webidl \
   LinkStyle.webidl \
   LocalMediaStream.webidl \
   Location.webidl \
   MediaStream.webidl \
   MessageEvent.webidl \
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -4137,22 +4137,22 @@ WorkerPrivate::UpdateGCZealInternal(JSCo
 
 void
 WorkerPrivate::GarbageCollectInternal(JSContext* aCx, bool aShrinking,
                                       bool aCollectChildren)
 {
   AssertIsOnWorkerThread();
 
   JSRuntime *rt = JS_GetRuntime(aCx);
-  js::PrepareForFullGC(rt);
+  JS::PrepareForFullGC(rt);
   if (aShrinking) {
-    js::ShrinkingGC(rt, js::gcreason::DOM_WORKER);
+    JS::ShrinkingGC(rt, JS::gcreason::DOM_WORKER);
   }
   else {
-    js::GCForReason(rt, js::gcreason::DOM_WORKER);
+    JS::GCForReason(rt, JS::gcreason::DOM_WORKER);
   }
 
   if (aCollectChildren) {
     for (uint32_t index = 0; index < mChildWorkers.Length(); index++) {
       mChildWorkers[index]->GarbageCollect(aCx, aShrinking);
     }
   }
 }
--- a/gfx/qcms/Makefile.in
+++ b/gfx/qcms/Makefile.in
@@ -48,17 +48,17 @@ else
 endif
 else
 	SSE1_FLAGS=
 	SSE2_FLAGS=
 endif
 endif
 endif
 else
-ifeq (ppc,$(CPU_ARCH))
+ifeq (ppc,$(findstring ppc,$(CPU_ARCH)))
 ifdef GNU_CC
 	CSRCS += transform-altivec.c
 	ALTIVEC_FLAGS=-maltivec
 endif
 endif
 endif
 
 FORCE_STATIC_LIB = 1
--- a/js/public/HashTable.h
+++ b/js/public/HashTable.h
@@ -481,29 +481,29 @@ class HashSet
 
 // Pointer hashing policy that strips the lowest zeroBits when calculating the
 // hash to improve key distribution.
 template <typename Key, size_t zeroBits>
 struct PointerHasher
 {
     typedef Key Lookup;
     static HashNumber hash(const Lookup &l) {
-        JS_ASSERT(!js::IsPoisonedPtr(l));
+        JS_ASSERT(!JS::IsPoisonedPtr(l));
         size_t word = reinterpret_cast<size_t>(l) >> zeroBits;
         JS_STATIC_ASSERT(sizeof(HashNumber) == 4);
 #if JS_BYTES_PER_WORD == 4
         return HashNumber(word);
 #else
         JS_STATIC_ASSERT(sizeof word == 8);
         return HashNumber((word >> 32) ^ word);
 #endif
     }
     static bool match(const Key &k, const Lookup &l) {
-        JS_ASSERT(!js::IsPoisonedPtr(k));
-        JS_ASSERT(!js::IsPoisonedPtr(l));
+        JS_ASSERT(!JS::IsPoisonedPtr(k));
+        JS_ASSERT(!JS::IsPoisonedPtr(l));
         return k == l;
     }
 };
 
 // Default hash policy: just use the 'lookup' value. This of course only
 // works if the lookup value is integral. HashTable applies ScrambleHashCode to
 // the result of the 'hash' which means that it is 'ok' if the lookup value is
 // not well distributed over the HashNumber domain.
--- a/js/public/RootingAPI.h
+++ b/js/public/RootingAPI.h
@@ -324,17 +324,17 @@ class InternalHandle<T*>
     InternalHandle(const JS::Handle<H> &handle, T *field)
       : holder((void**)handle.address()), offset(uintptr_t(field) - uintptr_t(handle.get()))
     {}
 
     /*
      * Create an InternalHandle to a field within a Rooted<>.
      */
     template<typename R>
-    InternalHandle(const Rooted<R> &root, T *field)
+    InternalHandle(const JS::Rooted<R> &root, T *field)
       : holder((void**)root.address()), offset(uintptr_t(field) - uintptr_t(root.get()))
     {}
 
     T *get() const { return reinterpret_cast<T*>(uintptr_t(*holder) + offset); }
 
     const T &operator*() const { return *get(); }
     T *operator->() const { return get(); }
 
@@ -383,17 +383,17 @@ struct RootKind<T *>
     static ThingRootKind rootKind() { return T::rootKind(); }
 };
 
 template <typename T>
 struct RootMethods<T *>
 {
     static T *initial() { return NULL; }
     static ThingRootKind kind() { return RootKind<T *>::rootKind(); }
-    static bool poisoned(T *v) { return IsPoisonedPtr(v); }
+    static bool poisoned(T *v) { return JS::IsPoisonedPtr(v); }
 };
 
 } /* namespace js */
 
 namespace JS {
 
 /*
  * Local variable of type T whose value is always rooted. This is typically
@@ -702,44 +702,44 @@ enum AllowGC {
 template <typename T, AllowGC allowGC>
 class MaybeRooted
 {
 };
 
 template <typename T> class MaybeRooted<T, CanGC>
 {
   public:
-    typedef Handle<T> HandleType;
-    typedef Rooted<T> RootType;
-    typedef MutableHandle<T> MutableHandleType;
+    typedef JS::Handle<T> HandleType;
+    typedef JS::Rooted<T> RootType;
+    typedef JS::MutableHandle<T> MutableHandleType;
 
-    static inline Handle<T> toHandle(HandleType v) {
+    static inline JS::Handle<T> toHandle(HandleType v) {
         return v;
     }
 
-    static inline MutableHandle<T> toMutableHandle(MutableHandleType v) {
+    static inline JS::MutableHandle<T> toMutableHandle(MutableHandleType v) {
         return v;
     }
 };
 
 template <typename T> class MaybeRooted<T, NoGC>
 {
   public:
     typedef T HandleType;
     typedef FakeRooted<T> RootType;
     typedef FakeMutableHandle<T> MutableHandleType;
 
-    static inline Handle<T> toHandle(HandleType v) {
+    static inline JS::Handle<T> toHandle(HandleType v) {
         JS_NOT_REACHED("Bad conversion");
-        return Handle<T>::fromMarkedLocation(NULL);
+        return JS::Handle<T>::fromMarkedLocation(NULL);
     }
 
-    static inline MutableHandle<T> toMutableHandle(MutableHandleType v) {
+    static inline JS::MutableHandle<T> toMutableHandle(MutableHandleType v) {
         JS_NOT_REACHED("Bad conversion");
-        return MutableHandle<T>::fromMarkedLocation(NULL);
+        return JS::MutableHandle<T>::fromMarkedLocation(NULL);
     }
 };
 
 } /* namespace js */
 
 namespace JS {
 
 template <typename T> template <typename S>
@@ -760,32 +760,28 @@ Handle<T>::Handle(MutableHandle<S> &root
 
 template <typename T>
 inline
 MutableHandle<T>::MutableHandle(Rooted<T> *root)
 {
     ptr = root->address();
 }
 
-JS_FRIEND_API(bool) NeedRelaxedRootChecks();
-
 } /* namespace JS */
 
 namespace js {
 
 /*
  * Hook for dynamic root analysis. Checks the native stack and poisons
  * references to GC things which have not been rooted.
  */
-inline void MaybeCheckStackRoots(JSContext *cx, bool relax = true)
+inline void MaybeCheckStackRoots(JSContext *cx)
 {
 #if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
-    if (relax && NeedRelaxedRootChecks())
-        return;
-    CheckStackRoots(cx);
+    JS::CheckStackRoots(cx);
 #endif
 }
 
 namespace gc {
 struct Cell;
 } /* namespace gc */
 
 /* Base class for automatic read-only object rooting during compilation. */
--- a/js/public/Utility.h
+++ b/js/public/Utility.h
@@ -26,22 +26,17 @@
 
 /* The public JS engine namespace. */
 namespace JS {}
 
 /* The mozilla-shared reusable template/utility namespace. */
 namespace mozilla {}
 
 /* The private JS engine namespace. */
-namespace js {
-
-/* The private namespace is a superset of the public/shared namespaces. */
-using namespace JS;
-
-}  /* namespace js */
+namespace js {}
 
 /*
  * Pattern used to overwrite freed memory. If you are accessing an object with
  * this pattern, you probably have a dangling pointer.
  */
 #define JS_FREE_PATTERN 0xDA
 
 #define JS_ASSERT(expr)           MOZ_ASSERT(expr)
--- a/js/public/Value.h
+++ b/js/public/Value.h
@@ -1392,26 +1392,26 @@ SameType(const Value &lhs, const Value &
 } // namespace JS
 
 /************************************************************************/
 
 namespace js {
 
 template <> struct RootMethods<const JS::Value>
 {
-    static JS::Value initial() { return UndefinedValue(); }
+    static JS::Value initial() { return JS::UndefinedValue(); }
     static ThingRootKind kind() { return THING_ROOT_VALUE; }
-    static bool poisoned(const JS::Value &v) { return IsPoisonedValue(v); }
+    static bool poisoned(const JS::Value &v) { return JS::IsPoisonedValue(v); }
 };
 
 template <> struct RootMethods<JS::Value>
 {
-    static JS::Value initial() { return UndefinedValue(); }
+    static JS::Value initial() { return JS::UndefinedValue(); }
     static ThingRootKind kind() { return THING_ROOT_VALUE; }
-    static bool poisoned(const JS::Value &v) { return IsPoisonedValue(v); }
+    static bool poisoned(const JS::Value &v) { return JS::IsPoisonedValue(v); }
 };
 
 template <class Outer> class MutableValueOperations;
 
 /*
  * A class designed for CRTP use in implementing the non-mutating parts of the
  * Value interface in Value-like classes.  Outer must be a class inheriting
  * ValueOperations<Outer> with a visible extract() method returning the
@@ -1483,57 +1483,57 @@ class MutableValueOperations : public Va
     void setObjectOrNull(JSObject *arg) { value()->setObjectOrNull(arg); }
 };
 
 /*
  * Augment the generic Handle<T> interface when T = Value with type-querying
  * and value-extracting operations.
  */
 template <>
-class HandleBase<JS::Value> : public ValueOperations<Handle<JS::Value> >
+class HandleBase<JS::Value> : public ValueOperations<JS::Handle<JS::Value> >
 {
-    friend class ValueOperations<Handle<JS::Value> >;
+    friend class ValueOperations<JS::Handle<JS::Value> >;
     const JS::Value * extract() const {
-        return static_cast<const Handle<JS::Value>*>(this)->address();
+        return static_cast<const JS::Handle<JS::Value>*>(this)->address();
     }
 };
 
 /*
  * Augment the generic MutableHandle<T> interface when T = Value with
  * type-querying, value-extracting, and mutating operations.
  */
 template <>
-class MutableHandleBase<JS::Value> : public MutableValueOperations<MutableHandle<JS::Value> >
+class MutableHandleBase<JS::Value> : public MutableValueOperations<JS::MutableHandle<JS::Value> >
 {
-    friend class ValueOperations<MutableHandle<JS::Value> >;
+    friend class ValueOperations<JS::MutableHandle<JS::Value> >;
     const JS::Value * extract() const {
-        return static_cast<const MutableHandle<JS::Value>*>(this)->address();
+        return static_cast<const JS::MutableHandle<JS::Value>*>(this)->address();
     }
 
-    friend class MutableValueOperations<MutableHandle<JS::Value> >;
+    friend class MutableValueOperations<JS::MutableHandle<JS::Value> >;
     JS::Value * extractMutable() {
-        return static_cast<MutableHandle<JS::Value>*>(this)->address();
+        return static_cast<JS::MutableHandle<JS::Value>*>(this)->address();
     }
 };
 
 /*
  * Augment the generic Rooted<T> interface when T = Value with type-querying,
  * value-extracting, and mutating operations.
  */
 template <>
-class RootedBase<JS::Value> : public MutableValueOperations<Rooted<JS::Value> >
+class RootedBase<JS::Value> : public MutableValueOperations<JS::Rooted<JS::Value> >
 {
-    friend class ValueOperations<Rooted<JS::Value> >;
+    friend class ValueOperations<JS::Rooted<JS::Value> >;
     const JS::Value * extract() const {
-        return static_cast<const Rooted<JS::Value>*>(this)->address();
+        return static_cast<const JS::Rooted<JS::Value>*>(this)->address();
     }
 
-    friend class MutableValueOperations<Rooted<JS::Value> >;
+    friend class MutableValueOperations<JS::Rooted<JS::Value> >;
     JS::Value * extractMutable() {
-        return static_cast<Rooted<JS::Value>*>(this)->address();
+        return static_cast<JS::Rooted<JS::Value>*>(this)->address();
     }
 };
 
 } // namespace js
 
 inline jsval_layout
 JSVAL_TO_IMPL(JS::Value v)
 {
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -139,16 +139,17 @@ CPPSRCS		= \
 		StoreBuffer.cpp \
 		Iteration.cpp \
 		Zone.cpp \
 		Verifier.cpp \
 		StringBuffer.cpp \
 		Unicode.cpp \
 		Xdr.cpp \
 		Module.cpp \
+		Instruments.cpp \
 		$(NULL)
 
 # Changes to internal header files, used externally, massively slow down
 # browser builds.  Don't add new files here unless you know what you're
 # doing!
 INSTALLED_HEADERS = \
 		js-config.h \
 		jscpucfg.h \
--- a/js/src/builtin/Profilers.cpp
+++ b/js/src/builtin/Profilers.cpp
@@ -16,16 +16,17 @@
 #include "vm/Stack-inl.h"
 
 #ifdef MOZ_CALLGRIND
 #include <valgrind/callgrind.h>
 #endif
 
 #ifdef __APPLE__
 #include "devtools/sharkctl.h"
+#include "devtools/Instruments.h"
 #endif
 
 using namespace js;
 
 using mozilla::ArrayLength;
 
 /* Thread-unsafe error management */
 
@@ -46,40 +47,67 @@ UnsafeError(const char *format, ...)
 }
 
 JS_PUBLIC_API(const char *)
 JS_UnsafeGetLastProfilingError()
 {
     return gLastError;
 }
 
+#ifdef __APPLE__
+static bool
+StartOSXProfiling(const char *profileName = NULL)
+{
+    bool ok = true;
+    const char* profiler = NULL;
+#ifdef MOZ_SHARK
+    ok = Shark::Start();
+    profiler = "Shark";
+#endif
+#ifdef MOZ_INSTRUMENTS
+    ok = Instruments::Start();
+    profiler = "Instruments";
+#endif
+    if (!ok) {
+        if (profileName)
+            UnsafeError("Failed to start %s for %s", profiler, profileName);
+        else
+            UnsafeError("Failed to start %s", profiler);
+        return false;
+    }
+    return true;
+}
+#endif
+
 JS_PUBLIC_API(JSBool)
 JS_StartProfiling(const char *profileName)
 {
     JSBool ok = JS_TRUE;
-#if defined(MOZ_SHARK) && defined(__APPLE__)
-    if (!Shark::Start()) {
-        UnsafeError("Failed to start Shark for %s", profileName);
-        ok = JS_FALSE;
-    }
+#ifdef __APPLE__
+    ok = StartOSXProfiling(profileName);
 #endif
 #ifdef __linux__
     if (!js_StartPerf())
         ok = JS_FALSE;
 #endif
     return ok;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_StopProfiling(const char *profileName)
 {
     JSBool ok = JS_TRUE;
-#if defined(MOZ_SHARK) && defined(__APPLE__)
+#ifdef __APPLE__
+#ifdef MOZ_SHARK
     Shark::Stop();
 #endif
+#ifdef MOZ_INSTRUMENTS
+    Instruments::Stop(profileName);
+#endif
+#endif
 #ifdef __linux__
     if (!js_StopPerf())
         ok = JS_FALSE;
 #endif
     return ok;
 }
 
 /*
@@ -87,32 +115,47 @@ JS_StopProfiling(const char *profileName
  * backends are available.
  */
 static JSBool
 ControlProfilers(bool toState)
 {
     JSBool ok = JS_TRUE;
 
     if (! Probes::ProfilingActive && toState) {
-#if defined(MOZ_SHARK) && defined(__APPLE__)
-        if (!Shark::Start()) {
-            UnsafeError("Failed to start Shark");
-            ok = JS_FALSE;
+#ifdef __APPLE__
+#if defined(MOZ_SHARK) || defined(MOZ_INSTRUMENTS)
+        const char* profiler;
+#ifdef MOZ_SHARK
+        ok = Shark::Start();
+        profiler = "Shark";
+#endif
+#ifdef MOZ_INSTRUMENTS
+        ok = Instruments::Resume();
+        profiler = "Instruments";
+#endif
+        if (!ok) {
+            UnsafeError("Failed to start %s", profiler);
         }
 #endif
+#endif
 #ifdef MOZ_CALLGRIND
         if (! js_StartCallgrind()) {
             UnsafeError("Failed to start Callgrind");
             ok = JS_FALSE;
         }
 #endif
     } else if (Probes::ProfilingActive && ! toState) {
-#if defined(MOZ_SHARK) && defined(__APPLE__)
+#ifdef __APPLE__
+#ifdef MOZ_SHARK
         Shark::Stop();
 #endif
+#ifdef MOZ_INSTRUMENTS
+        Instruments::Pause();
+#endif
+#endif
 #ifdef MOZ_CALLGRIND
         if (! js_StopCallgrind()) {
             UnsafeError("failed to stop Callgrind");
             ok = JS_FALSE;
         }
 #endif
     }
 
@@ -258,17 +301,17 @@ DumpProfile(JSContext *cx, unsigned argc
             ret = JS_DumpProfile(filename.mBytes, profileName.mBytes);
         }
     }
 
     JS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(ret));
     return true;
 }
 
-#ifdef MOZ_SHARK
+#if defined(MOZ_SHARK) || defined(MOZ_INSTRUMENTS)
 
 static JSBool
 IgnoreAndReturnTrue(JSContext *cx, unsigned argc, jsval *vp)
 {
     JS_SET_RVAL(cx, vp, JSVAL_TRUE);
     return true;
 }
 
@@ -307,17 +350,17 @@ DumpCallgrind(JSContext *cx, unsigned ar
 #endif
 
 static JSFunctionSpec profiling_functions[] = {
     JS_FN("startProfiling",  StartProfiling,      1,0),
     JS_FN("stopProfiling",   StopProfiling,       1,0),
     JS_FN("pauseProfilers",  PauseProfilers,      1,0),
     JS_FN("resumeProfilers", ResumeProfilers,     1,0),
     JS_FN("dumpProfile",     DumpProfile,         2,0),
-#ifdef MOZ_SHARK
+#if defined(MOZ_SHARK) || defined(MOZ_INSTRUMENTS)
     /* Keep users of the old shark API happy. */
     JS_FN("connectShark",    IgnoreAndReturnTrue, 0,0),
     JS_FN("disconnectShark", IgnoreAndReturnTrue, 0,0),
     JS_FN("startShark",      StartProfiling,      0,0),
     JS_FN("stopShark",       StopProfiling,       0,0),
 #endif
 #ifdef MOZ_CALLGRIND
     JS_FN("startCallgrind", StartCallgrind,       0,0),
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -3641,16 +3641,29 @@ MOZ_ARG_ENABLE_BOOL(shark,
     MOZ_SHARK=1,
     MOZ_SHARK= )
 if test -n "$MOZ_SHARK"; then
     MOZ_PROFILING=1
     AC_DEFINE(MOZ_SHARK)
 fi
 
 dnl ========================================================
+dnl instruments
+dnl ========================================================
+MOZ_ARG_ENABLE_BOOL(instruments,
+[  --enable-instruments    Enable instruments remote profiling. Implies --enable-profiling.],
+    MOZ_INSTRUMENTS=1,
+    MOZ_INSTRUMENTS= )
+if test -n "$MOZ_INSTRUMENTS"; then
+    MOZ_PROFILING=1
+    AC_DEFINE(MOZ_INSTRUMENTS)
+    LIBS="$LIBS -framework CoreFoundation"
+fi
+
+dnl ========================================================
 dnl callgrind
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(callgrind,
 [  --enable-callgrind      Enable callgrind profiling. Implies --enable-profiling.],
     MOZ_CALLGRIND=1,
     MOZ_CALLGRIND= )
 if test -n "$MOZ_CALLGRIND"; then
     MOZ_PROFILING=1
@@ -4118,16 +4131,17 @@ AC_SUBST(MOZ_DEBUG)
 AC_SUBST(MOZ_DEBUG_SYMBOLS)
 AC_SUBST(MOZ_DEBUG_ENABLE_DEFS)
 AC_SUBST(MOZ_DEBUG_DISABLE_DEFS)
 AC_SUBST(MOZ_DEBUG_FLAGS)
 AC_SUBST(MOZ_DEBUG_LDFLAGS)
 AC_SUBST(WARNINGS_AS_ERRORS)
 AC_SUBST(MOZ_JPROF)
 AC_SUBST(MOZ_SHARK)
+AC_SUBST(MOZ_INSTRUMENTS)
 AC_SUBST(MOZ_CALLGRIND)
 AC_SUBST(MOZ_VTUNE)
 AC_SUBST(MOZ_ETW)
 AC_SUBST(MOZ_PROFILING)
 AC_SUBST(LIBICONV)
 
 AC_SUBST(ENABLE_TESTS)
 
new file mode 100644
--- /dev/null
+++ b/js/src/devtools/Instruments.cpp
@@ -0,0 +1,233 @@
+/* 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 "Instruments.h"
+
+#ifdef __APPLE__
+
+#include "jsapi.h"
+#include <dlfcn.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+// There are now 2 paths to the DTPerformanceSession framework. We try to load
+// the one contained in /Applications/Xcode.app first, falling back to the one
+// contained in /Library/Developer/4.0/Instruments.
+#define DTPerformanceLibraryPath "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/DTPerformanceSession.framework/Versions/Current/DTPerformanceSession"
+#define OldDTPerformanceLibraryPath "/Library/Developer/4.0/Instruments/Frameworks/DTPerformanceSession.framework/Versions/Current/DTPerformanceSession"
+
+extern "C" {
+
+typedef CFTypeRef DTPerformanceSessionRef;
+
+#define DTPerformanceSession_TimeProfiler               "com.apple.instruments.dtps.timeprofiler"
+// DTPerformanceSession_Option_SamplingInterval is measured in microseconds
+#define DTPerformanceSession_Option_SamplingInterval    "com.apple.instruments.dtps.option.samplinginterval"
+
+typedef void (*dtps_errorcallback_t)(CFStringRef, CFErrorRef);
+typedef DTPerformanceSessionRef (*DTPerformanceSessionCreateFunction)(CFStringRef, CFStringRef, CFDictionaryRef, CFErrorRef*);
+typedef bool (*DTPerformanceSessionAddInstrumentFunction)(DTPerformanceSessionRef, CFStringRef, CFDictionaryRef, dtps_errorcallback_t, CFErrorRef*);
+typedef bool (*DTPerformanceSessionIsRecordingFunction)(DTPerformanceSessionRef);
+typedef bool (*DTPerformanceSessionStartFunction)(DTPerformanceSessionRef, CFArrayRef, CFErrorRef*);
+typedef bool (*DTPerformanceSessionStopFunction)(DTPerformanceSessionRef, CFArrayRef, CFErrorRef*);
+typedef bool (*DTPerformanceSessionSaveFunction)(DTPerformanceSessionRef, CFStringRef, CFErrorRef*);
+
+} // extern "C"
+
+namespace Instruments {
+
+static const int kSamplingInterval = 20; // microseconds
+
+template<typename T>
+class AutoReleased
+{
+public:
+  AutoReleased(T aTypeRef) : mTypeRef(aTypeRef)
+  {
+  }
+  ~AutoReleased()
+  {
+    if (mTypeRef) {
+      CFRelease(mTypeRef);
+    }
+  }
+
+  operator T()
+  {
+    return mTypeRef;
+  }
+
+private:
+  T mTypeRef;
+};
+
+#define DTPERFORMANCE_SYMBOLS \
+  SYMBOL(DTPerformanceSessionCreate) \
+  SYMBOL(DTPerformanceSessionAddInstrument) \
+  SYMBOL(DTPerformanceSessionIsRecording) \
+  SYMBOL(DTPerformanceSessionStart) \
+  SYMBOL(DTPerformanceSessionStop) \
+  SYMBOL(DTPerformanceSessionSave)
+
+#define SYMBOL(_sym) \
+  _sym##Function _sym = NULL;
+
+DTPERFORMANCE_SYMBOLS
+
+#undef SYMBOL
+
+void*
+LoadDTPerformanceLibraries(bool dontLoad)
+{
+  int flags = RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE;
+  if (dontLoad) {
+    flags |= RTLD_NOLOAD;
+  }
+
+  void *DTPerformanceLibrary = dlopen(DTPerformanceLibraryPath, flags);
+  if (!DTPerformanceLibrary) {
+    DTPerformanceLibrary = dlopen(OldDTPerformanceLibraryPath, flags);
+  }
+  return DTPerformanceLibrary;
+}
+
+bool
+LoadDTPerformanceLibrary()
+{
+  void *DTPerformanceLibrary = LoadDTPerformanceLibraries(true);
+  if (!DTPerformanceLibrary) {
+    DTPerformanceLibrary = LoadDTPerformanceLibraries(false);
+    if (!DTPerformanceLibrary) {
+      return false;
+    }
+  }
+
+#define SYMBOL(_sym) \
+  _sym = reinterpret_cast<_sym##Function>(dlsym(DTPerformanceLibrary, #_sym)); \
+  if (!_sym) { \
+    dlclose(DTPerformanceLibrary); \
+    DTPerformanceLibrary = NULL; \
+    return false; \
+  }
+
+  DTPERFORMANCE_SYMBOLS
+
+#undef SYMBOL
+
+  dlclose(DTPerformanceLibrary);
+
+  return true;
+}
+
+static DTPerformanceSessionRef gSession;
+
+bool
+Error(CFErrorRef error)
+{
+  if (gSession) {
+    CFErrorRef unused = NULL;
+    DTPerformanceSessionStop(gSession, NULL, &unused);
+    CFRelease(gSession);
+    gSession = NULL;
+  }
+#ifdef DEBUG
+  AutoReleased<CFDataRef> data =
+    CFStringCreateExternalRepresentation(NULL, CFErrorCopyDescription(error),
+                                         kCFStringEncodingUTF8, '?');
+  if (data != NULL) {
+    printf("%.*s\n\n", (int)CFDataGetLength(data), CFDataGetBytePtr(data));
+  }
+#endif
+  return false;
+}
+
+bool
+Start()
+{
+  if (gSession) {
+    return false;
+  }
+
+  if (!LoadDTPerformanceLibrary()) {
+    return false;
+  }
+
+  AutoReleased<CFStringRef> process =
+    CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), getpid());
+  if (!process) {
+    return false;
+  }
+  CFErrorRef error = NULL;
+  gSession = DTPerformanceSessionCreate(NULL, process, NULL, &error);
+  if (!gSession) {
+    return Error(error);
+  }
+
+  AutoReleased<CFNumberRef> interval =
+    CFNumberCreate(0, kCFNumberIntType, &kSamplingInterval);
+  if (!interval) {
+    return false;
+  }
+  CFStringRef keys[1] = { CFSTR(DTPerformanceSession_Option_SamplingInterval) };
+  CFNumberRef values[1] = { interval };
+  AutoReleased<CFDictionaryRef> options =
+    CFDictionaryCreate(kCFAllocatorDefault, (const void**)keys,
+                       (const void**)values, 1, &kCFTypeDictionaryKeyCallBacks,
+                       &kCFTypeDictionaryValueCallBacks);
+  if (!options) {
+    return false;
+  }
+
+  if (!DTPerformanceSessionAddInstrument(gSession,
+                                         CFSTR(DTPerformanceSession_TimeProfiler),
+                                         options, NULL, &error)) {
+    return Error(error);
+  }
+
+  return Resume();
+}
+
+void
+Pause()
+{
+  if (gSession && DTPerformanceSessionIsRecording(gSession)) {
+    CFErrorRef error = NULL;
+    if (!DTPerformanceSessionStop(gSession, NULL, &error)) {
+      Error(error);
+    }
+  }
+}
+
+bool
+Resume()
+{
+  if (!gSession) {
+    return false;
+  }
+
+  CFErrorRef error = NULL;
+  return DTPerformanceSessionStart(gSession, NULL, &error) ||
+         Error(error);
+}
+
+void
+Stop(const char* profileName)
+{
+  Pause();
+
+  CFErrorRef error = NULL;
+  AutoReleased<CFStringRef> name =
+    CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s%s"), "/tmp/",
+                             profileName ? profileName : "mozilla");
+  if (!DTPerformanceSessionSave(gSession, name, &error)) {
+    Error(error);
+    return;
+  }
+
+  CFRelease(gSession);
+  gSession = NULL;
+}
+
+} // namespace Instruments
+
+#endif /* __APPLE__ */
new file mode 100644
--- /dev/null
+++ b/js/src/devtools/Instruments.h
@@ -0,0 +1,21 @@
+/* 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 Instruments_h__
+#define Instruments_h__
+
+#ifdef __APPLE__
+
+namespace Instruments {
+
+bool Start();
+void Pause();
+bool Resume();
+void Stop(const char* profileName);
+
+}
+
+#endif /* __APPLE__ */
+
+#endif /* Instruments_h__ */
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -1660,39 +1660,45 @@ BytecodeEmitter::tellDebuggerAboutCompil
             compileAndGoGlobal = &script->global();
         Debugger::onNewScript(cx, script, compileAndGoGlobal);
     }
 }
 
 bool
 BytecodeEmitter::reportError(ParseNode *pn, unsigned errorNumber, ...)
 {
+    TokenPos pos = pn ? pn->pn_pos : tokenStream()->currentToken().pos;
+
     va_list args;
     va_start(args, errorNumber);
-    bool result = tokenStream()->reportCompileErrorNumberVA(pn->pn_pos, JSREPORT_ERROR, errorNumber, args);
+    bool result = tokenStream()->reportCompileErrorNumberVA(pos, JSREPORT_ERROR, errorNumber, args);
     va_end(args);
     return result;
 }
 
 bool
 BytecodeEmitter::reportStrictWarning(ParseNode *pn, unsigned errorNumber, ...)
 {
+    TokenPos pos = pn ? pn->pn_pos : tokenStream()->currentToken().pos;
+
     va_list args;
     va_start(args, errorNumber);
-    bool result = tokenStream()->reportStrictWarningErrorNumberVA(pn->pn_pos, errorNumber, args);
+    bool result = tokenStream()->reportStrictWarningErrorNumberVA(pos, errorNumber, args);
     va_end(args);
     return result;
 }
 
 bool
 BytecodeEmitter::reportStrictModeError(ParseNode *pn, unsigned errorNumber, ...)
 {
+    TokenPos pos = pn ? pn->pn_pos : tokenStream()->currentToken().pos;
+
     va_list args;
     va_start(args, errorNumber);
-    bool result = tokenStream()->reportStrictModeErrorNumberVA(pn->pn_pos, sc->strict, errorNumber, args);
+    bool result = tokenStream()->reportStrictModeErrorNumberVA(pos, sc->strict, errorNumber, args);
     va_end(args);
     return result;
 }
 
 static bool
 EmitNameOp(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool callContext)
 {
     JSOp op;
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -1569,17 +1569,17 @@ UnmarkGrayChildren(JSTracer *trc, void *
         /*
          * If we run out of stack, we take a more drastic measure: require that
          * we GC again before the next CC.
          */
         trc->runtime->gcGrayBitsValid = false;
         return;
     }
 
-    if (!GCThingIsMarkedGray(thing))
+    if (!JS::GCThingIsMarkedGray(thing))
         return;
 
     UnmarkGrayGCThing(thing);
 
     /*
      * Trace children of |thing|. If |thing| and its parent are both shapes,
      * |thing| will get saved to mPreviousShape without being traced. The parent
      * will later trace |thing|. This is done to avoid increasing the stack
@@ -1597,29 +1597,29 @@ UnmarkGrayChildren(JSTracer *trc, void *
 
     if (tracer->tracingShape) {
         JS_ASSERT(!tracer->previousShape);
         tracer->previousShape = thing;
         return;
     }
 
     do {
-        JS_ASSERT(!GCThingIsMarkedGray(thing));
+        JS_ASSERT(!JS::GCThingIsMarkedGray(thing));
         JS_TraceChildren(&childTracer, thing, JSTRACE_SHAPE);
         thing = childTracer.previousShape;
         childTracer.previousShape = NULL;
     } while (thing);
 }
 
 JS_FRIEND_API(void)
 JS::UnmarkGrayGCThingRecursively(void *thing, JSGCTraceKind kind)
 {
     JS_ASSERT(kind != JSTRACE_SHAPE);
 
-    if (!GCThingIsMarkedGray(thing))
+    if (!JS::GCThingIsMarkedGray(thing))
         return;
 
     UnmarkGrayGCThing(thing);
 
     JSRuntime *rt = static_cast<Cell *>(thing)->zone()->rt;
     UnmarkGrayTracer trc(rt);
     JS_TraceChildren(&trc, thing, kind);
 }
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -371,17 +371,17 @@ ConservativeGCData::recordStackTop()
 #endif
     (void) setjmp(registerSnapshot.jmpbuf);
 #if defined(_MSC_VER)
 # pragma warning(pop)
 #endif
 }
 
 void
-AutoIdArray::trace(JSTracer *trc)
+JS::AutoIdArray::trace(JSTracer *trc)
 {
     JS_ASSERT(tag_ == IDARRAY);
     gc::MarkIdRange(trc, idArray->length, idArray->vector, "JSAutoIdArray.idArray");
 }
 
 inline void
 AutoGCRooter::trace(JSTracer *trc)
 {
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -236,24 +236,24 @@ class gcstats::StatisticsSerializer
     }
 };
 
 /*
  * If this fails, then you can either delete this assertion and allow all
  * larger-numbered reasons to pile up in the last telemetry bucket, or switch
  * to GC_REASON_3 and bump the max value.
  */
-JS_STATIC_ASSERT(gcreason::NUM_TELEMETRY_REASONS >= gcreason::NUM_REASONS);
+JS_STATIC_ASSERT(JS::gcreason::NUM_TELEMETRY_REASONS >= JS::gcreason::NUM_REASONS);
 
 static const char *
-ExplainReason(gcreason::Reason reason)
+ExplainReason(JS::gcreason::Reason reason)
 {
     switch (reason) {
 #define SWITCH_REASON(name)                     \
-        case gcreason::name:                    \
+        case JS::gcreason::name:                    \
           return #name;
         GCREASONS(SWITCH_REASON)
 
         default:
           JS_NOT_REACHED("bad GC reason");
           return "?";
 #undef SWITCH_REASON
     }
@@ -566,17 +566,17 @@ Statistics::endGC()
     }
 
     if (fp)
         printStats();
 }
 
 void
 Statistics::beginSlice(int collectedCount, int zoneCount, int compartmentCount,
-                       gcreason::Reason reason)
+                       JS::gcreason::Reason reason)
 {
     this->collectedCount = collectedCount;
     this->zoneCount = zoneCount;
     this->compartmentCount = compartmentCount;
 
     bool first = runtime->gcIncrementalState == gc::NO_INCREMENTAL;
     if (first)
         beginGC();
@@ -585,18 +585,19 @@ Statistics::beginSlice(int collectedCoun
     (void) slices.append(data); /* Ignore any OOMs here. */
 
     if (JSAccumulateTelemetryDataCallback cb = runtime->telemetryCallback)
         (*cb)(JS_TELEMETRY_GC_REASON, reason);
 
     // Slice callbacks should only fire for the outermost level
     if (++gcDepth == 1) {
         bool wasFullGC = collectedCount == zoneCount;
-        if (GCSliceCallback cb = runtime->gcSliceCallback)
-            (*cb)(runtime, first ? GC_CYCLE_BEGIN : GC_SLICE_BEGIN, GCDescription(!wasFullGC));
+        if (JS::GCSliceCallback cb = runtime->gcSliceCallback)
+            (*cb)(runtime, first ? JS::GC_CYCLE_BEGIN : JS::GC_SLICE_BEGIN,
+                  JS::GCDescription(!wasFullGC));
     }
 }
 
 void
 Statistics::endSlice()
 {
     slices.back().end = PRMJ_Now();
     slices.back().endFaults = gc::GetPageFaultCount();
@@ -608,18 +609,19 @@ Statistics::endSlice()
 
     bool last = runtime->gcIncrementalState == gc::NO_INCREMENTAL;
     if (last)
         endGC();
 
     // Slice callbacks should only fire for the outermost level
     if (--gcDepth == 0) {
         bool wasFullGC = collectedCount == zoneCount;
-        if (GCSliceCallback cb = runtime->gcSliceCallback)
-            (*cb)(runtime, last ? GC_CYCLE_END : GC_SLICE_END, GCDescription(!wasFullGC));
+        if (JS::GCSliceCallback cb = runtime->gcSliceCallback)
+            (*cb)(runtime, last ? JS::GC_CYCLE_END : JS::GC_SLICE_END,
+                  JS::GCDescription(!wasFullGC));
     }
 
     /* Do this after the slice callback since it uses these values. */
     if (last)
         PodArrayZero(counts);
 }
 
 void
--- a/js/src/gc/Statistics.h
+++ b/js/src/gc/Statistics.h
@@ -81,17 +81,17 @@ class StatisticsSerializer;
 
 struct Statistics {
     Statistics(JSRuntime *rt);
     ~Statistics();
 
     void beginPhase(Phase phase);
     void endPhase(Phase phase);
 
-    void beginSlice(int collectedCount, int zoneCount, int compartmentCount, gcreason::Reason reason);
+    void beginSlice(int collectedCount, int zoneCount, int compartmentCount, JS::gcreason::Reason reason);
     void endSlice();
 
     void reset(const char *reason) { slices.back().resetReason = reason; }
     void nonincremental(const char *reason) { nonincrementalReason = reason; }
 
     void count(Stat s) {
         JS_ASSERT(s < STAT_LIMIT);
         counts[s]++;
@@ -118,23 +118,23 @@ struct Statistics {
     int gcDepth;
 
     int collectedCount;
     int zoneCount;
     int compartmentCount;
     const char *nonincrementalReason;
 
     struct SliceData {
-        SliceData(gcreason::Reason reason, int64_t start, size_t startFaults)
+        SliceData(JS::gcreason::Reason reason, int64_t start, size_t startFaults)
           : reason(reason), resetReason(NULL), start(start), startFaults(startFaults)
         {
             PodArrayZero(phaseTimes);
         }
 
-        gcreason::Reason reason;
+        JS::gcreason::Reason reason;
         const char *resetReason;
         int64_t start, end;
         size_t startFaults, endFaults;
         int64_t phaseTimes[PHASE_LIMIT];
 
         int64_t duration() const { return end - start; }
     };
 
@@ -174,17 +174,17 @@ struct Statistics {
     bool formatData(StatisticsSerializer &ss, uint64_t timestamp);
 
     double computeMMU(int64_t resolution);
 };
 
 struct AutoGCSlice
 {
     AutoGCSlice(Statistics &stats, int collectedCount, int zoneCount, int compartmentCount,
-                gcreason::Reason reason
+                JS::gcreason::Reason reason
                 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
       : stats(stats)
     {
         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
         stats.beginSlice(collectedCount, zoneCount, compartmentCount, reason);
     }
     ~AutoGCSlice() { stats.endSlice(); }
 
--- a/js/src/gc/Verifier.cpp
+++ b/js/src/gc/Verifier.cpp
@@ -88,17 +88,17 @@ CheckStackRoot(JSRuntime *rt, uintptr_t 
     }
 
     /*
      * Only poison the last byte in the word. It is easy to get accidental
      * collisions when a value that does not occupy a full word is used to
      * overwrite a now-dead GC thing pointer. In this case we want to avoid
      * damaging the smaller value.
      */
-    PoisonPtr(w);
+    JS::PoisonPtr(w);
 }
 
 static void
 CheckStackRootsRange(JSRuntime *rt, uintptr_t *begin, uintptr_t *end, Rooter *rbegin, Rooter *rend)
 {
     JS_ASSERT(begin <= end);
     for (uintptr_t *i = begin; i != end; ++i)
         CheckStackRoot(rt, i, rbegin, rend);
--- a/js/src/ion/Bailouts.cpp
+++ b/js/src/ion/Bailouts.cpp
@@ -187,18 +187,17 @@ StackFrame::initFromBailout(JSContext *c
 static StackFrame *
 PushInlinedFrame(JSContext *cx, StackFrame *callerFrame)
 {
     // Grab the callee object out of the caller's frame, which has already been restored.
     // N.B. we currently assume that the caller frame is at a JSOP_CALL pc for the caller frames,
     // which will not be the case when we inline getters (in which case it would be a
     // JSOP_GETPROP). That will have to be handled differently.
     FrameRegs &regs = cx->regs();
-    JS_ASSERT(JSOp(*regs.pc) == JSOP_CALL || JSOp(*regs.pc) == JSOP_NEW ||
-              JSOp(*regs.pc) == JSOP_FUNAPPLY);
+    JS_ASSERT(js_CodeSpec[*regs.pc].format & JOF_INVOKE);
     int callerArgc = GET_ARGC(regs.pc);
     if (JSOp(*regs.pc) == JSOP_FUNAPPLY)
         callerArgc = callerFrame->nactual();
     const Value &calleeVal = regs.sp[-callerArgc - 2];
 
     RootedFunction fun(cx, calleeVal.toObject().toFunction());
     RootedScript script(cx, fun->nonLazyScript());
     CallArgs inlineArgs = CallArgsFromSp(callerArgc, regs.sp);
@@ -310,18 +309,16 @@ ConvertFrames(JSContext *cx, IonActivati
 
     switch (iter.bailoutKind()) {
       case Bailout_Normal:
         return BAILOUT_RETURN_OK;
       case Bailout_TypeBarrier:
         return BAILOUT_RETURN_TYPE_BARRIER;
       case Bailout_Monitor:
         return BAILOUT_RETURN_MONITOR;
-      case Bailout_RecompileCheck:
-        return BAILOUT_RETURN_RECOMPILE_CHECK;
       case Bailout_BoundsCheck:
         return BAILOUT_RETURN_BOUNDS_CHECK;
       case Bailout_ShapeGuard:
         return BAILOUT_RETURN_SHAPE_GUARD;
       case Bailout_CachedShapeGuard:
         return BAILOUT_RETURN_CACHED_SHAPE_GUARD;
 
       // When bailing out from an argument check, none of the code of the
@@ -466,35 +463,16 @@ ion::ReflowTypeInfo(uint32_t bailoutResu
 
     // When a type barrier fails, the bad value is at the top of the stack.
     Value &result = cx->regs().sp[-1];
     types::TypeScript::Monitor(cx, script, pc, result);
 
     return true;
 }
 
-uint32_t
-ion::RecompileForInlining()
-{
-    JSContext *cx = GetIonContext()->cx;
-    RawScript script = cx->fp()->script();
-
-    IonSpew(IonSpew_Inlining, "Recompiling script to inline calls %s:%d", script->filename(),
-            script->lineno);
-
-    // Invalidate the script to force a recompile.
-    if (!Invalidate(cx, script, /* resetUses */ false))
-        return BAILOUT_RETURN_FATAL_ERROR;
-
-    // Invalidation should not reset the use count.
-    JS_ASSERT(script->getUseCount() >= js_IonOptions.usesBeforeInlining());
-
-    return true;
-}
-
 // Initialize the decl env Object and the call object of the current frame.
 bool
 ion::EnsureHasScopeObjects(JSContext *cx, StackFrame *fp)
 {
     if (fp->isFunctionFrame() &&
         fp->fun()->isHeavyweight() &&
         !fp->hasCallObj())
     {
--- a/js/src/ion/Bailouts.h
+++ b/js/src/ion/Bailouts.h
@@ -99,21 +99,20 @@ static const uint32_t BAILOUT_TABLE_SIZE
 
 // Bailout return codes.
 // N.B. the relative order of these values is hard-coded into ::GenerateBailoutThunk.
 static const uint32_t BAILOUT_RETURN_OK = 0;
 static const uint32_t BAILOUT_RETURN_FATAL_ERROR = 1;
 static const uint32_t BAILOUT_RETURN_ARGUMENT_CHECK = 2;
 static const uint32_t BAILOUT_RETURN_TYPE_BARRIER = 3;
 static const uint32_t BAILOUT_RETURN_MONITOR = 4;
-static const uint32_t BAILOUT_RETURN_RECOMPILE_CHECK = 5;
-static const uint32_t BAILOUT_RETURN_BOUNDS_CHECK = 6;
-static const uint32_t BAILOUT_RETURN_SHAPE_GUARD = 7;
-static const uint32_t BAILOUT_RETURN_OVERRECURSED = 8;
-static const uint32_t BAILOUT_RETURN_CACHED_SHAPE_GUARD = 9;
+static const uint32_t BAILOUT_RETURN_BOUNDS_CHECK = 5;
+static const uint32_t BAILOUT_RETURN_SHAPE_GUARD = 6;
+static const uint32_t BAILOUT_RETURN_OVERRECURSED = 7;
+static const uint32_t BAILOUT_RETURN_CACHED_SHAPE_GUARD = 8;
 
 // Attached to the compartment for easy passing through from ::Bailout to
 // ::ThunkToInterpreter.
 class BailoutClosure
 {
     // These class are used to control the stack usage and the order of
     // declaration is used by the destructor to restore the stack in the
     // expected order when classes are created. This class is only created
@@ -213,18 +212,16 @@ uint32_t Bailout(BailoutStack *sp);
 uint32_t InvalidationBailout(InvalidationBailoutStack *sp, size_t *frameSizeOut);
 
 // Called from a bailout thunk. Interprets the frame(s) that have been bailed
 // out.
 uint32_t ThunkToInterpreter(Value *vp);
 
 uint32_t ReflowTypeInfo(uint32_t bailoutResult);
 
-uint32_t RecompileForInlining();
-
 uint32_t BoundsCheckFailure();
 
 uint32_t ShapeGuardFailure();
 
 uint32_t CachedShapeGuardFailure();
 
 } // namespace ion
 } // namespace js
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -333,19 +333,16 @@ IonBuilder::build()
     // analysis explicitly checks (this is the same mechanism used for
     // effectful operations).
     for (uint32_t i = 0; i < CountArgSlots(info().fun()); i++) {
         MInstruction *ins = current->getEntrySlot(i)->toInstruction();
         if (ins->type() == MIRType_Value)
             ins->setResumePoint(current->entryResumePoint());
     }
 
-    // Recompile to inline calls if this function is hot.
-    insertRecompileCheck();
-
     if (script()->argumentsHasVarBinding()) {
         lazyArguments_ = MConstant::New(MagicValue(JS_OPTIMIZED_ARGUMENTS));
         current->add(lazyArguments_);
     }
 
     if (!traverseBytecode())
         return false;
 
@@ -758,22 +755,19 @@ IonBuilder::snoopControlFlow(JSOp op)
 bool
 IonBuilder::inspectOpcode(JSOp op)
 {
     // Don't compile fat opcodes, run the decomposed version instead.
     if (js_CodeSpec[op].format & JOF_DECOMPOSE)
         return true;
 
     switch (op) {
-      case JSOP_LOOPENTRY:
-        insertRecompileCheck();
-        return true;
-
       case JSOP_NOP:
       case JSOP_LINENO:
+      case JSOP_LOOPENTRY:
         return true;
 
       case JSOP_LABEL:
         return jsop_label();
 
       case JSOP_UNDEFINED:
         return pushConstant(UndefinedValue());
 
@@ -4470,17 +4464,20 @@ IonBuilder::jsop_eval(uint32_t argc)
         }
 
         MInstruction *filterArguments = MFilterArguments::New(string);
         current->add(filterArguments);
 
         MInstruction *ins = MCallDirectEval::New(scopeChain, string, thisValue);
         current->add(ins);
         current->push(ins);
-        return resumeAfter(ins);
+
+        types::StackTypeSet *barrier;
+        types::StackTypeSet *types = oracle->returnTypeSet(script(), pc, &barrier);
+        return resumeAfter(ins) && pushTypeBarrier(ins, types, barrier);
     }
 
     return jsop_call(argc, /* constructing = */ false);
 }
 
 bool
 IonBuilder::jsop_compare(JSOp op)
 {
@@ -4970,39 +4967,16 @@ IonBuilder::maybeInsertResume()
         return true;
 
     MNop *ins = MNop::New();
     current->add(ins);
 
     return resumeAfter(ins);
 }
 
-void
-IonBuilder::insertRecompileCheck()
-{
-    if (!inliningEnabled())
-        return;
-
-    if (inliningDepth_ > 0)
-        return;
-
-    // Don't recompile if we are already inlining.
-    if (script()->getUseCount() >= js_IonOptions.usesBeforeInlining())
-        return;
-
-    // Don't recompile if the oracle cannot provide inlining information
-    // or if the script has no calls.
-    if (!oracle->canInlineCalls())
-        return;
-
-    uint32_t minUses = UsesBeforeIonRecompile(script(), pc);
-    MRecompileCheck *check = MRecompileCheck::New(minUses);
-    current->add(check);
-}
-
 static inline bool
 TestSingletonProperty(JSContext *cx, HandleObject obj, HandleId id, bool *isKnownConstant)
 {
     // We would like to completely no-op property/global accesses which can
     // produce only a particular JSObject. When indicating the access result is
     // definitely an object, type inference does not account for the
     // possibility that the property is entirely missing from the input object
     // and its prototypes (if this happens, a semantic trigger would be hit and
--- a/js/src/ion/IonBuilder.h
+++ b/js/src/ion/IonBuilder.h
@@ -266,18 +266,16 @@ class IonBuilder : public MIRGenerator
 
     // Please see the Big Honkin' Comment about how resume points work in
     // IonBuilder.cpp, near the definition for this function.
     bool resume(MInstruction *ins, jsbytecode *pc, MResumePoint::Mode mode);
     bool resumeAt(MInstruction *ins, jsbytecode *pc);
     bool resumeAfter(MInstruction *ins);
     bool maybeInsertResume();
 
-    void insertRecompileCheck();
-
     bool initParameters();
     void rewriteParameters();
     bool initScopeChain();
     bool pushConstant(const Value &v);
 
     // Add a guard which ensure that the set of type which goes through this
     // generated code correspond to the observed or infered (actual) type.
     bool pushTypeBarrier(MInstruction *ins, types::StackTypeSet *actual, types::StackTypeSet *observed);
--- a/js/src/ion/IonCaches.cpp
+++ b/js/src/ion/IonCaches.cpp
@@ -1481,16 +1481,18 @@ SetPropertyIC::update(JSContext *cx, siz
         RootedShape newShape(cx, obj->lastProperty());
         if (!cache.attachNativeAdding(cx, ion, obj, oldShape, newShape, shape))
             return false;
     }
 
     return true;
 }
 
+const size_t GetElementIC::MAX_FAILED_UPDATES = 16;
+
 bool
 GetElementIC::attachGetProp(JSContext *cx, IonScript *ion, HandleObject obj,
                             const Value &idval, HandlePropertyName name)
 {
     JS_ASSERT(index().reg().hasValue());
 
     RootedObject holder(cx);
     RootedShape shape(cx);
@@ -1720,20 +1722,26 @@ GetElementIC::update(JSContext *cx, size
                 attachedStub = true;
             }
         }
     }
 
     if (!GetElementOperation(cx, JSOp(*pc), &lval, idval, res))
         return false;
 
-    // If no new attach was done, and we've reached maximum number of stubs, then
-    // disable the cache.
-    if (!attachedStub && !cache.canAttachStub())
-        cache.disable();
+    // Disable cache when we reach max stubs or update failed too much.
+    if (!attachedStub) {
+        cache.incFailedUpdates();
+        if (cache.shouldDisable()) {
+            IonSpew(IonSpew_InlineCaches, "Disable inline cache");
+            cache.disable();
+        }
+    } else {
+        cache.resetFailedUpdates();
+    }
 
     types::TypeScript::Monitor(cx, script, pc, res);
     return true;
 }
 
 bool
 BindNameIC::attachGlobal(JSContext *cx, IonScript *ion, JSObject *scopeChain)
 {
--- a/js/src/ion/IonCaches.h
+++ b/js/src/ion/IonCaches.h
@@ -406,27 +406,33 @@ class SetPropertyIC : public IonCache
 };
 
 class GetElementIC : public IonCache
 {
   protected:
     Register object_;
     ConstantOrRegister index_;
     TypedOrValueRegister output_;
+
     bool monitoredResult_ : 1;
     bool hasDenseStub_ : 1;
 
+    size_t failedUpdates_;
+
+    static const size_t MAX_FAILED_UPDATES;
+
   public:
     GetElementIC(Register object, ConstantOrRegister index,
                  TypedOrValueRegister output, bool monitoredResult)
       : object_(object),
         index_(index),
         output_(output),
         monitoredResult_(monitoredResult),
-        hasDenseStub_(false)
+        hasDenseStub_(false),
+        failedUpdates_(0)
     {
     }
 
     CACHE_HEADER(GetElement)
 
     Register object() const {
         return object_;
     }
@@ -449,16 +455,27 @@ class GetElementIC : public IonCache
 
     bool attachGetProp(JSContext *cx, IonScript *ion, HandleObject obj, const Value &idval, HandlePropertyName name);
     bool attachDenseElement(JSContext *cx, IonScript *ion, JSObject *obj, const Value &idval);
     bool attachTypedArrayElement(JSContext *cx, IonScript *ion, JSObject *obj, const Value &idval);
 
     static bool
     update(JSContext *cx, size_t cacheIndex, HandleObject obj, HandleValue idval,
                 MutableHandleValue vp);
+
+    void incFailedUpdates() {
+        failedUpdates_++;
+    }
+    void resetFailedUpdates() {
+        failedUpdates_ = 0;
+    }
+    bool shouldDisable() const {
+        return !canAttachStub() ||
+               (stubCount_ == 0 && failedUpdates_ > MAX_FAILED_UPDATES);
+    }
 };
 
 class BindNameIC : public IonCache
 {
   protected:
     Register scopeChain_;
     PropertyName *name_;
     Register output_;
--- a/js/src/ion/IonMacroAssembler.cpp
+++ b/js/src/ion/IonMacroAssembler.cpp
@@ -650,38 +650,35 @@ void
 MacroAssembler::generateBailoutTail(Register scratch)
 {
     enterExitFrame();
 
     Label reflow;
     Label interpret;
     Label exception;
     Label osr;
-    Label recompile;
     Label boundscheck;
     Label overrecursed;
     Label invalidate;
 
     // The return value from Bailout is tagged as:
     // - 0x0: done (thunk to interpreter)
     // - 0x1: error (handle exception)
     // - 0x2: reflow args
     // - 0x3: reflow barrier
     // - 0x4: monitor types
-    // - 0x5: recompile to inline calls
-    // - 0x6: bounds check failure
-    // - 0x7: force invalidation
-    // - 0x8: overrecursed
-    // - 0x9: cached shape guard failure
+    // - 0x5: bounds check failure
+    // - 0x6: force invalidation
+    // - 0x7: overrecursed
+    // - 0x8: cached shape guard failure
 
     branch32(LessThan, ReturnReg, Imm32(BAILOUT_RETURN_FATAL_ERROR), &interpret);
     branch32(Equal, ReturnReg, Imm32(BAILOUT_RETURN_FATAL_ERROR), &exception);
 
-    branch32(LessThan, ReturnReg, Imm32(BAILOUT_RETURN_RECOMPILE_CHECK), &reflow);
-    branch32(Equal, ReturnReg, Imm32(BAILOUT_RETURN_RECOMPILE_CHECK), &recompile);
+    branch32(LessThan, ReturnReg, Imm32(BAILOUT_RETURN_BOUNDS_CHECK), &reflow);
 
     branch32(Equal, ReturnReg, Imm32(BAILOUT_RETURN_BOUNDS_CHECK), &boundscheck);
     branch32(Equal, ReturnReg, Imm32(BAILOUT_RETURN_OVERRECURSED), &overrecursed);
     branch32(Equal, ReturnReg, Imm32(BAILOUT_RETURN_SHAPE_GUARD), &invalidate);
 
     // Fall-through: cached shape guard failure.
     {
         setupUnalignedABICall(0, scratch);
@@ -706,26 +703,16 @@ MacroAssembler::generateBailoutTail(Regi
     {
         setupUnalignedABICall(0, scratch);
         callWithABI(JS_FUNC_TO_DATA_PTR(void *, BoundsCheckFailure));
 
         branchTest32(Zero, ReturnReg, ReturnReg, &exception);
         jump(&interpret);
     }
 
-    // Recompile to inline calls.
-    bind(&recompile);
-    {
-        setupUnalignedABICall(0, scratch);
-        callWithABI(JS_FUNC_TO_DATA_PTR(void *, RecompileForInlining));
-
-        branchTest32(Zero, ReturnReg, ReturnReg, &exception);
-        jump(&interpret);
-    }
-
     // Reflow types.
     bind(&reflow);
     {
         setupUnalignedABICall(1, scratch);
         passABIArg(ReturnReg);
         callWithABI(JS_FUNC_TO_DATA_PTR(void *, ReflowTypeInfo));
 
         branchTest32(Zero, ReturnReg, ReturnReg, &exception);
--- a/js/src/ion/IonTypes.h
+++ b/js/src/ion/IonTypes.h
@@ -32,19 +32,16 @@ enum BailoutKind
 
     // A bailout required to monitor a newly observed type in a type inference
     // barrier.
     Bailout_TypeBarrier,
 
     // A bailout required to monitor the result of a VM call.
     Bailout_Monitor,
 
-    // A bailout to trigger recompilation to inline calls when the script is hot.
-    Bailout_RecompileCheck,
-
     // A bailout triggered by a bounds-check failure.
     Bailout_BoundsCheck,
 
     // A shape guard based on TI information failed.
     Bailout_ShapeGuard,
 
     // A shape guard based on JM ICs failed.
     Bailout_CachedShapeGuard
--- a/js/src/ion/LOpcodes.h
+++ b/js/src/ion/LOpcodes.h
@@ -31,17 +31,16 @@
     _(NewStringObject)              \
     _(ParNew)                       \
     _(ParNewDenseArray)             \
     _(ParNewCallObject)             \
     _(ParBailout)                   \
     _(InitProp)                     \
     _(CheckOverRecursed)            \
     _(ParCheckOverRecursed)         \
-    _(RecompileCheck)               \
     _(DefVar)                       \
     _(DefFun)                       \
     _(CallKnown)                    \
     _(CallGeneric)                  \
     _(CallNative)                   \
     _(ApplyArgsGeneric)             \
     _(GetDynamicName)               \
     _(FilterArguments)              \
--- a/js/src/ion/MIR.h
+++ b/js/src/ion/MIR.h
@@ -3470,42 +3470,16 @@ class MParCheckInterrupt : public MUnary
         setMovable();
     }
 
     MDefinition *parSlice() const {
         return getOperand(0);
     }
 };
 
-// Check the script's use count and trigger recompilation to inline
-// calls when the script becomes hot.
-class MRecompileCheck : public MNullaryInstruction
-{
-    uint32_t minUses_;
-
-    MRecompileCheck(uint32_t minUses)
-      : minUses_(minUses)
-    {
-        setGuard();
-    }
-
-  public:
-    INSTRUCTION_HEADER(RecompileCheck)
-
-    uint32_t minUses() const {
-        return minUses_;
-    }
-    static MRecompileCheck *New(uint32_t minUses) {
-        return new MRecompileCheck(minUses);
-    }
-    AliasSet getAliasSet() const {
-        return AliasSet::None();
-    }
-};
-
 // Check whether we need to fire the interrupt handler.
 class MInterruptCheck : public MNullaryInstruction
 {
     MInterruptCheck() {
         setGuard();
     }
 
   public:
--- a/js/src/ion/MOpcodes.h
+++ b/js/src/ion/MOpcodes.h
@@ -22,17 +22,16 @@ namespace ion {
     _(PolyInlineDispatch)                                                   \
     _(Compare)                                                              \
     _(Phi)                                                                  \
     _(Beta)                                                                 \
     _(OsrValue)                                                             \
     _(OsrScopeChain)                                                        \
     _(ReturnFromCtor)                                                       \
     _(CheckOverRecursed)                                                    \
-    _(RecompileCheck)                                                       \
     _(DefVar)                                                               \
     _(DefFun)                                                               \
     _(CreateThis)                                                           \
     _(CreateThisWithProto)                                                  \
     _(CreateThisWithTemplate)                                               \
     _(PrepareCall)                                                          \
     _(PassArg)                                                              \
     _(Call)                                                                 \
--- a/js/src/ion/ParallelArrayAnalysis.cpp
+++ b/js/src/ion/ParallelArrayAnalysis.cpp
@@ -126,17 +126,16 @@ class ParallelArrayVisitor : public MIns
     CUSTOM_OP(Test)
     CUSTOM_OP(Compare)
     SAFE_OP(Phi)
     SAFE_OP(Beta)
     UNSAFE_OP(OsrValue)
     UNSAFE_OP(OsrScopeChain)
     UNSAFE_OP(ReturnFromCtor)
     CUSTOM_OP(CheckOverRecursed)
-    DROP_OP(RecompileCheck)
     UNSAFE_OP(DefVar)
     UNSAFE_OP(DefFun)
     UNSAFE_OP(CreateThis)
     UNSAFE_OP(CreateThisWithTemplate)
     UNSAFE_OP(CreateThisWithProto)
     SAFE_OP(PrepareCall)
     SAFE_OP(PassArg)
     CUSTOM_OP(Call)
--- a/js/src/ion/TypeOracle.cpp
+++ b/js/src/ion/TypeOracle.cpp
@@ -524,22 +524,16 @@ bool
 TypeInferenceOracle::arrayResultShouldHaveDoubleConversion(RawScript script, jsbytecode *pc)
 {
     types::StackTypeSet::DoubleConversion conversion =
         script->analysis()->pushedTypes(pc, 0)->convertDoubleElements(cx);
     return conversion == types::StackTypeSet::AlwaysConvertToDoubles;
 }
 
 bool
-TypeInferenceOracle::canInlineCalls()
-{
-    return script()->analysis()->hasFunctionCalls();
-}
-
-bool
 TypeInferenceOracle::propertyWriteCanSpecialize(RawScript script, jsbytecode *pc)
 {
     return !script->analysis()->getCode(pc).monitoredTypes;
 }
 
 bool
 TypeInferenceOracle::propertyWriteNeedsBarrier(RawScript script, jsbytecode *pc, RawId id)
 {
--- a/js/src/ion/TypeOracle.h
+++ b/js/src/ion/TypeOracle.h
@@ -139,19 +139,16 @@ class TypeOracle
         return true;
     }
     virtual bool elementWriteNeedsBarrier(RawScript script, jsbytecode *pc) {
         return true;
     }
     virtual MIRType elementWrite(RawScript script, jsbytecode *pc) {
         return MIRType_None;
     }
-    virtual bool canInlineCalls() {
-        return false;
-    }
 
     /* |pc| must be a |JSOP_CALL|. */
     virtual types::StackTypeSet *getCallTarget(RawScript caller, uint32_t argc, jsbytecode *pc) {
         // Same assertion as TypeInferenceOracle::getCallTarget.
         JS_ASSERT(js_CodeSpec[*pc].format & JOF_INVOKE && JSOp(*pc) != JSOP_EVAL);
         return NULL;
     }
     virtual types::StackTypeSet *getCallArg(RawScript script, uint32_t argc, uint32_t arg, jsbytecode *pc) {
@@ -269,17 +266,16 @@ class TypeInferenceOracle : public TypeO
     bool elementWriteHasExtraIndexedProperty(RawScript script, jsbytecode *pc);
     bool elementWriteIsPacked(RawScript script, jsbytecode *pc);
     bool arrayResultShouldHaveDoubleConversion(RawScript script, jsbytecode *pc);
     bool setElementHasWrittenHoles(RawScript script, jsbytecode *pc);
     bool propertyWriteCanSpecialize(RawScript script, jsbytecode *pc);
     bool propertyWriteNeedsBarrier(RawScript script, jsbytecode *pc, RawId id);
     bool elementWriteNeedsBarrier(RawScript script, jsbytecode *pc);
     MIRType elementWrite(RawScript script, jsbytecode *pc);
-    bool canInlineCalls();
     bool canInlineCall(HandleScript caller, jsbytecode *pc);
     types::TypeBarrier *callArgsBarrier(HandleScript caller, jsbytecode *pc);
     bool canEnterInlinedFunction(RawScript caller, jsbytecode *pc, RawFunction callee);
     types::StackTypeSet *aliasedVarBarrier(RawScript script, jsbytecode *pc, types::StackTypeSet **barrier);
 
     LazyArgumentsType isArgumentObject(types::StackTypeSet *obj);
     LazyArgumentsType propertyReadMagicArguments(RawScript script, jsbytecode *pc);
     LazyArgumentsType elementReadMagicArguments(RawScript script, jsbytecode *pc);
--- a/js/src/ion/VMFunctions.cpp
+++ b/js/src/ion/VMFunctions.cpp
@@ -488,18 +488,22 @@ GetIntrinsicValue(JSContext *cx, HandleP
 
 bool
 CreateThis(JSContext *cx, HandleObject callee, MutableHandleValue rval)
 {
     rval.set(MagicValue(JS_IS_CONSTRUCTING));
 
     if (callee->isFunction()) {
         JSFunction *fun = callee->toFunction();
-        if (fun->isInterpreted())
+        if (fun->isInterpreted()) {
+            JSScript *script = fun->getOrCreateScript(cx);
+            if (!script || !script->ensureHasTypes(cx))
+                return false;
             rval.set(ObjectValue(*CreateThisForFunction(cx, callee, false)));
+        }
     }
 
     return true;
 }
 
 void
 GetDynamicName(JSContext *cx, JSObject *scopeChain, JSString *str, Value *vp)
 {
--- a/js/src/ion/arm/CodeGenerator-arm.cpp
+++ b/js/src/ion/arm/CodeGenerator-arm.cpp
@@ -1551,36 +1551,16 @@ CodeGeneratorARM::visitImplicitThis(LImp
     // TODO: OOL stub path.
     if (!bailoutIf(Assembler::NotEqual, lir->snapshot()))
         return false;
 
     masm.moveValue(UndefinedValue(), out);
     return true;
 }
 
-bool
-CodeGeneratorARM::visitRecompileCheck(LRecompileCheck *lir)
-{
-    Register tmp = ToRegister(lir->tempInt());
-    size_t *addr = gen->info().script()->addressOfUseCount();
-
-    // Bump the script's use count. Note that it's safe to bake in this pointer
-    // since scripts are never nursery allocated and jitcode will be purged before
-    // doing a compacting GC.
-    masm.load32(AbsoluteAddress(addr), tmp);
-    masm.ma_add(Imm32(1), tmp);
-    masm.store32(tmp, AbsoluteAddress(addr));
-
-    // Bailout if the script is hot.
-    masm.ma_cmp(tmp, Imm32(lir->mir()->minUses()));
-    if (!bailoutIf(Assembler::AboveOrEqual, lir->snapshot()))
-        return false;
-    return true;
-}
-
 typedef bool (*InterruptCheckFn)(JSContext *);
 static const VMFunction InterruptCheckInfo = FunctionInfo<InterruptCheckFn>(InterruptCheck);
 
 bool
 CodeGeneratorARM::visitInterruptCheck(LInterruptCheck *lir)
 {
     OutOfLineCode *ool = oolCallVM(InterruptCheckInfo, lir, (ArgList()), StoreNothing());
     if (!ool)
--- a/js/src/ion/arm/CodeGenerator-arm.h
+++ b/js/src/ion/arm/CodeGenerator-arm.h
@@ -134,17 +134,16 @@ class CodeGeneratorARM : public CodeGene
     bool visitStoreSlotT(LStoreSlotT *load);
 
     bool visitLoadElementT(LLoadElementT *load);
 
     bool visitGuardShape(LGuardShape *guard);
     bool visitGuardClass(LGuardClass *guard);
     bool visitImplicitThis(LImplicitThis *lir);
 
-    bool visitRecompileCheck(LRecompileCheck *lir);
     bool visitInterruptCheck(LInterruptCheck *lir);
 
     bool generateInvalidateEpilogue();
 
     void postAsmJSCall(LAsmJSCall *lir) {}
 };
 
 typedef CodeGeneratorARM CodeGeneratorSpecific;
--- a/js/src/ion/arm/LIR-arm.h
+++ b/js/src/ion/arm/LIR-arm.h
@@ -273,32 +273,16 @@ class LGuardShape : public LInstructionH
     const MGuardShape *mir() const {
         return mir_->toGuardShape();
     }
     const LAllocation *tempInt() {
         return getTemp(0)->output();
     }
 };
 
-class LRecompileCheck : public LInstructionHelper<0, 0, 1>
-{
-  public:
-    LIR_HEADER(RecompileCheck);
-
-    LRecompileCheck(const LDefinition &temp) {
-        setTemp(0, temp);
-    }
-    const LAllocation *tempInt() {
-        return getTemp(0)->output();
-    }
-    const MRecompileCheck *mir() const {
-        return mir_->toRecompileCheck();
-    }
-};
-
 class LInterruptCheck : public LInstructionHelper<0, 0, 0>
 {
   public:
     LIR_HEADER(InterruptCheck);
 };
 
 class LMulI : public LBinaryMath<0>
 {
--- a/js/src/ion/arm/Lowering-arm.cpp
+++ b/js/src/ion/arm/Lowering-arm.cpp
@@ -312,23 +312,16 @@ LIRGeneratorARM::visitGuardShape(MGuardS
     if (!assignSnapshot(guard, ins->bailoutKind()))
         return false;
     if (!add(guard, ins))
         return false;
     return redefine(ins, ins->obj());
 }
 
 bool
-LIRGeneratorARM::visitRecompileCheck(MRecompileCheck *ins)
-{
-    LRecompileCheck *lir = new LRecompileCheck(temp(LDefinition::GENERAL));
-    return assignSnapshot(lir, Bailout_RecompileCheck) && add(lir, ins);
-}
-
-bool
 LIRGeneratorARM::visitStoreTypedArrayElement(MStoreTypedArrayElement *ins)
 {
     JS_ASSERT(ins->elements()->type() == MIRType_Elements);
     JS_ASSERT(ins->index()->type() == MIRType_Int32);
 
     if (ins->isFloatArray())
         JS_ASSERT(ins->value()->type() == MIRType_Double);
     else
--- a/js/src/ion/arm/Lowering-arm.h
+++ b/js/src/ion/arm/Lowering-arm.h
@@ -55,17 +55,16 @@ class LIRGeneratorARM : public LIRGenera
 
   public:
     bool visitConstant(MConstant *ins);
     bool visitBox(MBox *box);
     bool visitUnbox(MUnbox *unbox);
     bool visitReturn(MReturn *ret);
     bool lowerPhi(MPhi *phi);
     bool visitGuardShape(MGuardShape *ins);
-    bool visitRecompileCheck(MRecompileCheck *ins);
     bool visitStoreTypedArrayElement(MStoreTypedArrayElement *ins);
     bool visitInterruptCheck(MInterruptCheck *ins);
 };
 
 typedef LIRGeneratorARM LIRGeneratorSpecific;
 
 } // namespace ion
 } // namespace js
--- a/js/src/ion/shared/LIR-x86-shared.h
+++ b/js/src/ion/shared/LIR-x86-shared.h
@@ -183,26 +183,16 @@ class LGuardShape : public LInstructionH
     LGuardShape(const LAllocation &in) {
         setOperand(0, in);
     }
     const MGuardShape *mir() const {
         return mir_->toGuardShape();
     }
 };
 
-class LRecompileCheck : public LInstructionHelper<0, 0, 0>
-{
-  public:
-    LIR_HEADER(RecompileCheck)
-
-    const MRecompileCheck *mir() const {
-        return mir_->toRecompileCheck();
-    }
-};
-
 class LInterruptCheck : public LInstructionHelper<0, 0, 0>
 {
   public:
     LIR_HEADER(InterruptCheck)
 };
 
 class LMulI : public LBinaryMath<0, 1>
 {
--- a/js/src/ion/shared/Lowering-x86-shared.cpp
+++ b/js/src/ion/shared/Lowering-x86-shared.cpp
@@ -21,23 +21,16 @@ LIRGeneratorX86Shared::newLTableSwitch(c
 
 LTableSwitchV *
 LIRGeneratorX86Shared::newLTableSwitchV(MTableSwitch *tableswitch)
 {
     return new LTableSwitchV(temp(), tempFloat(), temp(), tableswitch);
 }
 
 bool
-LIRGeneratorX86Shared::visitRecompileCheck(MRecompileCheck *ins)
-{
-    LRecompileCheck *lir = new LRecompileCheck();
-    return assignSnapshot(lir, Bailout_RecompileCheck) && add(lir, ins);
-}
-
-bool
 LIRGeneratorX86Shared::visitInterruptCheck(MInterruptCheck *ins)
 {
     LInterruptCheck *lir = new LInterruptCheck();
     if (!add(lir, ins))
         return false;
     if (!assignSafepoint(lir, ins))
         return false;
     return true;
--- a/js/src/ion/shared/Lowering-x86-shared.h
+++ b/js/src/ion/shared/Lowering-x86-shared.h
@@ -19,17 +19,16 @@ class LIRGeneratorX86Shared : public LIR
     LIRGeneratorX86Shared(MIRGenerator *gen, MIRGraph &graph, LIRGraph &lirGraph)
       : LIRGeneratorShared(gen, graph, lirGraph)
     {}
 
     LTableSwitch *newLTableSwitch(const LAllocation &in, const LDefinition &inputCopy,
                                   MTableSwitch *ins);
     LTableSwitchV *newLTableSwitchV(MTableSwitch *ins);
 
-    bool visitRecompileCheck(MRecompileCheck *ins);
     bool visitInterruptCheck(MInterruptCheck *ins);
     bool visitGuardShape(MGuardShape *ins);
     bool visitPowHalf(MPowHalf *ins);
     bool visitConstant(MConstant *ins);
     bool visitAsmJSNeg(MAsmJSNeg *ins);
     bool visitAsmJSUDiv(MAsmJSUDiv *ins);
     bool visitAsmJSUMod(MAsmJSUMod *ins);
     bool lowerMulI(MMul *mul, MDefinition *lhs, MDefinition *rhs);
--- a/js/src/ion/x64/CodeGenerator-x64.cpp
+++ b/js/src/ion/x64/CodeGenerator-x64.cpp
@@ -280,33 +280,16 @@ CodeGeneratorX64::visitImplicitThis(LImp
     // TODO: OOL stub path.
     if (!bailoutIf(Assembler::NotEqual, lir->snapshot()))
         return false;
 
     masm.moveValue(UndefinedValue(), ToOutValue(lir));
     return true;
 }
 
-bool
-CodeGeneratorX64::visitRecompileCheck(LRecompileCheck *lir)
-{
-    // Bump the script's use count and bailout if the script is hot. Note that
-    // it's safe to bake in this pointer since scripts are never nursery
-    // allocated and jitcode will be purged before doing a compacting GC.
-    const uint32_t *useCount = gen->info().script()->addressOfUseCount();
-    masm.movq(ImmWord(useCount), ScratchReg);
-
-    Operand addr(ScratchReg, 0);
-    masm.addl(Imm32(1), addr);
-    masm.cmpl(addr, Imm32(lir->mir()->minUses()));
-    if (!bailoutIf(Assembler::AboveOrEqual, lir->snapshot()))
-        return false;
-    return true;
-}
-
 typedef bool (*InterruptCheckFn)(JSContext *);
 static const VMFunction InterruptCheckInfo = FunctionInfo<InterruptCheckFn>(InterruptCheck);
 
 bool
 CodeGeneratorX64::visitInterruptCheck(LInterruptCheck *lir)
 {
     OutOfLineCode *ool = oolCallVM(InterruptCheckInfo, lir, (ArgList()), StoreNothing());
     if (!ool)
--- a/js/src/ion/x64/CodeGenerator-x64.h
+++ b/js/src/ion/x64/CodeGenerator-x64.h
@@ -41,17 +41,16 @@ class CodeGeneratorX64 : public CodeGene
     bool visitOsrValue(LOsrValue *value);
     bool visitBox(LBox *box);
     bool visitUnbox(LUnbox *unbox);
     bool visitLoadSlotV(LLoadSlotV *ins);
     bool visitLoadSlotT(LLoadSlotT *load);
     bool visitStoreSlotT(LStoreSlotT *store);
     bool visitLoadElementT(LLoadElementT *load);
     bool visitImplicitThis(LImplicitThis *lir);
-    bool visitRecompileCheck(LRecompileCheck *lir);
     bool visitInterruptCheck(LInterruptCheck *lir);
     bool visitCompareB(LCompareB *lir);
     bool visitCompareBAndBranch(LCompareBAndBranch *lir);
     bool visitCompareV(LCompareV *lir);
     bool visitCompareVAndBranch(LCompareVAndBranch *lir);
     bool visitUInt32ToDouble(LUInt32ToDouble *lir);
     bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins);
     bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins);
--- a/js/src/ion/x86/CodeGenerator-x86.cpp
+++ b/js/src/ion/x86/CodeGenerator-x86.cpp
@@ -257,31 +257,16 @@ CodeGeneratorX86::visitImplicitThis(LImp
     // TODO: OOL stub path.
     if (!bailoutIf(Assembler::NotEqual, lir->snapshot()))
         return false;
 
     masm.moveValue(UndefinedValue(), out);
     return true;
 }
 
-bool
-CodeGeneratorX86::visitRecompileCheck(LRecompileCheck *lir)
-{
-    // Bump the script's use count and bailout if the script is hot. Note that
-    // it's safe to bake in this pointer since scripts are never nursery
-    // allocated and jitcode will be purged before doing a compacting GC.
-    // Without this assumption we'd need a temp register here.
-    Operand addr(gen->info().script()->addressOfUseCount());
-    masm.addl(Imm32(1), addr);
-    masm.cmpl(addr, Imm32(lir->mir()->minUses()));
-    if (!bailoutIf(Assembler::AboveOrEqual, lir->snapshot()))
-        return false;
-    return true;
-}
-
 typedef bool (*InterruptCheckFn)(JSContext *);
 static const VMFunction InterruptCheckInfo = FunctionInfo<InterruptCheckFn>(InterruptCheck);
 
 bool
 CodeGeneratorX86::visitInterruptCheck(LInterruptCheck *lir)
 {
     OutOfLineCode *ool = oolCallVM(InterruptCheckInfo, lir, (ArgList()), StoreNothing());
     if (!ool)
--- a/js/src/ion/x86/CodeGenerator-x86.h
+++ b/js/src/ion/x86/CodeGenerator-x86.h
@@ -40,17 +40,16 @@ class CodeGeneratorX86 : public CodeGene
     bool visitUnbox(LUnbox *unbox);
     bool visitValue(LValue *value);
     bool visitOsrValue(LOsrValue *value);
     bool visitLoadSlotV(LLoadSlotV *load);
     bool visitLoadSlotT(LLoadSlotT *load);
     bool visitStoreSlotT(LStoreSlotT *store);
     bool visitLoadElementT(LLoadElementT *load);
     bool visitImplicitThis(LImplicitThis *lir);
-    bool visitRecompileCheck(LRecompileCheck *lir);
     bool visitInterruptCheck(LInterruptCheck *lir);
     bool visitCompareB(LCompareB *lir);
     bool visitCompareBAndBranch(LCompareBAndBranch *lir);
     bool visitCompareV(LCompareV *lir);
     bool visitCompareVAndBranch(LCompareVAndBranch *lir);
     bool visitUInt32ToDouble(LUInt32ToDouble *lir);
     bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins);
     bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug849777.js
@@ -0,0 +1,7 @@
+//|jit-test| error: InternalError
+
+var LIMIT = 65535;
+for ( var i = 0, args = "" ; i < LIMIT; i++ ) {
+  args += String(i) + ( i+1 < LIMIT ? "," : "" );
+}
+var LENGTH = eval( "GetLength("+ args +")" );
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug833076.js
@@ -0,0 +1,6 @@
+
+eval("(function() { " + "\
+var Constr = function( ... property)  {};\
+Constr.prototype = 0.0;\
+var c = new Constr(  ) ;\
+" + " })();");
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug847412.js
@@ -0,0 +1,19 @@
+
+var gTestcases = new Array();
+var gTc = gTestcases.length;
+function TestCase( a) {
+  this.actual = a;
+  gTestcases[gTc++] = this;
+}
+function test() {
+  for ( gTc=0; gTc < gTestcases.length; gTc++ ) {
+	gTestcases[gTc].actual.toString()
+  }
+}
+function testOverwritingSparseHole() {
+  for (var i = 0; i < 50; i++)
+    new TestCase(eval("VAR1 = 0; VAR2 = -1; VAR1 %= VAR2; VAR1"));
+}
+testOverwritingSparseHole();
+test();
+this.toSource();
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug852174.js
@@ -0,0 +1,9 @@
+
+function eval()
+  isPrototypeOf[Iterator.length] 
+function DoWhile_3()
+  eval();
+DoWhile_3();
+function f()
+  DoWhile_3(f - 0);
+for (var i in f());
--- a/js/src/jit-test/tests/sunspider/check-crypto-md5.js
+++ b/js/src/jit-test/tests/sunspider/check-crypto-md5.js
@@ -278,15 +278,10 @@ And, Montague, come you this afternoon,\
 To know our further pleasure in this case,\n\
 To old Free-town, our common judgment-place.\n\
 Once more, on pain of death, all men depart."
 
 for (var i = 0; i <4; i++) {
     plainText += plainText;
 }
 
-// root checks performed during integer conversion operations can poison
-// crypto integers in this test.
-if (relaxRootChecks)
-  relaxRootChecks();
-
 var md5Output = hex_md5(plainText);
 assertEq(md5Output, "a831e91e0f70eddcb70dc61c6f82f6cd")
--- a/js/src/jit-test/tests/sunspider/check-crypto-sha1.js
+++ b/js/src/jit-test/tests/sunspider/check-crypto-sha1.js
@@ -216,15 +216,10 @@ Which, but their children's end, nought 
 Is now the two hours' traffic of our stage;\n\
 The which if you with patient ears attend,\n\
 What here shall miss, our toil shall strive to mend.";
 
 for (var i = 0; i <4; i++) {
     plainText += plainText;
 }
 
-// root checks performed during integer conversion operations can poison
-// crypto integers in this test.
-if (relaxRootChecks)
-  relaxRootChecks();
-
 var sha1Output = hex_sha1(plainText);
 assertEq(sha1Output, "2524d264def74cce2498bf112bedf00e6c0b796d")
--- a/js/src/jit-test/tests/v8-v5/check-crypto.js
+++ b/js/src/jit-test/tests/v8-v5/check-crypto.js
@@ -1,8 +1,12 @@
+// |jit-test| slow;
+// This test times out in rooting analyis builds, and so is marked slow so that
+// it's not run as part of the rooting analysis tests on tinderbox.
+
 /*
  * Copyright (c) 2003-2005  Tom Wu
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
  * "Software"), to deal in the Software without restriction, including
  * without limitation the rights to use, copy, modify, merge, publish,
@@ -1702,17 +1706,12 @@ function check_correctness(text, hash) {
   RSA.setPublic(nValue, eValue);
   RSA.setPrivateEx(nValue, eValue, dValue, pValue, qValue, dmp1Value, dmq1Value, coeffValue);
   var encrypted = RSA.encrypt(text);
   var decrypted = RSA.decrypt(encrypted);
   assertEq( encrypted, hash );
   assertEq( decrypted, text );
 }
 
-// Too much time is taken checking roots on each ToNumber when interpreting the
-// crypto kernel in this benchmark.
-if (relaxRootChecks)
-    relaxRootChecks();
-
 // All 'correct' hashes here come from v8's javascript shell built off of tag 2.3.4
 check_correctness("Hello! I am some text.", "142b19b40fee712ab9468be296447d38c7dfe81a7850f11ae6aa21e49396a4e90bd6ba4aa385105e15960a59f95447dfad89671da6e08ed42229939583753be84d07558abb4feee4d46a92fd31d962679a1a5f4bf0fb7af414b9a756e18df7e6d1e96971cc66769f3b27d61ad932f2211373e0de388dc040557d4c3c3fe74320");
 check_correctness("PLEASE ENCRYPT ME. I AM TEXT. I AM DIEING TO BE ENCRYPTED. OH WHY WONT YOU ENCRYPT ME!?", "490c1fae87d7046296e4b34b357912a72cb7c38c0da3198f1ac3aad3489662ce02663ec5ea1be58ae73a275f3096b16c491f3520ebf822df6c65cc95e28be1cc0a4454dfba3fdd402c3a9de0db2f308989bfc1a7fada0dd680db76d24b2d96bd6b7e7d7e7f962deb953038bae06092f7bb9bcb40bba4ec92e040df32f98e035e");
 check_correctness("x","46c1b7cf202171b1b588e9ecf250e768dcf3b300490e859d508f708e702ef799bc496b9fac7634d60a82644653c5fd25b808393b234567116b8890d5f119c7c74dae7c97c8e40ba78ca2dc3e3d78ce859a7fa3815f42c27d0607eafc3940896abb6019cc28b2ff875531ed581a6351728a8df0d607b7c2c26265bf3dddbe4f84");
--- a/js/src/jsapi-tests/testGCFinalizeCallback.cpp
+++ b/js/src/jsapi-tests/testGCFinalizeCallback.cpp
@@ -34,80 +34,80 @@ BEGIN_TEST(testGCFinalizeCallback)
     JS_GC(rt);
     CHECK(rt->gcIsFull);
     CHECK(checkSingleGroup());
     CHECK(checkFinalizeStatus());
     CHECK(checkFinalizeIsCompartmentGC(false));
 
     /* Full GC, incremental. */
     FinalizeCalls = 0;
-    js::PrepareForFullGC(rt);
-    js::IncrementalGC(rt, js::gcreason::API, 1000000);
+    JS::PrepareForFullGC(rt);
+    JS::IncrementalGC(rt, JS::gcreason::API, 1000000);
     CHECK(rt->gcIncrementalState == js::gc::NO_INCREMENTAL);
     CHECK(rt->gcIsFull);
     CHECK(checkMultipleGroups());
     CHECK(checkFinalizeStatus());
     CHECK(checkFinalizeIsCompartmentGC(false));
 
     JS::RootedObject global1(cx, createGlobal());
     JS::RootedObject global2(cx, createGlobal());
     JS::RootedObject global3(cx, createGlobal());
     CHECK(global1);
     CHECK(global2);
     CHECK(global3);
 
     /* Compartment GC, non-incremental, single compartment. */
     FinalizeCalls = 0;
-    js::PrepareZoneForGC(global1->zone());
-    js::GCForReason(rt, js::gcreason::API);
+    JS::PrepareZoneForGC(global1->zone());
+    JS::GCForReason(rt, JS::gcreason::API);
     CHECK(!rt->gcIsFull);
     CHECK(checkSingleGroup());
     CHECK(checkFinalizeStatus());
     CHECK(checkFinalizeIsCompartmentGC(true));
 
     /* Compartment GC, non-incremental, multiple compartments. */
     FinalizeCalls = 0;
-    js::PrepareZoneForGC(global1->zone());
-    js::PrepareZoneForGC(global2->zone());
-    js::PrepareZoneForGC(global3->zone());
-    js::GCForReason(rt, js::gcreason::API);
+    JS::PrepareZoneForGC(global1->zone());
+    JS::PrepareZoneForGC(global2->zone());
+    JS::PrepareZoneForGC(global3->zone());
+    JS::GCForReason(rt, JS::gcreason::API);
     CHECK(!rt->gcIsFull);
     CHECK(checkSingleGroup());
     CHECK(checkFinalizeStatus());
     CHECK(checkFinalizeIsCompartmentGC(true));
 
     /* Compartment GC, incremental, single compartment. */
     FinalizeCalls = 0;
-    js::PrepareZoneForGC(global1->zone());
-    js::IncrementalGC(rt, js::gcreason::API, 1000000);
+    JS::PrepareZoneForGC(global1->zone());
+    JS::IncrementalGC(rt, JS::gcreason::API, 1000000);
     CHECK(rt->gcIncrementalState == js::gc::NO_INCREMENTAL);
     CHECK(!rt->gcIsFull);
     CHECK(checkSingleGroup());
     CHECK(checkFinalizeStatus());
     CHECK(checkFinalizeIsCompartmentGC(true));
 
     /* Compartment GC, incremental, multiple compartments. */
     FinalizeCalls = 0;
-    js::PrepareZoneForGC(global1->zone());
-    js::PrepareZoneForGC(global2->zone());
-    js::PrepareZoneForGC(global3->zone());
-    js::IncrementalGC(rt, js::gcreason::API, 1000000);
+    JS::PrepareZoneForGC(global1->zone());
+    JS::PrepareZoneForGC(global2->zone());
+    JS::PrepareZoneForGC(global3->zone());
+    JS::IncrementalGC(rt, JS::gcreason::API, 1000000);
     CHECK(rt->gcIncrementalState == js::gc::NO_INCREMENTAL);
     CHECK(!rt->gcIsFull);
     CHECK(checkMultipleGroups());
     CHECK(checkFinalizeStatus());
     CHECK(checkFinalizeIsCompartmentGC(true));
 
 #ifdef JS_GC_ZEAL
 
     /* Full GC with reset due to new compartment, becoming compartment GC. */
 
     FinalizeCalls = 0;
     JS_SetGCZeal(cx, 9, 1000000);
-    js::PrepareForFullGC(rt);
+    JS::PrepareForFullGC(rt);
     js::GCDebugSlice(rt, true, 1);
     CHECK(rt->gcIncrementalState == js::gc::MARK);
     CHECK(rt->gcIsFull);
 
     JS::RootedObject global4(cx, createGlobal());
     js::GCDebugSlice(rt, true, 1);
     CHECK(rt->gcIncrementalState == js::gc::NO_INCREMENTAL);
     CHECK(!rt->gcIsFull);
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -666,35 +666,25 @@ static JSBool js_NewRuntimeWasCalled = J
 mozilla::ThreadLocal<PerThreadData *> js::TlsPerThreadData;
 
 #ifdef DEBUG
 JS_FRIEND_API(bool)
 JS::isGCEnabled()
 {
     return !TlsPerThreadData.get()->suppressGC;
 }
-
-JS_FRIEND_API(bool)
-JS::NeedRelaxedRootChecks()
-{
-    return TlsPerThreadData.get()->gcRelaxRootChecks;
-}
 #else
 JS_FRIEND_API(bool) JS::isGCEnabled() { return true; }
-JS_FRIEND_API(bool) JS::NeedRelaxedRootChecks() { return false; }
 #endif
 
 static const JSSecurityCallbacks NullSecurityCallbacks = { };
 
 PerThreadData::PerThreadData(JSRuntime *runtime)
   : PerThreadDataFriendFields(),
     runtime_(runtime),
-#ifdef DEBUG
-    gcRelaxRootChecks(false),
-#endif
     ionTop(NULL),
     ionJSContext(NULL),
     ionStackLimit(0),
     ionActivation(NULL),
     asmJSActivationStack_(NULL),
 # ifdef JS_THREADSAFE
     asmJSActivationStackLock_(NULL),
 # endif
@@ -780,17 +770,17 @@ JSRuntime::JSRuntime(JSUseHelperThreads 
     gcDynamicMarkSlice(false),
     gcShouldCleanUpEverything(false),
     gcGrayBitsValid(false),
     gcIsNeeded(0),
     gcStats(thisFromCtor()),
     gcNumber(0),
     gcStartNumber(0),
     gcIsFull(false),
-    gcTriggerReason(gcreason::NO_REASON),
+    gcTriggerReason(JS::gcreason::NO_REASON),
     gcStrictCompartmentChecking(false),
     gcDisableStrictProxyCheckingCount(0),
     gcIncrementalState(gc::NO_INCREMENTAL),
     gcLastMarkSlice(false),
     gcSweepOnBackgroundThread(false),
     gcFoundBlackGrayEdges(false),
     gcSweepingZones(NULL),
     gcZoneGroupIndex(0),
@@ -2830,18 +2820,18 @@ JS_IsGCMarkingTracer(JSTracer *trc)
 {
     return IS_GC_MARKING_TRACER(trc);
 }
 
 JS_PUBLIC_API(void)
 JS_GC(JSRuntime *rt)
 {
     AssertHeapIsIdle(rt);
-    PrepareForFullGC(rt);
-    GC(rt, GC_NORMAL, gcreason::API);
+    JS::PrepareForFullGC(rt);
+    GC(rt, GC_NORMAL, JS::gcreason::API);
 }
 
 JS_PUBLIC_API(void)
 JS_MaybeGC(JSContext *cx)
 {
     MaybeGC(cx);
 }
 
@@ -3301,37 +3291,37 @@ class AutoHoldZone
     }
 
   private:
     bool *holdp;
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 JS_PUBLIC_API(JSObject *)
-JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals, ZoneSpecifier zoneSpec)
+JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals, JS::ZoneSpecifier zoneSpec)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
 
     JSRuntime *rt = cx->runtime;
 
     Zone *zone;
-    if (zoneSpec == SystemZone)
+    if (zoneSpec == JS::SystemZone)
         zone = rt->systemZone;
-    else if (zoneSpec == FreshZone)
+    else if (zoneSpec == JS::FreshZone)
         zone = NULL;
     else
         zone = ((JSObject *)zoneSpec)->zone();
 
     JSCompartment *compartment = NewCompartment(cx, zone, principals);
     if (!compartment)
         return NULL;
 
-    if (zoneSpec == SystemZone) {
+    if (zoneSpec == JS::SystemZone) {
         rt->systemZone = compartment->zone();
         rt->systemZone->isSystem = true;
     }
 
     AutoHoldZone hold(compartment->zone());
 
     JSCompartment *saved = cx->compartment;
     cx->setCompartment(compartment);
@@ -6243,17 +6233,17 @@ JS_Stringify(JSContext *cx, jsval *vp, J
 
 JS_PUBLIC_API(JSBool)
 JS_ParseJSON(JSContext *cx, const jschar *chars, uint32_t len, jsval *vp)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
 
     RootedValue reviver(cx, NullValue()), value(cx);
-    if (!ParseJSONWithReviver(cx, StableCharPtr(chars, len), len, reviver, &value))
+    if (!ParseJSONWithReviver(cx, JS::StableCharPtr(chars, len), len, reviver, &value))
         return false;
 
     *vp = value;
     return true;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_ParseJSONWithReviver(JSContext *cx, const jschar *chars, uint32_t len, jsval reviverArg, jsval *vp)
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1646,82 +1646,82 @@ ToInt64Slow(JSContext *cx, const JS::Val
 /* DO NOT CALL THIS. Use JS::ToUint64. */
 extern JS_PUBLIC_API(bool)
 ToUint64Slow(JSContext *cx, const JS::Value &v, uint64_t *out);
 } /* namespace js */
 
 namespace JS {
 
 JS_ALWAYS_INLINE bool
-ToUint16(JSContext *cx, const js::Value &v, uint16_t *out)
+ToUint16(JSContext *cx, const JS::Value &v, uint16_t *out)
 {
     AssertArgumentsAreSane(cx, v);
     {
         js::SkipRoot skip(cx, &v);
         js::MaybeCheckStackRoots(cx);
     }
 
     if (v.isInt32()) {
         *out = uint16_t(v.toInt32());
         return true;
     }
     return js::ToUint16Slow(cx, v, out);
 }
 
 JS_ALWAYS_INLINE bool
-ToInt32(JSContext *cx, const js::Value &v, int32_t *out)
+ToInt32(JSContext *cx, const JS::Value &v, int32_t *out)
 {
     AssertArgumentsAreSane(cx, v);
     {
         js::SkipRoot root(cx, &v);
         js::MaybeCheckStackRoots(cx);
     }
 
     if (v.isInt32()) {
         *out = v.toInt32();
         return true;
     }
     return js::ToInt32Slow(cx, v, out);
 }
 
 JS_ALWAYS_INLINE bool
-ToUint32(JSContext *cx, const js::Value &v, uint32_t *out)
+ToUint32(JSContext *cx, const JS::Value &v, uint32_t *out)
 {
     AssertArgumentsAreSane(cx, v);
     {
         js::SkipRoot root(cx, &v);
         js::MaybeCheckStackRoots(cx);
     }
 
     if (v.isInt32()) {
         *out = uint32_t(v.toInt32());
         return true;
     }
     return js::ToUint32Slow(cx, v, out);
 }
 
 JS_ALWAYS_INLINE bool
-ToInt64(JSContext *cx, const js::Value &v, int64_t *out)
+ToInt64(JSContext *cx, const JS::Value &v, int64_t *out)
 {
     AssertArgumentsAreSane(cx, v);
     {
         js::SkipRoot skip(cx, &v);
         js::MaybeCheckStackRoots(cx);
     }
 
     if (v.isInt32()) {
         *out = int64_t(v.toInt32());
         return true;
     }
 
     return js::ToInt64Slow(cx, v, out);
 }
 
 JS_ALWAYS_INLINE bool
-ToUint64(JSContext *cx, const js::Value &v, uint64_t *out)
+ToUint64(JSContext *cx, const JS::Value &v, uint64_t *out)
 {
     AssertArgumentsAreSane(cx, v);
     {
         js::SkipRoot skip(cx, &v);
         js::MaybeCheckStackRoots(cx);
     }
 
     if (v.isInt32()) {
@@ -1841,17 +1841,17 @@ IsPoisonedId(jsid iden)
 } /* namespace JS */
 
 namespace js {
 
 template <> struct RootMethods<jsid>
 {
     static jsid initial() { return JSID_VOID; }
     static ThingRootKind kind() { return THING_ROOT_ID; }
-    static bool poisoned(jsid id) { return IsPoisonedId(id); }
+    static bool poisoned(jsid id) { return JS::IsPoisonedId(id); }
 };
 
 } /* namespace js */
 
 class JSAutoRequest
 {
   public:
     JSAutoRequest(JSContext *cx
@@ -4948,9 +4948,90 @@ JS_EncodeInterpretedFunction(JSContext *
 extern JS_PUBLIC_API(JSScript *)
 JS_DecodeScript(JSContext *cx, const void *data, uint32_t length,
                 JSPrincipals *principals, JSPrincipals *originPrincipals);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_DecodeInterpretedFunction(JSContext *cx, const void *data, uint32_t length,
                              JSPrincipals *principals, JSPrincipals *originPrincipals);
 
+namespace js {
+
+/*
+ * Import some JS:: names into the js namespace so we can make unqualified
+ * references to them.
+ */
+
+using JS::Value;
+using JS::IsPoisonedValue;
+using JS::NullValue;
+using JS::UndefinedValue;
+using JS::Int32Value;
+using JS::DoubleValue;
+using JS::StringValue;
+using JS::BooleanValue;
+using JS::ObjectValue;
+using JS::MagicValue;
+using JS::NumberValue;
+using JS::ObjectOrNullValue;
+using JS::PrivateValue;
+using JS::PrivateUint32Value;
+
+using JS::IsPoisonedPtr;
+using JS::IsPoisonedId;
+
+using JS::StableCharPtr;
+using JS::TwoByteChars;
+using JS::Latin1CharsZ;
+
+using JS::AutoIdVector;
+using JS::AutoValueVector;
+using JS::AutoScriptVector;
+using JS::AutoIdArray;
+
+using JS::AutoGCRooter;
+using JS::AutoValueRooter;
+using JS::AutoObjectRooter;
+using JS::AutoArrayRooter;
+using JS::AutoVectorRooter;
+using JS::AutoHashMapRooter;
+using JS::AutoHashSetRooter;
+
+using JS::CallArgs;
+using JS::IsAcceptableThis;
+using JS::NativeImpl;
+using JS::CallReceiver;
+using JS::CompileOptions;
+using JS::CallNonGenericMethod;
+
+using JS::Rooted;
+using JS::RootedObject;
+using JS::RootedModule;
+using JS::RootedFunction;
+using JS::RootedScript;
+using JS::RootedString;
+using JS::RootedId;
+using JS::RootedValue;
+
+using JS::Handle;
+using JS::HandleObject;
+using JS::HandleModule;
+using JS::HandleFunction;
+using JS::HandleScript;
+using JS::HandleString;
+using JS::HandleId;
+using JS::HandleValue;
+
+using JS::MutableHandle;
+using JS::MutableHandleObject;
+using JS::MutableHandleFunction;
+using JS::MutableHandleScript;
+using JS::MutableHandleString;
+using JS::MutableHandleId;
+using JS::MutableHandleValue;
+
+using JS::NullPtr;  /* To be removed by bug 781070. */
+
+using JS::Zone;
+
+}  /* namespace js */
+
 #endif /* jsapi_h___ */
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -2674,17 +2674,17 @@ NewArray(JSContext *cx, uint32_t length,
             if (allocateCapacity && !EnsureNewArrayElements(cx, obj, length))
                 return NULL;
             return obj;
         }
     }
 
     RootedObject proto(cx, protoArg);
     if (protoArg)
-        PoisonPtr(&protoArg);
+        JS::PoisonPtr(&protoArg);
 
     if (!proto && !FindProto(cx, &ArrayClass, &proto))
         return NULL;
 
     RootedTypeObject type(cx, proto->getNewType(cx, &ArrayClass));
     if (!type)
         return NULL;
 
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -105,17 +105,17 @@ js::TraceCycleDetectionSet(JSTracer *trc
         JSObject *prior = e.front();
         MarkObjectRoot(trc, const_cast<JSObject **>(&e.front()), "cycle detector table entry");
         if (prior != e.front())
             e.rekeyFront(e.front());
     }
 }
 
 void
-JSRuntime::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf, RuntimeSizes *rtSizes)
+JSRuntime::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf, JS::RuntimeSizes *rtSizes)
 {
     rtSizes->object = mallocSizeOf(this);
 
     rtSizes->atomsTable = atoms.sizeOfExcludingThis(mallocSizeOf);
 
     rtSizes->contexts = 0;
     for (ContextIter acx(this); !acx.done(); acx.next())
         rtSizes->contexts += acx->sizeOfIncludingThis(mallocSizeOf);
@@ -421,22 +421,22 @@ js::DestroyContext(JSContext *cx, Destro
         /* Clear debugging state to remove GC roots. */
         for (CompartmentsIter c(rt); !c.done(); c.next())
             c->clearTraps(rt->defaultFreeOp());
         JS_ClearAllWatchPoints(cx);
 
         /* Clear the statics table to remove GC roots. */
         rt->staticStrings.finish();
 
-        PrepareForFullGC(rt);
-        GC(rt, GC_NORMAL, gcreason::LAST_CONTEXT);
+        JS::PrepareForFullGC(rt);
+        GC(rt, GC_NORMAL, JS::gcreason::LAST_CONTEXT);
     } else if (mode == DCM_FORCE_GC) {
         JS_ASSERT(!rt->isHeapBusy());
-        PrepareForFullGC(rt);
-        GC(rt, GC_NORMAL, gcreason::DESTROY_CONTEXT);
+        JS::PrepareForFullGC(rt);
+        GC(rt, GC_NORMAL, JS::gcreason::DESTROY_CONTEXT);
     }
     js_delete(cx);
 }
 
 bool
 AutoResolving::alreadyStartedSlow() const
 {
     JS_ASSERT(link);
@@ -1367,17 +1367,17 @@ JSRuntime::updateMallocCounter(JS::Zone 
         onTooMuchMalloc();
     else if (zone)
         zone->updateMallocCounter(nbytes);
 }
 
 JS_FRIEND_API(void)
 JSRuntime::onTooMuchMalloc()
 {
-    TriggerGC(this, gcreason::TOO_MUCH_MALLOC);
+    TriggerGC(this, JS::gcreason::TOO_MUCH_MALLOC);
 }
 
 JS_FRIEND_API(void *)
 JSRuntime::onOutOfMemory(void *p, size_t nbytes)
 {
     return onOutOfMemory(p, nbytes, NULL);
 }
 
@@ -1386,17 +1386,17 @@ JSRuntime::onOutOfMemory(void *p, size_t
 {
     if (isHeapBusy())
         return NULL;
 
     /*
      * Retry when we are done with the background sweeping and have stopped
      * all the allocations and released the empty GC chunks.
      */
-    ShrinkGCBuffers(this);
+    JS::ShrinkGCBuffers(this);
     gcHelperThread.waitBackgroundSweepOrAllocEnd();
     if (!p)
         p = js_malloc(nbytes);
     else if (p == reinterpret_cast<void *>(1))
         p = js_calloc(nbytes);
     else
       p = js_realloc(p, nbytes);
     if (p)
@@ -1520,23 +1520,23 @@ JSContext::mark(JSTracer *trc)
 
     TraceCycleDetectionSet(trc, cycleDetectorSet);
 
     MarkValueRoot(trc, &iterValue, "iterValue");
 }
 
 #if defined JS_THREADSAFE && defined DEBUG
 
-AutoCheckRequestDepth::AutoCheckRequestDepth(JSContext *cx)
+JS::AutoCheckRequestDepth::AutoCheckRequestDepth(JSContext *cx)
     : cx(cx)
 {
     JS_ASSERT(cx->runtime->requestDepth || cx->runtime->isHeapBusy());
     cx->runtime->assertValidThread();
     cx->runtime->checkRequestDepth++;
 }
 
-AutoCheckRequestDepth::~AutoCheckRequestDepth()
+JS::AutoCheckRequestDepth::~AutoCheckRequestDepth()
 {
     JS_ASSERT(cx->runtime->checkRequestDepth != 0);
     cx->runtime->checkRequestDepth--;
 }
 
 #endif
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -459,18 +459,16 @@ class PerThreadData : public js::PerThre
 #ifdef DEBUG
     struct SavedGCRoot {
         void *thing;
         JSGCTraceKind kind;
 
         SavedGCRoot(void *thing, JSGCTraceKind kind) : thing(thing), kind(kind) {}
     };
     js::Vector<SavedGCRoot, 0, js::SystemAllocPolicy> gcSavedRoots;
-
-    bool                gcRelaxRootChecks;
 #endif
 
     /*
      * If Ion code is on the stack, and has called into C++, this will be
      * aligned to an Ion exit frame.
      */
     uint8_t             *ionTop;
     JSContext           *ionJSContext;
@@ -891,17 +889,17 @@ struct JSRuntime : js::RuntimeFriendFiel
 
     /* Whether the currently running GC can finish in multiple slices. */
     int                 gcIsIncremental;
 
     /* Whether all compartments are being collected in first GC slice. */
     bool                gcIsFull;
 
     /* The reason that an interrupt-triggered GC should be called. */
-    js::gcreason::Reason gcTriggerReason;
+    JS::gcreason::Reason gcTriggerReason;
 
     /*
      * If this is true, all marked objects must belong to a compartment being
      * GCed. This is used to look for compartment bugs.
      */
     bool                gcStrictCompartmentChecking;
 
     /*
@@ -1057,17 +1055,17 @@ struct JSRuntime : js::RuntimeFriendFiel
     int gcZeal() { return 0; }
     bool needZealousGC() { return false; }
 #endif
 
     bool                gcValidate;
     bool                gcFullCompartmentChecks;
 
     JSGCCallback        gcCallback;
-    js::GCSliceCallback gcSliceCallback;
+    JS::GCSliceCallback gcSliceCallback;
     JSFinalizeCallback  gcFinalizeCallback;
 
     js::AnalysisPurgeCallback analysisPurgeCallback;
     uint64_t            analysisPurgeTriggerBytes;
 
   private:
     /*
      * Malloc counter to measure memory pressure for GC scheduling. It runs
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -803,17 +803,17 @@ JSCompartment::sweepBreakpoints(FreeOp *
                     bp->destroy(fop);
             }
         }
     }
 }
 
 void
 JSCompartment::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf, size_t *compartmentObject,
-                                   TypeInferenceSizes *tiSizes, size_t *shapesCompartmentTables,
+                                   JS::TypeInferenceSizes *tiSizes, size_t *shapesCompartmentTables,
                                    size_t *crossCompartmentWrappersArg, size_t *regexpCompartment,
                                    size_t *debuggeesSet)
 {
     *compartmentObject = mallocSizeOf(this);
     sizeOfTypeInferenceData(tiSizes, mallocSizeOf);
     *shapesCompartmentTables = baseShapes.sizeOfExcludingThis(mallocSizeOf)
                              + initialShapes.sizeOfExcludingThis(mallocSizeOf)
                              + newTypeObjects.sizeOfExcludingThis(mallocSizeOf)
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -388,17 +388,17 @@ class js::AutoDebugModeGC
     explicit AutoDebugModeGC(JSRuntime *rt) : rt(rt), needGC(false) {}
 
     ~AutoDebugModeGC() {
         // Under some circumstances (say, in the midst of an animation),
         // the garbage collector may try to retain JIT code and analyses.
         // The DEBUG_MODE_GC reason forces the collector to always throw
         // everything away, as required for debug mode transitions.
         if (needGC)
-            GC(rt, GC_NORMAL, gcreason::DEBUG_MODE_GC);
+            GC(rt, GC_NORMAL, JS::gcreason::DEBUG_MODE_GC);
     }
 
     void scheduleGC(Zone *zone) {
         JS_ASSERT(!rt->isHeapBusy());
         PrepareZoneForGC(zone);
         needGC = true;
     }
 };
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -90,17 +90,17 @@ js::ScriptDebugPrologue(JSContext *cx, A
                                    true, 0, cx->runtime->debugHooks.executeHookData));
     } else {
         if (JSInterpreterHook hook = cx->runtime->debugHooks.callHook)
             frame.setHookData(hook(cx, Jsvalify(frame), IsTopFrameConstructing(cx, frame),
                                    true, 0, cx->runtime->debugHooks.callHookData));
     }
 
     RootedValue rval(cx);
-    JSTrapStatus status = Debugger::onEnterFrame(cx, &rval);
+    JSTrapStatus status = Debugger::onEnterFrame(cx, frame, &rval);
     switch (status) {
       case JSTRAP_CONTINUE:
         break;
       case JSTRAP_THROW:
         cx->setPendingException(rval);
         break;
       case JSTRAP_ERROR:
         cx->clearPendingException();
@@ -125,17 +125,17 @@ js::ScriptDebugEpilogue(JSContext *cx, A
             if (JSInterpreterHook hook = cx->runtime->debugHooks.executeHook)
                 hook(cx, Jsvalify(frame), IsTopFrameConstructing(cx, frame), false, &ok, hookData);
         } else {
             if (JSInterpreterHook hook = cx->runtime->debugHooks.callHook)
                 hook(cx, Jsvalify(frame), IsTopFrameConstructing(cx, frame), false, &ok, hookData);
         }
     }
 
-    return Debugger::onLeaveFrame(cx, ok);
+    return Debugger::onLeaveFrame(cx, frame, ok);
 }
 
 JSTrapStatus
 js::DebugExceptionUnwind(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc)
 {
     JS_ASSERT(cx->compartment->debugMode());
 
     if (!cx->runtime->debugHooks.throwHook && cx->compartment->getDebuggees().empty())
@@ -1027,17 +1027,17 @@ js_CallContextDebugHandler(JSContext *cx
         return JS_FALSE;
       case JSTRAP_RETURN:
       case JSTRAP_CONTINUE:
       default:
         return JS_TRUE;
     }
 }
 
-JS_PUBLIC_API(StackDescription *)
+JS_PUBLIC_API(JS::StackDescription *)
 JS::DescribeStack(JSContext *cx, unsigned maxFrames)
 {
     Vector<FrameDescription> frames(cx);
 
     for (ScriptFrameIter i(cx); !i.done(); ++i) {
         if (i.script()->selfHosted)
             continue;
         FrameDescription desc;
@@ -1045,27 +1045,27 @@ JS::DescribeStack(JSContext *cx, unsigne
         desc.lineno = PCToLineNumber(i.script(), i.pc());
         desc.fun = i.maybeCallee();
         if (!frames.append(desc))
             return NULL;
         if (frames.length() == maxFrames)
             break;
     }
 
-    StackDescription *desc = js_new<StackDescription>();
+    JS::StackDescription *desc = js_new<JS::StackDescription>();
     if (!desc)
         return NULL;
 
     desc->nframes = frames.length();
     desc->frames = frames.extractRawBuffer();
     return desc;
 }
 
 JS_PUBLIC_API(void)
-JS::FreeStackDescription(JSContext *cx, StackDescription *desc)
+JS::FreeStackDescription(JSContext *cx, JS::StackDescription *desc)
 {
     js_delete(desc->frames);
     js_delete(desc);
 }
 
 class AutoPropertyDescArray
 {
     JSContext *cx_;
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -141,17 +141,17 @@ JS::PrepareForFullGC(JSRuntime *rt)
 {
     for (ZonesIter zone(rt); !zone.done(); zone.next())
         zone->scheduleGC();
 }
 
 JS_FRIEND_API(void)
 JS::PrepareForIncrementalGC(JSRuntime *rt)
 {
-    if (!IsIncrementalGCInProgress(rt))
+    if (!JS::IsIncrementalGCInProgress(rt))
         return;
 
     for (ZonesIter zone(rt); !zone.done(); zone.next()) {
         if (zone->wasGCStarted())
             PrepareZoneForGC(zone);
     }
 }
 
@@ -778,20 +778,20 @@ js::SetActivityCallback(JSRuntime *rt, A
 }
 
 JS_FRIEND_API(bool)
 js::IsContextRunningJS(JSContext *cx)
 {
     return !cx->stack.empty();
 }
 
-JS_FRIEND_API(GCSliceCallback)
+JS_FRIEND_API(JS::GCSliceCallback)
 JS::SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback)
 {
-    GCSliceCallback old = rt->gcSliceCallback;
+    JS::GCSliceCallback old = rt->gcSliceCallback;
     rt->gcSliceCallback = callback;
     return old;
 }
 
 JS_FRIEND_API(bool)
 JS::WasIncrementalGC(JSRuntime *rt)
 {
     return rt->gcIsIncremental;
@@ -831,18 +831,18 @@ JS::NotifyDidPaint(JSRuntime *rt)
     }
 
     if (rt->gcZeal() == gc::ZealFrameGCValue) {
         PrepareForFullGC(rt);
         GCSlice(rt, GC_NORMAL, gcreason::REFRESH_FRAME);
         return;
     }
 
-    if (IsIncrementalGCInProgress(rt) && !rt->gcInterFrameGC) {
-        PrepareForIncrementalGC(rt);
+    if (JS::IsIncrementalGCInProgress(rt) && !rt->gcInterFrameGC) {
+        JS::PrepareForIncrementalGC(rt);
         GCSlice(rt, GC_NORMAL, gcreason::REFRESH_FRAME);
     }
 
     rt->gcInterFrameGC = false;
 }
 
 JS_FRIEND_API(bool)
 JS::IsIncrementalGCEnabled(JSRuntime *rt)
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -787,17 +787,17 @@ Chunk::allocateArena(Zone *zone, AllocKi
     aheader->init(zone, thingKind);
     if (JS_UNLIKELY(!hasAvailableArenas()))
         removeFromAvailableList();
 
     Probes::resizeHeap(zone, rt->gcBytes, rt->gcBytes + ArenaSize);
     rt->gcBytes += ArenaSize;
     zone->gcBytes += ArenaSize;
     if (zone->gcBytes >= zone->gcTriggerBytes)
-        TriggerZoneGC(zone, gcreason::ALLOC_TRIGGER);
+        TriggerZoneGC(zone, JS::gcreason::ALLOC_TRIGGER);
 
     return aheader;
 }
 
 inline void
 Chunk::addArenaToFreeList(JSRuntime *rt, ArenaHeader *aheader)
 {
     JS_ASSERT(!aheader->allocated());
@@ -1496,17 +1496,17 @@ RunLastDitchGC(JSContext *cx, JS::Zone *
     JS_ASSERT(!InParallelSection());
 
     PrepareZoneForGC(zone);
 
     JSRuntime *rt = cx->runtime;
 
     /* The last ditch GC preserves all atoms. */
     AutoKeepAtoms keep(rt);
-    GC(rt, GC_NORMAL, gcreason::LAST_DITCH);
+    GC(rt, GC_NORMAL, JS::gcreason::LAST_DITCH);
 
     /*
      * The JSGC_END callback can legitimately allocate new GC
      * things and populate the free list. If that happens, just
      * return that list head.
      */
     size_t thingSize = Arena::thingSize(thingKind);
     if (void *thing = zone->allocator.arenas.allocateFromFreeList(thingKind, thingSize))