Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Tue, 31 Jul 2012 17:19:41 -0700
changeset 106653 4b251874c178b8d51b59bfbcaf9821d7998849c0
parent 106652 b46621aba6fd1a81787626a968644abb4fa9ae2f (current diff)
parent 101040 95bd473e716405e886a472725e8dd670606cfbb2 (diff)
child 106654 e335d60b22263239dbc44d9048d7e2858043f625
push id14706
push usereakhgari@mozilla.com
push dateTue, 11 Sep 2012 20:39:52 +0000
treeherdermozilla-inbound@d50bf1edaabe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone17.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge from mozilla-central.
accessible/src/base/nsCoreUtils.cpp
accessible/src/generic/Accessible.cpp
accessible/src/generic/FormControlAccessible.cpp
accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
accessible/src/xul/XULMenuAccessible.cpp
accessible/src/xul/XULSliderAccessible.cpp
b2g/installer/package-manifest.in
browser/app/profile/firefox.js
browser/base/content/browser.js
config/autoconf.mk.in
config/system-headers
configure.in
content/base/public/nsIDocument.h
content/base/src/nsAttrValue.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
content/base/src/nsFrameLoader.cpp
content/base/src/nsFrameLoader.h
content/base/src/nsGenericElement.cpp
content/base/src/nsGenericElement.h
content/base/src/nsGkAtomList.h
content/base/src/nsHTMLContentSerializer.cpp
content/base/src/nsPlainTextSerializer.cpp
content/base/src/nsXHTMLContentSerializer.cpp
content/base/src/nsXMLNameSpaceMap.cpp
content/canvas/src/CustomQS_Canvas2D.h
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
content/canvas/test/test_canvas.html
content/html/content/public/nsHTMLCanvasElement.h
content/html/content/public/nsHTMLMediaElement.h
content/html/content/src/nsHTMLAudioElement.cpp
content/html/content/src/nsHTMLFormElement.cpp
content/html/content/src/nsHTMLFrameSetElement.cpp
content/html/content/src/nsHTMLInputElement.cpp
content/html/content/src/nsHTMLMediaElement.cpp
content/html/content/src/nsMediaFragmentURIParser.cpp
content/mathml/content/src/nsMathMLElement.cpp
content/media/MediaResource.cpp
content/media/nsAudioStream.cpp
content/media/nsBuiltinDecoder.cpp
content/media/nsBuiltinDecoder.h
content/media/nsBuiltinDecoderReader.h
content/media/nsBuiltinDecoderStateMachine.cpp
content/media/ogg/nsOggReader.cpp
content/media/ogg/nsOggReader.h
content/media/raw/nsRawReader.cpp
content/media/raw/nsRawReader.h
content/media/wave/nsWaveReader.cpp
content/media/wave/nsWaveReader.h
content/media/webm/nsWebMReader.cpp
content/media/webm/nsWebMReader.h
content/svg/content/src/SVGNumberList.cpp
content/svg/content/src/nsSVGSVGElement.cpp
content/svg/content/src/nsSVGScriptElement.cpp
content/svg/content/src/nsSVGUseElement.cpp
content/xbl/src/nsXBLBinding.cpp
content/xbl/src/nsXBLDocumentInfo.cpp
content/xul/content/src/nsXULContextMenuBuilder.cpp
content/xul/content/src/nsXULElement.cpp
content/xul/content/src/nsXULPopupListener.cpp
content/xul/document/src/nsXULDocument.cpp
content/xul/document/src/nsXULPrototypeCache.cpp
content/xul/document/src/nsXULPrototypeDocument.cpp
content/xul/templates/src/nsTemplateRule.cpp
content/xul/templates/src/nsXULContentBuilder.cpp
content/xul/templates/src/nsXULSortService.cpp
content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
docshell/base/nsDocShell.cpp
dom/Makefile.in
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
dom/base/nsDOMClassInfoClasses.h
dom/base/nsDOMWindowUtils.cpp
dom/base/nsFocusManager.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsJSEnvironment.cpp
dom/base/nsPIDOMWindow.h
dom/bindings/Codegen.py
dom/bindings/parser/WebIDL.py
dom/dom-config.mk
dom/indexedDB/IDBTransaction.cpp
dom/interfaces/base/nsIDOMWindowUtils.idl
dom/plugins/base/nsJSNPRuntime.cpp
dom/src/json/nsJSON.cpp
dom/workers/Events.cpp
dom/workers/Exceptions.cpp
dom/workers/File.cpp
dom/workers/Location.cpp
dom/workers/Navigator.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerScope.cpp
editor/libeditor/base/nsEditor.cpp
editor/libeditor/html/nsHTMLAbsPosition.cpp
editor/libeditor/html/nsHTMLAnonymousUtils.cpp
editor/libeditor/html/nsHTMLCSSUtils.cpp
editor/libeditor/html/nsHTMLDataTransfer.cpp
editor/libeditor/html/nsHTMLEditRules.cpp
editor/libeditor/html/nsHTMLEditRules.h
editor/libeditor/html/nsHTMLEditUtils.cpp
editor/libeditor/html/nsHTMLEditUtils.h
editor/libeditor/html/nsHTMLEditor.cpp
editor/libeditor/text/nsPlaintextEditor.cpp
editor/txmgr/tests/TestTXMgr.cpp
editor/txtsvc/src/nsTextServicesDocument.cpp
embedding/components/find/src/nsFind.cpp
embedding/components/printingui/src/unixshared/nsPrintProgress.cpp
embedding/components/printingui/src/unixshared/nsPrintProgress.h
extensions/cookie/nsPermissionManager.cpp
gfx/gl/GLContextProviderEGL.cpp
gfx/layers/ImageLayers.h
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/LayersBackend.h
gfx/layers/basic/BasicCanvasLayer.cpp
gfx/layers/basic/BasicLayers.h
gfx/layers/d3d10/LayerManagerD3D10.cpp
gfx/layers/ipc/PLayers.ipdl
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
gfx/layers/ipc/ShadowLayersParent.cpp
gfx/layers/opengl/ImageLayerOGL.cpp
gfx/layers/opengl/LayerManagerOGL.h
gfx/thebes/gfxASurface.h
gfx/thebes/gfxFontUtils.cpp
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPlatform.h
gfx/thebes/gfxUserFontSet.h
gfx/thebes/gfxWindowsPlatform.cpp
gfx/thebes/gfxWindowsPlatform.h
image/decoders/nsJPEGDecoder.cpp
image/src/imgRequest.cpp
js/ipc/ObjectWrapperParent.cpp
js/src/Makefile.in
js/src/builtin/Eval.cpp
js/src/builtin/ParallelArray.cpp
js/src/config/system-headers
js/src/frontend/BytecodeCompiler.cpp
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
js/src/gc/Root.h
js/src/ion/CodeGenerator.cpp
js/src/ion/IonCaches.cpp
js/src/ion/IonCaches.h
js/src/ion/IonFrames.cpp
js/src/ion/VMFunctions.cpp
js/src/ion/VMFunctions.h
js/src/ion/arm/Trampoline-arm.cpp
js/src/ion/shared/IonFrames-x86-shared.h
js/src/ion/x64/Trampoline-x64.cpp
js/src/ion/x86/Trampoline-x86.cpp
js/src/jsanalyze.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsarray.h
js/src/jsatom.cpp
js/src/jsatom.h
js/src/jsbool.cpp
js/src/jsclass.h
js/src/jscntxtinlines.h
js/src/jsdate.cpp
js/src/jsdbgapi.cpp
js/src/jsexn.cpp
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsfun.cpp
js/src/jsinfer.cpp
js/src/jsinterp.cpp
js/src/jsinterp.h
js/src/jsinterpinlines.h
js/src/jsiter.cpp
js/src/jsiter.h
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/json.cpp
js/src/jsopcode.cpp
js/src/jsopcode.h
js/src/jsproxy.cpp
js/src/jsreflect.cpp
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jsstr.cpp
js/src/jstypedarray.cpp
js/src/jstypedarray.h
js/src/jsutil.h
js/src/jsweakmap.cpp
js/src/jswrapper.cpp
js/src/jsxml.cpp
js/src/methodjit/Compiler.cpp
js/src/methodjit/PolyIC.cpp
js/src/methodjit/PolyIC.h
js/src/methodjit/StubCalls.cpp
js/src/shell/js.cpp
js/src/vm/ArgumentsObject.cpp
js/src/vm/ArgumentsObject.h
js/src/vm/Debugger.cpp
js/src/vm/GlobalObject.cpp
js/src/vm/ScopeObject.cpp
js/xpconnect/shell/xpcshell.cpp
js/xpconnect/src/Makefile.in
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCQuickStubs.cpp
js/xpconnect/src/XPCQuickStubs.h
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/XPCWrappedNativeJSOps.cpp
js/xpconnect/src/qsgen.py
js/xpconnect/src/xpcprivate.h
js/xpconnect/wrappers/WrapperFactory.cpp
js/xpconnect/wrappers/XrayWrapper.cpp
js/xpconnect/wrappers/XrayWrapper.h
layout/base/FrameLayerBuilder.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsDisplayList.cpp
layout/base/nsDocumentViewer.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
layout/base/nsPresShell.cpp
layout/build/Makefile.in
layout/forms/nsListControlFrame.cpp
layout/generic/nsContainerFrame.cpp
layout/generic/nsContainerFrame.h
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsHTMLCanvasFrame.cpp
layout/generic/nsHTMLCanvasFrame.h
layout/generic/nsImageFrame.cpp
layout/generic/nsObjectFrame.cpp
layout/generic/nsObjectFrame.h
layout/generic/nsSelection.cpp
layout/generic/nsTextFrameThebes.cpp
layout/generic/nsVideoFrame.cpp
layout/generic/nsVideoFrame.h
layout/inspector/src/inCSSValueSearch.cpp
layout/inspector/src/inDOMUtils.cpp
layout/ipc/RenderFrameParent.cpp
layout/ipc/RenderFrameParent.h
layout/mathml/nsMathMLChar.cpp
layout/mathml/nsMathMLOperators.cpp
layout/mathml/nsMathMLmactionFrame.cpp
layout/mathml/nsMathMLmpaddedFrame.cpp
layout/mathml/nsMathMLmtableFrame.cpp
layout/printing/nsPrintData.cpp
layout/reftests/bugs/reftest.list
layout/reftests/svg/reftest.list
layout/style/nsFontFaceLoader.h
layout/style/nsStyleCoord.cpp
layout/svg/base/src/nsSVGEffects.cpp
layout/svg/base/src/nsSVGImageFrame.cpp
layout/svg/base/src/nsSVGIntegrationUtils.h
layout/tables/nsTableRowGroupFrame.cpp
layout/tools/reftest/reftest.js
layout/tools/reftest/runreftest.py
layout/xul/base/public/nsXULPopupManager.h
layout/xul/base/src/nsBox.cpp
layout/xul/base/src/nsListBoxBodyFrame.cpp
layout/xul/base/src/nsMenuBarFrame.cpp
layout/xul/base/src/nsMenuBarFrame.h
layout/xul/base/src/nsMenuBoxObject.cpp
layout/xul/base/src/nsMenuFrame.cpp
layout/xul/base/src/nsMenuPopupFrame.cpp
layout/xul/base/src/nsPopupBoxObject.cpp
layout/xul/base/src/nsResizerFrame.cpp
layout/xul/base/src/nsSliderFrame.cpp
layout/xul/base/src/nsStackLayout.cpp
layout/xul/base/src/nsTitleBarFrame.cpp
layout/xul/base/src/nsXULPopupManager.cpp
layout/xul/base/src/nsXULTooltipListener.cpp
layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
layout/xul/base/test/Makefile.in
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/LauncherShortcuts.java.in
mobile/android/chrome/content/browser.js
mobile/xul/installer/package-manifest.in
modules/libjar/nsZipArchive.cpp
modules/libjar/nsZipArchive.h
modules/libpref/src/init/all.js
netwerk/base/public/nsNetUtil.h
netwerk/base/src/nsChannelClassifier.cpp
netwerk/base/src/nsIOService.cpp
netwerk/base/src/nsSocketTransport2.cpp
netwerk/base/src/nsURIChecker.cpp
netwerk/cache/nsDiskCacheDeviceSQL.cpp
netwerk/protocol/ftp/nsFtpConnectionThread.cpp
netwerk/protocol/http/nsHttpDigestAuth.cpp
netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
netwerk/test/urltest.cpp
parser/htmlparser/src/nsHTMLTokens.cpp
parser/htmlparser/src/nsParser.cpp
parser/htmlparser/src/nsParser.h
rdf/base/src/nsContainerEnumerator.cpp
rdf/base/src/nsRDFContainer.cpp
rdf/base/src/nsRDFContentSink.cpp
rdf/datasource/src/nsFileSystemDataSource.cpp
security/manager/ssl/src/NSSErrorsService.cpp
security/manager/ssl/src/TransportSecurityInfo.cpp
security/manager/ssl/src/nsCMS.cpp
security/manager/ssl/src/nsCertOverrideService.cpp
security/manager/ssl/src/nsNSSCertificateDB.cpp
security/manager/ssl/src/nsNSSIOLayer.cpp
storage/test/test_deadlock_detector.cpp
toolkit/components/downloads/nsDownloadProxy.h
toolkit/components/places/nsNavHistoryQuery.cpp
toolkit/components/places/nsNavHistoryResult.cpp
toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
toolkit/mozapps/extensions/AddonRepository.jsm
toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp
toolkit/xre/nsXREDirProvider.cpp
widget/android/AndroidBridge.h
widget/android/nsWindow.cpp
widget/android/nsWindow.h
widget/cocoa/nsChildView.mm
widget/cocoa/nsCocoaWindow.h
widget/cocoa/nsCocoaWindow.mm
widget/gtk2/nsDragService.cpp
widget/gtk2/nsWindow.cpp
widget/gtk2/nsWindow.h
widget/nsIWidget.h
widget/qt/nsWindow.cpp
widget/qt/nsWindow.h
widget/windows/nsWindow.cpp
widget/windows/nsWindow.h
widget/windows/nsWindowGfx.cpp
widget/xpwidgets/PuppetWidget.cpp
widget/xpwidgets/PuppetWidget.h
widget/xpwidgets/nsBaseFilePicker.cpp
widget/xpwidgets/nsBaseWidget.cpp
widget/xpwidgets/nsBaseWidget.h
widget/xpwidgets/nsNativeTheme.cpp
widget/xpwidgets/nsPrintOptionsImpl.cpp
xpcom/ds/nsSupportsArray.h
xpcom/string/public/nsTString.h
xpcom/string/src/nsStringObsolete.cpp
xpcom/string/src/nsTStringObsolete.cpp
xpcom/tests/TestDeadlockDetector.cpp
xpcom/tests/TestHashtables.cpp
xpfe/appshell/src/nsWebShellWindow.cpp
xpfe/appshell/src/nsXULWindow.cpp
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -508,17 +508,17 @@ nsCoreUtils::GetID(nsIContent *aContent,
 }
 
 bool
 nsCoreUtils::GetUIntAttr(nsIContent *aContent, nsIAtom *aAttr, PRInt32 *aUInt)
 {
   nsAutoString value;
   aContent->GetAttr(kNameSpaceID_None, aAttr, value);
   if (!value.IsEmpty()) {
-    PRInt32 error = NS_OK;
+    nsresult error = NS_OK;
     PRInt32 integer = value.ToInteger(&error);
     if (NS_SUCCEEDED(error) && integer > 0) {
       *aUInt = integer;
       return true;
     }
   }
 
   return false;
--- a/accessible/src/generic/Accessible.cpp
+++ b/accessible/src/generic/Accessible.cpp
@@ -3051,17 +3051,17 @@ Accessible::GetAttrValue(nsIAtom *aPrope
 
   nsAutoString attrValue;
   mContent->GetAttr(kNameSpaceID_None, aProperty, attrValue);
 
   // Return zero value if there is no attribute or its value is empty.
   if (attrValue.IsEmpty())
     return NS_OK;
 
-  PRInt32 error = NS_OK;
+  nsresult error = NS_OK;
   double value = attrValue.ToDouble(&error);
   if (NS_SUCCEEDED(error))
     *aValue = value;
 
   return NS_OK;
 }
 
 PRUint32
--- a/accessible/src/generic/FormControlAccessible.cpp
+++ b/accessible/src/generic/FormControlAccessible.cpp
@@ -106,17 +106,17 @@ NS_IMETHODIMP
 ProgressMeterAccessible<Max>::GetMaximumValue(double* aMaximumValue)
 {
   nsresult rv = LeafAccessible::GetMaximumValue(aMaximumValue);
   if (rv != NS_OK_NO_ARIA_VALUE)
     return rv;
 
   nsAutoString value;
   if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::max, value)) {
-    PRInt32 result = NS_OK;
+    nsresult result = NS_OK;
     *aMaximumValue = value.ToDouble(&result);
     return result;
   }
 
   *aMaximumValue = Max;
   return NS_OK;
 }
 
@@ -154,17 +154,17 @@ ProgressMeterAccessible<Max>::GetCurrent
 
   nsAutoString attrValue;
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue);
 
   // Return zero value if there is no attribute or its value is empty.
   if (attrValue.IsEmpty())
     return NS_OK;
 
-  PRInt32 error = NS_OK;
+  nsresult error = NS_OK;
   double value = attrValue.ToDouble(&error);
   if (NS_FAILED(error))
     return NS_OK; // Zero value because of wrong markup.
 
   *aCurrentValue = value;
   return NS_OK;
 }
 
--- a/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
@@ -308,62 +308,62 @@ nsXFormsRangeAccessible::GetMaximumValue
 {
   NS_ENSURE_ARG_POINTER(aMaximumValue);
 
   nsAutoString value;
   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
   nsresult rv = sXFormsService->GetRangeEnd(DOMNode, value);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 error = NS_OK;
+  nsresult error = NS_OK;
   *aMaximumValue = value.ToDouble(&error);
   return error;
 }
 
 NS_IMETHODIMP
 nsXFormsRangeAccessible::GetMinimumValue(double *aMinimumValue)
 {
   NS_ENSURE_ARG_POINTER(aMinimumValue);
 
   nsAutoString value;
   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
   nsresult rv = sXFormsService->GetRangeStart(DOMNode, value);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 error = NS_OK;
+  nsresult error = NS_OK;
   *aMinimumValue = value.ToDouble(&error);
   return error;
 }
 
 NS_IMETHODIMP
 nsXFormsRangeAccessible::GetMinimumIncrement(double *aMinimumIncrement)
 {
   NS_ENSURE_ARG_POINTER(aMinimumIncrement);
 
   nsAutoString value;
   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
   nsresult rv = sXFormsService->GetRangeStep(DOMNode, value);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 error = NS_OK;
+  nsresult error = NS_OK;
   *aMinimumIncrement = value.ToDouble(&error);
   return error;
 }
 
 NS_IMETHODIMP
 nsXFormsRangeAccessible::GetCurrentValue(double *aCurrentValue)
 {
   NS_ENSURE_ARG_POINTER(aCurrentValue);
 
   nsAutoString value;
   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
   nsresult rv = sXFormsService->GetValue(DOMNode, value);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 error = NS_OK;
+  nsresult error = NS_OK;
   *aCurrentValue = value.ToDouble(&error);
   return error;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXFormsSelectAccessible
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/src/xul/XULMenuAccessible.cpp
+++ b/accessible/src/xul/XULMenuAccessible.cpp
@@ -208,17 +208,17 @@ XULMenuitemAccessible::KeyboardShortcut(
 
   PRUint32 key = 0;
 
   nsAutoString keyStr;
   keyElm->GetAttr(kNameSpaceID_None, nsGkAtoms::key, keyStr);
   if (keyStr.IsEmpty()) {
     nsAutoString keyCodeStr;
     keyElm->GetAttr(kNameSpaceID_None, nsGkAtoms::keycode, keyCodeStr);
-    PRUint32 errorCode;
+    nsresult errorCode;
     key = keyStr.ToInteger(&errorCode, kAutoDetect);
   } else {
     key = keyStr[0];
   }
 
   nsAutoString modifiersStr;
   keyElm->GetAttr(kNameSpaceID_None, nsGkAtoms::modifiers, modifiersStr);
 
@@ -533,17 +533,17 @@ XULMenupopupAccessible::ContainerWidget(
 
   nsMenuPopupFrame* menuPopupFrame = do_QueryFrame(GetFrame());
   while (menuPopupFrame) {
     Accessible* menuPopup =
       document->GetAccessible(menuPopupFrame->GetContent());
     if (!menuPopup) // shouldn't be a real case
       return nullptr;
 
-    nsMenuFrame* menuFrame = menuPopupFrame->GetParentMenu();
+    nsMenuFrame* menuFrame = do_QueryFrame(menuPopupFrame->GetParent());
     if (!menuFrame) // context menu or popups
       return nullptr;
 
     nsMenuParent* menuParent = menuFrame->GetMenuParent();
     if (!menuParent) // menulist or menubutton
       return menuPopup->Parent();
 
     if (menuParent->IsMenuBar()) { // menubar menu
--- a/accessible/src/xul/XULSliderAccessible.cpp
+++ b/accessible/src/xul/XULSliderAccessible.cpp
@@ -218,17 +218,17 @@ XULSliderAccessible::GetSliderAttr(nsIAt
   nsAutoString attrValue;
   nsresult rv = GetSliderAttr(aName, attrValue);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Return zero value if there is no attribute or its value is empty.
   if (attrValue.IsEmpty())
     return NS_OK;
 
-  PRInt32 error = NS_OK;
+  nsresult error = NS_OK;
   double value = attrValue.ToDouble(&error);
   if (NS_SUCCEEDED(error))
     *aValue = value;
 
   return NS_OK;
 }
 
 nsresult
--- a/allmakefiles.sh
+++ b/allmakefiles.sh
@@ -120,16 +120,17 @@ if [ "$ENABLE_MARIONETTE" ]; then
 fi
 
 if [ "$ENABLE_TESTS" ]; then
   add_makefiles "
     build/autoconf/test/Makefile
     config/makefiles/test/Makefile
     config/tests/makefiles/autodeps/Makefile
     config/tests/src-simple/Makefile
+    mfbt/tests/Makefile
   "
   if [ ! "$LIBXUL_SDK" ]; then 
     add_makefiles "
       mozglue/tests/Makefile
     "
   fi
   if [ "$_MSC_VER" -a "$OS_TEST" != "x86_64" ]; then
     add_makefiles "
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -378,16 +378,22 @@ Services.obs.addObserver(function onSyst
   shell.sendChromeEvent({
     type: 'open-app',
     url: msg.uri,
     origin: origin,
     manifest: msg.manifest
   });
 }, 'system-messages-open-app', false);
 
+Services.obs.addObserver(function(aSubject, aTopic, aData) {
+  shell.sendEvent(shell.contentBrowser.contentWindow,
+                  "mozChromeEvent", { type: "fullscreenoriginchange",
+                                      fullscreenorigin: aData } );
+}, "fullscreen-origin-change", false);
+
 (function Repl() {
   if (!Services.prefs.getBoolPref('b2g.remote-js.enabled')) {
     return;
   }
   const prompt = 'JS> ';
   let output;
   let reader = {
     onInputStreamReady : function repl_readInput(input) {
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -160,16 +160,17 @@
 @BINPATH@/components/dom_telephony.xpt
 @BINPATH@/components/dom_wifi.xpt
 @BINPATH@/components/dom_system_gonk.xpt
 #endif
 @BINPATH@/components/dom_battery.xpt
 #ifdef MOZ_B2G_BT
 @BINPATH@/components/dom_bluetooth.xpt
 #endif
+@BINPATH@/components/dom_camera.xpt
 @BINPATH@/components/dom_canvas.xpt
 @BINPATH@/components/dom_contacts.xpt
 @BINPATH@/components/dom_alarm.xpt
 @BINPATH@/components/dom_core.xpt
 @BINPATH@/components/dom_css.xpt
 @BINPATH@/components/dom_devicestorage.xpt
 @BINPATH@/components/dom_events.xpt
 @BINPATH@/components/dom_file.xpt
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -643,22 +643,16 @@ const gFormSubmitObserver = {
 
   panel: null,
 
   init: function()
   {
     this.panel = document.getElementById('invalid-form-popup');
   },
 
-  panelIsOpen: function()
-  {
-    return this.panel && this.panel.state != "hiding" &&
-           this.panel.state != "closed";
-  },
-
   notifyInvalidSubmit : function (aFormElement, aInvalidElements)
   {
     // We are going to handle invalid form submission attempt by focusing the
     // first invalid element and show the corresponding validation message in a
     // panel attached to the element.
     if (!aInvalidElements.length) {
       return;
     }
@@ -1246,17 +1240,18 @@ var gBrowserInit = {
   _delayedStartup: function(isLoadingBlank, mustLoadSidebar) {
     let tmp = {};
     Cu.import("resource:///modules/TelemetryTimestamps.jsm", tmp);
     let TelemetryTimestamps = tmp.TelemetryTimestamps;
     TelemetryTimestamps.add("delayedStartupStarted");
     gDelayedStartupTimeoutId = null;
 
 #ifdef MOZ_SAFE_BROWSING
-    SafeBrowsing.init();
+    // Bug 778855 - Perf regression if we do this here. To be addressed in bug 779008.
+    setTimeout(function() { SafeBrowsing.init(); }, 2000);
 #endif
 
     Services.obs.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
     Services.obs.addObserver(gXPInstallObserver, "addon-install-disabled", false);
     Services.obs.addObserver(gXPInstallObserver, "addon-install-started", false);
     Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked", false);
     Services.obs.addObserver(gXPInstallObserver, "addon-install-failed", false);
     Services.obs.addObserver(gXPInstallObserver, "addon-install-complete", false);
@@ -3944,17 +3939,17 @@ var XULBrowserWindow = {
     }
   },
 
   onLocationChange: function (aWebProgress, aRequest, aLocationURI, aFlags) {
     var location = aLocationURI ? aLocationURI.spec : "";
     this._hostChanged = true;
 
     // Hide the form invalid popup.
-    if (gFormSubmitObserver.panelIsOpen()) {
+    if (gFormSubmitObserver.panel) {
       gFormSubmitObserver.panel.hidePopup();
     }
 
     if (document.tooltipNode) {
       // Optimise for the common case
       if (aWebProgress.DOMWindow == content) {
         document.getElementById("aHTMLTooltip").hidePopup();
         document.tooltipNode = null;
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -176,18 +176,16 @@ PlacesViewBase.prototype = {
   buildContextMenu: function PVB_buildContextMenu(aPopup) {
     this._contextMenuShown = true;
     window.updateCommands("places");
     return this.controller.buildContextMenu(aPopup);
   },
 
   destroyContextMenu: function PVB_destroyContextMenu(aPopup) {
     this._contextMenuShown = false;
-    if (window.content)
-      window.content.focus();
   },
 
   _cleanPopup: function PVB_cleanPopup(aPopup, aDelay) {
     // Remove Places nodes from the popup.
     let child = aPopup._startMarker;
     while (child.nextSibling != aPopup._endMarker) {
       let sibling = child.nextSibling;
       if (sibling._placesNode && !aDelay) {
new file mode 100644
--- /dev/null
+++ b/browser/config/mozconfigs/macosx64/debug-asan
@@ -0,0 +1,14 @@
+. $topsrcdir/build/unix/mozconfig.asan
+
+ac_add_options --enable-application=browser
+ac_add_options --enable-debug
+ac_add_options --enable-optimize="-O1"
+ac_add_options --enable-accessibility
+
+# Enable parallel compiling
+mk_add_options MOZ_MAKE_FLAGS="-j12"
+
+# Package js shell.
+export MOZ_PACKAGE_JSSHELL=1
+
+ac_add_options --with-macbundlename-prefix=Firefox
--- a/browser/devtools/styleinspector/CssRuleView.jsm
+++ b/browser/devtools/styleinspector/CssRuleView.jsm
@@ -76,17 +76,19 @@ function ElementStyle(aElement, aStore)
   // if it doesn't already exist.
   if (!("userProperties" in this.store)) {
     this.store.userProperties = new UserProperties();
   }
 
   if (this.store.disabled) {
     this.store.disabled = aStore.disabled;
   } else {
-    this.store.disabled = WeakMap();
+    // FIXME: This should be a WeakMap once bug 753517 is fixed.
+    // See Bug 777373 for details.
+    this.store.disabled = new Map();
   }
 
   let doc = aElement.ownerDocument;
 
   // To figure out how shorthand properties are interpreted by the
   // engine, we will set properties on a dummy element and observe
   // how their .style attribute reflects them as computed values.
   this.dummyElement = doc.createElementNS(this.element.namespaceURI,
@@ -482,17 +484,21 @@ Rule.prototype = {
       // any changes made during parsing.
       prop.priority = this.style.getPropertyPriority(prop.name);
       prop.updateComputed();
     }
     this.elementStyle._changed();
 
     // Store disabled properties in the disabled store.
     let disabled = this.elementStyle.store.disabled;
-    disabled.set(this.style, disabledProps);
+    if (disabledProps.length > 0) {
+      disabled.set(this.style, disabledProps);
+    } else {
+      disabled.delete(this.style);
+    }
 
     this.elementStyle.markOverridden();
   },
 
   /**
    * Renames a property.
    *
    * @param {TextProperty} aProperty
@@ -2152,17 +2158,19 @@ InplaceEditor.prototype = {
 function _getInplaceEditorForSpan(aSpan) { return aSpan.inplaceEditor; };
 
 /**
  * Store of CSSStyleDeclarations mapped to properties that have been changed by
  * the user.
  */
 function UserProperties()
 {
-  this.weakMap = new WeakMap();
+  // FIXME: This should be a WeakMap once bug 753517 is fixed.
+  // See Bug 777373 for details.
+  this.map = new Map();
 }
 
 UserProperties.prototype = {
   /**
    * Get a named property for a given CSSStyleDeclaration.
    *
    * @param {CSSStyleDeclaration} aStyle
    *        The CSSStyleDeclaration against which the property is mapped.
@@ -2172,17 +2180,17 @@ UserProperties.prototype = {
    *        The computed value of the property.  The user value will only be
    *        returned if the computed value hasn't changed since, and this will
    *        be returned as the default if no user value is available.
    * @returns {String}
    *          The property value if it has previously been set by the user, null
    *          otherwise.
    */
   getProperty: function UP_getProperty(aStyle, aName, aComputedValue) {
-    let entry = this.weakMap.get(aStyle, null);
+    let entry = this.map.get(aStyle, null);
 
     if (entry && aName in entry) {
       let item = entry[aName];
       if (item.computed != aComputedValue) {
         delete entry[aName];
         return aComputedValue;
       }
 
@@ -2201,36 +2209,36 @@ UserProperties.prototype = {
    *        The name of the property to set.
    * @param {String} aComputedValue
    *        The computed property value.  The user value will not be used if the
    *        computed value changes.
    * @param {String} aUserValue
    *        The value of the property to set.
    */
   setProperty: function UP_setProperty(aStyle, aName, aComputedValue, aUserValue) {
-    let entry = this.weakMap.get(aStyle, null);
+    let entry = this.map.get(aStyle, null);
     if (entry) {
       entry[aName] = { computed: aComputedValue, user: aUserValue };
     } else {
       let props = {};
       props[aName] = { computed: aComputedValue, user: aUserValue };
-      this.weakMap.set(aStyle, props);
+      this.map.set(aStyle, props);
     }
   },
 
   /**
    * Check whether a named property for a given CSSStyleDeclaration is stored.
    *
    * @param {CSSStyleDeclaration} aStyle
    *        The CSSStyleDeclaration against which the property would be mapped.
    * @param {String} aName
    *        The name of the property to check.
    */
   contains: function UP_contains(aStyle, aName) {
-    let entry = this.weakMap.get(aStyle, null);
+    let entry = this.map.get(aStyle, null);
     return !!entry && aName in entry;
   },
 };
 
 /**
  * Helper functions
  */
 
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -169,16 +169,17 @@
 @BINPATH@/components/dom_telephony.xpt
 @BINPATH@/components/dom_wifi.xpt
 @BINPATH@/components/dom_system_gonk.xpt
 #endif
 @BINPATH@/components/dom_battery.xpt
 #ifdef MOZ_B2G_BT
 @BINPATH@/components/dom_bluetooth.xpt
 #endif
+@BINPATH@/components/dom_camera.xpt
 @BINPATH@/components/dom_canvas.xpt
 @BINPATH@/components/dom_contacts.xpt
 @BINPATH@/components/dom_alarm.xpt
 @BINPATH@/components/dom_core.xpt
 @BINPATH@/components/dom_css.xpt
 @BINPATH@/components/dom_devicestorage.xpt
 @BINPATH@/components/dom_events.xpt
 @BINPATH@/components/dom_file.xpt
--- a/build/mobile/sutagent/android/CmdWorkerThread.java
+++ b/build/mobile/sutagent/android/CmdWorkerThread.java
@@ -3,23 +3,21 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package com.mozilla.SUTAgentAndroid.service;
 
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.FileWriter;
 import java.io.PrintWriter;
 import java.net.Socket;
 import java.net.SocketTimeoutException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
+
+import com.mozilla.SUTAgentAndroid.SUTAgentAndroid;
 
 import android.util.Log;
 
 // import com.mozilla.SUTAgentAndroid.DoCommand;
 
 public class CmdWorkerThread extends Thread
 {
     private RunCmdThread theParent = null;
@@ -95,16 +93,18 @@ public class CmdWorkerThread extends Thr
         try {
             OutputStream cmdOut = socket.getOutputStream();
             InputStream cmdIn = socket.getInputStream();
             PrintWriter out = new PrintWriter(cmdOut, true);
             BufferedInputStream in = new BufferedInputStream(cmdIn);
             String inputLine, outputLine;
             DoCommand dc = new DoCommand(theParent.svc);
 
+            SUTAgentAndroid.logToFile(dc.GetTestRoot(), dc.GetSystemTime(), "CmdWorkerThread starts: "+getId());
+
             int nAvail = cmdIn.available();
             cmdIn.skip(nAvail);
 
             out.print(prompt);
             out.flush();
 
             while (bListening)
                 {
@@ -129,40 +129,19 @@ public class CmdWorkerThread extends Thr
                         continue;
                         }
                     }
                 else
                     inputLine = "";
 
                 if ((inputLine += readLine(in)) != null)
                     {
-                    String datestamp = dc.GetSystemTime();
-                    String message = String.format("%s : %s : %s",
-                                     datestamp, socket.getInetAddress().getHostAddress(), inputLine);
-                    Log.i("SUTAgentAndroid", message);
-
-                    String fileDateStr = "00";
-                    try {
-                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
-                        Date dateStr = sdf.parse(datestamp);
-                        SimpleDateFormat sdf_file = new SimpleDateFormat("yyyy-MM-dd");
-                        fileDateStr = sdf_file.format(dateStr);
-                    } catch (ParseException pe) {}
-                    String logFile = dc.GetTestRoot() + "/" + fileDateStr + "-sutcommands.txt";
-                    PrintWriter pw = null;
-                    try {
-                        pw = new PrintWriter(new FileWriter(logFile, true));
-                        if (message != null) {
-                            pw.println(message);
-                        }
-                    } catch (IOException ioe) {
-                        Log.e("SUTAgentAndroid", "exception with file writer on: " + logFile);
-                    } finally {
-                        pw.close();
-                    }
+                    String message = String.format("%s : %s",
+                                     socket.getInetAddress().getHostAddress(), inputLine);
+                    SUTAgentAndroid.logToFile(dc.GetTestRoot(), dc.GetSystemTime(), message);
 
                     outputLine = dc.processCommand(inputLine, out, in, cmdOut);
                     if (outputLine.length() > 0)
                         {
                         out.print(outputLine + "\n" + prompt);
                         }
                     else
                         out.print(prompt);
@@ -182,16 +161,17 @@ public class CmdWorkerThread extends Thr
                 else
                     break;
                 }
             out.close();
             out = null;
             in.close();
             in = null;
             socket.close();
+            SUTAgentAndroid.logToFile(dc.GetTestRoot(), dc.GetSystemTime(), "CmdWorkerThread ends: "+getId());
         }
     catch (IOException e)
         {
         // TODO Auto-generated catch block
         e.printStackTrace();
         }
     }
 }
--- a/build/mobile/sutagent/android/SUTAgentAndroid.java
+++ b/build/mobile/sutagent/android/SUTAgentAndroid.java
@@ -1,15 +1,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/. */
 
 package com.mozilla.SUTAgentAndroid;
 
 import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.InetAddress;
 import org.apache.http.conn.util.InetAddressUtils;
 import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.net.UnknownHostException;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -145,16 +147,18 @@ public class SUTAgentAndroid extends Act
         super.onCreate(savedInstanceState);
 
         setContentView(R.layout.main);
 
         fixScreenOrientation();
 
         DoCommand dc = new DoCommand(getApplication());
 
+        logToFile(dc.GetTestRoot(), dc.GetSystemTime(), "onCreate");
+
         // Get configuration settings from "ini" file
         File dir = getFilesDir();
         File iniFile = new File(dir, "SUTAgent.ini");
         String sIniFile = iniFile.getAbsolutePath();
 
         SUTAgentAndroid.RegSvrIPAddr = dc.GetIniData("Registration Server", "IPAddr", sIniFile);
         SUTAgentAndroid.RegSvrIPPort = dc.GetIniData("Registration Server", "PORT", sIniFile);
         SUTAgentAndroid.HardwareID = dc.GetIniData("Registration Server", "HARDWARE", sIniFile);
@@ -346,30 +350,36 @@ public class SUTAgentAndroid extends Act
                Toast.makeText(getApplication().getApplicationContext(), "SUTAgent startprg finished ...", Toast.LENGTH_LONG).show();
             }
         }
 
     @Override
     public void onDestroy()
         {
         super.onDestroy();
+        DoCommand dc = new DoCommand(getApplication());
         if (isFinishing())
             {
+            logToFile(dc.GetTestRoot(), dc.GetSystemTime(), "onDestroy - finishing");
             Intent listenerSvc = new Intent(this, ASMozStub.class);
             listenerSvc.setAction("com.mozilla.SUTAgentAndroid.service.LISTENER_SERVICE");
             stopService(listenerSvc);
             bNetworkingStarted = false;
 
             unregisterReceiver(battReceiver);
 
             if (wl != null)
                 wl.release();
 
             System.exit(0);
             }
+        else
+            {
+            logToFile(dc.GetTestRoot(), dc.GetSystemTime(), "onDestroy - not finishing");
+            }
         }
 
     private void monitorBatteryState()
         {
         battReceiver = new BroadcastReceiver()
             {
             public void onReceive(Context context, Intent intent)
                 {
@@ -709,9 +719,46 @@ public class SUTAgentAndroid extends Act
                 }
             }
         catch (SocketException ex)
             {
             Toast.makeText(getApplication().getApplicationContext(), ex.toString(), Toast.LENGTH_LONG).show();
             }
         return null;
         }
+
+    public static void logToFile(String testRoot, String datestamp, String message)
+        {
+        if (testRoot == null ||
+            datestamp == null ||
+            message == null)
+            {
+            Log.e("SUTAgentAndroid", "bad arguments in logToFile()!");
+            return;
+            }
+        Log.i("SUTAgentAndroid", message);
+        String fileDateStr = "00";
+        try 
+            {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
+            Date dateStr = sdf.parse(datestamp);
+            SimpleDateFormat sdf_file = new SimpleDateFormat("yyyy-MM-dd");
+            fileDateStr = sdf_file.format(dateStr);
+            } 
+        catch (ParseException pe) {}
+        String logFile = testRoot + "/" + fileDateStr + "-sutcommands.txt";
+        PrintWriter pw = null;
+        try 
+            {
+            pw = new PrintWriter(new FileWriter(logFile, true));
+            pw.println(datestamp + " : " + message);
+            } 
+            catch (IOException ioe) 
+            {
+                Log.e("SUTAgentAndroid", "exception with file writer on: " + logFile);
+            } 
+            finally 
+            {
+                pw.close();
+            }
+
+        }
 }
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -268,16 +268,17 @@ MOZ_ENABLE_GIO = @MOZ_ENABLE_GIO@
 MOZ_GIO_CFLAGS = @MOZ_GIO_CFLAGS@
 MOZ_GIO_LIBS = @MOZ_GIO_LIBS@
 
 MOZ_NATIVE_NSPR = @MOZ_NATIVE_NSPR@
 MOZ_NATIVE_NSS = @MOZ_NATIVE_NSS@
 
 MOZ_B2G_RIL = @MOZ_B2G_RIL@
 MOZ_B2G_BT = @MOZ_B2G_BT@
+MOZ_B2G_CAMERA = @MOZ_B2G_CAMERA@
 
 MOZ_SYS_MSG = @MOZ_SYS_MSG@
 
 MOZ_ASAN = @MOZ_ASAN@
 MOZ_CFLAGS_NSS = @MOZ_CFLAGS_NSS@
 MOZ_NO_WLZDEFS = @MOZ_NO_WLZDEFS@
 
 BUILD_CTYPES = @BUILD_CTYPES@
--- a/config/system-headers
+++ b/config/system-headers
@@ -641,18 +641,20 @@ share.h
 shellapi.h
 shlguid.h
 shlobj.h
 sigcontext.h
 signal.h
 SimpleGameSound.h
 SIOUX.h
 size_t.h
+sndio.h
 someincludefile.h
 Sound.h
+soundcard.h
 sqlite3.h
 ssdef.h
 sslerr.h
 ssl.h
 sslproto.h
 sstream
 stack
 StandardFile.h
--- a/configure.in
+++ b/configure.in
@@ -187,17 +187,17 @@ if test -n "$gonkdir" ; then
     arm)
         ARCH_DIR=arch-arm
         ;;
     i?86)
         ARCH_DIR=arch-x86
         ;;
     esac
 
-    CPPFLAGS="-DANDROID -isystem $gonkdir/bionic/libc/$ARCH_DIR/include -isystem $gonkdir/bionic/libc/include/ -isystem $gonkdir/bionic/libc/kernel/common -isystem $gonkdir/bionic/libc/kernel/$ARCH_DIR -isystem $gonkdir/bionic/libm/include -I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/hardware/libhardware/include -I$gonkdir/hardware/libhardware_legacy/include -I$gonkdir/system -I$gonkdir/system/core/include -isystem $gonkdir/bionic -I$gonkdir/frameworks/base/include -I$gonkdir/external/dbus $CPPFLAGS -I$gonkdir/frameworks/base/services/sensorservice"
+    CPPFLAGS="-DANDROID -isystem $gonkdir/bionic/libc/$ARCH_DIR/include -isystem $gonkdir/bionic/libc/include/ -isystem $gonkdir/bionic/libc/kernel/common -isystem $gonkdir/bionic/libc/kernel/$ARCH_DIR -isystem $gonkdir/bionic/libm/include -I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/hardware/libhardware/include -I$gonkdir/hardware/libhardware_legacy/include -I$gonkdir/system -I$gonkdir/system/core/include -isystem $gonkdir/bionic -I$gonkdir/frameworks/base/include -I$gonkdir/external/dbus $CPPFLAGS -I$gonkdir/frameworks/base/services/sensorservice -I$gonkdir/frameworks/base/services/camera"
     CFLAGS="-mandroid -fno-short-enums -fno-exceptions $CFLAGS"
     CXXFLAGS="-mandroid -fno-short-enums -fno-exceptions $CXXFLAGS $STLPORT_CPPFLAGS"
     LIBS="$LIBS $STLPORT_LIBS"
 
     dnl Add -llog by default, since we use it all over the place.
     LDFLAGS="-mandroid -L$gonkdir/out/target/product/$GONK_PRODUCT/obj/lib -Wl,-rpath-link=$gonkdir/out/target/product/$GONK_PRODUCT/obj/lib --sysroot=$gonkdir/out/target/product/$GONK_PRODUCT/obj/ -llog $LDFLAGS"
 
     dnl prevent cross compile section from using these flags as host flags
@@ -3616,23 +3616,27 @@ AC_CACHE_CHECK(for __thread keyword for 
                             ac_cv_thread_keyword=yes,
                             ac_cv_thread_keyword=no)])
 LDFLAGS=$_SAVE_LDFLAGS
 # The custom dynamic linker doesn't support TLS variables
 MOZ_TLS=
 if test "$ac_cv_thread_keyword" = yes -a "$MOZ_LINKER" != 1; then
   # mips builds fail with TLS variables because of a binutils bug.
   # See bug 528687
+  # OpenBSD doesn't have TLS support, and the test succeeds with clang++
   case "${target}" in
     mips*-*)
       :
       ;;
     *-android*|*-linuxandroid*)
       :
       ;;
+    *-openbsd*)
+      :
+      ;;
     *)
       AC_DEFINE(HAVE_THREAD_TLS_KEYWORD)
       MOZ_TLS=1
       ;;
   esac
 fi
 
 dnl Using the custom linker on ARMv6 requires 16k alignment of ELF segments.
@@ -7343,16 +7347,28 @@ dnl ====================================
 dnl = Enable Support for System Messages API
 dnl ========================================================
 if test -n "$MOZ_SYS_MSG"; then
     AC_DEFINE(MOZ_SYS_MSG)
 fi
 AC_SUBST(MOZ_SYS_MSG)
 
 dnl ========================================================
+dnl = Enable Camera Interface for B2G (Gonk usually)
+dnl ========================================================
+MOZ_ARG_ENABLE_BOOL(b2g-camera,
+[  --enable-b2g-camera      Set compile flags necessary for compiling camera API for B2G ],
+    MOZ_B2G_CAMERA=1,
+    MOZ_B2G_CAMERA= )
+if test -n "$MOZ_B2G_CAMERA"; then
+   AC_DEFINE(MOZ_B2G_CAMERA)
+fi
+AC_SUBST(MOZ_B2G_CAMERA)
+
+dnl ========================================================
 dnl = Support for demangling undefined symbols
 dnl ========================================================
 if test -z "$SKIP_LIBRARY_CHECKS"; then
     AC_LANG_SAVE
     AC_LANG_CPLUSPLUS
     AC_CHECK_FUNCS(__cxa_demangle, HAVE_DEMANGLE=1, HAVE_DEMANGLE=)
     AC_LANG_RESTORE
 fi
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -87,18 +87,18 @@ class Loader;
 
 namespace dom {
 class Link;
 class Element;
 } // namespace dom
 } // namespace mozilla
 
 #define NS_IDOCUMENT_IID \
-{ 0x8c6a1e62, 0xd5ad, 0x4297, \
-  { 0xb9, 0x41, 0x64, 0x49, 0x22, 0x2e, 0xc4, 0xf0 } }
+{ 0xbd70ee06, 0x2a7d, 0x4258, \
+  { 0x86, 0x4b, 0xbd, 0x28, 0xad, 0x9f, 0xd1, 0x41 } }
 
 // Flag for AddStyleSheet().
 #define NS_STYLESHEET_FROM_CATALOG                (1 << 0)
 
 // Enum for requesting a particular type of document when creating a doc
 enum DocumentFlavor {
   DocumentFlavorLegacyGuess, // compat with old code until made HTML5-compliant
   DocumentFlavorHTML, // HTMLDocument with HTMLness bit set to true
@@ -719,16 +719,37 @@ public:
    * Asynchronously requests that the document make aElement the full-screen
    * element, and move into full-screen mode. The current full-screen element
    * (if any) is pushed onto the full-screen element stack, and it can be
    * returned to full-screen status by calling RestorePreviousFullScreenState().
    */
   virtual void AsyncRequestFullScreen(Element* aElement) = 0;
 
   /**
+   * Called when a frame in a child process has entered fullscreen or when a
+   * fullscreen frame in a child process changes to another origin.
+   * aFrameElement is the frame element which contains the child-process
+   * fullscreen document, and aNewOrigin is the origin of the new fullscreen
+   * document.
+   */
+  virtual nsresult RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
+                                                const nsAString& aNewOrigin) = 0;
+
+  /**
+   * Called when a frame in a remote child document has rolled back fullscreen
+   * so that all its fullscreen element stacks are empty; we must continue the
+   * rollback in this parent process' doc tree branch which is fullscreen.
+   * Note that only one branch of the document tree can have its documents in
+   * fullscreen state at one time. We're in inconsistent state if the a 
+   * fullscreen document has a parent and that parent isn't fullscreen. We
+   * preserve this property across process boundaries.
+   */
+   virtual nsresult RemoteFrameFullscreenReverted() = 0;
+
+  /**
    * Restores the previous full-screen element to full-screen status. If there
    * is no former full-screen element, this exits full-screen, moving the
    * top-level browser window out of full-screen mode.
    */
   virtual void RestorePreviousFullScreenState() = 0;
 
   /**
    * Returns true if this document is in full-screen mode.
--- a/content/base/src/Link.cpp
+++ b/content/base/src/Link.cpp
@@ -183,17 +183,17 @@ Link::SetHost(const nsAString &aHost)
   (void)uri->SetHost(host);
 
   // Also set the port if needed.
   if (iter != end) {
     iter++;
     if (iter != end) {
       nsAutoString portStr(Substring(iter, end));
       nsresult rv;
-      PRInt32 port = portStr.ToInteger((PRInt32 *)&rv);
+      PRInt32 port = portStr.ToInteger(&rv);
       if (NS_SUCCEEDED(rv)) {
         (void)uri->SetPort(port);
       }
     }
   };
 
   SetHrefAttribute(uri);
   return NS_OK;
@@ -249,17 +249,17 @@ Link::SetPort(const nsAString &aPort)
   nsCOMPtr<nsIURI> uri(GetURIToMutate());
   if (!uri) {
     // Ignore failures to be compatible with NS4.
     return NS_OK;
   }
 
   nsresult rv;
   nsAutoString portStr(aPort);
-  PRInt32 port = portStr.ToInteger((PRInt32 *)&rv);
+  PRInt32 port = portStr.ToInteger(&rv);
   if (NS_FAILED(rv)) {
     return NS_OK;
   }
 
   (void)uri->SetPort(port);
   SetHrefAttribute(uri);
   return NS_OK;
 }
--- a/content/base/src/nsAttrValue.cpp
+++ b/content/base/src/nsAttrValue.cpp
@@ -1457,17 +1457,17 @@ nsAttrValue::ParseColor(const nsAString&
 
   return false;
 }
 
 bool nsAttrValue::ParseDoubleValue(const nsAString& aString)
 {
   ResetIfSet();
 
-  PRInt32 ec;
+  nsresult ec;
   double val = PromiseFlatString(aString).ToDouble(&ec);
   if (NS_FAILED(ec)) {
     return false;
   }
   if (EnsureEmptyMiscContainer()) {
     MiscContainer* cont = GetMiscContainer();
     cont->mDoubleValue = val;
     cont->mType = eDoubleValue;
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -1256,18 +1256,18 @@ nsContentUtils::ParseIntMarginValue(cons
     if (count < 3)
       end = Substring(marginStr, start).FindChar(',');
     else
       end = Substring(marginStr, start).Length();
 
     if (end <= 0)
       return false;
 
-    PRInt32 ec, val = 
-      nsString(Substring(marginStr, start, end)).ToInteger(&ec);
+    nsresult ec;
+    PRInt32 val = nsString(Substring(marginStr, start, end)).ToInteger(&ec);
     if (NS_FAILED(ec))
       return false;
 
     switch(count) {
       case 0:
         result.top = val;
       break;
       case 1:
@@ -5015,49 +5015,48 @@ nsContentUtils::GetViewportInfo(nsIDocum
 
   nsAutoString handheldFriendly;
   aDocument->GetHeaderData(nsGkAtoms::handheldFriendly, handheldFriendly);
 
   if (handheldFriendly.EqualsLiteral("true")) {
     return ret;
   }
 
-  PRInt32 errorCode;
-
   nsAutoString minScaleStr;
   aDocument->GetHeaderData(nsGkAtoms::minimum_scale, minScaleStr);
 
+  nsresult errorCode;
   float scaleMinFloat = minScaleStr.ToFloat(&errorCode);
 
   if (errorCode) {
     scaleMinFloat = kViewportMinScale;
   }
 
   scaleMinFloat = NS_MIN(scaleMinFloat, kViewportMaxScale);
   scaleMinFloat = NS_MAX(scaleMinFloat, kViewportMinScale);
 
   nsAutoString maxScaleStr;
   aDocument->GetHeaderData(nsGkAtoms::maximum_scale, maxScaleStr);
 
   // We define a special error code variable for the scale and max scale,
   // because they are used later (see the width calculations).
-  PRInt32 scaleMaxErrorCode;
+  nsresult scaleMaxErrorCode;
   float scaleMaxFloat = maxScaleStr.ToFloat(&scaleMaxErrorCode);
 
   if (scaleMaxErrorCode) {
     scaleMaxFloat = kViewportMaxScale;
   }
 
   scaleMaxFloat = NS_MIN(scaleMaxFloat, kViewportMaxScale);
   scaleMaxFloat = NS_MAX(scaleMaxFloat, kViewportMinScale);
 
   nsAutoString scaleStr;
   aDocument->GetHeaderData(nsGkAtoms::viewport_initial_scale, scaleStr);
 
-  PRInt32 scaleErrorCode;
+  nsresult scaleErrorCode;
   float scaleFloat = scaleStr.ToFloat(&scaleErrorCode);
   scaleFloat = NS_MIN(scaleFloat, scaleMaxFloat);
   scaleFloat = NS_MAX(scaleFloat, scaleMinFloat);
 
   nsAutoString widthStr, heightStr;
 
   aDocument->GetHeaderData(nsGkAtoms::viewport_height, heightStr);
   aDocument->GetHeaderData(nsGkAtoms::viewport_width, widthStr);
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -8494,17 +8494,17 @@ nsDocument::MozCancelFullScreen()
   if (!nsContentUtils::IsRequestFullScreenAllowed()) {
     return NS_OK;
   }
   RestorePreviousFullScreenState();
   return NS_OK;
 }
 
 // Runnable to set window full-screen mode. Used as a script runner
-// to ensure we only call nsGlobalWindow::SetFullScreen() when it's safe to 
+// to ensure we only call nsGlobalWindow::SetFullScreen() when it's safe to
 // run script. nsGlobalWindow::SetFullScreen() dispatches a synchronous event
 // (handled in chome code) which is unsafe to run if this is called in
 // nsGenericElement::UnbindFromTree().
 class nsSetWindowFullScreen : public nsRunnable {
 public:
   nsSetWindowFullScreen(nsIDocument* aDoc, bool aValue)
     : mDoc(aDoc), mValue(aValue) {}
 
@@ -8542,23 +8542,64 @@ nsIDocument::ExitFullScreen(bool aRunAsy
 {
   if (aRunAsync) {
     NS_DispatchToCurrentThread(new nsCallExitFullScreen());
     return;
   }
   nsDocument::ExitFullScreen();
 }
 
+// Returns true if the document is a direct child of a cross process parent
+// mozbrowser iframe. This is the case when the document has a null parent,
+// and its DocShell reports that it is a browser frame.
 static bool
-ResetFullScreen(nsIDocument* aDocument, void* aData) {
+HasCrossProcessParent(nsIDocument* aDocument)
+{
+  if (XRE_GetProcessType() != GeckoProcessType_Content) {
+    return false;
+  }
+  if (aDocument->GetParentDocument() != nullptr) {
+    return false;
+  }
+  nsPIDOMWindow* win = aDocument->GetWindow();
+  if (!win) {
+    return false;
+  }
+  nsCOMPtr<nsIDocShell> docShell = win->GetDocShell();
+  if (!docShell) {
+    return false;
+  }
+  bool isBrowserElement = false;
+  docShell->GetIsBrowserElement(&isBrowserElement);
+  return isBrowserElement;
+}
+
+static bool
+ResetFullScreen(nsIDocument* aDocument, void* aData)
+{
   if (aDocument->IsFullScreenDoc()) {
     static_cast<nsDocument*>(aDocument)->CleanupFullscreenState();
     NS_ASSERTION(!aDocument->IsFullScreenDoc(), "Should reset full-screen");
     nsTArray<nsIDocument*>* changed = reinterpret_cast<nsTArray<nsIDocument*>*>(aData);
     changed->AppendElement(aDocument);
+
+    if (HasCrossProcessParent(aDocument)) {
+      // We're at the top of the content-process side doc tree. Ask the parent
+      // process to exit fullscreen.
+      nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
+      os->NotifyObservers(aDocument, "ask-parent-to-exit-fullscreen", nullptr);
+    }
+
+    // Dispatch a notification so that if this document has any
+    // cross-process subdocuments, they'll be notified to exit fullscreen.
+    // The BrowserElementParent listens for this event and performs the
+    // cross process notification if it has a remote child process.
+    nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
+    os->NotifyObservers(aDocument, "ask-children-to-exit-fullscreen", nullptr);
+
     aDocument->EnumerateSubDocuments(ResetFullScreen, aData);
   }
   return true;
 }
 
 /* static */
 void
 nsDocument::ExitFullScreen()
@@ -8618,34 +8659,47 @@ nsDocument::RestorePreviousFullScreenSta
 
   // If fullscreen mode is updated the pointer should be unlocked
   nsCOMPtr<Element> pointerLockedElement =
     do_QueryReferent(nsEventStateManager::sPointerLockedElement);
   if (pointerLockedElement) {
     UnlockPointer();
   }
 
-  // Clear full-screen stacks in all descendant documents, bottom up.
   nsCOMPtr<nsIDocument> fullScreenDoc(do_QueryReferent(sFullScreenDoc));
+
+  // The fullscreen document may contain a <iframe mozbrowser> element which
+  // has a cross process child. So send a notification so that its browser
+  // parent will send a message to its child process to also exit fullscreen.
+  nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
+  os->NotifyObservers(fullScreenDoc, "ask-children-to-exit-fullscreen", nullptr);
+
+  // Clear full-screen stacks in all descendant in process documents, bottom up.
   nsIDocument* doc = fullScreenDoc;
   while (doc != this) {
     NS_ASSERTION(doc->IsFullScreenDoc(), "Should be full-screen doc");
     static_cast<nsDocument*>(doc)->CleanupFullscreenState();
     UnlockPointer();
     DispatchFullScreenChange(doc);
     doc = doc->GetParentDocument();
   }
 
   // Roll-back full-screen state to previous full-screen element.
   NS_ASSERTION(doc == this, "Must have reached this doc.");
   while (doc != nullptr) {
     static_cast<nsDocument*>(doc)->FullScreenStackPop();
     UnlockPointer();
     DispatchFullScreenChange(doc);
     if (static_cast<nsDocument*>(doc)->mFullScreenStack.IsEmpty()) {
+      if (HasCrossProcessParent(doc)) {
+        // Send notification to the parent process to tell it to rollback to
+        // the previous fullscreen elements in its fullscreen element stacks.
+        nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
+        os->NotifyObservers(doc, "ask-parent-to-rollback-fullscreen", nullptr);
+      }
       // Full-screen stack in document is empty. Go back up to the parent
       // document. We'll pop the containing element off its stack, and use
       // its next full-screen element as the full-screen element.
       static_cast<nsDocument*>(doc)->CleanupFullscreenState();
       doc = doc->GetParentDocument();
     } else {
       // Else we popped the top of the stack, and there's still another
       // element in there, so that will become the full-screen element.
@@ -8660,16 +8714,28 @@ nsDocument::RestorePreviousFullScreenSta
           nsRefPtr<nsAsyncDOMEvent> e =
             new nsAsyncDOMEvent(doc,
                                 NS_LITERAL_STRING("MozEnteredDomFullscreen"),
                                 true,
                                 true);
           e->PostDOMEvent();
         }
       }
+
+      if (!nsContentUtils::HaveEqualPrincipals(doc, fullScreenDoc)) {
+        // The origin which is fullscreen changed. Send a notification to
+        // the root process so that a warning or approval UI can be shown
+        // as necessary.
+        nsAutoString origin;
+        nsContentUtils::GetUTFOrigin(doc->NodePrincipal(), origin);
+        nsIDocument* root = nsContentUtils::GetRootDocument(doc);
+        nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
+        os->NotifyObservers(root, "fullscreen-origin-change", origin.get());
+      }
+
       sFullScreenDoc = do_GetWeakReference(doc);
       break;
     }
   }
 
   if (doc == nullptr) {
     // We moved all documents out of full-screen mode, reset global full-screen
     // state and move the top-level window out of full-screen mode.
@@ -8695,17 +8761,19 @@ public:
       mDoc(aElement->OwnerDoc()),
       mWasCallerChrome(nsContentUtils::IsCallerChrome())
   {
   }
 
   NS_IMETHOD Run()
   {
     nsDocument* doc = static_cast<nsDocument*>(mDoc.get());
-    doc->RequestFullScreen(mElement, mWasCallerChrome);
+    doc->RequestFullScreen(mElement,
+                           mWasCallerChrome,
+                           /* aNotifyOnOriginChange */ true);
     return NS_OK;
   }
 
   nsRefPtr<Element> mElement;
   nsCOMPtr<nsIDocument> mDoc;
   bool mWasCallerChrome;
 };
 
@@ -8862,17 +8930,17 @@ IsInActiveTab(nsIDocument* aDoc)
     return false;
   }
 
   bool isActive = false;
   docshell->GetIsActive(&isActive);
   if (!isActive) {
     return false;
   }
-  
+
   nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(container);
   if (!dsti) {
     return false;
   }
   nsCOMPtr<nsIDocShellTreeItem> rootItem;
   dsti->GetRootTreeItem(getter_AddRefs(rootItem));
   if (!rootItem) {
     return false;
@@ -8891,18 +8959,53 @@ IsInActiveTab(nsIDocument* aDoc)
   fm->GetActiveWindow(getter_AddRefs(activeWindow));
   if (!activeWindow) {
     return false;
   }
 
   return activeWindow == rootWin;
 }
 
-void
-nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
+nsresult nsDocument::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
+                                                  const nsAString& aOrigin)
+{
+  // Ensure the frame element is the fullscreen element in this document.
+  // If the frame element is already the fullscreen element in this document,
+  // this has no effect.
+  nsCOMPtr<nsIContent> content(do_QueryInterface(aFrameElement));
+  RequestFullScreen(content->AsElement(),
+                    /* aWasCallerChrome */ false,
+                    /* aNotifyOnOriginChange */ false);
+
+  // Origin changed in child process, send notifiction, so that chrome can
+  // update the UI to reflect the fullscreen origin change if necessary.
+  // The BrowserElementChild listens on this, and forwards it over its
+  // parent process, where it is redispatched. Chrome (in the root process,
+  // which could be *this* process) listens for this notification so that
+  // it can show a warning or approval UI.
+  if (!aOrigin.IsEmpty()) {
+    nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
+    os->NotifyObservers(nsContentUtils::GetRootDocument(this),
+                        "fullscreen-origin-change",
+                        PromiseFlatString(aOrigin).get());
+  }
+
+  return NS_OK;
+}
+
+nsresult nsDocument::RemoteFrameFullscreenReverted()
+{
+  RestorePreviousFullScreenState();
+  return NS_OK;
+}
+
+void
+nsDocument::RequestFullScreen(Element* aElement,
+                              bool aWasCallerChrome,
+                              bool aNotifyOnOriginChange)
 {
   NS_ASSERTION(aElement,
     "Must pass non-null element to nsDocument::RequestFullScreen");
   if (!aElement || aElement == GetFullScreenElement()) {
     return;
   }
   if (!aElement->IsInDoc()) {
     LogFullScreenDenied(true, "FullScreenDeniedNotInDocument", this);
@@ -8917,17 +9020,17 @@ nsDocument::RequestFullScreen(Element* a
     return;
   }
   if (!IsFullScreenEnabled(aWasCallerChrome, true)) {
     // IsFullScreenEnabled calls LogFullScreenDenied, no need to log.
     return;
   }
   if (GetFullScreenElement() &&
       !nsContentUtils::ContentIsDescendantOf(aElement, GetFullScreenElement())) {
-    // If this document is full-screen, only grant full-screen requests from 
+    // If this document is full-screen, only grant full-screen requests from
     // a descendent of the current full-screen element.
     LogFullScreenDenied(true, "FullScreenDeniedNotDescendant", this);
     return;
   }
   if (!nsContentUtils::IsChromeDoc(this) && !IsInActiveTab(this)) {
     LogFullScreenDenied(true, "FullScreenDeniedNotFocusedTab", this);
     return;
   }
@@ -8953,22 +9056,22 @@ nsDocument::RequestFullScreen(Element* a
   // too. We're required by the spec to dispatch the events in root-to-leaf
   // order, but we traverse the doctree in a leaf-to-root order, so we save
   // references to the documents we must dispatch to so that we get the order
   // as specified.
   nsAutoTArray<nsIDocument*, 8> changed;
 
   // Remember the root document, so that if a full-screen document is hidden
   // we can reset full-screen state in the remaining visible full-screen documents.
-  nsIDocument* fullScreenDoc = nsContentUtils::GetRootDocument(this);
-  sFullScreenRootDoc = do_GetWeakReference(fullScreenDoc);
+  nsIDocument* fullScreenRootDoc = nsContentUtils::GetRootDocument(this);
+  sFullScreenRootDoc = do_GetWeakReference(fullScreenRootDoc);
 
   // If a document is already in fullscreen, then unlock the mouse pointer
   // before setting a new document to fullscreen
-  if (fullScreenDoc) {
+  if (sFullScreenDoc) {
     UnlockPointer();
   }
 
   // If a document is already in fullscreen, then unlock the mouse pointer
   // before setting a new document to fullscreen
   nsCOMPtr<Element> pointerLockedElement =
     do_QueryReferent(nsEventStateManager::sPointerLockedElement);
   if (pointerLockedElement) {
@@ -8976,25 +9079,28 @@ nsDocument::RequestFullScreen(Element* a
   }
 
   // Set the full-screen element. This sets the full-screen style on the
   // element, and the full-screen-ancestor styles on ancestors of the element
   // in this document.
   DebugOnly<bool> x = FullScreenStackPush(aElement);
   NS_ASSERTION(x, "Full-screen state of requesting doc should always change!");
   changed.AppendElement(this);
-  
+
   // Propagate up the document hierarchy, setting the full-screen element as
   // the element's container in ancestor documents. This also sets the
   // appropriate css styles as well. Note we don't propagate down the
   // document hierarchy, the full-screen element (or its container) is not
-  // visible there.  
+  // visible there. Stop when we reach the root document.
   nsIDocument* child = this;
-  nsIDocument* parent;
-  while ((parent = child->GetParentDocument())) {
+  while (true) {
+    nsIDocument* parent = child->GetParentDocument();
+    if (!parent) {
+      break;
+    }
     Element* element = parent->FindContentForSubDocument(child)->AsElement();
     if (static_cast<nsDocument*>(parent)->FullScreenStackPush(element)) {
       changed.AppendElement(parent);
       child = parent;
     } else {
       // We've reached either the root, or a point in the doctree where the
       // new full-screen element container is the same as the previous
       // full-screen element's container. No more changes need to be made
@@ -9007,20 +9113,22 @@ nsDocument::RequestFullScreen(Element* a
   // order so that the events for the root document arrives before the leaf
   // document, as required by the spec.
   for (PRUint32 i = 0; i < changed.Length(); ++i) {
     DispatchFullScreenChange(changed[changed.Length() - i - 1]);
   }
 
   // If this document hasn't already been approved in this session,
   // check to see if the user has granted the fullscreen access
-  // to the document's principal's host, if it has one.
+  // to the document's principal's host, if it has one. Note that documents
+  // in web apps which are the same origin as the web app are considered
+  // trusted and so are automatically approved.
   if (!mIsApprovedForFullscreen) {
     mIsApprovedForFullscreen =
-      GetWindow()->IsPartOfApp() ||
+      GetWindow()->IsInAppOrigin() ||
       nsContentUtils::IsSitePermAllow(NodePrincipal(), "fullscreen");
   }
 
   // If this document, or a document with the same principal has not
   // already been approved for fullscreen this fullscreen-session, dispatch
   // an event so that chrome knows to pop up a warning/approval UI.
   nsCOMPtr<nsIDocument> previousFullscreenDoc(do_QueryReferent(sFullScreenDoc));
   // Note previousFullscreenDoc=nullptr upon first entry, so we always
@@ -9047,16 +9155,31 @@ nsDocument::RequestFullScreen(Element* a
   NS_ASSERTION(IsFullScreenDoc(), "Should be full-screen doc");
   nsCOMPtr<nsIDOMElement> fse;
   GetMozFullScreenElement(getter_AddRefs(fse));
   nsCOMPtr<nsIContent> c(do_QueryInterface(fse));
   NS_ASSERTION(c->AsElement() == aElement,
     "GetMozFullScreenElement should match GetFullScreenElement()");
 #endif
 
+  // The origin which is fullscreen changed, send a notifiction so that the
+  // root document knows the origin of the document which requested fullscreen.
+  // This is used for the fullscreen approval UI. If we're in a child
+  // process, the root BrowserElementChild listens for this notification,
+  // and forwards it across to its BrowserElementParent, which
+  // re-broadcasts the message for the root document in its process.
+  if (aNotifyOnOriginChange &&
+      !nsContentUtils::HaveEqualPrincipals(previousFullscreenDoc, this)) {
+    nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
+    nsIDocument* root = nsContentUtils::GetRootDocument(this);
+    nsAutoString origin;
+    nsContentUtils::GetUTFOrigin(NodePrincipal(), origin);
+    os->NotifyObservers(root, "fullscreen-origin-change", origin.get());
+  }
+
   // Make the window full-screen. Note we must make the state changes above
   // before making the window full-screen, as then the document reports as
   // being in full-screen mode when the chrome "fullscreen" event fires,
   // enabling chrome to distinguish between browser and dom full-screen
   // modes. Also note that nsGlobalWindow::SetFullScreen() (which
   // SetWindowFullScreen() calls) proxies to the root window in its hierarchy,
   // and does not operate on the a per-nsIDOMWindow basis.
   SetWindowFullScreen(this, true);
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -932,24 +932,36 @@ public:
     return mHasAudioAvailableListener;
   }
 
   virtual Element* GetFullScreenElement();
   virtual void AsyncRequestFullScreen(Element* aElement);
   virtual void RestorePreviousFullScreenState();
   virtual bool IsFullScreenDoc();
   virtual void SetApprovedForFullscreen(bool aIsApproved);
+  virtual nsresult RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
+                                                const nsAString& aNewOrigin);
+
+  virtual nsresult RemoteFrameFullscreenReverted();
 
   static void ExitFullScreen();
 
   // This is called asynchronously by nsIDocument::AsyncRequestFullScreen()
-  // to move document into full-screen mode if allowed. aWasCallerChrome
+  // to move this document into full-screen mode if allowed. aWasCallerChrome
   // should be true when nsIDocument::AsyncRequestFullScreen() was called
-  // by chrome code.
-  void RequestFullScreen(Element* aElement, bool aWasCallerChrome);
+  // by chrome code. aNotifyOnOriginChange denotes whether we should send a
+  // fullscreen-origin-change notification if requesting fullscreen in this
+  // document causes the origin which is fullscreen to change. We may want to
+  // *not* send this notification if we're calling RequestFullscreen() as part
+  // of a continuation of a request in a subdocument, whereupon the caller will
+  // need to send the notification with the origin of the document which
+  // originally requested fullscreen, not *this* document's origin.
+  void RequestFullScreen(Element* aElement,
+                         bool aWasCallerChrome,
+                         bool aNotifyOnOriginChange);
 
   // Removes all elements from the full-screen stack, removing full-scren
   // styles from the top element in the stack.
   void CleanupFullscreenState();
 
   // Add/remove "fullscreen-approved" observer service notification listener.
   // Chrome sends us a notification when fullscreen is approved for a
   // document, with the notification subject as the document that was approved.
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -2337,8 +2337,9 @@ nsFrameLoader::SetRemoteBrowser(nsITabPa
   EnsureMessageManager();
   nsCOMPtr<nsIObserverService> os = services::GetObserverService();
   if (OwnerIsBrowserFrame() && os) {
     mRemoteBrowserInitialized = true;
     os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
                         "remote-browser-frame-shown", NULL);
   }
 }
+
--- a/content/base/src/nsFrameLoader.h
+++ b/content/base/src/nsFrameLoader.h
@@ -16,17 +16,17 @@
 #include "nsIFrameLoader.h"
 #include "nsPoint.h"
 #include "nsSize.h"
 #include "nsIURI.h"
 #include "nsAutoPtr.h"
 #include "nsFrameMessageManager.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/Attributes.h"
-#include "Layers.h"
+#include "FrameMetrics.h"
 
 class nsIURI;
 class nsSubDocumentFrame;
 class nsIView;
 class nsIInProcessContentFrameMessageManager;
 class AutoResetInShow;
 class nsITabParent;
 
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -4757,38 +4757,44 @@ nsGenericElement::MozRequestPointerLock(
   OwnerDoc()->RequestPointerLock(this);
   return NS_OK;
 }
 
 static const char*
 GetFullScreenError(nsIDocument* aDoc)
 {
   nsCOMPtr<nsPIDOMWindow> win = aDoc->GetWindow();
-  if (win && win->IsPartOfApp()) {
+  if (win && win->IsInAppOrigin()) {
+    // Request is in a web app and in the same origin as the web app.
+    // Don't enforce as strict security checks for web apps, the user
+    // is supposed to have trust in them. However documents cross-origin
+    // to the web app must still confirm to the normal security checks.
     return nullptr;
   }
 
   if (!nsContentUtils::IsRequestFullScreenAllowed()) {
     return "FullScreenDeniedNotInputDriven";
   }
-  
+
   if (nsContentUtils::IsSitePermDeny(aDoc->NodePrincipal(), "fullscreen")) {
     return "FullScreenDeniedBlocked";
   }
 
   return nullptr;
 }
 
 nsresult nsGenericElement::MozRequestFullScreen()
 {
   // Only grant full-screen requests if this is called from inside a trusted
   // event handler (i.e. inside an event handler for a user initiated event).
   // This stops the full-screen from being abused similar to the popups of old,
   // and it also makes it harder for bad guys' script to go full-screen and
   // spoof the browser chrome/window and phish logins etc.
+  // Note that requests for fullscreen inside a web app's origin are exempt
+  // from this restriction.
   const char* error = GetFullScreenError(OwnerDoc());
   if (error) {
     nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
                                     "DOM", OwnerDoc(),
                                     nsContentUtils::eDOM_PROPERTIES,
                                     error);
     nsRefPtr<nsAsyncDOMEvent> e =
       new nsAsyncDOMEvent(OwnerDoc(),
@@ -4798,8 +4804,9 @@ nsresult nsGenericElement::MozRequestFul
     e->PostDOMEvent();
     return NS_OK;
   }
 
   OwnerDoc()->AsyncRequestFullScreen(this);
 
   return NS_OK;
 }
+
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -1016,17 +1016,20 @@ nsresult                                
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;                                     \
   _elementName *it = new _elementName(ni.forget());                         \
   if (!it) {                                                                \
     return NS_ERROR_OUT_OF_MEMORY;                                          \
   }                                                                         \
                                                                             \
   nsCOMPtr<nsINode> kungFuDeathGrip = it;                                   \
   nsresult rv = it->Init();                                                 \
-  rv |= const_cast<_elementName*>(this)->CopyInnerTo(it);                   \
+  nsresult rv2 = const_cast<_elementName*>(this)->CopyInnerTo(it);          \
+  if (NS_FAILED(rv2)) {                                                     \
+    rv = rv2;                                                               \
+  }                                                                         \
   if (NS_SUCCEEDED(rv)) {                                                   \
     kungFuDeathGrip.swap(*aResult);                                         \
   }                                                                         \
                                                                             \
   return rv;                                                                \
 }
 
 #define DOMCI_NODE_DATA(_interface, _class)                             \
@@ -1043,17 +1046,18 @@ nsresult                                
  * SetAttr methods.  We use the 5-argument form of SetAttr, because
  * some consumers only implement that one, hiding superclass
  * 4-argument forms.
  */
 #define NS_IMPL_STRING_ATTR(_class, _method, _atom)                     \
   NS_IMETHODIMP                                                         \
   _class::Get##_method(nsAString& aValue)                               \
   {                                                                     \
-    return GetAttr(kNameSpaceID_None, nsGkAtoms::_atom, aValue);        \
+    GetAttr(kNameSpaceID_None, nsGkAtoms::_atom, aValue);               \
+    return NS_OK;                                                       \
   }                                                                     \
   NS_IMETHODIMP                                                         \
   _class::Set##_method(const nsAString& aValue)                         \
   {                                                                     \
     return SetAttr(kNameSpaceID_None, nsGkAtoms::_atom, nullptr, aValue, true); \
   }
 
 /**
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1699,17 +1699,16 @@ GK_ATOM(imageBoxFrame, "ImageBoxFrame")
 GK_ATOM(imageFrame, "ImageFrame")
 GK_ATOM(imageControlFrame, "ImageControlFrame")
 GK_ATOM(inlineFrame, "InlineFrame")
 GK_ATOM(leafBoxFrame, "LeafBoxFrame")
 GK_ATOM(legendFrame, "LegendFrame")
 GK_ATOM(letterFrame, "LetterFrame")
 GK_ATOM(lineFrame, "LineFrame")
 GK_ATOM(listControlFrame,"ListControlFrame")
-GK_ATOM(menuBarFrame,"MenuBarFrame")
 GK_ATOM(menuFrame,"MenuFrame")
 GK_ATOM(menuPopupFrame,"MenuPopupFrame")
 GK_ATOM(objectFrame, "ObjectFrame")
 GK_ATOM(pageFrame, "PageFrame")
 GK_ATOM(pageBreakFrame, "PageBreakFrame")
 GK_ATOM(pageContentFrame, "PageContentFrame")
 GK_ATOM(placeholderFrame, "PlaceholderFrame")
 GK_ATOM(popupSetFrame, "PopupSetFrame")
--- a/content/base/src/nsHTMLContentSerializer.cpp
+++ b/content/base/src/nsHTMLContentSerializer.cpp
@@ -236,17 +236,17 @@ nsHTMLContentSerializer::AppendElementSt
   if (mIsCopying && name == nsGkAtoms::ol && ns == kNameSpaceID_XHTML){
     // We are copying and current node is an OL;
     // Store its start attribute value in olState->startVal.
     nsAutoString start;
     PRInt32 startAttrVal = 0;
 
     aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::start, start);
     if (!start.IsEmpty()){
-      PRInt32 rv = 0;
+      nsresult rv = NS_OK;
       startAttrVal = start.ToInteger(&rv);
       //If OL has "start" attribute, first LI element has to start with that value
       //Therefore subtracting 1 as all the LI elements are incrementing it before using it;
       //In failure of ToInteger(), default StartAttrValue to 0.
       if (NS_SUCCEEDED(rv))
         startAttrVal--; 
       else
         startAttrVal = 0;
--- a/content/base/src/nsPlainTextSerializer.cpp
+++ b/content/base/src/nsPlainTextSerializer.cpp
@@ -475,17 +475,17 @@ nsPlainTextSerializer::DoOpenContainer(n
           // considers 'c' to be a valid numeric char (even if radix=10)
           // but then gets confused if it sees it next to the number
           // when the radix specified was 10, and returns an error code.
           PRInt32 semiOffset = style.Find("ch", false, widthOffset+6);
           PRInt32 length = (semiOffset > 0 ? semiOffset - widthOffset - 6
                             : style.Length() - widthOffset);
           nsAutoString widthstr;
           style.Mid(widthstr, widthOffset+6, length);
-          PRInt32 err;
+          nsresult err;
           PRInt32 col = widthstr.ToInteger(&err);
 
           if (NS_SUCCEEDED(err)) {
             mWrapColumn = (PRUint32)col;
 #ifdef DEBUG_preformatted
             printf("Set wrap column to %d based on style\n", mWrapColumn);
 #endif
           }
@@ -558,17 +558,17 @@ nsPlainTextSerializer::DoOpenContainer(n
   else if (aTag == nsGkAtoms::ol) {
     EnsureVerticalSpace(mULCount + mOLStackIndex == 0 ? 1 : 0);
     if (mFlags & nsIDocumentEncoder::OutputFormatted) {
       // Must end the current line before we change indention
       if (mOLStackIndex < OLStackSize) {
         nsAutoString startAttr;
         PRInt32 startVal = 1;
         if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::start, startAttr))) {
-          PRInt32 rv = 0;
+          nsresult rv = NS_OK;
           startVal = startAttr.ToInteger(&rv);
           if (NS_FAILED(rv))
             startVal = 1;
         }
         mOLStack[mOLStackIndex++] = startVal;
       }
     } else {
       mOLStackIndex++;
@@ -576,17 +576,17 @@ nsPlainTextSerializer::DoOpenContainer(n
     mIndent += kIndentSizeList;  // see ul
   }
   else if (aTag == nsGkAtoms::li &&
            (mFlags & nsIDocumentEncoder::OutputFormatted)) {
     if (mTagStackIndex > 1 && IsInOL()) {
       if (mOLStackIndex > 0) {
         nsAutoString valueAttr;
         if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::value, valueAttr))) {
-          PRInt32 rv = 0;
+          nsresult rv = NS_OK;
           PRInt32 valueAttrVal = valueAttr.ToInteger(&rv);
           if (NS_SUCCEEDED(rv))
             mOLStack[mOLStackIndex-1] = valueAttrVal;
         }
         // This is what nsBulletFrame does for OLs:
         mInIndentString.AppendInt(mOLStack[mOLStackIndex-1]++, 10);
       }
       else {
--- a/content/base/src/nsXHTMLContentSerializer.cpp
+++ b/content/base/src/nsXHTMLContentSerializer.cpp
@@ -249,17 +249,17 @@ nsXHTMLContentSerializer::SerializeAttri
     // for the LI.
     if (aTagName == nsGkAtoms::ol) {
       // We are copying and current node is an OL;
       // Store its start attribute value in olState->startVal.
       nsAutoString start;
       PRInt32 startAttrVal = 0;
       aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::start, start);
       if (!start.IsEmpty()) {
-        PRInt32 rv = 0;
+        nsresult rv = NS_OK;
         startAttrVal = start.ToInteger(&rv);
         //If OL has "start" attribute, first LI element has to start with that value
         //Therefore subtracting 1 as all the LI elements are incrementing it before using it;
         //In failure of ToInteger(), default StartAttrValue to 0.
         if (NS_SUCCEEDED(rv))
           --startAttrVal;
         else
           startAttrVal = 0;
@@ -915,17 +915,17 @@ nsXHTMLContentSerializer::SerializeLIVal
       nsAutoString tagName;
       currElement->GetTagName(tagName);
       if (tagName.LowerCaseEqualsLiteral("li")) {
         currElement->GetAttribute(NS_LITERAL_STRING("value"), valueStr);
         if (valueStr.IsEmpty())
           offset++;
         else {
           found = true;
-          PRInt32 rv = 0;
+          nsresult rv = NS_OK;
           startVal = valueStr.ToInteger(&rv);
         }
       }
     }
     nsCOMPtr<nsIDOMNode> tmp;
     currNode->GetPreviousSibling(getter_AddRefs(tmp));
     currNode.swap(tmp);
   }
--- a/content/base/src/nsXMLNameSpaceMap.cpp
+++ b/content/base/src/nsXMLNameSpaceMap.cpp
@@ -31,21 +31,21 @@ class nsDefaultComparator <nsNameSpaceEn
 
 /* static */ nsXMLNameSpaceMap*
 nsXMLNameSpaceMap::Create(bool aForXML)
 {
   nsXMLNameSpaceMap *map = new nsXMLNameSpaceMap();
   NS_ENSURE_TRUE(map, nullptr);
 
   if (aForXML) {
-    nsresult rv = map->AddPrefix(nsGkAtoms::xmlns,
-                                 kNameSpaceID_XMLNS);
-    rv |= map->AddPrefix(nsGkAtoms::xml, kNameSpaceID_XML);
+    nsresult rv1 = map->AddPrefix(nsGkAtoms::xmlns,
+                                  kNameSpaceID_XMLNS);
+    nsresult rv2 = map->AddPrefix(nsGkAtoms::xml, kNameSpaceID_XML);
 
-    if (NS_FAILED(rv)) {
+    if (NS_FAILED(rv1) || NS_FAILED(rv2)) {
       delete map;
       map = nullptr;
     }
   }
 
   return map;
 }
 
--- a/content/base/test/test_bug708620.html
+++ b/content/base/test/test_bug708620.html
@@ -27,21 +27,27 @@ var tests = [
 ];
 
 function resolveURL(relative) {
   var a = document.createElement('a');
   a.href = relative;
   return a.href;
 }
 
+var resolvedURL = resolveURL(tests[0]);
+
 var expectedErrors = [
-  '[JavaScript Warning: "A form was submitted in the windows-1252 encoding which cannot encode all Unicode characters, so user input may get corrupted. To avoid this problem, the page should be changed so that the form is submitted in the UTF-8 encoding either by changing the encoding of the page itself to UTF-8 or by specifying accept-charset=utf-8 on the form element." {file: "' + resolveURL(tests[0]) + '" line: 1}]'
+  '[JavaScript Warning: "A form was submitted in the windows-1252 encoding which cannot encode all Unicode characters, so user input may get corrupted. To avoid this problem, the page should be changed so that the form is submitted in the UTF-8 encoding either by changing the encoding of the page itself to UTF-8 or by specifying accept-charset=utf-8 on the form element." {file: "' + resolvedURL + '" line: 1}]'
 ];
 
-function consoleError(msg) {
+function consoleError(msg, fileName) {
+  // Ignore messages not generated by the test
+  if (fileName !== resolvedURL) {
+    return;
+  }
   var expected = expectedErrors.shift();
   is(msg, expected, "Not the right error message");
 }
 
 SpecialPowers.addErrorConsoleListener(consoleError);
 
 function start() {
   var url = tests.shift();
--- a/content/canvas/src/CustomQS_Canvas2D.h
+++ b/content/canvas/src/CustomQS_Canvas2D.h
@@ -13,117 +13,117 @@
 #include "jsfriendapi.h"
 
 typedef NS_STDCALL_FUNCPROTO(nsresult, CanvasStyleSetterType, nsIDOMCanvasRenderingContext2D,
                              SetStrokeStyle_multi, (const nsAString &, nsISupports *));
 typedef NS_STDCALL_FUNCPROTO(nsresult, CanvasStyleGetterType, nsIDOMCanvasRenderingContext2D,
                              GetStrokeStyle_multi, (nsAString &, nsISupports **, PRInt32 *));
 
 static JSBool
-Canvas2D_SetStyleHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
+Canvas2D_SetStyleHelper(JSContext *cx, JSObject *obj, jsid id, JSMutableHandleValue vp,
                         CanvasStyleSetterType setfunc)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     nsIDOMCanvasRenderingContext2D *self;
     xpc_qsSelfRef selfref;
     JS::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, &self, &selfref.ptr, tvr.jsval_addr(), nullptr))
         return JS_FALSE;
 
     nsresult rv = NS_OK;
-    if (JSVAL_IS_STRING(*vp)) {
-        xpc_qsDOMString arg0(cx, *vp, vp,
+    if (JSVAL_IS_STRING(vp)) {
+        xpc_qsDOMString arg0(cx, vp, vp.address(),
                              xpc_qsDOMString::eDefaultNullBehavior,
                              xpc_qsDOMString::eDefaultUndefinedBehavior);
         if (!arg0.IsValid())
             return JS_FALSE;
 
         rv = (self->*setfunc)(arg0, nullptr);
     } else {
         nsISupports *arg0;
         xpc_qsSelfRef arg0ref;
-        rv = xpc_qsUnwrapArg<nsISupports>(cx, *vp, &arg0, &arg0ref.ptr, vp);
+        rv = xpc_qsUnwrapArg<nsISupports>(cx, vp, &arg0, &arg0ref.ptr, vp.address());
         if (NS_FAILED(rv)) {
             xpc_qsThrowBadSetterValue(cx, rv, JSVAL_TO_OBJECT(*tvr.jsval_addr()), id);
             return JS_FALSE;
         }
 
         rv = (self->*setfunc)(NullString(), arg0);
     }
 
     if (NS_FAILED(rv))
         return xpc_qsThrowGetterSetterFailed(cx, rv, JSVAL_TO_OBJECT(*tvr.jsval_addr()), id);
 
     return JS_TRUE;
 }
 
 static JSBool
-Canvas2D_GetStyleHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
+Canvas2D_GetStyleHelper(JSContext *cx, JSObject *obj, jsid id, JSMutableHandleValue vp,
                         CanvasStyleGetterType getfunc)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     nsIDOMCanvasRenderingContext2D *self;
     xpc_qsSelfRef selfref;
     XPCLazyCallContext lccx(JS_CALLER, cx, obj);
-    if (!xpc_qsUnwrapThis(cx, obj, &self, &selfref.ptr, vp, &lccx))
+    if (!xpc_qsUnwrapThis(cx, obj, &self, &selfref.ptr, vp.address(), &lccx))
         return JS_FALSE;
     nsresult rv;
 
     nsString resultString;
     nsCOMPtr<nsISupports> resultInterface;
     PRInt32 resultType;
     rv = (self->*getfunc)(resultString, getter_AddRefs(resultInterface), &resultType);
     if (NS_FAILED(rv))
-        return xpc_qsThrowGetterSetterFailed(cx, rv, JSVAL_TO_OBJECT(*vp), id);
+        return xpc_qsThrowGetterSetterFailed(cx, rv, JSVAL_TO_OBJECT(vp), id);
 
     switch (resultType) {
     case nsIDOMCanvasRenderingContext2D::CMG_STYLE_STRING:
-        return xpc::StringToJsval(cx, resultString, vp);
+        return xpc::StringToJsval(cx, resultString, vp.address());
 
     case nsIDOMCanvasRenderingContext2D::CMG_STYLE_PATTERN:
     {
         qsObjectHelper helper(resultInterface,
                               xpc_qsGetWrapperCache(resultInterface));
         return xpc_qsXPCOMObjectToJsval(lccx, helper,
                                         &NS_GET_IID(nsIDOMCanvasPattern),
-                                        &interfaces[k_nsIDOMCanvasPattern], vp);
+                                        &interfaces[k_nsIDOMCanvasPattern], vp.address());
     }
     case nsIDOMCanvasRenderingContext2D::CMG_STYLE_GRADIENT:
     {
         qsObjectHelper helper(resultInterface,
                               xpc_qsGetWrapperCache(resultInterface));
         return xpc_qsXPCOMObjectToJsval(lccx, helper,
                                         &NS_GET_IID(nsIDOMCanvasGradient),
-                                        &interfaces[k_nsIDOMCanvasGradient], vp);
+                                        &interfaces[k_nsIDOMCanvasGradient], vp.address());
     }
     default:
-        return xpc_qsThrowGetterSetterFailed(cx, NS_ERROR_FAILURE, JSVAL_TO_OBJECT(*vp), id);
+        return xpc_qsThrowGetterSetterFailed(cx, NS_ERROR_FAILURE, JSVAL_TO_OBJECT(vp), id);
     }
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_SetStrokeStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, jsval *vp)
+nsIDOMCanvasRenderingContext2D_SetStrokeStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp)
 {
     return Canvas2D_SetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::SetStrokeStyle_multi);
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_GetStrokeStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, jsval *vp)
+nsIDOMCanvasRenderingContext2D_GetStrokeStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp)
 {
     return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetStrokeStyle_multi);
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_SetFillStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, jsval *vp)
+nsIDOMCanvasRenderingContext2D_SetFillStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp)
 {
     return Canvas2D_SetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::SetFillStyle_multi);
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_GetFillStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, jsval *vp)
+nsIDOMCanvasRenderingContext2D_GetFillStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp)
 {
     return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetFillStyle_multi);
 }
 
 static bool
 CreateImageData(JSContext* cx, JSObject* obj, uint32_t w, uint32_t h, jsval* vp)
 {
     using mozilla::CheckedInt;
--- a/content/html/content/public/nsHTMLCanvasElement.h
+++ b/content/html/content/public/nsHTMLCanvasElement.h
@@ -12,22 +12,27 @@
 #include "nsSize.h"
 #include "nsIFrame.h"
 #include "nsDOMError.h"
 #include "nsNodeInfoManager.h"
 
 #include "nsICanvasElementExternal.h"
 #include "nsLayoutUtils.h"
 
-#include "Layers.h"
-
 class nsICanvasRenderingContextInternal;
 class nsIDOMFile;
 class nsIPropertyBag;
 
+namespace mozilla {
+namespace layers {
+class CanvasLayer;
+class LayerManager;
+}
+}
+
 class nsHTMLCanvasElement : public nsGenericHTMLElement,
                             public nsICanvasElementExternal,
                             public nsIDOMHTMLCanvasElement
 {
   typedef mozilla::layers::CanvasLayer CanvasLayer;
   typedef mozilla::layers::LayerManager LayerManager;
 
 public:
--- a/content/html/content/public/nsHTMLMediaElement.h
+++ b/content/html/content/public/nsHTMLMediaElement.h
@@ -11,16 +11,17 @@
 #include "nsMediaDecoder.h"
 #include "nsIChannel.h"
 #include "nsIHttpChannel.h"
 #include "nsThreadUtils.h"
 #include "nsIDOMRange.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsILoadGroup.h"
 #include "nsIObserver.h"
+#include "nsDataHashtable.h"
 #include "nsAudioStream.h"
 #include "VideoFrameContainer.h"
 #include "mozilla/CORSMode.h"
 #include "nsDOMMediaStream.h"
 #include "mozilla/Mutex.h"
 #include "nsTimeRanges.h"
 
 // Define to output information on decoding and painting framerate
@@ -38,16 +39,18 @@ class nsHTMLMediaElement : public nsGene
 {
 public:
   typedef mozilla::TimeStamp TimeStamp;
   typedef mozilla::layers::ImageContainer ImageContainer;
   typedef mozilla::VideoFrameContainer VideoFrameContainer;
   typedef mozilla::MediaStream MediaStream;
   typedef mozilla::MediaResource MediaResource;
 
+  typedef nsDataHashtable<nsCStringHashKey, nsCString> MetadataTags;
+
   enum CanPlayStatus {
     CANPLAY_NO,
     CANPLAY_MAYBE,
     CANPLAY_YES
   };
 
   mozilla::CORSMode GetCORSMode() {
     return mCORSMode;
@@ -104,17 +107,20 @@ public:
    * Call this to reevaluate whether we should start/stop due to our owner
    * document being active or inactive.
    */
   void NotifyOwnerDocumentActivityChanged();
 
   // Called by the video decoder object, on the main thread,
   // when it has read the metadata containing video dimensions,
   // etc.
-  void MetadataLoaded(PRUint32 aChannels, PRUint32 aRate, bool aHasAudio);
+  void MetadataLoaded(PRUint32 aChannels,
+                      PRUint32 aRate,
+                      bool aHasAudio,
+                      const MetadataTags* aTags);
 
   // Called by the video decoder object, on the main thread,
   // when it has read the first frame of the video
   // aResourceFullyLoaded should be true if the resource has been
   // fully loaded and the caller will call ResourceLoaded next.
   void FirstFrameLoaded(bool aResourceFullyLoaded);
 
   // Called by the video decoder object, on the main thread,
@@ -695,16 +701,23 @@ protected:
   double mVolume;
 
   // Current number of audio channels.
   PRUint32 mChannels;
 
   // Current audio sample rate.
   PRUint32 mRate;
 
+  // Helper function to iterate over a hash table
+  // and convert it to a JSObject.
+  static PLDHashOperator BuildObjectFromTags(nsCStringHashKey::KeyType aKey,
+                                             nsCString aValue,
+                                             void* aUserArg);
+  nsAutoPtr<const MetadataTags> mTags;
+
   // URI of the resource we're attempting to load. This stores the value we
   // return in the currentSrc attribute. Use GetCurrentSrc() to access the
   // currentSrc attribute.
   // This is always the original URL we're trying to load --- before
   // redirects etc.
   nsCOMPtr<nsIURI> mLoadingSrc;
   
   // Stores the current preload action for this element. Initially set to
--- a/content/html/content/src/nsHTMLAudioElement.cpp
+++ b/content/html/content/src/nsHTMLAudioElement.cpp
@@ -118,17 +118,17 @@ nsHTMLAudioElement::MozSetup(PRUint32 aC
   nsresult rv = mAudioStream->Init(aChannels, aRate,
                                    nsAudioStream::FORMAT_FLOAT32);
   if (NS_FAILED(rv)) {
     mAudioStream->Shutdown();
     mAudioStream = nullptr;
     return rv;
   }
 
-  MetadataLoaded(aChannels, aRate, true);
+  MetadataLoaded(aChannels, aRate, true, nullptr);
   mAudioStream->SetVolume(mVolume);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLAudioElement::MozWriteAudio(const JS::Value& aData, JSContext* aCx, PRUint32* aRetVal)
 {
   if (!mAudioStream) {
@@ -180,21 +180,25 @@ nsHTMLAudioElement::MozWriteAudio(const 
 
 NS_IMETHODIMP
 nsHTMLAudioElement::MozCurrentSampleOffset(PRUint64 *aRetVal)
 {
   if (!mAudioStream) {
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
 
-  *aRetVal = mAudioStream->GetPositionInFrames() * mChannels;
+  PRInt64 position = mAudioStream->GetPositionInFrames();
+  if (position < 0) {
+    *aRetVal = 0;
+  } else {
+    *aRetVal = mAudioStream->GetPositionInFrames() * mChannels;
+  }
   return NS_OK;
 }
 
-  
 nsresult nsHTMLAudioElement::SetAcceptHeader(nsIHttpChannel* aChannel)
 {
     nsCAutoString value(
 #ifdef MOZ_WEBM
       "audio/webm,"
 #endif
 #ifdef MOZ_OGG
       "audio/ogg,"
--- a/content/html/content/src/nsHTMLFormElement.cpp
+++ b/content/html/content/src/nsHTMLFormElement.cpp
@@ -1789,17 +1789,17 @@ nsHTMLFormElement::UpdateValidity(bool a
   UpdateState(true);
 }
 
 // nsIWebProgressListener
 NS_IMETHODIMP
 nsHTMLFormElement::OnStateChange(nsIWebProgress* aWebProgress,
                                  nsIRequest* aRequest,
                                  PRUint32 aStateFlags,
-                                 PRUint32 aStatus)
+                                 nsresult aStatus)
 {
   // If STATE_STOP is never fired for any reason (redirect?  Failed state
   // change?) the form element will leak.  It will be kept around by the
   // nsIWebProgressListener (assuming it keeps a strong pointer).  We will
   // consequently leak the request.
   if (aRequest == mSubmittingRequest &&
       aStateFlags & nsIWebProgressListener::STATE_STOP) {
     ForgetCurrentSubmission();
--- a/content/html/content/src/nsHTMLFrameSetElement.cpp
+++ b/content/html/content/src/nsHTMLFrameSetElement.cpp
@@ -270,17 +270,17 @@ nsHTMLFrameSetElement::ParseRowCol(const
 
       // Treat * as 1*
       if ((eFramesetUnit_Relative == specs[i].mUnit) &&
         (0 == token.Length())) {
         specs[i].mValue = 1;
       }
       else {
         // Otherwise just convert to integer.
-        PRInt32 err;
+        nsresult err;
         specs[i].mValue = token.ToInteger(&err);
         if (err) {
           specs[i].mValue = 0;
         }
       }
 
       // Treat 0* as 1* in quirks mode (bug 40383)
       if (isInQuirks) {
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -1000,17 +1000,17 @@ nsHTMLInputElement::IsValueEmpty() const
   return value.IsEmpty();
 }
 
 double
 nsHTMLInputElement::GetValueAsDouble() const
 {
   double doubleValue;
   nsAutoString stringValue;
-  PRInt32 ec;
+  nsresult ec;
 
   GetValueInternal(stringValue);
   doubleValue = stringValue.ToDouble(&ec);
 
   return NS_SUCCEEDED(ec) ? doubleValue : MOZ_DOUBLE_NaN();
 }
 
 NS_IMETHODIMP 
@@ -1102,17 +1102,17 @@ nsHTMLInputElement::GetMinAsDouble() con
 
   if (!HasAttr(kNameSpaceID_None, nsGkAtoms::min)) {
     return MOZ_DOUBLE_NaN();
   }
 
   nsAutoString minStr;
   GetAttr(kNameSpaceID_None, nsGkAtoms::min, minStr);
 
-  PRInt32 ec;
+  nsresult ec;
   double min = minStr.ToDouble(&ec);
   return NS_SUCCEEDED(ec) ? min : MOZ_DOUBLE_NaN();
 }
 
 double
 nsHTMLInputElement::GetMaxAsDouble() const
 {
   // Should only be used for <input type='number'> for the moment.
@@ -1120,17 +1120,17 @@ nsHTMLInputElement::GetMaxAsDouble() con
 
   if (!HasAttr(kNameSpaceID_None, nsGkAtoms::max)) {
     return MOZ_DOUBLE_NaN();
   }
 
   nsAutoString maxStr;
   GetAttr(kNameSpaceID_None, nsGkAtoms::max, maxStr);
 
-  PRInt32 ec;
+  nsresult ec;
   double max = maxStr.ToDouble(&ec);
   return NS_SUCCEEDED(ec) ? max : MOZ_DOUBLE_NaN();
 }
 
 double
 nsHTMLInputElement::GetStepBase() const
 {
   double stepBase = GetMinAsDouble();
@@ -2656,17 +2656,17 @@ nsHTMLInputElement::SanitizeValue(nsAStr
         PRUnichar crlf[] = { PRUnichar('\r'), PRUnichar('\n'), 0 };
         aValue.StripChars(crlf);
 
         aValue = nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aValue);
       }
       break;
     case NS_FORM_INPUT_NUMBER:
       {
-        PRInt32 ec;
+        nsresult ec;
         PromiseFlatString(aValue).ToDouble(&ec);
         if (NS_FAILED(ec)) {
           aValue.Truncate();
         }
       }
       break;
   }
 }
@@ -3322,17 +3322,20 @@ nsHTMLInputElement::SaveState()
   if (inputState) {
     rv = GetPrimaryPresState(this, &state);
     if (state) {
       state->SetStateProperty(inputState);
     }
   }
 
   if (mDisabledChanged) {
-    rv |= GetPrimaryPresState(this, &state);
+    nsresult tmp = GetPrimaryPresState(this, &state);
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
     if (state) {
       // We do not want to save the real disabled state but the disabled
       // attribute.
       state->SetDisabled(HasAttr(kNameSpaceID_None, nsGkAtoms::disabled));
     }
   }
 
   return rv;
@@ -3855,17 +3858,17 @@ nsHTMLInputElement::GetStep() const
     nsAutoString stepStr;
     GetAttr(kNameSpaceID_None, nsGkAtoms::step, stepStr);
 
     if (stepStr.LowerCaseEqualsLiteral("any")) {
       // The element can't suffer from step mismatch if there is no step.
       return kStepAny;
     }
 
-    PRInt32 ec;
+    nsresult ec;
     // NOTE: should be multiplied by defaultStepScaleFactor,
     // which is 1 for type=number.
     step = stepStr.ToDouble(&ec);
     if (NS_FAILED(ec) || step <= 0) {
       // NOTE: we should use defaultStep * defaultStepScaleFactor,
       // which is 1 for type=number.
       step = 1;
     }
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -594,17 +594,19 @@ void nsHTMLMediaElement::AbortExistingLo
   mIsLoadingFromSourceChildren = false;
   mSuspendedAfterFirstFrame = false;
   mAllowSuspendAfterFirstFrame = true;
   mHaveQueuedSelectResource = false;
   mSuspendedForPreloadNone = false;
   mDownloadSuspendedByCache = false;
   mSourcePointer = nullptr;
 
-  // TODO: The playback rate must be set to the default playback rate.
+  mChannels = 0;
+  mRate = 0;
+  mTags = nullptr;
 
   if (mNetworkState != nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
     mNetworkState = nsIDOMHTMLMediaElement::NETWORK_EMPTY;
     NS_ASSERTION(!mDecoder && !mStream, "How did someone setup a new stream/decoder already?");
     ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING);
     mPaused = true;
 
     if (fireTimeUpdate) {
@@ -1420,16 +1422,59 @@ nsHTMLMediaElement::GetMozSampleRate(PRU
   if (!mDecoder && !mAudioStream) {
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
 
   *aMozSampleRate = mRate;
   return NS_OK;
 }
 
+// Helper struct with arguments for our hash iterator.
+typedef struct {
+  JSContext* cx;
+  JSObject*  tags;
+} MetadataIterCx;
+
+PLDHashOperator
+nsHTMLMediaElement::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());
+  JS::Value value = STRING_TO_JSVAL(string);
+  if (!JS_SetProperty(args->cx, args->tags, aKey.Data(), &value)) {
+    NS_WARNING("Failed to set metadata property");
+  }
+
+  return PL_DHASH_NEXT;
+}
+
+NS_IMETHODIMP
+nsHTMLMediaElement::MozGetMetadata(JSContext* cx, JS::Value* aValue)
+{
+  if (mReadyState < nsIDOMHTMLMediaElement::HAVE_METADATA) {
+    return NS_ERROR_DOM_INVALID_STATE_ERR;
+  }
+
+  JSObject* tags = JS_NewObject(cx, NULL, NULL, NULL);
+  if (!tags) {
+    return NS_ERROR_FAILURE;
+  }
+  if (mTags) {
+    MetadataIterCx iter = {cx, tags};
+    mTags->EnumerateRead(BuildObjectFromTags, static_cast<void*>(&iter));
+  }
+  *aValue = OBJECT_TO_JSVAL(tags);
+
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 nsHTMLMediaElement::GetMozFrameBufferLength(PRUint32 *aMozFrameBufferLength)
 {
   // The framebuffer (via MozAudioAvailable events) is only available
   // when reading vs. writing audio directly.
   if (!mDecoder) {
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
@@ -2633,21 +2678,25 @@ void nsHTMLMediaElement::ProcessMediaFra
     }
   }
   if (start > 0.0) {
     SetCurrentTime(start);
     mFragmentStart = start;
   }
 }
 
-void nsHTMLMediaElement::MetadataLoaded(PRUint32 aChannels, PRUint32 aRate, bool aHasAudio)
+void nsHTMLMediaElement::MetadataLoaded(PRUint32 aChannels,
+                                        PRUint32 aRate,
+                                        bool aHasAudio,
+                                        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"));
   if (mDecoder && mDecoder->IsSeekable()) {
     ProcessMediaFragmentURI();
     mDecoder->SetEndTime(mFragmentEnd);
   }
 }
--- a/content/html/content/src/nsMediaFragmentURIParser.cpp
+++ b/content/html/content/src/nsMediaFragmentURIParser.cpp
@@ -101,17 +101,17 @@ bool nsMediaFragmentURIParser::ParseNPTS
   }
 
   PRUint32 index = FirstNonDigit(aString, 0);
   if (index == 0) {
     return false;
   }
 
   nsDependentSubstring n(aString, 0, index);
-  PRInt32 ec;
+  nsresult ec;
   PRInt32 s = PromiseFlatString(n).ToInteger(&ec);
   if (NS_FAILED(ec)) {
     return false;
   }
 
   aString.Rebind(aString, index);
   double fraction = 0.0;
   if (!ParseNPTFraction(aString, fraction)) {
@@ -157,17 +157,17 @@ bool nsMediaFragmentURIParser::ParseNPTF
 {
   double fraction = 0.0;
 
   if (aString.Length() > 0 && aString[0] == '.') {
     PRUint32 index = FirstNonDigit(aString, 1);
 
     if (index > 1) {
       nsDependentSubstring number(aString, 0, index);
-      PRInt32 ec;
+      nsresult ec;
       fraction = PromiseFlatString(number).ToDouble(&ec);
       if (NS_FAILED(ec)) {
         return false;
       }
     }
     aString.Rebind(aString, index);
   }
 
@@ -206,17 +206,17 @@ bool nsMediaFragmentURIParser::ParseNPTH
   }
 
   PRUint32 index = FirstNonDigit(aString, 0);
   if (index == 0) {
     return false;
   }
 
   nsDependentSubstring n(aString, 0, index);
-  PRInt32 ec;
+  nsresult ec;
   PRInt32 u = PromiseFlatString(n).ToInteger(&ec);
   if (NS_FAILED(ec)) {
     return false;
   }
 
   aString.Rebind(aString, index);
   aHour = u;
   return true;
@@ -230,18 +230,17 @@ bool nsMediaFragmentURIParser::ParseNPTM
 bool nsMediaFragmentURIParser::ParseNPTSS(nsDependentSubstring& aString, PRUint32& aSecond)
 {
   if (aString.Length() < 2) {
     return false;
   }
 
   if (IsDigit(aString[0]) && IsDigit(aString[1])) {
     nsDependentSubstring n(aString, 0, 2);
-    PRInt32 ec;
-
+    nsresult ec;
     PRInt32 u = PromiseFlatString(n).ToInteger(&ec);
     if (NS_FAILED(ec)) {
       return false;
     }
 
     aString.Rebind(aString, 2);
     if (u >= 60)
       return false;
--- a/content/mathml/content/src/nsMathMLElement.cpp
+++ b/content/mathml/content/src/nsMathMLElement.cpp
@@ -329,17 +329,17 @@ nsMathMLElement::ParseNumericValue(const
       // some authors leave blanks before the unit, but that shouldn't
       // be allowed, so don't CompressWhitespace on 'unit'.
       break;
     }
     number.Append(c);
   }
 
   // Convert number to floating point
-  PRInt32 errorCode;
+  nsresult errorCode;
   float floatValue = number.ToFloat(&errorCode);
   if (NS_FAILED(errorCode))
     return false;
   if (floatValue < 0 && !(aFlags & PARSE_ALLOW_NEGATIVE))
     return false;
 
   nsCSSUnit cssUnit;
   if (unit.IsEmpty()) {
@@ -392,17 +392,17 @@ nsMathMLElement::MapMathMLAttributesInto
     nsCSSValue* scriptSizeMultiplier =
       aData->ValueForScriptSizeMultiplier();
     if (value && value->Type() == nsAttrValue::eString &&
         scriptSizeMultiplier->GetUnit() == eCSSUnit_Null) {
       nsAutoString str(value->GetStringValue());
       str.CompressWhitespace();
       // MathML numbers can't have leading '+'
       if (str.Length() > 0 && str.CharAt(0) != '+') {
-        PRInt32 errorCode;
+        nsresult errorCode;
         float floatValue = str.ToFloat(&errorCode);
         // Negative scriptsizemultipliers are not parsed
         if (NS_SUCCEEDED(errorCode) && floatValue >= 0.0f) {
           scriptSizeMultiplier->SetFloatValue(floatValue, eCSSUnit_Number);
         }
       }
     }
 
@@ -438,17 +438,17 @@ nsMathMLElement::MapMathMLAttributesInto
     //
     value = aAttributes->GetAttr(nsGkAtoms::scriptlevel_);
     nsCSSValue* scriptLevel = aData->ValueForScriptLevel();
     if (value && value->Type() == nsAttrValue::eString &&
         scriptLevel->GetUnit() == eCSSUnit_Null) {
       nsAutoString str(value->GetStringValue());
       str.CompressWhitespace();
       if (str.Length() > 0) {
-        PRInt32 errorCode;
+        nsresult errorCode;
         PRInt32 intValue = str.ToInteger(&errorCode);
         if (NS_SUCCEEDED(errorCode)) {
           // This is kind of cheesy ... if the scriptlevel has a sign,
           // then it's a relative value and we store the nsCSSValue as an
           // Integer to indicate that. Otherwise we store it as a Number
           // to indicate that the scriptlevel is absolute.
           PRUnichar ch = str.CharAt(0);
           if (ch == '+' || ch == '-') {
--- a/content/media/MediaResource.cpp
+++ b/content/media/MediaResource.cpp
@@ -175,17 +175,17 @@ ChannelMediaResource::OnStartRequest(nsI
       // In the case of multiple options for obtaining the duration
       // the order of precedence is:
       // 1) The Media resource metadata if possible (done by the decoder itself).
       // 2) Content-Duration message header.
       // 3) X-AMZ-Meta-Content-Duration.
       // 4) X-Content-Duration.
       // 5) Perform a seek in the decoder to find the value.
       nsCAutoString durationText;
-      PRInt32 ec = 0;
+      nsresult ec = NS_OK;
       rv = hc->GetResponseHeader(NS_LITERAL_CSTRING("Content-Duration"), durationText);
       if (NS_FAILED(rv)) {
         rv = hc->GetResponseHeader(NS_LITERAL_CSTRING("X-AMZ-Meta-Content-Duration"), durationText);
       }
       if (NS_FAILED(rv)) {
         rv = hc->GetResponseHeader(NS_LITERAL_CSTRING("X-Content-Duration"), durationText);
       }
 
--- a/content/media/gstreamer/nsGStreamerReader.cpp
+++ b/content/media/gstreamer/nsGStreamerReader.cpp
@@ -127,20 +127,28 @@ nsresult nsGStreamerReader::Init(nsBuilt
   GstPad *sinkpad = gst_element_get_pad(GST_ELEMENT(mVideoAppSink), "sink");
   gst_pad_add_event_probe(sinkpad,
       G_CALLBACK(&nsGStreamerReader::EventProbeCb), this);
   gst_object_unref(sinkpad);
 
   mAudioSink = gst_parse_bin_from_description("capsfilter name=filter ! "
 #ifdef MOZ_SAMPLE_TYPE_FLOAT32
         "appsink name=audiosink sync=true caps=audio/x-raw-float,"
+#ifdef IS_LITTLE_ENDIAN
         "channels={1,2},rate=44100,width=32,endianness=1234", TRUE, NULL);
 #else
+        "channels={1,2},rate=44100,width=32,endianness=4321", TRUE, NULL);
+#endif
+#else
         "appsink name=audiosink sync=true caps=audio/x-raw-int,"
+#ifdef IS_LITTLE_ENDIAN
         "channels={1,2},rate=48000,width=16,endianness=1234", TRUE, NULL);
+#else
+        "channels={1,2},rate=48000,width=16,endianness=4321", TRUE, NULL);
+#endif
 #endif
   mAudioAppSink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(mAudioSink),
         "audiosink"));
   gst_app_sink_set_callbacks(mAudioAppSink, &mSinkCallbacks,
       (gpointer) this, NULL);
   sinkpad = gst_element_get_pad(GST_ELEMENT(mAudioAppSink), "sink");
   gst_pad_add_event_probe(sinkpad,
       G_CALLBACK(&nsGStreamerReader::EventProbeCb), this);
@@ -181,17 +189,18 @@ void nsGStreamerReader::PlayBinSourceSet
     gst_app_src_set_stream_type(mSource, GST_APP_STREAM_TYPE_RANDOM_ACCESS);
   } else {
     /* make the demuxer work in push mode so that seeking is kept to a minimum
      */
     gst_app_src_set_stream_type(mSource, GST_APP_STREAM_TYPE_SEEKABLE);
   }
 }
 
-nsresult nsGStreamerReader::ReadMetadata(nsVideoInfo* aInfo)
+nsresult nsGStreamerReader::ReadMetadata(nsVideoInfo* aInfo,
+                                         nsHTMLMediaElement::MetadataTags** aTags)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
   nsresult ret = NS_OK;
 
   /* We do 3 attempts here: decoding audio and video, decoding video only,
    * decoding audio only. This allows us to play streams that have one broken
    * stream but that are otherwise decodeable.
    */
@@ -291,16 +300,18 @@ nsresult nsGStreamerReader::ReadMetadata
 
   int n_video = 0, n_audio = 0;
   g_object_get(mPlayBin, "n-video", &n_video, "n-audio", &n_audio, NULL);
   mInfo.mHasVideo = n_video != 0;
   mInfo.mHasAudio = n_audio != 0;
 
   *aInfo = mInfo;
 
+  *aTags = nullptr;
+
   /* set the pipeline to PLAYING so that it starts decoding and queueing data in
    * the appsinks */
   gst_element_set_state(mPlayBin, GST_STATE_PLAYING);
 
   return NS_OK;
 }
 
 nsresult nsGStreamerReader::ResetDecode()
--- a/content/media/gstreamer/nsGStreamerReader.h
+++ b/content/media/gstreamer/nsGStreamerReader.h
@@ -22,17 +22,18 @@ public:
   nsGStreamerReader(nsBuiltinDecoder* aDecoder);
   virtual ~nsGStreamerReader();
 
   virtual nsresult Init(nsBuiltinDecoderReader* aCloneDonor);
   virtual nsresult ResetDecode();
   virtual bool DecodeAudioData();
   virtual bool DecodeVideoFrame(bool &aKeyframeSkip,
                                 PRInt64 aTimeThreshold);
-  virtual nsresult ReadMetadata(nsVideoInfo* aInfo);
+  virtual nsresult ReadMetadata(nsVideoInfo* aInfo,
+                                nsHTMLMediaElement::MetadataTags** aTags);
   virtual nsresult Seek(PRInt64 aTime,
                         PRInt64 aStartTime,
                         PRInt64 aEndTime,
                         PRInt64 aCurrentTime);
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime);
 
   virtual bool IsSeekableInBufferedRanges() {
     return true;
--- a/content/media/nsAudioStream.cpp
+++ b/content/media/nsAudioStream.cpp
@@ -875,23 +875,23 @@ class nsBufferedAudioStream : public nsA
   PRInt32 GetMinWriteSize();
 
 private:
   static long DataCallback_S(cubeb_stream*, void* aThis, void* aBuffer, long aFrames)
   {
     return static_cast<nsBufferedAudioStream*>(aThis)->DataCallback(aBuffer, aFrames);
   }
 
-  static int StateCallback_S(cubeb_stream*, void* aThis, cubeb_state aState)
+  static void StateCallback_S(cubeb_stream*, void* aThis, cubeb_state aState)
   {
-    return static_cast<nsBufferedAudioStream*>(aThis)->StateCallback(aState);
+    static_cast<nsBufferedAudioStream*>(aThis)->StateCallback(aState);
   }
 
   long DataCallback(void* aBuffer, long aFrames);
-  int StateCallback(cubeb_state aState);
+  void StateCallback(cubeb_state aState);
 
   // Shared implementation of underflow adjusted position calculation.
   // Caller must own the monitor.
   PRInt64 GetPositionInFramesUnlocked();
 
   // The monitor is held to protect all access to member variables.  Write()
   // waits while mBuffer is full; DataCallback() notifies as it consumes
   // data from mBuffer.  Drain() waits while mState is DRAINING;
@@ -1142,22 +1142,29 @@ nsBufferedAudioStream::GetPosition()
   MonitorAutoLock mon(mMonitor);
   PRInt64 frames = GetPositionInFramesUnlocked();
   if (frames >= 0) {
     return USECS_PER_S * frames / mRate;
   }
   return -1;
 }
 
+// This function is miscompiled by PGO with MSVC 2010.  See bug 768333.
+#ifdef _MSC_VER
+#pragma optimize("", off)
+#endif
 PRInt64
 nsBufferedAudioStream::GetPositionInFrames()
 {
   MonitorAutoLock mon(mMonitor);
   return GetPositionInFramesUnlocked();
 }
+#ifdef _MSC_VER
+#pragma optimize("", on)
+#endif
 
 PRInt64
 nsBufferedAudioStream::GetPositionInFramesUnlocked()
 {
   mMonitor.AssertCurrentThreadOwns();
 
   if (!mCubebStream || mState == ERRORED) {
     return -1;
@@ -1168,21 +1175,21 @@ nsBufferedAudioStream::GetPositionInFram
     MonitorAutoUnlock mon(mMonitor);
     if (cubeb_stream_get_position(mCubebStream, &position) != CUBEB_OK) {
       return -1;
     }
   }
 
   // Adjust the reported position by the number of silent frames written
   // during stream underruns.
-  PRInt64 adjustedPosition = 0;
+  PRUint64 adjustedPosition = 0;
   if (position >= mLostFrames) {
     adjustedPosition = position - mLostFrames;
   }
-  return adjustedPosition;
+  return NS_MIN<PRUint64>(adjustedPosition, PR_INT64_MAX);
 }
 
 bool
 nsBufferedAudioStream::IsPaused()
 {
   MonitorAutoLock mon(mMonitor);
   return mState == STOPPED;
 }
@@ -1256,22 +1263,21 @@ nsBufferedAudioStream::DataCallback(void
     memset(static_cast<PRUint8*>(aBuffer) + available, 0, bytesWanted);
     mLostFrames += bytesWanted / mBytesPerFrame;
     bytesWanted = 0;
   }
 
   return aFrames - (bytesWanted / mBytesPerFrame);
 }
 
-int
+void
 nsBufferedAudioStream::StateCallback(cubeb_state aState)
 {
   MonitorAutoLock mon(mMonitor);
   if (aState == CUBEB_STATE_DRAINED) {
     mState = DRAINED;
   } else if (aState == CUBEB_STATE_ERROR) {
     mState = ERRORED;
   }
   mon.NotifyAll();
-  return CUBEB_OK;
 }
 #endif
 
--- a/content/media/nsBuiltinDecoder.cpp
+++ b/content/media/nsBuiltinDecoder.cpp
@@ -401,17 +401,18 @@ void nsBuiltinDecoder::AudioAvailable(fl
   if (mShuttingDown || !mElement) {
     return;
   }
   mElement->NotifyAudioAvailable(frameBuffer.forget(), aFrameBufferLength, aTime);
 }
 
 void nsBuiltinDecoder::MetadataLoaded(PRUint32 aChannels,
                                       PRUint32 aRate,
-                                      bool aHasAudio)
+                                      bool aHasAudio,
+                                      const nsHTMLMediaElement::MetadataTags* aTags)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   if (mShuttingDown) {
     return;
   }
 
   {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
@@ -423,17 +424,17 @@ void nsBuiltinDecoder::MetadataLoaded(PR
   if (mDuration == -1) {
     SetInfinite(true);
   }
 
   if (mElement) {
     // Make sure the element and the frame (if any) are told about
     // our new size.
     Invalidate();
-    mElement->MetadataLoaded(aChannels, aRate, aHasAudio);
+    mElement->MetadataLoaded(aChannels, aRate, aHasAudio, aTags);
   }
 
   if (!mResourceLoaded) {
     StartProgress();
   } else if (mElement) {
     // Resource was loaded during metadata loading, when progress
     // events are being ignored. Fire the final progress event.
     mElement->DispatchAsyncEvent(NS_LITERAL_STRING("progress"));
--- a/content/media/nsBuiltinDecoder.h
+++ b/content/media/nsBuiltinDecoder.h
@@ -574,17 +574,18 @@ public:
   // notifies any thread blocking on this object's monitor of the
   // change. Call on the main thread only.
   void ChangeState(PlayState aState);
 
   // Called when the metadata from the media file has been read.
   // Call on the main thread only.
   void MetadataLoaded(PRUint32 aChannels,
                       PRUint32 aRate,
-                      bool aHasAudio);
+                      bool aHasAudio,
+                      const nsHTMLMediaElement::MetadataTags* aTags);
 
   // Called when the first frame has been loaded.
   // Call on the main thread only.
   void FirstFrameLoaded();
 
   // Called when the video has completed playing.
   // Call on the main thread only.
   void PlaybackEnded();
--- a/content/media/nsBuiltinDecoderReader.h
+++ b/content/media/nsBuiltinDecoderReader.h
@@ -410,20 +410,22 @@ public:
   // than aTimeThreshold will be decoded (unless they're not keyframes
   // and aKeyframeSkip is true), but will not be added to the queue.
   virtual bool DecodeVideoFrame(bool &aKeyframeSkip,
                                 PRInt64 aTimeThreshold) = 0;
 
   virtual bool HasAudio() = 0;
   virtual bool HasVideo() = 0;
 
-  // Read header data for all bitstreams in the file. Fills mInfo with
-  // the data required to present the media. Returns NS_OK on success,
-  // or NS_ERROR_FAILURE on failure.
-  virtual nsresult ReadMetadata(nsVideoInfo* aInfo) = 0;
+  // Read header data for all bitstreams in the file. Fills aInfo with
+  // the data required to present the media, and optionally fills *aTags
+  // with tag metadata from the file.
+  // Returns NS_OK on success, or NS_ERROR_FAILURE on failure.
+  virtual nsresult ReadMetadata(nsVideoInfo* aInfo,
+                                nsHTMLMediaElement::MetadataTags** aTags) = 0;
 
   // Stores the presentation time of the first frame we'd be able to play if
   // we started playback at the current position. Returns the first video
   // frame, if we have video.
   VideoData* FindStartTime(PRInt64& aOutStartTime);
 
   // Moves the decode head to aTime microseconds. aStartTime and aEndTime
   // denote the start and end times of the media in usecs, and aCurrentTime
--- a/content/media/nsBuiltinDecoderStateMachine.cpp
+++ b/content/media/nsBuiltinDecoderStateMachine.cpp
@@ -116,33 +116,36 @@ static PRInt64 DurationToUsecs(TimeDurat
 }
 
 class nsAudioMetadataEventRunner : public nsRunnable
 {
 private:
   nsCOMPtr<nsBuiltinDecoder> mDecoder;
 public:
   nsAudioMetadataEventRunner(nsBuiltinDecoder* aDecoder, PRUint32 aChannels,
-                             PRUint32 aRate, bool aHasAudio) :
+                             PRUint32 aRate, bool aHasAudio,
+                             nsHTMLMediaElement::MetadataTags* aTags) :
     mDecoder(aDecoder),
     mChannels(aChannels),
     mRate(aRate),
-    mHasAudio(aHasAudio)
+    mHasAudio(aHasAudio),
+    mTags(aTags)
   {
   }
 
   NS_IMETHOD Run()
   {
-    mDecoder->MetadataLoaded(mChannels, mRate, mHasAudio);
+    mDecoder->MetadataLoaded(mChannels, mRate, mHasAudio, mTags);
     return NS_OK;
   }
 
   const PRUint32 mChannels;
   const PRUint32 mRate;
   const bool mHasAudio;
+  nsHTMLMediaElement::MetadataTags* mTags;
 };
 
 // Owns the global state machine thread and counts of
 // state machine and decoder threads. There should
 // only be one instance of this class.
 class StateMachineTracker
 {
 private:
@@ -1739,19 +1742,20 @@ nsresult nsBuiltinDecoderStateMachine::D
   NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
   mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
   NS_ASSERTION(mState == DECODER_STATE_DECODING_METADATA,
                "Only call when in metadata decoding state");
 
   LOG(PR_LOG_DEBUG, ("%p Decoding Media Headers", mDecoder.get()));
   nsresult res;
   nsVideoInfo info;
+  nsHTMLMediaElement::MetadataTags* tags;
   {
     ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
-    res = mReader->ReadMetadata(&info);
+    res = mReader->ReadMetadata(&info, &tags);
   }
   mInfo = info;
 
   if (NS_FAILED(res) || (!info.mHasVideo && !info.mHasAudio)) {
     // Dispatch the event to call DecodeError synchronously. This ensures
     // we're in shutdown state by the time we exit the decode thread.
     // If we just moved to shutdown state here on the decode thread, we may
     // cause the state machine to shutdown/free memory without closing its
@@ -1795,17 +1799,21 @@ nsresult nsBuiltinDecoderStateMachine::D
     mEventManager.Init(mInfo.mAudioChannels, mInfo.mAudioRate);
     // Set the buffer length at the decoder level to be able, to be able
     // to retrive the value via media element method. The RequestFrameBufferLength
     // will call the nsBuiltinDecoderStateMachine::SetFrameBufferLength().
     PRUint32 frameBufferLength = mInfo.mAudioChannels * FRAMEBUFFER_LENGTH_PER_CHANNEL;
     mDecoder->RequestFrameBufferLength(frameBufferLength);
   }
   nsCOMPtr<nsIRunnable> metadataLoadedEvent =
-    new nsAudioMetadataEventRunner(mDecoder, mInfo.mAudioChannels, mInfo.mAudioRate, HasAudio());
+    new nsAudioMetadataEventRunner(mDecoder,
+                                   mInfo.mAudioChannels,
+                                   mInfo.mAudioRate,
+                                   HasAudio(),
+                                   tags);
   NS_DispatchToMainThread(metadataLoadedEvent, NS_DISPATCH_NORMAL);
 
   if (mState == DECODER_STATE_DECODING_METADATA) {
     LOG(PR_LOG_DEBUG, ("%p Changed state from DECODING_METADATA to DECODING", mDecoder.get()));
     StartDecoding();
   }
 
   if ((mState == DECODER_STATE_DECODING || mState == DECODER_STATE_COMPLETED) &&
--- a/content/media/ogg/nsOggReader.cpp
+++ b/content/media/ogg/nsOggReader.cpp
@@ -146,24 +146,54 @@ void nsOggReader::BuildSerialList(nsTArr
     if (mVorbisState) {
       aTracks.AppendElement(mVorbisState->mSerial);
     } else if(mOpusState) {
       aTracks.AppendElement(mOpusState->mSerial);
     }
   }
 }
 
-nsresult nsOggReader::ReadMetadata(nsVideoInfo* aInfo)
+static
+nsHTMLMediaElement::MetadataTags* TagsFromVorbisComment(vorbis_comment *vc)
+{
+  nsHTMLMediaElement::MetadataTags* tags;
+  int i;
+
+  tags = new nsHTMLMediaElement::MetadataTags;
+  tags->Init();
+  for (i = 0; i < vc->comments; i++) {
+    char *comment = vc->user_comments[i];
+    char *div = (char*)memchr(comment, '=', vc->comment_lengths[i]);
+    if (!div) {
+      LOG(PR_LOG_DEBUG, ("Invalid vorbis comment: no separator"));
+      continue;
+    }
+    // This should be ASCII.
+    nsCString key = nsCString(comment, div-comment);
+    PRUint32 value_length = vc->comment_lengths[i] - (div-comment);
+    // This should be utf-8.
+    nsCString value = nsCString(div + 1, value_length);
+    tags->Put(key, value);
+  }
+
+  return tags;
+}
+
+nsresult nsOggReader::ReadMetadata(nsVideoInfo* aInfo,
+                                   nsHTMLMediaElement::MetadataTags** aTags)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
   // We read packets until all bitstreams have read all their header packets.
   // We record the offset of the first non-header page so that we know
   // what page to seek to when seeking to the media start.
 
+  NS_ASSERTION(aTags, "Called with null MetadataTags**.");
+  *aTags = nullptr;
+
   ogg_page page;
   nsAutoTArray<nsOggCodecState*,4> bitstreams;
   bool readAllBOS = false;
   while (!readAllBOS) {
     PRInt64 pageOffset = ReadOggPage(&page);
     if (pageOffset == -1) {
       // Some kind of error...
       break;
@@ -278,16 +308,17 @@ nsresult nsOggReader::ReadMetadata(nsVid
   if (mVorbisState && ReadHeaders(mVorbisState)) {
     mInfo.mHasAudio = true;
     mInfo.mAudioRate = mVorbisState->mInfo.rate;
     mInfo.mAudioChannels = mVorbisState->mInfo.channels;
     // Copy Vorbis info data for time computations on other threads.
     memcpy(&mVorbisInfo, &mVorbisState->mInfo, sizeof(mVorbisInfo));
     mVorbisInfo.codec_setup = NULL;
     mVorbisSerial = mVorbisState->mSerial;
+    *aTags = TagsFromVorbisComment(&mVorbisState->mComment);
   } else {
     memset(&mVorbisInfo, 0, sizeof(mVorbisInfo));
   }
 #ifdef MOZ_OPUS
   if (mOpusState && ReadHeaders(mOpusState)) {
     mInfo.mHasAudio = true;
     mInfo.mAudioRate = mOpusState->mRate;
     mInfo.mAudioChannels = mOpusState->mChannels;
@@ -1618,17 +1649,20 @@ nsresult nsOggReader::GetBuffered(nsTime
         // Stream is not the theora or vorbis stream we're playing,
         // but is one that we have header data for.
         startOffset += page.header_len + page.body_len;
         continue;
       }
       else {
         // Page is for a stream we don't know about (possibly a chained
         // ogg), return an error.
-        return PAGE_SYNC_ERROR;
+        //
+        // XXX Invalid cast of PageSyncResult to nsresult -- this has numeric
+        // value 1 and will pass an NS_SUCCEEDED() check (bug 778105)
+        return (nsresult)PAGE_SYNC_ERROR;
       }
     }
 
     if (startTime != -1) {
       // We were able to find a start time for that range, see if we can
       // find an end time.
       PRInt64 endTime = RangeEndTime(startOffset, endOffset, true);
       if (endTime != -1) {
--- a/content/media/ogg/nsOggReader.h
+++ b/content/media/ogg/nsOggReader.h
@@ -42,17 +42,18 @@ public:
     return (mVorbisState != 0 && mVorbisState->mActive) ||
            (mOpusState != 0 && mOpusState->mActive);
   }
 
   virtual bool HasVideo() {
     return mTheoraState != 0 && mTheoraState->mActive;
   }
 
-  virtual nsresult ReadMetadata(nsVideoInfo* aInfo);
+  virtual nsresult ReadMetadata(nsVideoInfo* aInfo,
+                                nsHTMLMediaElement::MetadataTags** aTags);
   virtual nsresult Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime);
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime);
 
   // We use bisection to seek in buffered range.
   virtual bool IsSeekableInBufferedRanges() {
     return true;
   }
 
--- a/content/media/plugins/nsMediaPluginReader.cpp
+++ b/content/media/plugins/nsMediaPluginReader.cpp
@@ -30,17 +30,18 @@ nsMediaPluginReader::~nsMediaPluginReade
 
 nsresult nsMediaPluginReader::Init(nsBuiltinDecoderReader* aCloneDonor)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
   return NS_OK;
 }
 
-nsresult nsMediaPluginReader::ReadMetadata(nsVideoInfo* aInfo)
+nsresult nsMediaPluginReader::ReadMetadata(nsVideoInfo* aInfo,
+                                           nsHTMLMediaElement::MetadataTags** aTags)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
   if (!mPlugin) {
     mPlugin = GetMediaPluginHost()->CreateDecoder(mDecoder->GetResource(), mType);
     if (!mPlugin) {
       return NS_ERROR_FAILURE;
     }
@@ -84,16 +85,17 @@ nsresult nsMediaPluginReader::ReadMetada
     int32_t numChannels, sampleRate;
     mPlugin->GetAudioParameters(mPlugin, &numChannels, &sampleRate);
     mHasAudio = mInfo.mHasAudio = true;
     mInfo.mAudioChannels = numChannels;
     mInfo.mAudioRate = sampleRate;
   }
 
  *aInfo = mInfo;
+ *aTags = nullptr;
   return NS_OK;
 }
 
 // Resets all state related to decoding, emptying all buffers etc.
 nsresult nsMediaPluginReader::ResetDecode()
 {
   if (mLastVideoFrame) {
     delete mLastVideoFrame;
--- a/content/media/plugins/nsMediaPluginReader.h
+++ b/content/media/plugins/nsMediaPluginReader.h
@@ -39,17 +39,18 @@ public:
     return mHasAudio;
   }
 
   virtual bool HasVideo()
   {
     return mHasVideo;
   }
 
-  virtual nsresult ReadMetadata(nsVideoInfo* aInfo);
+  virtual nsresult ReadMetadata(nsVideoInfo* aInfo,
+                                nsHTMLMediaElement::MetadataTags** aTags);
   virtual nsresult Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime);
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime);
   virtual bool IsSeekableInBufferedRanges() {
     return true;
   }
 
 };
 
--- a/content/media/raw/nsRawReader.cpp
+++ b/content/media/raw/nsRawReader.cpp
@@ -27,17 +27,18 @@ nsresult nsRawReader::Init(nsBuiltinDeco
 }
 
 nsresult nsRawReader::ResetDecode()
 {
   mCurrentFrame = 0;
   return nsBuiltinDecoderReader::ResetDecode();
 }
 
-nsresult nsRawReader::ReadMetadata(nsVideoInfo* aInfo)
+nsresult nsRawReader::ReadMetadata(nsVideoInfo* aInfo,
+                                   nsHTMLMediaElement::MetadataTags** aTags)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(),
                "Should be on decode thread.");
 
   MediaResource* resource = mDecoder->GetResource();
   NS_ASSERTION(resource, "Decoder has no media resource");
 
   if (!ReadFromResource(resource, reinterpret_cast<PRUint8*>(&mMetadata),
@@ -98,16 +99,18 @@ nsresult nsRawReader::ReadMetadata(nsVid
     mozilla::ReentrantMonitorAutoEnter autoMonitor(mDecoder->GetReentrantMonitor());
     mDecoder->GetStateMachine()->SetDuration(USECS_PER_S *
                                            (length - sizeof(nsRawVideoHeader)) /
                                            (mFrameSize * mFrameRate));
   }
 
   *aInfo = mInfo;
 
+  *aTags = nullptr;
+
   return NS_OK;
 }
 
  bool nsRawReader::DecodeAudioData()
 {
   NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
                "Should be on state machine thread or decode thread.");
   return false;
--- a/content/media/raw/nsRawReader.h
+++ b/content/media/raw/nsRawReader.h
@@ -27,17 +27,18 @@ public:
     return false;
   }
 
   virtual bool HasVideo()
   {
     return true;
   }
 
-  virtual nsresult ReadMetadata(nsVideoInfo* aInfo);
+  virtual nsresult ReadMetadata(nsVideoInfo* aInfo,
+                                nsHTMLMediaElement::MetadataTags** aTags);
   virtual nsresult Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime);
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime);
 
   // By seeking in the media resource, it is possible to seek.
   bool IsSeekableInBufferedRanges() {
     return true;
   }
 
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -82,16 +82,17 @@ MOCHITEST_FILES = \
 		test_error_on_404.html \
 		test_error_in_video_document.html \
 		test_info_leak.html \
 		test_load.html \
 		test_load_candidates.html \
 		test_load_same_resource.html \
 		test_load_source.html \
 		test_loop.html \
+		test_metadata.html \
 		test_mozLoadFrom.html \
 		test_no_load_event.html \
 		test_networkState.html \
 		test_new_audio.html \
 		test_paused.html \
 		test_paused_after_ended.html \
 		test_play_events.html \
 		test_play_events_2.html \
--- a/content/media/test/manifest.js
+++ b/content/media/test/manifest.js
@@ -298,16 +298,47 @@ var gDecodeErrorTests = [
 ];
 
 // These are files that are used for media fragments tests
 var gFragmentTests = [
   { name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444 }
 ];
 
 
+// These are files with non-trivial tag sets.
+// Used by test_metadata.html.
+var gMetadataTests = [
+  // Ogg Vorbis files
+  { name:"short-video.ogv", tags: {
+      TITLE:"Lepidoptera",
+      ARTIST:"Epoq",
+      ALBUM:"Kahvi Collective",
+      DATE:"2002",
+      COMMENT:"http://www.kahvi.org",
+    }
+  },
+  { name:"bug516323.ogv", tags: {
+      GENRE:"Open Movie",
+      ENCODER:"Audacity",
+      TITLE:"Elephants Dream",
+      ARTIST:"Silvia Pfeiffer",
+      COMMENTS:"Audio Description"
+    }
+  },
+  { name:"bug516323.indexed.ogv", tags: {
+      GENRE:"Open Movie",
+      ENCODER:"Audacity",
+      TITLE:"Elephants Dream",
+      ARTIST:"Silvia Pfeiffer",
+      COMMENTS:"Audio Description"
+    }
+  },
+  { name:"sound.ogg", tags: { } }
+];
+
 function checkMetadata(msg, e, test) {
   if (test.width) {
     is(e.videoWidth, test.width, msg + " video width");
   }
   if (test.height) {
     is(e.videoHeight, test.height, msg + " video height");
   }
   if (test.duration) {
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_metadata.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test returning metadata from media files with mozGetMetadata()</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+</head>
+<body>
+<pre id="test">
+<div id="output"></div>
+<script class="testbody" type="text/javascript">
+
+var manager = new MediaTestManager;
+
+function startTest(test, token) {
+  var a = document.createElement('audio');
+  a.token = token;
+  manager.started(token);
+
+  a.src = test.name;
+  a.name = test.name;
+
+  // Tags should not be available immediately.
+  var exception_fired = false;
+  try {
+    var m = a.mozGetMetadata();
+  } catch (e) {
+    is(e.name, 'InvalidStateError',
+       "early mozGetMetadata() threw incorrect exception");
+    exception_fired = true;
+  }
+  ok(exception_fired,
+     "mozGetMetadata() should throw an exception before HAVE_METADATA");
+
+  // Wait until metadata has loaded.
+  a.addEventListener('loadedmetadata', function() {
+    // read decoded tags
+    tags = a.mozGetMetadata();
+    ok(tags, "mozGetMetadata() failed");
+    // Dump them out.
+    var d = document.getElementById('output');
+    var html = '<table>\n';
+    html += '<caption><p>Called getMozMetadata()'
+    html += ' on '+test.name+'</p></caption>\n';
+    html += '<tr><th>tag</th>';
+    html += '<th>decoded value</th><th>expected value</th></tr>\n';
+    for (tag in tags) {
+      html += '<tr><td>'+tag+'</td>';
+      html += '<td>'+tags[tag]+'</td>';
+      html += '<td>'+test.tags[tag]+'</td>';
+      html += '</tr>\n';
+    }
+    if (!Object.keys(tags).length) {
+      html += '<tr><td colspan=3 align=center><em>no tags</em></td></tr>\n';
+    }
+    html += '</table>\n';
+    var div = document.createElement('div');
+    div.innerHTML = html;
+    d.appendChild(div);
+    // Verify decoded tag values.
+    for (tag in tags) {
+      is(tags[tag], test.tags[tag], "Tag '"+tag+"' doesn't match");
+    }
+    // Verify expected tag values
+    for (tag in test.tags) {
+      is(tags[tag], test.tags[tag], "Tag '"+tag+"' doesn't match");
+    }
+    manager.finished(token);
+  }, false);
+}
+
+manager.runTests(gMetadataTests, startTest);
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/media/wave/nsWaveReader.cpp
+++ b/content/media/wave/nsWaveReader.cpp
@@ -114,32 +114,35 @@ nsWaveReader::~nsWaveReader()
   MOZ_COUNT_DTOR(nsWaveReader);
 }
 
 nsresult nsWaveReader::Init(nsBuiltinDecoderReader* aCloneDonor)
 {
   return NS_OK;
 }
 
-nsresult nsWaveReader::ReadMetadata(nsVideoInfo* aInfo)
+nsresult nsWaveReader::ReadMetadata(nsVideoInfo* aInfo,
+                                    nsHTMLMediaElement::MetadataTags** aTags)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
   bool loaded = LoadRIFFChunk() && LoadFormatChunk() && FindDataOffset();
   if (!loaded) {
     return NS_ERROR_FAILURE;
   }
 
   mInfo.mHasAudio = true;
   mInfo.mHasVideo = false;
   mInfo.mAudioRate = mSampleRate;
   mInfo.mAudioChannels = mChannels;
 
   *aInfo = mInfo;
 
+  *aTags = nullptr;
+
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
 
   mDecoder->GetStateMachine()->SetDuration(
     static_cast<PRInt64>(BytesToTime(GetDataLength()) * USECS_PER_S));
 
   return NS_OK;
 }
 
--- a/content/media/wave/nsWaveReader.h
+++ b/content/media/wave/nsWaveReader.h
@@ -27,17 +27,18 @@ public:
     return true;
   }
 
   virtual bool HasVideo()
   {
     return false;
   }
 
-  virtual nsresult ReadMetadata(nsVideoInfo* aInfo);
+  virtual nsresult ReadMetadata(nsVideoInfo* aInfo,
+                                nsHTMLMediaElement::MetadataTags** aTags);
   virtual nsresult Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime);
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime);
 
   // To seek in a buffered range, we just have to seek the stream.
   virtual bool IsSeekableInBufferedRanges() {
     return true;
   }
 
--- a/content/media/webm/nsWebMReader.cpp
+++ b/content/media/webm/nsWebMReader.cpp
@@ -173,17 +173,18 @@ nsresult nsWebMReader::ResetDecode()
 void nsWebMReader::Cleanup()
 {
   if (mContext) {
     nestegg_destroy(mContext);
     mContext = nullptr;
   }
 }
 
-nsresult nsWebMReader::ReadMetadata(nsVideoInfo* aInfo)
+nsresult nsWebMReader::ReadMetadata(nsVideoInfo* aInfo,
+                                    nsHTMLMediaElement::MetadataTags** aTags)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
   nestegg_io io;
   io.read = webm_read;
   io.seek = webm_seek;
   io.tell = webm_tell;
   io.userdata = static_cast<nsBuiltinDecoder*>(mDecoder);
@@ -333,16 +334,18 @@ nsresult nsWebMReader::ReadMetadata(nsVi
       mInfo.mAudioRate = mVorbisDsp.vi->rate;
       mInfo.mAudioChannels = mVorbisDsp.vi->channels;
       mChannels = mInfo.mAudioChannels;
     }
   }
 
   *aInfo = mInfo;
 
+  *aTags = nullptr;
+
   return NS_OK;
 }
 
 ogg_packet nsWebMReader::InitOggPacket(unsigned char* aData,
                                        size_t aLength,
                                        bool aBOS,
                                        bool aEOS,
                                        PRInt64 aGranulepos)
--- a/content/media/webm/nsWebMReader.h
+++ b/content/media/webm/nsWebMReader.h
@@ -123,17 +123,18 @@ public:
     return mHasVideo;
   }
 
   // Bug 575140, cannot seek in webm if no cue is present.
   bool IsSeekableInBufferedRanges() {
     return false;
   }
 
-  virtual nsresult ReadMetadata(nsVideoInfo* aInfo);
+  virtual nsresult ReadMetadata(nsVideoInfo* aInfo,
+                                nsHTMLMediaElement::MetadataTags** aTags);
   virtual nsresult Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime);
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime);
   virtual void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRInt64 aOffset);
 
 private:
   // Value passed to NextPacket to determine if we are reading a video or an
   // audio packet.
   enum TrackType {
--- a/content/media/webrtc/MediaEngineDefault.cpp
+++ b/content/media/webrtc/MediaEngineDefault.cpp
@@ -20,16 +20,24 @@
 #define RATE USECS_PER_S
 
 namespace mozilla {
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(MediaEngineDefaultVideoSource, nsITimerCallback)
 /**
  * Default video source.
  */
+
+MediaEngineDefaultVideoSource::MediaEngineDefaultVideoSource()
+  : mTimer(nsnull), mState(kReleased)
+{}
+
+MediaEngineDefaultVideoSource::~MediaEngineDefaultVideoSource()
+{}
+
 void
 MediaEngineDefaultVideoSource::GetName(nsAString& aName)
 {
   aName.Assign(NS_LITERAL_STRING("Default Video Device"));
   return;
 }
 
 void
--- a/content/media/webrtc/MediaEngineDefault.h
+++ b/content/media/webrtc/MediaEngineDefault.h
@@ -7,44 +7,47 @@
 
 #include "prmem.h"
 #include "nsITimer.h"
 
 #include "nsCOMPtr.h"
 #include "nsDOMMediaStream.h"
 #include "nsComponentManagerUtils.h"
 
-#include "Layers.h"
 #include "VideoUtils.h"
 #include "MediaEngine.h"
-#include "ImageLayers.h"
 #include "VideoSegment.h"
 #include "AudioSegment.h"
 #include "StreamBuffer.h"
 #include "MediaStreamGraph.h"
 
 namespace mozilla {
 
+namespace layers {
+class ImageContainer;
+class PlanarYCbCrImage;
+}
+
 /**
  * The default implementation of the MediaEngine interface.
  */
 
 enum DefaultEngineState {
   kAllocated,
   kStarted,
   kStopped,
   kReleased
 };
 
 class MediaEngineDefaultVideoSource : public nsITimerCallback,
                                       public MediaEngineVideoSource
 {
 public:
-  MediaEngineDefaultVideoSource() : mTimer(nullptr), mState(kReleased) {}
-  ~MediaEngineDefaultVideoSource(){};
+  MediaEngineDefaultVideoSource();
+  ~MediaEngineDefaultVideoSource();
 
   virtual void GetName(nsAString&);
   virtual void GetUUID(nsAString&);
 
   virtual MediaEngineVideoOptions GetOptions();
   virtual nsresult Allocate();
 
   virtual nsresult Deallocate();
--- a/content/media/webrtc/MediaEngineWebRTC.h
+++ b/content/media/webrtc/MediaEngineWebRTC.h
@@ -13,20 +13,18 @@
 
 #include "nsCOMPtr.h"
 #include "nsDOMFile.h"
 #include "nsThreadUtils.h"
 #include "nsDOMMediaStream.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsComponentManagerUtils.h"
 
-#include "Layers.h"
 #include "VideoUtils.h"
 #include "MediaEngine.h"
-#include "ImageLayers.h"
 #include "VideoSegment.h"
 #include "AudioSegment.h"
 #include "StreamBuffer.h"
 #include "MediaStreamGraph.h"
 
 // WebRTC library includes follow
 
 // Audio Engine
--- a/content/svg/content/src/SVGNumberList.cpp
+++ b/content/svg/content/src/SVGNumberList.cpp
@@ -58,17 +58,17 @@ SVGNumberList::SetValueFromString(const 
   nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
     tokenizer(aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
 
   nsCAutoString str;  // outside loop to minimize memory churn
 
   while (tokenizer.hasMoreTokens()) {
     CopyUTF16toUTF8(tokenizer.nextToken(), str); // NS_ConvertUTF16toUTF8
     const char *token = str.get();
-    if (token == '\0') {
+    if (*token == '\0') {
       return NS_ERROR_DOM_SYNTAX_ERR; // nothing between commas
     }
     char *end;
     float num = float(PR_strtod(token, &end));
     if (*end != '\0' || !NS_finite(num)) {
       return NS_ERROR_DOM_SYNTAX_ERR;
     }
     if (!temp.AppendItem(num)) {
--- a/content/svg/content/src/nsSVGSVGElement.cpp
+++ b/content/svg/content/src/nsSVGSVGElement.cpp
@@ -182,23 +182,23 @@ nsSVGSVGElement::nsSVGSVGElement(already
 nsresult
 nsSVGSVGElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
 {
   *aResult = nullptr;
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
   nsSVGSVGElement *it = new nsSVGSVGElement(ni.forget(), NOT_FROM_PARSER);
 
   nsCOMPtr<nsINode> kungFuDeathGrip = it;
-  nsresult rv = it->Init();
-  rv |= const_cast<nsSVGSVGElement*>(this)->CopyInnerTo(it);
-  if (NS_SUCCEEDED(rv)) {
+  nsresult rv1 = it->Init();
+  nsresult rv2 = const_cast<nsSVGSVGElement*>(this)->CopyInnerTo(it);
+  if (NS_SUCCEEDED(rv1) && NS_SUCCEEDED(rv2)) {
     kungFuDeathGrip.swap(*aResult);
   }
 
-  return rv;
+  return NS_FAILED(rv1) ? rv1 : rv2;
 }
 
 
 //----------------------------------------------------------------------
 // nsIDOMSVGSVGElement methods:
 
 /* readonly attribute nsIDOMSVGAnimatedLength x; */
 NS_IMETHODIMP
--- a/content/svg/content/src/nsSVGScriptElement.cpp
+++ b/content/svg/content/src/nsSVGScriptElement.cpp
@@ -123,19 +123,20 @@ nsresult
 nsSVGScriptElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
 {
   *aResult = nullptr;
 
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
   nsSVGScriptElement* it = new nsSVGScriptElement(ni.forget(), NOT_FROM_PARSER);
 
   nsCOMPtr<nsINode> kungFuDeathGrip = it;
-  nsresult rv = it->Init();
-  rv |= const_cast<nsSVGScriptElement*>(this)->CopyInnerTo(it);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsresult rv1 = it->Init();
+  nsresult rv2 = const_cast<nsSVGScriptElement*>(this)->CopyInnerTo(it);
+  NS_ENSURE_SUCCESS(rv1, rv1);
+  NS_ENSURE_SUCCESS(rv2, rv2);
 
   // The clone should be marked evaluated if we are.
   it->mAlreadyStarted = mAlreadyStarted;
   it->mLineNumber = mLineNumber;
   it->mMalformed = mMalformed;
 
   kungFuDeathGrip.swap(*aResult);
 
--- a/content/svg/content/src/nsSVGUseElement.cpp
+++ b/content/svg/content/src/nsSVGUseElement.cpp
@@ -102,27 +102,27 @@ nsSVGUseElement::Clone(nsINodeInfo *aNod
   *aResult = nullptr;
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
   nsSVGUseElement *it = new nsSVGUseElement(ni.forget());
   if (!it) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   nsCOMPtr<nsINode> kungFuDeathGrip(it);
-  nsresult rv = it->Init();
-  rv |= const_cast<nsSVGUseElement*>(this)->CopyInnerTo(it);
+  nsresult rv1 = it->Init();
+  nsresult rv2 = const_cast<nsSVGUseElement*>(this)->CopyInnerTo(it);
 
   // nsSVGUseElement specific portion - record who we cloned from
   it->mOriginal = const_cast<nsSVGUseElement*>(this);
 
-  if (NS_SUCCEEDED(rv)) {
+  if (NS_SUCCEEDED(rv1) && NS_SUCCEEDED(rv2)) {
     kungFuDeathGrip.swap(*aResult);
   }
 
-  return rv;
+  return NS_FAILED(rv1) ? rv1 : rv2;
 }
 
 //----------------------------------------------------------------------
 // nsIDOMSVGURIReference methods
 
 /* readonly attribute nsIDOMSVGAnimatedString href; */
   NS_IMETHODIMP nsSVGUseElement::GetHref(nsIDOMSVGAnimatedString * *aHref)
 {
--- a/content/svg/content/test/test_SVGLengthList.xhtml
+++ b/content/svg/content/test/test_SVGLengthList.xhtml
@@ -56,16 +56,20 @@ function run_tests()
   eventChecker.expect("modify");
   lengths[0].valueAsString = "10";
   eventChecker.expect("");
   lengths[0].value = 10;
   lengths[0].valueInSpecifiedUnits = 10;
   lengths[0].valueAsString = "10";
   lengths[0].convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_NUMBER);
   lengths[0].newValueSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_NUMBER, 10);
+  // -- Invalid attribute
+  eventChecker.expect("modify");
+  text.setAttribute("x", ",20");
+  is(lengths.numberOfItems, 0, 'Checking that parsing stops at invalid token');
   // -- Attribute removal
   eventChecker.expect("remove");
   text.removeAttribute("x");
   // -- Non-existent attribute removal
   eventChecker.expect("");
   text.removeAttribute("x");
   text.removeAttributeNS(null, "x");
   eventChecker.finish();
--- a/content/svg/content/test/test_SVGNumberList.xhtml
+++ b/content/svg/content/test/test_SVGNumberList.xhtml
@@ -45,16 +45,20 @@ function run_tests()
   eventChecker.expect("modify modify");
   numbers[0].value = 15;
   text.setAttribute("rotate", "17 20 30");
   // -- Redundant changes
   eventChecker.expect("");
   numbers[0].value = 17;
   numbers[1].value = 20;
   text.setAttribute("rotate", "17 20 30");
+  // -- Invalid attribute
+  eventChecker.expect("modify");
+  text.setAttribute("rotate", ",20");
+  is(numbers.numberOfItems, 0, 'Checking that parsing stops at invalid token');
   // -- Attribute removal
   eventChecker.expect("remove");
   text.removeAttribute("rotate");
   // -- Non-existent attribute removal
   eventChecker.expect("");
   text.removeAttribute("rotate");
   text.removeAttributeNS(null, "rotate");
   eventChecker.finish();
--- a/content/svg/content/test/test_SVGPointList.xhtml
+++ b/content/svg/content/test/test_SVGPointList.xhtml
@@ -45,16 +45,20 @@ function run_tests()
   eventChecker.expect("modify modify");
   points[0].x = 40;
   polyline.setAttribute("points", "30,375 150,380");
   // -- Redundant changes
   eventChecker.expect("");
   points[0].x = 30;
   points[1].y = 380;
   polyline.setAttribute("points", "30,375 150,380");
+  // -- Invalid attribute
+  eventChecker.expect("modify");
+  polyline.setAttribute("points", ",30,375");
+  is(points.numberOfItems, 0, 'Checking that parsing stops at invalid token');
   // -- Attribute removal
   eventChecker.expect("remove");
   polyline.removeAttribute("points");
   // -- Non-existent attribute removal
   eventChecker.expect("");
   polyline.removeAttribute("points");
   polyline.removeAttributeNS(null, "points");
   eventChecker.finish();
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -225,25 +225,25 @@ FieldGetterImpl(JSContext *cx, JS::CallA
   bool installed = false;
   JS::Rooted<JSObject*> callee(cx, &args.calleev().toObject());
   JS::Rooted<jsid> id(cx);
   if (!InstallXBLField(cx, callee, thisObj, id.address(), &installed)) {
     return false;
   }
 
   if (!installed) {
-    args.rval() = JS::UndefinedValue();
+    args.rval().setUndefined();
     return true;
   }
 
   JS::Rooted<JS::Value> v(cx);
   if (!JS_GetPropertyById(cx, thisObj, id, v.address())) {
     return false;
   }
-  args.rval() = v;
+  args.rval().set(v);
   return true;
 }
 
 static JSBool
 FieldGetter(JSContext *cx, unsigned argc, JS::Value *vp)
 {
   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
   return JS::CallNonGenericMethod(cx, ValueHasISupportsPrivate, FieldGetterImpl,
--- a/content/xbl/src/nsXBLDocumentInfo.cpp
+++ b/content/xbl/src/nsXBLDocumentInfo.cpp
@@ -107,25 +107,25 @@ nsXBLDocGlobalObject::doCheckAccess(JSCo
 
   nsresult rv = ssm->CheckPropertyAccess(cx, obj, JS_GetClass(obj)->name,
                                          id, accessType);
   return NS_SUCCEEDED(rv);
 }
 
 static JSBool
 nsXBLDocGlobalObject_getProperty(JSContext *cx, JSHandleObject obj,
-                                 JSHandleId id, jsval *vp)
+                                 JSHandleId id, JSMutableHandleValue vp)
 {
   return nsXBLDocGlobalObject::
     doCheckAccess(cx, obj, id, nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
 }
 
 static JSBool
 nsXBLDocGlobalObject_setProperty(JSContext *cx, JSHandleObject obj,
-                                 JSHandleId id, JSBool strict, jsval *vp)
+                                 JSHandleId id, JSBool strict, JSMutableHandleValue vp)
 {
   return nsXBLDocGlobalObject::
     doCheckAccess(cx, obj, id, nsIXPCSecurityManager::ACCESS_SET_PROPERTY);
 }
 
 static JSBool
 nsXBLDocGlobalObject_checkAccess(JSContext *cx, JSHandleObject obj, JSHandleId id,
                                  JSAccessMode mode, jsval *vp)
--- a/content/xslt/tests/mochitest/test_bug427060.html
+++ b/content/xslt/tests/mochitest/test_bug427060.html
@@ -15,30 +15,30 @@ https://bugzilla.mozilla.org/show_bug.cg
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 427060 **/
 
 var xmldoc, xsltdoc;
-[ xmldoc, xsltdoc ] = [ new DOMParser().parseFromString(String(xml), "text/xml") for each (xml in [ 
+[ xmldoc, xsltdoc ] = [ new DOMParser().parseFromString(xml, "text/xml") for each (xml in [ 
 
-    <opml version="1.0"><body></body></opml> ,
+    '<opml version="1.0"><body></body></opml>' ,
 
-    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-    	<xsl:template match="/opml">
-    		<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-    			<head>
-    				<base target="_blank"></base>
-    			</head>
-    			<body></body>
-    		</html>
-    	</xsl:template>
-    </xsl:stylesheet>
+    '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\n\
+    	<xsl:template match="/opml">\n\
+    		<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n\
+    			<head>\n\
+    				<base target="_blank"></base>\n\
+    			</head>\n\
+    			<body></body>\n\
+    		</html>\n\
+    	</xsl:template>\n\
+    </xsl:stylesheet>'
 
 ]) ];
 
 var processor = new XSLTProcessor;
 processor.importStylesheet(xsltdoc);
 try
 {
   var result = processor.transformToDocument(xmldoc);
--- a/content/xslt/tests/mochitest/test_bug440974.html
+++ b/content/xslt/tests/mochitest/test_bug440974.html
@@ -21,24 +21,24 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 function isTxResult(node)
 {
   return node.namespaceURI == "http://www.mozilla.org/TransforMiix" &&
          node.localName == "result";
 }
 
 var xmldoc, xsltdoc;
-[ xmldoc, xsltdoc ] = [ new DOMParser().parseFromString(String(xml), "text/xml") for each (xml in [ 
+[ xmldoc, xsltdoc ] = [ new DOMParser().parseFromString(xml, "text/xml") for each (xml in [ 
 
-    <items><item><id>1</id></item><item><id>2</id></item><item><id>3</id></item></items> ,
+    '<items><item><id>1</id></item><item><id>2</id></item><item><id>3</id></item></items>' ,
 
-    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-        <xsl:output method="xml" />
-        <xsl:template match="item"><foo id="{id}"/></xsl:template>
-    </xsl:stylesheet>
+    '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\n\
+        <xsl:output method="xml" />\n\
+        <xsl:template match="item"><foo id="{id}"/></xsl:template>\n\
+    </xsl:stylesheet>'
 
 ]) ];
 var processor = new XSLTProcessor;
 processor.importStylesheet(xsltdoc);
 var result = processor.transformToDocument(xmldoc);
 var resultElements = Array.prototype.filter.call(result.getElementsByTagName('*'), isTxResult);
 is(resultElements.length, 1, "there should be only one 'transformiix:result' element"); 
 is(resultElements[0], result.documentElement, "the 'transformiix:result' element should be the document element"); 
--- a/content/xslt/tests/mochitest/test_bug453441.html
+++ b/content/xslt/tests/mochitest/test_bug453441.html
@@ -18,40 +18,40 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 453441 **/
 
 function tryImportStylesheet(xml, valid)
 {
   var processor = new XSLTProcessor;
 
-  var xsltdoc = new DOMParser().parseFromString(String(xml), "text/xml");
+  var xsltdoc = new DOMParser().parseFromString(xml, "text/xml");
   try
   {
     processor.importStylesheet(xsltdoc);
     ok(valid, "should be able to parse this XSLT stylesheet");
   }
   catch (e)
   {
     ok(!valid, "should not be able to parse this XSLT stylesheet");
   }
 }
 
 tryImportStylesheet(
-  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-  <xsl:template match="/">
-    <html xmlns="http://www.w3.org/1999/xhtml" xsl:version="1.0" />
-  </xsl:template>
-  </xsl:stylesheet>
+  '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\n\
+  <xsl:template match="/">\n\
+    <html xmlns="http://www.w3.org/1999/xhtml" xsl:version="1.0" />\n\
+  </xsl:template>\n\
+  </xsl:stylesheet>'
 , true);
 
 tryImportStylesheet(
-  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" />
+  '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" />'
 , false);
 
 tryImportStylesheet(
-  <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" />
+  '<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" />'
 , false);
 
 </script>
 </pre>
 </body>
 </html>
--- a/content/xslt/tests/mochitest/test_bug468208.html
+++ b/content/xslt/tests/mochitest/test_bug468208.html
@@ -14,23 +14,22 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 468208 **/
-
 var xslt =
-    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-        <xsl:strip-space elements="color"/>
-    </xsl:stylesheet>
+    '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\n\
+        <xsl:strip-space elements="color"/>\n\
+    </xsl:stylesheet>'
 ;
-var xsltdoc = new DOMParser().parseFromString(String(xslt), "text/xml"); 
+var xsltdoc = new DOMParser().parseFromString(xslt, "text/xml"); 
 
 var processor = new XSLTProcessor;
 processor.importStylesheet(xsltdoc);
 ok(true, "XSLT shouldn't leak");
 </script>
 </pre>
 </body>
 </html>
--- a/content/xul/content/src/Makefile.in
+++ b/content/xul/content/src/Makefile.in
@@ -33,16 +33,18 @@ FORCE_STATIC_LIB = 1
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES	= \
 	-I$(srcdir)/../../document/src \
 	-I$(srcdir)/../../templates/src \
 	-I$(srcdir)/../../../xml/content/src \
 	-I$(srcdir)/../../../base/src \
 	-I$(srcdir)/../../../xml/document/src \
+	-I$(srcdir)/../../../../layout/generic \
 	-I$(srcdir)/../../../../layout/style \
+	-I$(srcdir)/../../../../layout/xul/base/src \
 	-I$(srcdir)/../../../html/content/src \
 	-I$(srcdir)/../../../events/src \
 	-I$(srcdir)/../../../xbl/src \
 	-I$(topsrcdir)/xpcom/ds \
 	$(NULL)
 
 DEFINES += -D_IMPL_NS_LAYOUT
--- a/content/xul/content/src/nsXULContextMenuBuilder.cpp
+++ b/content/xul/content/src/nsXULContextMenuBuilder.cpp
@@ -191,17 +191,17 @@ nsXULContextMenuBuilder::Init(nsIDOMDocu
   mGeneratedItemIdAttr = do_GetAtom(aGeneratedItemIdAttrName);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULContextMenuBuilder::Click(const nsAString& aGeneratedItemId)
 {
-  PRInt32 rv;
+  nsresult rv;
   PRInt32 idx = nsString(aGeneratedItemId).ToInteger(&rv);
   if (NS_SUCCEEDED(rv)) {
     nsCOMPtr<nsIDOMHTMLElement> element = mElements.SafeObjectAt(idx);
     if (element) {
       element->Click();
     }
   }
 
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -1930,20 +1930,26 @@ nsXULPrototypeElement::Serialize(nsIObje
     nsresult rv;
 
     // Write basic prototype data
     rv = aStream->Write32(mType);
 
     // Write Node Info
     PRInt32 index = aNodeInfos->IndexOf(mNodeInfo);
     NS_ASSERTION(index >= 0, "unknown nsINodeInfo index");
-    rv |= aStream->Write32(index);
+    nsresult tmp = aStream->Write32(index);
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
 
     // Write Attributes
-    rv |= aStream->Write32(mNumAttributes);
+    tmp = aStream->Write32(mNumAttributes);
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
 
     nsAutoString attributeValue;
     PRUint32 i;
     for (i = 0; i < mNumAttributes; ++i) {
         nsCOMPtr<nsINodeInfo> ni;
         if (mAttributes[i].mName.IsAtom()) {
             ni = mNodeInfo->NodeInfoManager()->
                 GetNodeInfo(mAttributes[i].mName.Atom(), nullptr,
@@ -1952,51 +1958,78 @@ nsXULPrototypeElement::Serialize(nsIObje
             NS_ASSERTION(ni, "the nodeinfo should already exist");
         }
         else {
             ni = mAttributes[i].mName.NodeInfo();
         }
 
         index = aNodeInfos->IndexOf(ni);
         NS_ASSERTION(index >= 0, "unknown nsINodeInfo index");
-        rv |= aStream->Write32(index);
+        tmp = aStream->Write32(index);
+        if (NS_FAILED(tmp)) {
+          rv = tmp;
+        }
 
         mAttributes[i].mValue.ToString(attributeValue);
-        rv |= aStream->WriteWStringZ(attributeValue.get());
+        tmp = aStream->WriteWStringZ(attributeValue.get());
+        if (NS_FAILED(tmp)) {
+          rv = tmp;
+        }
     }
 
     // Now write children
-    rv |= aStream->Write32(PRUint32(mChildren.Length()));
+    tmp = aStream->Write32(PRUint32(mChildren.Length()));
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
     for (i = 0; i < mChildren.Length(); i++) {
         nsXULPrototypeNode* child = mChildren[i].get();
         switch (child->mType) {
         case eType_Element:
         case eType_Text:
         case eType_PI:
-            rv |= child->Serialize(aStream, aGlobal, aNodeInfos);
+            tmp = child->Serialize(aStream, aGlobal, aNodeInfos);
+            if (NS_FAILED(tmp)) {
+              rv = tmp;
+            }
             break;
         case eType_Script:
-            rv |= aStream->Write32(child->mType);
+            tmp = aStream->Write32(child->mType);
+            if (NS_FAILED(tmp)) {
+              rv = tmp;
+            }
             nsXULPrototypeScript* script = static_cast<nsXULPrototypeScript*>(child);
 
-            rv |= aStream->Write8(script->mOutOfLine);
+            tmp = aStream->Write8(script->mOutOfLine);
+            if (NS_FAILED(tmp)) {
+              rv = tmp;
+            }
             if (! script->mOutOfLine) {
-                rv |= script->Serialize(aStream, aGlobal, aNodeInfos);
+                tmp = script->Serialize(aStream, aGlobal, aNodeInfos);
+                if (NS_FAILED(tmp)) {
+                  rv = tmp;
+                }
             } else {
-                rv |= aStream->WriteCompoundObject(script->mSrcURI,
+                tmp = aStream->WriteCompoundObject(script->mSrcURI,
                                                    NS_GET_IID(nsIURI),
                                                    true);
+                if (NS_FAILED(tmp)) {
+                  rv = tmp;
+                }
 
                 if (script->mScriptObject.mObject) {
                     // This may return NS_OK without muxing script->mSrcURI's
                     // data into the cache file, in the case where that
                     // muxed document is already there (written by a prior
                     // session, or by an earlier cache episode during this
                     // session).
-                    rv |= script->SerializeOutOfLine(aStream, aGlobal);
+                    tmp = script->SerializeOutOfLine(aStream, aGlobal);
+                    if (NS_FAILED(tmp)) {
+                      rv = tmp;
+                    }
                 }
             }
             break;
         }
     }
 
     return rv;
 }
@@ -2012,96 +2045,135 @@ nsXULPrototypeElement::Deserialize(nsIOb
     // Read Node Info
     PRUint32 number;
     nsresult rv = aStream->Read32(&number);
     mNodeInfo = aNodeInfos->SafeObjectAt(number);
     if (!mNodeInfo)
         return NS_ERROR_UNEXPECTED;
 
     // Read Attributes
-    rv |= aStream->Read32(&number);
+    nsresult tmp = aStream->Read32(&number);
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
     mNumAttributes = PRInt32(number);
 
     PRUint32 i;
     if (mNumAttributes > 0) {
         mAttributes = new nsXULPrototypeAttribute[mNumAttributes];
         if (! mAttributes)
             return NS_ERROR_OUT_OF_MEMORY;
 
         nsAutoString attributeValue;
         for (i = 0; i < mNumAttributes; ++i) {
-            rv |= aStream->Read32(&number);
+            tmp = aStream->Read32(&number);
+            if (NS_FAILED(tmp)) {
+              rv = tmp;
+            }
             nsINodeInfo* ni = aNodeInfos->SafeObjectAt(number);
             if (!ni)
                 return NS_ERROR_UNEXPECTED;
 
             mAttributes[i].mName.SetTo(ni);
 
-            rv |= aStream->ReadString(attributeValue);
-            rv |= SetAttrAt(i, attributeValue, aDocumentURI);
+            tmp = aStream->ReadString(attributeValue);
+            if (NS_FAILED(tmp)) {
+              rv = tmp;
+            }
+            tmp = SetAttrAt(i, attributeValue, aDocumentURI);
+            if (NS_FAILED(tmp)) {
+              rv = tmp;
+            }
         }
     }
 
-    rv |= aStream->Read32(&number);
+    tmp = aStream->Read32(&number);
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
     PRUint32 numChildren = PRInt32(number);
 
     if (numChildren > 0) {
         if (!mChildren.SetCapacity(numChildren))
             return NS_ERROR_OUT_OF_MEMORY;
 
         for (i = 0; i < numChildren; i++) {
-            rv |= aStream->Read32(&number);
+            tmp = aStream->Read32(&number);
+            if (NS_FAILED(tmp)) {
+              rv = tmp;
+            }
             Type childType = (Type)number;
 
             nsRefPtr<nsXULPrototypeNode> child;
 
             switch (childType) {
             case eType_Element:
                 child = new nsXULPrototypeElement();
                 if (! child)
                     return NS_ERROR_OUT_OF_MEMORY;
                 child->mType = childType;
 
-                rv |= child->Deserialize(aStream, aGlobal, aDocumentURI,
+                tmp = child->Deserialize(aStream, aGlobal, aDocumentURI,
                                          aNodeInfos);
+                if (NS_FAILED(tmp)) {
+                  rv = tmp;
+                }
                 break;
             case eType_Text:
                 child = new nsXULPrototypeText();
                 if (! child)
                     return NS_ERROR_OUT_OF_MEMORY;
                 child->mType = childType;
 
-                rv |= child->Deserialize(aStream, aGlobal, aDocumentURI,
+                tmp = child->Deserialize(aStream, aGlobal, aDocumentURI,
                                          aNodeInfos);
+                if (NS_FAILED(tmp)) {
+                  rv = tmp;
+                }
                 break;
             case eType_PI:
                 child = new nsXULPrototypePI();
                 if (! child)
                     return NS_ERROR_OUT_OF_MEMORY;
                 child->mType = childType;
 
-                rv |= child->Deserialize(aStream, aGlobal, aDocumentURI,
+                tmp = child->Deserialize(aStream, aGlobal, aDocumentURI,
                                          aNodeInfos);
+                if (NS_FAILED(tmp)) {
+                  rv = tmp;
+                }
                 break;
             case eType_Script: {
                 // language version/options obtained during deserialization.
                 nsXULPrototypeScript* script = new nsXULPrototypeScript(0, 0);
                 if (! script)
                     return NS_ERROR_OUT_OF_MEMORY;
                 child = script;
                 child->mType = childType;
 
-                rv |= aStream->ReadBoolean(&script->mOutOfLine);
+                tmp = aStream->ReadBoolean(&script->mOutOfLine);
+                if (NS_FAILED(tmp)) {
+                  rv = tmp;
+                }
                 if (! script->mOutOfLine) {
-                    rv |= script->Deserialize(aStream, aGlobal, aDocumentURI,
+                    tmp = script->Deserialize(aStream, aGlobal, aDocumentURI,
                                               aNodeInfos);
+                    if (NS_FAILED(tmp)) {
+                      rv = tmp;
+                    }
                 } else {
-                    rv |= aStream->ReadObject(true, getter_AddRefs(script->mSrcURI));
+                    tmp = aStream->ReadObject(true, getter_AddRefs(script->mSrcURI));
+                    if (NS_FAILED(tmp)) {
+                      rv = tmp;
+                    }
 
-                    rv |= script->DeserializeOutOfLine(aStream, aGlobal);
+                    tmp = script->DeserializeOutOfLine(aStream, aGlobal);
+                    if (NS_FAILED(tmp)) {
+                      rv = tmp;
+                    }
                 }
                 // If we failed to deserialize, consider deleting 'script'?
                 break;
             }
             default:
                 NS_NOTREACHED("Unexpected child type!");
                 rv = NS_ERROR_UNEXPECTED;
             }
@@ -2267,18 +2339,24 @@ nsXULPrototypeScript::SerializeOutOfLine
      */
     if (exists)
         return NS_OK;
 
     nsCOMPtr<nsIObjectOutputStream> oos;
     rv = cache->GetOutputStream(mSrcURI, getter_AddRefs(oos));
     NS_ENSURE_SUCCESS(rv, rv);
     
-    rv |= Serialize(oos, aGlobal, nullptr);
-    rv |= cache->FinishOutputStream(mSrcURI);
+    nsresult tmp = Serialize(oos, aGlobal, nullptr);
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
+    tmp = cache->FinishOutputStream(mSrcURI);
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
 
     if (NS_FAILED(rv))
         cache->AbortCaching();
     return rv;
 }
 
 
 nsresult
@@ -2485,17 +2563,20 @@ nsXULPrototypeText::Serialize(nsIObjectO
                               nsIScriptGlobalObject* aGlobal,
                               const nsCOMArray<nsINodeInfo> *aNodeInfos)
 {
     nsresult rv;
 
     // Write basic prototype data
     rv = aStream->Write32(mType);
 
-    rv |= aStream->WriteWStringZ(mValue.get());
+    nsresult tmp = aStream->WriteWStringZ(mValue.get());
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
 
     return rv;
 }
 
 nsresult
 nsXULPrototypeText::Deserialize(nsIObjectInputStream* aStream,
                                 nsIScriptGlobalObject* aGlobal,
                                 nsIURI* aDocumentURI,
@@ -2518,27 +2599,36 @@ nsXULPrototypePI::Serialize(nsIObjectOut
                             nsIScriptGlobalObject* aGlobal,
                             const nsCOMArray<nsINodeInfo> *aNodeInfos)
 {
     nsresult rv;
 
     // Write basic prototype data
     rv = aStream->Write32(mType);
 
-    rv |= aStream->WriteWStringZ(mTarget.get());
-    rv |= aStream->WriteWStringZ(mData.get());
+    nsresult tmp = aStream->WriteWStringZ(mTarget.get());
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
+    tmp = aStream->WriteWStringZ(mData.get());
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
 
     return rv;
 }
 
 nsresult
 nsXULPrototypePI::Deserialize(nsIObjectInputStream* aStream,
                               nsIScriptGlobalObject* aGlobal,
                               nsIURI* aDocumentURI,
                               const nsCOMArray<nsINodeInfo> *aNodeInfos)
 {
     nsresult rv;
 
     rv = aStream->ReadString(mTarget);
-    rv |= aStream->ReadString(mData);
+    nsresult tmp = aStream->ReadString(mData);
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
 
     return rv;
 }
--- a/content/xul/content/src/nsXULPopupListener.cpp
+++ b/content/xul/content/src/nsXULPopupListener.cpp
@@ -38,16 +38,17 @@
 
 // for event firing in context menus
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsFocusManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsIViewManager.h"
 #include "nsDOMError.h"
+#include "nsMenuFrame.h"
 
 using namespace mozilla;
 
 // on win32 and os/2, context menus come up on mouse up. On other platforms,
 // they appear on mouse down. Certain bits of code care about this difference.
 #if defined(XP_WIN) || defined(XP_OS2)
 #define NS_CONTEXT_MENU_IS_MOUSEUP 1
 #endif
@@ -382,18 +383,18 @@ nsXULPopupListener::LaunchPopup(nsIDOMEv
   if ( !popupElement || popupElement == mElement)
     return NS_OK;
 
   // Submenus can't be used as context menus or popups, bug 288763.
   // Similar code also in nsXULTooltipListener::GetTooltipFor.
   nsCOMPtr<nsIContent> popup = do_QueryInterface(popupElement);
   nsIContent* parent = popup->GetParent();
   if (parent) {
-    nsIFrame* frame = parent->GetPrimaryFrame();
-    if (frame && frame->GetType() == nsGkAtoms::menuFrame)
+    nsMenuFrame* menu = do_QueryFrame(parent->GetPrimaryFrame());
+    if (menu)
       return NS_OK;
   }
 
   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
   if (!pm)
     return NS_OK;
 
   // For left-clicks, if the popup has an position attribute, or both the
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -4417,17 +4417,17 @@ nsXULDocument::InsertElement(nsIContent*
     }
 
     if (!wasInserted) {
 
         aChild->GetAttr(kNameSpaceID_None, nsGkAtoms::position, posStr);
         if (!posStr.IsEmpty()) {
             nsresult rv;
             // Positions are one-indexed.
-            PRInt32 pos = posStr.ToInteger(reinterpret_cast<PRInt32*>(&rv));
+            PRInt32 pos = posStr.ToInteger(&rv);
             // Note: if the insertion index (which is |pos - 1|) would be less
             // than 0 or greater than the number of children aParent has, then
             // don't insert, since the position is bogus.  Just skip on to
             // appending.
             if (NS_SUCCEEDED(rv) && pos > 0 &&
                 PRUint32(pos - 1) <= aParent->GetChildCount()) {
                 rv = aParent->InsertChildAt(aChild, pos - 1, aNotify);
                 if (NS_SUCCEEDED(rv))
--- a/content/xul/document/src/nsXULPrototypeCache.cpp
+++ b/content/xul/document/src/nsXULPrototypeCache.cpp
@@ -528,17 +528,17 @@ CachePrefChangedCallback(const char* aPr
             cache->AbortCaching();
     }
     return 0;
 }
 
 nsresult
 nsXULPrototypeCache::BeginCaching(nsIURI* aURI)
 {
-    nsresult rv;
+    nsresult rv, tmp;
 
     nsCAutoString path;
     aURI->GetPath(path);
     if (!StringEndsWith(path, NS_LITERAL_CSTRING(".xul")))
         return NS_ERROR_NOT_AVAILABLE;
 
     // Test gStartupCache to decide whether this is the first nsXULDocument
     // participating in the serialization.  If gStartupCache is non-null, this document
@@ -601,17 +601,20 @@ nsXULPrototypeCache::BeginCaching(nsIURI
     rv = startupCache->GetBuffer(kXULCacheInfoKey, getter_Transfers(buf), 
                                  &len);
     if (NS_SUCCEEDED(rv))
         rv = NewObjectInputStreamFromBuffer(buf, len, getter_AddRefs(objectInput));
     
     if (NS_SUCCEEDED(rv)) {
         buf.forget();
         rv = objectInput->ReadCString(fileLocale);
-        rv |= objectInput->ReadCString(fileChromePath);
+        tmp = objectInput->ReadCString(fileChromePath);
+        if (NS_FAILED(tmp)) {
+          rv = tmp;
+        }
         if (NS_FAILED(rv) ||
             (!fileChromePath.Equals(chromePath) ||
              !fileLocale.Equals(locale))) {
             // Our cache won't be valid in this case, we'll need to rewrite.
             // XXX This blows away work that other consumers (like
             // mozJSComponentLoader) have done, need more fine-grained control.
             startupCache->InvalidateCache();
             rv = NS_ERROR_UNEXPECTED;
@@ -625,19 +628,28 @@ nsXULPrototypeCache::BeginCaching(nsIURI
         nsCOMPtr<nsIObjectOutputStream> objectOutput;
         nsCOMPtr<nsIInputStream> inputStream;
         nsCOMPtr<nsIStorageStream> storageStream;
         rv = NewObjectOutputWrappedStorageStream(getter_AddRefs(objectOutput),
                                                  getter_AddRefs(storageStream),
                                                  false);
         if (NS_SUCCEEDED(rv)) {
             rv = objectOutput->WriteStringZ(locale.get());
-            rv |= objectOutput->WriteStringZ(chromePath.get());
-            rv |= objectOutput->Close();
-            rv |= storageStream->NewInputStream(0, getter_AddRefs(inputStream));
+            tmp = objectOutput->WriteStringZ(chromePath.get());
+            if (NS_FAILED(tmp)) {
+              rv = tmp;
+            }
+            tmp = objectOutput->Close();
+            if (NS_FAILED(tmp)) {
+              rv = tmp;
+            }
+            tmp = storageStream->NewInputStream(0, getter_AddRefs(inputStream));
+            if (NS_FAILED(tmp)) {
+              rv = tmp;
+            }
         }
         if (NS_SUCCEEDED(rv))
             rv = inputStream->Available(&len);
         
         if (NS_SUCCEEDED(rv)) {
             buf = new char[len];
             rv = inputStream->Read(buf, len, &amtRead);
             if (NS_SUCCEEDED(rv) && len == amtRead)
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -246,94 +246,138 @@ nsXULPrototypeDocument::Read(nsIObjectIn
     NS_TIME_FUNCTION;
     nsresult rv;
 
     rv = aStream->ReadObject(true, getter_AddRefs(mURI));
 
     PRUint32 count, i;
     nsCOMPtr<nsIURI> styleOverlayURI;
 
-    rv |= aStream->Read32(&count);
-    if (NS_FAILED(rv)) return rv;
+    nsresult tmp = aStream->Read32(&count);
+    if (NS_FAILED(tmp)) {
+      return tmp;
+    }
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
 
     for (i = 0; i < count; ++i) {
-        rv |= aStream->ReadObject(true, getter_AddRefs(styleOverlayURI));
+        tmp = aStream->ReadObject(true, getter_AddRefs(styleOverlayURI));
+        if (NS_FAILED(tmp)) {
+          rv = tmp;
+        }
         mStyleSheetReferences.AppendObject(styleOverlayURI);
     }
 
 
     // nsIPrincipal mNodeInfoManager->mPrincipal
     nsCOMPtr<nsIPrincipal> principal;
-    rv |= aStream->ReadObject(true, getter_AddRefs(principal));
+    tmp = aStream->ReadObject(true, getter_AddRefs(principal));
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
     // Better safe than sorry....
     mNodeInfoManager->SetDocumentPrincipal(principal);
 
 
     // nsIScriptGlobalObject mGlobalObject
     mGlobalObject = NewXULPDGlobalObject();
     if (! mGlobalObject)
         return NS_ERROR_OUT_OF_MEMORY;
 
     mRoot = new nsXULPrototypeElement();
     if (! mRoot)
        return NS_ERROR_OUT_OF_MEMORY;
 
     // nsINodeInfo table
     nsCOMArray<nsINodeInfo> nodeInfos;
 
-    rv |= aStream->Read32(&count);
+    tmp = aStream->Read32(&count);
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
     nsAutoString namespaceURI, prefixStr, localName;
     bool prefixIsNull;
     nsCOMPtr<nsIAtom> prefix;
     for (i = 0; i < count; ++i) {
-        rv |= aStream->ReadString(namespaceURI);
-        rv |= aStream->ReadBoolean(&prefixIsNull);
+        tmp = aStream->ReadString(namespaceURI);
+        if (NS_FAILED(tmp)) {
+          rv = tmp;
+        }
+        tmp = aStream->ReadBoolean(&prefixIsNull);
+        if (NS_FAILED(tmp)) {
+          rv = tmp;
+        }
         if (prefixIsNull) {
             prefix = nullptr;
         } else {
-            rv |= aStream->ReadString(prefixStr);
+            tmp = aStream->ReadString(prefixStr);
+            if (NS_FAILED(tmp)) {
+              rv = tmp;
+            }
             prefix = do_GetAtom(prefixStr);
         }
-        rv |= aStream->ReadString(localName);
+        tmp = aStream->ReadString(localName);
+        if (NS_FAILED(tmp)) {
+          rv = tmp;
+        }
 
         nsCOMPtr<nsINodeInfo> nodeInfo;
         // Using PR_UINT16_MAX here as we don't know which nodeinfos will be
         // used for attributes and which for elements. And that doesn't really
         // matter.
-        rv |= mNodeInfoManager->GetNodeInfo(localName, prefix, namespaceURI,
+        tmp = mNodeInfoManager->GetNodeInfo(localName, prefix, namespaceURI,
                                             PR_UINT16_MAX,
                                             getter_AddRefs(nodeInfo));
+        if (NS_FAILED(tmp)) {
+          rv = tmp;
+        }
         if (!nodeInfos.AppendObject(nodeInfo))
-            rv |= NS_ERROR_OUT_OF_MEMORY;
+          rv = NS_ERROR_OUT_OF_MEMORY;
     }
 
     // Document contents
     PRUint32 type;
     while (NS_SUCCEEDED(rv)) {
-        rv |= aStream->Read32(&type);
+        tmp = aStream->Read32(&type);
+        if (NS_FAILED(tmp)) {
+          rv = tmp;
+        }
 
         if ((nsXULPrototypeNode::Type)type == nsXULPrototypeNode::eType_PI) {
             nsRefPtr<nsXULPrototypePI> pi = new nsXULPrototypePI();
             if (! pi) {
-               rv |= NS_ERROR_OUT_OF_MEMORY;
+               rv = NS_ERROR_OUT_OF_MEMORY;
                break;
             }
 
-            rv |= pi->Deserialize(aStream, mGlobalObject, mURI, &nodeInfos);
-            rv |= AddProcessingInstruction(pi);
+            tmp = pi->Deserialize(aStream, mGlobalObject, mURI, &nodeInfos);
+            if (NS_FAILED(tmp)) {
+              rv = tmp;
+            }
+            tmp = AddProcessingInstruction(pi);
+            if (NS_FAILED(tmp)) {
+              rv = tmp;
+            }
         } else if ((nsXULPrototypeNode::Type)type == nsXULPrototypeNode::eType_Element) {
-            rv |= mRoot->Deserialize(aStream, mGlobalObject, mURI, &nodeInfos);
+            tmp = mRoot->Deserialize(aStream, mGlobalObject, mURI, &nodeInfos);
+            if (NS_FAILED(tmp)) {
+              rv = tmp;
+            }
             break;
         } else {
             NS_NOTREACHED("Unexpected prototype node type");
-            rv |= NS_ERROR_FAILURE;
+            rv = NS_ERROR_FAILURE;
             break;
         }
     }
-    rv |= NotifyLoadDone();
+    tmp = NotifyLoadDone();
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
 
     return rv;
 }
 
 static nsresult
 GetNodeInfos(nsXULPrototypeElement* aPrototype,
              nsCOMArray<nsINodeInfo>& aArray)
 {
@@ -384,75 +428,113 @@ nsXULPrototypeDocument::Write(nsIObjectO
 {
     nsresult rv;
 
     rv = aStream->WriteCompoundObject(mURI, NS_GET_IID(nsIURI), true);
     
     PRUint32 count;
 
     count = mStyleSheetReferences.Count();
-    rv |= aStream->Write32(count);
+    nsresult tmp = aStream->Write32(count);
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
 
     PRUint32 i;
     for (i = 0; i < count; ++i) {
-        rv |= aStream->WriteCompoundObject(mStyleSheetReferences[i],
+        tmp = aStream->WriteCompoundObject(mStyleSheetReferences[i],
                                            NS_GET_IID(nsIURI), true);
+        if (NS_FAILED(tmp)) {
+          rv = tmp;
+        }
     }
 
     // nsIPrincipal mNodeInfoManager->mPrincipal
-    rv |= aStream->WriteObject(mNodeInfoManager->DocumentPrincipal(),
+    tmp = aStream->WriteObject(mNodeInfoManager->DocumentPrincipal(),
                                true);
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
     
 #ifdef DEBUG
     // XXX Worrisome if we're caching things without system principal.
     if (!nsContentUtils::IsSystemPrincipal(mNodeInfoManager->DocumentPrincipal())) {
         NS_WARNING("Serializing document without system principal");
     }
 #endif
 
     // nsINodeInfo table
     nsCOMArray<nsINodeInfo> nodeInfos;
-    if (mRoot)
-        rv |= GetNodeInfos(mRoot, nodeInfos);
+    if (mRoot) {
+      tmp = GetNodeInfos(mRoot, nodeInfos);
+      if (NS_FAILED(tmp)) {
+        rv = tmp;
+      }
+    }
 
     PRUint32 nodeInfoCount = nodeInfos.Count();
-    rv |= aStream->Write32(nodeInfoCount);
+    tmp = aStream->Write32(nodeInfoCount);
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
     for (i = 0; i < nodeInfoCount; ++i) {
         nsINodeInfo *nodeInfo = nodeInfos[i];
         NS_ENSURE_TRUE(nodeInfo, NS_ERROR_FAILURE);
 
         nsAutoString namespaceURI;
-        rv |= nodeInfo->GetNamespaceURI(namespaceURI);
-        rv |= aStream->WriteWStringZ(namespaceURI.get());
+        tmp = nodeInfo->GetNamespaceURI(namespaceURI);
+        if (NS_FAILED(tmp)) {
+          rv = tmp;
+        }
+        tmp = aStream->WriteWStringZ(namespaceURI.get());
+        if (NS_FAILED(tmp)) {
+          rv = tmp;
+        }
 
         nsAutoString prefix;
         nodeInfo->GetPrefix(prefix);
         bool nullPrefix = DOMStringIsNull(prefix);
-        rv |= aStream->WriteBoolean(nullPrefix);
+        tmp = aStream->WriteBoolean(nullPrefix);
+        if (NS_FAILED(tmp)) {
+          rv = tmp;
+        }
         if (!nullPrefix) {
-            rv |= aStream->WriteWStringZ(prefix.get());
+            tmp = aStream->WriteWStringZ(prefix.get());
+            if (NS_FAILED(tmp)) {
+              rv = tmp;
+            }
         }
 
         nsAutoString localName;
         nodeInfo->GetName(localName);
-        rv |= aStream->WriteWStringZ(localName.get());
+        tmp = aStream->WriteWStringZ(localName.get());
+        if (NS_FAILED(tmp)) {
+          rv = tmp;
+        }
     }
 
     // Now serialize the document contents
     nsIScriptGlobalObject* globalObject = GetScriptGlobalObject();
     NS_ENSURE_TRUE(globalObject, NS_ERROR_UNEXPECTED);
 
     count = mProcessingInstructions.Length();
     for (i = 0; i < count; ++i) {
         nsXULPrototypePI* pi = mProcessingInstructions[i];
-        rv |= pi->Serialize(aStream, globalObject, &nodeInfos);
+        tmp = pi->Serialize(aStream, globalObject, &nodeInfos);
+        if (NS_FAILED(tmp)) {
+          rv = tmp;
+        }
     }
 
-    if (mRoot)
-        rv |= mRoot->Serialize(aStream, globalObject, &nodeInfos);
+    if (mRoot) {
+      tmp = mRoot->Serialize(aStream, globalObject, &nodeInfos);
+      if (NS_FAILED(tmp)) {
+        rv = tmp;
+      }
+    }
  
     return rv;
 }
 
 
 //----------------------------------------------------------------------
 //
 
--- a/content/xul/templates/src/nsTemplateRule.cpp
+++ b/content/xul/templates/src/nsTemplateRule.cpp
@@ -150,17 +150,17 @@ nsTemplateCondition::CheckMatchStrings(c
                 else
                     match = aLeftString.Equals(aRightString);
                 break;
 
             case eLess:
             case eGreater:
             {
                 // non-numbers always compare false
-                PRInt32 err;
+                nsresult err;
                 PRInt32 leftint = PromiseFlatString(aLeftString).ToInteger(&err);
                 if (NS_SUCCEEDED(err)) {
                     PRInt32 rightint = PromiseFlatString(aRightString).ToInteger(&err);
                     if (NS_SUCCEEDED(err)) {
                         match = (mRelation == eLess) ? (leftint < rightint) :
                                                        (leftint > rightint);
                     }
                 }
--- a/content/xul/templates/src/nsXULContentBuilder.cpp
+++ b/content/xul/templates/src/nsXULContentBuilder.cpp
@@ -1884,17 +1884,17 @@ nsXULContentBuilder::InsertSortedNode(ns
         // rjc says: determine where static XUL ends and generated XUL/RDF begins
         PRInt32 staticCount = 0;
 
         nsAutoString staticValue;
         aContainer->GetAttr(kNameSpaceID_None, nsGkAtoms::staticHint, staticValue);
         if (!staticValue.IsEmpty())
         {
             // found "static" XUL element count hint
-            PRInt32 strErr = 0;
+            nsresult strErr = NS_OK;
             staticCount = staticValue.ToInteger(&strErr);
             if (strErr)
                 staticCount = 0;
         } else {
             // compute the "static" XUL element count
             for (nsIContent* child = aContainer->GetFirstChild();
                  child;
                  child = child->GetNextSibling()) {
--- a/content/xul/templates/src/nsXULSortService.cpp
+++ b/content/xul/templates/src/nsXULSortService.cpp
@@ -448,17 +448,17 @@ XULSortServiceImpl::InitializeSortState(
 }
 
 PRInt32
 XULSortServiceImpl::CompareValues(const nsAString& aLeft,
                                   const nsAString& aRight,
                                   PRUint32 aSortHints)
 {
   if (aSortHints & SORT_INTEGER) {
-    PRInt32 err;
+    nsresult err;
     PRInt32 leftint = PromiseFlatString(aLeft).ToInteger(&err);
     if (NS_SUCCEEDED(err)) {
       PRInt32 rightint = PromiseFlatString(aRight).ToInteger(&err);
       if (NS_SUCCEEDED(err)) {
         return leftint - rightint;
       }
     }
     // if they aren't integers, just fall through and compare strings
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
@@ -1316,17 +1316,17 @@ nsXULTemplateQueryProcessorRDF::ParseLit
                                              const nsString& aValue,
                                              nsIRDFNode** aResult)
 {
     nsresult rv = NS_OK;
     *aResult = nullptr;
 
     if (aParseType.EqualsLiteral(PARSE_TYPE_INTEGER)) {
         nsCOMPtr<nsIRDFInt> intLiteral;
-        PRInt32 errorCode;
+        nsresult errorCode;
         PRInt32 intValue = aValue.ToInteger(&errorCode);
         if (NS_FAILED(errorCode))
             return NS_ERROR_FAILURE;
         rv = gRDFService->GetIntLiteral(intValue, getter_AddRefs(intLiteral));
         if (NS_FAILED(rv)) 
             return rv;
         rv = CallQueryInterface(intLiteral, aResult);
     }
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -4135,16 +4135,18 @@ nsDocShell::DisplayLoadError(nsresult aE
         case NS_ERROR_UNSAFE_CONTENT_TYPE:
             // Channel refused to load from an unrecognized content type.
             error.AssignLiteral("unsafeContentType");
             break;
         case NS_ERROR_CORRUPTED_CONTENT:
             // Broken Content Detected. e.g. Content-MD5 check failure.
             error.AssignLiteral("corruptedContentError");
             break;
+        default:
+            break;
         }
     }
 
     // Test if the error should be displayed
     if (error.IsEmpty()) {
         return NS_OK;
     }
 
@@ -4265,17 +4267,18 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, 
         mLSHE->AbandonBFCacheEntry();
     }
 
     nsCAutoString url;
     nsCAutoString charset;
     if (aURI)
     {
         nsresult rv = aURI->GetSpec(url);
-        rv |= aURI->GetOriginCharset(charset);
+        NS_ENSURE_SUCCESS(rv, rv);
+        rv = aURI->GetOriginCharset(charset);
         NS_ENSURE_SUCCESS(rv, rv);
     }
     else if (aURL)
     {
         // We need a URI object to store a session history entry, so make up a URI
         nsresult rv = NS_NewURI(getter_AddRefs(mFailedURI), "about:blank");
         NS_ENSURE_SUCCESS(rv, rv);
 
--- a/docshell/base/nsIContentViewer.idl
+++ b/docshell/base/nsIContentViewer.idl
@@ -32,17 +32,17 @@ interface nsIContentViewer : nsISupports
 {
 
   [noscript] void init(in nsIWidgetPtr aParentWidget,
                        [const] in nsIntRectRef aBounds);
 
   attribute nsISupports container;
 
   void loadStart(in nsISupports aDoc);
-  void loadComplete(in unsigned long aStatus);
+  void loadComplete(in nsresult aStatus);
 
   /**
    * Checks if the document wants to prevent unloading by firing beforeunload on
    * the document, and if it does, prompts the user. The result is returned.
    *
    * @param aCallerClosesWindow indicates that the current caller will close the
    *        window. If the method returns true, all subsequent calls will be
    *        ignored.
--- a/dom/Makefile.in
+++ b/dom/Makefile.in
@@ -65,16 +65,17 @@ DIRS += \
   network \
   plugins/base \
   plugins/ipc \
   indexedDB \
   system \
   ipc \
   identity \
   workers \
+  camera \
   $(NULL)
 
 ifdef MOZ_B2G_RIL
 DIRS += \
   telephony \
   wifi \
   $(NULL)
 endif
--- a/dom/alarm/AlarmService.jsm
+++ b/dom/alarm/AlarmService.jsm
@@ -42,17 +42,17 @@ let AlarmService = {
 
     // add the messages to be listened
     const messages = ["AlarmsManager:GetAll", "AlarmsManager:Add", "AlarmsManager:Remove"];
     messages.forEach(function addMessage(msgName) {
         ppmm.addMessageListener(msgName, this);
     }.bind(this));
 
     // set the indexeddb database
-    let idbManager = Components.classes["@mozilla.org/dom/indexeddb/manager;1"].getService(Ci.nsIIndexedDatabaseManager);
+    let idbManager = Cc["@mozilla.org/dom/indexeddb/manager;1"].getService(Ci.nsIIndexedDatabaseManager);
     idbManager.initWindowless(myGlobal);
     this._db = new AlarmDB(myGlobal);
     this._db.init(myGlobal);
 
     // variable to save alarms waiting to be set
     this._alarmQueue = [];
 
     this._restoreAlarmsFromDb();
@@ -95,30 +95,30 @@ let AlarmService = {
         let newAlarm = {
           date: json.date, 
           ignoreTimezone: json.ignoreTimezone, 
           timezoneOffset: this._currentTimezoneOffset, 
           data: json.data,
           manifestURL: json.manifestURL
         };
 
+        let newAlarmTime = this._getAlarmTime(newAlarm);
+        if (newAlarmTime <= Date.now()) {
+          debug("Adding a alarm that has past time. Return DOMError.");
+          this._debugCurrentAlarm();
+          this._sendAsyncMessage(mm, "Add", false, json.requestId, "InvalidStateError");
+          break;
+        }
+
         this._db.add(
           newAlarm,
           function addSuccessCb(aNewId) {
             debug("Callback after adding alarm in database.");
 
             newAlarm['id'] = aNewId;
-            let newAlarmTime = this._getAlarmTime(newAlarm);
-
-            if (newAlarmTime <= Date.now()) {
-              debug("Adding a alarm that has past time. Don't set it in system.");
-              this._debugCurrentAlarm();
-              this._sendAsyncMessage(mm, "Add", true, json.requestId, aNewId);
-              return;
-            }
 
             // if there is no alarm being set in system, set the new alarm
             if (this._currentAlarm == null) {
               this._currentAlarm = newAlarm;
               this._debugCurrentAlarm();
               this._sendAsyncMessage(mm, "Add", true, json.requestId, aNewId);
               return;
             }
@@ -143,17 +143,17 @@ let AlarmService = {
           }.bind(this),
           function addErrorCb(aErrorMsg) {
             this._sendAsyncMessage(mm, "Add", false, json.requestId, aErrorMsg);
           }.bind(this)
         );
         break;
 
       case "AlarmsManager:Remove":
-        this._db.remove(
+        this._removeAlarmFromDb(
           json.id,
           function removeSuccessCb() {
             debug("Callback after removing alarm from database.");
 
             // if there is no alarm being set
             if (!this._currentAlarm) {
               this._debugCurrentAlarm();
               return;
@@ -178,20 +178,17 @@ let AlarmService = {
               this._currentAlarm = alarmQueue.shift();
               this._debugCurrentAlarm();
               return;
             }
 
             // no alarm waiting to be set in the queue
             this._currentAlarm = null;
             this._debugCurrentAlarm();
-          }.bind(this),
-          function removeErrorCb(aErrorMsg) {
-            throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-          }
+          }.bind(this)
         );
         break;
 
       default:
         throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
         break;
     }
   },
@@ -222,39 +219,62 @@ let AlarmService = {
       default:
         throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
         break;
     }
 
     aMessageManager.sendAsyncMessage("AlarmsManager:" + aMessageName + ":Return:" + (aSuccess ? "OK" : "KO"), json);
   },
 
+  _removeAlarmFromDb: function _removeAlarmFromDb(aId, aRemoveSuccessCb) {
+    debug("_removeAlarmFromDb()");
+
+    // If the aRemoveSuccessCb is undefined or null, set a 
+    // dummy callback for it which is needed for _db.remove()
+    if (!aRemoveSuccessCb) {
+      aRemoveSuccessCb = function removeSuccessCb() {
+        debug("Remove alarm from DB successfully.");
+      };
+    }
+
+    this._db.remove(
+      aId,
+      aRemoveSuccessCb,
+      function removeErrorCb(aErrorMsg) {
+        throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+      }
+    );
+  },
+
+  _fireSystemMessage: function _fireSystemMessage(aAlarm) {
+    debug("Fire system message: " + JSON.stringify(aAlarm));
+    let manifestURI = Services.io.newURI(aAlarm.manifestURL, null, null);
+    messenger.sendMessage("alarm", aAlarm, manifestURI);
+  },
+
   _onAlarmFired: function _onAlarmFired() {
     debug("_onAlarmFired()");
 
     if (this._currentAlarm) {
-      debug("Fire system intent: " + JSON.stringify(this._currentAlarm));
-      let manifestURI = Services.io.newURI(this._currentAlarm.manifestURL, null, null);
-      messenger.sendMessage("alarm", this._currentAlarm, manifestURI);
+      this._fireSystemMessage(this._currentAlarm);
+      this._removeAlarmFromDb(this._currentAlarm.id);
       this._currentAlarm = null;
     }
 
-    // reset the next alarm from the queue
-    let nowTime = Date.now();
+    // Reset the next alarm from the queue.
     let alarmQueue = this._alarmQueue;
     while (alarmQueue.length > 0) {
       let nextAlarm = alarmQueue.shift();
       let nextAlarmTime = this._getAlarmTime(nextAlarm);
 
-      // if the next alarm has been expired, directly 
-      // fire system intent for it instead of setting it
-      if (nextAlarmTime <= nowTime) {
-        debug("Fire system intent: " + JSON.stringify(nextAlarm));
-        let manifestURI = Services.io.newURI(nextAlarm.manifestURL, null, null);
-        messenger.sendMessage("alarm", nextAlarm, manifestURI);
+      // If the next alarm has been expired, directly 
+      // fire system message for it instead of setting it.
+      if (nextAlarmTime <= Date.now()) {
+        this._fireSystemMessage(nextAlarm);
+        this._removeAlarmFromDb(nextAlarm.id);
       } else {
         this._currentAlarm = nextAlarm;
         break;
       }
     }
     this._debugCurrentAlarm();
   },
 
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -45,16 +45,18 @@
 #endif
 #ifdef MOZ_B2G_RIL
 #include "TelephonyFactory.h"
 #endif
 #ifdef MOZ_B2G_BT
 #include "nsIDOMBluetoothManager.h"
 #include "BluetoothManager.h"
 #endif
+#include "nsIDOMCameraManager.h"
+#include "DOMCameraManager.h"
 
 #include "nsIDOMGlobalPropertyInitializer.h"
 
 // This should not be in the namespace.
 DOMCI_DATA(Navigator, mozilla::dom::Navigator)
 
 namespace mozilla {
 namespace dom {
@@ -107,16 +109,17 @@ NS_INTERFACE_MAP_BEGIN(Navigator)
 #endif
 #ifdef MOZ_B2G_RIL
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorTelephony)
 #endif
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozNavigatorNetwork)
 #ifdef MOZ_B2G_BT
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorBluetooth)
 #endif
+  NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorCamera)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorSystemMessages)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Navigator)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(Navigator)
 NS_IMPL_RELEASE(Navigator)
 
 void
@@ -176,16 +179,18 @@ Navigator::Invalidate()
   }
 
 #ifdef MOZ_B2G_BT
   if (mBluetooth) {
     mBluetooth = nullptr;
   }
 #endif
 
+  mCameraManager = nullptr;
+
 #ifdef MOZ_SYS_MSG
   if (mMessagesManager) {
     mMessagesManager = nullptr;
   }
 #endif
 
 }
 
@@ -1315,16 +1320,40 @@ Navigator::MozSetMessageHandler(const ns
   NS_ENSURE_SUCCESS(rv, rv);
 
   return mMessagesManager->MozSetMessageHandler(aType, aCallback);
 #else
   return NS_ERROR_NOT_IMPLEMENTED;
 #endif
 }
 
+//*****************************************************************************
+//    nsNavigator::nsIDOMNavigatorCamera
+//*****************************************************************************
+
+NS_IMETHODIMP
+Navigator::GetMozCameras(nsIDOMCameraManager** aCameraManager)
+{
+  if (!mCameraManager) {
+    nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
+    NS_ENSURE_TRUE(win, NS_ERROR_FAILURE);
+
+    if (!win->GetOuterWindow() || win->GetOuterWindow()->GetCurrentInnerWindow() != win) {
+      return NS_ERROR_NOT_AVAILABLE;
+    }
+
+    mCameraManager = nsDOMCameraManager::Create(win->WindowID());
+  }
+
+  nsRefPtr<nsDOMCameraManager> cameraManager = mCameraManager;
+  cameraManager.forget(aCameraManager);
+
+  return NS_OK;
+}
+
 size_t
 Navigator::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
 {
   size_t n = aMallocSizeOf(this);
 
   // TODO: add SizeOfIncludingThis() to nsMimeTypeArray, bug 674113.
   // TODO: add SizeOfIncludingThis() to nsPluginArray, bug 674114.
   // TODO: add SizeOfIncludingThis() to nsGeolocation, bug 674115.
@@ -1339,22 +1368,29 @@ Navigator::SetWindow(nsPIDOMWindow *aInn
   NS_ASSERTION(aInnerWindow->IsInnerWindow(),
                "Navigator must get an inner window!");
   mWindow = do_GetWeakReference(aInnerWindow);
 }
 
 void
 Navigator::OnNavigation()
 {
+  nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
+  if (!win) {
+    return;
+  }
+
+#ifdef MOZ_MEDIA_NAVIGATOR
   // Inform MediaManager in case there are live streams or pending callbacks.
-#ifdef MOZ_MEDIA_NAVIGATOR
   MediaManager *manager = MediaManager::Get();
-  nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
-  return manager->OnNavigation(win->WindowID());
+  manager->OnNavigation(win->WindowID());
 #endif
+  if (mCameraManager) {
+    mCameraManager->OnNavigation(win->WindowID());
+  }
 }
 
 } // namespace dom
 } // namespace mozilla
 
 nsresult
 NS_GetNavigatorUserAgent(nsAString& aUserAgent)
 {
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -36,16 +36,19 @@ class nsIDOMMozVoicemail;
 #endif
 
 #ifdef MOZ_B2G_BT
 #include "nsIDOMNavigatorBluetooth.h"
 #endif
 
 #include "nsIDOMNavigatorSystemMessages.h"
 
+#include "nsIDOMNavigatorCamera.h"
+#include "DOMCameraManager.h"
+
 //*****************************************************************************
 // Navigator: Script "navigator" object
 //*****************************************************************************
 
 namespace mozilla {
 namespace dom {
 
 namespace battery {
@@ -77,16 +80,17 @@ class Navigator : public nsIDOMNavigator
 #endif
 #ifdef MOZ_B2G_RIL
                 , public nsIDOMNavigatorTelephony
 #endif
                 , public nsIDOMMozNavigatorNetwork
 #ifdef MOZ_B2G_BT
                 , public nsIDOMNavigatorBluetooth
 #endif
+                , public nsIDOMNavigatorCamera
                 , public nsIDOMNavigatorSystemMessages
 {
 public:
   Navigator(nsPIDOMWindow *aInnerWindow);
   virtual ~Navigator();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMNAVIGATOR
@@ -129,16 +133,17 @@ public:
    * Called when the inner window navigates to a new page.
    */
   void OnNavigation();
 
 #ifdef MOZ_SYS_MSG
   // Helper to initialize mMessagesManager.
   nsresult EnsureMessagesManager();
 #endif
+  NS_DECL_NSIDOMNAVIGATORCAMERA
 
 private:
   bool IsSmsAllowed() const;
   bool IsSmsSupported() const;
 
   nsRefPtr<nsMimeTypeArray> mMimeTypes;
   nsRefPtr<nsPluginArray> mPlugins;
   nsRefPtr<nsGeolocation> mGeolocation;
@@ -150,16 +155,17 @@ private:
   nsCOMPtr<nsIDOMTelephony> mTelephony;
   nsCOMPtr<nsIDOMMozVoicemail> mVoicemail;
 #endif
   nsRefPtr<network::Connection> mConnection;
   nsRefPtr<network::MobileConnection> mMobileConnection;
 #ifdef MOZ_B2G_BT
   nsCOMPtr<nsIDOMBluetoothManager> mBluetooth;
 #endif
+  nsRefPtr<nsDOMCameraManager> mCameraManager;
   nsCOMPtr<nsIDOMNavigatorSystemMessages> mMessagesManager;
   nsWeakPtr mWindow;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 nsresult NS_GetNavigatorUserAgent(nsAString& aUserAgent);
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -517,16 +517,20 @@ using mozilla::dom::indexedDB::IDBWrappe
 #include "BluetoothDevice.h"
 #include "BluetoothDeviceEvent.h"
 #endif
 
 #include "nsIDOMNavigatorSystemMessages.h"
 
 #include "mozilla/dom/Activity.h"
 
+#include "DOMCameraManager.h"
+#include "CameraControl.h"
+#include "CameraCapabilities.h"
+
 #include "DOMError.h"
 #include "DOMRequest.h"
 #include "nsIOpenWindowEventDetail.h"
 #include "nsIDOMGlobalObjectConstructor.h"
 
 #include "DOMFileHandle.h"
 #include "FileRequest.h"
 #include "LockedFile.h"
@@ -1663,16 +1667,23 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(BluetoothAdapter, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)  
   NS_DEFINE_CLASSINFO_DATA(BluetoothDevice, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(BluetoothDeviceEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 #endif
 
+  NS_DEFINE_CLASSINFO_DATA(CameraManager, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(CameraControl, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(CameraCapabilities, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
   NS_DEFINE_CLASSINFO_DATA(DOMError, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(DOMRequest, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(OpenWindowEventDetail, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
@@ -2461,16 +2472,17 @@ nsDOMClassInfo::Init()
 #ifdef MOZ_B2G_RIL
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorTelephony)
 #endif
     DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIDOMMozNavigatorNetwork,
                                         network::IsAPIEnabled())
 #ifdef MOZ_B2G_BT
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorBluetooth)
 #endif
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorCamera)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorSystemMessages)
 
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Plugin, nsIDOMPlugin)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMPlugin)
   DOM_CLASSINFO_MAP_END
 
@@ -4452,16 +4464,28 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(BluetoothDeviceEvent, nsIDOMBluetoothDeviceEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMBluetoothDeviceEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)
   DOM_CLASSINFO_MAP_END
 #endif
 
+  DOM_CLASSINFO_MAP_BEGIN(CameraManager, nsIDOMCameraManager)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMCameraManager)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(CameraControl, nsICameraControl)
+    DOM_CLASSINFO_MAP_ENTRY(nsICameraControl)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(CameraCapabilities, nsICameraCapabilities)
+    DOM_CLASSINFO_MAP_ENTRY(nsICameraCapabilities)
+  DOM_CLASSINFO_MAP_END
+
   DOM_CLASSINFO_MAP_BEGIN(DOMError, nsIDOMDOMError)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMError)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(DOMRequest, nsIDOMDOMRequest)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMRequest)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
@@ -5277,17 +5301,17 @@ static JSClass sGlobalScopePolluterClass
   JS_ConvertStub,
   nsHTMLDocumentSH::ReleaseDocument
 };
 
 
 // static
 JSBool
 nsWindowSH::GlobalScopePolluterGetProperty(JSContext *cx, JSHandleObject obj,
-                                           JSHandleId id, jsval *vp)
+                                           JSHandleId id, JSMutableHandleValue vp)
 {
   // Someone is accessing a element by referencing its name/id in the
   // global scope, do a security check to make sure that's ok.
 
   nsresult rv =
     sSecMan->CheckPropertyAccess(cx, ::JS_GetGlobalForObject(cx, obj),
                                  "Window", id,
                                  nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
@@ -5300,17 +5324,17 @@ nsWindowSH::GlobalScopePolluterGetProper
   }
 
   return JS_TRUE;
 }
 
 // static
 JSBool
 nsWindowSH::SecurityCheckOnAddDelProp(JSContext *cx, JSHandleObject obj, JSHandleId id,
-                                      jsval *vp)
+                                      JSMutableHandleValue vp)
 {
   // Someone is accessing a element by referencing its name/id in the
   // global scope, do a security check to make sure that's ok.
 
   nsresult rv =
     sSecMan->CheckPropertyAccess(cx, ::JS_GetGlobalForObject(cx, obj),
                                  "Window", id,
                                  nsIXPCSecurityManager::ACCESS_SET_PROPERTY);
@@ -5318,17 +5342,17 @@ nsWindowSH::SecurityCheckOnAddDelProp(JS
   // If !NS_SUCCEEDED(rv) the security check failed. The security
   // manager set a JS exception for us.
   return NS_SUCCEEDED(rv);
 }
 
 // static
 JSBool
 nsWindowSH::SecurityCheckOnSetProp(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict,
-                                   jsval *vp)
+                                   JSMutableHandleValue vp)
 {
   return SecurityCheckOnAddDelProp(cx, obj, id, vp);
 }
 
 static nsHTMLDocument*
 GetDocument(JSObject *obj)
 {
   return static_cast<nsHTMLDocument*>(
@@ -5864,17 +5888,17 @@ static const IDBConstant sIDBConstants[]
   { IDBConstant::IDBRequest,     "LOADING",           "pending" },
   { IDBConstant::IDBRequest,     "DONE",              "done" },
   { IDBConstant::IDBTransaction, "READ_ONLY",         "readonly" },
   { IDBConstant::IDBTransaction, "READ_WRITE",        "readwrite" },
   { IDBConstant::IDBTransaction, "VERSION_CHANGE",    "versionchange" },
 };
 
 static JSBool
-IDBConstantGetter(JSContext *cx, JSHandleObject obj, JSHandleId id, jsval* vp)
+IDBConstantGetter(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp)
 {
   JSString *idstr = JSID_TO_STRING(id);
   unsigned index;
   for (index = 0; index < mozilla::ArrayLength(sIDBConstants); index++) {
     JSBool match;
     if (!JS_StringEqualsAscii(cx, idstr, sIDBConstants[index].name, &match)) {
       return JS_FALSE;
     }
@@ -5938,17 +5962,17 @@ IDBConstantGetter(JSContext *cx, JSHandl
     return JS_FALSE;
   }
   if (!::JS_DefineProperty(cx, obj, c.name, value, nullptr, nullptr,
                            JSPROP_ENUMERATE)) {
     return JS_FALSE;
   }
 
   // Return value
-  *vp = value;
+  vp.set(value);
   return JS_TRUE;
 }
 
 static nsresult
 DefineIDBInterfaceConstants(JSContext *cx, JSObject *obj, const nsIID *aIID)
 {
   const char* interface;
   if (aIID->Equals(NS_GET_IID(nsIIDBCursor))) {
@@ -6999,30 +7023,30 @@ LocationSetterGuts(JSContext *cx, JSObje
   NS_ENSURE_TRUE(depStr.init(cx, val), NS_ERROR_UNEXPECTED);
   
   return location->SetHref(depStr);
 }
 
 template<class Interface>
 static JSBool
 LocationSetter(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict,
-               jsval *vp)
-{
-  nsresult rv = LocationSetterGuts<Interface>(cx, obj, vp);
+               JSMutableHandleValue vp)
+{
+  nsresult rv = LocationSetterGuts<Interface>(cx, obj, vp.address());
   if (NS_FAILED(rv)) {
     xpc::Throw(cx, rv);
     return JS_FALSE;
   }
 
   return JS_TRUE;
 }
 
 static JSBool
 LocationSetterUnwrapper(JSContext *cx, JSHandleObject obj_, JSHandleId id, JSBool strict,
-                        jsval *vp)
+                        JSMutableHandleValue vp)
 {
   JS::RootedObject obj(cx, obj_);
 
   JSObject *wrapped = XPCWrapper::UnsafeUnwrapSecurityWrapper(obj);
   if (wrapped) {
     obj = wrapped;
   }
 
@@ -7674,19 +7698,19 @@ nsNavigatorSH::PreCreate(nsISupports *na
   }
   return SetParentToWindow(win, parentObj);
 }
 
 // DOM Node helper
 
 template<nsresult (*func)(JSContext *cx, JSObject *obj, jsval *vp)>
 static JSBool
-GetterShim(JSContext *cx, JSHandleObject obj, JSHandleId /* unused */, jsval *vp)
-{
-  nsresult rv = (*func)(cx, obj, vp);
+GetterShim(JSContext *cx, JSHandleObject obj, JSHandleId /* unused */, JSMutableHandleValue vp)
+{
+  nsresult rv = (*func)(cx, obj, vp.address());
   if (NS_FAILED(rv)) {
     xpc::Throw(cx, rv);
     return JS_FALSE;
   }
 
   return JS_TRUE;  
 }
 
@@ -8791,23 +8815,26 @@ nsHTMLDocumentSH::GetDocumentAllNodeList
       }
     }
   } else {
     // No node list for this document.all yet, create one...
 
     nsRefPtr<nsContentList> list =
       domdoc->GetElementsByTagName(NS_LITERAL_STRING("*"));
     if (!list) {
-      rv |= NS_ERROR_OUT_OF_MEMORY;
+      rv = NS_ERROR_OUT_OF_MEMORY;
     }
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
-    rv |= WrapNative(cx, JS_GetGlobalForScopeChain(cx),
-                     static_cast<nsINodeList*>(list), list, false,
-                     &collection, getter_AddRefs(holder));
+    nsresult tmp = WrapNative(cx, JS_GetGlobalForScopeChain(cx),
+                              static_cast<nsINodeList*>(list), list, false,
+                              &collection, getter_AddRefs(holder));
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
 
     list.forget(nodeList);
 
     // ... and store it in our reserved slot.
     JS_SetReservedSlot(obj, 0, collection);
   }
 
   if (NS_FAILED(rv)) {
@@ -8816,17 +8843,17 @@ nsHTMLDocumentSH::GetDocumentAllNodeList
     return JS_FALSE;
   }
 
   return *nodeList != nullptr;
 }
 
 JSBool
 nsHTMLDocumentSH::DocumentAllGetProperty(JSContext *cx, JSHandleObject obj_,
-                                         JSHandleId id, jsval *vp)
+                                         JSHandleId id, JSMutableHandleValue vp)
 {
   JSObject *obj = obj_;
 
   // document.all.item and .namedItem get their value in the
   // newResolve hook, so nothing to do for those properties here. And
   // we need to return early to prevent <div id="item"> from shadowing
   // document.all.item(), etc.
   if (sItem_id == id || sNamedItem_id == id) {
@@ -8863,17 +8890,17 @@ nsHTMLDocumentSH::DocumentAllGetProperty
       rv = nodeList->GetLength(&length);
 
       if (NS_FAILED(rv)) {
         xpc::Throw(cx, rv);
 
         return JS_FALSE;
       }
 
-      *vp = INT_TO_JSVAL(length);
+      vp.set(INT_TO_JSVAL(length));
 
       return JS_TRUE;
     } else if (sTags_id != id) {
       // For all other strings, look for an element by id or name.
 
       nsDependentJSString str(id);
 
       result = doc->GetDocumentAllResult(str, &cache, &rv);
@@ -8900,40 +8927,40 @@ nsHTMLDocumentSH::DocumentAllGetProperty
 
     result = node;
     cache = node;
   } else {
     result = nullptr;
   }
 
   if (result) {
-    rv = WrapNative(cx, JS_GetGlobalForScopeChain(cx), result, cache, true, vp);
+    rv = WrapNative(cx, JS_GetGlobalForScopeChain(cx), result, cache, true, vp.address());
     if (NS_FAILED(rv)) {
       xpc::Throw(cx, rv);
 
       return JS_FALSE;
     }
   } else {
-    *vp = JSVAL_VOID;
+    vp.setUndefined();
   }
 
   return JS_TRUE;
 }
 
 JSBool
 nsHTMLDocumentSH::DocumentAllNewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id,
                                         unsigned flags, JSMutableHandleObject objp)
 {
   if (flags & JSRESOLVE_ASSIGNING) {
     // Nothing to do here if we're assigning
 
     return JS_TRUE;
   }
 
-  jsval v = JSVAL_VOID;
+  JS::RootedValue v(cx);
 
   if (sItem_id == id || sNamedItem_id == id) {
     // Define the item() or namedItem() method.
 
     JSFunction *fnc = ::JS_DefineFunctionById(cx, obj, id, CallToGetPropMapper,
                                               0, JSPROP_ENUMERATE);
     objp.set(obj);
 
@@ -8965,17 +8992,17 @@ nsHTMLDocumentSH::DocumentAllNewResolve(
   } else {
     if (!DocumentAllGetProperty(cx, obj, id, &v)) {
       return JS_FALSE;
     }
   }
 
   JSBool ok = JS_TRUE;
 
-  if (v != JSVAL_VOID) {
+  if (v.get() != JSVAL_VOID) {
     ok = ::JS_DefinePropertyById(cx, obj, id, v, nullptr, nullptr, 0);
     objp.set(obj);
   }
 
   return ok;
 }
 
 // Finalize hook used by document related JS objects, but also by
@@ -9054,17 +9081,17 @@ static inline PRUint32
 PrivateToFlags(void *priv)
 {
   JS_ASSERT(size_t(priv) <= PR_UINT32_MAX && (size_t(priv) & 1) == 0);
   return (PRUint32)(size_t(priv) >> 1);
 }
 
 JSBool
 nsHTMLDocumentSH::DocumentAllHelperGetProperty(JSContext *cx, JSHandleObject obj,
-                                               JSHandleId id, JS::Value *vp)
+                                               JSHandleId id, JSMutableHandleValue vp)
 {
   if (nsDOMClassInfo::sAll_id != id) {
     return JS_TRUE;
   }
 
   JSObject *helper = GetDocumentAllHelper(obj);
 
   if (!helper) {
@@ -9077,22 +9104,22 @@ nsHTMLDocumentSH::DocumentAllHelperGetPr
 
   PRUint32 flags = PrivateToFlags(::JS_GetPrivate(helper));
 
   if (flags & JSRESOLVE_DETECTING || !(flags & JSRESOLVE_QUALIFIED)) {
     // document.all is either being detected, e.g. if (document.all),
     // or it was not being resolved with a qualified name. Claim that
     // document.all is undefined.
 
-    vp->setUndefined();
+    vp.setUndefined();
   } else {
     // document.all is not being detected, and it resolved with a
     // qualified name. Expose the document.all collection.
 
-    if (!vp->isObjectOrNull()) { 
+    if (!vp.isObjectOrNull()) { 
       // First time through, create the collection, and set the
       // document as its private nsISupports data.
       nsresult rv;
       nsCOMPtr<nsIHTMLDocument> doc = do_QueryWrapper(cx, obj, &rv);
       if (NS_FAILED(rv)) {
         xpc::Throw(cx, rv);
 
         return JS_FALSE;
@@ -9104,17 +9131,17 @@ nsHTMLDocumentSH::DocumentAllHelperGetPr
         return JS_FALSE;
       }
 
       // Let the JSObject take over ownership of doc.
       ::JS_SetPrivate(all, doc);
 
       doc.forget();
 
-      vp->setObject(*all);
+      vp.setObject(*all);
     }
   }
 
   return JS_TRUE;
 }
 
 JSBool
 nsHTMLDocumentSH::DocumentAllHelperNewResolve(JSContext *cx, JSHandleObject obj,
@@ -10284,17 +10311,17 @@ nsStorage2SH::NewResolve(nsIXPConnectWra
     return NS_ERROR_FAILURE;
   }
 
   // First check to see if the property is defined on our prototype,
   // after converting id to a string if it's an integer.
 
   JSString *jsstr = IdToString(cx, id);
   if (!jsstr) {
-    return JS_FALSE;
+    return NS_OK;
   }
 
   JSObject *proto = ::JS_GetPrototype(realObj);
   JSBool hasProp;
 
   if (proto &&
       (::JS_HasPropertyById(cx, proto, id, &hasProp) &&
        hasProp)) {
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -381,21 +381,21 @@ public:
                       JSObject *obj);
   NS_IMETHOD OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
                          JSObject * obj, JSObject * *_retval);
 
   static JSBool GlobalScopePolluterNewResolve(JSContext *cx, JSHandleObject obj,
                                               JSHandleId id, unsigned flags,
                                               JSMutableHandleObject objp);
   static JSBool GlobalScopePolluterGetProperty(JSContext *cx, JSHandleObject obj,
-                                               JSHandleId id, jsval *vp);
+                                               JSHandleId id, JSMutableHandleValue vp);
   static JSBool SecurityCheckOnAddDelProp(JSContext *cx, JSHandleObject obj, JSHandleId id,
-                                          jsval *vp);
+                                          JSMutableHandleValue vp);
   static JSBool SecurityCheckOnSetProp(JSContext *cx, JSHandleObject obj, JSHandleId id,
-                                       JSBool strict, jsval *vp);
+                                       JSBool strict, JSMutableHandleValue vp);
   static void InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj);
   static nsresult InstallGlobalScopePolluter(JSContext *cx, JSObject *obj,
                                              nsIHTMLDocument *doc);
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   {
     return new nsWindowSH(aData);
   }
 };
@@ -775,23 +775,23 @@ protected:
   }
 
   static JSBool GetDocumentAllNodeList(JSContext *cx, JSObject *obj,
                                        nsDocument *doc,
                                        nsContentList **nodeList);
 
 public:
   static JSBool DocumentAllGetProperty(JSContext *cx, JSHandleObject obj, JSHandleId id,
-                                       jsval *vp);
+                                       JSMutableHandleValue vp);
   static JSBool DocumentAllNewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id,
                                       unsigned flags, JSMutableHandleObject objp);
   static void ReleaseDocument(JSFreeOp *fop, JSObject *obj);
   static JSBool CallToGetPropMapper(JSContext *cx, unsigned argc, jsval *vp);
   static JSBool DocumentAllHelperGetProperty(JSContext *cx, JSHandleObject obj,
-                                             JSHandleId id, jsval *vp);
+                                             JSHandleId id, JSMutableHandleValue vp);
   static JSBool DocumentAllHelperNewResolve(JSContext *cx, JSHandleObject obj,
                                             JSHandleId id, unsigned flags,
                                             JSMutableHandleObject objp);
   static JSBool DocumentAllTagsNewResolve(JSContext *cx, JSHandleObject obj,
                                           JSHandleId id, unsigned flags,
                                           JSMutableHandleObject objp);
 
   NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -521,16 +521,20 @@ DOMCI_CLASS(MozVoicemailEvent)
 
 #ifdef MOZ_B2G_BT
 DOMCI_CLASS(BluetoothManager)
 DOMCI_CLASS(BluetoothAdapter)
 DOMCI_CLASS(BluetoothDevice)
 DOMCI_CLASS(BluetoothDeviceEvent)
 #endif
 
+DOMCI_CLASS(CameraManager)
+DOMCI_CLASS(CameraControl)
+DOMCI_CLASS(CameraCapabilities)
+
 DOMCI_CLASS(DOMError)
 DOMCI_CLASS(DOMRequest)
 DOMCI_CLASS(OpenWindowEventDetail)
 
 DOMCI_CLASS(DOMFileHandle)
 DOMCI_CLASS(FileRequest)
 DOMCI_CLASS(LockedFile)
 
--- a/dom/base/nsDOMException.cpp
+++ b/dom/base/nsDOMException.cpp
@@ -65,17 +65,17 @@ enum DOM4ErrorTypeCodeMap {
 static struct ResultStruct
 {
   nsresult mNSResult;
   PRUint16 mCode;
   const char* mName;
   const char* mMessage;
 } gDOMErrorMsgMap[] = {
 #include "domerr.msg"
-  {0, 0, nullptr, nullptr}   // sentinel to mark end of array
+  {NS_OK, 0, nullptr, nullptr}   // sentinel to mark end of array
 };
 
 #undef DOM4_MSG_DEF
 #undef DOM_MSG_DEF
 
 static void
 NSResultToNameAndMessage(nsresult aNSResult,
                          const char** aName,
@@ -200,17 +200,17 @@ nsDOMException::GetMessageMoz(char **aMe
   } else {
     *aMessage = nullptr;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMException::GetResult(PRUint32* aResult)
+nsDOMException::GetResult(nsresult* aResult)
 {
   NS_ENSURE_ARG_POINTER(aResult);
 
   *aResult = mResult;
 
   return NS_OK;
 }
 
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2588,8 +2588,42 @@ nsDOMWindowUtils::GetApp(mozIDOMApplicat
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
 
   return static_cast<nsGlobalWindow*>(window.get())->GetApp(aApplication);
 }
+
+nsresult
+nsDOMWindowUtils::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
+                                            const nsAString& aNewOrigin)
+{
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
+  NS_ENSURE_STATE(window);
+
+  nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
+  NS_ENSURE_STATE(doc);
+
+  doc->RemoteFrameFullscreenChanged(aFrameElement, aNewOrigin);
+  return NS_OK;
+}
+
+nsresult
+nsDOMWindowUtils::RemoteFrameFullscreenReverted()
+{
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
+  NS_ENSURE_STATE(window);
+
+  nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
+  NS_ENSURE_STATE(doc);
+
+  doc->RemoteFrameFullscreenReverted();
+  return NS_OK;
+}
+
+nsresult
+nsDOMWindowUtils::ExitFullscreen()
+{
+  nsIDocument::ExitFullScreen(/* async = */ false);
+  return NS_OK;
+}
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -64,26 +64,48 @@
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::widget;
 
-//#define DEBUG_FOCUS 1
-//#define DEBUG_FOCUS_NAVIGATION 1
-#define PRINTTAGF(format, content)                     \
-  {                                                    \
-    nsAutoString tag(NS_LITERAL_STRING("(none)"));     \
-    if (content)                                       \
-      content->Tag()->ToString(tag);                   \
-    printf(format, NS_ConvertUTF16toUTF8(tag).get());  \
+#ifdef PR_LOGGING
+
+// Two types of focus pr logging are available:
+//   'Focus' for normal focus manager calls
+//   'FocusNavigation' for tab and document navigation
+PRLogModuleInfo* gFocusLog;
+PRLogModuleInfo* gFocusNavigationLog;
+
+#define LOGFOCUS(args) PR_LOG(gFocusLog, 4, args)
+#define LOGFOCUSNAVIGATION(args) PR_LOG(gFocusNavigationLog, 4, args)
+
+#define LOGTAG(log, format, content)                            \
+  {                                                             \
+    nsCAutoString tag(NS_LITERAL_CSTRING("(none)"));            \
+    if (content) {                                              \
+      content->Tag()->ToUTF8String(tag);                        \
+    }                                                           \
+    PR_LOG(log, 4, (format, tag.get()));                        \
   }
 
+#define LOGCONTENT(format, content) LOGTAG(gFocusLog, format, content)
+#define LOGCONTENTNAVIGATION(format, content) LOGTAG(gFocusNavigationLog, format, content)
+
+#else
+
+#define LOGFOCUS(args)
+#define LOGFOCUSNAVIGATION(args)
+#define LOGCONTENT(format, content)
+#define LOGCONTENTNAVIGATION(format, content)
+
+#endif
+
 struct nsDelayedBlurOrFocusEvent
 {
   nsDelayedBlurOrFocusEvent(PRUint32 aType,
                             nsIPresShell* aPresShell,
                             nsIDocument* aDocument,
                             nsIDOMEventTarget* aTarget)
    : mType(aType),
      mPresShell(aPresShell),
@@ -159,16 +181,21 @@ nsFocusManager::~nsFocusManager()
 nsresult
 nsFocusManager::Init()
 {
   nsFocusManager* fm = new nsFocusManager();
   NS_ENSURE_TRUE(fm, NS_ERROR_OUT_OF_MEMORY);
   NS_ADDREF(fm);
   sInstance = fm;
 
+#ifdef PR_LOGGING
+  gFocusLog = PR_NewLogModule("Focus");
+  gFocusNavigationLog = PR_NewLogModule("FocusNavigation");
+#endif
+
   nsIContent::sTabFocusModelAppliesToXUL =
     Preferences::GetBool("accessibility.tabfocus_applies_to_xul",
                          nsIContent::sTabFocusModelAppliesToXUL);
 
   sMouseFocusesFormControl =
     Preferences::GetBool("accessibility.mouse_focuses_formcontrol", false);
 
   sTestMode = Preferences::GetBool("focusmanager.testmode", false);
@@ -353,19 +380,17 @@ NS_IMETHODIMP
 nsFocusManager::GetFocusedWindow(nsIDOMWindow** aFocusedWindow)
 {
   NS_IF_ADDREF(*aFocusedWindow = mFocusedWindow);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsFocusManager::SetFocusedWindow(nsIDOMWindow* aWindowToFocus)
 {
-#ifdef DEBUG_FOCUS
-  printf("<<SetFocusedWindow begin>>\n");
-#endif
+  LOGFOCUS(("<<SetFocusedWindow begin>>"));
 
   nsCOMPtr<nsPIDOMWindow> windowToFocus(do_QueryInterface(aWindowToFocus));
   NS_ENSURE_TRUE(windowToFocus, NS_ERROR_FAILURE);
 
   windowToFocus = windowToFocus->GetOuterWindow();
 
   nsCOMPtr<nsIContent> frameContent =
     do_QueryInterface(windowToFocus->GetFrameElementInternal());
@@ -386,19 +411,17 @@ NS_IMETHODIMP nsFocusManager::SetFocused
         ClearFocus(windowToFocus);
     }
   }
 
   nsCOMPtr<nsPIDOMWindow> rootWindow = windowToFocus->GetPrivateRoot();
   if (rootWindow)
     RaiseWindow(rootWindow);
 
-#ifdef DEBUG_FOCUS
-  printf("<<SetFocusedWindow end>>\n");
-#endif
+  LOGFOCUS(("<<SetFocusedWindow end>>"));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFocusManager::GetFocusedElement(nsIDOMElement** aFocusedElement)
 {
   if (mFocusedContent)
@@ -423,25 +446,25 @@ nsFocusManager::GetLastFocusMethod(nsIDO
   NS_ASSERTION((*aLastFocusMethod & FOCUSMETHOD_MASK) == *aLastFocusMethod,
                "invalid focus method");
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFocusManager::SetFocus(nsIDOMElement* aElement, PRUint32 aFlags)
 {
-#ifdef DEBUG_FOCUS
-  printf("<<SetFocus>>\n");
-#endif
+  LOGFOCUS(("<<SetFocus begin>>"));
 
   nsCOMPtr<nsIContent> newFocus = do_QueryInterface(aElement);
   NS_ENSURE_ARG(newFocus);
 
   SetFocusInner(newFocus, aFlags, true, true);
 
+  LOGFOCUS(("<<SetFocus end>>"));
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFocusManager::ElementIsFocusable(nsIDOMElement* aElement, PRUint32 aFlags,
                                    bool* aIsFocusable)
 {
   NS_ENSURE_TRUE(aElement, NS_ERROR_INVALID_ARG);
@@ -454,29 +477,29 @@ nsFocusManager::ElementIsFocusable(nsIDO
 }
 
 NS_IMETHODIMP
 nsFocusManager::MoveFocus(nsIDOMWindow* aWindow, nsIDOMElement* aStartElement,
                           PRUint32 aType, PRUint32 aFlags, nsIDOMElement** aElement)
 {
   *aElement = nullptr;
 
-#ifdef DEBUG_FOCUS
-  printf("<<MoveFocus Type: %d Flags: %x>>\n<<", aType, aFlags);
-
-  nsCOMPtr<nsPIDOMWindow> focusedWindow = mFocusedWindow;
-  if (focusedWindow) {
-    nsCOMPtr<nsIDocument> doc = do_QueryInterface(focusedWindow->GetExtantDocument());
-    if (doc) {
+#ifdef PR_LOGGING
+  LOGFOCUS(("<<MoveFocus begin Type: %d Flags: %x>>", aType, aFlags));
+
+  if (PR_LOG_TEST(gFocusLog, PR_LOG_DEBUG) && mFocusedWindow) {
+    nsIDocument* doc = mFocusedWindow->GetExtantDoc();
+    if (doc && doc->GetDocumentURI()) {
       nsCAutoString spec;
       doc->GetDocumentURI()->GetSpec(spec);
-      printf(" [%p] Focused Window: %s", mFocusedWindow.get(), spec.get());
+      LOGFOCUS((" Focused Window: %p %s", mFocusedWindow.get(), spec.get()));
     }
   }
-  PRINTTAGF(">> $[[%s]]\n", mFocusedContent);
+
+  LOGCONTENT("  Current Focus: %s", mFocusedContent.get());
 #endif
 
   // use FLAG_BYMOVEFOCUS when switching focus with MoveFocus unless one of
   // the other focus methods is already set, or we're just moving to the root
   // or caret position.
   if (aType != MOVEFOCUS_ROOT && aType != MOVEFOCUS_CARET &&
       (aFlags & FOCUSMETHOD_MASK) == 0) {
     aFlags |= FLAG_BYMOVEFOCUS;
@@ -499,46 +522,40 @@ nsFocusManager::MoveFocus(nsIDOMWindow* 
   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
 
   bool noParentTraversal = aFlags & FLAG_NOPARENTFRAME;
   nsCOMPtr<nsIContent> newFocus;
   nsresult rv = DetermineElementToMoveFocus(window, startContent, aType, noParentTraversal,
                                             getter_AddRefs(newFocus));
   NS_ENSURE_SUCCESS(rv, rv);
 
-#ifdef DEBUG_FOCUS_NAVIGATION
-  PRINTTAGF("-> Element to be focused: %s\n", newFocus);
-#endif
+  LOGCONTENTNAVIGATION("Element to be focused: %s", newFocus.get());
 
   if (newFocus) {
     // for caret movement, pass false for the aFocusChanged argument,
     // otherwise the caret will end up moving to the focus position. This
     // would be a problem because the caret would move to the beginning of the
     // focused link making it impossible to navigate the caret over a link.
     SetFocusInner(newFocus, aFlags, aType != MOVEFOCUS_CARET, true);
     CallQueryInterface(newFocus, aElement);
   }
   else if (aType == MOVEFOCUS_ROOT || aType == MOVEFOCUS_CARET) {
     // no content was found, so clear the focus for these two types.
     ClearFocus(window);
   }
 
-#ifdef DEBUG_FOCUS
-  printf("<<MoveFocus end>>\n");
-#endif
+  LOGFOCUS(("<<MoveFocus end>>"));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFocusManager::ClearFocus(nsIDOMWindow* aWindow)
 {
-#ifdef DEBUG_FOCUS
-  printf("<<ClearFocus begin>>\n");
-#endif
+  LOGFOCUS(("<<ClearFocus begin>>"));
 
   // if the window to clear is the focused window or an ancestor of the
   // focused window, then blur the existing focused content. Otherwise, the
   // focus is somewhere else so just update the current node.
   nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(aWindow));
   NS_ENSURE_TRUE(window, NS_ERROR_INVALID_ARG);
 
   window = window->GetOuterWindow();
@@ -552,19 +569,17 @@ nsFocusManager::ClearFocus(nsIDOMWindow*
       if (isAncestor)
         Focus(window, nullptr, 0, true, false, false, true);
     }
   }
   else {
     window->SetFocusedNode(nullptr);
   }
 
-#ifdef DEBUG_FOCUS
-  printf("<<ClearFocus end>>\n");
-#endif
+  LOGFOCUS(("<<ClearFocus end>>"));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFocusManager::GetFocusedElementForWindow(nsIDOMWindow* aWindow,
                                            bool aDeep,
                                            nsIDOMWindow** aFocusedWindow,
@@ -629,32 +644,33 @@ nsFocusManager::MoveCaretToFocus(nsIDOMW
 }
 
 NS_IMETHODIMP
 nsFocusManager::WindowRaised(nsIDOMWindow* aWindow)
 {
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
   NS_ENSURE_TRUE(window && window->IsOuterWindow(), NS_ERROR_INVALID_ARG);
 
-#ifdef DEBUG_FOCUS
-  printf("Window %p Raised [Currently: %p %p] <<", aWindow, mActiveWindow.get(), mFocusedWindow.get());
-  nsCAutoString spec;
-  nsCOMPtr<nsIDocument> doc = do_QueryInterface(window->GetExtantDocument());
-  if (doc) {
-    doc->GetDocumentURI()->GetSpec(spec);
-    printf("[%p] Raised Window: %s", aWindow, spec.get());
-  }
-  if (mActiveWindow) {
-    doc = do_QueryInterface(mActiveWindow->GetExtantDocument());
-    if (doc) {
+#ifdef PR_LOGGING
+  if (PR_LOG_TEST(gFocusLog, PR_LOG_DEBUG)) {
+    LOGFOCUS(("Window %p Raised [Currently: %p %p]", aWindow, mActiveWindow.get(), mFocusedWindow.get()));
+    nsCAutoString spec;
+    nsIDocument* doc = window->GetExtantDoc();
+    if (doc && doc->GetDocumentURI()) {
       doc->GetDocumentURI()->GetSpec(spec);
-      printf(" [%p] Active Window: %s", mActiveWindow.get(), spec.get());
+      LOGFOCUS(("  Raised Window: %p %s", aWindow, spec.get()));
+    }
+    if (mActiveWindow) {
+      doc = mActiveWindow->GetExtantDoc();
+      if (doc && doc->GetDocumentURI()) {
+        doc->GetDocumentURI()->GetSpec(spec);
+        LOGFOCUS(("  Active Window: %p %s", mActiveWindow.get(), spec.get()));
+      }
     }
   }
-  printf(">>\n");
 #endif
 
   if (mActiveWindow == window) {
     // The window is already active, so there is no need to focus anything,
     // but make sure that the right widget is focused. This is a special case
     // for Windows because when restoring a minimized window, a second
     // activation will occur and the top-level widget could be focused instead
     // of the child we want. We solve this by calling SetFocus to ensure that
@@ -690,18 +706,17 @@ nsFocusManager::WindowRaised(nsIDOMWindo
     baseWindow->SetVisibility(true);
   }
 
   // inform the DOM window that it has activated, so that the active attribute
   // is updated on the window
   window->ActivateOrDeactivate(true);
 
   // send activate event
-  nsCOMPtr<nsIDocument> document = do_QueryInterface(window->GetExtantDocument());
-  nsContentUtils::DispatchTrustedEvent(document,
+  nsContentUtils::DispatchTrustedEvent(window->GetExtantDoc(),
                                        window,
                                        NS_LITERAL_STRING("activate"),
                                        true, true, nullptr);
 
   // retrieve the last focused element within the window that was raised
   nsCOMPtr<nsPIDOMWindow> currentWindow;
   nsCOMPtr<nsIContent> currentFocus =
     GetFocusedDescendant(window, true, getter_AddRefs(currentWindow));
@@ -727,47 +742,47 @@ nsFocusManager::WindowRaised(nsIDOMWindo
 }
 
 NS_IMETHODIMP
 nsFocusManager::WindowLowered(nsIDOMWindow* aWindow)
 {
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
   NS_ENSURE_TRUE(window && window->IsOuterWindow(), NS_ERROR_INVALID_ARG);
 
-#ifdef DEBUG_FOCUS
-  printf("Window %p Lowered [Currently: %p %p] <<", aWindow, mActiveWindow.get(), mFocusedWindow.get());
-  nsCAutoString spec;
-  nsCOMPtr<nsIDocument> doc = do_QueryInterface(window->GetExtantDocument());
-  if (doc) {
-    doc->GetDocumentURI()->GetSpec(spec);
-    printf("[%p] Lowered Window: %s", aWindow, spec.get());
-  }
-  if (mActiveWindow) {
-    doc = do_QueryInterface(mActiveWindow->GetExtantDocument());
-    if (doc) {
+#ifdef PR_LOGGING
+  if (PR_LOG_TEST(gFocusLog, PR_LOG_DEBUG)) {
+    LOGFOCUS(("Window %p Lowered [Currently: %p %p]", aWindow, mActiveWindow.get(), mFocusedWindow.get()));
+    nsCAutoString spec;
+    nsIDocument* doc = window->GetExtantDoc();
+    if (doc && doc->GetDocumentURI()) {
       doc->GetDocumentURI()->GetSpec(spec);
-      printf(" [%p] Active Window: %s", mActiveWindow.get(), spec.get());
+      LOGFOCUS(("  Lowered Window: %s", spec.get()));
+    }
+    if (mActiveWindow) {
+      doc = mActiveWindow->GetExtantDoc();
+      if (doc && doc->GetDocumentURI()) {
+        doc->GetDocumentURI()->GetSpec(spec);
+        LOGFOCUS(("  Active Window: %s", spec.get()));
+      }
     }
   }
-  printf(">>\n");
 #endif
 
   if (mActiveWindow != window)
     return NS_OK;
 
   // clear the mouse capture as the active window has changed
   nsIPresShell::SetCapturingContent(nullptr, 0);
 
   // inform the DOM window that it has deactivated, so that the active
   // attribute is updated on the window
   window->ActivateOrDeactivate(false);
 
   // send deactivate event
-  nsCOMPtr<nsIDocument> document = do_QueryInterface(window->GetExtantDocument());
-  nsContentUtils::DispatchTrustedEvent(document,
+  nsContentUtils::DispatchTrustedEvent(window->GetExtantDoc(),
                                        window,
                                        NS_LITERAL_STRING("deactivate"),
                                        true, true, nullptr);
 
   // keep track of the window being lowered, so that attempts to raise the
   // window can be prevented until we return. Otherwise, focus can get into
   // an unusual state.
   mWindowBeingLowered = mActiveWindow;
@@ -835,33 +850,34 @@ nsFocusManager::ContentRemoved(nsIDocume
 NS_IMETHODIMP
 nsFocusManager::WindowShown(nsIDOMWindow* aWindow, bool aNeedsFocus)
 {
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
   NS_ENSURE_TRUE(window, NS_ERROR_INVALID_ARG);
 
   window = window->GetOuterWindow();
 
-#ifdef DEBUG_FOCUS
-  printf("Window %p Shown [Currently: %p %p] <<", window.get(), mActiveWindow.get(), mFocusedWindow.get());
-  nsCAutoString spec;
-  nsCOMPtr<nsIDocument> doc = do_QueryInterface(window->GetExtantDocument());
-  if (doc) {
-    doc->GetDocumentURI()->GetSpec(spec);
-    printf("Shown Window: %s", spec.get());
-  }
-
-  if (mFocusedWindow) {
-    doc = do_QueryInterface(mFocusedWindow->GetExtantDocument());
-    if (doc) {
+#ifdef PR_LOGGING
+  if (PR_LOG_TEST(gFocusLog, PR_LOG_DEBUG)) {
+    LOGFOCUS(("Window %p Shown [Currently: %p %p]", window.get(), mActiveWindow.get(), mFocusedWindow.get()));
+    nsCAutoString spec;
+    nsIDocument* doc = window->GetExtantDoc();
+    if (doc && doc->GetDocumentURI()) {
       doc->GetDocumentURI()->GetSpec(spec);
-      printf(" Focused Window: %s", spec.get());
+      LOGFOCUS(("Shown Window: %s", spec.get()));
+    }
+
+    if (mFocusedWindow) {
+      doc = mFocusedWindow->GetExtantDoc();
+      if (doc && doc->GetDocumentURI()) {
+        doc->GetDocumentURI()->GetSpec(spec);
+        LOGFOCUS((" Focused Window: %s", spec.get()));
+      }
     }
   }
-  printf(">>\n");
 #endif
 
   if (mFocusedWindow != window)
     return NS_OK;
 
   if (aNeedsFocus) {
     nsCOMPtr<nsPIDOMWindow> currentWindow;
     nsCOMPtr<nsIContent> currentFocus =
@@ -886,41 +902,42 @@ nsFocusManager::WindowHidden(nsIDOMWindo
   // currently focused window, just return, as the current focus will not
   // be affected.
 
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
   NS_ENSURE_TRUE(window, NS_ERROR_INVALID_ARG);
 
   window = window->GetOuterWindow();
 
-#ifdef DEBUG_FOCUS
-  printf("Window %p Hidden [Currently: %p %p] <<", window.get(), mActiveWindow.get(), mFocusedWindow.get());
-  nsCAutoString spec;
-  nsCOMPtr<nsIDocument> doc = do_QueryInterface(window->GetExtantDocument());
-  if (doc) {
-    doc->GetDocumentURI()->GetSpec(spec);
-    printf("Hide Window: %s", spec.get());
-  }
-
-  if (mFocusedWindow) {
-    doc = do_QueryInterface(mFocusedWindow->GetExtantDocument());
-    if (doc) {
+#ifdef PR_LOGGING
+  if (PR_LOG_TEST(gFocusLog, PR_LOG_DEBUG)) {
+    LOGFOCUS(("Window %p Hidden [Currently: %p %p]", window.get(), mActiveWindow.get(), mFocusedWindow.get()));
+    nsCAutoString spec;
+    nsIDocument* doc = window->GetExtantDoc();
+    if (doc && doc->GetDocumentURI()) {
       doc->GetDocumentURI()->GetSpec(spec);
-      printf(" Focused Window: %s", spec.get());
+      LOGFOCUS(("  Hide Window: %s", spec.get()));
+    }
+
+    if (mFocusedWindow) {
+      doc = mFocusedWindow->GetExtantDoc();
+      if (doc && doc->GetDocumentURI()) {
+        doc->GetDocumentURI()->GetSpec(spec);
+        LOGFOCUS(("  Focused Window: %s", spec.get()));
+      }
+    }
+
+    if (mActiveWindow) {
+      doc = mActiveWindow->GetExtantDoc();
+      if (doc && doc->GetDocumentURI()) {
+        doc->GetDocumentURI()->GetSpec(spec);
+        LOGFOCUS(("  Active Window: %s", spec.get()));
+      }
     }
   }
-
-  if (mActiveWindow) {
-    doc = do_QueryInterface(mActiveWindow->GetExtantDocument());
-    if (doc) {
-      doc->GetDocumentURI()->GetSpec(spec);
-      printf(" Active Window: %s", spec.get());
-    }
-  }
-  printf(">>\n");
 #endif
 
   if (!IsSameOrAncestor(window, mFocusedWindow))
     return NS_OK;
 
   // at this point, we know that the window being hidden is either the focused
   // window, or an ancestor of the focused window. Either way, the focus is no
   // longer valid, so it needs to be updated.
@@ -1156,24 +1173,16 @@ nsFocusManager::SetFocusInner(nsIContent
   if (dsti) {
     nsCOMPtr<nsIDocShellTreeItem> root;
     dsti->GetRootTreeItem(getter_AddRefs(root));
     newRootWindow = do_GetInterface(root);
 
     isElementInActiveWindow = (mActiveWindow && newRootWindow == mActiveWindow);
   }
 
-#ifdef DEBUG_FOCUS
-  PRINTTAGF("Shift Focus: %s", contentToFocus);
-  printf(" Flags: %x Current Window: %p New Window: %p Current Element: %p",
-         aFlags, mFocusedWindow.get(), newWindow.get(), mFocusedContent.get());
-  printf(" In Active Window: %d In Focused Window: %d\n",
-         isElementInActiveWindow, isElementInFocusedWindow);
-#endif
-
   // Exit full-screen if we're focusing a windowed plugin on a non-MacOSX
   // system. We don't control event dispatch to windowed plugins on non-MacOSX,
   // so we can't display the "Press ESC to leave full-screen mode" warning on
   // key input if a windowed plugin is focused, so just exit full-screen
   // to guard against phishing.
 #ifndef XP_MACOSX
   if (contentToFocus &&
       nsContentUtils::GetRootDocument(contentToFocus->OwnerDoc())->IsFullScreenDoc() &&
@@ -1213,16 +1222,22 @@ nsFocusManager::SetFocusInner(nsIContent
     if (!sendFocusEvent && mMouseDownEventHandlingDocument) {
       // However, while mouse down event is handling, the handling document's
       // script should be able to steal focus.
       domNode = do_QueryInterface(mMouseDownEventHandlingDocument);
       sendFocusEvent = nsContentUtils::CanCallerAccess(domNode);
     }
   }
 
+  LOGCONTENT("Shift Focus: %s", contentToFocus.get());
+  LOGFOCUS((" Flags: %x Current Window: %p New Window: %p Current Element: %p",
+           aFlags, mFocusedWindow.get(), newWindow.get(), mFocusedContent.get()));
+  LOGFOCUS((" In Active Window: %d In Focused Window: %d SendFocus: %d",
+           isElementInActiveWindow, isElementInFocusedWindow, sendFocusEvent));
+
   if (sendFocusEvent) {
     // return if blurring fails or the focus changes during the blur
     if (mFocusedWindow) {
       // if the focus is being moved to another element in the same document,
       // or to a descendant, pass the existing window to Blur so that the
       // current node in the existing window is cleared. If moving to a
       // window elsewhere, we want to maintain the current node in the
       // window but still blur it.
@@ -1424,38 +1439,44 @@ nsFocusManager::CheckIfFocusable(nsICont
   // this is a special case for some XUL elements where an anonymous child is
   // actually focusable and not the element itself.
   nsIContent* redirectedFocus = GetRedirectedFocus(aContent);
   if (redirectedFocus)
     return CheckIfFocusable(redirectedFocus, aFlags);
 
   nsCOMPtr<nsIDocument> doc = aContent->GetCurrentDoc();
   // can't focus elements that are not in documents
-  if (!doc)
+  if (!doc) {
+    LOGCONTENT("Cannot focus %s because content not in document", aContent)
     return nullptr;
+  }
 
   // Make sure that our frames are up to date
   doc->FlushPendingNotifications(Flush_Layout);
 
   nsIPresShell *shell = doc->GetShell();
   if (!shell)
     return nullptr;
 
   // the root content can always be focused
   if (aContent == doc->GetRootElement())
     return aContent;
 
   // cannot focus content in print preview mode. Only the root can be focused.
   nsPresContext* presContext = shell->GetPresContext();
-  if (presContext && presContext->Type() == nsPresContext::eContext_PrintPreview)
+  if (presContext && presContext->Type() == nsPresContext::eContext_PrintPreview) {
+    LOGCONTENT("Cannot focus %s while in print preview", aContent)
     return nullptr;
+  }
 
   nsIFrame* frame = aContent->GetPrimaryFrame();
-  if (!frame)
+  if (!frame) {
+    LOGCONTENT("Cannot focus %s as it has no frame", aContent)
     return nullptr;
+  }
 
   if (aContent->Tag() == nsGkAtoms::area && aContent->IsHTML()) {
     // HTML areas do not have their own frame, and the img frame we get from
     // GetPrimaryFrame() is not relevant as to whether it is focusable or
     // not, so we have to do all the relevant checks manually for them.
     return frame->IsVisibleConsideringAncestors() &&
            aContent->IsFocusable() ? aContent : nullptr;
   }
@@ -1476,16 +1497,18 @@ nsFocusManager::CheckIfFocusable(nsICont
 }
 
 bool
 nsFocusManager::Blur(nsPIDOMWindow* aWindowToClear,
                      nsPIDOMWindow* aAncestorWindowToFocus,
                      bool aIsLeavingDocument,
                      bool aAdjustWidgets)
 {
+  LOGFOCUS(("<<Blur begin>>"));
+
   // hold a reference to the focused content, which may be null
   nsCOMPtr<nsIContent> content = mFocusedContent;
   if (content) {
     if (!content->IsInDoc()) {
       mFocusedContent = nullptr;
       return true;
     }
     if (content == mFirstBlurEvent)
@@ -1531,19 +1554,17 @@ nsFocusManager::Blur(nsPIDOMWindow* aWin
 
   // now adjust the actual focus, by clearing the fields in the focus manager
   // and in the window.
   mFocusedContent = nullptr;
   bool shouldShowFocusRing = window->ShouldShowFocusRing();
   if (aWindowToClear)
     aWindowToClear->SetFocusedNode(nullptr);
 
-#ifdef DEBUG_FOCUS
-  PRINTTAGF("**Element %s has been blurred\n", content);
-#endif
+  LOGCONTENT("Element %s has been blurred", content.get());
 
   // Don't fire blur event on the root content which isn't editable.
   bool sendBlurEvent =
     content && content->IsInDoc() && !IsNonFocusableRoot(content);
   if (content) {
     if (sendBlurEvent) {
       NotifyFocusStateChange(content, shouldShowFocusRing, false);
     }
@@ -1565,19 +1586,17 @@ nsFocusManager::Blur(nsPIDOMWindow* aWin
           if (widget)
             widget->SetFocus(false);
         }
       }
 
       // if the object being blurred is a remote browser, deactivate remote content
       if (TabParent* remote = TabParent::GetFrom(content)) {
         remote->Deactivate();
-  #ifdef DEBUG_FOCUS
-      printf("*Remote browser deactivated\n");
-  #endif
+        LOGFOCUS(("Remote browser deactivated"));
       }
     }
   }
 
   bool result = true;
   if (sendBlurEvent) {
     // if there is an active window, update commands. If there isn't an active
     // window, then this was a blur caused by the active window being lowered,
@@ -1614,17 +1633,17 @@ nsFocusManager::Blur(nsPIDOMWindow* aWin
       aAncestorWindowToFocus->SetFocusedNode(nullptr, 0, true);
 
     mFocusedWindow = nullptr;
     mFocusedContent = nullptr;
 
     // pass 1 for the focus method when calling SendFocusOrBlurEvent just so
     // that the check is made for suppressed documents. Check to ensure that
     // the document isn't null in case someone closed it during the blur above
-    nsCOMPtr<nsIDocument> doc = do_QueryInterface(window->GetExtantDocument());
+    nsIDocument* doc = window->GetExtantDoc();
     if (doc)
       SendFocusOrBlurEvent(NS_BLUR_CONTENT, presShell, doc, doc, 1, false);
     if (mFocusedWindow == nullptr)
       SendFocusOrBlurEvent(NS_BLUR_CONTENT, presShell, doc, window, 1, false);
 
     // check if a different window was focused
     result = (mFocusedWindow == nullptr && mActiveWindow);
   }
@@ -1647,16 +1666,18 @@ void
 nsFocusManager::Focus(nsPIDOMWindow* aWindow,
                       nsIContent* aContent,
                       PRUint32 aFlags,
                       bool aIsNewDocument,
                       bool aFocusChanged,
                       bool aWindowRaised,
                       bool aAdjustWidgets)
 {
+  LOGFOCUS(("<<Focus begin>>"));
+
   if (!aWindow)
     return;
 
   if (aContent && (aContent == mFirstFocusEvent || aContent == mFirstBlurEvent))
     return;
 
   // Keep a reference to the presShell since dispatching the DOM event may
   // cause the document to be destroyed.
@@ -1687,23 +1708,27 @@ nsFocusManager::Focus(nsPIDOMWindow* aWi
   }
 
   bool clearFirstFocusEvent = false;
   if (!mFirstFocusEvent) {
     mFirstFocusEvent = aContent;
     clearFirstFocusEvent = true;
   }
 
-#ifdef DEBUG_FOCUS
-  PRINTTAGF("**Element %s has been focused", aContent);
-  nsCOMPtr<nsIDocument> docm = do_QueryInterface(aWindow->GetExtantDocument());
-  if (docm)
-    PRINTTAGF(" from %s", docm->GetRootElement());
-  printf(" [Newdoc: %d FocusChanged: %d Raised: %d Flags: %x]\n",
-         aIsNewDocument, aFocusChanged, aWindowRaised, aFlags);
+#ifdef PR_LOGGING
+  LOGCONTENT("Element %s has been focused", aContent);
+
+  if (PR_LOG_TEST(gFocusLog, PR_LOG_DEBUG)) {
+    nsIDocument* docm = aWindow->GetExtantDoc();
+    if (docm) {
+      LOGCONTENT(" from %s", docm->GetRootElement());
+    }
+    LOGFOCUS((" [Newdoc: %d FocusChanged: %d Raised: %d Flags: %x]",
+             aIsNewDocument, aFocusChanged, aWindowRaised, aFlags));
+  }
 #endif
 
   if (aIsNewDocument) {
     // if this is a new document, update the parent chain of frames so that
     // focus can be traversed from the top level down to the newly focused
     // window.
     AdjustWindowFocus(aWindow, false);
 
@@ -1736,17 +1761,17 @@ nsFocusManager::Focus(nsPIDOMWindow* aWi
       if (widget)
         widget->SetFocus(false);
     }
   }
 
   // if switching to a new document, first fire the focus event on the
   // document and then the window.
   if (aIsNewDocument) {
-    nsCOMPtr<nsIDocument> doc = do_QueryInterface(aWindow->GetExtantDocument());
+    nsIDocument* doc = aWindow->GetExtantDoc();
     if (doc)
       SendFocusOrBlurEvent(NS_FOCUS_CONTENT, presShell, doc,
                            doc, aFlags & FOCUSMETHOD_MASK, aWindowRaised);
     if (mFocusedWindow == aWindow && mFocusedContent == nullptr)
       SendFocusOrBlurEvent(NS_FOCUS_CONTENT, presShell, doc,
                            aWindow, aFlags & FOCUSMETHOD_MASK, aWindowRaised);
   }
 
@@ -1776,19 +1801,17 @@ nsFocusManager::Focus(nsPIDOMWindow* aWi
       // aIsNewDocument.
       if (presShell->GetDocument() == aContent->GetDocument()) {
         if (aAdjustWidgets && objectFrameWidget && !sTestMode)
           objectFrameWidget->SetFocus(false);
 
         // if the object being focused is a remote browser, activate remote content
         if (TabParent* remote = TabParent::GetFrom(aContent)) {
           remote->Activate();
-#ifdef DEBUG_FOCUS
-          printf("*Remote browser activated\n");
-#endif
+          LOGFOCUS(("Remote browser activated"));
         }
       }
 
       nsIMEStateManager::OnChangeFocus(presContext, aContent,
                                        GetFocusMoveActionCause(aFlags));
 
       // as long as this focus wasn't because a window was raised, update the
       // commands
@@ -2001,19 +2024,17 @@ nsFocusManager::RaiseWindow(nsPIDOMWindo
 #endif
 }
 
 void
 nsFocusManager::UpdateCaret(bool aMoveCaretToFocus,
                             bool aUpdateVisibility,
                             nsIContent* aContent)
 {
-#ifdef DEBUG_FOCUS
-  printf("Update Caret: %d %d\n", aMoveCaretToFocus, aUpdateVisibility);
-#endif
+  LOGFOCUS(("Update Caret: %d %d", aMoveCaretToFocus, aUpdateVisibility));
 
   if (!mFocusedWindow)
     return;
 
   // this is called when a document is focused or when the caretbrowsing
   // preference is changed
   nsCOMPtr<nsIDocShell> focusedDocShell = mFocusedWindow->GetDocShell();
   nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(focusedDocShell);
@@ -2333,17 +2354,17 @@ nsFocusManager::DetermineElementToMoveFo
       startContent = aWindow->GetFocusedNode();
     }
   }
 
   nsCOMPtr<nsIDocument> doc;
   if (startContent)
     doc = startContent->GetCurrentDoc();
   else
-    doc = do_QueryInterface(aWindow->GetExtantDocument());
+    doc = aWindow->GetExtantDoc();
   if (!doc)
     return NS_OK;
 
   LookAndFeel::GetInt(LookAndFeel::eIntID_TabFocusModel,
                       &nsIContent::sTabFocusModel);
 
   if (aType == MOVEFOCUS_ROOT) {
     NS_IF_ADDREF(*aNextContent = GetRootForFocus(aWindow, doc, false, false));
@@ -2504,36 +2525,33 @@ nsFocusManager::DetermineElementToMoveFo
   // be the same as the start content -- when nothing is focused and tabbing
   // forward. Without skipOriginalContentCheck set to true, we'd end up
   // returning right away and focusing nothing. Luckily, GetNextTabbableContent
   // will never wrap around on its own, and can only return the original
   // content when it is called a second time or later.
   bool skipOriginalContentCheck = true;
   nsIContent* originalStartContent = startContent;
 
-#ifdef DEBUG_FOCUS_NAVIGATION
-  PRINTTAGF("Focus Navigation Start Content %s\n", startContent);
-  printf("[Tabindex: %d Ignore: %d]", tabIndex, ignoreTabIndex);
-#endif
+  LOGCONTENTNAVIGATION("Focus Navigation Start Content %s", startContent.get());
+  LOGFOCUSNAVIGATION(("  Tabindex: %d Ignore: %d", tabIndex, ignoreTabIndex));
 
   while (doc) {
     if (doNavigation) {
       nsCOMPtr<nsIContent> nextFocus;
       nsresult rv = GetNextTabbableContent(presShell, rootContent,
                                            skipOriginalContentCheck ? nullptr : originalStartContent,
                                            startContent, forward,
                                            tabIndex, ignoreTabIndex,
                                            getter_AddRefs(nextFocus));
       NS_ENSURE_SUCCESS(rv, rv);
 
       // found a content node to focus.
       if (nextFocus) {
-#ifdef DEBUG_FOCUS_NAVIGATION
-        PRINTTAGF("Next Content: %s\n", nextFocus);
-#endif
+        LOGCONTENTNAVIGATION("Next Content: %s", nextFocus.get());
+
         // as long as the found node was not the same as the starting node,
         // set it as the return value.
         if (nextFocus != originalStartContent)
           NS_ADDREF(*aNextContent = nextFocus);
         return NS_OK;
       }
 
       if (popupFrame) {
@@ -2573,17 +2591,17 @@ nsFocusManager::DetermineElementToMoveFo
       NS_ENSURE_TRUE(piWindow, NS_ERROR_FAILURE);
 
       // Next, retrieve the parent docshell, document and presshell.
       docShell = do_QueryInterface(docShellParent);
       NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
 
       nsCOMPtr<nsPIDOMWindow> piParentWindow = do_GetInterface(docShellParent);
       NS_ENSURE_TRUE(piParentWindow, NS_ERROR_FAILURE);
-      doc = do_QueryInterface(piParentWindow->GetExtantDocument());
+      doc = piParentWindow->GetExtantDoc();
       NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
 
       presShell = doc->GetShell();
 
       rootContent = doc->GetRootElement();
       startContent = do_QueryInterface(piWindow->GetFrameElementInternal());
       if (startContent) {
         nsIFrame* frame = startContent->GetPrimaryFrame();
@@ -2653,20 +2671,18 @@ nsFocusManager::GetNextTabbableContent(n
                                        nsIContent** aResultContent)
 {
   *aResultContent = nullptr;
 
   nsCOMPtr<nsIContent> startContent = aStartContent;
   if (!startContent)
     return NS_OK;
 
-#ifdef DEBUG_FOCUS_NAVIGATION
-  PRINTTAGF("GetNextTabbable: %s", aStartContent);
-  printf(" tabindex: %d\n", aCurrentTabIndex);
-#endif
+  LOGCONTENTNAVIGATION("GetNextTabbable: %s", aStartContent);
+  LOGFOCUSNAVIGATION(("  tabindex: %d", aCurrentTabIndex));
 
   nsPresContext* presContext = aPresShell->GetPresContext();
 
   bool getNextFrame = true;
   nsCOMPtr<nsIContent> iterStartContent = aStartContent;
   while (1) {
     nsIFrame* startFrame = iterStartContent->GetPrimaryFrame();
     // if there is no frame, look for another content node that has a frame
@@ -2725,22 +2741,18 @@ nsFocusManager::GetNextTabbableContent(n
       // The returned computed tabindex from IsFocusable() is as follows:
       //          < 0 not tabbable at all
       //          == 0 in normal tab order (last after positive tabindexed items)
       //          > 0 can be tabbed to in the order specified by this value
 
       PRInt32 tabIndex;
       frame->IsFocusable(&tabIndex, 0);
 
-#ifdef DEBUG_FOCUS_NAVIGATION
-      if (frame->GetContent()) {
-        PRINTTAGF("Next Tabbable %s:", frame->GetContent());
-        printf(" with tabindex: %d expected: %d\n", tabIndex, aCurrentTabIndex);
-      }
-#endif
+      LOGCONTENTNAVIGATION("Next Tabbable %s:", frame->GetContent());
+      LOGFOCUSNAVIGATION(("  with tabindex: %d expected: %d", tabIndex, aCurrentTabIndex));
 
       nsIContent* currentContent = frame->GetContent();
       if (tabIndex >= 0) {
         NS_ASSERTION(currentContent, "IsFocusable set a tabindex for a frame with no content");
         if (currentContent->Tag() == nsGkAtoms::img &&
             currentContent->HasAttr(kNameSpaceID_None, nsGkAtoms::usemap)) {
           // This is an image with a map. Image map areas are not traversed by
           // nsIFrameTraversal so look for the next or previous area element.
@@ -2921,17 +2933,18 @@ nsFocusManager::GetNextTabIndex(nsIConte
          child = child->GetNextSibling()) {
       childTabIndex = GetNextTabIndex(child, aCurrentTabIndex, aForward);
       if (childTabIndex > aCurrentTabIndex && childTabIndex != tabIndex) {
         tabIndex = (tabIndex == 0 || childTabIndex < tabIndex) ? childTabIndex : tabIndex;
       }
 
       nsAutoString tabIndexStr;
       child->GetAttr(kNameSpaceID_None, nsGkAtoms::tabindex, tabIndexStr);
-      PRInt32 ec, val = tabIndexStr.ToInteger(&ec);
+      nsresult ec;
+      PRInt32 val = tabIndexStr.ToInteger(&ec);
       if (NS_SUCCEEDED (ec) && val > aCurrentTabIndex && val != tabIndex) {
         tabIndex = (tabIndex == 0 || val < tabIndex) ? val : tabIndex;
       }
     }
   }
   else { /* !aForward */
     tabIndex = 1;
     for (nsIContent* child = aParent->GetFirstChild();
@@ -2940,17 +2953,18 @@ nsFocusManager::GetNextTabIndex(nsIConte
       childTabIndex = GetNextTabIndex(child, aCurrentTabIndex, aForward);
       if ((aCurrentTabIndex == 0 && childTabIndex > tabIndex) ||
           (childTabIndex < aCurrentTabIndex && childTabIndex > tabIndex)) {
         tabIndex = childTabIndex;
       }
 
       nsAutoString tabIndexStr;
       child->GetAttr(kNameSpaceID_None, nsGkAtoms::tabindex, tabIndexStr);
-      PRInt32 ec, val = tabIndexStr.ToInteger(&ec);
+      nsresult ec;
+      PRInt32 val = tabIndexStr.ToInteger(&ec);
       if (NS_SUCCEEDED (ec)) {
         if ((aCurrentTabIndex == 0 && val > tabIndex) ||
             (val < aCurrentTabIndex && val > tabIndex) ) {
           tabIndex = val;
         }
       }
     }
   }
@@ -3172,24 +3186,24 @@ nsFocusManager::GetNextTabbableDocument(
         currentPopup = content->GetPrimaryFrame();
         break;
       }
       content = content->GetParent();
     }
   }
   else if (mFocusedWindow) {
     startItem = do_QueryInterface(mFocusedWindow->GetDocShell());
-    doc = do_QueryInterface(mFocusedWindow->GetExtantDocument());
+    doc = mFocusedWindow->GetExtantDoc();
   }
   else {
     nsCOMPtr<nsIWebNavigation> webnav = do_GetInterface(mActiveWindow);
     startItem = do_QueryInterface(webnav);
 
     if (mActiveWindow) {
-      doc = do_QueryInterface(mActiveWindow->GetExtantDocument());
+      doc = mActiveWindow->GetExtantDoc();
     }
   }
 
   if (!startItem)
     return nullptr;
 
   // perform a depth first search (preorder) of the docshell tree
   // looking for an HTML Frame or a chrome document
@@ -3252,17 +3266,17 @@ nsFocusManager::GetNextTabbableDocument(
       return nullptr;
 
     // Clear currentPopup for the next iteration
     currentPopup = nullptr;
 
     // If event handling is suppressed, move on to the next document. Set
     // content to null so that the popup check will be skipped on the next
     // loop iteration.
-    doc = do_QueryInterface(nextFrame->GetExtantDocument());
+    doc = nextFrame->GetExtantDoc();
     if (!doc || doc->EventHandlingSuppressed()) {
       content = nullptr;
       continue;
     }
 
     if (checkPopups) {
       // When iterating backwards, check the panels of the previous document
       // first. If a panel exists that has focusable content, focus that.
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -10657,16 +10657,44 @@ nsGlobalWindow::SetIsApp(bool aValue)
 
   // You shouldn't call SetIsApp() more than once.
   MOZ_ASSERT(mIsApp == TriState_Unknown);
 
   mIsApp = aValue ? TriState_True : TriState_False;
 }
 
 bool
+nsGlobalWindow::IsInAppOrigin()
+{
+  FORWARD_TO_OUTER(IsInAppOrigin, (), false);
+
+  nsIPrincipal* principal = GetPrincipal();
+  NS_ENSURE_TRUE(principal != nullptr, false);
+
+  // We go trough all window parents until we find one with |mIsApp| set to
+  // something. If none is found, we are not part of an application.
+  for (nsGlobalWindow* w = static_cast<nsGlobalWindow*>(this); w;
+      w = static_cast<nsGlobalWindow*>(w->GetParentInternal())) {
+    if (w->mIsApp == TriState_True) {
+      // The window should be part of an application.
+      MOZ_ASSERT(w->mApp);
+      bool sameOrigin = false;
+      return w->mAppPrincipal &&
+             principal &&
+             NS_SUCCEEDED(principal->Equals(w->mAppPrincipal, &sameOrigin)) &&
+             sameOrigin;
+    } else if (w->mIsApp == TriState_False) {
+      return false;
+    }
+  }
+
+  return false;
+}
+
+bool
 nsGlobalWindow::IsPartOfApp()
 {
   nsCOMPtr<mozIDOMApplication> app;
 
   return NS_SUCCEEDED(GetApp(getter_AddRefs(app))) ? app != nullptr : false;
 }
 
 nsresult
@@ -10686,16 +10714,24 @@ nsGlobalWindow::SetApp(const nsAString& 
 
   nsCOMPtr<mozIDOMApplication> app;
   appsService->GetAppByManifestURL(aManifestURL, getter_AddRefs(app));
   if (!app) {
     NS_WARNING("No application found with the specified manifest URL");
     return NS_ERROR_FAILURE;
   }
 
+  nsCOMPtr<nsIURI> uri;
+  nsresult res = NS_NewURI(getter_AddRefs(uri), aManifestURL);
+  NS_ENSURE_SUCCESS(res, res);
+
+  nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
+  res = ssm->GetSimpleCodebasePrincipal(uri, getter_AddRefs(mAppPrincipal));
+  NS_ENSURE_SUCCESS(res, res);
+
   mApp = app.forget();
 
   return NS_OK;
 }
 
 nsresult
 nsGlobalWindow::GetApp(mozIDOMApplication** aApplication)
 {
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -380,16 +380,17 @@ public:
   virtual NS_HIDDEN_(nsresult) ForceClose();
 
   virtual NS_HIDDEN_(void) MaybeUpdateTouchState();
   virtual NS_HIDDEN_(void) UpdateTouchState();
   virtual NS_HIDDEN_(bool) DispatchCustomEvent(const char *aEventName);
   virtual NS_HIDDEN_(void) RefreshCompartmentPrincipal();
   virtual NS_HIDDEN_(nsresult) SetFullScreenInternal(bool aIsFullScreen, bool aRequireTrust);
   virtual NS_HIDDEN_(bool) IsPartOfApp();
+  virtual NS_HIDDEN_(bool) IsInAppOrigin();
 
   // nsIDOMStorageIndexedDB
   NS_DECL_NSIDOMSTORAGEINDEXEDDB
 
   // nsIInterfaceRequestor
   NS_DECL_NSIINTERFACEREQUESTOR
 
   // Object Management
@@ -973,16 +974,19 @@ protected:
   // whether we've sent the destroy notification for our window id
   bool                   mNotifiedIDDestroyed : 1;
 
   // Whether the window is the window of an application frame.
   // This is TriState_Unknown if the object is the content window of an
   // iframe which is neither mozBrowser nor mozApp.
   TriState               mIsApp : 2;
 
+  // Principal of the web app running in this window, if any.
+  nsCOMPtr<nsIPrincipal>        mAppPrincipal;
+
   nsCOMPtr<nsIScriptContext>    mContext;
   nsWeakPtr                     mOpener;
   nsCOMPtr<nsIControllers>      mControllers;
   nsCOMPtr<nsIArray>            mArguments;
   nsCOMPtr<nsIArray>            mArgumentsLast;
   nsCOMPtr<nsIPrincipal>        mArgumentsOrigin;
   nsRefPtr<Navigator>           mNavigator;
   nsRefPtr<nsScreen>            mScreen;
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -751,42 +751,60 @@ nsJSContext::DOMOperationCallback(JSCont
 
   // Get localizable strings
   nsXPIDLString title, msg, stopButton, waitButton, debugButton, neverShowDlg;
 
   rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
                                           "KillScriptTitle",
                                           title);
 
-  rv |= nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
+  nsresult tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
                                            "StopScriptButton",
                                            stopButton);
-
-  rv |= nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
+  if (NS_FAILED(tmp)) {
+    rv = tmp;
+  }
+
+  tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
                                            "WaitForScriptButton",
                                            waitButton);
-
-  rv |= nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
+  if (NS_FAILED(tmp)) {
+    rv = tmp;
+  }
+
+  tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
                                            "DontAskAgain",
                                            neverShowDlg);
+  if (NS_FAILED(tmp)) {
+    rv = tmp;
+  }
 
 
   if (debugPossible) {
-    rv |= nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
+    tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
                                              "DebugScriptButton",
                                              debugButton);
-
-    rv |= nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
+
+    tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
                                              "KillScriptWithDebugMessage",
                                              msg);
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
   }
   else {
-    rv |= nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
+    tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
                                              "KillScriptMessage",
                                              msg);
+    if (NS_FAILED(tmp)) {
+      rv = tmp;
+    }
   }
 
   //GetStringFromName can return NS_OK and still give NULL string
   if (NS_FAILED(rv) || !title || !msg || !stopButton || !waitButton ||
       (!debugButton && debugPossible) || !neverShowDlg) {
     NS_ERROR("Failed to get localized strings.");
     return JS_TRUE;
   }
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -597,16 +597,22 @@ public:
 
   /**
    * Returns if the window is part of an application.
    * It will check for the window app state and its parents until a window has
    * an app state different from |TriState_Unknown|.
    */
   virtual bool IsPartOfApp() = 0;
 
+  /**
+   * Returns true of this window is part of an we app, and this window has
+   * the same origin (principal) as the web app.
+   */
+  virtual bool IsInAppOrigin() = 0;
+
 protected:
   // The nsPIDOMWindow constructor. The aOuterWindow argument should
   // be null if and only if the created window itself is an outer
   // window. In all other cases aOuterWindow should be the outer
   // window for the inner window that is being created.
   nsPIDOMWindow(nsPIDOMWindow *aOuterWindow);
 
   ~nsPIDOMWindow();
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -852,16 +852,17 @@ private:
 };
 
 enum StringificationBehavior {
   eStringify,
   eEmpty,
   eNull
 };
 
+// pval must not be null and must point to a rooted JS::Value
 static inline bool
 ConvertJSValueToString(JSContext* cx, const JS::Value& v, JS::Value* pval,
                        StringificationBehavior nullBehavior,
                        StringificationBehavior undefinedBehavior,
                        FakeDependentString& result)
 {
   JSString *s;
   if (v.isString()) {
@@ -871,22 +872,17 @@ ConvertJSValueToString(JSContext* cx, co
     if (v.isNull()) {
       behavior = nullBehavior;
     } else if (v.isUndefined()) {
       behavior = undefinedBehavior;
     } else {
       behavior = eStringify;
     }
 
-    // If pval is null, that means the argument was optional and
-    // not passed; turn those into void strings if they're
-    // supposed to be stringified.
-    if (behavior != eStringify || !pval) {
-      // Here behavior == eStringify implies !pval, so both eNull and
-      // eStringify should end up with void strings.
+    if (behavior != eStringify) {
       if (behavior == eEmpty) {
         result.Truncate();
       } else {
         result.SetNull();
       }
       return true;
     }
 
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -590,17 +590,17 @@ class CGAbstractClassHook(CGAbstractStat
         assert(False)
 
 class CGAddPropertyHook(CGAbstractClassHook):
     """
     A hook for addProperty, used to preserve our wrapper from GC.
     """
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'cx'), Argument('JSHandleObject', 'obj'),
-                Argument('JSHandleId', 'id'), Argument('jsval*', 'vp')]
+                Argument('JSHandleId', 'id'), Argument('JSMutableHandleValue', 'vp')]
         CGAbstractClassHook.__init__(self, descriptor, ADDPROPERTY_HOOK_NAME,
                                      'JSBool', args)
 
     def generate_code(self):
         # FIXME https://bugzilla.mozilla.org/show_bug.cgi?id=774279
         # Using a real trace hook might enable us to deal with non-nsISupports
         # wrappercached things here.
         assert self.descriptor.nativeIsISupports
@@ -1350,16 +1350,24 @@ builtinNames = {
     IDLType.Tags.uint8: 'uint8_t',
     IDLType.Tags.uint16: 'uint16_t',
     IDLType.Tags.uint32: 'uint32_t',
     IDLType.Tags.uint64: 'uint64_t',
     IDLType.Tags.float: 'float',
     IDLType.Tags.double: 'double'
 }
 
+numericTags = [
+    IDLType.Tags.int8, IDLType.Tags.uint8,
+    IDLType.Tags.int16, IDLType.Tags.uint16,
+    IDLType.Tags.int32, IDLType.Tags.uint32,
+    IDLType.Tags.int64, IDLType.Tags.uint64,
+    IDLType.Tags.float, IDLType.Tags.double
+    ]
+
 class CastableObjectUnwrapper():
     """
     A class for unwrapping an object named by the "source" argument
     based on the passed-in descriptor and storing it in a variable
     called by the name in the "target" argument.
 
     codeOnFailure is the code to run if unwrapping fails.
     """
@@ -1435,17 +1443,18 @@ if (!tmp) {
 ${codeOnFailure}
 }
 ${target} = tmp.forget();""").substitute(self.substitution)
 
 def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
                                     isDefinitelyObject=False,
                                     isMember=False,
                                     isOptional=False,
-                                    invalidEnumValueFatal=True):
+                                    invalidEnumValueFatal=True,
+                                    defaultValue=None):
     """
     Get a template for converting a JS value to a native object based on the
     given type and descriptor.  If failureCode is given, then we're actually
     testing whether we can convert the argument to the desired type.  That
     means that failures to convert due to the JS value being the wrong type of
     value need to use failureCode instead of throwing exceptions.  Failures to
     convert that are due to JS exceptions (from toString or valueOf methods) or
     out of memory conditions need to throw exceptions no matter what
@@ -1456,25 +1465,34 @@ def getJSToNativeConversionTemplate(type
 
     if isMember is True, we're being converted from a property of some
     JS object, not from an actual method argument, so we can't rely on
     our jsval being rooted or outliving us in any way.
 
     If isOptional is true, then we are doing conversion of an optional
     argument with no default value.
 
+    invalidEnumValueFatal controls whether an invalid enum value conversion
+    attempt will throw (if true) or simply return without doing anything (if
+    false).
+
+    If defaultValue is not None, it's the IDL default value for this conversion
+
     The return value from this function is a tuple consisting of four things:
 
     1)  A string representing the conversion code.  This will have template
         substitution performed on it as follows:
 
           ${val} replaced by an expression for the JS::Value in question
           ${valPtr} is a pointer to the JS::Value in question
           ${holderName} replaced by the holder's name, if any
           ${declName} replaced by the declaration's name
+          ${haveValue} replaced by an expression that evaluates to a boolean
+                       for whether we have a JS::Value.  Only used when
+                       defaultValue is not None.
 
     2)  A CGThing representing the native C++ type we're converting to
         (declType).  This is allowed to be None if the conversion code is
         supposed to be used as-is.
     3)  A CGThing representing the type of a "holder" (holderType) which will
         hold a possible reference to the C++ thing whose type we returned in #1,
         or None if no such holder is needed.
     4)  A boolean indicating whether the caller has to do optional-argument handling.
@@ -1483,25 +1501,54 @@ def getJSToNativeConversionTemplate(type
         ${declName} and ${holderName} adjusted to point to the Value() of the
         Optional, and Construct() calls to be made on the Optional<>s as needed.
 
     ${declName} must be in scope before the generated code is entered.
 
     If holderType is not None then ${holderName} must be in scope
     before the generated code is entered.
     """
+    # If we have a defaultValue then we're not actually optional for
+    # purposes of what we need to be declared as.
+    assert(defaultValue is None or not isOptional)
+
+    # Also, we should not have a defaultValue if we know we're an object
+    assert(not isDefinitelyObject or defaultValue is None)
 
     # A helper function for dealing with failures due to the JS value being the
     # wrong type of value
     def onFailure(failureCode, isWorker):
         return CGWrapper(CGGeneric(
                 failureCode or
                 "return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);"
                 % toStringBool(isWorker)), post="\n")
 
+    # A helper function for handling default values.  Takes a template
+    # body and the C++ code to set the default value and wraps the
+    # given template body in handling for the default value.
+    def handleDefault(template, setDefault):
+        if defaultValue is None:
+            return template
+        return CGWrapper(
+            CGIndenter(CGGeneric(template)),
+            pre="if (${haveValue}) {\n",
+            post=("\n"
+                  "} else {\n"
+                  "%s;\n"
+                  "}" %
+                  CGIndenter(CGGeneric(setDefault)).define())).define()
+
+    # A helper function for handling null default values.  Much like
+    # handleDefault, but checks that the default value, if it exists, is null.
+    def handleDefaultNull(template, codeToSetNull):
+        if (defaultValue is not None and
+            not isinstance(defaultValue, IDLNullValue)):
+            raise TypeError("Can't handle non-null default value here")
+        return handleDefault(template, codeToSetNull)
+
     # A helper function for wrapping up the template body for
     # possibly-nullable objecty stuff
     def wrapObjectTemplate(templateBody, isDefinitelyObject, type,
                            codeToSetNull, isWorker, failureCode=None):
         if not isDefinitelyObject:
             # Handle the non-object cases by wrapping up the whole
             # thing in an if cascade.
             templateBody = (
@@ -1510,16 +1557,21 @@ def getJSToNativeConversionTemplate(type
             if type.nullable():
                 templateBody += (
                     "} else if (${val}.isNullOrUndefined()) {\n"
                     "  %s;\n" % codeToSetNull)
             templateBody += (
                 "} else {\n" +
                 CGIndenter(onFailure(failureCode, isWorker)).define() +
                 "}")
+            if type.nullable():
+                templateBody = handleDefaultNull(templateBody, codeToSetNull)
+            else:
+                assert(defaultValue is None)
+
         return templateBody
 
     if type.isArray():
         raise TypeError("Can't handle array arguments yet")
 
     if type.isSequence():
         if isMember:
             # XXXbz we probably _could_ handle this; we just have to be careful
@@ -1597,21 +1649,23 @@ for (uint32_t i = 0; i < length; ++i) {
                                           "const_cast< %s & >(${declName}).SetNull()" % mutableTypeName.define(),
                                           descriptorProvider.workers)
         return (templateBody, typeName, None, isOptional)
 
     if type.isUnion():
         if isMember:
             raise TypeError("Can't handle unions as members, we have a "
                             "holderType")
-
         nullable = type.nullable();
         if nullable:
             type = type.inner
 
+        assert(defaultValue is None or
+               (isinstance(defaultValue, IDLNullValue) and nullable))
+
         unionArgumentObj = "${holderName}"
         if isOptional or nullable:
             unionArgumentObj += ".ref()"
 
         memberTypes = type.flatMemberTypes
 
         interfaceMemberTypes = filter(lambda t: t.isNonCallbackInterface(), memberTypes)
         if len(interfaceMemberTypes) > 0:
@@ -1754,20 +1808,20 @@ for (uint32_t i = 0; i < length; ++i) {
         if nullable:
             typeName = "Nullable<" + typeName + " >"
         if isOptional:
             nonConstDecl = "const_cast<Optional<" + typeName + " >& >(${declName})"
         else:
             nonConstDecl = "const_cast<" + typeName + "& >(${declName})"
             typeName = "const " + typeName
 
-        def handleNull(templateBody, setToNullVar):
-            null = CGGeneric("if (${val}.isNullOrUndefined()) {\n"
+        def handleNull(templateBody, setToNullVar, extraConditionForNull=""):
+            null = CGGeneric("if (%s${val}.isNullOrUndefined()) {\n"
                              "  %s.SetNull();\n"
-                             "}" % setToNullVar)
+                             "}" % (extraConditionForNull, setToNullVar))
             templateBody = CGWrapper(CGIndenter(templateBody), pre="{\n", post="\n}")
             return CGList([null, templateBody], " else ")
 
         if type.hasNullableType:
             templateBody = handleNull(templateBody, unionArgumentObj)
 
         declType = CGGeneric(typeName)
         holderType = CGGeneric(argumentTypeName)
@@ -1787,17 +1841,23 @@ for (uint32_t i = 0; i < length; ++i) {
                 holderType = CGWrapper(holderType, pre="Maybe<", post=" >")
                 constructHolder = CGGeneric("${holderName}.construct(%s.SetValue());" % mutableDecl)
             else:
                 constructHolder = CGWrapper(holderType, post=" ${holderName}(${declName});")
                 holderType = None
 
         templateBody = CGList([constructHolder, templateBody], "\n")
         if nullable:
-            templateBody = handleNull(templateBody, mutableDecl)
+            if defaultValue:
+                assert(isinstance(defaultValue, IDLNullValue))
+                valueMissing = "!(${haveValue}) || "
+            else:
+                valueMissing = ""
+            templateBody = handleNull(templateBody, mutableDecl,
+                                      extraConditionForNull=valueMissing)
         templateBody = CGList([constructDecl, templateBody], "\n")
 
         return templateBody.define(), declType, holderType, False
 
     if type.isGeckoInterface():
         descriptor = descriptorProvider.getDescriptor(
             type.unroll().inner.identifier.name)
         # This is an interface that we implement as a concrete class
@@ -1975,42 +2035,56 @@ for (uint32_t i = 0; i < length; ++i) {
         # and undefined become null strings.
         if type.nullable():
             nullBehavior = "eNull"
             undefinedBehavior = "eNull"
         else:
             nullBehavior = "eStringify"
             undefinedBehavior = "eStringify"
 
+        def getConversionCode(varName):
+            conversionCode = (
+                "if (!ConvertJSValueToString(cx, ${val}, ${valPtr}, %s, %s, %s)) {\n"
+                "  return false;\n"
+                "}" % (nullBehavior, undefinedBehavior, varName))
+            if defaultValue is None:
+                return conversionCode
+
+            if isinstance(defaultValue, IDLNullValue):
+                assert(type.nullable())
+                return handleDefault(conversionCode,
+                                     "%s.SetNull()" % varName)
+            return handleDefault(
+                conversionCode,
+                ("static const PRUnichar data[] = { %s, 0 };\n"
+                 "%s.SetData(data, ArrayLength(data) - 1)" %
+                 (", ".join("'" + char + "'" for char in defaultValue.value),
+                  varName)))
+
         if isMember:
             # We have to make a copy, because our jsval may well not
             # live as long as our string needs to.
             declType = CGGeneric("nsString")
             return (
                 "{\n"
                 "  FakeDependentString str;\n"
-                "  if (!ConvertJSValueToString(cx, ${val}, ${valPtr}, %s, %s, str)) {\n"
-                "    return false;\n"
-                "  }\n"
+                "%s\n"
                 "  ${declName} = str;\n"
-                "}\n" %
-                (nullBehavior, undefinedBehavior),
-            declType, None,
-            isOptional)
+                "}\n" % CGIndenter(CGGeneric(getConversionCode("str"))).define(),
+                declType, None, isOptional)
 
         if isOptional:
             declType = "Optional<nsAString>"
         else:
             declType = "NonNull<nsAString>"
+
         return (
-            "if (!ConvertJSValueToString(cx, ${val}, ${valPtr}, %s, %s, ${holderName})) {\n"
-            "  return false;\n"
-            "}\n"
+            "%s\n"
             "const_cast<%s&>(${declName}) = &${holderName};" %
-            (nullBehavior, undefinedBehavior, declType),
+            (getConversionCode("${holderName}"), declType),
             CGGeneric("const " + declType), CGGeneric("FakeDependentString"),
             # No need to deal with Optional here; we have handled it already
             False)
 
     if type.isEnum():
         if type.nullable():
             raise TypeError("We don't support nullable enumerated arguments "
                             "yet")
@@ -2018,49 +2092,64 @@ for (uint32_t i = 0; i < length; ++i) {
         if invalidEnumValueFatal:
             handleInvalidEnumValueCode = "  MOZ_ASSERT(index >= 0);\n"
         else:
             handleInvalidEnumValueCode = (
                 "  if (index < 0) {\n"
                 "    return true;\n"
                 "  }\n")
             
-        return (
+        template = (
             "{\n"
             "  bool ok;\n"
             "  int index = FindEnumStringIndex<%(invalidEnumValueFatal)s>(cx, ${val}, %(values)s, \"%(enumtype)s\", &ok);\n"
             "  if (!ok) {\n"
             "    return false;\n"
             "  }\n"
             "%(handleInvalidEnumValueCode)s"
             "  ${declName} = static_cast<%(enumtype)s>(index);\n"
             "}" % { "enumtype" : enum,
                       "values" : enum + "Values::strings",
        "invalidEnumValueFatal" : toStringBool(invalidEnumValueFatal),
-  "handleInvalidEnumValueCode" : handleInvalidEnumValueCode },
-            CGGeneric(enum), None, isOptional)
+  "handleInvalidEnumValueCode" : handleInvalidEnumValueCode })
+
+        if defaultValue is not None:
+            assert(defaultValue.type.tag() == IDLType.Tags.domstring)
+            template = handleDefault(template,
+                                     ("${declName} = %sValues::%s" %
+                                      (enum,
+                                       getEnumValueName(defaultValue.value))))
+        return (template, CGGeneric(enum), None, isOptional)
 
     if type.isCallback():
         if isMember:
             raise TypeError("Can't handle member callbacks; need to sort out "
                             "rooting issues")
         # XXXbz we're going to assume that callback types are always
         # nullable and always have [TreatNonCallableAsNull] for now.
+        haveCallable = "${val}.isObject() && JS_ObjectIsCallable(cx, &${val}.toObject())"
+        if defaultValue is not None:
+            assert(isinstance(defaultValue, IDLNullValue))
+            haveCallable = "${haveValue} && " + haveCallable
         return (
-            "if (${val}.isObject() && JS_ObjectIsCallable(cx, &${val}.toObject())) {\n"
+            "if (%s) {\n"
             "  ${declName} = &${val}.toObject();\n"
             "} else {\n"
             "  ${declName} = NULL;\n"
-            "}", CGGeneric("JSObject*"), None, isOptional)
+            "}" % haveCallable,
+            CGGeneric("JSObject*"), None, isOptional)
 
     if type.isAny():
         if isMember:
             raise TypeError("Can't handle member 'any'; need to sort out "
                             "rooting issues")
-        return ("${declName} = ${val};", CGGeneric("JS::Value"), None, isOptional)
+        templateBody = "${declName} = ${val};"
+        templateBody = handleDefaultNull(templateBody,
+                                         "${declName} = JS::NullValue()")
+        return (templateBody, CGGeneric("JS::Value"), None, isOptional)
 
     if type.isObject():
         if isMember:
             raise TypeError("Can't handle member 'object'; need to sort out "
                             "rooting issues")
         template = wrapObjectTemplate("${declName} = &${val}.toObject();",
                                       isDefinitelyObject, type,
                                       "${declName} = NULL",
@@ -2088,37 +2177,73 @@ for (uint32_t i = 0; i < length; ++i) {
         declType = CGGeneric(actualTypeName)
 
         # If we're a member of something else, the const
         # will come from the Optional or our container.
         if not isMember:
             declType = CGWrapper(declType, pre="const ")
             selfRef = "const_cast<%s&>(%s)" % (typeName, selfRef)
 
-        template = ("if (!%s.Init(cx, ${val})) {\n"
+        # We do manual default value handling here, because we
+        # actually do want a jsval, and we only handle null anyway
+        if defaultValue is not None:
+            assert(isinstance(defaultValue, IDLNullValue))
+            val = "(${haveValue}) ? ${val} : JSVAL_NULL"
+        else:
+            val = "${val}"
+
+        template = ("if (!%s.Init(cx, %s)) {\n"
                     "  return false;\n"
-                    "}" % selfRef)
+                    "}" % (selfRef, val))
 
         return (template, declType, None, False)
 
     if not type.isPrimitive():
         raise TypeError("Need conversion for argument type '%s'" % type)
 
     # XXXbz need to add support for [EnforceRange] and [Clamp]
     typeName = builtinNames[type.tag()]
     if type.nullable():
-        return ("if (${val}.isNullOrUndefined()) {\n"
-                "  ${declName}.SetNull();\n"
-                "} else if (!ValueToPrimitive<" + typeName + ">(cx, ${val}, &${declName}.SetValue())) {\n"
-                "  return false;\n"
-                "}", CGGeneric("Nullable<" + typeName + ">"), None, isOptional)
+        dataLoc = "${declName}.SetValue()"
+        nullCondition = "${val}.isNullOrUndefined()"
+        if defaultValue is not None and isinstance(defaultValue, IDLNullValue):
+            nullCondition = "!(${haveValue}) || " + nullCondition
+        template = (
+            "if (%s) {\n"
+            "  ${declName}.SetNull();\n"
+            "} else if (!ValueToPrimitive<%s>(cx, ${val}, &%s)) {\n"
+            "  return false;\n"
+            "}" % (nullCondition, typeName, dataLoc))
+        declType = CGGeneric("Nullable<" + typeName + ">")
     else:
-        return ("if (!ValueToPrimitive<" + typeName + ">(cx, ${val}, &${declName})) {\n"
-                "  return false;\n"
-                "}", CGGeneric(typeName), None, isOptional)
+        assert(defaultValue is None or
+               not isinstance(defaultValue, IDLNullValue))
+        dataLoc = "${declName}"
+        template = (
+            "if (!ValueToPrimitive<%s>(cx, ${val}, &%s)) {\n"
+            "  return false;\n"
+            "}" % (typeName, dataLoc))
+        declType = CGGeneric(typeName)
+    if (defaultValue is not None and
+        # We already handled IDLNullValue, so just deal with the other ones
+        not isinstance(defaultValue, IDLNullValue)):
+        tag = defaultValue.type.tag()
+        if tag in numericTags:
+            defaultStr = defaultValue.value
+        else:
+            assert(tag == IDLType.Tags.bool)
+            defaultStr = toStringBool(defaultValue.value)
+        template = CGWrapper(CGIndenter(CGGeneric(template)),
+                             pre="if (${haveValue}) {\n",
+                             post=("\n"
+                                   "} else {\n"
+                                   "  %s = %s;\n"
+                                   "}" % (dataLoc, defaultStr))).define()
+
+    return (template, declType, None, isOptional)
 
 def instantiateJSToNativeConversionTemplate(templateTuple, replacements,
                                             argcAndIndex=None):
     """
     Take a tuple as returned by getJSToNativeConversionTemplate and a set of
     replacements as required by the strings in such a tuple, and generate code
     to convert into stack C++ types.
 
@@ -2211,75 +2336,62 @@ def convertConstIDLValueToJSVal(value):
     if tag in [IDLType.Tags.int64, IDLType.Tags.uint64]:
         return "DOUBLE_TO_JSVAL(%s)" % (value.value)
     if tag == IDLType.Tags.bool:
         return "JSVAL_TRUE" if value.value else "JSVAL_FALSE"
     if tag in [IDLType.Tags.float, IDLType.Tags.double]:
         return "DOUBLE_TO_JSVAL(%s)" % (value.value)
     raise TypeError("Const value of unhandled type: " + value.type)
 
-def convertIDLDefaultValueToJSVal(value):
-    if value.type:
-        tag = value.type.tag()
-        if (tag == IDLTy