Merge from mozilla-inbound.
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 19 Mar 2013 10:31:21 +0100
changeset 127425 c67e0e3bfa3d14dfe7af56b2c8862d04c8c31879
parent 127424 ae738d911ded004d800287f06a3e7e87c2b9e6ef (current diff)
parent 125296 f7e1b97dcc734e84550aba15c3e7eeef51cedacf (diff)
child 127426 5f25ee4c94ab949c753ca8fb5f65403460ba7632
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
milestone22.0a1
Merge from mozilla-inbound.
b2g/branding/official/Makefile.in
b2g/branding/official/content/Makefile.in
b2g/branding/unofficial/Makefile.in
b2g/branding/unofficial/content/Makefile.in
browser/components/certerror/Makefile.in
browser/components/downloads/Makefile.in
browser/components/feeds/Makefile.in
browser/components/migration/Makefile.in
browser/components/places/Makefile.in
browser/components/privatebrowsing/test/browser/global/moz.build
browser/components/privatebrowsing/test/browser/obsolete/moz.build
browser/components/privatebrowsing/test/browser/perwindow/Makefile.in
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_DownloadLastDirWithCPS.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_certexceptionsui.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_concurrent.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_concurrent_page.html
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_cookieacceptdialog.html
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_cookieacceptdialog.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_crh.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_downloadLastDir.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_downloadLastDir_c.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_downloadLastDir_toggle.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_geoprompt.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_geoprompt_page.html
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_lastpbcontextexited.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after_page.html
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after_page2.html
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_page1.html
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_page2.html
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_nonbrowser.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_openLocationLastURL.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_opendir.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_openlocation.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_placesTitleNoUpdate.html
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_placesTitleNoUpdate.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_placestitle.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_popupblocker.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_protocolhandler.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_protocolhandler_page.html
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_theming.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_ui.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_urlbarfocus.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_windowtitle.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_windowtitle_page.html
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_zoom.js
browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_zoomrestore.js
browser/components/privatebrowsing/test/browser/perwindow/head.js
browser/components/privatebrowsing/test/browser/perwindow/moz.build
browser/components/privatebrowsing/test/browser/perwindow/popup.html
browser/components/privatebrowsing/test/browser/perwindow/title.sjs
browser/components/safebrowsing/Makefile.in
browser/components/search/Makefile.in
browser/components/shell/Makefile.in
browser/devtools/Makefile.in
browser/devtools/fontinspector/Makefile.in
browser/devtools/layoutview/Makefile.in
browser/fuel/Makefile.in
browser/metro/theme/Makefile.in
browser/modules/RecentWindow.jsm
browser/themes/Makefile.in
browser/themes/linux/communicator/Makefile.in
browser/themes/osx/communicator/Makefile.in
browser/themes/windows/communicator/Makefile.in
build/unix/add_phony_targets.py
chrome/Makefile.in
content/base/Makefile.in
content/canvas/Makefile.in
content/events/Makefile.in
content/html/Makefile.in
content/html/content/Makefile.in
content/html/content/src/nsHTMLSharedObjectElement.cpp
content/html/document/Makefile.in
content/svg/Makefile.in
content/svg/content/Makefile.in
content/svg/content/src/nsSVGFilters.cpp
content/xbl/Makefile.in
content/xbl/builtin/Makefile.in
content/xbl/builtin/android/Makefile.in
content/xbl/builtin/emacs/Makefile.in
content/xbl/builtin/mac/Makefile.in
content/xbl/builtin/unix/Makefile.in
content/xbl/builtin/win/Makefile.in
content/xml/Makefile.in
content/xml/document/Makefile.in
content/xml/document/resources/Makefile.in
content/xslt/Makefile.in
content/xslt/src/Makefile.in
content/xslt/tests/buster/Makefile.in
content/xul/Makefile.in
dbm/Makefile.in
docshell/resources/content/Makefile.in
docshell/test/test_bug344861.html
dom/activities/Makefile.in
dom/activities/interfaces/Makefile.in
dom/apps/Makefile.in
dom/base/nsJSEnvironment.cpp
dom/cellbroadcast/Makefile.in
dom/cellbroadcast/tests/Makefile.in
dom/icc/Makefile.in
dom/identity/tests/Makefile.in
dom/mms/interfaces/Makefile.in
dom/network/Makefile.in
dom/payment/interfaces/Makefile.in
dom/src/Makefile.in
dom/tests/mochitest/Makefile.in
dom/tests/mochitest/ajax/Makefile.in
dom/workers/test/extensions/Makefile.in
editor/libeditor/Makefile.in
embedding/browser/Makefile.in
embedding/components/Makefile.in
embedding/components/printingui/src/Makefile.in
embedding/components/windowwatcher/Makefile.in
extensions/Makefile.in
extensions/pref/Makefile.in
gfx/cairo/Makefile.in
image/encoders/Makefile.in
intl/Makefile.in
intl/chardet/Makefile.in
ipc/Makefile.in
ipc/ipdl/test/Makefile.in
js/public/MemoryMetrics.h
js/src/Makefile.in
js/src/build/unix/add_phony_targets.py
js/src/ion/CodeGenerator.cpp
js/src/ion/IonCaches.cpp
js/src/jsmemorymetrics.cpp
js/src/shell/js.cpp
js/src/tests/lib/jittests.py
js/xpconnect/src/XPCJSRuntime.cpp
layout/style/xbl-marquee/Makefile.in
layout/tools/layout-debug/ui/Makefile.in
media/libjpeg/simd/Makefile.in
memory/Makefile.in
memory/replace/Makefile.in
mobile/android/app/profile/extensions/Makefile.in
mobile/android/app/profile/extensions/feedback@mobile.mozilla.org/chrome.manifest
mobile/android/app/profile/extensions/feedback@mobile.mozilla.org/content/content.js
mobile/android/app/profile/extensions/feedback@mobile.mozilla.org/content/overlay.js
mobile/android/app/profile/extensions/feedback@mobile.mozilla.org/content/overlay.xul
mobile/android/app/profile/extensions/feedback@mobile.mozilla.org/defaults/preferences/preferences.js
mobile/android/app/profile/extensions/feedback@mobile.mozilla.org/install.rdf.in
mobile/android/app/profile/extensions/feedback@mobile.mozilla.org/skin/beta-hdpi.png
mobile/android/app/profile/extensions/feedback@mobile.mozilla.org/skin/dino-32.png
mobile/android/app/profile/extensions/feedback@mobile.mozilla.org/skin/happy-32.png
mobile/android/app/profile/extensions/feedback@mobile.mozilla.org/skin/overlay.css
mobile/android/app/profile/extensions/feedback@mobile.mozilla.org/skin/sad-32.png
mobile/android/app/profile/extensions/moz.build
mobile/android/base/resources/menu-large-v11/browser_app_menu.xml
mobile/android/base/resources/menu-v11/browser_app_menu.xml
mobile/android/base/resources/menu-xlarge-v11/browser_app_menu.xml
mobile/android/base/resources/menu/browser_app_menu.xml
mobile/android/branding/aurora/Makefile.in
mobile/android/branding/beta/Makefile.in
mobile/android/branding/nightly/Makefile.in
mobile/android/branding/official/Makefile.in
mobile/android/branding/unofficial/Makefile.in
mobile/android/themes/core/Makefile.in
modules/libpref/src/init/all.js
mozglue/Makefile.in
parser/htmlparser/tests/Makefile.in
parser/xml/Makefile.in
python/mozbuild/mozbuild/test/backend/data/stub0/dir2/Makefile.in
rdf/base/Makefile.in
rdf/datasource/Makefile.in
security/manager/Makefile.in
security/manager/pki/resources/Makefile.in
services/Makefile.in
testing/extensions/community/README
testing/extensions/community/build.xml
testing/extensions/community/chatzilla.jar
testing/extensions/community/chrome.manifest
testing/extensions/community/chrome/content/MochiKit/MochiKit.js
testing/extensions/community/chrome/content/MochiKit/__package__.js
testing/extensions/community/chrome/content/accountcreate.js
testing/extensions/community/chrome/content/accountcreate.xul
testing/extensions/community/chrome/content/browserOverlays.xul
testing/extensions/community/chrome/content/common.js
testing/extensions/community/chrome/content/litmus.js
testing/extensions/community/chrome/content/litmusReporter.js
testing/extensions/community/chrome/content/notifications.js
testing/extensions/community/chrome/content/prefs.js
testing/extensions/community/chrome/content/qa.js
testing/extensions/community/chrome/content/qa.xul
testing/extensions/community/chrome/content/settings.js
testing/extensions/community/chrome/content/setup.xul
testing/extensions/community/chrome/content/tabs/bugAccess.js
testing/extensions/community/chrome/content/tabs/bugzilla.js
testing/extensions/community/chrome/content/tabs/bugzilla.xul
testing/extensions/community/chrome/content/tabs/chat.xul
testing/extensions/community/chrome/content/tabs/help.xul
testing/extensions/community/chrome/content/tabs/litmus.xul
testing/extensions/community/chrome/content/tabs/qmo.js
testing/extensions/community/chrome/content/tabs/qmo.xul
testing/extensions/community/chrome/content/tabs/selecttests.js
testing/extensions/community/chrome/content/tabs/selecttests.xul
testing/extensions/community/chrome/content/tabs/settings.xul
testing/extensions/community/chrome/locale/en-US/qa.dtd
testing/extensions/community/chrome/locale/en-US/qa.properties
testing/extensions/community/chrome/locale/en-US/urls.properties
testing/extensions/community/chrome/skin/browserOverlays.css
testing/extensions/community/chrome/skin/caption-bg.gif
testing/extensions/community/chrome/skin/highlight-end.png
testing/extensions/community/chrome/skin/highlight-hover-end.png
testing/extensions/community/chrome/skin/highlight-hover-mid.png
testing/extensions/community/chrome/skin/highlight-hover-start.png
testing/extensions/community/chrome/skin/highlight-mid.png
testing/extensions/community/chrome/skin/highlight-start.png
testing/extensions/community/chrome/skin/logolight.png
testing/extensions/community/chrome/skin/qa.css
testing/extensions/community/chrome/skin/qmo-16px.png
testing/extensions/community/chrome/skin/qmo-badge.png
testing/extensions/community/chrome/skin/qmo.png
testing/extensions/community/chrome/skin/qmo_logo_32x32.png
testing/extensions/community/chrome/skin/tabrow-bg.gif
testing/extensions/community/components/chatzilla-service.js
testing/extensions/community/defaults/preferences/qa.js
testing/extensions/community/install.rdf
testing/extensions/community/jar-chrome.manifest
testing/extensions/community/platform/Darwin/chrome.manifest
testing/extensions/community/platform/Darwin/chrome/skin/platform.css
testing/extensions/community/platform/WINNT/chrome.manifest
testing/extensions/community/platform/WINNT/chrome/skin/platform.css
testing/marionette/atoms/Makefile.in
testing/mochitest/tests/MochiKit-1.4.2/Makefile.in
toolkit/components/aboutmemory/Makefile.in
toolkit/components/alerts/mac/Makefile.in
toolkit/components/alerts/mac/ObserverPair.h
toolkit/components/alerts/mac/ObserverPair.mm
toolkit/components/alerts/mac/growl/CFGrowlAdditions.c
toolkit/components/alerts/mac/growl/CFGrowlAdditions.h
toolkit/components/alerts/mac/growl/CFGrowlDefines.h
toolkit/components/alerts/mac/growl/CFMutableDictionaryAdditions.c
toolkit/components/alerts/mac/growl/CFMutableDictionaryAdditions.h
toolkit/components/alerts/mac/growl/CFURLAdditions.c
toolkit/components/alerts/mac/growl/CFURLAdditions.h
toolkit/components/alerts/mac/growl/GrowlAbstractSingletonObject.h
toolkit/components/alerts/mac/growl/GrowlApplicationBridge.h
toolkit/components/alerts/mac/growl/GrowlApplicationBridge.m
toolkit/components/alerts/mac/growl/GrowlDefines.h
toolkit/components/alerts/mac/growl/GrowlDefinesInternal.h
toolkit/components/alerts/mac/growl/GrowlPathUtilities.h
toolkit/components/alerts/mac/growl/GrowlPathUtilities.m
toolkit/components/alerts/mac/growl/GrowlPathway.h
toolkit/components/alerts/mac/growl/GrowlPreferencesController.h
toolkit/components/alerts/mac/growl/GrowlTicketController.h
toolkit/components/alerts/mac/growl/Makefile.in
toolkit/components/alerts/mac/growl/license.txt
toolkit/components/alerts/mac/growl/moz.build
toolkit/components/alerts/mac/moz.build
toolkit/components/alerts/mac/mozGrowlDelegate.h
toolkit/components/alerts/mac/mozGrowlDelegate.mm
toolkit/components/alerts/mac/mozNotificationCenterDelegate.h
toolkit/components/alerts/mac/mozNotificationCenterDelegate.mm
toolkit/components/alerts/mac/nsAlertsImageLoadListener.h
toolkit/components/alerts/mac/nsAlertsImageLoadListener.mm
toolkit/components/alerts/mac/nsAlertsServiceModule.cpp
toolkit/components/alerts/mac/nsMacAlertsService.h
toolkit/components/alerts/mac/nsMacAlertsService.mm
toolkit/components/alerts/mac/nsNotificationCenterCompat.h
toolkit/components/alerts/mac/nsNotificationsList.h
toolkit/components/alerts/mac/nsNotificationsList.mm
toolkit/components/alerts/nsINotificationsList.idl
toolkit/components/apppicker/Makefile.in
toolkit/components/cookie/Makefile.in
toolkit/components/help/Makefile.in
toolkit/components/jsdownloads/Makefile.in
toolkit/components/printing/Makefile.in
toolkit/components/prompts/Makefile.in
toolkit/components/viewconfig/Makefile.in
toolkit/components/viewsource/Makefile.in
toolkit/identity/tests/mochitest/Makefile.in
toolkit/mozapps/preferences/Makefile.in
toolkit/obsolete/Makefile.in
toolkit/system/gnome/nsAlertsIconListener.h
toolkit/system/gnome/nsSystemAlertsService.cpp
toolkit/system/gnome/nsSystemAlertsService.h
toolkit/themes/Makefile.in
toolkit/themes/faststripe/global/Makefile.in
toolkit/themes/linux/Makefile.in
toolkit/themes/linux/global/Makefile.in
toolkit/themes/linux/help/Makefile.in
toolkit/themes/linux/mozapps/Makefile.in
toolkit/themes/os2/global/Makefile.in
toolkit/themes/osx/Makefile.in
toolkit/themes/osx/global/Makefile.in
toolkit/themes/osx/help/Makefile.in
toolkit/themes/osx/mozapps/Makefile.in
toolkit/themes/windows/Makefile.in
toolkit/themes/windows/global/Makefile.in
toolkit/themes/windows/help/Makefile.in
toolkit/themes/windows/mozapps/Makefile.in
tools/profiler/sampler.h
tools/profiler/sps_sampler.h
uriloader/Makefile.in
webapprt/test/Makefile.in
widget/windows/tests/Makefile.in
xpcom/ds/nsFixedSizeAllocator.cpp
xpcom/ds/nsFixedSizeAllocator.h
xpcom/reflect/xptcall/src/md/Makefile.in
xpfe/components/autocomplete/Makefile.in
xulrunner/Makefile.in
xulrunner/examples/Makefile.in
xulrunner/examples/simple/components/Makefile.in
--- a/CLOBBER
+++ b/CLOBBER
@@ -10,9 +10,9 @@
 #                  O   <-- Users coming from both parents need to Clobber
 #               /     \
 #          O               O
 #          |               |
 #          O <-- Clobber   O  <-- Clobber
 #
 # Note: The description below will be part of the error message shown to users.
 #
-Bug 648407 - Fold NSPR, NSS and SQLite libraries all together on B2G, Android, OSX and Windows
+Bug 851920 - Resources removed from the pre-processing chain are still dependant on MOZ_PROFILING/MOZ_TELEMETRY*
--- a/accessible/src/base/RoleMap.h
+++ b/accessible/src/base/RoleMap.h
@@ -1001,17 +1001,17 @@ ROLE(EMBEDDED_OBJECT,
      eNoNameRule)
 
 ROLE(NOTE,
      "note",
      ATK_ROLE_SECTION,
      NSAccessibilityGroupRole,
      USE_ROLE_STRING,
      IA2_ROLE_NOTE,
-     eNameFromSubtreeRule)
+     eNameFromSubtreeIfReqRule)
 
 ROLE(FIGURE,
      "figure",
      ATK_ROLE_PANEL,
      NSAccessibilityGroupRole,
      ROLE_SYSTEM_GROUPING,
      ROLE_SYSTEM_GROUPING,
      eNoNameRule)
--- a/accessible/tests/mochitest/events/test_focus_browserui.xul
+++ b/accessible/tests/mochitest/events/test_focus_browserui.xul
@@ -113,18 +113,22 @@ if (!MAC) {
 
       gQueue.onFinish = function()
       {
         closeBrowserWindow();
       }
       gQueue.invoke();
     }
 
-    SimpleTest.waitForExplicitFinish();
-    openBrowserWindow(doTests, gInputDocURI);
+    if (navigator.oscpu.startsWith("Windows NT 6.1") || navigator.oscpu.startsWith("Windows NT 6.2")) {
+      todo(false, "fix the leak!");
+      } else {
+      SimpleTest.waitForExplicitFinish();
+      openBrowserWindow(doTests, gInputDocURI);
+    }
   ]]>
   </script>
 
   <vbox flex="1" style="overflow: auto;">
   <body xmlns="http://www.w3.org/1999/xhtml">
     <a target="_blank"
        href="https://bugzilla.mozilla.org/show_bug.cgi?id=644452"
        title="Focus not set when switching to cached document with back or forward if anything other than the document was last focused">
--- a/accessible/tests/mochitest/name/test_general.html
+++ b/accessible/tests/mochitest/name/test_general.html
@@ -205,16 +205,21 @@
       testName("ph_text2", "a label");
       testName("ph_textarea2", "a label");
       testName("ph_text3", "a label");
 
       // Test equation image
       testName("img_eq", "x^2 + y^2 + z^2")
       testName("txt_eq", "x^2 + y^2 + z^2")
 
+      ////////////////////////////////////////////////////////////////////////
+      // tests for duplicate announcement of content
+
+      testName("test_note", null);
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 
 </head>
@@ -271,16 +276,21 @@
      title="Text is jammed with control's text in name computation">
     Bug 823927
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=835666"
      title="ARIA combobox selected value is not a part of name computation">
     Bug 835666
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=833256"
+     title="role note shouldn't pick up the name from subtree">
+    Mozilla Bug 833256
+   </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <!-- aria-label, simple label -->
   <span id="btn_simple_aria_label" role="button" aria-label="I am a button"/>
   <br/>
@@ -597,10 +607,13 @@
   <p>Image: 
     <img id="img_eq" role="math" src="foo" alt="x^2 + y^2 + z^2">
   </p>
 
   <p>Text: 
     <span id="txt_eq" role="math" title="x^2 + y^2 + z^2">x<sup>2</sup> + 
       y<sup>2</sup> + z<sup>2</sup></span>
 
+  <!-- duplicate announcement -->
+  <div id="test_note" role="note">subtree</div>
+
 </body>
 </html>
--- a/accessible/tests/mochitest/states/test_tree.xul
+++ b/accessible/tests/mochitest/states/test_tree.xul
@@ -90,19 +90,20 @@
       gQueue = new eventQueue(EVENT_REORDER);
       gQueue.push(new statesChecker("tree", new nsTreeTreeView()));
       gQueue.push(new statesChecker("treesingle", new nsTreeTreeView()));
       gQueue.push(new statesChecker("tabletree", new nsTreeTreeView()));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
-    if (MAC) {
+    if (MAC && (navigator.userAgent.indexOf("Mac OS X 10.6") != -1)) {
+
       todo(false,
-           "Re-enable on Mac after fixing bug 845095 - intermittent orange");
+           "Re-enable on Mac OS 10.6 after fixing bug 845095 - intermittent orange");
       SimpleTest.finish();
     } else {
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
     }
   ]]>
   </script>
 
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -250,16 +250,17 @@ pref("layers.offmainthreadcomposition.an
 pref("layers.offmainthreadcomposition.animate-transform", true);
 pref("layers.offmainthreadcomposition.throttle-animations", true);
 pref("layers.async-video.enabled", true);
 pref("layers.async-pan-zoom.enabled", true);
 #endif
 
 // Web Notifications
 pref("notification.feature.enabled", true);
+pref("dom.webnotifications.enabled", false);
 
 // IndexedDB
 pref("indexedDB.feature.enabled", true);
 pref("dom.indexedDB.warningQuota", 5);
 
 // prevent video elements from preloading too much data
 pref("media.preload.default", 1); // default to preload none
 pref("media.preload.auto", 2);    // preload metadata if preload=auto
deleted file mode 100644
--- a/b2g/branding/official/Makefile.in
+++ /dev/null
@@ -1,12 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/b2g/branding/official/content/Makefile.in
+++ /dev/null
@@ -1,16 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# Branding Makefile
-#  - jars chrome artwork
-
-DEPTH = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
-
deleted file mode 100644
--- a/b2g/branding/unofficial/Makefile.in
+++ /dev/null
@@ -1,12 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/b2g/branding/unofficial/content/Makefile.in
+++ /dev/null
@@ -1,15 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# Branding Makefile
-#  - jars chrome artwork
-
-DEPTH = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -631,16 +631,17 @@ var CustomEventManager = {
     }).bind(this), false);
   },
 
   handleEvent: function custevt_handleEvent(evt) {
     let detail = evt.detail;
     dump('XXX FIXME : Got a mozContentEvent: ' + detail.type + "\n");
 
     switch(detail.type) {
+      case 'desktop-notification-show':
       case 'desktop-notification-click':
       case 'desktop-notification-close':
         AlertsHelper.handleEvent(detail);
         break;
       case 'webapps-install-granted':
       case 'webapps-install-denied':
         WebappsHelper.handleEvent(detail);
         break;
@@ -668,18 +669,26 @@ var AlertsHelper = {
     if (!detail || !detail.id)
       return;
 
     let uid = detail.id;
     let listener = this._listeners[uid];
     if (!listener)
      return;
 
-    let topic = detail.type == "desktop-notification-click" ? "alertclickcallback"
-                           /* desktop-notification-close */ : "alertfinished";
+    let topic;
+    if (detail.type == "desktop-notification-click") {
+      topic = "alertclickcallback";
+    } else if (detail.type == "desktop-notification-show") {
+      topic = "alertshow";
+    } else {
+      /* desktop-notification-close */
+      topic = "alertfinished";
+    }
+
     if (uid.startsWith("app-notif")) {
       try {
         listener.mm.sendAsyncMessage("app-notification-return", {
           uid: uid,
           topic: topic,
           target: listener.target
         });
       } catch(e) {
@@ -702,20 +711,18 @@ var AlertsHelper = {
     }
 
     // we're done with this notification
     if (topic === "alertfinished") {
       delete this._listeners[uid];
     }
   },
 
-  registerListener: function alert_registerListener(cookie, alertListener) {
-    let uid = "alert" + this._count++;
-    this._listeners[uid] = { observer: alertListener, cookie: cookie };
-    return uid;
+  registerListener: function alert_registerListener(alertId, cookie, alertListener) {
+    this._listeners[alertId] = { observer: alertListener, cookie: cookie };
   },
 
   registerAppListener: function alert_registerAppListener(uid, listener) {
     this._listeners[uid] = listener;
 
     let app = DOMApplicationRegistry.getAppByManifestURL(listener.manifestURL);
     DOMApplicationRegistry.getManifestFor(app.origin, function(manifest) {
       let helper = new ManifestHelper(manifest, app.origin);
@@ -740,25 +747,28 @@ var AlertsHelper = {
   },
 
   showNotification: function alert_showNotification(imageUrl,
                                                     title,
                                                     text,
                                                     textClickable,
                                                     cookie,
                                                     uid,
-                                                    name,
+                                                    bidi,
+                                                    lang,
                                                     manifestUrl) {
     function send(appName, appIcon) {
       shell.sendChromeEvent({
         type: "desktop-notification",
         id: uid,
         icon: imageUrl,
         title: title,
         text: text,
+        bidi: bidi,
+        lang: lang,
         appName: appName,
         appIcon: appIcon,
         manifestURL: manifestUrl
       });
     }
 
     if (!manifestUrl || !manifestUrl.length) {
       send(null, null);
@@ -774,20 +784,34 @@ var AlertsHelper = {
   },
 
   showAlertNotification: function alert_showAlertNotification(imageUrl,
                                                               title,
                                                               text,
                                                               textClickable,
                                                               cookie,
                                                               alertListener,
-                                                              name) {
-    let uid = this.registerListener(null, alertListener);
+                                                              name,
+                                                              bidi,
+                                                              lang) {
+    let currentListener = this._listeners[name];
+    if (currentListener) {
+      currentListener.observer.observe(null, "alertfinished", currentListener.cookie);
+    }
+
+    this.registerListener(name, cookie, alertListener);
     this.showNotification(imageUrl, title, text, textClickable, cookie,
-                          uid, name, null);
+                          name, bidi, lang, null);
+  },
+
+  closeAlert: function alert_closeAlert(name) {
+    shell.sendChromeEvent({
+      type: "desktop-notification-close",
+      id: name
+    });
   },
 
   receiveMessage: function alert_receiveMessage(aMessage) {
     if (!aMessage.target.assertAppHasPermission("desktop-notification")) {
       Cu.reportError("Desktop-notification message " + aMessage.name +
                      " from a content process with no desktop-notification privileges.");
       return null;
     }
@@ -799,17 +823,17 @@ var AlertsHelper = {
       text: data.text,
       manifestURL: data.manifestURL,
       imageURL: data.imageURL
     }
     this.registerAppListener(data.uid, listener);
 
     this.showNotification(data.imageURL, data.title, data.text,
                           data.textClickable, null,
-                          data.uid, null, data.manifestURL);
+                          data.uid, null, null, data.manifestURL);
   },
 }
 
 var WebappsHelper = {
   _installers: {},
   _count: 0,
 
   init: function webapps_init() {
--- a/b2g/components/AlertsService.js
+++ b/b2g/components/AlertsService.js
@@ -41,21 +41,29 @@ AlertsService.prototype = {
 
   // nsIAlertsService
   showAlertNotification: function showAlertNotification(aImageUrl,
                                                         aTitle,
                                                         aText,
                                                         aTextClickable,
                                                         aCookie,
                                                         aAlertListener,
-                                                        aName) {
+                                                        aName,
+                                                        aBidi,
+                                                        aLang) {
     let browser = Services.wm.getMostRecentWindow("navigator:browser");
     browser.AlertsHelper.showAlertNotification(aImageUrl, aTitle, aText,
                                                aTextClickable, aCookie,
-                                               aAlertListener, aName);
+                                               aAlertListener, aName, aBidi,
+                                               aLang);
+  },
+
+  closeAlert: function(aName) {
+    let browser = Services.wm.getMostRecentWindow("navigator:browser");
+    browser.AlertsHelper.closeAlert(aName);
   },
 
   // nsIAppNotificationService
   showAppNotification: function showAppNotification(aImageURL,
                                                     aTitle,
                                                     aText,
                                                     aTextClickable,
                                                     aManifestURL,
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -464,19 +464,16 @@
 @BINPATH@/components/DOMWifiManager.manifest
 @BINPATH@/components/NetworkStatsManager.js
 @BINPATH@/components/NetworkStatsManager.manifest
 #endif
 #ifdef MOZ_B2G_FM
 @BINPATH@/components/DOMFMRadioChild.js
 @BINPATH@/components/DOMFMRadio.manifest
 #endif
-#ifdef XP_MACOSX
-@BINPATH@/components/libalerts.dylib
-#endif
 #ifdef MOZ_ENABLE_DBUS
 @BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
 #endif
 @BINPATH@/components/nsINIProcessor.manifest
 @BINPATH@/components/nsINIProcessor.js
 @BINPATH@/components/nsPrompter.manifest
 @BINPATH@/components/nsPrompter.js
 #ifdef MOZ_SERVICES_SYNC
--- a/b2g/test/b2g-unittest-requirements.txt
+++ b/b2g/test/b2g-unittest-requirements.txt
@@ -1,2 +1,6 @@
-mozprocess==0.8
-mozdevice==0.18
+mozprocess==0.9
+mozrunner==5.15
+mozdevice==0.21
+mozcrash==0.2.1
+mozfile==0.3
+mozlog==1.1
--- a/browser/base/content/abouthome/aboutHome.xhtml
+++ b/browser/base/content/abouthome/aboutHome.xhtml
@@ -17,17 +17,17 @@
   %browserDTD;
 ]>
 
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <title>&abouthome.pageTitle;</title>
 
     <link rel="icon" type="image/png" id="favicon"
-          href="chrome://branding/content/icon16.png"/>
+          href="chrome://branding/content/icon32.png"/>
     <link rel="stylesheet" type="text/css" media="all"
           href="chrome://browser/content/abouthome/aboutHome.css"/>
 
     <script type="text/javascript;version=1.8"
             src="chrome://browser/content/abouthome/aboutHome.js"/>
   </head>
 
   <body dir="&locale.dir;">
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -20,19 +20,18 @@ tabbrowser {
 #tabbrowser-tabs:not([overflow="true"]) ~ #alltabs-button,
 #tabbrowser-tabs:not([overflow="true"]) + #new-tab-button,
 #tabbrowser-tabs[overflow="true"] > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
 #TabsToolbar[currentset]:not([currentset*="tabbrowser-tabs,new-tab-button"]) > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
 #TabsToolbar[customizing="true"] > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button {
   visibility: collapse;
 }
 
-#tabbrowser-tabs[overflow=true] > .tabbrowser-arrowscrollbox > .scrollbutton-up[collapsed=true],
-#tabbrowser-tabs[overflow=true] > .tabbrowser-arrowscrollbox > .scrollbutton-down[collapsed=true] {
-  visibility: visible; /* keep a tab's close button under the cursor while it's closing tabs */
+#tabbrowser-tabs:not([overflow="true"])[using-closing-tabs-spacer] ~ #alltabs-button {
+  visibility: hidden; /* temporary space to keep a tab's close button under the cursor */
 }
 
 .tabbrowser-tab {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
 }
 
 .tabbrowser-tab:not([pinned]) {
   -moz-box-flex: 100;
@@ -48,24 +47,16 @@ tabbrowser {
   max-width: 0.1px;
   min-width: 0.1px;
   opacity: 0 !important;
   transition: min-width 200ms ease-out,
               max-width 250ms ease-out,
               opacity 50ms ease-out 180ms /* hide the tab for the last 20ms of the max-width transition */;
 }
 
-.tabbrowser-tabs[dontresize] > .tabbrowser-tab[fadein]:not([pinned]) {
-  /* controlled in tabbrowser.xml */
-}
-
-.tabbrowser-tabs[dontanimate] > .tabbrowser-tab {
-  transition: none !important;
-}
-
 .tab-throbber:not([fadein]):not([pinned]),
 .tab-label:not([fadein]):not([pinned]),
 .tab-icon-image:not([fadein]):not([pinned]),
 .tab-close-button:not([fadein]):not([pinned]) {
   display: none;
 }
 
 .tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned] {
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -570,16 +570,17 @@
             <image id="default-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="identity-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="geo-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="addons-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="indexedDB-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="password-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="webapps-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="plugins-notification-icon" class="notification-anchor-icon" role="button"/>
+            <image id="web-notifications-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="blocked-plugins-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="mixed-content-blocked-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="webRTC-shareDevices-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="webRTC-sharingDevices-notification-icon" class="notification-anchor-icon" role="button"/>
           </box>
           <!-- Use onclick instead of normal popup= syntax since the popup
                code fires onmousedown, and hence eats our favicon drag events.
                We only add the identity-box button to the tab order when the location bar
--- a/browser/base/content/pageinfo/pageInfo.xul
+++ b/browser/base/content/pageinfo/pageInfo.xul
@@ -44,24 +44,26 @@
     <command id="cmd_help"      oncommand="doHelpButton();"/>
     <command id="cmd_copy"      oncommand="doCopy();"/>
     <command id="cmd_selectall" oncommand="doSelectAll();"/>
 
     <!-- permissions tab -->
     <command id="cmd_imageDef"      oncommand="onCheckboxClick('image');"/>
     <command id="cmd_popupDef"      oncommand="onCheckboxClick('popup');"/>
     <command id="cmd_cookieDef"     oncommand="onCheckboxClick('cookie');"/>
+    <command id="cmd_desktop-notificationDef" oncommand="onCheckboxClick('desktop-notification');"/>
     <command id="cmd_installDef"    oncommand="onCheckboxClick('install');"/>
     <command id="cmd_fullscreenDef" oncommand="onCheckboxClick('fullscreen');"/>
     <command id="cmd_geoDef"        oncommand="onCheckboxClick('geo');"/>
     <command id="cmd_indexedDBDef"  oncommand="onCheckboxClick('indexedDB');"/>
     <command id="cmd_pluginsDef"    oncommand="onCheckboxClick('plugins');"/>
     <command id="cmd_imageToggle"   oncommand="onRadioClick('image');"/>
     <command id="cmd_popupToggle"   oncommand="onRadioClick('popup');"/>
     <command id="cmd_cookieToggle"  oncommand="onRadioClick('cookie');"/>
+    <command id="cmd_desktop-notificationToggle" oncommand="onRadioClick('desktop-notification');"/>
     <command id="cmd_installToggle" oncommand="onRadioClick('install');"/>
     <command id="cmd_fullscreenToggle" oncommand="onRadioClick('fullscreen');"/>
     <command id="cmd_geoToggle"     oncommand="onRadioClick('geo');"/>
     <command id="cmd_indexedDBToggle" oncommand="onRadioClick('indexedDB');"/>
     <command id="cmd_pluginsToggle" oncommand="onPluginRadioClick(event);"/>
   </commandset>
 
   <keyset id="pageInfoKeySet">
@@ -322,16 +324,28 @@
             <spacer flex="1"/>
             <radiogroup id="cookieRadioGroup" orient="horizontal">
               <radio id="cookie#1" command="cmd_cookieToggle" label="&permAllow;"/>
               <radio id="cookie#8" command="cmd_cookieToggle" label="&permAllowSession;"/>
               <radio id="cookie#2" command="cmd_cookieToggle" label="&permBlock;"/>
             </radiogroup>
           </hbox>
         </vbox>
+        <vbox class="permission" id="permNotificationRow">
+          <label class="permissionLabel" id="permNotificationLabel"
+                 value="&permNotifications;" control="desktop-notificationRadioGroup"/>
+          <hbox role="group" aria-labelledby="permNotificationLabel">
+            <checkbox id="desktop-notificationDef" command="cmd_desktop-notificationDef" label="&permUseDefault;"/>
+            <spacer flex="1"/>
+            <radiogroup id="desktop-notificationRadioGroup" orient="horizontal">
+              <radio id="desktop-notification#1" command="cmd_desktop-notificationToggle" label="&permAllow;"/>
+              <radio id="desktop-notification#2" command="cmd_desktop-notificationToggle" label="&permBlock;"/>
+            </radiogroup>
+          </hbox>
+        </vbox>
         <vbox class="permission" id="permInstallRow">
           <label class="permissionLabel" id="permInstallLabel"
                  value="&permInstall;" control="installRadioGroup"/>
           <hbox id="permInstallBox" role="group" aria-labelledby="permInstallLabel">
             <checkbox id="installDef" command="cmd_installDef" label="&permUseDefault;"/>
             <spacer flex="1"/>
             <radiogroup id="installRadioGroup" orient="horizontal">
               <radio id="install#1" command="cmd_installToggle" label="&permAllow;"/>
--- a/browser/base/content/pageinfo/permissions.js
+++ b/browser/base/content/pageinfo/permissions.js
@@ -24,16 +24,20 @@ var gPermObj = {
   {
     if (gPrefs.getIntPref("network.cookie.cookieBehavior") == 2)
       return BLOCK;
 
     if (gPrefs.getIntPref("network.cookie.lifetimePolicy") == 2)
       return SESSION;
     return ALLOW;
   },
+  "desktop-notification": function getNotificationDefaultPermission()
+  {
+    return BLOCK;
+  },
   popup: function getPopupDefaultPermission()
   {
     if (gPrefs.getBoolPref("dom.disable_open_during_load"))
       return BLOCK;
     return ALLOW;
   },
   install: function getInstallDefaultPermission()
   {
--- a/browser/base/content/tabbrowser.css
+++ b/browser/base/content/tabbrowser.css
@@ -42,22 +42,21 @@ tabpanels {
 }
 
 .tab-throbber:not([busy]),
 .tab-throbber[busy] + .tab-icon-image {
   display: none;
 }
 
 .closing-tabs-spacer {
-  min-width: 0;
   pointer-events: none;
 }
 
 .tabbrowser-tabs:not(:hover) > .tabbrowser-arrowscrollbox > .closing-tabs-spacer {
-  transition: min-width 150ms ease-out;
+  transition: width .15s ease-out;
 }
 
 /**
  * Optimization for tabs that are restored lazily. We can save a good amount of
  * memory that to-be-restored tabs would otherwise consume simply by setting
  * their browsers to 'display: none' as that will prevent them from having to
  * create a presentation and the like.
  */
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1573,16 +1573,17 @@
                 !Services.prefs.getBoolPref("browser.tabs.animate")) {
               this._endRemoveTab(aTab);
               return;
             }
 
             this.tabContainer._handleTabTelemetryStart(aTab);
 
             this._blurTab(aTab);
+            aTab.style.maxWidth = ""; // ensure that fade-out transition happens
             aTab.removeAttribute("fadein");
 
             setTimeout(function (tab, tabbrowser) {
               if (tab.parentNode &&
                   window.getComputedStyle(tab).maxWidth == "0.1px") {
                 NS_ASSERT(false, "Giving up waiting for the tab closing animation to finish (bug 608589)");
                 tabbrowser._endRemoveTab(tab);
               }
@@ -1769,16 +1770,20 @@
               this.tabs[i]._tPos = i;
 
             if (!this._windowIsClosing) {
               if (wasPinned)
                 this.tabContainer._positionPinnedTabs();
 
               // update tab close buttons state
               this.tabContainer.adjustTabstrip();
+
+              setTimeout(function(tabs) {
+                tabs._lastTabClosedByMouse = false;
+              }, 0, this.tabContainer);
             }
 
             // update first-tab/last-tab/beforeselected/afterselected attributes
             this.selectedTab._selected = true;
 
             // Removing the panel requires fixing up selectedPanel immediately
             // (see below), which would be hindered by the potentially expensive
             // browser removal. So we remove the browser and the panel in two
@@ -2840,24 +2845,25 @@
     </implementation>
 
     <handlers>
       <handler event="underflow" phase="capturing"><![CDATA[
         if (event.detail == 0)
           return; // Ignore vertical events
 
         var tabs = document.getBindingParent(this);
+        tabs.removeAttribute("overflow");
+
+        if (tabs._lastTabClosedByMouse)
+          tabs._expandSpacerBy(this._scrollButtonDown.clientWidth);
 
         tabs.tabbrowser._removingTabs.forEach(tabs.tabbrowser.removeTab,
                                               tabs.tabbrowser);
 
-        if (!tabs.hasAttribute("dontresize") && !tabs._closingTabsSpacer.style.minWidth) {
-          tabs.removeAttribute("overflow");
-          tabs._positionPinnedTabs();
-        }
+        tabs._positionPinnedTabs();
       ]]></handler>
       <handler event="overflow"><![CDATA[
         if (event.detail == 0)
           return; // Ignore vertical events
 
         var tabs = document.getBindingParent(this);
         tabs.setAttribute("overflow", "true");
         tabs._positionPinnedTabs();
@@ -2887,17 +2893,18 @@
         <children includes="tab"/>
 # This is to ensure anything extensions put here will go before the newtab
 # button, necessary due to the previous hack.
         <children/>
         <xul:toolbarbutton class="tabs-newtab-button"
                            command="cmd_newNavigatorTab"
                            onclick="checkForMiddleClick(this, event);"
                            tooltiptext="&newTabButton.tooltip;"/>
-        <xul:spacer class="closing-tabs-spacer" anonid="closing-tabs-spacer"/>
+        <xul:spacer class="closing-tabs-spacer" anonid="closing-tabs-spacer"
+                    style="width: 0;"/>
       </xul:arrowscrollbox>
     </content>
 
     <implementation implements="nsIDOMEventListener">
       <constructor>
         <![CDATA[
           this.mTabClipWidth = Services.prefs.getIntPref("browser.tabs.tabClipWidth");
           this.mCloseButtons = Services.prefs.getIntPref("browser.tabs.closeButtons");
@@ -3084,96 +3091,107 @@
           } catch (e) {}
         ]]></body>
       </method>
 
       <field name="_closingTabsSpacer">
         document.getAnonymousElementByAttribute(this, "anonid", "closing-tabs-spacer");
       </field>
 
-      <field name="_delayResizingRule" readonly="true"><![CDATA[
-        const href = "chrome://browser/content/browser.css";
-        const selector = ".tabbrowser-tabs[dontresize] > .tabbrowser-tab[fadein]:not([pinned])";
-
-        // XXX: document.styleSheets is not iterable (see bug 738196)
-        for (let sheet of Array.slice(document.styleSheets))
-          if (sheet.href == href)
-            for (let rule of Array.slice(sheet.cssRules))
-              if (rule.selectorText == selector) { rule; break; }
-      ]]></field>
+      <field name="_tabDefaultMaxWidth">NaN</field>
+      <field name="_lastTabClosedByMouse">false</field>
+      <field name="_hasTabTempMaxWidth">false</field>
 
       <!-- Try to keep the active tab's close button under the mouse cursor -->
       <method name="_lockTabSizing">
         <parameter name="aTab"/>
         <body><![CDATA[
           var tabs = this.tabbrowser.visibleTabs;
           if (!tabs.length)
             return;
 
+          var isEndTab = (aTab._tPos > tabs[tabs.length-1]._tPos);
+          var tabWidth = aTab.getBoundingClientRect().width;
+
+          if (!this._tabDefaultMaxWidth)
+            this._tabDefaultMaxWidth =
+              parseFloat(window.getComputedStyle(aTab).maxWidth);
+          this._lastTabClosedByMouse = true;
+
+          if (this.getAttribute("overflow") == "true") {
+            // Don't need to do anything if we're in overflow mode and aren't scrolled
+            // all the way to the right, or if we're closing the last tab.
+            if (isEndTab || !this.mTabstrip._scrollButtonDown.disabled)
+              return;
+
+            // If the tab has an owner that will become the active tab, the owner will
+            // be to the left of it, so we actually want the left tab to slide over.
+            // This can't be done as easily in non-overflow mode, so we don't bother.
+            if (aTab.owner)
+              return;
+
+            this._expandSpacerBy(tabWidth);
+          } else { // non-overflow mode
+            // Locking is neither in effect nor needed, so let tabs expand normally.
+            if (isEndTab && !this._hasTabTempMaxWidth)
+              return;
+
+            let numPinned = this.tabbrowser._numPinnedTabs;
+            // Force tabs to stay the same width, unless we're closing the last tab,
+            // which case we need to let them expand just enough so that the overall
+            // tabbar width is the same.
+            if (isEndTab) {
+              let numNormalTabs = tabs.length - numPinned;
+              tabWidth = tabWidth * (numNormalTabs + 1) / numNormalTabs;
+              if (tabWidth > this._tabDefaultMaxWidth)
+                tabWidth = this._tabDefaultMaxWidth;
+            }
+            tabWidth += "px";
+            for (let i = numPinned; i < tabs.length; i++) {
+              let tab = tabs[i];
+              tab.style.setProperty("max-width", tabWidth, "important");
+              if (!isEndTab) { // keep tabs the same width
+                tab.style.transition = "none";
+                tab.clientTop; // flush styles to skip animation; see bug 649247
+                tab.style.transition = "";
+              }
+            }
+            this._hasTabTempMaxWidth = true;
+            this.tabbrowser.addEventListener("mousemove", this, false);
+            window.addEventListener("mouseout", this, false);
+          }
+        ]]></body>
+      </method>
+
+      <method name="_expandSpacerBy">
+        <parameter name="pixels"/>
+        <body><![CDATA[
+          let spacer = this._closingTabsSpacer;
+          spacer.style.width = parseFloat(spacer.style.width) + pixels + "px";
+          this.setAttribute("using-closing-tabs-spacer", "true");
           this.tabbrowser.addEventListener("mousemove", this, false);
           window.addEventListener("mouseout", this, false);
-
-          let isEndTab = (aTab._tPos > tabs[tabs.length-1]._tPos);
-          if (isEndTab) {
-            let spacer = this._closingTabsSpacer;
-            if (!spacer.style.minWidth)
-              spacer.style.minWidth = 0;
-
-            // Locking is neither in effect nor needed, so let tabs expand normally
-            if (!this.hasAttribute("dontresize"))
-              return;
-
-            spacer.style.MozBoxFlex = 1;
-            spacer.style.minWidth = getComputedStyle(spacer).width;
-            spacer.style.MozBoxFlex = "";
-
-            this.setAttribute("dontanimate", "true");
-            this.removeAttribute("dontresize");
-            this.clientTop;
-            this.removeAttribute("dontanimate");
-            return;
-          }
-
-          if (!this.hasAttribute("dontresize")) {
-            let tabWidth = aTab.getBoundingClientRect().width;
-            this._delayResizingRule.style.setProperty("max-width", tabWidth + "px", "important");
-            this.setAttribute("dontanimate", "true");
-            this.setAttribute("dontresize", "true");
-            this.clientTop; // flush styles to skip animation; see bug 649247
-            this.removeAttribute("dontanimate");
-          }
-
-          if (!this.mTabstrip._scrollButtonUp.disabled) {
-            let spacer = this._closingTabsSpacer;
-            let width = parseFloat(spacer.style.minWidth) || 0;
-            width += aTab.getBoundingClientRect().width;
-
-            if (!this.mTabstrip._scrollButtonDown.disabled) {
-              let scrollbox = this.mTabstrip._scrollbox;
-              width -= scrollbox.scrollLeftMax - scrollbox.scrollLeft;
-            }
-
-            if (width >= 0)
-              spacer.style.minWidth = width + "px";
-          }
         ]]></body>
       </method>
 
       <method name="_unlockTabSizing">
         <body><![CDATA[
           this.tabbrowser.removeEventListener("mousemove", this, false);
           window.removeEventListener("mouseout", this, false);
 
-          this._closingTabsSpacer.style.minWidth = "";
-          this.removeAttribute("dontresize");
-
-          if (this.hasAttribute("overflow") &&
-              this.mTabstrip._scrollbox.scrollWidth <= this.mTabstrip._scrollbox.clientWidth) {
-            this.removeAttribute("overflow");
-            this._positionPinnedTabs();
+          if (this._hasTabTempMaxWidth) {
+            this._hasTabTempMaxWidth = false;
+            let tabs = this.tabbrowser.visibleTabs;
+            for (let i = 0; i < tabs.length; i++)
+              tabs[i].style.maxWidth = "";
+          }
+
+          if (this.hasAttribute("using-closing-tabs-spacer")) {
+            this.removeAttribute("using-closing-tabs-spacer");
+            this._closingTabsSpacer.style.width = 0;
           }
         ]]></body>
       </method>
 
       <field name="_lastNumPinned">0</field>
       <method name="_positionPinnedTabs">
         <body><![CDATA[
           var numPinned = this.tabbrowser._numPinnedTabs;
--- a/browser/base/content/test/social/browser_social_errorPage.js
+++ b/browser/base/content/test/social/browser_social_errorPage.js
@@ -148,17 +148,20 @@ var tests = {
     openChat(
       "https://example.com/browser/browser/base/content/test/social/social_chat.html",
       function() { // the panel api callback
         panelCallbackCount++;
       },
       function() { // the "load" callback.
         executeSoon(function() {
           todo_is(panelCallbackCount, 0, "Bug 833207 - should be no callback when error page loads.");
-          ok(SocialChatBar.chatbar.selectedChat.iframe.contentDocument.location.href.indexOf("about:socialerror?")==0, "is on social error page");
-          SocialChatBar.chatbar.selectedChat.close();
-          next();
+          let iframe = SocialChatBar.chatbar.selectedChat.iframe;
+          waitForCondition(function() iframe.contentDocument.location.href.indexOf("about:socialerror?")==0,
+                           function() {
+                            SocialChatBar.chatbar.selectedChat.close();
+                            next();
+                            },
+                           "error page didn't appear");
         });
       }
     );
   }
 }
-
--- a/browser/base/content/test/test_bug787619.html
+++ b/browser/base/content/test/test_bug787619.html
@@ -19,17 +19,17 @@
   SimpleTest.waitForExplicitFinish();
 
   const Ci = SpecialPowers.Ci;
   let wrapperClickCount = 0;
 
   function test1() {
     let plugin = document.getElementById('plugin');
     ok(plugin, 'got plugin element');
-    let objLC = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+    let objLC = SpecialPowers.wrap(plugin);
     ok(!objLC.activated, 'plugin should not be activated');
 
     synthesizeMouseAtCenter(plugin, {});
     waitForCondition(function() objLC.activated, test2, 
                      'waited too long for plugin to activate');
   }
 
   function test2() {
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -2,16 +2,17 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 // Services = object with smart getters for common XPCOM services
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
+Components.utils.import("resource:///modules/RecentWindow.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "BROWSER_NEW_TAB_URL", function () {
   const PREF = "browser.newtab.url";
 
   function getNewTabPageURL() {
     if (!Services.prefs.prefHasUserValue(PREF)) {
       if (PrivateBrowsingUtils.isWindowPrivate(window) &&
           !PrivateBrowsingUtils.permanentPrivateBrowsing)
@@ -53,22 +54,19 @@ function getBrowserURL()
 function getTopWin(skipPopups) {
   // If this is called in a browser window, use that window regardless of
   // whether it's the frontmost window, since commands can be executed in
   // background windows (bug 626148).
   if (top.document.documentElement.getAttribute("windowtype") == "navigator:browser" &&
       (!skipPopups || top.toolbar.visible))
     return top;
 
-  if (skipPopups) {
-    return Components.classes["@mozilla.org/browser/browserglue;1"]
-                     .getService(Components.interfaces.nsIBrowserGlue)
-                     .getMostRecentBrowserWindow();
-  }
-  return Services.wm.getMostRecentWindow("navigator:browser");
+  let isPrivate = PrivateBrowsingUtils.isWindowPrivate(window);
+  return RecentWindow.getMostRecentBrowserWindow({private: isPrivate,
+                                                  allowPopups: !skipPopups});
 }
 
 function openTopWin(url) {
   /* deprecated */
   openUILinkIn(url, "current");
 }
 
 function getBoolPref(prefname, def)
--- a/browser/branding/aurora/content/jar.mn
+++ b/browser/branding/aurora/content/jar.mn
@@ -6,9 +6,10 @@ browser.jar:
 % content branding %content/branding/ contentaccessible=yes
   content/branding/about.png                     (about.png)
   content/branding/about-background.png          (about-background.png)
   content/branding/about-logo.png                (about-logo.png)
   content/branding/about-wordmark.png            (about-wordmark.png)
   content/branding/icon48.png                    (icon48.png)
   content/branding/icon64.png                    (icon64.png)
   content/branding/icon16.png                    (../default16.png)
+  content/branding/icon32.png                    (../default32.png)
   content/branding/aboutDialog.css               (aboutDialog.css)
--- a/browser/branding/nightly/content/jar.mn
+++ b/browser/branding/nightly/content/jar.mn
@@ -6,9 +6,10 @@ browser.jar:
 % content branding %content/branding/ contentaccessible=yes
   content/branding/about.png                     (about.png)
   content/branding/about-background.png          (about-background.png)
   content/branding/about-logo.png                (about-logo.png)
   content/branding/about-wordmark.png            (about-wordmark.png)
   content/branding/icon48.png                    (icon48.png)
   content/branding/icon64.png                    (icon64.png)
   content/branding/icon16.png                    (../default16.png)
+  content/branding/icon32.png                    (../default32.png)
   content/branding/aboutDialog.css               (aboutDialog.css)
--- a/browser/branding/official/content/jar.mn
+++ b/browser/branding/official/content/jar.mn
@@ -5,9 +5,10 @@
 browser.jar:
 % content branding %content/branding/ contentaccessible=yes
   content/branding/about.png                     (about.png)
   content/branding/about-logo.png                (about-logo.png)
   content/branding/about-wordmark.png            (about-wordmark.png)
   content/branding/icon48.png                    (icon48.png)
   content/branding/icon64.png                    (icon64.png)
   content/branding/icon16.png                    (../default16.png)
+  content/branding/icon32.png                    (../default32.png)
   content/branding/aboutDialog.css               (aboutDialog.css)
--- a/browser/branding/unofficial/content/jar.mn
+++ b/browser/branding/unofficial/content/jar.mn
@@ -6,9 +6,10 @@ browser.jar:
 % content branding %content/branding/ contentaccessible=yes
   content/branding/about.png                     (about.png)
   content/branding/about-background.png          (about-background.png)
   content/branding/about-logo.png                (about-logo.png)
   content/branding/about-wordmark.png            (about-wordmark.png)
   content/branding/icon48.png                    (icon48.png)
   content/branding/icon64.png                    (icon64.png)
   content/branding/icon16.png                    (../default16.png)
+  content/branding/icon32.png                    (../default32.png)
   content/branding/aboutDialog.css               (aboutDialog.css)
deleted file mode 100644
--- a/browser/components/certerror/Makefile.in
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-DEPTH     = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH     = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/browser/components/downloads/Makefile.in
+++ /dev/null
@@ -1,12 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this file,
-# You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH     = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH     = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/browser/components/feeds/Makefile.in
+++ /dev/null
@@ -1,12 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/browser/components/migration/Makefile.in
+++ /dev/null
@@ -1,12 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1608,109 +1608,217 @@ BrowserGlue.prototype = {
 
 function ContentPermissionPrompt() {}
 
 ContentPermissionPrompt.prototype = {
   classID:          Components.ID("{d8903bf6-68d5-4e97-bcd1-e4d3012f721a}"),
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]),
 
-  prompt: function CPP_prompt(request) {
+  _getChromeWindow: function CPP_getChromeWindow(aWindow) {
+    var chromeWin = aWindow
+      .QueryInterface(Ci.nsIInterfaceRequestor)
+      .getInterface(Ci.nsIWebNavigation)
+      .QueryInterface(Ci.nsIDocShellTreeItem)
+      .rootTreeItem
+      .QueryInterface(Ci.nsIInterfaceRequestor)
+      .getInterface(Ci.nsIDOMWindow)
+      .QueryInterface(Ci.nsIDOMChromeWindow);
+    return chromeWin;
+  },
+
+  /**
+   * Show a permission prompt.
+   *
+   * @param aRequest               The permission request.
+   * @param aMessage               The message to display on the prompt.
+   * @param aPermission            The type of permission to prompt.
+   * @param aActions               An array of actions of the form:
+   *                               [main action, secondary actions, ...]
+   *                               Actions are of the form { stringId, action, expireType, callback }
+   *                               Permission is granted if action is null or ALLOW_ACTION.
+   * @param aNotificationId        The id of the PopupNotification.
+   * @param aAnchorId              The id for the PopupNotification anchor.
+   */
+  _showPrompt: function CPP_showPrompt(aRequest, aMessage, aPermission, aActions,
+                                       aNotificationId, aAnchorId) {
+    var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
+
+    var requestingWindow = aRequest.window.top;
+    var chromeWin = this._getChromeWindow(requestingWindow).wrappedJSObject;
+    var browser = chromeWin.gBrowser.getBrowserForDocument(requestingWindow.document);
+    var requestPrincipal = aRequest.principal;
+
+    // Transform the prompt actions into PopupNotification actions.
+    var popupNotificationActions = [];
+    for (var i = 0; i < aActions.length; i++) {
+      let promptAction = aActions[i];
+
+      // Don't offer action in PB mode if the action remembers permission for more than a session.
+      if (PrivateBrowsingUtils.isWindowPrivate(chromeWin) &&
+          promptAction.expireType != Ci.nsIPermissionManager.EXPIRE_SESSION &&
+          promptAction.action) {
+        continue;
+      }
+
+      var action = {
+        label: browserBundle.GetStringFromName(promptAction.stringId),
+        accessKey: browserBundle.GetStringFromName(promptAction.stringId + ".accesskey"),
+        callback: function() {
+          if (promptAction.callback) {
+            promptAction.callback();
+          }
+
+          // Remember permissions.
+          if (promptAction.action) {
+            Services.perms.addFromPrincipal(requestPrincipal, aPermission,
+                                            promptAction.action, promptAction.expireType);
+          }
+
+          // Grant permission if action is null or ALLOW_ACTION.
+          if (!promptAction.action || promptAction.action == Ci.nsIPermissionManager.ALLOW_ACTION) {
+            aRequest.allow();
+          } else {
+            aRequest.cancel();
+          }
+        },
+      };
+
+      popupNotificationActions.push(action);
+    }
+
+    var mainAction = popupNotificationActions[0];
+    var secondaryActions = popupNotificationActions.splice(1);
+    chromeWin.PopupNotifications.show(browser, aNotificationId, aMessage, aAnchorId,
+                                      mainAction, secondaryActions);
+  },
+
+  _promptGeo : function(aRequest) {
+    var secHistogram = Services.telemetry.getHistogramById("SECURITY_UI");
+    var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
+    var requestingURI = aRequest.principal.URI;
+
+    var message;
 
-    if (request.type != "geolocation") {
+    // Share location action.
+    var actions = [{
+      stringId: "geolocation.shareLocation",
+      action: null,
+      expireType: null,
+      callback: function() {
+        secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST_SHARE_LOCATION);
+      },
+    }];
+
+    if (requestingURI.schemeIs("file")) {
+      message = browserBundle.formatStringFromName("geolocation.shareWithFile",
+                                                   [requestingURI.path], 1);
+    } else {
+      message = browserBundle.formatStringFromName("geolocation.shareWithSite",
+                                                   [requestingURI.host], 1);
+      // Always share location action.
+      actions.push({
+        stringId: "geolocation.alwaysShareLocation",
+        action: Ci.nsIPermissionManager.ALLOW_ACTION,
+        expireType: null,
+        callback: function() {
+          secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST_ALWAYS_SHARE);
+        },
+      });
+
+      // Never share location action.
+      actions.push({
+        stringId: "geolocation.neverShareLocation",
+        action: Ci.nsIPermissionManager.DENY_ACTION,
+        expireType: null,
+        callback: function() {
+          secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST_NEVER_SHARE);
+        },
+      });
+    }
+
+    var requestingWindow = aRequest.window.top;
+    var chromeWin = this._getChromeWindow(requestingWindow).wrappedJSObject;
+    var link = chromeWin.document.getElementById("geolocation-learnmore-link");
+    link.value = browserBundle.GetStringFromName("geolocation.learnMore");
+    link.href = Services.urlFormatter.formatURLPref("browser.geolocation.warning.infoURL");
+
+    secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST);
+
+    this._showPrompt(aRequest, message, "geo", actions, "geolocation", "geo-notification-icon");
+  },
+
+  _promptWebNotifications : function(aRequest) {
+    var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
+    var requestingURI = aRequest.principal.URI;
+
+    var message = browserBundle.formatStringFromName("webNotifications.showFromSite",
+                                                     [requestingURI.host], 1);
+
+    var actions = [
+      {
+        stringId: "webNotifications.showForSession",
+        action: Ci.nsIPermissionManager.ALLOW_ACTION,
+        expireType: Ci.nsIPermissionManager.EXPIRE_SESSION,
+        callback: function() {},
+      },
+      {
+        stringId: "webNotifications.alwaysShow",
+        action: Ci.nsIPermissionManager.ALLOW_ACTION,
+        expireType: null,
+        callback: function() {},
+      },
+      {
+        stringId: "webNotifications.neverShow",
+        action: Ci.nsIPermissionManager.DENY_ACTION,
+        expireType: null,
+        callback: function() {},
+      },
+    ];
+
+    this._showPrompt(aRequest, message, "desktop-notification", actions,
+                     "web-notifications",
+                     "web-notifications-notification-icon");
+  },
+
+  prompt: function CPP_prompt(request) {
+    const kFeatureKeys = { "geolocation" : "geo",
+                           "desktop-notification" : "desktop-notification" };
+
+    // Make sure that we support the request.
+    if (!(request.type in kFeatureKeys)) {
         return;
     }
 
     var requestingPrincipal = request.principal;
     var requestingURI = requestingPrincipal.URI;
 
     // Ignore requests from non-nsIStandardURLs
     if (!(requestingURI instanceof Ci.nsIStandardURL))
       return;
 
-    var result = Services.perms.testExactPermissionFromPrincipal(requestingPrincipal, "geo");
+    var permissionKey = kFeatureKeys[request.type];
+    var result = Services.perms.testExactPermissionFromPrincipal(requestingPrincipal, permissionKey);
 
     if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
       request.allow();
       return;
     }
 
     if (result == Ci.nsIPermissionManager.DENY_ACTION) {
       request.cancel();
       return;
     }
 
-    function getChromeWindow(aWindow) {
-      var chromeWin = aWindow 
-        .QueryInterface(Ci.nsIInterfaceRequestor)
-        .getInterface(Ci.nsIWebNavigation)
-        .QueryInterface(Ci.nsIDocShellTreeItem)
-        .rootTreeItem
-        .QueryInterface(Ci.nsIInterfaceRequestor)
-        .getInterface(Ci.nsIDOMWindow)
-        .QueryInterface(Ci.nsIDOMChromeWindow);
-      return chromeWin;
+    // Show the prompt.
+    switch (request.type) {
+    case "geolocation":
+      this._promptGeo(request);
+      break;
+    case "desktop-notification":
+      this._promptWebNotifications(request);
+      break;
     }
-
-    var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
-    let secHistogram = Components.classes["@mozilla.org/base/telemetry;1"].
-                                  getService(Ci.nsITelemetry).
-                                  getHistogramById("SECURITY_UI");
-
-    var mainAction = {
-      label: browserBundle.GetStringFromName("geolocation.shareLocation"),
-      accessKey: browserBundle.GetStringFromName("geolocation.shareLocation.accesskey"),
-      callback: function() {
-        secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST_SHARE_LOCATION);
-        request.allow();
-      },
-    };
-
-    var message;
-    var secondaryActions = [];
-    var requestingWindow = request.window.top;
-    var chromeWin = getChromeWindow(requestingWindow).wrappedJSObject;
-
-    // Different message/options if it is a local file
-    if (requestingURI.schemeIs("file")) {
-      message = browserBundle.formatStringFromName("geolocation.shareWithFile",
-                                                   [requestingURI.path], 1);
-    } else {
-      message = browserBundle.formatStringFromName("geolocation.shareWithSite",
-                                                   [requestingURI.host], 1);
-
-      // Don't offer to "always/never share" in PB mode
-      if (!PrivateBrowsingUtils.isWindowPrivate(chromeWin)) {
-        secondaryActions.push({
-          label: browserBundle.GetStringFromName("geolocation.alwaysShareLocation"),
-          accessKey: browserBundle.GetStringFromName("geolocation.alwaysShareLocation.accesskey"),
-          callback: function () {
-            Services.perms.addFromPrincipal(requestingPrincipal, "geo", Ci.nsIPermissionManager.ALLOW_ACTION);
-            secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST_ALWAYS_SHARE);
-            request.allow();
-          }
-        });
-        secondaryActions.push({
-          label: browserBundle.GetStringFromName("geolocation.neverShareLocation"),
-          accessKey: browserBundle.GetStringFromName("geolocation.neverShareLocation.accesskey"),
-          callback: function () {
-            Services.perms.addFromPrincipal(requestingPrincipal, "geo", Ci.nsIPermissionManager.DENY_ACTION);
-            secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST_NEVER_SHARE);
-            request.cancel();
-          }
-        });
-      }
-    }
-
-    var link = chromeWin.document.getElementById("geolocation-learnmore-link");
-    link.value = browserBundle.GetStringFromName("geolocation.learnMore");
-    link.href = Services.urlFormatter.formatURLPref("browser.geolocation.warning.infoURL");
-
-    var browser = chromeWin.gBrowser.getBrowserForDocument(requestingWindow.document);
-
-    secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST);
-    chromeWin.PopupNotifications.show(browser, "geolocation", message, "geo-notification-icon",
-                                      mainAction, secondaryActions);
   }
 };
 
 var components = [BrowserGlue, ContentPermissionPrompt];
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
deleted file mode 100644
--- a/browser/components/places/Makefile.in
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
-
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -272,16 +272,17 @@ var gPrivacyPane = {
       if (shouldProceed) {
         let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
                            .createInstance(Ci.nsISupportsPRBool);
         Services.obs.notifyObservers(cancelQuit, "quit-application-requested",
                                      "restart");
         shouldProceed = !cancelQuit.data;
 
         if (shouldProceed) {
+          pref.value = autoStart.hasAttribute('checked');
           document.documentElement.acceptDialog();
           let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
                              .getService(Ci.nsIAppStartup);
           appStartup.quit(Ci.nsIAppStartup.eAttemptQuit |  Ci.nsIAppStartup.eRestart);
           return;
         }
       }
 
--- a/browser/components/preferences/privacy.js
+++ b/browser/components/preferences/privacy.js
@@ -275,16 +275,17 @@ var gPrivacyPane = {
       if (shouldProceed) {
         let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
                            .createInstance(Ci.nsISupportsPRBool);
         Services.obs.notifyObservers(cancelQuit, "quit-application-requested",
                                      "restart");
         shouldProceed = !cancelQuit.data;
 
         if (shouldProceed) {
+          pref.value = autoStart.hasAttribute('checked');
           document.documentElement.acceptDialog();
           let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
                              .getService(Ci.nsIAppStartup);
           appStartup.quit(Ci.nsIAppStartup.eAttemptQuit |  Ci.nsIAppStartup.eRestart);
           return;
         }
       }
 
--- a/browser/components/privatebrowsing/test/browser/Makefile.in
+++ b/browser/components/privatebrowsing/test/browser/Makefile.in
@@ -7,9 +7,51 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= test_privatebrowsing
 
+MOCHITEST_BROWSER_FILES =  \
+		head.js \
+		browser_privatebrowsing_certexceptionsui.js \
+		browser_privatebrowsing_concurrent.js \
+		browser_privatebrowsing_concurrent_page.html \
+		browser_privatebrowsing_cookieacceptdialog.js \
+		browser_privatebrowsing_cookieacceptdialog.html \
+		browser_privatebrowsing_crh.js \
+		browser_privatebrowsing_downloadLastDir.js \
+		browser_privatebrowsing_downloadLastDir_c.js \
+		browser_privatebrowsing_downloadLastDir_toggle.js \
+		browser_privatebrowsing_DownloadLastDirWithCPS.js \
+		browser_privatebrowsing_geoprompt.js \
+		browser_privatebrowsing_geoprompt_page.html \
+		browser_privatebrowsing_lastpbcontextexited.js \
+		browser_privatebrowsing_localStorage.js \
+		browser_privatebrowsing_localStorage_before_after.js \
+		browser_privatebrowsing_localStorage_before_after_page.html \
+		browser_privatebrowsing_localStorage_before_after_page2.html \
+		browser_privatebrowsing_localStorage_page1.html \
+		browser_privatebrowsing_localStorage_page2.html \
+		browser_privatebrowsing_nonbrowser.js \
+		browser_privatebrowsing_opendir.js \
+		browser_privatebrowsing_openlocation.js \
+		browser_privatebrowsing_openLocationLastURL.js \
+		browser_privatebrowsing_placestitle.js \
+		browser_privatebrowsing_placesTitleNoUpdate.js \
+		browser_privatebrowsing_placesTitleNoUpdate.html \
+		browser_privatebrowsing_popupblocker.js \
+		browser_privatebrowsing_protocolhandler.js \
+		browser_privatebrowsing_protocolhandler_page.html \
+		browser_privatebrowsing_theming.js \
+		browser_privatebrowsing_ui.js \
+		browser_privatebrowsing_urlbarfocus.js \
+		browser_privatebrowsing_windowtitle.js \
+		browser_privatebrowsing_windowtitle_page.html \
+		browser_privatebrowsing_zoom.js \
+		browser_privatebrowsing_zoomrestore.js \
+		popup.html \
+		title.sjs \
+		$(NULL)
+
 include $(topsrcdir)/config/rules.mk
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_DownloadLastDirWithCPS.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_DownloadLastDirWithCPS.js
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_certexceptionsui.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_certexceptionsui.js
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_concurrent.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent.js
--- a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_concurrent.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent.js
@@ -7,17 +7,17 @@
 // earlier private storage sessions aren't visible later.
 
 // Step 1: create new tab, load a page that sets test=value in non-private storage
 // Step 2: create a new tab, load a page that sets test2=value2 in private storage
 // Step 3: load a page in the tab from step 1 that checks the value of test2 is value2 and the total count in non-private storage is 1
 // Step 4: load a page in the tab from step 2 that checks the value of test is value and the total count in private storage is 1
 
 function test() {
-  let prefix = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_concurrent_page.html';
+  let prefix = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent_page.html';
   waitForExplicitFinish();
   gBrowser.selectedTab = gBrowser.addTab();
   let non_private_tab = gBrowser.selectedBrowser;
   non_private_tab.addEventListener('load', function() {
     non_private_tab.removeEventListener('load', arguments.callee, true);
     gBrowser.selectedTab = gBrowser.addTab();
     let private_tab = gBrowser.selectedBrowser;
     private_tab.docShell.QueryInterface(Ci.nsILoadContext).usePrivateBrowsing = true;
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_concurrent_page.html
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent_page.html
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_cookieacceptdialog.html
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_cookieacceptdialog.html
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_cookieacceptdialog.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_cookieacceptdialog.js
--- a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_cookieacceptdialog.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_cookieacceptdialog.js
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // This test makes sure that private browsing mode disables the "remember"
 // option in the cookie accept dialog.
 
 function test() {
   // initialization
   const TEST_URL = "http://mochi.test:8888/browser/browser/components/" +
-                   "privatebrowsing/test/browser/perwindow/" +
+                   "privatebrowsing/test/browser/" +
                    "browser_privatebrowsing_cookieacceptdialog.html";
   const BLANK_URL = "http://mochi.test:8888/";
   let cp = Cc["@mozilla.org/embedcomp/cookieprompt-service;1"].
            getService(Ci.nsICookiePromptService);
 
   waitForExplicitFinish();
 
   function checkRememberOption(expectedDisabled, aWindow, callback) {
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_crh.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_crh.js
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_downloadLastDir.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir.js
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_downloadLastDir_c.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir_c.js
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_downloadLastDir_toggle.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir_toggle.js
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_geoprompt.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js
--- a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_geoprompt.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js
@@ -2,17 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // This test makes sure that the geolocation prompt does not show a remember
 // control inside the private browsing mode.
 
 function test() {
   const testPageURL = "http://mochi.test:8888/browser/" +
-    "browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_geoprompt_page.html";
+    "browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt_page.html";
   waitForExplicitFinish();
 
     function checkGeolocation(aPrivateMode, aWindow, aCallback) {
     executeSoon(function() {
       aWindow.gBrowser.selectedTab = aWindow.gBrowser.addTab();
       aWindow.gBrowser.selectedBrowser.addEventListener("load", function () {
         aWindow.gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
 
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_geoprompt_page.html
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt_page.html
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_lastpbcontextexited.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_lastpbcontextexited.js
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage.js
--- a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage.js
@@ -7,26 +7,26 @@ function test() {
 
   function checkLocalStorage(aWindow, aCallback) {
     executeSoon(function() {
       let tab = aWindow.gBrowser.selectedTab = aWindow.gBrowser.addTab();
       let browser = aWindow.gBrowser.selectedBrowser;
       browser.addEventListener('load', function() {
         browser.removeEventListener('load', arguments.callee, true);
         let tab2 = aWindow.gBrowser.selectedTab = aWindow.gBrowser.addTab();
-        browser.contentWindow.location = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/perwindow/' +
+        browser.contentWindow.location = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/' +
                          'browser_privatebrowsing_localStorage_page2.html';
         browser.addEventListener('load', function() {
           browser.removeEventListener('load', arguments.callee, true);
           is(browser.contentWindow.document.title, '2', "localStorage should contain 2 items");
           aCallback();
         }, true);
       }, true);
 
-      browser.loadURI('http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/perwindow/' +
+      browser.loadURI('http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/' +
                       'browser_privatebrowsing_localStorage_page1.html');
     });
   }
 
   let windowsToClose = [];
   function testOnWindow(options, callback) {
     let win = OpenBrowserWindow(options);
     win.addEventListener("load", function onLoad() {
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after.js
--- a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after.js
@@ -10,17 +10,17 @@
 // Step 2: Load the same page in a non-private tab, ensuring that the storage instance reports only one item
 //   existing.
 
 function test() {
   // initialization
   waitForExplicitFinish();
   let windowsToClose = [];
   let testURI = "about:blank";
-  let prefix = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/perwindow/';
+  let prefix = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/';
 
   function doTest(aIsPrivateMode, aWindow, aCallback) {
     aWindow.gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
       aWindow.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
 
       if (aIsPrivateMode) {
         // do something when aIsPrivateMode is true
         is(aWindow.gBrowser.contentWindow.document.title, '1', "localStorage should contain 1 item");
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after_page.html
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after_page.html
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after_page2.html
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after_page2.html
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_page1.html
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_page1.html
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_page2.html
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_page2.html
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_nonbrowser.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_nonbrowser.js
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_openLocationLastURL.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_openLocationLastURL.js
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_opendir.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_opendir.js
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_openlocation.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_openlocation.js
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_placesTitleNoUpdate.html
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placesTitleNoUpdate.html
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_placesTitleNoUpdate.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placesTitleNoUpdate.js
--- a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_placesTitleNoUpdate.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placesTitleNoUpdate.js
@@ -5,17 +5,17 @@
 // Test to make sure that the visited page titles do not get updated inside the
 // private browsing mode.
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/PlacesUtils.jsm");
 
 function test() {
   waitForExplicitFinish();
-  const TEST_URL = "http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_placesTitleNoUpdate.html"
+  const TEST_URL = "http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placesTitleNoUpdate.html"
   const TEST_URI = Services.io.newURI(TEST_URL, null, null);
   const TITLE_1 = "Title 1";
   const TITLE_2 = "Title 2";
 
   let selectedWin = null;
   let windowsToClose = [];
   let tabToClose = null;
   let testNumber = 0;
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_placestitle.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placestitle.js
--- a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_placestitle.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placestitle.js
@@ -4,17 +4,17 @@
 
 // This test makes sure that the title of existing history entries does not
 // change inside a private window.
 
 function test() {
   waitForExplicitFinish();
 
   const TEST_URL = "http://mochi.test:8888/browser/browser/components/" +
-                   "privatebrowsing/test/browser/perwindow/title.sjs";
+                   "privatebrowsing/test/browser/title.sjs";
   let cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
 
   function waitForCleanup(aCallback) {
     // delete all cookies
     cm.removeAll();
     // delete all history items
     Services.obs.addObserver(function observeCH(aSubject, aTopic, aData) {
       Services.obs.removeObserver(observeCH, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_popupblocker.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_popupblocker.js
--- a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_popupblocker.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_popupblocker.js
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // This test makes sure that private browsing mode disables the remember option
 // for the popup blocker menu.
 function test() {
   // initialization
   waitForExplicitFinish();
 
-  let testURI = "http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/perwindow/popup.html";
+  let testURI = "http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/popup.html";
   let windowsToClose = [];
   let oldPopupPolicy = gPrefService.getBoolPref("dom.disable_open_during_load");
   gPrefService.setBoolPref("dom.disable_open_during_load", true);
 
   function testPopupBlockerMenuItem(aExpectedDisabled, aWindow, aCallback) {
 
     aWindow.gBrowser.addEventListener("DOMUpdatePageReport", function() {
       aWindow.gBrowser.removeEventListener("DOMUpdatePageReport", arguments.callee, false);
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_protocolhandler.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_protocolhandler.js
--- a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_protocolhandler.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_protocolhandler.js
@@ -6,17 +6,17 @@
 // inside the private browsing mode.
 
 function test() {
   // initialization
   waitForExplicitFinish();
   let windowsToClose = [];
   let notificationValue = "Protocol Registration: testprotocol";
   let testURI = "http://example.com/browser/" +
-    "browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_protocolhandler_page.html";
+    "browser/components/privatebrowsing/test/browser/browser_privatebrowsing_protocolhandler_page.html";
 
   function doTest(aIsPrivateMode, aWindow, aCallback) {
     aWindow.gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
       aWindow.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
 
       setTimeout(function() {
         let notificationBox = aWindow.gBrowser.getNotificationBox();
         let notification = notificationBox.getNotificationWithValue(notificationValue);
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_protocolhandler_page.html
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_protocolhandler_page.html
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_theming.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_theming.js
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_ui.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_urlbarfocus.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_urlbarfocus.js
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_windowtitle.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle.js
--- a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_windowtitle.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle.js
@@ -2,17 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // This test makes sure that the window title changes correctly while switching
 // from and to private browsing mode.
 
 function test() {
   const testPageURL = "http://mochi.test:8888/browser/" +
-    "browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_windowtitle_page.html";
+    "browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle_page.html";
   waitForExplicitFinish();
   requestLongerTimeout(2);
 
   // initialization of expected titles
   let test_title = "Test title";
   let app_name = document.documentElement.getAttribute("title");
   const isOSX = ("nsILocalFileMac" in Ci);
   let page_with_title;
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_windowtitle_page.html
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle_page.html
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_zoom.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoom.js
rename from browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_zoomrestore.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoomrestore.js
deleted file mode 100644
--- a/browser/components/privatebrowsing/test/browser/global/moz.build
+++ /dev/null
@@ -1,5 +0,0 @@
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
rename from browser/components/privatebrowsing/test/browser/perwindow/head.js
rename to browser/components/privatebrowsing/test/browser/head.js
--- a/browser/components/privatebrowsing/test/browser/moz.build
+++ b/browser/components/privatebrowsing/test/browser/moz.build
@@ -1,17 +1,5 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-# We have three category of browser-chrome tests:
-#  global: these tests focus on the global PB service implementation.
-#  perwindow: these tests focus on the per-window PB implementation.
-#  obsolete: these tests focus on the global mode, but the functionality
-#            that they are testing is specific to the global mode, and
-#            will never have a per-window counterpart.
-#
-# As a transition plan, we have divided the existing tests into the
-# global and obsolete categories, and we'll then focus on rewriting the
-# global tests to test the per-window mode.
-
-DIRS += ['perwindow']
deleted file mode 100644
--- a/browser/components/privatebrowsing/test/browser/obsolete/moz.build
+++ /dev/null
@@ -1,5 +0,0 @@
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
deleted file mode 100644
--- a/browser/components/privatebrowsing/test/browser/perwindow/Makefile.in
+++ /dev/null
@@ -1,55 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-relativesrcdir  = @relativesrcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MOCHITEST_BROWSER_FILES =  \
-		head.js \
-		browser_privatebrowsing_certexceptionsui.js \
-		browser_privatebrowsing_concurrent.js \
-		browser_privatebrowsing_concurrent_page.html \
-		browser_privatebrowsing_cookieacceptdialog.js \
-		browser_privatebrowsing_cookieacceptdialog.html \
-		browser_privatebrowsing_crh.js \
-		browser_privatebrowsing_downloadLastDir.js \
-		browser_privatebrowsing_downloadLastDir_c.js \
-		browser_privatebrowsing_downloadLastDir_toggle.js \
-		browser_privatebrowsing_DownloadLastDirWithCPS.js \
-		browser_privatebrowsing_geoprompt.js \
-		browser_privatebrowsing_geoprompt_page.html \
-		browser_privatebrowsing_lastpbcontextexited.js \
-		browser_privatebrowsing_localStorage.js \
-		browser_privatebrowsing_localStorage_before_after.js \
-		browser_privatebrowsing_localStorage_before_after_page.html \
-		browser_privatebrowsing_localStorage_before_after_page2.html \
-		browser_privatebrowsing_localStorage_page1.html \
-		browser_privatebrowsing_localStorage_page2.html \
-		browser_privatebrowsing_nonbrowser.js \
-		browser_privatebrowsing_opendir.js \
-		browser_privatebrowsing_openlocation.js \
-		browser_privatebrowsing_openLocationLastURL.js \
-		browser_privatebrowsing_placestitle.js \
-		browser_privatebrowsing_placesTitleNoUpdate.js \
-		browser_privatebrowsing_placesTitleNoUpdate.html \
-		browser_privatebrowsing_popupblocker.js \
-		browser_privatebrowsing_protocolhandler.js \
-		browser_privatebrowsing_protocolhandler_page.html \
-		browser_privatebrowsing_theming.js \
-		browser_privatebrowsing_ui.js \
-		browser_privatebrowsing_urlbarfocus.js \
-		browser_privatebrowsing_windowtitle.js \
-		browser_privatebrowsing_windowtitle_page.html \
-		browser_privatebrowsing_zoom.js \
-		browser_privatebrowsing_zoomrestore.js \
-		popup.html \
-		title.sjs \
-		$(NULL)
-
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/browser/components/privatebrowsing/test/browser/perwindow/moz.build
+++ /dev/null
@@ -1,5 +0,0 @@
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
rename from browser/components/privatebrowsing/test/browser/perwindow/popup.html
rename to browser/components/privatebrowsing/test/browser/popup.html
rename from browser/components/privatebrowsing/test/browser/perwindow/title.sjs
rename to browser/components/privatebrowsing/test/browser/title.sjs
deleted file mode 100644
--- a/browser/components/safebrowsing/Makefile.in
+++ /dev/null
@@ -1,13 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-DEPTH     = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH     = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/browser/components/search/Makefile.in
+++ /dev/null
@@ -1,12 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH     = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH     = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/browser/components/shell/Makefile.in
+++ /dev/null
@@ -1,12 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/browser/devtools/Makefile.in
+++ /dev/null
@@ -1,14 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH   = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH   = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/config.mk
-
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/browser/devtools/fontinspector/Makefile.in
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/browser/devtools/layoutview/Makefile.in
+++ /dev/null
@@ -1,12 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/browser/fuel/Makefile.in
+++ /dev/null
@@ -1,12 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH     = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH     = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -450,28 +450,27 @@
 @BINPATH@/browser/components/ChromeProfileMigrator.js
 @BINPATH@/browser/components/FirefoxProfileMigrator.js
 #ifdef XP_WIN
 @BINPATH@/browser/components/IEProfileMigrator.js
 @BINPATH@/browser/components/SafariProfileMigrator.js
 #endif
 #ifdef XP_MACOSX
 @BINPATH@/browser/components/SafariProfileMigrator.js
-@BINPATH@/components/libalerts.dylib
 #endif
 #ifdef MOZ_ENABLE_DBUS
 @BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
 #endif
 #ifdef MOZ_ENABLE_GNOME_COMPONENT
 @BINPATH@/components/@DLL_PREFIX@mozgnome@DLL_SUFFIX@
 #endif
 #ifdef MOZ_ENABLE_GNOMEVFS
 @BINPATH@/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
 #endif
-#if defined(XP_MACOSX) || defined(MOZ_ENABLE_DBUS) || defined(MOZ_ENABLE_GNOME_COMPONENT) || defined(MOZ_ENABLE_GNOMEVFS)
+#if defined(MOZ_ENABLE_DBUS) || defined(MOZ_ENABLE_GNOME_COMPONENT) || defined(MOZ_ENABLE_GNOMEVFS)
 @BINPATH@/components/components.manifest
 #endif
 @BINPATH@/components/nsINIProcessor.manifest
 @BINPATH@/components/nsINIProcessor.js
 @BINPATH@/components/nsPrompter.manifest
 @BINPATH@/components/nsPrompter.js
 #ifdef MOZ_DATA_REPORTING
 @BINPATH@/components/DataReporting.manifest
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -42,16 +42,17 @@ component.reg
 components/browser.manifest
 components/components.list
 components/@DLL_PREFIX@browserdirprovider@DLL_SUFFIX@
 components/@DLL_PREFIX@brwsrdir@DLL_SUFFIX@
 components/@DLL_PREFIX@myspell@DLL_SUFFIX@
 components/@DLL_PREFIX@spellchecker@DLL_SUFFIX@
 components/@DLL_PREFIX@spellchk@DLL_SUFFIX@
 #ifdef XP_MACOSX
+components/libalerts.dylib
 components/libalerts_s.dylib
 #endif
 components/aboutCertError.js
 components/aboutPrivateBrowsing.js
 components/aboutRights.js
 components/aboutRobots.js
 components/aboutSessionRestore.js
 components/autocomplete.xpt
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -261,16 +261,24 @@ geolocation.alwaysShareLocation.accesske
 geolocation.neverShareLocation=Never Share Location
 geolocation.neverShareLocation.accesskey=N
 geolocation.shareWithSite=Would you like to share your location with %S?
 geolocation.shareWithFile=Would you like to share your location with the file %S?
 # LOCALIZATION NOTE (geolocation.learnMore): Use the unicode ellipsis char, \u2026,
 # or use "..." if \u2026 doesn't suit traditions in your locale.
 geolocation.learnMore=Learn More…
 
+webNotifications.showForSession=Show for this session
+webNotifications.showForSession.accesskey=s
+webNotifications.alwaysShow=Always Show Notifications
+webNotifications.alwaysShow.accesskey=A
+webNotifications.neverShow=Always Block Notifications
+webNotifications.neverShow.accesskey=N
+webNotifications.showFromSite=Would you like to show notifications from %S?
+
 # Phishing/Malware Notification Bar.
 # LOCALIZATION NOTE (notAForgery, notAnAttack)
 # The two button strings will never be shown at the same time, so
 # it's okay for them to have the same access key
 safebrowsing.getMeOutOfHereButton.label=Get me out of here!
 safebrowsing.getMeOutOfHereButton.accessKey=G
 safebrowsing.reportedWebForgery=Reported Web Forgery!
 safebrowsing.notAForgeryButton.label=This isn't a web forgery…
--- a/browser/locales/en-US/chrome/browser/pageInfo.dtd
+++ b/browser/locales/en-US/chrome/browser/pageInfo.dtd
@@ -56,16 +56,17 @@
 <!ENTITY  permAskAlways         "Always ask">
 <!ENTITY  permAllow             "Allow">
 <!ENTITY  permAllowSession      "Allow for Session">
 <!ENTITY  permBlock             "Block">
 <!ENTITY  permissionsFor        "Permissions for:">
 <!ENTITY  permImage             "Load Images">
 <!ENTITY  permPopup             "Open Pop-up Windows">
 <!ENTITY  permCookie            "Set Cookies">
+<!ENTITY  permNotifications     "Show Notifications">
 <!ENTITY  permInstall           "Install Extensions or Themes">
 <!ENTITY  permGeo               "Share Location">
 <!ENTITY  permPlugins           "Activate Plugins">
 <!ENTITY  permFullscreen        "Enter Fullscreen">
 
 <!ENTITY  permIndexedDB              "Maintain Offline Storage">
 <!ENTITY  permClearStorage           "Clear Storage">
 <!ENTITY  permClearStorage.accesskey "C">
--- a/browser/metro/base/content/Util.js
+++ b/browser/metro/base/content/Util.js
@@ -147,16 +147,39 @@ let Util = {
     }
 
     if (link && link.hasAttribute("href"))
       return link.href;
     else
       return null;
   },
 
+  isTextInput: function isTextInput(aElement) {
+    return ((aElement instanceof Ci.nsIDOMHTMLInputElement &&
+             aElement.mozIsTextField(false)) ||
+            aElement instanceof Ci.nsIDOMHTMLTextAreaElement);
+  },
+
+  isLink: function isLink(aElement) {
+    return ((aElement instanceof Ci.nsIDOMHTMLAnchorElement && aElement.href) ||
+            (aElement instanceof Ci.nsIDOMHTMLAreaElement && aElement.href) ||
+            aElement instanceof Ci.nsIDOMHTMLLinkElement ||
+            aElement.getAttributeNS(kXLinkNamespace, "type") == "simple");
+  },
+
+  isText: function isText(aElement) {
+    return (aElement instanceof Ci.nsIDOMHTMLParagraphElement ||
+            aElement instanceof Ci.nsIDOMHTMLDivElement ||
+            aElement instanceof Ci.nsIDOMHTMLLIElement ||
+            aElement instanceof Ci.nsIDOMHTMLPreElement ||
+            aElement instanceof Ci.nsIDOMHTMLHeadingElement ||
+            aElement instanceof Ci.nsIDOMHTMLTableCellElement ||
+            aElement instanceof Ci.nsIDOMHTMLBodyElement);
+  },
+
   /*
    * Rect and nsIDOMRect utilities
    */
 
   pointWithinRect: function pointWithinRect(aX, aY, aRect) {
     return (aRect.left < aX && aRect.top < aY &&
             aRect.right > aX && aRect.bottom > aY);
   },
--- a/browser/metro/base/content/bindings/grid.xml
+++ b/browser/metro/base/content/bindings/grid.xml
@@ -44,31 +44,45 @@
           ]]>
         </body>
       </method>
 
       <method name="toggleItemSelection">
         <parameter name="anItem"/>
         <body>
           <![CDATA[
-            anItem.selected = !anItem.selected;
+            let wasSelected = anItem.selected;
+            if ("single" == this.getAttribute("seltype")) {
+              this.clearSelection();
+            }
+            anItem.selected = !wasSelected;
+            this._selectedItem = wasSelected ? null : anItem;
             this._fireOnSelectionChange();
           ]]>
         </body>
       </method>
 
       <method name="selectItem">
         <parameter name="anItem"/>
         <body>
           <![CDATA[
-            this.clearSelection();
+            let wasSelected = anItem.selected,
+                isSingleMode = ("single" == this.getAttribute("seltype"));
+            if (isSingleMode) {
+              this.clearSelection();
+            }
             this._selectedItem = anItem;
-            this._selectedItem.selected = true;
-
-            this._fireOnSelect();
+            anItem.selected = true;
+            if (isSingleMode) {
+              if (!wasSelected) {
+                this._fireOnSelect();
+              }
+            } else {
+              this._fireOnSelectionChange();
+            }
           ]]>
         </body>
       </method>
 
       <method name="handleItemClick">
         <parameter name="aItem"/>
         <body>
           <![CDATA[
--- a/browser/metro/base/content/contenthandlers/Content.js
+++ b/browser/metro/base/content/contenthandlers/Content.js
@@ -329,33 +329,33 @@ let Content = {
         if (!aEvent.target.value)
           this.formAssistant.close();
         else
           this.formAssistant.open(aEvent.target);
         break;
 
       case "click":
         if (aEvent.eventPhase == aEvent.BUBBLING_PHASE)
-          this._onClick(aEvent);
+          this._onClickBubble(aEvent);
         else
-          this._genericMouseClick(aEvent);
+          this._onClickCapture(aEvent);
         break;
       
       case "DOMContentLoaded":
-        this._maybeNotifyErroPage();
+        this._maybeNotifyErrorPage();
         break;
 
       case "pagehide":
         if (aEvent.target == content.document)
           this._resetFontSize();          
         break;
 
       case "touchstart":
         let touch = aEvent.changedTouches[0];
-        this._genericMouseDown(touch.clientX, touch.clientY);
+        this._onTouchStart(touch.clientX, touch.clientY);
         break;
     }
   },
 
   receiveMessage: function receiveMessage(aMessage) {
     if (this._debugEvents) Util.dumpLn("Content:", aMessage.name);
     let json = aMessage.json;
     let x = json.x;
@@ -395,38 +395,35 @@ let Content = {
 
       case "Browser:PanBegin":
         this._cancelTapHighlight();
         break;
     }
   },
 
   /******************************************************
-   * generic input handlers
-   *
-   * regardless of whether the input was received via
-   * message manager or sent directly via dispatch.
+   * Event handlers
    */
 
-  _genericMouseDown: function _genericMouseDown(x, y) {
+  _onTouchStart: function _onTouchStart(x, y) {
     let { element } = elementFromPoint(x, y);
     if (!element)
       return;
 
     // There is no need to have a feedback for disabled element
     let isDisabled = element instanceof HTMLOptionElement ?
       (element.disabled || element.parentNode.disabled) : element.disabled;
     if (isDisabled)
       return;
 
     // Set the target element to active
     this._doTapHighlight(element);
   },
 
-  _genericMouseClick: function _genericMouseClick(aEvent) {
+  _onClickCapture: function _onClickCapture(aEvent) {
     ContextMenuHandler.reset();
 
     let { element: element } = elementFromPoint(aEvent.clientX, aEvent.clientY);
     if (!element)
       return;
 
     // Only show autocomplete after the item is clicked
     if (!this.lastClickElement || this.lastClickElement != element) {
@@ -438,22 +435,18 @@ let Content = {
     }
 
     this.formAssistant.focusSync = true;
     this.formAssistant.open(element, aEvent);
     this._cancelTapHighlight();
     this.formAssistant.focusSync = false;
   },
 
-  /******************************************************
-   * Event handlers
-   */
-
   // Checks clicks we care about - events bubbling up from about pages.
-  _onClick: function _onClick(aEvent) {
+  _onClickBubble: function _onClickBubble(aEvent) {
     // Don't trust synthetic events
     if (!aEvent.isTrusted)
       return;
 
     let ot = aEvent.originalTarget;
     let errorDoc = ot.ownerDocument;
     if (!errorDoc)
       return;
@@ -526,17 +519,17 @@ let Content = {
                     top: r.top + offset.y,
                     width: r.width,
                     height: r.height
                   });
     }
     return result;
   },
 
-  _maybeNotifyErroPage: function _maybeNotifyErroPage() {
+  _maybeNotifyErrorPage: function _maybeNotifyErrorPage() {
     // Notify browser that an error page is being shown instead
     // of the target location. Necessary to get proper thumbnail
     // updates on chrome for error pages.
     if (content.location.href !== content.document.documentURI)
       sendAsyncMessage("Browser:ErrorPage", null);
   },
 
   _resetFontSize: function _resetFontSize() {
--- a/browser/metro/base/content/contenthandlers/ContextMenuHandler.js
+++ b/browser/metro/base/content/contenthandlers/ContextMenuHandler.js
@@ -128,57 +128,57 @@ var ContextMenuHandler = {
                            aEvent.clientY, aEvent.mozInputSource);
   },
 
   /******************************************************
    * ContextCommand handlers
    */
 
   _onSelectAll: function _onSelectAll() {
-    if (this._isTextInput(this._target)) {
+    if (Util.isTextInput(this._target)) {
       // select all text in the input control
       this._target.select();
     } else {
       // select the entire document
       content.getSelection().selectAllChildren(content.document);
     }
     this.reset();
   },
 
   _onPaste: function _onPaste() {
     // paste text if this is an input control
-    if (this._isTextInput(this._target)) {
+    if (Util.isTextInput(this._target)) {
       let edit = this._target.QueryInterface(Ci.nsIDOMNSEditableElement);
       if (edit) {
         edit.editor.paste(Ci.nsIClipboard.kGlobalClipboard);
       } else {
         Util.dumpLn("error: target element does not support nsIDOMNSEditableElement");
       }
     }
     this.reset();
   },
 
   _onCopyImage: function _onCopyImage() {
     Util.copyImageToClipboard(this._target);
   },
 
   _onCut: function _onCut() {
-    if (this._isTextInput(this._target)) {
+    if (Util.isTextInput(this._target)) {
       let edit = this._target.QueryInterface(Ci.nsIDOMNSEditableElement);
       if (edit) {
         edit.editor.cut();
       } else {
         Util.dumpLn("error: target element does not support nsIDOMNSEditableElement");
       }
     }
     this.reset();
   },
 
   _onCopy: function _onCopy() {
-    if (this._isTextInput(this._target)) {
+    if (Util.isTextInput(this._target)) {
       let edit = this._target.QueryInterface(Ci.nsIDOMNSEditableElement);
       if (edit) {
         edit.editor.copy();
       } else {
         Util.dumpLn("error: target element does not support nsIDOMNSEditableElement");
       }
     } else {
       let selectionText = this._previousState.string;
@@ -276,33 +276,33 @@ var ContextMenuHandler = {
     }
 
     let elem = popupNode;
     let isText = false;
 
     while (elem) {
       if (elem.nodeType == Ci.nsIDOMNode.ELEMENT_NODE) {
         // is the target a link or a descendant of a link?
-        if (this._isLink(elem)) {
+        if (Util.isLink(elem)) {
           // If this is an image that links to itself, don't include both link and
           // image otpions.
           if (imageUrl == this._getLinkURL(elem)) {
             elem = elem.parentNode;
             continue;
           }
 
           state.types.push("link");
           state.label = state.linkURL = this._getLinkURL(elem);
           linkUrl = state.linkURL;
           state.linkTitle = popupNode.textContent || popupNode.title;
           state.linkProtocol = this._getProtocol(this._getURI(state.linkURL));
           // mark as text so we can pickup on selection below
           isText = true;
           break;
-        } else if (this._isTextInput(elem)) {
+        } else if (Util.isTextInput(elem)) {
           let selectionStart = elem.selectionStart;
           let selectionEnd = elem.selectionEnd;
 
           state.types.push("input-text");
           this._target = elem;
 
           // Don't include "copy" for password fields.
           if (!(elem instanceof Ci.nsIDOMHTMLInputElement) || elem.mozIsTextField(true)) {
@@ -325,17 +325,17 @@ var ContextMenuHandler = {
           let cb = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
           let hasData = cb.hasDataMatchingFlavors(flavors,
                                                   flavors.length,
                                                   Ci.nsIClipboard.kGlobalClipboard);
           if (hasData && !elem.readOnly) {
             state.types.push("paste");
           }
           break;
-        } else if (this._isText(elem)) {
+        } else if (Util.isText(elem)) {
           isText = true;
         } else if (elem instanceof Ci.nsIDOMHTMLMediaElement ||
                    elem instanceof Ci.nsIDOMHTMLVideoElement) {
           state.label = state.mediaURL = (elem.currentSrc || elem.src);
           state.types.push((elem.paused || elem.ended) ?
             "media-paused" : "media-playing");
           if (elem instanceof Ci.nsIDOMHTMLVideoElement) {
             state.types.push("video");
@@ -376,39 +376,16 @@ var ContextMenuHandler = {
       if (this._types[i].handler(state, popupNode))
         state.types.push(this._types[i].name);
 
     this._previousState = state;
 
     sendAsyncMessage("Content:ContextMenu", state);
   },
 
-  _isTextInput: function _isTextInput(element) {
-    return ((element instanceof Ci.nsIDOMHTMLInputElement &&
-             element.mozIsTextField(false)) ||
-            element instanceof Ci.nsIDOMHTMLTextAreaElement);
-  },
-
-  _isLink: function _isLink(element) {
-    return ((element instanceof Ci.nsIDOMHTMLAnchorElement && element.href) ||
-            (element instanceof Ci.nsIDOMHTMLAreaElement && element.href) ||
-            element instanceof Ci.nsIDOMHTMLLinkElement ||
-            element.getAttributeNS(kXLinkNamespace, "type") == "simple");
-  },
-
-  _isText: function _isText(element) {
-    return (element instanceof Ci.nsIDOMHTMLParagraphElement ||
-            element instanceof Ci.nsIDOMHTMLDivElement ||
-            element instanceof Ci.nsIDOMHTMLLIElement ||
-            element instanceof Ci.nsIDOMHTMLPreElement ||
-            element instanceof Ci.nsIDOMHTMLHeadingElement ||
-            element instanceof Ci.nsIDOMHTMLTableCellElement ||
-            element instanceof Ci.nsIDOMHTMLBodyElement);
-  },
-
   _getLinkURL: function ch_getLinkURL(aLink) {
     let href = aLink.href;
     if (href)
       return href;
 
     href = aLink.getAttributeNS(kXLinkNamespace, "href");
     if (!href || !href.match(/\S/)) {
       // Without this we try to save as the current doc,
--- a/browser/metro/base/content/contenthandlers/FormHelper.js
+++ b/browser/metro/base/content/contenthandlers/FormHelper.js
@@ -48,78 +48,71 @@ function FormAssistant() {
   addEventListener("pagehide", this, false);
   addEventListener("submit", this, false);
 
   this._enabled = Services.prefs.prefHasUserValue(kPrefFormHelperEnabled) ?
                     Services.prefs.getBoolPref(kPrefFormHelperEnabled) : false;
 };
 
 FormAssistant.prototype = {
+  _els: Cc["@mozilla.org/eventlistenerservice;1"].getService(Ci.nsIEventListenerService),
+  _open: false,
+  _focusSync: false,
   _debugEvents: false,
   _selectWrapper: null,
-  _currentIndex: -1,
-  _elements: [],
-
+  _currentElement: null,
   invalidSubmit: false,
 
-  get currentElement() {
-    return this._elements[this._currentIndex];
+  get focusSync() {
+    return this._focusSync;
   },
 
-  get currentIndex() {
-    return this._currentIndex;
+  set focusSync(aVal) {
+    this._focusSync = aVal;
+  },
+
+  get currentElement() {
+    return this._currentElement;
   },
 
-  set currentIndex(aIndex) {
-    let element = this._elements[aIndex];
-    if (!element)
-      return -1;
+  set currentElement(aElement) {
+    if (!aElement || !this._isVisibleElement(aElement)) {
+      return null;
+    }
 
-    if (this._isVisibleElement(element)) {
-      this._currentIndex = aIndex;
-      gFocusManager.setFocus(element, Ci.nsIFocusManager.FLAG_NOSCROLL);
+    this._currentElement = aElement;
+    gFocusManager.setFocus(this._currentElement, Ci.nsIFocusManager.FLAG_NOSCROLL);
 
-      // To ensure we get the current caret positionning of the focused
-      // element we need to delayed a bit the event
-      this._executeDelayed(function(self) {
-        // Bug 640870
-        // Sometimes the element inner frame get destroyed while the element
-        // receive the focus because the display is turned to 'none' for
-        // example, in this "fun" case just do nothing if the element is hidden
-        if (self._isVisibleElement(gFocusManager.focusedElement))
-          sendAsyncMessage("FormAssist:Show", self._getJSON());
-      });
-    } else {
-      // Repopulate the list of elements in the page, some could have gone
-      // because of AJAX changes for example
-      this._elements = [];
-      let currentIndex = this._getAllElements(gFocusManager.focusedElement)
-
-      if (aIndex < this._currentIndex)
-        this.currentIndex = currentIndex - 1;
-      else if (aIndex > this._currentIndex)
-        this.currentIndex = currentIndex + 1;
-      else if (this._currentIndex != currentIndex)
-        this.currentIndex = currentIndex;
-    }
-    return element;
+    // To ensure we get the current caret positionning of the focused
+    // element we need to delayed a bit the event
+    this._executeDelayed(function(self) {
+      // Bug 640870
+      // Sometimes the element inner frame get destroyed while the element
+      // receive the focus because the display is turned to 'none' for
+      // example, in this "fun" case just do nothing if the element is hidden
+      if (self._isVisibleElement(gFocusManager.focusedElement))
+        sendAsyncMessage("FormAssist:Show", self._getJSON());
+    });
+    return this._currentElement;
   },
 
-  _open: false,
   open: function formHelperOpen(aElement, aEvent) {
+    this._enabled = Services.prefs.prefHasUserValue(kPrefFormHelperEnabled) ?
+                    Services.prefs.getBoolPref(kPrefFormHelperEnabled) : false;
+
     // If the click is on an option element we want to check if the parent
     // is a valid target.
     if (aElement instanceof HTMLOptionElement &&
         aElement.parentNode instanceof HTMLSelectElement &&
         !aElement.disabled) {
       aElement = aElement.parentNode;
     }
 
+    // Don't show the formhelper popup for multi-select boxes, except for touch.
     if (aElement instanceof HTMLSelectElement && aEvent) {
-      // Don't show the formhelper popup for multi-select boxes, except for touch.
       if ((aElement.multiple || aElement.size > 1) &&
           aEvent.mozInputSource != Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH) {
         return false;
       }
       // Don't fire mouse events on selects; see bug 685197.
       aEvent.preventDefault()
       aEvent.stopPropagation()
     }
@@ -128,131 +121,86 @@ FormAssistant.prototype = {
     // * outside of the scope of the form helper
     // * hover a button of type=[image|submit]
     // * hover a disabled element
     if (!this._isValidElement(aElement)) {
       let passiveButtons = { button: true, checkbox: true, file: true, radio: true, reset: true };
       if ((aElement instanceof HTMLInputElement || aElement instanceof HTMLButtonElement) &&
           passiveButtons[aElement.type] && !aElement.disabled)
         return false;
-
-      // Check for plugins element
-      if (aElement instanceof Ci.nsIDOMHTMLEmbedElement) {
-        let x = (aEvent && aEvent.clientX) || 0;
-        let y = (aEvent && aEvent.clientY) || 0;
-        this._executeDelayed(function(self) {
-          let utils = Util.getWindowUtils(aElement.ownerDocument.defaultView);
-          if (utils.IMEStatus == utils.IME_STATUS_PLUGIN) {
-            let jsvar = {
-              current: {
-                id: aElement.id,
-                name: aElement.name,
-                title: "plugin",
-                value: null,
-                maxLength: 0,
-                type: (aElement.getAttribute("type") || "").toLowerCase(),
-                choices: null,
-                isAutocomplete: false,
-                validationMessage: null,
-                list: null,
-                rect: getBoundingContentRect(aElement),
-                caretRect: new Rect(x, y, 1, 10),
-                editable: true
-              },
-              hasPrevious: false,
-              hasNext: false
-            };
-            sendAsyncMessage("FormAssist:Show", jsvar);
-          }
-        });
-        return false;
-      }
       return this.close();
     }
 
     // Look for a top editable element
-    if (this._isEditable(aElement))
+    if (this._isEditable(aElement)) {
       aElement = this._getTopLevelEditable(aElement);
+    }
 
-    // There are some cases where we still want data to be sent to FormHelperUI
-    // even if form assistant is disabled:
-    //  - the element is a choice list
-    //  - the element has autocomplete suggestions
-    this._enabled = Services.prefs.prefHasUserValue(kPrefFormHelperEnabled) ?
-                    Services.prefs.getBoolPref(kPrefFormHelperEnabled) : false;
-    if (!this._enabled && !this._isSelectElement(aElement) && !this._isAutocomplete(aElement)) {
+    // We only work with choice lists or elements with autocomplete suggestions
+    if (!this._enabled &&
+        !this._isSelectElement(aElement) &&
+        !this._isAutocomplete(aElement)) {
       return this.close();
     }
 
-    if (this._enabled) {
-      this._elements = [];
-      this.currentIndex = this._getAllElements(aElement);
-    } else {
-      this._elements = [aElement];
-      this.currentIndex = 0;
-    }
-
+    // Enable the assistant
+    this.currentElement = aElement;
     return this._open = true;
   },
 
   close: function close() {
     if (this._open) {
-      this._currentIndex = -1;
-      this._elements = [];
+      this._currentElement = null;
       sendAsyncMessage("FormAssist:Hide", { });
       this._open = false;
     }
 
     return this._open;
   },
 
   receiveMessage: function receiveMessage(aMessage) {
     if (this._debugEvents) Util.dumpLn(aMessage.name);
+
     let currentElement = this.currentElement;
-    if ((!this._enabled && !this._isAutocomplete(currentElement) && !getWrapperForElement(currentElement)) || !currentElement)
+    if ((!this._enabled &&
+         !this._isAutocomplete(currentElement) &&
+         !getWrapperForElement(currentElement)) ||
+        !currentElement) {
       return;
+    }
 
     let json = aMessage.json;
+
     switch (aMessage.name) {
-      case "FormAssist:Previous":
-        this.currentIndex--;
-        break;
-
-      case "FormAssist:Next":
-        this.currentIndex++;
-        break;
-
       case "Content:SetWindowSize":
         // If the CSS viewport change just show the current element to the new
         // position
         sendAsyncMessage("FormAssist:Resize", this._getJSON());
         break;
 
       case "FormAssist:ChoiceSelect": {
         this._selectWrapper = getWrapperForElement(currentElement);
         this._selectWrapper.select(json.index, json.selected);
         break;
       }
 
       case "FormAssist:ChoiceChange": {
-        // ChoiceChange could happened once we have move to an other element or
-        // to nothing, so we should keep the used wrapper in mind
+        // ChoiceChange could happened once we have move to another element or
+        // to nothing, so we should keep the used wrapper in mind.
         this._selectWrapper.fireOnChange();
 
         // New elements can be shown when a select is updated so we need to
         // reconstruct the inner elements array and to take care of possible
         // focus change, this is why we use "self.currentElement" instead of 
         // using directly "currentElement".
         this._executeDelayed(function(self) {
           let currentElement = self.currentElement;
           if (!currentElement)
             return;
-
-          self._elements = [];
-          self._currentIndex = self._getAllElements(currentElement);
+          self._currentElement = currentElement;
         });
         break;
       }
 
       case "FormAssist:AutoComplete": {
         try {
           currentElement = currentElement.QueryInterface(Ci.nsIDOMNSEditableElement);
           let imeEditor = currentElement.editor.QueryInterface(Ci.nsIEditorIMESupport);
@@ -266,37 +214,34 @@ FormAssistant.prototype = {
         let event = currentElement.ownerDocument.createEvent("Events");
         event.initEvent("DOMAutoComplete", true, true);
         currentElement.dispatchEvent(event);
         break;
       }
 
       case "FormAssist:Closed":
         currentElement.blur();
-        this._currentIndex = null;
         this._open = false;
         break;
     }
   },
 
-  _els: Cc["@mozilla.org/eventlistenerservice;1"].getService(Ci.nsIEventListenerService),
   _hasKeyListener: function _hasKeyListener(aElement) {
     let els = this._els;
     let listeners = els.getListenerInfoFor(aElement, {});
     for (let i = 0; i < listeners.length; i++) {
       let listener = listeners[i];
       if (["keyup", "keydown", "keypress"].indexOf(listener.type) != -1
           && !listener.inSystemEventGroup) {
         return true;
       }
     }
     return false;
   },
 
-  focusSync: false,
   handleEvent: function formHelperHandleEvent(aEvent) {
     if (this._debugEvents) Util.dumpLn(aEvent.type, this.currentElement);
     // focus changes should be taken into account only if the user has done a
     // manual operation like manually clicking
     let shouldIgnoreFocus = (aEvent.type == "focus" && !this._open && !this.focusSync);
     if ((!this._open && aEvent.type != "focus") || shouldIgnoreFocus) {
       return;
     }
@@ -313,17 +258,19 @@ FormAssistant.prototype = {
         // When reacting to a page show/hide, if the focus is different this
         // could mean the web page has dramatically changed because of
         // an Ajax change based on fragment identifier
         if (gFocusManager.focusedElement != currentElement)
           this.close();
         break;
 
       case "focus":
-        let focusedElement = gFocusManager.getFocusedElementForWindow(content, true, {}) || aEvent.target;
+        let focusedElement =
+          gFocusManager.getFocusedElementForWindow(content, true, {}) ||
+          aEvent.target;
 
         // If a body element is editable and the body is the child of an
         // iframe we can assume this is an advanced HTML editor, so let's
         // redirect the form helper selection to the iframe element
         if (focusedElement && this._isEditable(focusedElement)) {
           let editableElement = this._getTopLevelEditable(focusedElement);
           if (this._isValidElement(editableElement)) {
             this._executeDelayed(function(self) {
@@ -339,19 +286,18 @@ FormAssistant.prototype = {
           if (focusedElement && this._isValidElement(focusedElement)) {
             this._executeDelayed(function(self) {
               self.open(focusedElement);
             });
           }
           return;
         }
 
-        let focusedIndex = this._getIndexForElement(focusedElement);
-        if (focusedIndex != -1 && this.currentIndex != focusedIndex)
-          this.currentIndex = focusedIndex;
+        if (this._currentElement != focusedElement)
+          this.currentElement = focusedElement;
         break;
 
       case "blur":
         content.setTimeout(function(self) {
           if (!self._open)
             return;
 
           // If the blurring causes focus be in no other element,
@@ -365,148 +311,52 @@ FormAssistant.prototype = {
       case "text":
         if (this._isValidatable(aEvent.target))
           sendAsyncMessage("FormAssist:ValidationMessage", this._getJSON());
 
         if (this._isAutocomplete(aEvent.target))
           sendAsyncMessage("FormAssist:AutoComplete", this._getJSON());
         break;
 
-      // key processing inside a select element are done during the keypress
-      // handler, preventing this one to be fired cancel the selection change
-      case "keypress":
-        // There is no need to handle keys if there is not element currently
-        // used by the form assistant
-        if (!currentElement)
-          return;
-
-        let formExceptions = { button: true, checkbox: true, file: true, image: true, radio: true, reset: true, submit: true };
-        if (this._isSelectElement(currentElement) || formExceptions[currentElement.type] ||
-            currentElement instanceof HTMLButtonElement || (currentElement.getAttribute("role") == "button" && currentElement.hasAttribute("tabindex"))) {
-          switch (aEvent.keyCode) {
-            case aEvent.DOM_VK_RIGHT:
-              this._executeDelayed(function(self) {
-                self.currentIndex++;
-              });
-              aEvent.stopPropagation();
-              aEvent.preventDefault();
-              break;
-
-            case aEvent.DOM_VK_LEFT:
-              this._executeDelayed(function(self) {
-                self.currentIndex--;
-              });
-              aEvent.stopPropagation();
-              aEvent.preventDefault();
-              break;
-          }
-        }
-        break;
-
       case "keyup":
         // There is no need to handle keys if there is not element currently
         // used by the form assistant
         if (!currentElement)
           return;
 
-        switch (aEvent.keyCode) {
-          case aEvent.DOM_VK_DOWN:
-            if (currentElement instanceof HTMLInputElement && !this._isAutocomplete(currentElement)) {
-              if (this._hasKeyListener(currentElement))
-                return;
-            } else if (currentElement instanceof HTMLTextAreaElement) {
-              let existSelection = currentElement.selectionEnd - currentElement.selectionStart;
-              let isEnd = (currentElement.textLength == currentElement.selectionEnd);
-              if (!isEnd || existSelection)
-                return;
-            } else if (getListForElement(currentElement)) {
-              this.currentIndex = this.currentIndex;
-              return;
-            }
-
-            this.currentIndex++;
-            break;
+        if (this._isValidatable(aEvent.target)) {
+          sendAsyncMessage("FormAssist:ValidationMessage", this._getJSON());
+        }
 
-          case aEvent.DOM_VK_UP:
-            if (currentElement instanceof HTMLInputElement && !this._isAutocomplete(currentElement)) {
-              if (this._hasKeyListener(currentElement))
-                return;
-            } else if (currentElement instanceof HTMLTextAreaElement) {
-              let existSelection = currentElement.selectionEnd - currentElement.selectionStart;
-              let isStart = (currentElement.selectionEnd == 0);
-              if (!isStart || existSelection)
-                return;
-            } else if (this._isSelectElement(currentElement)) {
-              this.currentIndex = this.currentIndex;
-              return;
-            }
-
-            this.currentIndex--;
-            break;
-
-          case aEvent.DOM_VK_RETURN:
-            if (!this._isVisibleElement(currentElement))
-              this.close();
-            break;
-
-          case aEvent.DOM_VK_ESCAPE:
-          case aEvent.DOM_VK_TAB:
-            break;
-
-          default:
-            if (this._isValidatable(aEvent.target)) {
-              sendAsyncMessage("FormAssist:ValidationMessage", this._getJSON());
-            }
-
-            if (this._isAutocomplete(aEvent.target)) {
-              sendAsyncMessage("FormAssist:AutoComplete", this._getJSON());
-            } else if (currentElement && this._isSelectElement(currentElement)) {
-              this.currentIndex = this.currentIndex;
-            }
-            break;
+        if (this._isAutocomplete(aEvent.target)) {
+          sendAsyncMessage("FormAssist:AutoComplete", this._getJSON());
         }
 
         let caretRect = this._getCaretRect();
         if (!caretRect.isEmpty())
           sendAsyncMessage("FormAssist:Update", { caretRect: caretRect });
     }
   },
 
   _executeDelayed: function formHelperExecuteSoon(aCallback) {
     let self = this;
     let timer = new Util.Timeout(function() {
       aCallback(self);
     });
     timer.once(0);
   },
 
-  _filterEditables: function formHelperFilterEditables(aNodes) {
-    let result = [];
-    for (let i = 0; i < aNodes.length; i++) {
-      let node = aNodes[i];
-
-      // Avoid checking the top level editable element of each node
-      if (this._isEditable(node)) {
-        let editableElement = this._getTopLevelEditable(node);
-        if (result.indexOf(editableElement) == -1)
-          result.push(editableElement);
-      }
-      else {
-        result.push(node);
-      }
-    }
-    return result;
-  },
-
   _isEditable: function formHelperIsEditable(aElement) {
     let canEdit = false;
 
     if (aElement.isContentEditable || aElement.designMode == "on") {
       canEdit = true;
-    } else if (aElement instanceof HTMLIFrameElement && (aElement.contentDocument.body.isContentEditable || aElement.contentDocument.designMode == "on")) {
+    } else if (aElement instanceof HTMLIFrameElement &&
+               (aElement.contentDocument.body.isContentEditable ||
+                aElement.contentDocument.designMode == "on")) {
       canEdit = true;
     } else {
       canEdit = aElement.ownerDocument && aElement.ownerDocument.designMode == "on";
     }
 
     return canEdit;
   },
 
@@ -689,67 +539,16 @@ FormAssistant.prototype = {
           title: label.textContent
         });
       }
     }
 
     return associatedLabels;
   },
 
-  _getAllElements: function getAllElements(aElement) {
-    // XXX good candidate for tracing if possible.
-    // The tough ones are lenght and isVisibleElement.
-    let document = aElement.ownerDocument;
-    if (!document)
-      return;
-
-    let documents = Util.getAllDocuments(document);
-
-    let elements = this._elements;
-    for (let i = 0; i < documents.length; i++) {
-      let selector = "input, button, select, textarea, [role=button], iframe, [contenteditable=true]";
-      let nodes = documents[i].querySelectorAll(selector);
-      nodes = this._filterRadioButtons(nodes);
-
-      for (let j = 0; j < nodes.length; j++) {
-        let node = nodes[j];
-        if (!this._isNavigableElement(node) || !this._isVisibleElement(node))
-          continue;
-
-        elements.push(node);
-      }
-    }
-    this._elements = this._filterEditables(elements);
-
-    function orderByTabIndex(a, b) {
-      // for an explanation on tabbing navigation see
-      // http://www.w3.org/TR/html401/interact/forms.html#h-17.11.1
-      // In resume tab index navigation order is 1, 2, 3, ..., 32767, 0
-      if (a.tabIndex == 0 || b.tabIndex == 0)
-        return b.tabIndex;
-
-      return a.tabIndex > b.tabIndex;
-    }
-    this._elements = this._elements.sort(orderByTabIndex);
-
-    // retrieve the correct index
-    let currentIndex = this._getIndexForElement(aElement);
-    return currentIndex;
-  },
-
-  _getIndexForElement: function(aElement) {
-    let currentIndex = -1;
-    let elements = this._elements;
-    for (let i = 0; i < elements.length; i++) {
-      if (elements[i] == aElement)
-        return i;
-    }
-    return -1;
-  },
-
   _getJSON: function() {
     let element = this.currentElement;
     let choices = getListForElement(element);
     let editable = (element instanceof HTMLInputElement && element.mozIsTextField(false)) || this._isEditable(element);
 
     let labels = this._getLabels();
     return {
       current: {
@@ -762,18 +561,18 @@ FormAssistant.prototype = {
         choices: choices,
         isAutocomplete: this._isAutocomplete(element),
         validationMessage: this.invalidSubmit ? element.validationMessage : null,
         list: this._getListSuggestions(element),
         rect: this._getRect(),
         caretRect: this._getCaretRect(),
         editable: editable
       },
-      hasPrevious: !!this._elements[this._currentIndex - 1],
-      hasNext: !!this._elements[this._currentIndex + 1]
+      hasPrevious: false,
+      hasNext: false
     };
   },
 
   /**
    * For each radio button group, remove all but the checked button
    * if there is one, or the first button otherwise.
    */
   _filterRadioButtons: function(aNodes) {
--- a/browser/metro/base/tests/Makefile.in
+++ b/browser/metro/base/tests/Makefile.in
@@ -10,16 +10,18 @@ relativesrcdir  = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 BROWSER_TESTS = \
   head.js \
   browser_test.js \
   browser_canonizeURL.js \
   browser_context_ui.js \
+  browser_tiles.js \
+  browser_tilegrid.xul \
   browser_onscreen_keyboard.js \
   browser_onscreen_keyboard.html \
   browser_remotetabs.js \
   browser_downloads.js \
   browser_plugin_input.html \
   browser_plugin_input_mouse.js \
   browser_plugin_input_keyboard.js \
   browser_context_menu_tests.js \
new file mode 100644
--- /dev/null
+++ b/browser/metro/base/tests/browser_tilegrid.xul
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<?xml-stylesheet href="chrome://browser/skin/platform.css" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/skin/browser.css" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/content/browser.css" type="text/css"?>
+
+<!DOCTYPE window []>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <vbox flex="1">
+    <hbox>
+      <richgrid id="grid1" seltype="single" flex="1">
+        <richgriditem value="about:blank" id="grid1_item1" label="First item"/>
+      </richgrid>
+    </hbox>
+    <hbox>
+      <richgrid id="emptygrid" seltype="single" flex="1"/>
+    </hbox>
+    <hbox>
+      <richgrid id="grid2" seltype="single" flex="1">
+        <richgriditem value="about:blank" id="grid2_item1" label="First item"/>
+        <richgriditem value="about:blank" id="grid2_item2" label="2nd item"/>
+      </richgrid>
+    </hbox>
+    <hbox>
+      <richgrid id="grid3" seltype="single" flex="1">
+        <richgriditem value="about:blank" id="grid3_item1" label="First item"/>
+        <richgriditem value="about:blank" id="grid3_item2" label="2nd item"/>
+      </richgrid>
+    </hbox>
+    <hbox>
+      <richgrid id="grid4" seltype="single" flex="1">
+        <richgriditem value="about:blank" id="grid4_item1" label="First item"/>
+        <richgriditem value="about:blank" id="grid4_item2" label="2nd item"/>
+      </richgrid>
+    </hbox>
+    <hbox>
+      <richgrid id="grid-select1" seltype="single" flex="1">
+        <richgriditem value="about:blank" id="grid-select1_item1" label="First item"/>
+        <richgriditem value="about:blank" id="grid-select1_item2" label="2nd item"/>
+      </richgrid>
+    </hbox>
+    <hbox>
+      <richgrid id="grid-select2" seltype="multiple" flex="1">
+        <richgriditem value="about:blank" id="grid-select2_item1" label="First item"/>
+        <richgriditem value="about:blank" id="grid-select2_item2" label="2nd item"/>
+      </richgrid>
+    </hbox>
+  </vbox>
+</window>
+
new file mode 100644
--- /dev/null
+++ b/browser/metro/base/tests/browser_tiles.js
@@ -0,0 +1,294 @@
+let doc, win;
+
+function test() {
+  waitForExplicitFinish();
+  Task.spawn(function(){
+    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+
+    info(chromeRoot + "browser_tilegrid.xul");
+    yield addTab(chromeRoot + "browser_tilegrid.xul");
+    doc = Browser.selectedTab.browser.contentWindow.document;
+  }).then(runTests);
+}
+
+gTests.push({
+  desc: "richgrid binding is applied",
+  run: function() {
+    ok(doc, "doc got defined");
+
+    let grid = doc.querySelector("#grid1");
+    ok(grid, "#grid1 is found");
+    is(typeof grid.clearSelection, "function", "#grid1 has the binding applied");
+
+    is(grid.children.length, 1, "#grid1 has a single item");
+    is(grid.children[0].control, grid, "#grid1 item's control points back at #grid1'");
+  }
+});
+
+gTests.push({
+  desc: "item clicks are handled",
+  run: function() {
+    let grid = doc.querySelector("#grid1");
+    is(typeof grid.handleItemClick, "function", "grid.handleItemClick is a function");
+    let handleStub = stubMethod(grid, 'handleItemClick');
+    let itemId = "grid1_item1"; // grid.children[0].getAttribute("id");
+
+    // send click to item and wait for next tick;
+    EventUtils.sendMouseEvent({type: 'click'}, itemId, doc.defaultView);
+    yield waitForMs(0);
+
+    is(handleStub.callCount, 1, "handleItemClick was called when we clicked an item");
+    handleStub.restore();
+
+    // if the grid has a controller, it should be called too
+    let gridController = {
+      handleItemClick: function() {}
+    };
+    let controllerHandleStub = stubMethod(gridController, "handleItemClick");
+    let origController = grid.controller;
+    grid.controller = gridController;
+
+    // send click to item and wait for next tick;
+    EventUtils.sendMouseEvent({type: 'click'}, itemId, doc.defaultView);
+    yield waitForMs(0);
+
+    is(controllerHandleStub.callCount, 1, "controller.handleItemClick was called when we clicked an item");
+    is(controllerHandleStub.calledWith[0], doc.getElementById(itemId), "controller.handleItemClick was passed the grid item");
+    grid.controller = origController;
+  }
+});
+
+gTests.push({
+  desc: "arrangeItems",
+  run: function() {
+     // implements an arrangeItems method, with optional cols, rows signature
+    let grid = doc.querySelector("#grid1");
+    is(typeof grid.arrangeItems, "function", "arrangeItems is a function on the grid");
+    todo(false, "Test outcome of arrangeItems with cols and rows arguments");
+  }
+});
+
+gTests.push({
+  desc: "appendItem",
+  run: function() {
+     // implements an appendItem with signature title, uri, returns item element
+     // appendItem triggers arrangeItems
+    let grid = doc.querySelector("#emptygrid");
+
+    is(grid.itemCount, 0, "0 itemCount when empty");
+    is(grid.children.length, 0, "0 children when empty");
+    is(typeof grid.appendItem, "function", "appendItem is a function on the grid");
+
+    let arrangeStub = stubMethod(grid, "arrangeItems");
+    let newItem = grid.appendItem("test title", "about:blank");
+
+    ok(newItem && grid.children[0]==newItem, "appendItem gives back the item");
+    is(grid.itemCount, 1, "itemCount is incremented when we appendItem");
+    is(newItem.getAttribute("label"), "test title", "title ends up on label attribute");
+    is(newItem.getAttribute("value"), "about:blank", "url ends up on value attribute");
+
+    is(arrangeStub.callCount, 1, "arrangeItems is called when we appendItem");
+    arrangeStub.restore();
+  }
+});
+
+gTests.push({
+  desc: "getItemAtIndex",
+  run: function() {
+     // implements a getItemAtIndex method
+    let grid = doc.querySelector("#grid2");
+    is(typeof grid.getItemAtIndex, "function", "getItemAtIndex is a function on the grid");
+    is(grid.getItemAtIndex(0).getAttribute("id"), "grid2_item1", "getItemAtIndex retrieves the first item");
+    is(grid.getItemAtIndex(1).getAttribute("id"), "grid2_item2", "getItemAtIndex item at index 2");
+    ok(!grid.getItemAtIndex(5), "getItemAtIndex out-of-bounds index returns falsy");
+  }
+});
+
+gTests.push({
+  desc: "removeItemAt",
+  run: function() {
+     // implements a removeItemAt method, with 'index' signature
+     // removeItemAt triggers arrangeItems
+    let grid = doc.querySelector("#grid2");
+
+    is(grid.itemCount, 2, "2 items initially");
+    is(typeof grid.removeItemAt, "function", "removeItemAt is a function on the grid");
+
+    let arrangeStub = stubMethod(grid, "arrangeItems");
+    let removedItem = grid.removeItemAt(0);
+
+    ok(removedItem, "removeItemAt gives back an item");
+    is(removedItem.getAttribute("id"), "grid2_item1", "removeItemAt gives back the correct item");
+    is(grid.children[0].getAttribute("id"), "grid2_item2", "2nd item becomes the first item");
+    is(grid.itemCount, 1, "itemCount is decremented when we removeItemAt");
+
+    is(arrangeStub.callCount, 1, "arrangeItems is called when we removeItemAt");
+    arrangeStub.restore();
+  }
+});
+
+gTests.push({
+  desc: "insertItemAt",
+  run: function() {
+     // implements an insertItemAt method, with index, title, uri.spec signature
+     // insertItemAt triggers arrangeItems
+    let grid = doc.querySelector("#grid3");
+
+    is(grid.itemCount, 2, "2 items initially");
+    is(typeof grid.insertItemAt, "function", "insertItemAt is a function on the grid");
+
+    let arrangeStub = stubMethod(grid, "arrangeItems");
+    let insertedItem = grid.insertItemAt(1, "inserted item", "http://example.com/inserted");
+
+    ok(insertedItem, "insertItemAt gives back an item");
+    is(grid.children[1], insertedItem, "item is inserted at the correct index");
+    is(insertedItem.getAttribute("label"), "inserted item", "insertItemAt creates item with the correct label");
+    is(insertedItem.getAttribute("value"), "http://example.com/inserted", "insertItemAt creates item with the correct url value");
+    is(grid.children[2].getAttribute("id"), "grid3_item2", "following item ends up at the correct index");
+    is(grid.itemCount, 3, "itemCount is incremented when we insertItemAt");
+
+    is(arrangeStub.callCount, 1, "arrangeItems is called when we insertItemAt");
+    arrangeStub.restore();
+  }
+});
+
+gTests.push({
+  desc: "getIndexOfItem",
+  run: function() {
+     // implements a getIndexOfItem method, with item (element) signature
+     // insertItemAt triggers arrangeItems
+    let grid = doc.querySelector("#grid4");
+
+    is(grid.itemCount, 2, "2 items initially");
+    is(typeof grid.getIndexOfItem, "function", "getIndexOfItem is a function on the grid");
+
+    let item = doc.getElementById("grid4_item2");
+    let badItem = doc.createElement("richgriditem");
+
+    is(grid.getIndexOfItem(item), 1, "getIndexOfItem returns the correct value for an item");
+    is(grid.getIndexOfItem(badItem), -1, "getIndexOfItem returns -1 for items it doesn't contain");
+  }
+});
+
+gTests.push({
+  desc: "selections (single)",
+  run: function() {
+     // when seltype is single,
+     //      maintains a selectedItem property
+     //      maintains a selectedIndex property
+     //     clearSelection, selectItem, toggleItemSelection methods are implemented
+     //     'select' events are implemented
+    let grid = doc.querySelector("#grid-select1");
+
+    is(typeof grid.clearSelection, "function", "clearSelection is a function on the grid");
+    is(typeof grid.selectedItems, "object", "selectedItems is a property on the grid");
+    is(typeof grid.toggleItemSelection, "function", "toggleItemSelection is function on the grid");
+    is(typeof grid.selectItem, "function", "selectItem is a function on the grid");
+
+    is(grid.itemCount, 2, "2 items initially");
+    is(grid.selectedItems.length, 0, "nothing selected initially");
+
+    grid.toggleItemSelection(grid.children[1]);
+    ok(grid.children[1].selected, "toggleItemSelection sets truthy selected prop on previously-unselected item");
+    is(grid.selectedIndex, 1, "selectedIndex is correct");
+
+    grid.toggleItemSelection(grid.children[1]);
+    is(grid.selectedIndex, -1, "selectedIndex reports correctly with nothing selected");
+
+    // item selection
+    grid.selectItem(grid.children[1]);
+    ok(grid.children[1].selected, "Item selected property is truthy after grid.selectItem");
+    ok(grid.children[1].getAttribute("selected"), "Item selected attribute is truthy after grid.selectItem");
+    ok(grid.selectedItems.length, "There are selectedItems after grid.selectItem");
+
+    // clearSelection
+    grid.selectItem(grid.children[0]);
+    grid.selectItem(grid.children[1]);
+    grid.clearSelection();
+    is(grid.selectedItems.length, 0, "Nothing selected when we clearSelection");
+    is(grid.selectedIndex, -1, "selectedIndex resets after clearSelection");
+
+    // select events
+    // in seltype=single mode, select is like the default action for the tile
+    // (think <a>, not <select multiple>)
+    let handler = {
+      handleEvent: function(aEvent) {}
+    };
+    let handlerStub = stubMethod(handler, "handleEvent");
+    doc.defaultView.addEventListener("select", handler, false);
+    info("select listener added");
+
+    info("calling selectItem, currently it is:" + grid.children[0].selected);
+    // Note: A richgrid in seltype=single mode fires "select" events from selectItem
+    grid.selectItem(grid.children[0]);
+    info("/calling selectItem, now it is:" + grid.children[0].selected);
+    yield waitForMs(0);
+
+    is(handlerStub.callCount, 1, "select event handler was called when we selected an item");
+    is(handlerStub.calledWith[0].type, "select", "handler got a select event");
+    is(handlerStub.calledWith[0].target, grid, "select event had the originating grid as the target");
+    handlerStub.restore();
+    doc.defaultView.removeEventListener("select", handler, false);
+  }
+});
+
+gTests.push({
+  desc: "selections (multiple)",
+  run: function() {
+     // when seltype is multiple,
+     //      maintains a selectedItems property
+     //      clearSelection, selectItem, toggleItemSelection methods are implemented
+     //     'selectionchange' events are implemented
+    let grid = doc.querySelector("#grid-select2");
+
+    is(typeof grid.clearSelection, "function", "clearSelection is a function on the grid");
+    is(typeof grid.selectedItems, "object", "selectedItems is a property on the grid");
+    is(typeof grid.toggleItemSelection, "function", "toggleItemSelection is function on the grid");
+    is(typeof grid.selectItem, "function", "selectItem is a function on the grid");
+
+    is(grid.itemCount, 2, "2 items initially");
+    is(grid.selectedItems.length, 0, "nothing selected initially");
+
+    grid.toggleItemSelection(grid.children[1]);
+    ok(grid.children[1].selected, "toggleItemSelection sets truthy selected prop on previously-unselected item");
+    is(grid.selectedItems.length, 1, "1 item selected when we first toggleItemSelection");
+    is(grid.selectedItems[0], grid.children[1], "the right item is selected");
+    is(grid.selectedIndex, 1, "selectedIndex is correct");
+
+    grid.toggleItemSelection(grid.children[1]);
+    is(grid.selectedItems.length, 0, "Nothing selected when we toggleItemSelection again");
+
+    // clearSelection
+    grid.children[0].selected=true;
+    grid.children[1].selected=true;
+    is(grid.selectedItems.length, 2, "Both items are selected before calling clearSelection");
+    grid.clearSelection();
+    is(grid.selectedItems.length, 0, "Nothing selected when we clearSelection");
+    ok(!(grid.children[0].selected || grid.children[1].selected), "selected properties all falsy when we clearSelection");
+
+    // selectionchange events
+    // in seltype=multiple mode, we track selected state on all items
+    // (think <select multiple> not <a>)
+    let handler = {
+      handleEvent: function(aEvent) {}
+    };
+    let handlerStub = stubMethod(handler, "handleEvent");
+    doc.defaultView.addEventListener("selectionchange", handler, false);
+    info("selectionchange listener added");
+
+    info("calling toggleItemSelection, currently it is:" + grid.children[0].selected);
+    // Note: A richgrid in seltype=single mode fires "select" events from selectItem
+    grid.toggleItemSelection(grid.children[0]);
+    info("/calling toggleItemSelection, now it is:" + grid.children[0].selected);
+    yield waitForMs(0);
+
+    is(handlerStub.callCount, 1, "selectionchange event handler was called when we selected an item");
+    is(handlerStub.calledWith[0].type, "selectionchange", "handler got a selectionchange event");
+    is(handlerStub.calledWith[0].target, grid, "select event had the originating grid as the target");
+    handlerStub.restore();
+    doc.defaultView.removeEventListener("selectionchange", handler, false);
+  }
+});
+
+     // implements a getItemAtIndex method (or grid.children[idx] ?)
+
--- a/browser/metro/base/tests/head.js
+++ b/browser/metro/base/tests/head.js
@@ -419,8 +419,22 @@ function runTests() {
       if ('function' == typeof gCurrentTest.tearDown) {
         yield Task.spawn(gCurrentTest.tearDown.bind(gCurrentTest));
       }
       info("END "+gCurrentTest.desc);
     }
     finish();
   });
 }
+
+function stubMethod(aObj, aMethod) {
+  let origFunc = aObj[aMethod];
+  let func = function() {
+    func.calledWith = Array.slice(arguments);
+    func.callCount++;
+  }
+  func.callCount = 0;
+  func.restore = function() {
+    return (aObj[aMethod] = origFunc);
+  };
+  aObj[aMethod] = func;
+  return func;
+}
\ No newline at end of file
--- a/browser/metro/shell/commandexecutehandler/CEHHelper.cpp
+++ b/browser/metro/shell/commandexecutehandler/CEHHelper.cpp
@@ -45,17 +45,17 @@ Log(const wchar_t *fmt, ...)
 
 #if defined(SHOW_CONSOLE)
 void
 SetupConsole()
 {
   FILE *fp;
   AllocConsole();
   sCon = GetStdHandle(STD_OUTPUT_HANDLE); 
-  int fd = _open_osfhandle(reinterpret_cast<long>(sCon), 0); 
+  int fd = _open_osfhandle(reinterpret_cast<intptr_t>(sCon), 0);
   fp = _fdopen(fd, "w");
   *stdout = *fp;
   setvbuf(stdout, NULL, _IONBF, 0);
 }
 #endif
 
 bool
 IsDX10Available()
deleted file mode 100644
--- a/browser/metro/theme/Makefile.in
+++ /dev/null
@@ -1,12 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH	    = ../../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
--- a/browser/metro/theme/browser.css
+++ b/browser/metro/theme/browser.css
@@ -174,16 +174,20 @@ documenttab[selected=true] .documenttab-
   background: none !important;
   padding: @metro_spacing_small@ !important;
   margin-top: @metro_spacing_snormal@;
   -moz-margin-end: @metro_spacing_xsmall@;
   border-color: transparent !important;
   list-style-image: url("chrome://browser/skin/images/closetab-default.png");
 }
 
+.documenttab-close > .button-box > .button-text {
+  display: none;
+}
+
 #tray[tabsonly=true] {
   transform: none !important;
 }
 
 #tray[tabsonly=true] #tabs {
   -moz-padding-start: @metro_spacing_small@;
 }
 
--- a/browser/modules/RecentWindow.jsm
+++ b/browser/modules/RecentWindow.jsm
@@ -15,28 +15,31 @@ Cu.import("resource://gre/modules/Privat
 #define BROKEN_WM_Z_ORDER
 #endif
 
 this.RecentWindow = {
   /*
    * Get the most recent browser window.
    *
    * @param aOptions an object accepting the arguments for the search.
-   *        Set the private property to true in order to restrict the
-   *        search to private windows only, or to false in order to
-   *        restrict the search to non-private windows only.  To search
-   *        in both groups, don't specify the private property.
+   *        * private: true to restrict the search to private windows
+   *            only, false to restrict the search to non-private only.
+   *            Omit the property to search in both groups.
+   *        * allowPopups: true if popup windows are permissable.
    */
   getMostRecentBrowserWindow: function RW_getMostRecentBrowserWindow(aOptions) {
     let checkPrivacy = typeof aOptions == "object" &&
                        "private" in aOptions;
 
+    let allowPopups = typeof aOptions == "object" && !!aOptions.allowPopups;
+
     function isSuitableBrowserWindow(win) {
       return (!win.closed &&
               win.toolbar.visible &&
+              (allowPopups || win.toolbar.visible) &&
               (!checkPrivacy ||
                PrivateBrowsingUtils.permanentPrivateBrowsing ||
                PrivateBrowsingUtils.isWindowPrivate(win) == aOptions.private));
     }
 
 #ifdef BROKEN_WM_Z_ORDER
     let win = Services.wm.getMostRecentWindow("navigator:browser");
 
deleted file mode 100644
--- a/browser/themes/Makefile.in
+++ /dev/null
@@ -1,12 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -1171,16 +1171,20 @@ toolbar[iconsize="small"] #webrtc-status
   width: 32px;
   height: 32px;
 }
 
 .popup-notification-icon[popupid="click-to-play-plugins"] {
   list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png);
 }
 
+.popup-notification-icon[popupid="web-notifications"] {
+  list-style-image: url(chrome://browser/skin/notification-64.png);
+}
+
 .addon-progress-description {
   width: 350px;
   max-width: 350px;
 }
 
 .popup-progress-label,
 .popup-progress-meter {
   -moz-margin-start: 0;
@@ -1320,16 +1324,20 @@ toolbar[iconsize="small"] #webrtc-status
 #webRTC-shareDevices-notification-icon {
   list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
 }
 
 #webRTC-sharingDevices-notification-icon {
   list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png);
 }
 
+#web-notifications-notification-icon {
+  list-style-image: url(chrome://browser/skin/notification-16.png);
+}
+
 #treecolAutoCompleteImage {
   max-width : 36px;
 }
 
 .ac-result-type-bookmark,
 .autocomplete-treebody::-moz-tree-image(bookmark, treecolAutoCompleteImage) {
   list-style-image: url("chrome://browser/skin/places/pageStarred.png");
   width: 16px;
deleted file mode 100644
--- a/browser/themes/linux/communicator/Makefile.in
+++ /dev/null
@@ -1,13 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH     = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH     = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
-
--- a/browser/themes/linux/jar.mn
+++ b/browser/themes/linux/jar.mn
@@ -29,16 +29,18 @@ browser.jar:
   skin/classic/browser/identity-icons-https.png
   skin/classic/browser/identity-icons-https-ev.png
   skin/classic/browser/identity-icons-https-mixed-active.png
   skin/classic/browser/Info.png
   skin/classic/browser/mixed-content-blocked-16.png
   skin/classic/browser/mixed-content-blocked-64.png
   skin/classic/browser/monitor.png
   skin/classic/browser/monitor_16-10.png
+  skin/classic/browser/notification-16.png
+  skin/classic/browser/notification-64.png
 * skin/classic/browser/pageInfo.css
   skin/classic/browser/pageInfo.png
   skin/classic/browser/page-livemarks.png
   skin/classic/browser/Privacy-16.png
   skin/classic/browser/Privacy-48.png
   skin/classic/browser/privatebrowsing-mask.png
   skin/classic/browser/searchbar.css
   skin/classic/browser/Secure.png
new file mode 100644
index 0000000000000000000000000000000000000000..6b2df734137b83b58f899252907e52ebde657bd6
GIT binary patch
literal 610
zc$@)Z0-gPdP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00006VoOIv0RI60
z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru+zJB|0tuw22DAVG0q;pf
zK~y-)jgvn})o~QXKi}uep+QTbK>{Cyi%5tCK@AZOg=JVRmf2EDuLuLFrHJSsQbcJz
zl_Hh2!N@d&uqBt4qzIxYnk0l8GNdBHhv&5Xgx{0WzHo<g?)Mz-z1$o4kJo)~bTe=j
zSPhH;t%n<SP6H&C5_b)ZHrYI~$=FocytaATH85HTko=dhvwx%z=(bf4Tt3oR*BhnU
zJNrj|0&PG#{7sy>JG=oH1WF^S{OEyQ@1xwj<~dNGV{oHys03&PYJp7={TpZnI)FSN
z1H3XJ8K59^^gal{c3>Z{2e=jq=G*%QOafIAE&z5o<h{VUl91FU>9M4}lJX_ZNJ>f~
ziULW?Vz@*y?@H??WtSu@9kN6$<}77nIB97rhBKDR04!ybl8P40a4ql#SQq17Mguj_
z^K1F4`^D356SE2=CCvaUVxMb(t_23QK*fplegia*JFNLQSP|?G30qHW5sM;Q30q%d
zT&1m+c$r}?n-&a*wwrxrz{G+oW`VQ7$rwKeoB<w2Rn~k?ZQT|CE_L*zfQ>*gupUrk
zat`<bR7Rp|AO(ymFaOx5@`mp@i*&L5&Te2Rg3nI19IRgKPMXIZa*oN?M6B=Bh3mJA
w7c;oEB{;|6^zo)C%U>*KEw8kEeyMBy12rfguUWen=l}o!07*qoM6N<$f_`}XHvj+t
new file mode 100644
index 0000000000000000000000000000000000000000..a01d0ab7764fd0766d4b38208e7e50ce996aba3a
GIT binary patch
literal 3373
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
Dh&Oq7
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -3141,31 +3141,49 @@ toolbarbutton.chevron > .toolbarbutton-m
   list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png);
 }
 @media (min-resolution: 2dppx) {
   #webRTC-sharingDevices-notification-icon {
     list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16@2x.png);
   }
 }
 
+#web-notifications-notification-icon {
+  list-style-image: url(chrome://browser/skin/notification-16.png);
+}
+@media (min-resolution: 2dppx) {
+  #web-notifications-notification-icon {
+    list-style-image: url(chrome://browser/skin/notification-16@2x.png);
+  }
+}
+
 .popup-notification-icon {
   width: 64px;
   height: 64px;
   -moz-margin-end: 10px;
 }
 
 .popup-notification-icon[popupid="geolocation"] {
   list-style-image: url(chrome://browser/skin/Geolocation-64.png);
 }
 @media (min-resolution: 2dppx) {
   .popup-notification-icon[popupid="geolocation"] {
     list-style-image: url(chrome://browser/skin/Geolocation-64@2x.png);
   }
 }
 
+.popup-notification-icon[popupid="web-notifications"] {
+  list-style-image: url(chrome://browser/skin/notification-64.png);
+}
+@media (min-resolution: 2dppx) {
+  .popup-notification-icon[popupid="web-notifications"] {
+    list-style-image: url(chrome://browser/skin/notification-64@2x.png);
+  }
+}
+
 .popup-notification-icon[popupid="xpinstall-disabled"],
 .popup-notification-icon[popupid="addon-progress"],
 .popup-notification-icon[popupid="addon-install-cancelled"],
 .popup-notification-icon[popupid="addon-install-blocked"],
 .popup-notification-icon[popupid="addon-install-failed"],
 .popup-notification-icon[popupid="addon-install-complete"] {
   list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
   width: 32px;
deleted file mode 100644
--- a/browser/themes/osx/communicator/Makefile.in
+++ /dev/null
@@ -1,13 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH     = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH     = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
-
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -36,16 +36,20 @@ browser.jar:
   skin/classic/browser/identity-icons-https-ev@2x.png
   skin/classic/browser/identity-icons-https-mixed-active.png
   skin/classic/browser/identity-icons-https-mixed-active@2x.png
   skin/classic/browser/Info.png
   skin/classic/browser/keyhole-circle.png
   skin/classic/browser/KUI-background.png
   skin/classic/browser/menu-back.png
   skin/classic/browser/menu-forward.png
+  skin/classic/browser/notification-16.png
+  skin/classic/browser/notification-16@2x.png
+  skin/classic/browser/notification-64.png
+  skin/classic/browser/notification-64@2x.png
   skin/classic/browser/mixed-content-blocked-16.png
   skin/classic/browser/mixed-content-blocked-16@2x.png
   skin/classic/browser/mixed-content-blocked-64.png
   skin/classic/browser/mixed-content-blocked-64@2x.png
   skin/classic/browser/panel-expander-closed.png
   skin/classic/browser/panel-expander-closed@2x.png
   skin/classic/browser/panel-expander-open.png
   skin/classic/browser/panel-expander-open@2x.png
new file mode 100644
index 0000000000000000000000000000000000000000..6b2df734137b83b58f899252907e52ebde657bd6
GIT binary patch
literal 610
zc$@)Z0-gPdP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00006VoOIv0RI60
z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru+zJB|0tuw22DAVG0q;pf
zK~y-)jgvn})o~QXKi}uep+QTbK>{Cyi%5tCK@AZOg=JVRmf2EDuLuLFrHJSsQbcJz
zl_Hh2!N@d&uqBt4qzIxYnk0l8GNdBHhv&5Xgx{0WzHo<g?)Mz-z1$o4kJo)~bTe=j
zSPhH;t%n<SP6H&C5_b)ZHrYI~$=FocytaATH85HTko=dhvwx%z=(bf4Tt3oR*BhnU
zJNrj|0&PG#{7sy>JG=oH1WF^S{OEyQ@1xwj<~dNGV{oHys03&PYJp7={TpZnI)FSN
z1H3XJ8K59^^gal{c3>Z{2e=jq=G*%QOafIAE&z5o<h{VUl91FU>9M4}lJX_ZNJ>f~
ziULW?Vz@*y?@H??WtSu@9kN6$<}77nIB97rhBKDR04!ybl8P40a4ql#SQq17Mguj_
z^K1F4`^D356SE2=CCvaUVxMb(t_23QK*fplegia*JFNLQSP|?G30qHW5sM;Q30q%d
zT&1m+c$r}?n-&a*wwrxrz{G+oW`VQ7$rwKeoB<w2Rn~k?ZQT|CE_L*zfQ>*gupUrk
zat`<bR7Rp|AO(ymFaOx5@`mp@i*&L5&Te2Rg3nI19IRgKPMXIZa*oN?M6B=Bh3mJA
w7c;oEB{;|6^zo)C%U>*KEw8kEeyMBy12rfguUWen=l}o!07*qoM6N<$f_`}XHvj+t
new file mode 100644
index 0000000000000000000000000000000000000000..21818c847e9a55288e39556fb5f35c7d94c7d18f
GIT binary patch
literal 1262
zc$@+51QGj*P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800006VoOIv0RI60
z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_00fRnL_t(o!>yNVY*bYc$A9<sW?P{W
zutJaow18+@1Rt0fND%RXJOY&x)N~7lCWRKL2~cYQ4TON8kyj}tkV0EZg3?l`V#O#m
zu_mS>$|EEwF-5|&3k4rlpzhxf9ALBAd#|>g&3xE1GiT=f&)k_g7M)0&ch&}gJRlu-
z2sjNK07_<OObo@cu{z6n$<Eroz-K^83~>vPnVT_jf3(2v6z7$-k0ZW9q#&*#<|9%O
zBN6Km35btNDr+-39f3`i`(^`cfdrr#7?Bs8^mCNX5TFjYA9x`zIO*#S2e4_!-tNFw
zU`oXD)V$2J-7fl%0p9}WfgyRBX|3(Pg5rw3BPEVVOp(CwQ8(uRd6{X)Bnl)3NEEay
z2Z}3d;)^S4R)G$J`hkexa{nE)8FU0RuehQn@qY!dv3yUwq((`FlHw#0#b0>XCIHNt
z_DWdNYDq~FnK|{cd~=|vtU3{xZ1SbdMXe3!0u%yE%>S-N76yI=8h~kl16%-(AA4}}
zDBIm}RiLP>Y8L1x(7m8nqacsu3!o=K%R%v=t`V}g=4GWPgRX)m%*#r@3EBr5@#xvQ
z?oPDh4cn{w06~elKwq<b09fV$)K%bh7g;rc#4?~Lr(U0goAw;E(2TgYzn*pg)^FP#
z0A2&;N_r|PH?9C7AjvDcfc`GB%K-T^ri6?i!j^r=4!0o~>Z~jM$dObBjCR@J641>j
zRg!=v7g-<R+AS1h0ff3ee5z;5i5rMyThc5^qhn<CZT?fzbq_g`dP%zAA{%oDCMf{W
z+#@wC>Aa*~4pPwPbUjQn@gfH}=OQayyLDGJ&;{vs^|g?G2i@aHdctS(-oQ<B6}>$4
zT1+qK8N>c0a9Ng}9)X4>tn0R<cprGXNa`=?kdNL7NlRj^UzGGtn;l3wIdJNC5dn0+
zA^W<cTd?@ivp^#-&O>J`kYx}k0Dc4309zK$&S=f4*PWvGz`2Hiq~5Y<awN5yD&|F#
zfTf1rC=r-ekQ-b9ta!hq(kjRe#ynluKhCB~ii@+thi#!Bh3{{i&?TY6K6(q^E7=hb
z5bb=+bC&MH-!?|*pT84&G}uUWMD$b_c951LE%wnHfb^ypl=n3sv8`}83+bD){ay;$
zlFB9B@JTQv&6LzEsn$nt$?D?r(XQWg^U-Wc1H)LQ0CwS=>1QMr{f7W-NgqmDAnBBc
zUO-aKs*Ppiqn#(8s2DDV*GT%IC28<3;8te7TeLj@d<s18lZ>sv_dq_d5qQLu;aF`w
z4D1D}OeucRjO;gMJHwk&g2#co^T5gt+v0%*z<A({>EGu}W0Lu-6w&=IF3O*I#@G!4
zh5^q2F9ZEt4sb=5opyTg^oH9(yAC8PH<a2Y@<f-@ja`(V{ke<nFklog#sqiSwDb=a
z<!6T?YJ&Gfv|@efmo8m$`{FmUXSR2ujx0)^GoeTMt?tNMBC;kpK2vO?i(n|QzcYgH
zL4Zb=nzMNM+N~2i<5}lB6)#`2<-BRBu_*QJ`8g*#5`gc!K&a8&e2d|b&@YAubrgYr
Y0qRP4Zq9cg?EnA(07*qoM6N<$f^HH>M*si-
new file mode 100644
index 0000000000000000000000000000000000000000..a01d0ab7764fd0766d4b38208e7e50ce996aba3a
GIT binary patch
literal 3373
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
Dh&Oq7
new file mode 100644
index 0000000000000000000000000000000000000000..9adb75fbffca924af685b9f14af4a2ef3519b30b
GIT binary patch
literal 7338
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
Qp8x;=07*qoM6N<$f&qT!i~s-t
--- a/browser/themes/osx/searchbar.css
+++ b/browser/themes/osx/searchbar.css
@@ -43,16 +43,21 @@
   -moz-padding-end: 6px;
 }
 
 .search-go-button {
   list-style-image: url("chrome://browser/skin/Search.png");
 }
 
 @media (min-resolution: 2dppx) {
+  .searchbar-engine-image,
+  .searchbar-engine-menuitem > .menu-iconic-left > .menu-iconic-icon {
+    image-rendering: -moz-crisp-edges;
+  }
+
   .searchbar-engine-image {
     list-style-image: url("chrome://mozapps/skin/places/defaultFavicon@2x.png");
   }
 
   .searchbar-dropmarker-image {
     list-style-image: url("chrome://browser/skin/searchbar-dropmarker@2x.png");
     width: 7px;
   }
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -2220,16 +2220,20 @@ toolbarbutton.bookmark-item[dragover="tr
   width: 32px;
   height: 32px;
 }
 
 .popup-notification-icon[popupid="click-to-play-plugins"] {
   list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png);
 }
 
+.popup-notification-icon[popupid="web-notifications"] {
+  list-style-image: url(chrome://browser/skin/notification-64.png);
+}
+
 .addon-progress-description {
   width: 350px;
   max-width: 350px;
 }
 
 .popup-progress-label,
 .popup-progress-meter {
   -moz-margin-start: 0;
@@ -2375,16 +2379,20 @@ toolbarbutton.bookmark-item[dragover="tr
 #webRTC-shareDevices-notification-icon {
   list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
 }
 
 #webRTC-sharingDevices-notification-icon {
   list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png);
 }
 
+#web-notifications-notification-icon {
+  list-style-image: url(chrome://browser/skin/notification-16.png);
+}
+
 #identity-popup-container {
   min-width: 280px;
 }
 
 /* Bookmarks roots menu-items */
 #appmenu_subscribeToPage:not([disabled]),
 #appmenu_subscribeToPageMenu,
 #subscribeToPageMenuitem:not([disabled]),
deleted file mode 100644
--- a/browser/themes/windows/communicator/Makefile.in
+++ /dev/null
@@ -1,13 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH     = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH     = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
-
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -37,16 +37,18 @@ browser.jar:
         skin/classic/browser/KUI-background.png
         skin/classic/browser/livemark-folder.png
         skin/classic/browser/menu-back.png
         skin/classic/browser/menu-forward.png
         skin/classic/browser/mixed-content-blocked-16.png
         skin/classic/browser/mixed-content-blocked-64.png
         skin/classic/browser/monitor.png
         skin/classic/browser/monitor_16-10.png
+        skin/classic/browser/notification-16.png
+        skin/classic/browser/notification-64.png
         skin/classic/browser/pageInfo.css
         skin/classic/browser/pageInfo.png
         skin/classic/browser/page-livemarks.png                      (feeds/feedIcon16.png)
         skin/classic/browser/Privacy-16.png
         skin/classic/browser/Privacy-48.png
         skin/classic/browser/privatebrowsing-light.png
         skin/classic/browser/privatebrowsing-dark.png
         skin/classic/browser/reload-stop-go.png
@@ -268,16 +270,18 @@ browser.jar:
         skin/classic/aero/browser/KUI-background.png
         skin/classic/aero/browser/livemark-folder.png                (livemark-folder-aero.png)
         skin/classic/aero/browser/menu-back.png                      (menu-back-aero.png)
         skin/classic/aero/browser/menu-forward.png                   (menu-forward-aero.png)
         skin/classic/aero/browser/mixed-content-blocked-16.png
         skin/classic/aero/browser/mixed-content-blocked-64.png
         skin/classic/aero/browser/monitor.png
         skin/classic/aero/browser/monitor_16-10.png
+        skin/classic/aero/browser/notification-16.png
+        skin/classic/aero/browser/notification-64.png
         skin/classic/aero/browser/pageInfo.css
         skin/classic/aero/browser/pageInfo.png                       (pageInfo-aero.png)
         skin/classic/aero/browser/page-livemarks.png                 (feeds/feedIcon16-aero.png)
         skin/classic/aero/browser/Privacy-16.png                     (Privacy-16-aero.png)
         skin/classic/aero/browser/Privacy-48.png                     (Privacy-48-aero.png)
         skin/classic/aero/browser/privatebrowsing-light.png
         skin/classic/aero/browser/privatebrowsing-dark.png
         skin/classic/aero/browser/reload-stop-go.png
new file mode 100644
index 0000000000000000000000000000000000000000..6b2df734137b83b58f899252907e52ebde657bd6
GIT binary patch
literal 610
zc$@)Z0-gPdP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00006VoOIv0RI60
z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru+zJB|0tuw22DAVG0q;pf
zK~y-)jgvn})o~QXKi}uep+QTbK>{Cyi%5tCK@AZOg=JVRmf2EDuLuLFrHJSsQbcJz
zl_Hh2!N@d&uqBt4qzIxYnk0l8GNdBHhv&5Xgx{0WzHo<g?)Mz-z1$o4kJo)~bTe=j
zSPhH;t%n<SP6H&C5_b)ZHrYI~$=FocytaATH85HTko=dhvwx%z=(bf4Tt3oR*BhnU
zJNrj|0&PG#{7sy>JG=oH1WF^S{OEyQ@1xwj<~dNGV{oHys03&PYJp7={TpZnI)FSN
z1H3XJ8K59^^gal{c3>Z{2e=jq=G*%QOafIAE&z5o<h{VUl91FU>9M4}lJX_ZNJ>f~
ziULW?Vz@*y?@H??WtSu@9kN6$<}77nIB97rhBKDR04!ybl8P40a4ql#SQq17Mguj_
z^K1F4`^D356SE2=CCvaUVxMb(t_23QK*fplegia*JFNLQSP|?G30qHW5sM;Q30q%d
zT&1m+c$r}?n-&a*wwrxrz{G+oW`VQ7$rwKeoB<w2Rn~k?ZQT|CE_L*zfQ>*gupUrk
zat`<bR7Rp|AO(ymFaOx5@`mp@i*&L5&Te2Rg3nI19IRgKPMXIZa*oN?M6B=Bh3mJA
w7c;oEB{;|6^zo)C%U>*KEw8kEeyMBy12rfguUWen=l}o!07*qoM6N<$f_`}XHvj+t
new file mode 100644
index 0000000000000000000000000000000000000000..a01d0ab7764fd0766d4b38208e7e50ce996aba3a
GIT binary patch
literal 3373
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
Dh&Oq7
--- a/build/automationutils.py
+++ b/build/automationutils.py
@@ -278,149 +278,138 @@ def dumpLeakLog(leakLogFile, filter = Fa
   Use this function if you want the raw log only.
   Use it preferably with the |XPCOM_MEM_LEAK_LOG| environment variable.
   """
 
   # Don't warn (nor "info") if the log file is not there.
   if not os.path.exists(leakLogFile):
     return
 
-  leaks = open(leakLogFile, "r")
-  leakReport = leaks.read()
-  leaks.close()
+  with open(leakLogFile, "r") as leaks:
+    leakReport = leaks.read()
 
   # Only |XPCOM_MEM_LEAK_LOG| reports can be actually filtered out.
   # Only check whether an actual leak was reported.
   if filter and not "0 TOTAL " in leakReport:
     return
 
   # Simply copy the log.
   log.info(leakReport.rstrip("\n"))
 
-def processSingleLeakFile(leakLogFileName, PID, processType, leakThreshold):
-  """Process a single leak log, corresponding to the specified
-  process PID and type.
+def processSingleLeakFile(leakLogFileName, processType, leakThreshold):
+  """Process a single leak log.
   """
 
   #                  Per-Inst  Leaked      Total  Rem ...
   #   0 TOTAL              17     192  419115886    2 ...
   # 833 nsTimerImpl        60     120      24726    2 ...
   lineRe = re.compile(r"^\s*\d+\s+(?P<name>\S+)\s+"
                       r"(?P<size>-?\d+)\s+(?P<bytesLeaked>-?\d+)\s+"
                       r"-?\d+\s+(?P<numLeaked>-?\d+)")
 
   processString = ""
-  if PID and processType:
-    processString = "| %s process %s " % (processType, PID)
-  leaks = open(leakLogFileName, "r")
-  for line in leaks:
-    matches = lineRe.match(line)
-    if (matches and
-        int(matches.group("numLeaked")) == 0 and
-        matches.group("name") != "TOTAL"):
-      continue
-    log.info(line.rstrip())
-  leaks.close()
+  if processType:
+    # eg 'plugin'
+    processString = " %s process:" % processType
 
-  leaks = open(leakLogFileName, "r")
-  seenTotal = False
   crashedOnPurpose = False
-  prefix = "TEST-PASS"
-  numObjects = 0
-  for line in leaks:
-    if line.find("purposefully crash") > -1:
-      crashedOnPurpose = True
-    matches = lineRe.match(line)
-    if not matches:
-      continue
-    name = matches.group("name")
-    size = int(matches.group("size"))
-    bytesLeaked = int(matches.group("bytesLeaked"))
-    numLeaked = int(matches.group("numLeaked"))
-    if size < 0 or bytesLeaked < 0 or numLeaked < 0:
-      log.info("TEST-UNEXPECTED-FAIL %s| automationutils.processLeakLog() | negative leaks caught!" %
-               processString)
+  totalBytesLeaked = None
+  leakAnalysis = []
+  leakedObjectNames = []
+  with open(leakLogFileName, "r") as leaks:
+    for line in leaks:
+      if line.find("purposefully crash") > -1:
+        crashedOnPurpose = True
+      matches = lineRe.match(line)
+      if not matches:
+        # eg: the leak table header row
+        log.info(line.rstrip())
+        continue
+      name = matches.group("name")
+      size = int(matches.group("size"))
+      bytesLeaked = int(matches.group("bytesLeaked"))
+      numLeaked = int(matches.group("numLeaked"))
+      # Output the raw line from the leak log table if it is the TOTAL row,
+      # or is for an object row that has been leaked.
+      if numLeaked != 0 or name == "TOTAL":
+        log.info(line.rstrip())
+      # Analyse the leak log, but output later or it will interrupt the leak table
       if name == "TOTAL":
-        seenTotal = True
-    elif name == "TOTAL":
-      seenTotal = True
-      # Check for leaks.
-      if bytesLeaked < 0 or bytesLeaked > leakThreshold:
-        prefix = "TEST-UNEXPECTED-FAIL"
-        leakLog = "TEST-UNEXPECTED-FAIL %s| automationutils.processLeakLog() | leaked" \
-                  " %d bytes during test execution" % (processString, bytesLeaked)
-      elif bytesLeaked > 0:
-        leakLog = "TEST-PASS %s| automationutils.processLeakLog() | WARNING leaked" \
-                  " %d bytes during test execution" % (processString, bytesLeaked)
-      else:
-        leakLog = "TEST-PASS %s| automationutils.processLeakLog() | no leaks detected!" \
-                  % processString
-      # Remind the threshold if it is not 0, which is the default/goal.
-      if leakThreshold != 0:
-        leakLog += " (threshold set at %d bytes)" % leakThreshold
-      # Log the information.
-      log.info(leakLog)
+        totalBytesLeaked = bytesLeaked
+      if size < 0 or bytesLeaked < 0 or numLeaked < 0:
+        leakAnalysis.append("TEST-UNEXPECTED-FAIL | leakcheck |%s negative leaks caught!"
+                            % processString)
+        continue
+      if name != "TOTAL" and numLeaked != 0:
+        leakedObjectNames.append(name)
+        leakAnalysis.append("TEST-INFO | leakcheck |%s leaked %d %s (%s bytes)"
+                            % (processString, numLeaked, name, bytesLeaked))
+  log.info('\n'.join(leakAnalysis))
+
+  if totalBytesLeaked is None:
+    # We didn't see a line with name 'TOTAL'
+    if crashedOnPurpose:
+      log.info("TEST-INFO | leakcheck |%s deliberate crash and thus no leak log"
+               % processString)
     else:
-      if numLeaked != 0:
-        if numLeaked > 1:
-          instance = "instances"
-          rest = " each (%s bytes total)" % matches.group("bytesLeaked")
-        else:
-          instance = "instance"
-          rest = ""
-        numObjects += 1
-        if numObjects > 5:
-          # don't spam brief tinderbox logs with tons of leak output
-          prefix = "TEST-INFO"
-        log.info("%(prefix)s %(process)s| automationutils.processLeakLog() | leaked %(numLeaked)d %(instance)s of %(name)s "
-                 "with size %(size)s bytes%(rest)s" %
-                 { "prefix": prefix,
-                   "process": processString,
-                   "numLeaked": numLeaked,
-                   "instance": instance,
-                   "name": name,
-                   "size": matches.group("size"),
-                   "rest": rest })
-  if not seenTotal:
-    if crashedOnPurpose:
-      log.info("INFO | automationutils.processLeakLog() | process %s was " \
-               "deliberately crashed and thus has no leak log" % PID)
-    else:
-      log.info("WARNING | automationutils.processLeakLog() | missing output line for total leaks!")
-  leaks.close()
+      # TODO: This should be a TEST-UNEXPECTED-FAIL, but was changed to a warning
+      # due to too many intermittent failures (see bug 831223).
+      log.info("WARNING | leakcheck |%s missing output line for total leaks!"
+               % processString)
+    return
+
+  if totalBytesLeaked == 0:
+    log.info("TEST-PASS | leakcheck |%s no leaks detected!" % processString)
+    return
 
+  # totalBytesLeaked was seen and is non-zero.
+  if totalBytesLeaked > leakThreshold:
+    # Fail the run if we're over the threshold (which defaults to 0)
+    prefix = "TEST-UNEXPECTED-FAIL"
+  else:
+    prefix = "WARNING"
+  # Create a comma delimited string of the first N leaked objects found,
+  # to aid with bug summary matching in TBPL. Note: The order of the objects
+  # had no significance (they're sorted alphabetically).
+  maxSummaryObjects = 5
+  leakedObjectSummary = ', '.join(leakedObjectNames[:maxSummaryObjects])
+  if len(leakedObjectNames) > maxSummaryObjects:
+    leakedObjectSummary += ', ...'
+  log.info("%s | leakcheck |%s %d bytes leaked (%s)"
+           % (prefix, processString, totalBytesLeaked, leakedObjectSummary))
 
 def processLeakLog(leakLogFile, leakThreshold = 0):
   """Process the leak log, including separate leak logs created
   by child processes.
 
   Use this function if you want an additional PASS/FAIL summary.
   It must be used with the |XPCOM_MEM_BLOAT_LOG| environment variable.
   """
 
   if not os.path.exists(leakLogFile):
-    log.info("WARNING | automationutils.processLeakLog() | refcount logging is off, so leaks can't be detected!")
+    log.info("WARNING | leakcheck | refcount logging is off, so leaks can't be detected!")
     return
 
+  if leakThreshold != 0:
+    log.info("TEST-INFO | leakcheck | threshold set at %d bytes" % leakThreshold)
+
   (leakLogFileDir, leakFileBase) = os.path.split(leakLogFile)
-  pidRegExp = re.compile(r".*?_([a-z]*)_pid(\d*)$")
+  fileNameRegExp = re.compile(r".*?_([a-z]*)_pid\d*$")
   if leakFileBase[-4:] == ".log":
     leakFileBase = leakFileBase[:-4]
-    pidRegExp = re.compile(r".*?_([a-z]*)_pid(\d*).log$")
+    fileNameRegExp = re.compile(r".*?_([a-z]*)_pid\d*.log$")
 
   for fileName in os.listdir(leakLogFileDir):
     if fileName.find(leakFileBase) != -1:
       thisFile = os.path.join(leakLogFileDir, fileName)
-      processPID = 0
       processType = None
-      m = pidRegExp.search(fileName)
+      m = fileNameRegExp.search(fileName)
       if m:
         processType = m.group(1)
-        processPID = m.group(2)
-      processSingleLeakFile(thisFile, processPID, processType, leakThreshold)
+      processSingleLeakFile(thisFile, processType, leakThreshold)
 
 def replaceBackSlashes(input):
   return input.replace('\\', '/')
 
 def wrapCommand(cmd):
   """
   If running on OS X 10.5 or older, wrap |cmd| so that it will
   be executed as an i386 binary, in case it's a 32-bit/64-bit universal
--- a/build/cl.py
+++ b/build/cl.py
@@ -52,12 +52,11 @@ def InvokeClWithDependencyGeneration(cmd
         except OSError:
             pass # This suppresses the error we get when the dir exists, at the
                  # cost of masking failure to create the directory.  We'll just
                  # die on the next line though, so it's not that much of a loss.
 
     f = open(depstarget, "w")
     for dep in sorted(deps):
         print >>f, "%s: %s" % (target, dep)
-        print >>f, "%s:" % dep
 
 if __name__ == "__main__":
     InvokeClWithDependencyGeneration(sys.argv[1:])
--- a/build/mobile/b2gautomation.py
+++ b/build/mobile/b2gautomation.py
@@ -1,13 +1,13 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-import automationutils
+import mozcrash
 import threading
 import os
 import Queue
 import re
 import shutil
 import tempfile
 import time
 
@@ -76,16 +76,20 @@ class B2GRemoteAutomation(Automation):
 
     # Set up what we need for the remote environment
     def environment(self, env=None, xrePath=None, crashreporter=True):
         # Because we are running remote, we don't want to mimic the local env
         # so no copying of os.environ
         if env is None:
             env = {}
 
+        if crashreporter:
+            env['MOZ_CRASHREPORTER'] = '1'
+            env['MOZ_CRASHREPORTER_NO_REPORT'] = '1'
+
         # We always hide the results table in B2G; it's much slower if we don't.
         env['MOZ_HIDE_RESULTS_TABLE'] = '1'
         return env
 
     def waitForNet(self):
         active = False
         time_out = 0
         while not active and time_out < 40:
@@ -95,27 +99,26 @@ class B2GRemoteAutomation(Automation):
                 if (re.search(r'UP\s+(?:[0-9]{1,3}\.){3}[0-9]{1,3}', line)):
                     active = True
                     break
             time_out += 1
             time.sleep(1)
         return active
 
     def checkForCrashes(self, directory, symbolsPath):
-        # XXX: This will have to be updated after crash reporting on b2g
-        # is in place.
-        try:
-            dumpDir = tempfile.mkdtemp()
-            self._devicemanager.getDirectory(self._remoteProfile + '/minidumps/', dumpDir)
-            crashed = automationutils.checkForCrashes(dumpDir, symbolsPath, self.lastTestSeen)
-        finally:
+        crashed = False
+        remote_dump_dir = self._remoteProfile + '/minidumps'
+        if self._devicemanager.dirExists(remote_dump_dir):
+            local_dump_dir = tempfile.mkdtemp()
+            self._devicemanager.getDirectory(remote_dump_dir, local_dump_dir)
             try:
-                shutil.rmtree(dumpDir)
-            except:
-                print "WARNING: unable to remove directory: %s" % (dumpDir)
+                crashed = mozcrash.check_for_crashes(local_dump_dir, symbolsPath, test_name=self.lastTestSeen)
+            finally:
+                shutil.rmtree(local_dump_dir)
+                self._devicemanager.removeDir(remote_dump_dir)
         return crashed
 
     def initializeProfile(self,  profileDir, extraPrefs=[],
                           useServerLocations=False,
                           initialProfile=None):
         # add b2g specific prefs
         extraPrefs.extend(["browser.manifestURL='dummy (bug 772307)'"])
         return Automation.initializeProfile(self, profileDir,
deleted file mode 100644
--- a/build/unix/add_phony_targets.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-import pymake.data
-import pymake.parser
-import pymake.parserdata
-import sys
-
-'''
-Modifies the output of Sun Studio's -xM to look more like the output
-of gcc's -MD -MP, adding phony targets for dependencies.
-'''
-
-
-def add_phony_targets(path):
-    print path
-    deps = set()
-    targets = set()
-    for stmt in pymake.parser.parsefile(path):
-        if isinstance(stmt, pymake.parserdata.Rule):
-            assert isinstance(stmt.depexp, pymake.data.StringExpansion)
-            assert isinstance(stmt.targetexp, pymake.data.StringExpansion)
-            for d in stmt.depexp.s.split():
-                deps.add(d)
-            for t in stmt.targetexp.s.split():
-                targets.add(t)
-    phony_targets = deps - targets
-    if not phony_targets:
-        return
-    with open(path, 'a') as f:
-        f.writelines('%s:\n' % d for d in phony_targets)
-
-
-if __name__ == '__main__':
-    for f in sys.argv[1:]:
-        add_phony_targets(f)
deleted file mode 100644
--- a/chrome/Makefile.in
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/config/rules.mk
-
--- a/config/expandlibs_exec.py
+++ b/config/expandlibs_exec.py
@@ -324,14 +324,11 @@ def main():
         if proc.returncode:
             exit(proc.returncode)
     if not options.depend:
         return
     ensureParentDir(options.depend)
     with open(options.depend, 'w') as depfile:
         depfile.write("%s : %s\n" % (options.target, ' '.join(dep for dep in deps if os.path.isfile(dep) and dep != options.target)))
 
-        for dep in deps:
-            if os.path.isfile(dep) and dep != options.target:
-                depfile.write("%s :\n" % dep)
 
 if __name__ == '__main__':
     main()
--- a/config/expandlibs_gen.py
+++ b/config/expandlibs_gen.py
@@ -39,12 +39,9 @@ if __name__ == '__main__':
         raise Exception("Missing option: -o")
 
     ensureParentDir(options.output)
     with open(options.output, 'w') as outfile:
         print >>outfile, generate(args)
     if options.depend:
         ensureParentDir(options.depend)
         with open(options.depend, 'w') as depfile:
-            deps = ExpandLibsDeps(args)
-            depfile.write("%s : %s\n" % (options.output, ' '.join(deps)))
-            for dep in deps:
-                depfile.write("%s :\n" % dep)
+            depfile.write("%s : %s\n" % (options.output, ' '.join(ExpandLibsDeps(args))))
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -981,29 +981,27 @@ endif
 
 ifeq ($(SOLARIS_SUNPRO_CC),1)
 _MDDEPFILE = $(MDDEPDIR)/$(@F).pp
 
 define MAKE_DEPS_AUTO_CC
 if test -d $(@D); then \
 	echo "Building deps for $< using Sun Studio cc"; \
 	$(CC) $(COMPILE_CFLAGS) -xM  $< >$(_MDDEPFILE) ; \
-	$(PYTHON) $(topsrcdir)/build/unix/add_phony_targets.py $(_MDDEPFILE) ; \
 fi
 endef
 define MAKE_DEPS_AUTO_CXX
 if test -d $(@D); then \
 	echo "Building deps for $< using Sun Studio CC"; \
 	$(CXX) $(COMPILE_CXXFLAGS) -xM $< >$(_MDDEPFILE) ; \
-	$(PYTHON) $(topsrcdir)/build/unix/add_phony_targets.py $(_MDDEPFILE) ; \
 fi
 endef
 endif # Sun Studio on Solaris
 
-$(OBJS) $(HOST_OBJS) $(PROGOBJS) $(HOST_PROGOBJS): $(GLOBAL_DEPS)
+$(OBJS) $(HOST_OBJS): $(GLOBAL_DEPS)
 
 # Rules for building native targets must come first because of the host_ prefix
 $(HOST_COBJS): host_%.$(OBJ_SUFFIX): %.c
 	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
 $(HOST_CPPOBJS): host_%.$(OBJ_SUFFIX): %.cpp
 	$(REPORT_BUILD)
@@ -1610,17 +1608,24 @@ endif
 #   a previous build in the source tree) and thus neglect to create a
 #   dependency directory in the object directory, where we really need
 #   it.
 
 ifneq (,$(filter-out all chrome default export realchrome tools clean clobber clobber_all distclean realclean,$(MAKECMDGOALS)))
 MDDEPEND_FILES		:= $(strip $(wildcard $(foreach file,$(OBJS) $(PROGOBJS) $(HOST_OBJS) $(HOST_PROGOBJS) $(TARGETS) $(XPIDLSRCS:.idl=.h) $(XPIDLSRCS:.idl=.xpt),$(MDDEPDIR)/$(notdir $(file)).pp) $(addprefix $(MDDEPDIR)/,$(EXTRA_MDDEPEND_FILES))))
 
 ifneq (,$(MDDEPEND_FILES))
-include $(MDDEPEND_FILES)
+# The script mddepend.pl checks the dependencies and writes to stdout
+# one rule to force out-of-date objects. For example,
+#   foo.o boo.o: FORCE
+# The script has an advantage over including the *.pp files directly
+# because it handles the case when header files are removed from the build.
+# 'make' would complain that there is no way to build missing headers.
+ALL_PP_RESULTS = $(shell $(PERL) $(BUILD_TOOLS)/mddepend.pl - $(MDDEPEND_FILES))
+$(eval $(ALL_PP_RESULTS))
 endif
 
 endif
 #############################################################################
 
 -include $(topsrcdir)/$(MOZ_BUILD_APP)/app-rules.mk
 -include $(MY_RULES)
 
--- a/configure.in
+++ b/configure.in
@@ -7930,17 +7930,17 @@ fi # COMPILE_ENVIRONMENT
 dnl ========================================================
 dnl =
 dnl = Build depencency options
 dnl =
 dnl ========================================================
 MOZ_ARG_HEADER(Build dependencies)
 
 if test "$GNU_CC" -a "$GNU_CXX"; then
-  _DEPEND_CFLAGS='-MD -MP -MF $(MDDEPDIR)/$(@F).pp'
+  _DEPEND_CFLAGS='$(filter-out %/.pp,-MD -MF $(MDDEPDIR)/$(@F).pp)'
 dnl Sun Studio on Solaris use -xM instead of -MD, see config/rules.mk
 elif test "$SOLARIS_SUNPRO_CC"; then
   _DEPEND_CFLAGS=
 else
   dnl Don't override this for MSVC
   if test -z "$_WIN32_MSVC"; then
     _USE_CPP_INCLUDE_FLAG=
     _DEFINES_CFLAGS='$(ACDEFINES) -D_MOZILLA_CONFIG_H_ -DMOZILLA_CLIENT'
deleted file mode 100644
--- a/content/base/Makefile.in
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/config/rules.mk
-
--- a/content/base/public/nsIStyleSheetLinkingElement.h
+++ b/content/base/public/nsIStyleSheetLinkingElement.h
@@ -11,29 +11,30 @@
 class nsICSSLoaderObserver;
 class nsIURI;
 
 #define NS_ISTYLESHEETLINKINGELEMENT_IID          \
 { 0xd753c84a, 0x17fd, 0x4d5f, \
  { 0xb2, 0xe9, 0x63, 0x52, 0x8c, 0x87, 0x99, 0x7a } }
 
 class nsIStyleSheet;
+class nsCSSStyleSheet;
 
 class nsIStyleSheetLinkingElement : public nsISupports {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISTYLESHEETLINKINGELEMENT_IID)
 
   /**
    * Used to make the association between a style sheet and
    * the element that linked it to the document.
    *
    * @param aStyleSheet the style sheet associated with this
    *                    element.
    */
-  NS_IMETHOD SetStyleSheet(nsIStyleSheet* aStyleSheet) = 0;
+  NS_IMETHOD SetStyleSheet(nsCSSStyleSheet* aStyleSheet) = 0;
 
   /**
    * Used to obtain the style sheet linked in by this element.
    *
    * @param aStyleSheet out parameter that returns the style
    *                    sheet associated with this element.
    */
   NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aStyleSheet) = 0;
--- a/content/base/src/CSPUtils.jsm
+++ b/content/base/src/CSPUtils.jsm
@@ -1904,17 +1904,24 @@ CSPViolationReportListener.prototype = {
                 this._reportURI);
     }
   },
 
   onStartRequest:
   function(request, context) { },
 
   onDataAvailable:
-  function(request, context, inputStream, offset, count) { },
+  function(request, context, inputStream, offset, count) {
+    // We MUST read equal to count from the inputStream to avoid an assertion.
+    var input = Components.classes['@mozilla.org/scriptableinputstream;1']
+                .createInstance(Ci.nsIScriptableInputStream);
+
+    input.init(inputStream);
+    input.read(count);
+  },
 
 };
 
 //////////////////////////////////////////////////////////////////////
 
 function innerWindowFromRequest(docRequest) {
   let win = null;
   let loadContext = null;
--- a/content/base/src/nsStyleLinkElement.cpp
+++ b/content/base/src/nsStyleLinkElement.cpp
@@ -51,31 +51,27 @@ nsStyleLinkElement::Unlink()
 void
 nsStyleLinkElement::Traverse(nsCycleCollectionTraversalCallback &cb)
 {
   nsStyleLinkElement* tmp = this;
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheet);
 }
 
 NS_IMETHODIMP 
-nsStyleLinkElement::SetStyleSheet(nsIStyleSheet* aStyleSheet)
+nsStyleLinkElement::SetStyleSheet(nsCSSStyleSheet* aStyleSheet)
 {
-  nsRefPtr<nsCSSStyleSheet> cssSheet = do_QueryObject(mStyleSheet);
-  if (cssSheet) {
-    cssSheet->SetOwningNode(nullptr);
+  if (mStyleSheet) {
+    mStyleSheet->SetOwningNode(nullptr);
   }
 
   mStyleSheet = aStyleSheet;
-  cssSheet = do_QueryObject(mStyleSheet);
-  if (cssSheet) {
-    nsCOMPtr<nsIDOMNode> node;
-    CallQueryInterface(this,
-                       static_cast<nsIDOMNode**>(getter_AddRefs(node)));
+  if (mStyleSheet) {
+    nsCOMPtr<nsINode> node = do_QueryObject(this);
     if (node) {
-      cssSheet->SetOwningNode(node);
+      mStyleSheet->SetOwningNode(node);
     }
   }
     
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsStyleLinkElement::GetStyleSheet(nsIStyleSheet*& aStyleSheet)
@@ -92,25 +88,17 @@ nsStyleLinkElement::InitStyleLinkElement
   mDontLoadStyle = aDontLoadStyle;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsStyleLinkElement::GetSheet(nsIDOMStyleSheet** aSheet)
 {
-  NS_ENSURE_ARG_POINTER(aSheet);
-  *aSheet = nullptr;
-
-  if (mStyleSheet) {
-    CallQueryInterface(mStyleSheet, aSheet);
-  }
-
-  // Always return NS_OK to avoid throwing JS exceptions if mStyleSheet 
-  // is not a nsIDOMStyleSheet
+  NS_IF_ADDREF(*aSheet = mStyleSheet);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsStyleLinkElement::SetEnableUpdates(bool aEnableUpdates)
 {
   mUpdatesEnabled = aEnableUpdates;
 
@@ -411,38 +399,34 @@ nsStyleLinkElement::DoUpdateStyleSheet(n
 
 void
 nsStyleLinkElement::UpdateStyleSheetScopedness(bool aIsNowScoped)
 {
   if (!mStyleSheet) {
     return;
   }
 
-  nsRefPtr<nsCSSStyleSheet> cssStyleSheet = do_QueryObject(mStyleSheet);
-  NS_ASSERTION(cssStyleSheet, "should only call UpdateStyleSheetScope for "
-                              "an nsCSSStyleSheet");
-
   nsCOMPtr<nsIContent> thisContent;
   CallQueryInterface(this, getter_AddRefs(thisContent));
 
-  Element* oldScopeElement = cssStyleSheet->GetScopeElement();
+  Element* oldScopeElement = mStyleSheet->GetScopeElement();
   Element* newScopeElement = aIsNowScoped ?
                                thisContent->GetParentElement() :
                                nullptr;
 
   if (oldScopeElement == newScopeElement) {
     return;
   }
 
   nsIDocument* document = thisContent->GetOwnerDocument();
 
   document->BeginUpdate(UPDATE_STYLE);
   document->RemoveStyleSheet(mStyleSheet);
 
-  cssStyleSheet->SetScopeElement(newScopeElement);
+  mStyleSheet->SetScopeElement(newScopeElement);
 
   document->AddStyleSheet(mStyleSheet);
   document->EndUpdate(UPDATE_STYLE);
 
   if (oldScopeElement) {
     UpdateIsElementInStyleScopeFlagOnSubtree(oldScopeElement);
   }
   if (newScopeElement) {
--- a/content/base/src/nsStyleLinkElement.h
+++ b/content/base/src/nsStyleLinkElement.h
@@ -11,17 +11,17 @@
  */
 
 #ifndef nsStyleLinkElement_h___
 #define nsStyleLinkElement_h___
 
 #include "nsCOMPtr.h"
 #include "nsIDOMLinkStyle.h"
 #include "nsIStyleSheetLinkingElement.h"
-#include "nsIStyleSheet.h"
+#include "nsCSSStyleSheet.h"
 #include "nsIURI.h"
 #include "nsTArray.h"
 #include "mozilla/CORSMode.h"
 
 #define PREFETCH      0x00000001
 #define DNS_PREFETCH  0x00000002
 #define STYLESHEET    0x00000004
 #define NEXT          0x00000008
@@ -36,20 +36,20 @@ public:
   nsStyleLinkElement();
   virtual ~nsStyleLinkElement();
 
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) = 0;
 
   // nsIDOMLinkStyle
   NS_DECL_NSIDOMLINKSTYLE
 
-  nsIStyleSheet* GetSheet() { return mStyleSheet; }
+  nsCSSStyleSheet* GetSheet() const { return mStyleSheet; }
 
   // nsIStyleSheetLinkingElement  
-  NS_IMETHOD SetStyleSheet(nsIStyleSheet* aStyleSheet);
+  NS_IMETHOD SetStyleSheet(nsCSSStyleSheet* aStyleSheet);
   NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aStyleSheet);
   NS_IMETHOD InitStyleLinkElement(bool aDontLoadStyle);
   NS_IMETHOD UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
                               bool* aWillNotify,
                               bool* aIsAlternate);
   NS_IMETHOD SetEnableUpdates(bool aEnableUpdates);
   NS_IMETHOD GetCharset(nsAString& aCharset);
 
@@ -100,17 +100,17 @@ private:
    *                     changed but the URI may not have changed.
    */
   nsresult DoUpdateStyleSheet(nsIDocument *aOldDocument,
                               nsICSSLoaderObserver* aObserver,
                               bool* aWillNotify,
                               bool* aIsAlternate,
                               bool aForceUpdate);
 
-  nsCOMPtr<nsIStyleSheet> mStyleSheet;
+  nsRefPtr<nsCSSStyleSheet> mStyleSheet;
 protected:
   bool mDontLoadStyle;
   bool mUpdatesEnabled;
   uint32_t mLineNumber;
 };
 
 #endif /* nsStyleLinkElement_h___ */
 
--- a/content/base/test/file_mixed_content_main_bug803225.html
+++ b/content/base/test/file_mixed_content_main_bug803225.html
@@ -50,16 +50,19 @@ https://bugzilla.mozilla.org/show_bug.cg
       data = {"test": protocols[i][0], "msg": "resource with " + protocols[i][0] + " protocol did not load"};
       parent.postMessage(data, "http://mochi.test:8888");
     }.bind(generic_frame, i);
 
     testContent.appendChild(generic_frame, i);
   }
 
   // Test 3: for resource within a script tag
+  // Note: the script we load throws an exception, but the script element's
+  // onload listener is called after we successfully fetch the script,
+  // independently of whether it throws an exception.
   var resource_script=document.createElement("script");
   resource_script.src = "resource://gre/modules/XPCOMUtils.jsm";
   resource_script.name = "resource_protocol";
   resource_script.onload = function() {
     parent.postMessage({"test": "resource", "msg": "resource with resource protocol loaded"}, "http://mochi.test:8888");
   }
   resource_script.onerror = function() {
     parent.postMessage({"test": "resource", "msg": "resource with resource protocol did not load"}, "http://mochi.test:8888");
@@ -112,26 +115,27 @@ https://bugzilla.mozilla.org/show_bug.cg
   webHandler.uriTemplate = "http://example.com/tests/content/base/test/bug803225_test_mailto.html?s=%";
 
   var uri = ioService.newURI("mailto:foo@bar.com", null, null);
   webHandler.launchWithURI(uri);
 
   var mailto = false;
 
   // listen for a messages from a new window
+  var os = SpecialPowers.Cc["@mozilla.org/observer-service;1"].
+     getService(SpecialPowers.Components.interfaces.nsIObserverService);
   var observer = {
     observe: function(subject, topic, data) {
       if(topic == "content-document-global-created" && data =="http://example.com") {
          parent.postMessage({"test": "mailto", "msg": "resource with mailto protocol loaded"}, "http://mochi.test:8888");
+         os.removeObserver(observer, "content-document-global-created");
          mailto = true;
       }
     }
   }
-  var os = SpecialPowers.Cc["@mozilla.org/observer-service;1"].
-     getService(SpecialPowers.Components.interfaces.nsIObserverService);
   os.addObserver(observer, "content-document-global-created", false);
 
   function mailtoProtocolStatus() {
     if(!mailto) {
       //There is no onerror event associated with the WebHandler, and hence we need a setTimeout to check the status
       setTimeout(mailtoProtocolStatus, TIMEOUT_INTERVAL);
     }
   }
--- a/content/base/test/test_bug548193.html
+++ b/content/base/test/test_bug548193.html
@@ -7,58 +7,55 @@
 </head>
 <body>
 <p id="display"></p>
 <div id="content" style="display: none">
 </div>
 
 <iframe style="width:200px;height:200px;" id='cspframe'></iframe>
 <script class="testbody" type="text/javascript">
-
-SimpleTest.expectAssertions(1);
-
 // This is used to watch requests go out so we can see if the report is
 // sent correctly
 function examiner() {
-  netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-  var obsvc = Components.classes['@mozilla.org/observer-service;1']
-                        .getService(Components.interfaces.nsIObserverService);
-  obsvc.addObserver(this, "http-on-modify-request", false);
+  SpecialPowers.addObserver(this, "http-on-opening-request", false);
 }
 examiner.prototype  = {
   observe: function(subject, topic, data) {
-    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
     // subject should be an nsURI
-    if(!subject.QueryInterface)
+    if (!SpecialPowers.can_QI(subject))
       return;
 
     const reportURI = "http://mochi.test:8888/csp-report.cgi";
 
-    if (topic === "http-on-modify-request") {
-      var uri = subject.QueryInterface(Components.interfaces.nsIHttpChannel).URI;
-      if (uri.asciiSpec !== reportURI) return;
+    if (topic === "http-on-opening-request") {
+      var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIHttpChannel"), "URI.asciiSpec");
+      if (asciiSpec !== reportURI) return;
 
       // Verify that the report was properly formatted.
       // We'll parse the report text as JSON and verify that the properties
       // have expected values.
       var reportText = "{}";
       try {
-        var uploadStream = subject.QueryInterface(Components.interfaces.nsIUploadChannel).uploadStream;
+        var uploadStream = SpecialPowers.wrap(SpecialPowers.do_QueryInterface(subject, "nsIUploadChannel")).uploadStream;
 
         if (uploadStream) {
           // get the bytes from the request body
-          var binstream = Components.classes["@mozilla.org/binaryinputstream;1"]
-                                    .createInstance(Components.interfaces.nsIBinaryInputStream);
+          var binstream = SpecialPowers.Cc["@mozilla.org/binaryinputstream;1"]
+                                          .createInstance(SpecialPowers.Ci.nsIBinaryInputStream);
           binstream.setInputStream(uploadStream);
 
           var segments = [];
-          for (var count = uploadStream.available(); count; count = uploadStream.available())
-            segments.push(binstream.readBytes(count));
+          for (var count = uploadStream.available(); count; count = uploadStream.available()) {
+            var data = binstream.readBytes(count);
+            segments.push(data);
+          }
 
           var reportText = segments.join("");
+          // rewind stream as we are supposed to - there will be an assertion later if we don't.
+          SpecialPowers.do_QueryInterface(uploadStream, "nsISeekableStream").seek(SpecialPowers.Ci.nsISeekableStream.NS_SEEK_SET, 0);
         }
       }
       catch(e) {}
 
       var reportObj = JSON.parse(reportText);
 
       // test for the proper values in the report object
       window.checkResults(reportObj);
@@ -66,20 +63,17 @@ examiner.prototype  = {
       // finish up
       window.examiner.remove();
       SimpleTest.finish();
     }
   },
 
   // remove the listener
   remove: function() {
-    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-    var obsvc = Components.classes['@mozilla.org/observer-service;1']
-                          .getService(Components.interfaces.nsIObserverService);
-    obsvc.removeObserver(this, "http-on-modify-request");
+    SpecialPowers.removeObserver(this, "http-on-opening-request");
   }
 }
 
 // content file that triggers a violation report
 var testFile = "file_bug548193.sjs";
 
 window.checkResults = function(reportObj) {
   var cspReport = reportObj["csp-report"];
deleted file mode 100644
--- a/content/canvas/Makefile.in
+++ /dev/null
@@ -1,13 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/rules.mk
-
deleted file mode 100644
--- a/content/events/Makefile.in
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/config/rules.mk
-
--- a/content/events/src/nsDOMMessageEvent.cpp
+++ b/content/events/src/nsDOMMessageEvent.cpp
@@ -4,19 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMMessageEvent.h"
 #include "nsContentUtils.h"
 #include "jsapi.h"
 #include "nsDOMClassInfoID.h"
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMMessageEvent, nsDOMEvent)
-  if (tmp->mDataRooted) {
-    tmp->UnrootData();
-  }
+  tmp->mData = JSVAL_VOID;
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSource)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMMessageEvent, nsDOMEvent)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSource)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsDOMMessageEvent, nsDOMEvent)
@@ -32,41 +30,23 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEve
 
 NS_IMPL_ADDREF_INHERITED(nsDOMMessageEvent, nsDOMEvent)
 NS_IMPL_RELEASE_INHERITED(nsDOMMessageEvent, nsDOMEvent)
 
 nsDOMMessageEvent::nsDOMMessageEvent(mozilla::dom::EventTarget* aOwner,
                                      nsPresContext* aPresContext,
                                      nsEvent* aEvent)
   : nsDOMEvent(aOwner, aPresContext, aEvent),
-    mData(JSVAL_VOID),
-    mDataRooted(false)
+    mData(JSVAL_VOID)
 {
   SetIsDOMBinding();
 }
 
 nsDOMMessageEvent::~nsDOMMessageEvent()
 {
-  if (mDataRooted)
-    UnrootData();
-}
-
-void
-nsDOMMessageEvent::RootData()
-{
-  NS_ASSERTION(!mDataRooted, "...");
-  NS_HOLD_JS_OBJECTS(this, nsDOMMessageEvent);
-  mDataRooted = true;
-}
-
-void
-nsDOMMessageEvent::UnrootData()
-{
-  NS_ASSERTION(mDataRooted, "...");
-  mDataRooted = false;
   mData = JSVAL_VOID;
   NS_DROP_JS_OBJECTS(this, nsDOMMessageEvent);
 }
 
 NS_IMETHODIMP
 nsDOMMessageEvent::GetData(JSContext* aCx, JS::Value* aData)
 {
   *aData = mData;
@@ -103,22 +83,18 @@ nsDOMMessageEvent::InitMessageEvent(cons
                                     const JS::Value& aData,
                                     const nsAString& aOrigin,
                                     const nsAString& aLastEventId,
                                     nsIDOMWindow* aSource)
 {
   nsresult rv = nsDOMEvent::InitEvent(aType, aCanBubble, aCancelable);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // Allowing double-initialization seems a little silly, but we have a test
-  // for it so it might be important ...
-  if (mDataRooted)
-    UnrootData();
   mData = aData;
-  RootData();
+  NS_HOLD_JS_OBJECTS(this, nsDOMMessageEvent);
   mOrigin = aOrigin;
   mLastEventId = aLastEventId;
   mSource = aSource;
 
   return NS_OK;
 }
 
 nsresult
--- a/content/events/src/nsDOMMessageEvent.h
+++ b/content/events/src/nsDOMMessageEvent.h
@@ -31,19 +31,16 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(nsDOMMessageEvent,
                                                          nsDOMEvent)
 
   NS_DECL_NSIDOMMESSAGEEVENT
 
   // Forward to base class
   NS_FORWARD_TO_NSDOMEVENT
 
-  void RootData();
-  void UnrootData();
-
   virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope)
   {
     return mozilla::dom::MessageEventBinding::Wrap(aCx, aScope, this);
   }
 
   JS::Value GetData(JSContext* aCx, mozilla::ErrorResult& aRv)
   {
     JS::Value data;
@@ -68,15 +65,14 @@ public:
                         mozilla::ErrorResult& aRv)
   {
     aRv = InitMessageEvent(aType, aCanBubble, aCancelable, aData,
                            aOrigin, aLastEventId, aSource);
   }
 
 private:
   JS::Value mData;
-  bool mDataRooted;
   nsString mOrigin;
   nsString mLastEventId;
   nsCOMPtr<nsIDOMWindow> mSource;
 };
 
 #endif // nsDOMMessageEvent_h__
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -749,16 +749,21 @@ nsEventListenerManager::CompileEventHand
                "What is there to compile?");
 
   nsIScriptContext *context = listener->GetEventContext();
   JSContext *cx = context->GetNativeContext();
   nsScriptObjectHolder<JSObject> handler(context);
 
   nsCOMPtr<nsPIDOMWindow> win; // Will end up non-null if mTarget is a window
 
+  nsCxPusher pusher;
+  if (aNeedsCxPush) {
+    pusher.Push(cx);
+  }
+
   if (aListenerStruct->mHandlerIsString) {
     // OK, we didn't find an existing compiled event handler.  Flag us
     // as not a string so we don't keep trying to compile strings
     // which can't be compiled
     aListenerStruct->mHandlerIsString = false;
 
     // mTarget may not be an nsIContent if it's a window and we're
     // getting an inline event listener forwarded from <html:body> or
@@ -812,21 +817,16 @@ nsEventListenerManager::CompileEventHand
     if (doc) {
       nsIURI *uri = doc->GetDocumentURI();
       if (uri) {
         uri->GetSpec(url);
         lineNo = 1;
       }
     }
 
-    nsCxPusher pusher;
-    if (aNeedsCxPush) {
-      pusher.Push(cx);
-    }
-
     uint32_t argCount;
     const char **argNames;
     // If no content, then just use kNameSpaceID_None for the
     // namespace ID.  In practice, it doesn't matter since SVG is
     // the only thing with weird arg names and SVG doesn't map event
     // listeners to the window.
     nsContentUtils::GetEventArgNames(content ?
                                        content->GetNameSpaceID() :
@@ -852,44 +852,41 @@ nsEventListenerManager::CompileEventHand
 
   if (handler) {
     // Bind it
     nsScriptObjectHolder<JSObject> boundHandler(context);
     context->BindCompiledEventHandler(mTarget, listener->GetEventScope(),
                                       handler.get(), boundHandler);
     if (listener->EventName() == nsGkAtoms::onerror && win) {
       bool ok;
-      JSAutoRequest ar(context->GetNativeContext());
+      JSAutoRequest ar(cx);
       nsRefPtr<OnErrorEventHandlerNonNull> handlerCallback =
-        new OnErrorEventHandlerNonNull(context->GetNativeContext(),
-                                       listener->GetEventScope(),
+        new OnErrorEventHandlerNonNull(cx, listener->GetEventScope(),
                                        boundHandler.get(), &ok);
       if (!ok) {
         // JS_WrapObject failed, which means OOM allocating the JSObject.
         return NS_ERROR_OUT_OF_MEMORY;
       }
       listener->SetHandler(handlerCallback);
     } else if (listener->EventName() == nsGkAtoms::onbeforeunload && win) {
       bool ok;
-      JSAutoRequest ar(context->GetNativeContext());
+      JSAutoRequest ar(cx);
       nsRefPtr<BeforeUnloadEventHandlerNonNull> handlerCallback =
-        new BeforeUnloadEventHandlerNonNull(context->GetNativeContext(),
-                                            listener->GetEventScope(),
+        new BeforeUnloadEventHandlerNonNull(cx, listener->GetEventScope(),
                                             boundHandler.get(), &ok);
       if (!ok) {
         // JS_WrapObject failed, which means OOM allocating the JSObject.
         return NS_ERROR_OUT_OF_MEMORY;
       }
       listener->SetHandler(handlerCallback);
     } else {
       bool ok;
-      JSAutoRequest ar(context->GetNativeContext());
+      JSAutoRequest ar(cx);
       nsRefPtr<EventHandlerNonNull> handlerCallback =
-        new EventHandlerNonNull(context->GetNativeContext(),
-                                listener->GetEventScope(),
+        new EventHandlerNonNull(cx, listener->GetEventScope(),
                                 boundHandler.get(), &ok);
       if (!ok) {
         // JS_WrapObject failed, which means OOM allocating the JSObject.
         return NS_ERROR_OUT_OF_MEMORY;
       }
       listener->SetHandler(handlerCallback);
     }
   }
deleted file mode 100644
--- a/content/html/Makefile.in
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/content/html/content/Makefile.in
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/config/rules.mk
-
--- a/content/html/content/src/HTMLLinkElement.cpp
+++ b/content/html/content/src/HTMLLinkElement.cpp
@@ -64,53 +64,44 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(HTMLLinkElement,
                                                nsGenericHTMLElement)
 NS_HTML_CONTENT_INTERFACE_MAP_END
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLLinkElement)
 
 bool
-HTMLLinkElement::GetDisabled(ErrorResult& aRv)
+HTMLLinkElement::Disabled()
 {
-  nsCOMPtr<nsIDOMStyleSheet> ss = do_QueryInterface(GetSheet());
-  if (!ss) {
-    return false;
-  }
-
-  bool disabled = false;
-  aRv = ss->GetDisabled(&disabled);
-  return disabled;
+  nsCSSStyleSheet* ss = GetSheet();
+  return ss && ss->Disabled();
 }
 
 NS_IMETHODIMP
-HTMLLinkElement::GetDisabled(bool* aDisabled)
+HTMLLinkElement::GetMozDisabled(bool* aDisabled)
 {
-  ErrorResult rv;
-  *aDisabled = GetDisabled(rv);
-  return rv.ErrorCode();
+  *aDisabled = Disabled();
+  return NS_OK;
 }
 
 void
-HTMLLinkElement::SetDisabled(bool aDisabled, ErrorResult& aRv)
+HTMLLinkElement::SetDisabled(bool aDisabled)
 {
-  nsCOMPtr<nsIDOMStyleSheet> ss = do_QueryInterface(GetSheet());
-  if (!ss) {
-    return;
+  nsCSSStyleSheet* ss = GetSheet();
+  if (ss) {
+    ss->SetDisabled(aDisabled);
   }
 
-  aRv = ss->SetDisabled(aDisabled);
 }
 
 NS_IMETHODIMP
-HTMLLinkElement::SetDisabled(bool aDisabled)
+HTMLLinkElement::SetMozDisabled(bool aDisabled)
 {
-  ErrorResult rv;
-  SetDisabled(aDisabled, rv);
-  return rv.ErrorCode();
+  SetDisabled(aDisabled);
+  return NS_OK;
 }
 
 
 NS_IMPL_STRING_ATTR(HTMLLinkElement, Charset, charset)
 NS_IMPL_URI_ATTR(HTMLLinkElement, Href, href)
 NS_IMPL_STRING_ATTR(HTMLLinkElement, Hreflang, hreflang)
 NS_IMPL_STRING_ATTR(HTMLLinkElement, Media, media)
 NS_IMPL_STRING_ATTR(HTMLLinkElement, Rel, rel)
--- a/content/html/content/src/HTMLLinkElement.h
+++ b/content/html/content/src/HTMLLinkElement.h
@@ -87,18 +87,18 @@ public:
                               const nsAString& aValue,
                               nsAttrValue& aResult);
   virtual void GetLinkTarget(nsAString& aTarget);
   virtual nsEventStates IntrinsicState() const;
 
   void CreateAndDispatchEvent(nsIDocument* aDoc, const nsAString& aEventName);
 
   // WebIDL
-  bool GetDisabled(ErrorResult& aRv);
-  void SetDisabled(bool aDisabled, ErrorResult& aRv);
+  bool Disabled();
+  void SetDisabled(bool aDisabled);
   // XPCOM GetHref is fine.
   void SetHref(const nsAString& aHref, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::href, aHref, aRv);
   }
   // XPCOM GetCrossOrigin is fine.
   void SetCrossOrigin(const nsAString& aCrossOrigin, ErrorResult& aRv)
   {
rename from content/html/content/src/nsHTMLSharedObjectElement.cpp
rename to content/html/content/src/HTMLSharedObjectElement.cpp
--- a/content/html/content/src/nsHTMLSharedObjectElement.cpp
+++ b/content/html/content/src/HTMLSharedObjectElement.cpp
@@ -1,269 +1,145 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 // vim:set et sw=2 sts=2 cin:
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "mozilla/dom/HTMLSharedObjectElement.h"
+#include "mozilla/dom/HTMLEmbedElementBinding.h"
+#include "mozilla/dom/HTMLAppletElementBinding.h"
 #include "mozilla/Util.h"
 
-#include "nsGenericHTMLElement.h"
-#include "nsObjectLoadingContent.h"
-#include "nsGkAtoms.h"
-#include "nsError.h"
 #include "nsIDocument.h"
 #include "nsIPluginDocument.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMHTMLAppletElement.h"
-#include "nsIDOMHTMLEmbedElement.h"
 #include "nsThreadUtils.h"
-#include "nsIDOMGetSVGDocument.h"
 #include "nsIDOMSVGDocument.h"
 #include "nsIScriptError.h"
 #include "nsIWidget.h"
 #include "nsContentUtils.h"
 
-using namespace mozilla;
-using namespace mozilla::dom;
-
-class nsHTMLSharedObjectElement : public nsGenericHTMLElement
-                                , public nsObjectLoadingContent
-                                , public nsIDOMHTMLAppletElement
-                                , public nsIDOMHTMLEmbedElement
-                                , public nsIDOMGetSVGDocument
-{
-public:
-  nsHTMLSharedObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                            mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
-  virtual ~nsHTMLSharedObjectElement();
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
-  virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
-
-  // nsIDOMHTMLAppletElement
-  NS_DECL_NSIDOMHTMLAPPLETELEMENT
-
-  // Can't use macro for nsIDOMHTMLEmbedElement because it has conflicts with
-  // NS_DECL_NSIDOMHTMLAPPLETELEMENT.
-
-  // nsIDOMHTMLEmbedElement
-  NS_IMETHOD GetSrc(nsAString &aSrc);
-  NS_IMETHOD SetSrc(const nsAString &aSrc);
-  NS_IMETHOD GetType(nsAString &aType);
-  NS_IMETHOD SetType(const nsAString &aType);
-
-  // nsIDOMGetSVGDocument
-  NS_DECL_NSIDOMGETSVGDOCUMENT
-
-  virtual nsresult BindToTree(nsIDocument *aDocument, nsIContent *aParent,
-                              nsIContent *aBindingParent,
-                              bool aCompileEventHandlers);
-  virtual void UnbindFromTree(bool aDeep = true,
-                              bool aNullParent = true);
-  virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom *aName,
-                           nsIAtom *aPrefix, const nsAString &aValue,
-                           bool aNotify);
-
-  virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex);
-  virtual IMEState GetDesiredIMEState();
-
-  virtual void DoneAddingChildren(bool aHaveNotified);
-  virtual bool IsDoneAddingChildren();
-
-  virtual bool ParseAttribute(int32_t aNamespaceID,
-                                nsIAtom *aAttribute,
-                                const nsAString &aValue,
-                                nsAttrValue &aResult);
-  virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom *aAttribute) const;
-  virtual nsEventStates IntrinsicState() const;
-  virtual void DestroyContent();
-
-  // nsObjectLoadingContent
-  virtual uint32_t GetCapabilities() const;
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  nsresult CopyInnerTo(Element* aDest);
-
-  void StartObjectLoad() { StartObjectLoad(true); }
-
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLSharedObjectElement,
-                                                     nsGenericHTMLElement)
-
-  virtual nsXPCClassInfo* GetClassInfo()
-  {
-    return static_cast<nsXPCClassInfo*>(GetClassInfoInternal());
-  }
-  nsIClassInfo* GetClassInfoInternal();
-
-  virtual nsIDOMNode* AsDOMNode()
-  {
-    return static_cast<nsIDOMHTMLAppletElement*>(this);
-  }
-private:
-  /**
-   * Calls LoadObject with the correct arguments to start the plugin load.
-   */
-  NS_HIDDEN_(void) StartObjectLoad(bool aNotify);
-
-  void GetTypeAttrValue(nsCString &aValue) const
-  {
-    if (mNodeInfo->Equals(nsGkAtoms::applet)) {
-      aValue.AppendLiteral("application/x-java-vm");
-    }
-    else {
-      nsAutoString type;
-      GetAttr(kNameSpaceID_None, nsGkAtoms::type, type);
-
-      CopyUTF16toUTF8(type, aValue);
-    }
-  }
-
-  nsIAtom *URIAttrName() const
-  {
-    return mNodeInfo->Equals(nsGkAtoms::applet) ?
-           nsGkAtoms::code :
-           nsGkAtoms::src;
-  }
-
-  // mIsDoneAddingChildren is only really used for <applet>.  This boolean is
-  // always true for <embed>, per the documentation in nsIContent.h.
-  bool mIsDoneAddingChildren;
-
-  virtual void GetItemValueText(nsAString& text);
-  virtual void SetItemValueText(const nsAString& text);
-};
-
-
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(SharedObject)
 
+DOMCI_DATA(HTMLAppletElement, mozilla::dom::HTMLSharedObjectElement)
+DOMCI_DATA(HTMLEmbedElement, mozilla::dom::HTMLSharedObjectElement)
 
-nsHTMLSharedObjectElement::nsHTMLSharedObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                                     FromParser aFromParser)
+namespace mozilla {
+namespace dom {
+
+HTMLSharedObjectElement::HTMLSharedObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
+                                                 FromParser aFromParser)
   : nsGenericHTMLElement(aNodeInfo),
     mIsDoneAddingChildren(mNodeInfo->Equals(nsGkAtoms::embed) || !aFromParser)
 {
   RegisterFreezableElement();
   SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK);
 
   // By default we're in the loading state
   AddStatesSilently(NS_EVENT_STATE_LOADING);
+
+  SetIsDOMBinding();
 }
 
 void
-nsHTMLSharedObjectElement::GetItemValueText(nsAString& aValue)
+HTMLSharedObjectElement::GetItemValueText(nsAString& aValue)
 {
   if (mNodeInfo->Equals(nsGkAtoms::applet)) {
     nsGenericHTMLElement::GetItemValueText(aValue);
   } else {
     GetSrc(aValue);
   }
 }
 
 void
-nsHTMLSharedObjectElement::SetItemValueText(const nsAString& aValue)
+HTMLSharedObjectElement::SetItemValueText(const nsAString& aValue)
 {
   if (mNodeInfo->Equals(nsGkAtoms::applet)) {
     nsGenericHTMLElement::SetItemValueText(aValue);
   } else {
     SetSrc(aValue);
   }
 }
 
-nsHTMLSharedObjectElement::~nsHTMLSharedObjectElement()
+HTMLSharedObjectElement::~HTMLSharedObjectElement()
 {
   UnregisterFreezableElement();
   DestroyImageLoadingContent();
 }
 
 bool
-nsHTMLSharedObjectElement::IsDoneAddingChildren()
+HTMLSharedObjectElement::IsDoneAddingChildren()
 {
   return mIsDoneAddingChildren;
 }
 
 void
-nsHTMLSharedObjectElement::DoneAddingChildren(bool aHaveNotified)
+HTMLSharedObjectElement::DoneAddingChildren(bool aHaveNotified)
 {
   if (!mIsDoneAddingChildren) {
     mIsDoneAddingChildren = true;
 
     // If we're already in a document, we need to trigger the load
     // Otherwise, BindToTree takes care of that.
     if (IsInDoc()) {
       StartObjectLoad(aHaveNotified);
     }
   }
 }
 
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLSharedObjectElement,
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLSharedObjectElement,
                                                   nsGenericHTMLElement)
   nsObjectLoadingContent::Traverse(tmp, cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
-NS_IMPL_ADDREF_INHERITED(nsHTMLSharedObjectElement, Element)
-NS_IMPL_RELEASE_INHERITED(nsHTMLSharedObjectElement, Element)
-
-DOMCI_DATA(HTMLAppletElement, nsHTMLSharedObjectElement)
-DOMCI_DATA(HTMLEmbedElement, nsHTMLSharedObjectElement)
+NS_IMPL_ADDREF_INHERITED(HTMLSharedObjectElement, Element)
+NS_IMPL_RELEASE_INHERITED(HTMLSharedObjectElement, Element)
 
 nsIClassInfo*
-nsHTMLSharedObjectElement::GetClassInfoInternal()
+HTMLSharedObjectElement::GetClassInfoInternal()
 {
   if (mNodeInfo->Equals(nsGkAtoms::applet)) {
     return NS_GetDOMClassInfoInstance(eDOMClassInfo_HTMLAppletElement_id);
   }
   if (mNodeInfo->Equals(nsGkAtoms::embed)) {
     return NS_GetDOMClassInfoInstance(eDOMClassInfo_HTMLEmbedElement_id);
   }
   return nullptr;
 }
 
-NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLSharedObjectElement)
-  NS_HTML_CONTENT_INTERFACE_TABLE_AMBIGUOUS_BEGIN(nsHTMLSharedObjectElement,
+NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLSharedObjectElement)
+  NS_HTML_CONTENT_INTERFACE_TABLE_AMBIGUOUS_BEGIN(HTMLSharedObjectElement,
                                                   nsIDOMHTMLAppletElement)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIRequestObserver)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIStreamListener)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIFrameLoaderOwner)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIObjectLoadingContent)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, imgINotificationObserver)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIImageLoadingContent)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, imgIOnloadBlocker)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIInterfaceRequestor)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIChannelEventSink)
+    NS_INTERFACE_TABLE_ENTRY(HTMLSharedObjectElement, nsIRequestObserver)
+    NS_INTERFACE_TABLE_ENTRY(HTMLSharedObjectElement, nsIStreamListener)
+    NS_INTERFACE_TABLE_ENTRY(HTMLSharedObjectElement, nsIFrameLoaderOwner)
+    NS_INTERFACE_TABLE_ENTRY(HTMLSharedObjectElement, nsIObjectLoadingContent)
+    NS_INTERFACE_TABLE_ENTRY(HTMLSharedObjectElement, imgINotificationObserver)
+    NS_INTERFACE_TABLE_ENTRY(HTMLSharedObjectElement, nsIImageLoadingContent)
+    NS_INTERFACE_TABLE_ENTRY(HTMLSharedObjectElement, imgIOnloadBlocker)
+    NS_INTERFACE_TABLE_ENTRY(HTMLSharedObjectElement, nsIInterfaceRequestor)
+    NS_INTERFACE_TABLE_ENTRY(HTMLSharedObjectElement, nsIChannelEventSink)
   NS_OFFSET_AND_INTERFACE_TABLE_END
-  NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE_AMBIGUOUS(nsHTMLSharedObjectElement,
+  NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE_AMBIGUOUS(HTMLSharedObjectElement,
                                                          nsGenericHTMLElement,
                                                          nsIDOMHTMLAppletElement)
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLAppletElement, applet)
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLEmbedElement, embed)
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMGetSVGDocument, embed)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_GETTER(GetClassInfoInternal)
 NS_HTML_CONTENT_INTERFACE_MAP_END
 
-NS_IMPL_ELEMENT_CLONE(nsHTMLSharedObjectElement)
+NS_IMPL_ELEMENT_CLONE(HTMLSharedObjectElement)
 
 nsresult
-nsHTMLSharedObjectElement::BindToTree(nsIDocument *aDocument,
-                                      nsIContent *aParent,
-                                      nsIContent *aBindingParent,
-                                      bool aCompileEventHandlers)
+HTMLSharedObjectElement::BindToTree(nsIDocument *aDocument,
+                                    nsIContent *aParent,
+                                    nsIContent *aBindingParent,
+                                    bool aCompileEventHandlers)
 {
   nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
                                                  aBindingParent,
                                                  aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = nsObjectLoadingContent::BindToTree(aDocument, aParent,
                                           aBindingParent,
@@ -272,37 +148,37 @@ nsHTMLSharedObjectElement::BindToTree(ns
 
   // Don't kick off load from being bound to a plugin document - the plugin
   // document will call nsObjectLoadingContent::InitializeFromChannel() for the
   // initial load.
   nsCOMPtr<nsIPluginDocument> pluginDoc = do_QueryInterface(aDocument);
 
   // If we already have all the children, start the load.
   if (mIsDoneAddingChildren && !pluginDoc) {
-    void (nsHTMLSharedObjectElement::*start)() =
-      &nsHTMLSharedObjectElement::StartObjectLoad;
+    void (HTMLSharedObjectElement::*start)() =
+      &HTMLSharedObjectElement::StartObjectLoad;
     nsContentUtils::AddScriptRunner(NS_NewRunnableMethod(this, start));
   }
 
   return NS_OK;
 }
 
 void
-nsHTMLSharedObjectElement::UnbindFromTree(bool aDeep,
-                                          bool aNullParent)
+HTMLSharedObjectElement::UnbindFromTree(bool aDeep,
+                                        bool aNullParent)
 {
   nsObjectLoadingContent::UnbindFromTree(aDeep, aNullParent);
   nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
 }
 
 
 nsresult
-nsHTMLSharedObjectElement::SetAttr(int32_t aNameSpaceID, nsIAtom *aName,
-                                   nsIAtom *aPrefix, const nsAString &aValue,
-                                   bool aNotify)
+HTMLSharedObjectElement::SetAttr(int32_t aNameSpaceID, nsIAtom *aName,
+                                 nsIAtom *aPrefix, const nsAString &aValue,
+                                 bool aNotify)
 {
   nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
                                               aValue, aNotify);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // if aNotify is false, we are coming from the parser or some such place;
   // we'll get bound after all the attributes have been set, so we'll do the
   // object load from BindToTree/DoneAddingChildren.
@@ -314,19 +190,19 @@ nsHTMLSharedObjectElement::SetAttr(int32
       aNameSpaceID == kNameSpaceID_None && aName == URIAttrName()) {
     return LoadObject(aNotify, true);
   }
 
   return NS_OK;
 }
 
 bool
-nsHTMLSharedObjectElement::IsHTMLFocusable(bool aWithMouse,
-                                           bool *aIsFocusable,
-                                           int32_t *aTabIndex)
+HTMLSharedObjectElement::IsHTMLFocusable(bool aWithMouse,
+                                         bool *aIsFocusable,
+                                         int32_t *aTabIndex)
 {
   if (mNodeInfo->Equals(nsGkAtoms::embed) || Type() == eType_Plugin) {
     // Has plugin content: let the plugin decide what to do in terms of
     // internal focus from mouse clicks
     if (aTabIndex) {
       GetTabIndex(aTabIndex);
     }
 
@@ -335,47 +211,47 @@ nsHTMLSharedObjectElement::IsHTMLFocusab
     // Let the plugin decide, so override.
     return true;
   }
 
   return nsGenericHTMLElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex);
 }
 
 nsIContent::IMEState
-nsHTMLSharedObjectElement::GetDesiredIMEState()
+HTMLSharedObjectElement::GetDesiredIMEState()
 {
   if (Type() == eType_Plugin) {
     return IMEState(IMEState::PLUGIN);
   }
    
   return nsGenericHTMLElement::GetDesiredIMEState();
 }
 
-NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Align, align)
-NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Alt, alt)
-NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Archive, archive)
-NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Code, code)
-NS_IMPL_URI_ATTR(nsHTMLSharedObjectElement, CodeBase, codebase)
-NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Height, height)
-NS_IMPL_INT_ATTR(nsHTMLSharedObjectElement, Hspace, hspace)
-NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Name, name)
-NS_IMPL_URI_ATTR_WITH_BASE(nsHTMLSharedObjectElement, Object, object, codebase)
-NS_IMPL_URI_ATTR(nsHTMLSharedObjectElement, Src, src)
-NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Type, type)
-NS_IMPL_INT_ATTR(nsHTMLSharedObjectElement, Vspace, vspace)
-NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Width, width)
+NS_IMPL_STRING_ATTR(HTMLSharedObjectElement, Align, align)
+NS_IMPL_STRING_ATTR(HTMLSharedObjectElement, Alt, alt)
+NS_IMPL_STRING_ATTR(HTMLSharedObjectElement, Archive, archive)
+NS_IMPL_STRING_ATTR(HTMLSharedObjectElement, Code, code)
+NS_IMPL_URI_ATTR(HTMLSharedObjectElement, CodeBase, codebase)
+NS_IMPL_STRING_ATTR(HTMLSharedObjectElement, Height, height)
+NS_IMPL_INT_ATTR(HTMLSharedObjectElement, Hspace, hspace)
+NS_IMPL_STRING_ATTR(HTMLSharedObjectElement, Name, name)
+NS_IMPL_URI_ATTR_WITH_BASE(HTMLSharedObjectElement, Object, object, codebase)
+NS_IMPL_URI_ATTR(HTMLSharedObjectElement, Src, src)
+NS_IMPL_STRING_ATTR(HTMLSharedObjectElement, Type, type)
+NS_IMPL_INT_ATTR(HTMLSharedObjectElement, Vspace, vspace)
+NS_IMPL_STRING_ATTR(HTMLSharedObjectElement, Width, width)
 
 int32_t
-nsHTMLSharedObjectElement::TabIndexDefault()
+HTMLSharedObjectElement::TabIndexDefault()
 {
   return -1; 
 }
 
 NS_IMETHODIMP
-nsHTMLSharedObjectElement::GetSVGDocument(nsIDOMDocument **aResult)
+HTMLSharedObjectElement::GetSVGDocument(nsIDOMDocument **aResult)
 {
   NS_ENSURE_ARG_POINTER(aResult);
 
   *aResult = nullptr;
 
   if (!IsInDoc()) {
     return NS_OK;
   }
@@ -385,20 +261,20 @@ nsHTMLSharedObjectElement::GetSVGDocumen
   if (!sub_doc) {
     return NS_OK;
   }
 
   return CallQueryInterface(sub_doc, aResult);
 }
 
 bool
-nsHTMLSharedObjectElement::ParseAttribute(int32_t aNamespaceID,
-                                          nsIAtom *aAttribute,
-                                          const nsAString &aValue,
-                                          nsAttrValue &aResult)
+HTMLSharedObjectElement::ParseAttribute(int32_t aNamespaceID,
+                                        nsIAtom *aAttribute,
+                                        const nsAString &aValue,
+                                        nsAttrValue &aResult)
 {
   if (aNamespaceID == kNameSpaceID_None) {
     if (aAttribute == nsGkAtoms::align) {
       return ParseAlignValue(aValue, aResult);
     }
     if (ParseImageAttribute(aAttribute, aValue, aResult)) {
       return true;
     }
@@ -415,76 +291,106 @@ MapAttributesIntoRule(const nsMappedAttr
   nsGenericHTMLElement::MapImageBorderAttributeInto(aAttributes, aData);
   nsGenericHTMLElement::MapImageMarginAttributeInto(aAttributes, aData);
   nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aData);
   nsGenericHTMLElement::MapImageAlignAttributeInto(aAttributes, aData);
   nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
 }
 
 NS_IMETHODIMP_(bool)
-nsHTMLSharedObjectElement::IsAttributeMapped(const nsIAtom *aAttribute) const
+HTMLSharedObjectElement::IsAttributeMapped(const nsIAtom *aAttribute) const
 {
   static const MappedAttributeEntry* const map[] = {
     sCommonAttributeMap,
     sImageMarginSizeAttributeMap,
     sImageBorderAttributeMap,
     sImageAlignAttributeMap,
   };
 
   return FindAttributeDependence(aAttribute, map);
 }
 
 
 nsMapRuleToAttributesFunc
-nsHTMLSharedObjectElement::GetAttributeMappingFunction() const
+HTMLSharedObjectElement::GetAttributeMappingFunction() const
 {
   return &MapAttributesIntoRule;
 }
 
 void
-nsHTMLSharedObjectElement::StartObjectLoad(bool aNotify)
+HTMLSharedObjectElement::StartObjectLoad(bool aNotify)
 {
   // BindToTree can call us asynchronously, and we may be removed from the tree
   // in the interim
   if (!IsInDoc() || !OwnerDoc()->IsActive()) {
     return;
   }
 
   LoadObject(aNotify);
   SetIsNetworkCreated(false);
 }
 
 nsEventStates
-nsHTMLSharedObjectElement::IntrinsicState() const
+HTMLSharedObjectElement::IntrinsicState() const
 {
   return nsGenericHTMLElement::IntrinsicState() | ObjectState();
 }
 
 uint32_t
-nsHTMLSharedObjectElement::GetCapabilities() const
+HTMLSharedObjectElement::GetCapabilities() const
 {
   uint32_t capabilities = eSupportPlugins | eAllowPluginSkipChannel;
   if (mNodeInfo->Equals(nsGkAtoms::embed)) {
     capabilities |= eSupportSVG | eSupportImages;
   }
 
   return capabilities;
 }
 
 void
-nsHTMLSharedObjectElement::DestroyContent()
+HTMLSharedObjectElement::DestroyContent()
 {
   nsObjectLoadingContent::DestroyContent();
   nsGenericHTMLElement::DestroyContent();
 }
 
 nsresult
-nsHTMLSharedObjectElement::CopyInnerTo(Element* aDest)
+HTMLSharedObjectElement::CopyInnerTo(Element* aDest)
 {
   nsresult rv = nsGenericHTMLElement::CopyInnerTo(aDest);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aDest->OwnerDoc()->IsStaticDocument()) {
-    CreateStaticClone(static_cast<nsHTMLSharedObjectElement*>(aDest));
+    CreateStaticClone(static_cast<HTMLSharedObjectElement*>(aDest));
   }
 
   return rv;
 }
+
+JSObject*
+HTMLSharedObjectElement::WrapNode(JSContext* aCx, JSObject* aScope)
+{
+  JSObject* obj;
+  if (mNodeInfo->Equals(nsGkAtoms::applet)) {
+    obj = HTMLAppletElementBinding::Wrap(aCx, aScope, this);
+  } else {
+    MOZ_ASSERT(mNodeInfo->Equals(nsGkAtoms::embed));
+    obj = HTMLEmbedElementBinding::Wrap(aCx, aScope, this);
+  }
+  if (!obj) {
+    return nullptr;
+  }
+  SetupProtoChain(aCx, obj);
+  return obj;
+}
+
+JSObject*
+HTMLSharedObjectElement::GetCanonicalPrototype(JSContext* aCx, JSObject* aGlobal)
+{
+  if (mNodeInfo->Equals(nsGkAtoms::applet)) {
+    return HTMLAppletElementBinding::GetProtoObject(aCx, aGlobal);
+  }
+  MOZ_ASSERT(mNodeInfo->Equals(nsGkAtoms::embed));
+  return HTMLEmbedElementBinding::GetProtoObject(aCx, aGlobal);
+}
+
+} // namespace dom
+} // namespace mozilla
copy from content/html/content/src/nsHTMLSharedObjectElement.cpp
copy to content/html/content/src/HTMLSharedObjectElement.h
--- a/content/html/content/src/nsHTMLSharedObjectElement.cpp
+++ b/content/html/content/src/HTMLSharedObjectElement.h
@@ -1,45 +1,38 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 // vim:set et sw=2 sts=2 cin:
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "mozilla/Util.h"
+#ifndef mozilla_dom_HTMLSharedObjectElement_h
+#define mozilla_dom_HTMLSharedObjectElement_h
 
 #include "nsGenericHTMLElement.h"
 #include "nsObjectLoadingContent.h"
 #include "nsGkAtoms.h"
 #include "nsError.h"
-#include "nsIDocument.h"
-#include "nsIPluginDocument.h"
-#include "nsIDOMDocument.h"
 #include "nsIDOMHTMLAppletElement.h"
 #include "nsIDOMHTMLEmbedElement.h"
-#include "nsThreadUtils.h"
 #include "nsIDOMGetSVGDocument.h"
-#include "nsIDOMSVGDocument.h"
-#include "nsIScriptError.h"
-#include "nsIWidget.h"
-#include "nsContentUtils.h"
+
+namespace mozilla {
+namespace dom {
 
-using namespace mozilla;
-using namespace mozilla::dom;
-
-class nsHTMLSharedObjectElement : public nsGenericHTMLElement
-                                , public nsObjectLoadingContent
-                                , public nsIDOMHTMLAppletElement
-                                , public nsIDOMHTMLEmbedElement
-                                , public nsIDOMGetSVGDocument
+class HTMLSharedObjectElement : public nsGenericHTMLElement
+                              , public nsObjectLoadingContent
+                              , public nsIDOMHTMLAppletElement
+                              , public nsIDOMHTMLEmbedElement
+                              , public nsIDOMGetSVGDocument
 {
 public:
-  nsHTMLSharedObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                            mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
-  virtual ~nsHTMLSharedObjectElement();
+  HTMLSharedObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
+                          mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
+  virtual ~HTMLSharedObjectElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
@@ -93,29 +86,137 @@ public:
   virtual uint32_t GetCapabilities() const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   nsresult CopyInnerTo(Element* aDest);
 
   void StartObjectLoad() { StartObjectLoad(true); }
 
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLSharedObjectElement,
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(HTMLSharedObjectElement,
                                                      nsGenericHTMLElement)
 
   virtual nsXPCClassInfo* GetClassInfo()
   {
     return static_cast<nsXPCClassInfo*>(GetClassInfoInternal());
   }
   nsIClassInfo* GetClassInfoInternal();
 
   virtual nsIDOMNode* AsDOMNode()
   {
     return static_cast<nsIDOMHTMLAppletElement*>(this);
   }
+
+  // WebIDL API for <applet>
+  void GetAlign(DOMString& aValue)
+  {
+    GetHTMLAttr(nsGkAtoms::align, aValue);
+  }
+  void SetAlign(const nsAString& aValue, ErrorResult& aRv)
+  {
+    SetHTMLAttr(nsGkAtoms::align, aValue, aRv);
+  }
+  void GetAlt(DOMString& aValue)
+  {
+    GetHTMLAttr(nsGkAtoms::alt, aValue);
+  }
+  void SetAlt(const nsAString& aValue, ErrorResult& aRv)
+  {
+    SetHTMLAttr(nsGkAtoms::alt, aValue, aRv);
+  }
+  void GetArchive(DOMString& aValue)
+  {
+    GetHTMLAttr(nsGkAtoms::archive, aValue);
+  }
+  void SetArchive(const nsAString& aValue, ErrorResult& aRv)
+  {
+    SetHTMLAttr(nsGkAtoms::archive, aValue, aRv);
+  }
+  void GetCode(DOMString& aValue)
+  {
+    GetHTMLAttr(nsGkAtoms::code, aValue);
+  }
+  void SetCode(const nsAString& aValue, ErrorResult& aRv)
+  {
+    SetHTMLAttr(nsGkAtoms::code, aValue, aRv);
+  }
+  // XPCOM GetCodebase is ok; note that it's a URI attribute
+  void SetCodeBase(const nsAString& aValue, ErrorResult& aRv)
+  {
+    SetHTMLAttr(nsGkAtoms::codebase, aValue, aRv);
+  }
+  void GetHeight(DOMString& aValue)
+  {
+    GetHTMLAttr(nsGkAtoms::height, aValue);
+  }
+  void SetHeight(const nsAString& aValue, ErrorResult& aRv)
+  {
+    SetHTMLAttr(nsGkAtoms::height, aValue, aRv);
+  }
+  uint32_t Hspace()
+  {
+    return GetHTMLUnsignedIntAttr(nsGkAtoms::hspace, 0);
+  }
+  void SetHspace(uint32_t aValue, ErrorResult& aRv)
+  {
+    SetHTMLUnsignedIntAttr(nsGkAtoms::hspace, aValue, aRv);
+  }
+  void GetName(DOMString& aValue)
+  {
+    GetHTMLAttr(nsGkAtoms::name, aValue);
+  }
+  void SetName(const nsAString& aValue, ErrorResult& aRv)
+  {
+    SetHTMLAttr(nsGkAtoms::name, aValue, aRv);
+  }
+  // XPCOM GetObject is ok; note that it's a URI attribute with a weird base URI
+  void SetObject(const nsAString& aValue, ErrorResult& aRv)
+  {
+    SetHTMLAttr(nsGkAtoms::object, aValue, aRv);
+  }
+    uint32_t Vspace()
+  {
+    return GetHTMLUnsignedIntAttr(nsGkAtoms::vspace, 0);
+  }
+  void SetVspace(uint32_t aValue, ErrorResult& aRv)
+  {
+    SetHTMLUnsignedIntAttr(nsGkAtoms::vspace, aValue, aRv);
+  }
+  void GetWidth(DOMString& aValue)
+  {
+    GetHTMLAttr(nsGkAtoms::width, aValue);
+  }
+  void SetWidth(const nsAString& aValue, ErrorResult& aRv)
+  {
+    SetHTMLAttr(nsGkAtoms::width, aValue, aRv);
+  }
+
+  // WebIDL <embed> api
+  // XPCOM GetSrc is ok; note that it's a URI attribute
+  void SetSrc(const nsAString& aValue, ErrorResult& aRv)
+  {
+    SetHTMLAttr(nsGkAtoms::src, aValue, aRv);
+  }
+  void GetType(DOMString& aValue)
+  {
+    GetHTMLAttr(nsGkAtoms::type, aValue);
+  }
+  void SetType(const nsAString& aValue, ErrorResult& aRv)
+  {
+    SetHTMLAttr(nsGkAtoms::type, aValue, aRv);
+  }
+  // width covered by <applet>
+  // height covered by <applet>
+  // align covered by <applet>
+  // name covered by <applet>
+  nsIDocument* GetSVGDocument()
+  {
+    return GetContentDocument();
+  }
+
 private:
   /**
    * Calls LoadObject with the correct arguments to start the plugin load.
    */
   NS_HIDDEN_(void) StartObjectLoad(bool aNotify);
 
   void GetTypeAttrValue(nsCString &aValue) const
   {
@@ -138,353 +239,18 @@ private:
   }
 
   // mIsDoneAddingChildren is only really used for <applet>.  This boolean is
   // always true for <embed>, per the documentation in nsIContent.h.
   bool mIsDoneAddingChildren;
 
   virtual void GetItemValueText(nsAString& text);
   virtual void SetItemValueText(const nsAString& text);
+
+  virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope) MOZ_OVERRIDE;
+  virtual JSObject* GetCanonicalPrototype(JSContext* aCx,
+                                          JSObject* aGlobal) MOZ_OVERRIDE;
 };
 
-
-NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(SharedObject)
-
-
-nsHTMLSharedObjectElement::nsHTMLSharedObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                                     FromParser aFromParser)
-  : nsGenericHTMLElement(aNodeInfo),
-    mIsDoneAddingChildren(mNodeInfo->Equals(nsGkAtoms::embed) || !aFromParser)
-{
-  RegisterFreezableElement();
-  SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK);
-
-  // By default we're in the loading state
-  AddStatesSilently(NS_EVENT_STATE_LOADING);
-}
-
-void
-nsHTMLSharedObjectElement::GetItemValueText(nsAString& aValue)
-{
-  if (mNodeInfo->Equals(nsGkAtoms::applet)) {
-    nsGenericHTMLElement::GetItemValueText(aValue);
-  } else {
-    GetSrc(aValue);
-  }
-}
-
-void
-nsHTMLSharedObjectElement::SetItemValueText(const nsAString& aValue)
-{
-  if (mNodeInfo->Equals(nsGkAtoms::applet)) {
-    nsGenericHTMLElement::SetItemValueText(aValue);
-  } else {
-    SetSrc(aValue);
-  }
-}
-
-nsHTMLSharedObjectElement::~nsHTMLSharedObjectElement()
-{
-  UnregisterFreezableElement();
-  DestroyImageLoadingContent();
-}
-
-bool
-nsHTMLSharedObjectElement::IsDoneAddingChildren()
-{
-  return mIsDoneAddingChildren;
-}
-
-void
-nsHTMLSharedObjectElement::DoneAddingChildren(bool aHaveNotified)
-{
-  if (!mIsDoneAddingChildren) {
-    mIsDoneAddingChildren = true;
-
-    // If we're already in a document, we need to trigger the load
-    // Otherwise, BindToTree takes care of that.
-    if (IsInDoc()) {
-      StartObjectLoad(aHaveNotified);
-    }
-  }
-}
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLSharedObjectElement,
-                                                  nsGenericHTMLElement)
-  nsObjectLoadingContent::Traverse(tmp, cb);
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_ADDREF_INHERITED(nsHTMLSharedObjectElement, Element)
-NS_IMPL_RELEASE_INHERITED(nsHTMLSharedObjectElement, Element)
-
-DOMCI_DATA(HTMLAppletElement, nsHTMLSharedObjectElement)
-DOMCI_DATA(HTMLEmbedElement, nsHTMLSharedObjectElement)
-
-nsIClassInfo*
-nsHTMLSharedObjectElement::GetClassInfoInternal()
-{
-  if (mNodeInfo->Equals(nsGkAtoms::applet)) {
-    return NS_GetDOMClassInfoInstance(eDOMClassInfo_HTMLAppletElement_id);
-  }
-  if (mNodeInfo->Equals(nsGkAtoms::embed)) {
-    return NS_GetDOMClassInfoInstance(eDOMClassInfo_HTMLEmbedElement_id);
-  }
-  return nullptr;
-}
-
-NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLSharedObjectElement)
-  NS_HTML_CONTENT_INTERFACE_TABLE_AMBIGUOUS_BEGIN(nsHTMLSharedObjectElement,
-                                                  nsIDOMHTMLAppletElement)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIRequestObserver)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIStreamListener)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIFrameLoaderOwner)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIObjectLoadingContent)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, imgINotificationObserver)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIImageLoadingContent)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, imgIOnloadBlocker)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIInterfaceRequestor)
-    NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIChannelEventSink)
-  NS_OFFSET_AND_INTERFACE_TABLE_END
-  NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE_AMBIGUOUS(nsHTMLSharedObjectElement,
-                                                         nsGenericHTMLElement,
-                                                         nsIDOMHTMLAppletElement)
-  NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLAppletElement, applet)
-  NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLEmbedElement, embed)
-  NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMGetSVGDocument, embed)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_GETTER(GetClassInfoInternal)
-NS_HTML_CONTENT_INTERFACE_MAP_END
-
-NS_IMPL_ELEMENT_CLONE(nsHTMLSharedObjectElement)
-
-nsresult
-nsHTMLSharedObjectElement::BindToTree(nsIDocument *aDocument,
-                                      nsIContent *aParent,
-                                      nsIContent *aBindingParent,
-                                      bool aCompileEventHandlers)
-{
-  nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
-                                                 aBindingParent,
-                                                 aCompileEventHandlers);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = nsObjectLoadingContent::BindToTree(aDocument, aParent,
-                                          aBindingParent,
-                                          aCompileEventHandlers);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Don't kick off load from being bound to a plugin document - the plugin
-  // document will call nsObjectLoadingContent::InitializeFromChannel() for the
-  // initial load.
-  nsCOMPtr<nsIPluginDocument> pluginDoc = do_QueryInterface(aDocument);
-
-  // If we already have all the children, start the load.
-  if (mIsDoneAddingChildren && !pluginDoc) {
-    void (nsHTMLSharedObjectElement::*start)() =
-      &nsHTMLSharedObjectElement::StartObjectLoad;
-    nsContentUtils::AddScriptRunner(NS_NewRunnableMethod(this, start));
-  }
-
-  return NS_OK;
-}
-
-void
-nsHTMLSharedObjectElement::UnbindFromTree(bool aDeep,
-                                          bool aNullParent)
-{
-  nsObjectLoadingContent::UnbindFromTree(aDeep, aNullParent);
-  nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
-}
-
-
-nsresult
-nsHTMLSharedObjectElement::SetAttr(int32_t aNameSpaceID, nsIAtom *aName,
-                                   nsIAtom *aPrefix, const nsAString &aValue,
-                                   bool aNotify)
-{
-  nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
-                                              aValue, aNotify);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // if aNotify is false, we are coming from the parser or some such place;
-  // we'll get bound after all the attributes have been set, so we'll do the
-  // object load from BindToTree/DoneAddingChildren.
-  // Skip the LoadObject call in that case.
-  // We also don't want to start loading the object when we're not yet in
-  // a document, just in case that the caller wants to set additional
-  // attributes before inserting the node into the document.
-  if (aNotify && IsInDoc() && mIsDoneAddingChildren &&
-      aNameSpaceID == kNameSpaceID_None && aName == URIAttrName()) {
-    return LoadObject(aNotify, true);
-  }
+} // namespace dom
+} // namespace mozilla
 
-  return NS_OK;
-}
-
-bool
-nsHTMLSharedObjectElement::IsHTMLFocusable(bool aWithMouse,
-                                           bool *aIsFocusable,
-                                           int32_t *aTabIndex)
-{
-  if (mNodeInfo->Equals(nsGkAtoms::embed) || Type() == eType_Plugin) {
-    // Has plugin content: let the plugin decide what to do in terms of
-    // internal focus from mouse clicks
-    if (aTabIndex) {
-      GetTabIndex(aTabIndex);
-    }
-
-    *aIsFocusable = true;
-
-    // Let the plugin decide, so override.
-    return true;
-  }
-
-  return nsGenericHTMLElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex);
-}
-
-nsIContent::IMEState
-nsHTMLSharedObjectElement::GetDesiredIMEState()
-{
-  if (Type() == eType_Plugin) {
-    return IMEState(IMEState::PLUGIN);
-  }
-   
-  return nsGenericHTMLElement::GetDesiredIMEState();
-}
-
-NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Align, align)
-NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Alt, alt)
-NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Archive, archive)
-NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Code, code)
-NS_IMPL_URI_ATTR(nsHTMLSharedObjectElement, CodeBase, codebase)
-NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Height, height)
-NS_IMPL_INT_ATTR(nsHTMLSharedObjectElement, Hspace, hspace)
-NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Name, name)
-NS_IMPL_URI_ATTR_WITH_BASE(nsHTMLSharedObjectElement, Object, object, codebase)
-NS_IMPL_URI_ATTR(nsHTMLSharedObjectElement, Src, src)
-NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Type, type)
-NS_IMPL_INT_ATTR(nsHTMLSharedObjectElement, Vspace, vspace)
-NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Width, width)
-
-int32_t
-nsHTMLSharedObjectElement::TabIndexDefault()
-{
-  return -1; 
-}
-
-NS_IMETHODIMP
-nsHTMLSharedObjectElement::GetSVGDocument(nsIDOMDocument **aResult)
-{
-  NS_ENSURE_ARG_POINTER(aResult);
-
-  *aResult = nullptr;
-
-  if (!IsInDoc()) {
-    return NS_OK;
-  }
-
-  // XXXbz should this use GetCurrentDoc()?  sXBL/XBL2 issue!
-  nsIDocument *sub_doc = OwnerDoc()->GetSubDocumentFor(this);
-  if (!sub_doc) {
-    return NS_OK;
-  }
-
-  return CallQueryInterface(sub_doc, aResult);
-}
-
-bool
-nsHTMLSharedObjectElement::ParseAttribute(int32_t aNamespaceID,
-                                          nsIAtom *aAttribute,
-                                          const nsAString &aValue,
-                                          nsAttrValue &aResult)
-{
-  if (aNamespaceID == kNameSpaceID_None) {
-    if (aAttribute == nsGkAtoms::align) {
-      return ParseAlignValue(aValue, aResult);
-    }
-    if (ParseImageAttribute(aAttribute, aValue, aResult)) {
-      return true;
-    }
-  }
-
-  return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
-                                              aResult);
-}
-
-static void
-MapAttributesIntoRule(const nsMappedAttributes *aAttributes,
-                      nsRuleData *aData)
-{
-  nsGenericHTMLElement::MapImageBorderAttributeInto(aAttributes, aData);
-  nsGenericHTMLElement::MapImageMarginAttributeInto(aAttributes, aData);
-  nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aData);
-  nsGenericHTMLElement::MapImageAlignAttributeInto(aAttributes, aData);
-  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
-}
-
-NS_IMETHODIMP_(bool)
-nsHTMLSharedObjectElement::IsAttributeMapped(const nsIAtom *aAttribute) const
-{
-  static const MappedAttributeEntry* const map[] = {
-    sCommonAttributeMap,
-    sImageMarginSizeAttributeMap,
-    sImageBorderAttributeMap,
-    sImageAlignAttributeMap,
-  };
-
-  return FindAttributeDependence(aAttribute, map);
-}
-
-
-nsMapRuleToAttributesFunc
-nsHTMLSharedObjectElement::GetAttributeMappingFunction() const
-{
-  return &MapAttributesIntoRule;
-}
-
-void
-nsHTMLSharedObjectElement::StartObjectLoad(bool aNotify)
-{
-  // BindToTree can call us asynchronously, and we may be removed from the tree
-  // in the interim
-  if (!IsInDoc() || !OwnerDoc()->IsActive()) {
-    return;
-  }
-
-  LoadObject(aNotify);
-  SetIsNetworkCreated(false);
-}
-
-nsEventStates
-nsHTMLSharedObjectElement::IntrinsicState() const
-{
-  return nsGenericHTMLElement::IntrinsicState() | ObjectState();
-}
-
-uint32_t
-nsHTMLSharedObjectElement::GetCapabilities() const
-{
-  uint32_t capabilities = eSupportPlugins | eAllowPluginSkipChannel;
-  if (mNodeInfo->Equals(nsGkAtoms::embed)) {
-    capabilities |= eSupportSVG | eSupportImages;
-  }
-
-  return capabilities;
-}
-
-void
-nsHTMLSharedObjectElement::DestroyContent()
-{
-  nsObjectLoadingContent::DestroyContent();
-  nsGenericHTMLElement::DestroyContent();
-}
-
-nsresult
-nsHTMLSharedObjectElement::CopyInnerTo(Element* aDest)
-{
-  nsresult rv = nsGenericHTMLElement::CopyInnerTo(aDest);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (aDest->OwnerDoc()->IsStaticDocument()) {
-    CreateStaticClone(static_cast<nsHTMLSharedObjectElement*>(aDest));
-  }
-
-  return rv;
-}
+#endif // mozilla_dom_HTMLSharedObjectElement_h
--- a/content/html/content/src/HTMLStyleElement.cpp
+++ b/content/html/content/src/HTMLStyleElement.cpp
@@ -56,57 +56,44 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(HTMLStyleElement,
                                                nsGenericHTMLElement)
 NS_HTML_CONTENT_INTERFACE_MAP_END
 
 NS_IMPL_ELEMENT_CLONE(HTMLStyleElement)
 
 
 NS_IMETHODIMP
-HTMLStyleElement::GetDisabled(bool* aDisabled)
+HTMLStyleElement::GetMozDisabled(bool* aDisabled)
 {
   NS_ENSURE_ARG_POINTER(aDisabled);
 
   *aDisabled = Disabled();
   return NS_OK;
 }
 
 bool
 HTMLStyleElement::Disabled()
 {
-  nsCOMPtr<nsIDOMStyleSheet> ss = do_QueryInterface(GetSheet());
-  if (!ss) {
-    return false;
-  }
-
-  bool disabled = false;
-  ss->GetDisabled(&disabled);
-
-  return disabled;
+  nsCSSStyleSheet* ss = GetSheet();
+  return ss && ss->Disabled();
 }
 
 NS_IMETHODIMP
-HTMLStyleElement::SetDisabled(bool aDisabled)
+HTMLStyleElement::SetMozDisabled(bool aDisabled)
 {
-  ErrorResult error;
-  SetDisabled(aDisabled, error);
-  return error.ErrorCode();
+  SetDisabled(aDisabled);
+  return NS_OK;
 }
 
 void
-HTMLStyleElement::SetDisabled(bool aDisabled, ErrorResult& aError)
+HTMLStyleElement::SetDisabled(bool aDisabled)
 {
-  nsCOMPtr<nsIDOMStyleSheet> ss = do_QueryInterface(GetSheet());
-  if (!ss) {
-    return;
-  }
-
-  nsresult result = ss->SetDisabled(aDisabled);
-  if (NS_FAILED(result)) {
-    aError.Throw(result);
+  nsCSSStyleSheet* ss = GetSheet();
+  if (ss) {
+    ss->SetDisabled(aDisabled);
   }
 }
 
 NS_IMPL_STRING_ATTR(HTMLStyleElement, Media, media)
 NS_IMPL_BOOL_ATTR(HTMLStyleElement, Scoped, scoped)
 NS_IMPL_STRING_ATTR(HTMLStyleElement, Type, type)
 
 void
--- a/content/html/content/src/HTMLStyleElement.h
+++ b/content/html/content/src/HTMLStyleElement.h
@@ -69,17 +69,17 @@ public:
 
   // nsIMutationObserver
   NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
 
   bool Disabled();
-  void SetDisabled(bool aDisabled, ErrorResult& aError);
+  void SetDisabled(bool aDisabled);
   void SetMedia(const nsAString& aMedia, ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::media, aMedia, aError);
   }
   void SetType(const nsAString& aType, ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::type, aType, aError);
   }
--- a/content/html/content/src/Makefile.in
+++ b/content/html/content/src/Makefile.in
@@ -60,16 +60,17 @@ EXPORTS_mozilla/dom = \
 		HTMLOptGroupElement.h \
 		HTMLOutputElement.h \
 		HTMLParagraphElement.h \
 		HTMLPreElement.h \
 		HTMLProgressElement.h \
 		HTMLScriptElement.h \
 		HTMLSharedElement.h \
 		HTMLSharedListElement.h \
+		HTMLSharedObjectElement.h \
 		HTMLSpanElement.h \
 		HTMLStyleElement.h \
 		HTMLTableCaptionElement.h \
 		HTMLTableCellElement.h \
 		HTMLTableColElement.h \
 		HTMLTableElement.h \
 		HTMLTableRowElement.h \
 		HTMLTableSectionElement.h \
@@ -116,17 +117,17 @@ CPPSRCS		= \
 		HTMLLinkElement.cpp \
 		HTMLMapElement.cpp \
 		HTMLMenuElement.cpp \
 		HTMLMenuItemElement.cpp \
 		HTMLMetaElement.cpp \
 		HTMLMeterElement.cpp \
 		HTMLModElement.cpp \
 		HTMLObjectElement.cpp \
-		nsHTMLSharedObjectElement.cpp \
+		HTMLSharedObjectElement.cpp \
 		HTMLOptionElement.cpp \
 		HTMLOptionsCollection.cpp \
 		HTMLOptGroupElement.cpp \
 		HTMLOutputElement.cpp \
 		HTMLParagraphElement.cpp \
 		HTMLPreElement.cpp \
 		HTMLProgressElement.cpp \
 		HTMLScriptElement.cpp \
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -242,16 +242,19 @@ MOCHITEST_FILES = \
 		file_fullscreen-esc-exit.html \
 		file_fullscreen-esc-exit-inner.html \
 		file_fullscreen-rollback.html \
 		file_fullscreen-svg-element.html \
 		file_fullscreen-multiple.html \
 		file_fullscreen-multiple-inner.html \
 		test_li_attributes_reflection.html \
 		test_link_attributes_reflection.html \
+		test_object_attributes_reflection.html \
+		test_embed_attributes_reflection.html \
+		test_applet_attributes_reflection.html \
 		test_ol_attributes_reflection.html \
 		test_dl_attributes_reflection.html \
 		test_ul_attributes_reflection.html \
 		test_param_attributes_reflection.html \
 		test_base_attributes_reflection.html \
 		test_dir_attributes_reflection.html \
 		test_q_attributes_reflection.html \
 		test_html_attributes_reflection.html \
--- a/content/html/content/test/reflect.js
+++ b/content/html/content/test/reflect.js
@@ -16,65 +16,76 @@
  * Checks that a given attribute is correctly reflected as a string.
  *
  * @param aParameters   Object    object containing the parameters, which are:
  *  - element           Element   node to test
  *  - attribute         String    name of the attribute
  *     OR
  *    attribute         Object    object containing two attributes, 'content' and 'idl'
  *  - otherValues       Array     [optional] other values to test in addition of the default ones
+ *  - extendedAttributes Object   object which can have 'TreatNullAs': "EmptyString"
  */
 function reflectString(aParameters)
 {
   var element = aParameters.element;
   var contentAttr = typeof aParameters.attribute === "string"
                       ? aParameters.attribute : aParameters.attribute.content;
   var idlAttr = typeof aParameters.attribute === "string"
                   ? aParameters.attribute : aParameters.attribute.idl;
   var otherValues = aParameters.otherValues !== undefined
                       ? aParameters.otherValues : [];
+  var treatNullAs = aParameters.extendedAttributes ?
+        aParameters.extendedAttributes.TreatNullAs : null;
 
   ok(idlAttr in element,
      idlAttr + " should be an IDL attribute of this element");
   is(typeof element[idlAttr], "string",
-     idlAttr + " IDL attribute should be a string");
+     "'" + idlAttr + "' IDL attribute should be a string");
 
   // Tests when the attribute isn't set.
   is(element.getAttribute(contentAttr), null,
      "When not set, the content attribute should be null.");
   is(element[idlAttr], "",
      "When not set, the IDL attribute should return the empty string");
 
   /**
    * TODO: as long as null stringification doesn't follow the WebIDL
    * specifications, don't add it to the loop below and keep it here.
    */
   element.setAttribute(contentAttr, null);
   is(element.getAttribute(contentAttr), "null",
-     "null should have been stringified to 'null'");
+     "null should have been stringified to 'null' for '" + contentAttr + "'");
   is(element[idlAttr], "null",
-     "null should have been stringified to 'null'");
+      "null should have been stringified to 'null' for '" + idlAttr + "'");
   element.removeAttribute(contentAttr);
 
   element[idlAttr] = null;
   // TODO: remove this ugly hack when null stringification will work as expected.
   var todoAttrs = {
     form: [ "acceptCharset", "name", "target" ],
     input: [ "accept", "alt", "formTarget", "max", "min", "name", "pattern", "placeholder", "step", "defaultValue" ]
   };
   if (!(element.localName in todoAttrs) || todoAttrs[element.localName].indexOf(idlAttr) == -1) {
-    is(element.getAttribute(contentAttr), "null",
-       "null should have been stringified to 'null'");
-    is(element[idlAttr], "null", "null should have been stringified to 'null'");
+    if (treatNullAs == "EmptyString") {
+      is(element.getAttribute(contentAttr), "",
+         "null should have been stringified to '' for '" + contentAttr + "'");
+      is(element[idlAttr], "",
+         "null should have been stringified to '' for '" + idlAttr + "'");
+    } else {
+      is(element.getAttribute(contentAttr), "null",
+         "null should have been stringified to 'null' for '" + contentAttr + "'");
+      is(element[idlAttr], "null",
+         "null should have been stringified to 'null' for '" + contentAttr + "'");
+    }
     element.removeAttribute(contentAttr);
   } else {
     todo_is(element.getAttribute(contentAttr), "null",
-       "null should have been stringified to 'null'");
+       "null should have been stringified to 'null' for '" + contentAttr + "'");
     todo_is(element[idlAttr], "null",
-       "null should have been stringified to 'null'");
+       "null should have been stringified to 'null' for '" + contentAttr + "'");
     element.removeAttribute(contentAttr);
   }
 
   // Tests various strings.
   var stringsToTest = [
     // [ test value, expected result ]
     [ "", "" ],
     [ "null", "null" ],
@@ -101,26 +112,26 @@ function reflectString(aParameters)
       "bar" ]
   ];
 
   otherValues.forEach(function(v) { stringsToTest.push([v, v]) });
 
   stringsToTest.forEach(function([v, r]) {
     element.setAttribute(contentAttr, v);
     is(element[idlAttr], r,
-       "IDL attribute should return the value it has been set to.");
+       "IDL attribute '" + idlAttr + "' should return the value it has been set to.");
     is(element.getAttribute(contentAttr), r,
-       "Content attribute should return the value it has been set to.");
+       "Content attribute '" + contentAttr + "'should return the value it has been set to.");
     element.removeAttribute(contentAttr);
 
     element[idlAttr] = v;
     is(element[idlAttr], r,
-       "IDL attribute should return the value it has been set to.");
+       "IDL attribute '" + idlAttr + "' should return the value it has been set to.");
     is(element.getAttribute(contentAttr), r,
-       "Content attribute should return the value it has been set to.");
+       "Content attribute '" + contentAttr + "' should return the value it has been set to.");
     element.removeAttribute(contentAttr);
   });
 
   // Tests after removeAttribute() is called. Should be equivalent with not set.
   is(element.getAttribute(contentAttr), null,
      "When not set, the content attribute should be null.");
   is(element[idlAttr], "",
      "When not set, the IDL attribute should return the empty string");
@@ -265,17 +276,17 @@ function reflectLimitedEnumerated(aParam
                                    ? aParameters.defaultValue : aParameters.defaultValue.invalid
   var defaultValueMissing = aParameters.defaultValue === undefined
                                 ? "" : typeof aParameters.defaultValue === "string"
                                     ? aParameters.defaultValue : aParameters.defaultValue.missing
   var unsupportedValues = aParameters.unsupportedValues !== undefined
                             ? aParameters.unsupportedValues : [];
 
   ok(idlAttr in element, idlAttr + " should be an IDL attribute of this element");
-  is(typeof element[idlAttr], "string", idlAttr + " IDL attribute should be a string");
+  is(typeof element[idlAttr], "string", "'" + idlAttr + "' IDL attribute should be a string");
 
   // Explicitly check the default value.
   element.removeAttribute(contentAttr);
   is(element[idlAttr], defaultValueMissing,
      "When no attribute is set, the value should be the default value.");
 
   // Check valid values.
   validValues.forEach(function (v) {
@@ -593,15 +604,15 @@ function reflectInt(aParameters)
  *  - attribute         String    name of the attribute
  *     OR
  *    attribute         Object    object containing two attributes, 'content' and 'idl'
  */
 function reflectURL(aParameters)
 {
   var element = aParameters.element;
   var contentAttr = typeof aParameters.attribute === "string"
-	              ? aParameters.attribute : aParameters.attribute.content;
+                      ? aParameters.attribute : aParameters.attribute.content;
   var idlAttr = typeof aParameters.attribute === "string"
                   ? aParameters.attribute : aParameters.attribute.idl;
 
   element[idlAttr] = "";
   is(element[idlAttr], document.URL, "Empty string should resolve to document URL");
 }
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_applet_attributes_reflection.html
@@ -0,0 +1,86 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for HTMLAppletElement attributes reflection</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="reflect.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for HTMLAppletElement attributes reflection **/
+
+// .align (String)
+reflectString({
+  element: document.createElement("applet"),
+  attribute: "align",
+});
+
+// .alt (String)
+reflectString({
+  element: document.createElement("applet"),
+  attribute: "alt",
+});
+
+// .archive (String)
+reflectString({
+  element: document.createElement("applet"),
+  attribute: "archive",
+});
+
+// .code (String)
+reflectString({
+  element: document.createElement("applet"),
+  attribute: "code",
+});
+
+// .codeBase (URL)
+reflectURL({
+  element: document.createElement("applet"),
+  attribute: "codeBase",
+});
+
+// .height (String)
+reflectString({
+  element: document.createElement("applet"),
+  attribute: "height",
+});
+
+// .hspace (unsigned int)
+reflectUnsignedInt({
+  element: document.createElement("applet"),
+  attribute: "hspace",
+});
+
+// .name (String)
+reflectString({
+  element: document.createElement("applet"),
+  attribute: "name",
+});
+
+// .object (URL)
+reflectURL({
+  element: document.createElement("applet"),
+  attribute: "object",
+});
+
+// .vspace (unsigned int)
+reflectUnsignedInt({
+  element: document.createElement("applet"),
+  attribute: "vspace",
+});
+
+// .width (String)
+reflectString({
+  element: document.createElement("applet"),
+  attribute: "width",
+});
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_embed_attributes_reflection.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for HTMLEmbedElement attributes reflection</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="reflect.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for HTMLEmbedElement attributes reflection **/
+
+// .src (URL)
+reflectURL({
+  element: document.createElement("embed"),
+  attribute: "src",
+});
+
+// .type (String)
+reflectString({
+  element: document.createElement("embed"),
+  attribute: "type",
+});
+
+// .width (String)
+reflectString({
+  element: document.createElement("embed"),
+  attribute: "width",
+});
+
+// .height (String)
+reflectString({
+  element: document.createElement("embed"),
+  attribute: "height",
+});
+
+// .align (String)
+reflectString({
+  element: document.createElement("embed"),
+  attribute: "align",
+});
+
+// .name (String)
+reflectString({
+  element: document.createElement("embed"),
+  attribute: "name",
+});
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_object_attributes_reflection.html
@@ -0,0 +1,117 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for HTMLObjectElement attributes reflection</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="reflect.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for HTMLObjectElement attributes reflection **/
+
+// .data (URL)
+reflectURL({
+  element: document.createElement("object"),
+  attribute: "data",
+});
+
+// .type (String)
+reflectString({
+  element: document.createElement("object"),
+  attribute: "type",
+});
+
+// .name (String)
+reflectString({
+  element: document.createElement("object"),
+  attribute: "name",
+});
+
+// .useMap (String)
+reflectString({
+  element: document.createElement("object"),
+  attribute: "useMap",
+});
+
+// .width (String)
+reflectString({
+  element: document.createElement("object"),
+  attribute: "width",
+});
+
+// .height (String)
+reflectString({
+  element: document.createElement("object"),
+  attribute: "height",
+});
+
+// .align (String)
+reflectString({
+  element: document.createElement("object"),
+  attribute: "align",
+});
+
+// .archive (String)
+reflectString({
+  element: document.createElement("object"),
+  attribute: "archive",
+});
+
+// .code (URL)
+reflectURL({
+  element: document.createElement("object"),
+  attribute: "code",
+});
+
+// .declare (String)
+reflectBoolean({
+  element: document.createElement("object"),
+  attribute: "declare",
+});
+
+// .hspace (unsigned int)
+reflectUnsignedInt({
+  element: document.createElement("object"),
+  attribute: "hspace",
+});
+
+// .standby (String)
+reflectString({
+  element: document.createElement("object"),
+  attribute: "standby",
+});
+
+// .vspace (unsigned int)
+reflectUnsignedInt({
+  element: document.createElement("object"),
+  attribute: "vspace",
+});
+
+// .codeBase (URL)
+reflectURL({
+  element: document.createElement("object"),
+  attribute: "codeBase",
+});
+
+// .codeType (String)
+reflectString({
+  element: document.createElement("object"),
+  attribute: "codeType",
+});
+
+// .border (String)
+reflectString({
+  element: document.createElement("object"),
+  attribute: "border",
+  extendedAttributes: { TreatNullAs: "EmptyString" },
+});
+</script>
+</pre>
+</body>
+</html>
deleted file mode 100644
--- a/content/html/document/Makefile.in
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/config/rules.mk
-
--- a/content/media/AudioNodeStream.cpp
+++ b/content/media/AudioNodeStream.cpp
@@ -179,22 +179,22 @@ AudioNodeStream::EnsureTrack()
 AudioChunk*
 AudioNodeStream::ObtainInputBlock(AudioChunk* aTmpChunk)
 {
   uint32_t inputCount = mInputs.Length();
   uint32_t outputChannelCount = 0;
   nsAutoTArray<AudioChunk*,250> inputChunks;
   for (uint32_t i = 0; i < inputCount; ++i) {
     MediaStream* s = mInputs[i]->GetSource();
-    AudioNodeStream* a = s->AsAudioNodeStream();
-    MOZ_ASSERT(a);
+    AudioNodeStream* a = static_cast<AudioNodeStream*>(s);
+    MOZ_ASSERT(a == s->AsAudioNodeStream());
     if (a->IsFinishedOnGraphThread()) {
       continue;
     }
-    AudioChunk* chunk = a->mLastChunk;
+    AudioChunk* chunk = &a->mLastChunk;
     // XXX when we implement DelayNode, this will no longer be true and we'll
     // need to treat a null chunk (when the DelayNode hasn't had a chance
     // to produce data yet) as silence here.
     MOZ_ASSERT(chunk);
     if (chunk->IsNull()) {
       continue;
     }
 
@@ -263,21 +263,26 @@ AudioNodeStream::ProduceOutput(GraphTime
     AudioChunk* inputChunk = ObtainInputBlock(&tmpChunk);
     bool finished = false;
     mEngine->ProduceAudioBlock(this, *inputChunk, &outputChunk, &finished);
     if (finished) {
       FinishOutput();
     }
   }
 
-  mLastChunk = segment->AppendAndConsumeChunk(&outputChunk);
+  mLastChunk = outputChunk;
+  if (mKind == MediaStreamGraph::EXTERNAL_STREAM) {
+    segment->AppendAndConsumeChunk(&outputChunk);
+  } else {
+    segment->AppendNullData(outputChunk.GetDuration());
+  }
 
   for (uint32_t j = 0; j < mListeners.Length(); ++j) {
     MediaStreamListener* l = mListeners[j];
-    AudioChunk copyChunk = *mLastChunk;
+    AudioChunk copyChunk = outputChunk;
     AudioSegment tmpSegment;
     tmpSegment.AppendAndConsumeChunk(&copyChunk);
     l->NotifyQueuedTrackChanges(Graph(), AUDIO_NODE_STREAM_TRACK_ID,
                                 IdealAudioRate(), segment->GetDuration(), 0,
                                 tmpSegment);
   }
 }
 
--- a/content/media/AudioNodeStream.h
+++ b/content/media/AudioNodeStream.h
@@ -37,18 +37,21 @@ class ThreadSharedFloatArrayBufferList;
  */
 class AudioNodeStream : public ProcessedMediaStream {
 public:
   enum { AUDIO_TRACK = 1 };
 
   /**
    * Transfers ownership of aEngine to the new AudioNodeStream.
    */
-  explicit AudioNodeStream(AudioNodeEngine* aEngine)
-    : ProcessedMediaStream(nullptr), mEngine(aEngine), mLastChunk(nullptr)
+  AudioNodeStream(AudioNodeEngine* aEngine,
+                  MediaStreamGraph::AudioNodeStreamKind aKind)
+    : ProcessedMediaStream(nullptr),
+      mEngine(aEngine),
+      mKind(aKind)
   {
   }
   ~AudioNodeStream();
 
   // Control API
   /**
    * Sets a parameter that's a time relative to some stream's played time.
    * This time is converted to a time relative to this stream when it's set.
@@ -76,14 +79,16 @@ protected:
   void FinishOutput();
 
   StreamBuffer::Track* EnsureTrack();
   AudioChunk* ObtainInputBlock(AudioChunk* aTmpChunk);
 
   // The engine that will generate output for this node.
   nsAutoPtr<AudioNodeEngine> mEngine;
   // The last block produced by this node.
-  AudioChunk* mLastChunk;
+  AudioChunk mLastChunk;
+  // Whether this is an internal or external stream
+  MediaStreamGraph::AudioNodeStreamKind mKind;
 };
 
 }
 
 #endif /* MOZILLA_AUDIONODESTREAM_H_ */
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -1997,19 +1997,20 @@ MediaStreamGraph::CreateTrackUnionStream
   NS_ADDREF(stream);
   MediaStreamGraphImpl* graph = static_cast<MediaStreamGraphImpl*>(this);
   stream->SetGraphImpl(graph);
   graph->AppendMessage(new CreateMessage(stream));
   return stream;
 }
 
 AudioNodeStream*
-MediaStreamGraph::CreateAudioNodeStream(AudioNodeEngine* aEngine)
+MediaStreamGraph::CreateAudioNodeStream(AudioNodeEngine* aEngine,
+                                        AudioNodeStreamKind aKind)
 {
-  AudioNodeStream* stream = new AudioNodeStream(aEngine);
+  AudioNodeStream* stream = new AudioNodeStream(aEngine, aKind);
   NS_ADDREF(stream);
   MediaStreamGraphImpl* graph = static_cast<MediaStreamGraphImpl*>(this);
   stream->SetGraphImpl(graph);
   graph->AppendMessage(new CreateMessage(stream));
   return stream;
 }
 
 }
--- a/content/media/MediaStreamGraph.h
+++ b/content/media/MediaStreamGraph.h
@@ -452,29 +452,29 @@ protected:
   };
   nsTArray<AudioOutput> mAudioOutputs;
   nsTArray<nsRefPtr<VideoFrameContainer> > mVideoOutputs;
   // We record the last played video frame to avoid redundant setting
   // of the current video frame.
   VideoFrame mLastPlayedVideoFrame;
   // The number of times this stream has been explicitly blocked by the control
   // API, minus the number of times it has been explicitly unblocked.
-  TimeVarying<GraphTime,uint32_t> mExplicitBlockerCount;
+  TimeVarying<GraphTime,uint32_t,0> mExplicitBlockerCount;
   nsTArray<nsRefPtr<MediaStreamListener> > mListeners;
   nsTArray<MainThreadMediaStreamListener*> mMainThreadListeners;
 
   // Precomputed blocking status (over GraphTime).
   // This is only valid between the graph's mCurrentTime and
   // mStateComputedTime. The stream is considered to have
   // not been blocked before mCurrentTime (its mBufferStartTime is increased
   // as necessary to account for that time instead) --- this avoids us having to
   // record the entire history of the stream's blocking-ness in mBlocked.
-  TimeVarying<GraphTime,bool> mBlocked;
+  TimeVarying<GraphTime,bool,5> mBlocked;
   // Maps graph time to the graph update that affected this stream at that time
-  TimeVarying<GraphTime,int64_t> mGraphUpdateIndices;
+  TimeVarying<GraphTime,int64_t,0> mGraphUpdateIndices;
 
   // MediaInputPorts to which this is connected
   nsTArray<MediaInputPort*> mConsumers;
 
   // Where audio output is going. There is one AudioOutputStream per
   // audio track.
   struct AudioOutputStream {
     // When we started audio playback for this track.
@@ -878,21 +878,26 @@ public:
    * removed tracks immediately end.
    * For each added track, the track ID of the output track is the track ID
    * of the input track or one plus the maximum ID of all previously added
    * tracks, whichever is greater.
    * TODO at some point we will probably need to add API to select
    * particular tracks of each input stream.
    */
   ProcessedMediaStream* CreateTrackUnionStream(DOMMediaStream* aWrapper);
+  // Internal AudioNodeStreams can only pass their output to another
+  // AudioNode, whereas external AudioNodeStreams can pass their output
+  // to an nsAudioStream for playback.
+  enum AudioNodeStreamKind { INTERNAL_STREAM, EXTERNAL_STREAM };
   /**
    * Create a stream that will process audio for an AudioNode.
    * Takes ownership of aEngine.
    */
-  AudioNodeStream* CreateAudioNodeStream(AudioNodeEngine* aEngine);
+  AudioNodeStream* CreateAudioNodeStream(AudioNodeEngine* aEngine,
+                                         AudioNodeStreamKind aKind);
   /**
    * Returns the number of graph updates sent. This can be used to track
    * whether a given update has been processed by the graph thread and reflected
    * in main-thread stream state.
    */
   int64_t GetCurrentGraphUpdateIndex() { return mGraphUpdatesSent; }
 
   /**
--- a/content/media/TimeVarying.h
+++ b/content/media/TimeVarying.h
@@ -27,27 +27,30 @@ protected:
   }
 };
 
 /**
  * Objects of this class represent values that can change over time ---
  * a mathematical function of time.
  * Time is the type of time values, T is the value that changes over time.
  * There are a finite set of "change times"; at each change time, the function
- * instantly changes to a new value.
+ * instantly changes to a new value. ReservedChanges should be set to the
+ * expected number of change events that the object is likely to contain.
+ * This value should be 0 for all consumers unless you know that a higher value
+ * would be a benefit.
  * There is also a "current time" which must always advance (not go backward).
  * The function is constant for all times less than the current time.
  * When the current time is advanced, the value of the function at the new
  * current time replaces the values for all previous times.
  *
  * The implementation records a mCurrent (the value at the current time)
  * and an array of "change times" (greater than the current time) and the
  * new value for each change time. This is a simple but dumb implementation.
  */
-template <typename Time, typename T>
+template <typename Time, typename T, uint32_t ReservedChanges>
 class TimeVarying : public TimeVaryingBase {
 public:
   TimeVarying(const T& aInitial) : mCurrent(aInitial) {}
   /**
    * This constructor can only be called if mCurrent has a no-argument
    * constructor.
    */
   TimeVarying() : mCurrent() {}
@@ -209,15 +212,15 @@ public:
 private:
   struct Entry {
     Entry(Time aTime, const T& aValue) : mTime(aTime), mValue(aValue) {}
 
     // The time at which the value changes to mValue
     Time mTime;
     T mValue;
   };
-  nsTArray<Entry> mChanges;
+  nsAutoTArray<Entry, ReservedChanges> mChanges;
   T mCurrent;
 };
 
 }
 
 #endif /* MOZILLA_TIMEVARYING_H_ */
--- a/content/media/gstreamer/GStreamerReader.cpp
+++ b/content/media/gstreamer/GStreamerReader.cpp
@@ -168,18 +168,18 @@ nsresult GStreamerReader::Init(MediaDeco
                           G_CALLBACK(&GStreamerReader::EventProbeCb), this);
   gst_object_unref(sinkpad);
 
   g_object_set(mPlayBin, "uri", "appsrc://",
                "video-sink", mVideoSink,
                "audio-sink", mAudioSink,
                nullptr);
 
-  g_object_connect(mPlayBin, "signal::source-setup",
-                  GStreamerReader::PlayBinSourceSetupCb, this, nullptr);
+  g_signal_connect(G_OBJECT(mPlayBin), "notify::source",
+                   G_CALLBACK(GStreamerReader::PlayBinSourceSetupCb), this);
 
   return NS_OK;
 }
 
 void GStreamerReader::PlayBinSourceSetupCb(GstElement* aPlayBin,
                                            GParamSpec* pspec,
                                            gpointer aUserData)
 {
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -295,21 +295,16 @@ ifdef MOZ_OGG
 MOCHITEST_FILES += \
 		test_can_play_type_ogg.html \
 		noContentLength.sjs \
 		test_seekable3.html \
 		test_a4_tone.html \
 		file_audio_event_adopt_iframe.html \
 		test_audio_event_adopt.html \
 		test_referer.html \
-		test_bug726904.html \
-		$(NULL)
-
-# Bug 759221
-MOCHITEST_FILES += \
 		test_bug686137.html \
 		test_contentDuration1.html \
 		test_contentDuration2.html \
 		test_contentDuration3.html \
 		test_contentDuration4.html \
 		test_contentDuration5.html \
 		test_contentDuration6.html \
 		test_contentDuration7.html \
@@ -319,16 +314,22 @@ MOCHITEST_FILES += \
 		contentDuration4.sjs \
 		contentDuration5.sjs \
 		contentDuration6.sjs \
 		contentDuration7.sjs \
 		test_framebuffer.html \
 		test_seekable2.html \
 		test_chaining.html \
 		$(NULL)
+# Temporarily disabled on OS X for bug 754860
+ifneq ($(MOZ_WIDGET_TOOLKIT),cocoa)
+MOCHITEST_FILES += \
+		test_bug726904.html \
+		$(NULL)
+endif
 else
 MOCHITEST_FILES += \
 		test_can_play_type_no_ogg.html \
 		$(NULL)
 endif
 
 ifdef MOZ_WEBM
 MOCHITEST_FILES += \
--- a/content/media/webaudio/AudioBufferSourceNode.cpp
+++ b/content/media/webaudio/AudioBufferSourceNode.cpp
@@ -222,17 +222,18 @@ public:
 AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* aContext)
   : AudioSourceNode(aContext)
   , mLoopStart(0.0)
   , mLoopEnd(0.0)
   , mLoop(false)
   , mStartCalled(false)
 {
   SetProduceOwnOutput(true);
-  mStream = aContext->Graph()->CreateAudioNodeStream(new AudioBufferSourceNodeEngine());
+  mStream = aContext->Graph()->CreateAudioNodeStream(new AudioBufferSourceNodeEngine(),
+                                                     MediaStreamGraph::INTERNAL_STREAM);
   mStream->AddMainThreadListener(this);
 }
 
 AudioBufferSourceNode::~AudioBufferSourceNode()
 {
   DestroyMediaStream();
 }
 
--- a/content/media/webaudio/AudioDestinationNode.cpp
+++ b/content/media/webaudio/AudioDestinationNode.cpp
@@ -26,17 +26,18 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_
 NS_INTERFACE_MAP_END_INHERITING(AudioNode)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(AudioDestinationNode)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(AudioDestinationNode)
 
 AudioDestinationNode::AudioDestinationNode(AudioContext* aContext, MediaStreamGraph* aGraph)
   : AudioNode(aContext)
 {
-  mStream = aGraph->CreateAudioNodeStream(new AudioNodeEngine());
+  mStream = aGraph->CreateAudioNodeStream(new AudioNodeEngine(),
+                                          MediaStreamGraph::EXTERNAL_STREAM);
   SetIsDOMBinding();
 }
 
 JSObject*
 AudioDestinationNode::WrapObject(JSContext* aCx, JSObject* aScope)
 {
   return AudioDestinationNodeBinding::Wrap(aCx, aScope, this);
 }
--- a/content/media/webaudio/AudioParam.h
+++ b/content/media/webaudio/AudioParam.h
@@ -59,16 +59,20 @@ public:
                                             aStartTime, aDuration, aRv);
     mCallback(mNode);
   }
 
   // We override the rest of the mutating AudioParamTimeline methods in order to make
   // sure that the callback is called every time that this object gets mutated.
   void SetValue(float aValue)
   {
+    // Optimize away setting the same value on an AudioParam
+    if (HasSimpleValue() && fabsf(GetValue() - aValue) < 1e-7) {
+      return;
+    }
     AudioParamTimeline::SetValue(aValue);
     mCallback(mNode);
   }
   void SetValueAtTime(float aValue, double aStartTime, ErrorResult& aRv)
   {
     AudioParamTimeline::SetValueAtTime(aValue, aStartTime, aRv);
     mCallback(mNode);
   }
--- a/content/media/webaudio/GainNode.cpp
+++ b/content/media/webaudio/GainNode.cpp
@@ -113,17 +113,17 @@ public:
   AudioParamTimeline mGain;
 };
 
 GainNode::GainNode(AudioContext* aContext)
   : AudioNode(aContext)
   , mGain(new AudioParam(this, SendGainToStream, 1.0f, 0.0f, 1.0f))
 {
   GainNodeEngine* engine = new GainNodeEngine(aContext->Destination());
-  mStream = aContext->Graph()->CreateAudioNodeStream(engine);
+  mStream = aContext->Graph()->CreateAudioNodeStream(engine, MediaStreamGraph::INTERNAL_STREAM);
   engine->SetSourceStream(static_cast<AudioNodeStream*> (mStream.get()));
 }
 
 GainNode::~GainNode()
 {
   DestroyMediaStream();
 }
 
--- a/content/media/webaudio/PannerNode.cpp
+++ b/content/media/webaudio/PannerNode.cpp
@@ -116,17 +116,18 @@ PannerNode::PannerNode(AudioContext* aCo
   , mVelocity()
   , mRefDistance(1.)
   , mMaxDistance(10000.)
   , mRolloffFactor(1.)
   , mConeInnerAngle(360.)
   , mConeOuterAngle(360.)
   , mConeOuterGain(0.)
 {
-  mStream = aContext->Graph()->CreateAudioNodeStream(new PannerNodeEngine());
+  mStream = aContext->Graph()->CreateAudioNodeStream(new PannerNodeEngine(),
+                                                     MediaStreamGraph::INTERNAL_STREAM);
   // We should register once we have set up our stream and engine.
   Context()->Listener()->RegisterPannerNode(this);
 }
 
 PannerNode::~PannerNode()
 {
   DestroyMediaStream();
 }
deleted file mode 100644
--- a/content/svg/Makefile.in
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/content/svg/content/Makefile.in
+++ /dev/null
@@ -1,14 +0,0 @@
-#!nmake
-#
-# 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/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/config/rules.mk
-
--- a/content/svg/content/src/SVGComponentTransferFunctionElement.h
+++ b/content/svg/content/src/SVGComponentTransferFunctionElement.h
@@ -33,17 +33,16 @@ protected:
     SetIsDOMBinding();
   }
 
 public:
   // interfaces:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_SVG_FE_COMPONENT_TRANSFER_FUNCTION_ELEMENT_CID)
 
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIDOMSVGCOMPONENTTRANSFERFUNCTIONELEMENT
 
   virtual bool AttributeAffectsRendering(
           int32_t aNameSpaceID, nsIAtom* aAttribute) const;
 
   virtual int32_t GetChannel() = 0;
   bool GenerateLookupTable(uint8_t* aTable);
 
   // WebIDL
@@ -57,17 +56,16 @@ public:
   already_AddRefed<nsIDOMSVGAnimatedNumber> Exponent();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Offset();
 
 protected:
   virtual NumberAttributesInfo GetNumberInfo();
   virtual EnumAttributesInfo GetEnumInfo();
   virtual NumberListAttributesInfo GetNumberListInfo();
 
-  // nsIDOMSVGComponentTransferFunctionElement properties:
   enum { TABLEVALUES };
   SVGAnimatedNumberList mNumberListAttributes[1];
   static NumberListInfo sNumberListInfo[1];
 
   enum { SLOPE, INTERCEPT, AMPLITUDE, EXPONENT, OFFSET };
   nsSVGNumber2 mNumberAttributes[5];
   static NumberInfo sNumberInfo[5];
 
@@ -82,34 +80,30 @@ protected:
 
 nsresult NS_NewSVGFEFuncRElement(
     nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo);
 
 namespace mozilla {
 namespace dom {
 
 class SVGFEFuncRElement : public SVGComponentTransferFunctionElement,
-                          public nsIDOMSVGFEFuncRElement
+                          public nsIDOMSVGElement
 {
   friend nsresult (::NS_NewSVGFEFuncRElement(
     nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo));
 protected:
-  SVGFEFuncRElement(already_AddRefed<nsINodeInfo> aNodeInfo) 
+  SVGFEFuncRElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : SVGComponentTransferFunctionElement(aNodeInfo) {}
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
 
-  NS_FORWARD_NSIDOMSVGCOMPONENTTRANSFERFUNCTIONELEMENT(SVGComponentTransferFunctionElement::)
+  virtual int32_t GetChannel() { return 0; }
 
-  NS_DECL_NSIDOMSVGFEFUNCRELEMENT
-
-  virtual int32_t GetChannel() { return 0; }
-  
   NS_FORWARD_NSIDOMSVGELEMENT(SVGComponentTransferFunctionElement::)
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 
@@ -122,32 +116,28 @@ public:
 
 nsresult NS_NewSVGFEFuncGElement(
   nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo);
 
 namespace mozilla {
 namespace dom {
 
 class SVGFEFuncGElement : public SVGComponentTransferFunctionElement,
-                          public nsIDOMSVGFEFuncGElement
+                          public nsIDOMSVGElement
 {
   friend nsresult (::NS_NewSVGFEFuncGElement(
     nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo));
 protected:
-  SVGFEFuncGElement(already_AddRefed<nsINodeInfo> aNodeInfo) 
+  SVGFEFuncGElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : SVGComponentTransferFunctionElement(aNodeInfo) {}
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
 
-  NS_FORWARD_NSIDOMSVGCOMPONENTTRANSFERFUNCTIONELEMENT(SVGComponentTransferFunctionElement::)
-
-  NS_DECL_NSIDOMSVGFEFUNCGELEMENT
-
   virtual int32_t GetChannel() { return 1; }
 
   NS_FORWARD_NSIDOMSVGELEMENT(SVGComponentTransferFunctionElement::)
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
@@ -162,32 +152,28 @@ public:
 
 nsresult NS_NewSVGFEFuncBElement(
   nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo);
 
 namespace mozilla {
 namespace dom {
 
 class SVGFEFuncBElement : public SVGComponentTransferFunctionElement,
-                          public nsIDOMSVGFEFuncBElement
+                          public nsIDOMSVGElement
 {
   friend nsresult (::NS_NewSVGFEFuncBElement(
     nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo));
 protected:
-  SVGFEFuncBElement(already_AddRefed<nsINodeInfo> aNodeInfo) 
+  SVGFEFuncBElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : SVGComponentTransferFunctionElement(aNodeInfo) {}
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
 
-  NS_FORWARD_NSIDOMSVGCOMPONENTTRANSFERFUNCTIONELEMENT(SVGComponentTransferFunctionElement::)
-
-  NS_DECL_NSIDOMSVGFEFUNCBELEMENT
-
   virtual int32_t GetChannel() { return 2; }
 
   NS_FORWARD_NSIDOMSVGELEMENT(SVGComponentTransferFunctionElement::)
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
@@ -202,32 +188,28 @@ public:
 
 nsresult NS_NewSVGFEFuncAElement(
   nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo);
 
 namespace mozilla {
 namespace dom {
 
 class SVGFEFuncAElement : public SVGComponentTransferFunctionElement,
-                          public nsIDOMSVGFEFuncAElement
+                          public nsIDOMSVGElement
 {
   friend nsresult (::NS_NewSVGFEFuncAElement(
     nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo));
 protected:
-  SVGFEFuncAElement(already_AddRefed<nsINodeInfo> aNodeInfo) 
+  SVGFEFuncAElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : SVGComponentTransferFunctionElement(aNodeInfo) {}
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
 
-  NS_FORWARD_NSIDOMSVGCOMPONENTTRANSFERFUNCTIONELEMENT(SVGComponentTransferFunctionElement::)
-
-  NS_DECL_NSIDOMSVGFEFUNCAELEMENT
-
   virtual int32_t GetChannel() { return 3; }
 
   NS_FORWARD_NSIDOMSVGELEMENT(SVGComponentTransferFunctionElement::)
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/nsSVGFilters.cpp
@@ -48,16 +48,23 @@
 #undef LoadImage
 #endif
 
 #define NUM_ENTRIES_IN_4x5_MATRIX 20
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
+static const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN  = 0;
+static const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY = 1;
+static const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_TABLE    = 2;
+static const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE = 3;
+static const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_LINEAR   = 4;
+static const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_GAMMA    = 5;
+
 void
 CopyDataRect(uint8_t *aDest, const uint8_t *aSrc, uint32_t aStride,
              const nsIntRect& aDataRect)
 {
   for (int32_t y = aDataRect.y; y < aDataRect.YMost(); y++) {
     memcpy(aDest + y * aStride + 4 * aDataRect.x,
            aSrc + y * aStride + 4 * aDataRect.x,
            4 * aDataRect.width);
@@ -1474,33 +1481,33 @@ nsSVGElement::NumberInfo SVGComponentTra
   { &nsGkAtoms::intercept, 0, false },
   { &nsGkAtoms::amplitude, 1, false },
   { &nsGkAtoms::exponent,  1, false },
   { &nsGkAtoms::offset,    0, false }
 };
 
 nsSVGEnumMapping SVGComponentTransferFunctionElement::sTypeMap[] = {
   {&nsGkAtoms::identity,
-   nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY},
+   SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY},
   {&nsGkAtoms::table,
-   nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_TABLE},
+   SVG_FECOMPONENTTRANSFER_TYPE_TABLE},
   {&nsGkAtoms::discrete,
-   nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE},
+   SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE},
   {&nsGkAtoms::linear,
-   nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_LINEAR},
+   SVG_FECOMPONENTTRANSFER_TYPE_LINEAR},
   {&nsGkAtoms::gamma,
-   nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_GAMMA},
+   SVG_FECOMPONENTTRANSFER_TYPE_GAMMA},
   {nullptr, 0}
 };
 
 nsSVGElement::EnumInfo SVGComponentTransferFunctionElement::sEnumInfo[1] =
 {
   { &nsGkAtoms::type,
     sTypeMap,
-    nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY
+    SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY
   }
 };
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(SVGComponentTransferFunctionElement,SVGComponentTransferFunctionElementBase)
 NS_IMPL_RELEASE_INHERITED(SVGComponentTransferFunctionElement,SVGComponentTransferFunctionElementBase)
@@ -1516,115 +1523,72 @@ NS_INTERFACE_MAP_BEGIN(SVGComponentTrans
 NS_INTERFACE_MAP_END_INHERITING(SVGComponentTransferFunctionElementBase)
 
 
 //----------------------------------------------------------------------
 // nsFEUnstyledElement methods
 
 bool
 SVGComponentTransferFunctionElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                                                 nsIAtom* aAttribute) const
+                                                               nsIAtom* aAttribute) const
 {
   return aNameSpaceID == kNameSpaceID_None &&
          (aAttribute == nsGkAtoms::tableValues ||
           aAttribute == nsGkAtoms::slope ||
           aAttribute == nsGkAtoms::intercept ||
           aAttribute == nsGkAtoms::amplitude ||
           aAttribute == nsGkAtoms::exponent ||
           aAttribute == nsGkAtoms::offset ||
           aAttribute == nsGkAtoms::type);
 }
 
 //----------------------------------------------------------------------
-// nsIDOMSVGComponentTransferFunctionElement methods
-
-/* readonly attribute nsIDOMSVGAnimatedEnumeration type; */
+
 already_AddRefed<nsIDOMSVGAnimatedEnumeration>
 SVGComponentTransferFunctionElement::Type()
 {
   return mEnumAttributes[TYPE].ToDOMAnimatedEnum(this);
 }
-NS_IMETHODIMP SVGComponentTransferFunctionElement::GetType(nsIDOMSVGAnimatedEnumeration * *aType)
-{
-  *aType = Type().get();
-  return NS_OK;
-}
-
-/* readonly attribute DOMSVGAnimatedNumberList tableValues; */
+
 already_AddRefed<DOMSVGAnimatedNumberList>
 SVGComponentTransferFunctionElement::TableValues()
 {
   return DOMSVGAnimatedNumberList::GetDOMWrapper(
     &mNumberListAttributes[TABLEVALUES], this, TABLEVALUES);
 }
-NS_IMETHODIMP SVGComponentTransferFunctionElement::GetTableValues(nsISupports * *aTableValues)
-{
-  *aTableValues = TableValues().get();
-  return NS_OK;
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber slope; */
+
 already_AddRefed<nsIDOMSVGAnimatedNumber>
 SVGComponentTransferFunctionElement::Slope()
 {
   return mNumberAttributes[SLOPE].ToDOMAnimatedNumber(this);
 }
-NS_IMETHODIMP SVGComponentTransferFunctionElement::GetSlope(nsIDOMSVGAnimatedNumber * *aSlope)
-{
-  *aSlope = Slope().get();
-  return NS_OK;
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber intercept; */
+
 already_AddRefed<nsIDOMSVGAnimatedNumber>
 SVGComponentTransferFunctionElement::Intercept()
 {
   return mNumberAttributes[INTERCEPT].ToDOMAnimatedNumber(this);
 }
-NS_IMETHODIMP SVGComponentTransferFunctionElement::GetIntercept(nsIDOMSVGAnimatedNumber * *aIntercept)
-{
-  *aIntercept = Intercept().get();
-  return NS_OK;
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber amplitude; */
+
 already_AddRefed<nsIDOMSVGAnimatedNumber>
 SVGComponentTransferFunctionElement::Amplitude()
 {
   return mNumberAttributes[AMPLITUDE].ToDOMAnimatedNumber(this);
 }
-NS_IMETHODIMP SVGComponentTransferFunctionElement::GetAmplitude(nsIDOMSVGAnimatedNumber * *aAmplitude)
-{
-  *aAmplitude = Amplitude().get();
-  return NS_OK;
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber exponent; */
+
 already_AddRefed<nsIDOMSVGAnimatedNumber>
 SVGComponentTransferFunctionElement::Exponent()
 {
   return mNumberAttributes[EXPONENT].ToDOMAnimatedNumber(this);
 }
-NS_IMETHODIMP SVGComponentTransferFunctionElement::GetExponent(nsIDOMSVGAnimatedNumber * *aExponent)
-{
-  *aExponent = Exponent().get();
-  return NS_OK;
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber offset; */
+
 already_AddRefed<nsIDOMSVGAnimatedNumber>
 SVGComponentTransferFunctionElement::Offset()
 {
   return mNumberAttributes[OFFSET].ToDOMAnimatedNumber(this);
 }
-NS_IMETHODIMP SVGComponentTransferFunctionElement::GetOffset(nsIDOMSVGAnimatedNumber * *aOffset)
-{
-  *aOffset = Offset().get();
-  return NS_OK;
-}
 
 bool
 SVGComponentTransferFunctionElement::GenerateLookupTable(uint8_t *aTable)
 {
   uint16_t type = mEnumAttributes[TYPE].GetAnimValue();
 
   float slope, intercept, amplitude, exponent, offset;
   GetAnimatedNumberValues(&slope, &intercept, &amplitude, 
@@ -1632,17 +1596,17 @@ SVGComponentTransferFunctionElement::Gen
 
   const SVGNumberList &tableValues =
     mNumberListAttributes[TABLEVALUES].GetAnimValue();
   uint32_t tvLength = tableValues.Length();
 
   uint32_t i;
 
   switch (type) {
-  case nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_TABLE:
+  case SVG_FECOMPONENTTRANSFER_TYPE_TABLE:
   {
     if (tableValues.Length() < 2)
       return false;
 
     for (i = 0; i < 256; i++) {
       uint32_t k = (i * (tvLength - 1)) / 255;
       float v1 = tableValues[k];
       float v2 = tableValues[std::min(k + 1, tvLength - 1)];
@@ -1650,56 +1614,56 @@ SVGComponentTransferFunctionElement::Gen
         int32_t(255 * (v1 + (i/255.0f - k/float(tvLength-1))*(tvLength - 1)*(v2 - v1)));
       val = std::min(255, val);
       val = std::max(0, val);
       aTable[i] = val;
     }
     break;
   }
 
-  case nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE:
+  case SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE:
   {
     if (tableValues.Length() < 1)
       return false;
 
     for (i = 0; i < 256; i++) {
       uint32_t k = (i * tvLength) / 255;
       k = std::min(k, tvLength - 1);
       float v = tableValues[k];
       int32_t val = int32_t(255 * v);
       val = std::min(255, val);
       val = std::max(0, val);
       aTable[i] = val;
     }
     break;
   }
 
-  case nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_LINEAR:
+  case SVG_FECOMPONENTTRANSFER_TYPE_LINEAR:
   {
     for (i = 0; i < 256; i++) {
       int32_t val = int32_t(slope * i + 255 * intercept);
       val = std::min(255, val);
       val = std::max(0, val);
       aTable[i] = val;
     }
     break;
   }
 
-  case nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_GAMMA:
+  case SVG_FECOMPONENTTRANSFER_TYPE_GAMMA:
   {
     for (i = 0; i < 256; i++) {
       int32_t val = int32_t(255 * (amplitude * pow(i / 255.0f, exponent) + offset));
       val = std::min(255, val);
       val = std::max(0, val);
       aTable[i] = val;
     }
     break;
   }