Merge m-c to fx-team.
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 19 Mar 2013 09:44:37 -0400
changeset 125378 55860fd20f67936b871953f0f3c6eba3a0da30a9
parent 125377 a53f03e0eeda6c752c1a53fa186d9503ea25fae6 (current diff)
parent 125375 2c41bf87b4e535fa9f5fb4976c5864dc8797a750 (diff)
child 125379 e562fcadfcf3ffa715793cc8134ed277467a212a
child 125435 d09d7e958b9cc44f45fff38eda1c9ca0f6c43fde
child 125438 98a625f3bf43572b4a17b25c4686a01e07077879
child 125445 348009ddf96d8a92a54a26e407f09eff9475e36f
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
milestone22.0a1
Merge m-c to fx-team.
b2g/branding/official/Makefile.in
b2g/branding/official/content/Makefile.in
b2g/branding/unofficial/Makefile.in
b2g/branding/unofficial/content/Makefile.in
browser/base/content/tabbrowser.xml
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/smil/nsISMILAnimationElement.h
content/svg/Makefile.in
content/svg/content/Makefile.in
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/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/src/build/unix/add_phony_targets.py
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/layout-large-v11/doorhangerpopup.xml
mobile/android/base/resources/layout-large-v11/site_identity_popup.xml
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
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/build/test-b2g-app-root-cert.der
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,13 @@
 #                  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
+#  *** Important! ***
+#  If changing this file you must manually clobber immediately before landing,
+#  (due to bug 837323), using: https://secure.pub.build.mozilla.org/clobberer/
+#
+Bug 851908 - The WebIDL build system still has some problems.
--- a/accessible/src/atk/ApplicationAccessibleWrap.cpp
+++ b/accessible/src/atk/ApplicationAccessibleWrap.cpp
@@ -123,19 +123,19 @@ gboolean fireRootAccessibleAddedCB(gpoin
     g_object_unref(eventData->app_accessible);
     g_object_unref(eventData->root_accessible);
     free(data);
 
     return FALSE;
 }
 
 bool
-ApplicationAccessibleWrap::AppendChild(Accessible* aChild)
+ApplicationAccessibleWrap::InsertChildAt(uint32_t aIdx, Accessible* aChild)
 {
-  if (!ApplicationAccessible::AppendChild(aChild))
+  if (!ApplicationAccessible::InsertChildAt(aIdx, aChild))
     return false;
 
   AtkObject* atkAccessible = AccessibleWrap::GetAtkObject(aChild);
   atk_object_set_parent(atkAccessible, mAtkObject);
 
     uint32_t count = mChildren.Length();
 
     // Emit children_changed::add in a timeout
--- a/accessible/src/atk/ApplicationAccessibleWrap.h
+++ b/accessible/src/atk/ApplicationAccessibleWrap.h
@@ -15,17 +15,17 @@ namespace a11y {
 class ApplicationAccessibleWrap: public ApplicationAccessible
 {
 public:
   ApplicationAccessibleWrap();
   virtual ~ApplicationAccessibleWrap();
 
   // Accessible
   virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
-  virtual bool AppendChild(Accessible* aChild);
+  virtual bool InsertChildAt(uint32_t aIdx, Accessible* aChild) MOZ_OVERRIDE;
   virtual bool RemoveChild(Accessible* aChild);
 
   /**
    * Return the atk object for app root accessible.
    */
   NS_IMETHOD GetNativeInterface(void** aOutAccessible);
 };
 
--- a/accessible/src/base/DocManager.cpp
+++ b/accessible/src/base/DocManager.cpp
@@ -364,17 +364,18 @@ DocManager::RemoveListeners(nsIDocument*
                                  dom::TrustedEventsAtCapture());
 }
 
 DocAccessible*
 DocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
 {
   // Ignore temporary, hiding, resource documents and documents without
   // docshell.
-  if (aDocument->IsInitialDocument() || !aDocument->IsVisible() ||
+  if (aDocument->IsInitialDocument() ||
+      !aDocument->IsVisibleConsideringAncestors() ||
       aDocument->IsResourceDoc() || !aDocument->IsActive())
     return nullptr;
 
   // Ignore documents without presshell and not having root frame.
   nsIPresShell* presShell = aDocument->GetShell();
   if (!presShell || presShell->IsDestroying())
     return nullptr;
 
--- a/accessible/src/base/Logging.cpp
+++ b/accessible/src/base/Logging.cpp
@@ -161,16 +161,17 @@ LogDocState(nsIDocument* aDocumentNode)
       docState = "complete";
       break;
   }
 
   printf("doc state: %s", docState);
   printf(", %sinitial", aDocumentNode->IsInitialDocument() ? "" : "not ");
   printf(", %sshowing", aDocumentNode->IsShowing() ? "" : "not ");
   printf(", %svisible", aDocumentNode->IsVisible() ? "" : "not ");
+  printf(", %svisible considering ancestors", aDocumentNode->IsVisibleConsideringAncestors() ? "" : "not ");
   printf(", %sactive", aDocumentNode->IsActive() ? "" : "not ");
   printf(", %sresource", aDocumentNode->IsResourceDoc() ? "" : "not ");
   printf(", has %srole content",
          nsCoreUtils::GetRoleContent(aDocumentNode) ? "" : "no ");
 }
 
 static void
 LogPresShell(nsIDocument* aDocumentNode)
--- 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/src/generic/Accessible.cpp
+++ b/accessible/src/generic/Accessible.cpp
@@ -2635,50 +2635,40 @@ Accessible::InvalidateChildren()
   }
 
   mEmbeddedObjCollector = nullptr;
   mChildren.Clear();
   SetChildrenFlag(eChildrenUninitialized);
 }
 
 bool
-Accessible::AppendChild(Accessible* aChild)
-{
-  if (!aChild)
-    return false;
-
-  if (!mChildren.AppendElement(aChild))
-    return false;
-
-  if (!nsAccUtils::IsEmbeddedObject(aChild))
-    SetChildrenFlag(eMixedChildren);
-
-  aChild->BindToParent(this, mChildren.Length() - 1);
-  return true;
-}
-
-bool
 Accessible::InsertChildAt(uint32_t aIndex, Accessible* aChild)
 {
   if (!aChild)
     return false;
 
-  if (!mChildren.InsertElementAt(aIndex, aChild))
-    return false;
-
-  for (uint32_t idx = aIndex + 1; idx < mChildren.Length(); idx++) {
-    NS_ASSERTION(mChildren[idx]->mIndexInParent == idx - 1, "Accessible child index doesn't match");
-    mChildren[idx]->mIndexInParent = idx;
+  if (aIndex == mChildren.Length()) {
+    if (!mChildren.AppendElement(aChild))
+      return false;
+
+  } else {
+    if (!mChildren.InsertElementAt(aIndex, aChild))
+      return false;
+
+    for (uint32_t idx = aIndex + 1; idx < mChildren.Length(); idx++) {
+      NS_ASSERTION(mChildren[idx]->mIndexInParent == idx - 1, "Accessible child index doesn't match");
+      mChildren[idx]->mIndexInParent = idx;
+    }
+
+    mEmbeddedObjCollector = nullptr;
   }
 
   if (!nsAccUtils::IsEmbeddedObject(aChild))
     SetChildrenFlag(eMixedChildren);
 
-  mEmbeddedObjCollector = nullptr;
-
   aChild->BindToParent(this, aIndex);
   return true;
 }
 
 bool
 Accessible::RemoveChild(Accessible* aChild)
 {
   if (!aChild)
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -328,17 +328,18 @@ public:
    * transformed. Note, if accessible cares about its parent relation chain
    * itself should override this method to do nothing.
    */
   virtual void InvalidateChildren();
 
   /**
    * Append/insert/remove a child. Return true if operation was successful.
    */
-  virtual bool AppendChild(Accessible* aChild);
+  bool AppendChild(Accessible* aChild)
+    { return InsertChildAt(mChildren.Length(), aChild); }
   virtual bool InsertChildAt(uint32_t aIndex, Accessible* aChild);
   virtual bool RemoveChild(Accessible* aChild);
 
   //////////////////////////////////////////////////////////////////////////////
   // Accessible tree traverse methods
 
   /**
    * Return parent accessible.
--- a/accessible/src/generic/BaseAccessibles.cpp
+++ b/accessible/src/generic/BaseAccessibles.cpp
@@ -39,23 +39,16 @@ Accessible*
 LeafAccessible::ChildAtPoint(int32_t aX, int32_t aY,
                              EWhichChildAtPoint aWhichChild)
 {
   // Don't walk into leaf accessibles.
   return this;
 }
 
 bool
-LeafAccessible::AppendChild(Accessible* aChild)
-{
-  NS_NOTREACHED("AppendChild called on leaf accessible!");
-  return false;
-}
-
-bool
 LeafAccessible::InsertChildAt(uint32_t aIndex, Accessible* aChild)
 {
   NS_NOTREACHED("InsertChildAt called on leaf accessible!");
   return false;
 }
 
 bool
 LeafAccessible::RemoveChild(Accessible* aChild)
--- a/accessible/src/generic/BaseAccessibles.h
+++ b/accessible/src/generic/BaseAccessibles.h
@@ -29,18 +29,16 @@ public:
   LeafAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // Accessible
   virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY,
                                    EWhichChildAtPoint aWhichChild);
-  
-  virtual bool AppendChild(Accessible* aChild) MOZ_OVERRIDE MOZ_FINAL;
   virtual bool InsertChildAt(uint32_t aIndex, Accessible* aChild) MOZ_OVERRIDE MOZ_FINAL;
   virtual bool RemoveChild(Accessible* aChild) MOZ_OVERRIDE MOZ_FINAL;
 
 protected:
 
   // Accessible
   virtual void CacheChildren();
 };
--- a/accessible/src/generic/OuterDocAccessible.cpp
+++ b/accessible/src/generic/OuterDocAccessible.cpp
@@ -144,27 +144,29 @@ OuterDocAccessible::InvalidateChildren()
   // DOM document (for example when DOM node of outerdoc accessible is shown)
   // then allow DocManager to handle this case since the document
   // accessible is created and appended as a child when it's requested.
 
   SetChildrenFlag(eChildrenUninitialized);
 }
 
 bool
-OuterDocAccessible::AppendChild(Accessible* aAccessible)
+OuterDocAccessible::InsertChildAt(uint32_t aIdx, Accessible* aAccessible)
 {
+  NS_ASSERTION(aAccessible->IsDoc(),
+               "OuterDocAccessible should only have document child!");
   // We keep showing the old document for a bit after creating the new one,
   // and while building the new DOM and frame tree. That's done on purpose
   // to avoid weird flashes of default background color.
   // The old viewer will be destroyed after the new one is created.
   // For a11y, it should be safe to shut down the old document now.
   if (mChildren.Length())
     mChildren[0]->Shutdown();
 
-  if (!AccessibleWrap::AppendChild(aAccessible))
+  if (!AccessibleWrap::InsertChildAt(0, aAccessible))
     return false;
 
 #ifdef A11Y_LOG
   if (logging::IsEnabled(logging::eDocCreate)) {
     logging::DocCreate("append document to outerdoc",
                        aAccessible->AsDoc()->DocumentNode());
     logging::Address("outerdoc", this);
   }
--- a/accessible/src/generic/OuterDocAccessible.h
+++ b/accessible/src/generic/OuterDocAccessible.h
@@ -37,17 +37,17 @@ public:
   virtual void Shutdown();
 
   // Accessible
   virtual mozilla::a11y::role NativeRole();
   virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY,
                                    EWhichChildAtPoint aWhichChild);
 
   virtual void InvalidateChildren();
-  virtual bool AppendChild(Accessible* aAccessible);
+  virtual bool InsertChildAt(uint32_t aIdx, Accessible* aChild) MOZ_OVERRIDE;
   virtual bool RemoveChild(Accessible* aAccessible);
 
   // ActionAccessible
   virtual uint8_t ActionCount();
 
 protected:
   // Accessible
   virtual void CacheChildren();
--- a/accessible/src/mac/AccessibleWrap.h
+++ b/accessible/src/mac/AccessibleWrap.h
@@ -44,17 +44,17 @@ public: // construction, destruction
    * should be instantied with.   used on runtime to determine the
    * right type for this accessible's associated native object.
    */
   virtual Class GetNativeType ();
 
   virtual void Shutdown ();
   virtual void InvalidateChildren();
 
-  virtual bool AppendChild(Accessible* aAccessible);
+  virtual bool InsertChildAt(uint32_t aIdx, Accessible* aChild) MOZ_OVERRIDE;
   virtual bool RemoveChild(Accessible* aAccessible);
 
   virtual nsresult HandleAccEvent(AccEvent* aEvent);
 
   /**
    * Ignored means that the accessible might still have children, but is not
    * displayed to the user. it also has no native accessible object represented
    * for it.
--- a/accessible/src/mac/AccessibleWrap.mm
+++ b/accessible/src/mac/AccessibleWrap.mm
@@ -193,24 +193,23 @@ AccessibleWrap::InvalidateChildren()
   [GetNativeObject() invalidateChildren];
 
   Accessible::InvalidateChildren();
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 bool
-AccessibleWrap::AppendChild(Accessible* aAccessible)
+AccessibleWrap::InsertChildAt(uint32_t aIdx, Accessible* aAccessible)
 {
-  bool appended = Accessible::AppendChild(aAccessible);
-  
-  if (appended && mNativeObject)
+  bool inserted = Accessible::InsertChildAt(aIdx, aAccessible);
+  if (inserted && mNativeObject)
     [mNativeObject appendChild:aAccessible];
 
-  return appended;
+  return inserted;
 }
 
 bool
 AccessibleWrap::RemoveChild(Accessible* aAccessible)
 {
   bool removed = Accessible::RemoveChild(aAccessible);
 
   if (removed && mNativeObject)
--- a/accessible/tests/mochitest/editabletext/test_1.html
+++ b/accessible/tests/mochitest/editabletext/test_1.html
@@ -14,21 +14,16 @@ https://bugzilla.mozilla.org/show_bug.cg
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../events.js"></script>
   <script type="application/javascript"
           src="editabletext.js"></script>
 
   <script type="application/javascript">
-    if (navigator.platform.startsWith("Mac")) {
-      SimpleTest.expectAssertions(0, 1);
-    } else {
-      SimpleTest.expectAssertions(1);
-    }
 
     function addTestEditable(aID, aTestRun, aTrailChar)
     {
       var et = new editableTextTest(aID);
 
       //////////////////////////////////////////////////////////////////////////
       // setTextContents
       et.scheduleTest(et.setTextContents, "hello");
--- a/accessible/tests/mochitest/events/test_focus_browserui.xul
+++ b/accessible/tests/mochitest/events/test_focus_browserui.xul
@@ -19,19 +19,16 @@
           src="../states.js"></script>
   <script type="application/javascript"
           src="../events.js"></script>
   <script type="application/javascript"
           src="../browser.js"></script>
 
   <script type="application/javascript">
   <![CDATA[
-    if (navigator.platform.startsWith("Linux")) {
-      SimpleTest.expectAssertions(1);
-    }
     ////////////////////////////////////////////////////////////////////////////
     // Helpers
 
     function inputInDocument()
     {
       var tabdoc = currentTabDocument();
       return tabdoc.getElementById("input");
     }
@@ -113,18 +110,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/events/test_focus_doc.html
+++ b/accessible/tests/mochitest/events/test_focus_doc.html
@@ -17,20 +17,16 @@
     src="../events.js"></script>
   <script type="application/javascript"
           src="../role.js"></script>
     <script type="application/javascript"
       src="../states.js"></script>
 
   <script type="application/javascript">
     if (navigator.platform.startsWith("Win")) {
-      SimpleTest.expectAssertions(1, 2);
-    } else if (navigator.platform.startsWith("Linux")) {
-      SimpleTest.expectAssertions(1);
-    } else if (navigator.platform.startsWith("Mac")) {
       SimpleTest.expectAssertions(0, 1);
     }
 
     var gQueue = null;
 
     //var gA11yEventDumpID = "eventdump";
     //gA11yEventDumpToConsole = true;
 
--- 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
@@ -108,17 +108,19 @@
 @BINPATH@/@MOZ_APP_NAME@.exe
 #else
 @BINPATH@/@MOZ_APP_NAME@-bin
 @BINPATH@/@MOZ_APP_NAME@
 #endif
 @BINPATH@/application.ini
 @BINPATH@/platform.ini
 #ifndef XP_OS2
+#ifndef MOZ_FOLD_LIBS
 @BINPATH@/@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@
+#endif
 #else
 @BINPATH@/mozsqlt3@DLL_SUFFIX@
 #endif
 @BINPATH@/blocklist.xml
 #ifdef XP_UNIX
 #ifndef XP_MACOSX
 @BINPATH@/run-mozilla.sh
 @BINPATH@/mozilla-xremote-client
@@ -464,19 +466,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/installer/removed-files.in
+++ b/b2g/installer/removed-files.in
@@ -5,9 +5,18 @@ jssubloader/
 run-mozilla.sh
 #endif
 #ifdef XP_WIN
   mozcrt19.dll
   mozcpp19.dll
 #endif
 defaults/preferences/services-sync.js
 defaults/preferences/healthreport-prefs.js
-components/dom_sms.xpt
\ No newline at end of file
+components/dom_sms.xpt
+#ifdef MOZ_FOLD_LIBS
+@DLL_PREFIX@nspr4@DLL_SUFFIX@
+@DLL_PREFIX@plds4@DLL_SUFFIX@
+@DLL_PREFIX@plc4@DLL_SUFFIX@
+@DLL_PREFIX@ssl3@DLL_SUFFIX@
+@DLL_PREFIX@smime3@DLL_SUFFIX@
+@DLL_PREFIX@nssutil3@DLL_SUFFIX@
+@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@
+#endif
--- 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
@@ -12,16 +12,25 @@
 @DLL_PREFIX@xpcom_compat@DLL_SUFFIX@
 @DLL_PREFIX@xpistub@DLL_SUFFIX@
 @DLL_PREFIX@zlib@DLL_SUFFIX@
 @DLL_PREFIX@jemalloc@DLL_SUFFIX@
 @DLL_PREFIX@mozutils@DLL_SUFFIX@
 #ifdef MOZ_STATIC_JS
 @DLL_PREFIX@mozjs@DLL_SUFFIX@
 #endif
+#ifdef MOZ_FOLD_LIBS
+@DLL_PREFIX@nspr4@DLL_SUFFIX@
+@DLL_PREFIX@plds4@DLL_SUFFIX@
+@DLL_PREFIX@plc4@DLL_SUFFIX@
+@DLL_PREFIX@ssl3@DLL_SUFFIX@
+@DLL_PREFIX@smime3@DLL_SUFFIX@
+@DLL_PREFIX@nssutil3@DLL_SUFFIX@
+@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@
+#endif
 LICENSE
 browserconfig.properties
 chrome/US.jar
 chrome/app-chrome.manifest
 chrome/browser.manifest
 chrome/chrome.rdf
 chrome/chromelist.txt
 chrome/classic.jar
@@ -42,16 +51,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…
@@ -377,18 +385,16 @@ social.turnOff.accesskey=T
 # LOCALIZATION NOTE (social.turnOn.label): %S is the name of the social provider
 social.turnOn.label=Turn on %S
 social.turnOn.accesskey=T
 
 # LOCALIZATION NOTE (social.error.message): %1$S is brandShortName (e.g. Firefox), %2$S is the name of the social provider
 social.error.message=%1$S is unable to connect with %2$S right now.
 social.error.tryAgain.label=Try Again
 social.error.tryAgain.accesskey=T
-social.error.ok.label=OK
-social.error.ok.accesskey=O
 social.error.closeSidebar.label=Close This Sidebar
 social.error.closeSidebar.accesskey=C
 
 # LOCALIZATION NOTE: %1$S is the label for the toolbar button, %2$S is the associated badge numbering that the social provider may provide.
 social.aria.toolbarButtonBadgeText=%1$S (%2$S)
 
 # Identity notifications popups
 identity.termsOfService = Terms of Service
--- 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
@@ -27,48 +27,66 @@
 
       <method name="clearSelection">
         <body>
           <![CDATA[
             // 'selection' and 'selected' are confusingly overloaded here
             // as richgrid is adopting multi-select behavior, but select/selected are already being
             // used to describe triggering the default action of a tile
             if (this._selectedItem){
-              this._selectedItem.selected = false;
+              this._selectedItem.removeAttribute("selected");
               this._selectedItem = null;
             }
 
             for (let childItem of this.selectedItems) {
-              childItem.selected = false;
+              childItem.removeAttribute("selected");
             }
             // reset context actions
             this._contextActions = null;
           ]]>
         </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();
+            }
+            this._selectedItem = wasSelected ? null : anItem;
+            if(anItem.selected) {
+              anItem.removeAttribute("selected");
+            } else {
+              anItem.setAttribute("selected", true);
+            }
             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[
@@ -487,18 +505,17 @@
 
     <implementation>
       <property name="_box" onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'anon-richgrid-item');"/>
       <property name="color" onset="this._color = val; this.setColor();" onget="return this._color;"/>
       <property name="backgroundimage"
                 onset="this._backgroundimage = val; this.setBackgroundImage();"
                 onget="return this._backgroundimage;" />
       <property name="selected"
-                onget="return this.getAttribute('selected') == 'true';"
-                onset="this.setAttribute('selected', val);"/>
+                onget="return this.getAttribute('selected') == 'true';" />
 
       <constructor>
         <![CDATA[
           // Bindings don't get bound until the item is displayed,
           // so we have to reset the background color/image when we get
           // created.
           this.setColor();
           this.setBackgroundImage();
--- a/browser/metro/base/content/browser-ui.js
+++ b/browser/metro/base/content/browser-ui.js
@@ -586,18 +586,26 @@ var BrowserUI = {
 
     let tab = Browser.getTabForBrowser(aBrowser);
     if (tab)
       tab.chromeTab.updateTitle(tabCaption);
   },
 
   _updateButtons: function _updateButtons() {
     let browser = Browser.selectedBrowser;
-    this._back.setAttribute("disabled", !browser.canGoBack);
-    this._forward.setAttribute("disabled", !browser.canGoForward);
+    if (browser.canGoBack) {
+      this._back.removeAttribute("disabled");
+    } else {
+      this._back.setAttribute("disabled", true);
+    }
+    if (browser.canGoForward) {
+      this._forward.removeAttribute("disabled");
+    } else {
+      this._forward.setAttribute("disabled", true);
+    }
   },
 
   _updateToolbar: function _updateToolbar() {
     let mode = Elements.urlbarState.getAttribute("mode");
     let isLoading = Browser.selectedTab.isLoading();
 
     if (isLoading && mode != "loading")
       Elements.urlbarState.setAttribute("mode", "loading");
--- 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/content/helperui/MasterPasswordUI.js
+++ b/browser/metro/base/content/helperui/MasterPasswordUI.js
@@ -96,17 +96,21 @@ var MasterPasswordUI = {
 
   checkPassword: function mp_checkPassword() {
     let newPasswordValue1 = document.getElementById("masterpassword-newpassword1").value;
     let newPasswordValue2 = document.getElementById("masterpassword-newpassword2").value;
 
     let buttonOk = this._dialog.getElementsByAttribute("class", "prompt-buttons")[0].firstChild;
     let isPasswordValid = this._secModuleDB.isFIPSEnabled ? (newPasswordValue1 != "" && newPasswordValue1 == newPasswordValue2)
                                                           : (newPasswordValue1 == newPasswordValue2);
-    buttonOk.setAttribute("disabled", !isPasswordValid);
+    if (isPasswordValid) {
+      buttonOk.removeAttribute("disabled");
+    } else {
+      buttonOk.setAttribute("disabled", true);
+    }
 
     return isPasswordValid;
   },
 
   checkOldPassword: function mp_checkOldPassword() {
     let oldPassword = document.getElementById("masterpassword-oldpassword");
 
     let buttonOk = this._dialog.getElementsByAttribute("class", "prompt-buttons")[0].firstChild;
--- 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
@@ -38,17 +38,17 @@
   opacity: 0;
   transition-property: width, opacity;
   transition-duration: .3s, .5s;
   transition-timing-function: ease-in, ease-in;
 }
 
 /* in non-tabsonly mode the navigation bar and tab tray float over content. In
    tabsonly mode they are always visible and offset content. */
-#tray:not([tabsonly=true]) {
+#tray:not([tabsonly]) {
   position: fixed;
 }
 
 #tray[visible][expanded] {
   transform: none;
 }
 
 #tray[startpage],
@@ -91,54 +91,54 @@
   -moz-image-region: rect(15px 58px 63px 14px) !important;
 }
 #tabs > .tabs-scrollbox > .scrollbutton-up:hover {
   -moz-image-region: rect(14px 102px 62px 58px) !important;
 }
 #tabs > .tabs-scrollbox > .scrollbutton-up:active {
   -moz-image-region: rect(14px 152px 62px 108px) !important;
 }
-#tabs > .tabs-scrollbox > .scrollbutton-up[disabled="true"] {
+#tabs > .tabs-scrollbox > .scrollbutton-up[disabled] {
   -moz-image-region: rect(15px 196px 63px 152px) !important;
 }
 
 #tabs > .tabs-scrollbox > .scrollbutton-down {
   list-style-image: url("images/tab-arrows.png") !important;
   -moz-image-region: rect(73px 58px 121px 14px) !important;
 }
 #tabs > .tabs-scrollbox > .scrollbutton-down:hover {
   -moz-image-region: rect(72px 102px 120px 58px) !important;
 }
 #tabs > .tabs-scrollbox > .scrollbutton-down:active {
   -moz-image-region: rect(72px 152px 120px 108px) !important;
 }
-#tabs > .tabs-scrollbox > .scrollbutton-down[disabled="true"] {
+#tabs > .tabs-scrollbox > .scrollbutton-down[disabled] {
   -moz-image-region: rect(73px 196px 121px 152px) !important;
 }
 
 
 @-moz-keyframes open-documenttab {
   0% {
     opacity: 0;
     transform: scale(0, 0);
   }
   
   100% {
     opacity: 1;
     transform: scale(1, 1);
   }
 }
 
-#tray:not([tabsonly=true]) documenttab > .documenttab-container {
+#tray:not([tabsonly]) documenttab > .documenttab-container {
   animation: open-documenttab;
   animation-duration: 0.4s;
   animation-timing-function: ease-out;
 }
 
-#tray:not([tabsonly=true]) .documenttab-favicon {
+#tray:not([tabsonly]) .documenttab-favicon {
   visibility: collapse;
 }
 
 .documenttab-thumbnail {
   margin: @metro_spacing_normal@ @metro_spacing_snormal@;
   background: white none center top no-repeat;
   background-size: cover;
   width: @thumbnail_width@;
@@ -161,124 +161,128 @@
 .documenttab-crop {
   background: transparent url("chrome://browser/skin/images/tab-crop.png") 50% 50% no-repeat;
 }
 
 .documenttab-selection {
   background: transparent -moz-image-rect(url("chrome://browser/skin/images/tab-overlay.png"), 0%, 100%, 50%, 0%) 50% 50% no-repeat;
 }
 
-documenttab[selected=true] .documenttab-selection {
+documenttab[selected] .documenttab-selection {
   background: transparent -moz-image-rect(url("chrome://browser/skin/images/tab-overlay.png"), 50%, 100%, 100%, 0%) 50% 50% no-repeat;
 }
 
 .documenttab-close {
   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");
 }
 
-#tray[tabsonly=true] {
+.documenttab-close > .button-box > .button-text {
+  display: none;
+}
+
+#tray[tabsonly] {
   transform: none !important;
 }
 
-#tray[tabsonly=true] #tabs {
+#tray[tabsonly] #tabs {
   -moz-padding-start: @metro_spacing_small@;
 }
 
-#tray[tabsonly=true] #tabs-controls {
+#tray[tabsonly] #tabs-controls {
   -moz-box-align: center;
   -moz-box-orient: horizontal;
   -moz-box-pack: end;
   margin: 0;
 }
 
-#tray[tabsonly=true] #tabs-controls toolbarbutton {
+#tray[tabsonly] #tabs-controls toolbarbutton {
   margin-top: 0;
   margin-bottom: 0;
 }
 
-#tray[tabsonly=true] documenttab {
+#tray[tabsonly] documenttab {
   height: @toolbar_height@;
   margin: 0 -@tab_compression@;
 }
 
-#tray[tabsonly=true] documenttab:first-child {
+#tray[tabsonly] documenttab:first-child {
   -moz-margin-start: 0;
 }
 
-#tray[tabsonly=true] documenttab:last-child {
+#tray[tabsonly] documenttab:last-child {
   -moz-margin-end: 0;
 }
 
-#tray[tabsonly=true] .documenttab-thumbnail,
-#tray[tabsonly=true] .documenttab-selection,
-#tray[tabsonly=true] .documenttab-crop {
+#tray[tabsonly] .documenttab-thumbnail,
+#tray[tabsonly] .documenttab-selection,
+#tray[tabsonly] .documenttab-crop {
   visibility: collapse;
 }
 
-#tray[tabsonly=true] .documenttab-container {
+#tray[tabsonly] .documenttab-container {
   display: -moz-box;
   -moz-box-orient: horizontal;
   -moz-box-align: center;
   padding: 0 @tab_spacing@;
 }
 
-#tray[tabsonly=true] .documenttab-favicon {
+#tray[tabsonly] .documenttab-favicon {
   -moz-margin-start: @metro_spacing_normal@;
   -moz-margin-end: @metro_spacing_snormal@;
 }
 
-#tray[tabsonly=true] .documenttab-title {
+#tray[tabsonly] .documenttab-title {
   padding: 0;
   margin: 0;
   height: auto;
   background: 0 none;
   opacity: 1;
   box-shadow: none;
   width: @tab_inner_width@;
 }
 
-#tray[tabsonly=true] .documenttab-close {
+#tray[tabsonly] .documenttab-close {
   list-style-image: url("chrome://browser/skin/images/closetab-tab.png");
   position: relative;
   padding: 0 !important;
   z-index: 1;
 }
 
-#tray[tabsonly=true] documenttab[selected=true] {
+#tray[tabsonly] documenttab[selected=true] {
   background-color: @panel_light_color@;
   background-image: url("chrome://browser/skin/images/tab-selection-left.png"),
                     url("chrome://browser/skin/images/tab-selection-right.png"),
                     @panel_light_background@;
   background-position: left top, right top, center center;
   background-repeat: no-repeat, no-repeat, repeat;
 }
 
-#tray[tabsonly=true] documenttab[selected=true] .documenttab-close {
+#tray[tabsonly] documenttab[selected=true] .documenttab-close {
   list-style-image: url("chrome://browser/skin/images/closetab-tabselected.png");
 }
 
 #page,
 .selection-overlay {
   -moz-stack-sizing: ignore;
 }
 
 .selection-overlay:-moz-focusring {
   outline: 0 !important;
 }
 
 .selection-overlay-hidden {
   display: none;
 }
 
-#tray[tabsonly=true] documenttab[selected=true] .documenttab-title {
+#tray[tabsonly] documenttab[selected=true] .documenttab-title {
   color: #000;
 }
 
 #tabs-controls {
   margin-top: @metro_spacing_small@;
   -moz-box-align: start;
   -moz-box-orient: vertical;
   padding: 0 @metro_spacing_small@;
@@ -347,17 +351,17 @@ documenttab[selected=true] .documenttab-
   -moz-image-region: rect(0 48px 48px 0);
   position: relative;
   z-index: 1;
   padding: 0 !important;
   min-height: 48px !important;
   max-height: 48px !important;
 }
 
-#back-button[disabled="true"] {
+#back-button[disabled] {
   -moz-image-region: rect(0 96px 48px 48px);
 }
 
 #forward-button {
   background: linear-gradient(to bottom, rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0.5)), @panel_light_background@;
   border: @metro_border_thick@ solid rgb(192, 198, 204);
   margin: 0 !important;
   padding: 0 !important;
@@ -368,17 +372,17 @@ documenttab[selected=true] .documenttab-
 }
 
 /* XXX: Hack to move the image up one pixel because
         it's not vertically centered for some reason. */
 #forward-button image {
   margin: -1px 0 1px 0 !important;
 }
 
-#unified-back-forward-button > #forward-button[disabled="true"] {
+#unified-back-forward-button > #forward-button[disabled] {
   opacity: 0;
 }
 
 /* URL bar */
 #unified-back-forward-button + #urlbar-container {
   margin: 0;
   padding: 0;
   padding-left: @back_width@;
@@ -393,22 +397,22 @@ documenttab[selected=true] .documenttab-
 }
 
 #unified-back-forward-button + #urlbar-container > #urlbar {
   -moz-border-start: none;
   pointer-events: all;
   transition: margin-left @forward_transition_length@ ease-out;
 }
 
-#unified-back-forward-button[forwarddisabled="true"] + #urlbar-container {
+#unified-back-forward-button[forwarddisabled] + #urlbar-container {
   clip-path: url("chrome://browser/content/browser.xul#back-button-clip-path");
   padding-left: @clipped_url_back_width@;
 }
 
-#unified-back-forward-button[forwarddisabled="true"] + #urlbar-container > #urlbar {
+#unified-back-forward-button[forwarddisabled] + #urlbar-container > #urlbar {
   margin-left: -@forward_width@;
 }
 
 /* Identity widget */
 #identity-icon {
   width: @metro_spacing_xxnormal@;
   height: @metro_spacing_xxnormal@;
   margin: 0;
@@ -472,28 +476,28 @@ documenttab[selected=true] .documenttab-
 
 /* Hide the tab toggle if the tabs are visible */
 #tray[visible][expanded] #tool-new-tab {
   opacity: 0;
 }
 
 /* Hide the tab toggle if we're showing classic tabs or we're snap-viewed. */
 #toolbar[viewstate="snapped"],
-#tray[tabsonly=true] #toolbar {
+#tray[tabsonly] #toolbar {
   background: @panel_light_color@ @panel_light_background@;
   -moz-padding-end: 0;
 }
 
 #toolbar-container[viewstate="snapped"],
-#tray[tabsonly=true] #toolbar-container {
+#tray[tabsonly] #toolbar-container {
   -moz-padding-end: 0;
 }
 
 #toolbar-transition[viewstate="snapped"],
-#tray[tabsonly=true] #toolbar-transition {
+#tray[tabsonly] #toolbar-transition {
   visibility: collapse;
 }
 
 /* If we're in the small snap view, compress and simplify the UI. */
 #tray[visible][expanded][viewstate="snapped"] {
   margin-top: -@tabs_height@ !important;
 }
 
@@ -531,17 +535,17 @@ appbar toolbarbutton {
   float: left;
   border-width: 0px;
   margin: 0 @toolbar_horizontal_spacing@;
   padding: 0;
   /* Don't inherit background-color from toolbarbutton[checked="true"] */
   background-color: transparent;
 }
 
-appbar toolbarbutton[disabled="true"] {
+appbar toolbarbutton[disabled] {
   visibility: collapse;
 }
 
 #appbar:not([viewstate="snapped"])[visible] {
   transform: none;
 }
 
 #appbar toolbarbutton {
@@ -601,28 +605,28 @@ appbar toolbarbutton[disabled="true"] {
   -moz-image-region: rect(0px, 240px, 40px, 200px) !important;
 }
 #pin-button:hover {
   -moz-image-region: rect(40px, 240px, 80px, 200px) !important;
 }
 #pin-button:active {
   -moz-image-region: rect(80px, 240px, 120px, 200px) !important;
 }
-#pin-button[checked="true"] {
+#pin-button[checked] {
   -moz-image-region: rect(0px, 280px, 40px, 240px) !important;
 }
 
 #star-button {
   -moz-image-region: rect(0px, 360px, 40px, 320px) !important;
 }
 #star-button:hover {
   -moz-image-region: rect(40px, 360px, 80px, 320px) !important;
 }
 #star-button:active,
-#star-button[checked="true"] {
+#star-button[checked] {
   -moz-image-region: rect(80px, 360px, 120px, 320px) !important;
 }
 
 /* Flyouts ---------------------------------------------------------------- */
 
 /* don't add a margin to the very top settings entry in flyouts */
 flyoutpanel > settings:first-child {
   margin-top: 0px;
@@ -784,17 +788,17 @@ setting[type="directory"] > .preferences
   list-style-image: url(chrome://browser/skin/images/back.png);
   -moz-image-region: rect(0 48px 48px 0);
   padding: 0;
   min-height: 48px;
   max-height: 48px;
   -moz-box-pack: center;
 }
 
-#panel-close-button[disabled="true"] {
+#panel-close-button[disabled] {
   -moz-image-region: rect(0 96px 48px 48px);
 }
 
 #panel-view-switcher {
   border: 0 none !important;
   color: #000 !important;
   background: transparent;
   padding: 0;
@@ -824,17 +828,17 @@ setting[type="directory"] > .preferences
 
 .console-error-msg,
 .console-msg-text {
   white-space: pre-wrap;
 }
 
 /* Context Menu ------------------------------------------------------------ */
 
-#context-commands richlistitem[disabled="true"] {
+#context-commands richlistitem[disabled] {
   display: none;
 }
 
 /* Alert Popup -------------------------------------------------------------- */
 #alerts-container {
   color: white;
   background-color: #5e6166;
   border: @border_width_small@ solid #767973;
@@ -907,17 +911,17 @@ setting[type="directory"] > .preferences
   -moz-border-top-colors: none !important;
   -moz-border-bottom-colors: none !important;
   -moz-border-right-colors: none !important;
   -moz-border-left-colors: none !important;
   border-radius: @border_radius_tiny@;
   border: @border_width_tiny@ solid rgba(255, 255, 255, 0.4) !important;
 }
 
-.scroller[panning="true"] {
+.scroller[panning] {
   opacity: 1;
 }
 
 .scroller[orient="vertical"] {
   min-width: @scroller_thickness@;
   width: @scroller_thickness@;
   min-height: @scroller_minimum@;
 }
--- a/browser/metro/theme/content.css
+++ b/browser/metro/theme/content.css
@@ -53,17 +53,17 @@ xul|window xul|scrollbar[orient="horizon
   border: 0px solid transparent !important;
 }
 
 xul|window xul|scrollbar[orient="horizontal"] xul|thumb {
   max-height: 6px !important;
   min-height: 6px !important;
 }
 
-xul|window xul|*[panning="true"] xul|scrollbar {
+xul|window xul|*[panning] xul|scrollbar {
   opacity: 1;
 }
 
 xul|window xul|scrollbox {
   overflow-y: scroll;
   overflow-x: scroll;
 }
 
@@ -213,17 +213,17 @@ select:not([size]):not([multiple])[disab
 select[size="0"][disabled],
 select[size="1"][disabled] {
   background: transparent -moz-linear-gradient(top, rgba(255,255,255,0.4) 0, rgba(235,235,235,0.4) 3px, rgba(185,185,185,0.4) 100%);
 }
 
 input[type="button"][disabled],
 input[type="submit"][disabled],
 input[type="reset"][disabled],
-button[disabled="true"] {
+button[disabled] {
   padding: 0 7px 0 7px;
   background: transparent -moz-linear-gradient(top, rgba(255,255,255,0.4) 0, rgba(235,235,235,0.4) 3px, rgba(185,185,185,0.4) 100%);
 }
 
 input[type="radio"][disabled],
 input[type="radio"][disabled]:active,
 input[type="radio"][disabled]:hover,
 input[type="radio"][disabled]:hover:active,
--- a/browser/metro/theme/forms.css
+++ b/browser/metro/theme/forms.css
@@ -9,17 +9,17 @@
 #content-navigator {
   display: none;
   pointer-events: none;
   padding: 0;
   background-color: @appbar_color@;
 }
 
 #content-navigator[type="find"],
-#content-navigator[type="form"]:not([disabled="true"]) {
+#content-navigator[type="form"]:not([disabled]) {
   display: -moz-box;
 }
 
 #content-navigator > .previous-button,
 #content-navigator > .next-button,
 #content-navigator > .close-button {
   min-width: @touch_button_small@ !important; /* button size */
   min-height: @touch_button_small@ !important; /* button size */
@@ -170,17 +170,17 @@
 }
 
 #form-helper-suggestions > .autorepeatbutton-up:-moz-locale-dir(rtl) {
   list-style-image: url("chrome://browser/skin/images/arrowright-16.png");
 }
 
 /* force the autorepeat buttons to create a 'padding' when collapsed */
 #form-helper-suggestions > autorepeatbutton[collapsed="true"],
-#form-helper-suggestions > autorepeatbutton[disabled="true"] {
+#form-helper-suggestions > autorepeatbutton[disabled] {
   visibility: hidden;
 }
 
 #form-helper-suggestions .form-helper-suggestions-label {
   padding: @padding_xxnormal@ @padding_normal@; /* 12px helps get row size for the labels */
   margin: 0;
   border-color: transparent rgb(215,215,215) transparent rgb(255,255,255);
   border-style: solid;
--- a/browser/metro/theme/platform.css
+++ b/browser/metro/theme/platform.css
@@ -33,18 +33,18 @@ menulist {
   font-weight: normal !important;
 
   color: @field_foreground_color@;
   background: @field_background_color@;
   border: @metro_border_thick@ solid @field_foreground_color@ !important;
   border-radius: 0;
 }
 
-textbox[disabled="true"],
-menulist[disabled="true"] {
+textbox[disabled],
+menulist[disabled] {
   border-color: @field_disabled_foreground_color@ !important;
   color: @field_disabled_foreground_color@;
 }
 
 menulist:not([disabled]):hover:active {
   color: @field_background_color@;
   background: @field_foreground_color@;
 }
@@ -166,17 +166,17 @@ menulist {
 .menu-container[showingfrom="below"] {
   transform: translateY(@metro_spacing_normal@);
 }
 
 .menu-container[showingfrom="above"] {
   transform: translateY(-@metro_spacing_normal@);
 }
 
-.menu-container[showing="true"] {
+.menu-container[showing] {
   opacity: 1;
   transform: none;
   transition: all ease-out 0.2s;
 }
 
 .menu-popup > richlistbox {
   padding: 3px 0;
   border: #000 solid @metro_border_thick@;
@@ -347,38 +347,38 @@ richlistitem description.normal {
   color: gray;
 }
 
 richlistitem label.normal-bold,
 richlistitem description.normal-bold {
   font-weight: bold;
 }
 
-richlistitem[selected="true"] {
+richlistitem[selected] {
   color: black;
   background-color: white;
 }
 
-richlistitem:hover:active:not([selected="true"]):not([nohighlight="true"]) {
+richlistitem:hover:active:not([selected]) {
   background-color: #8db8d8;
 }
 
 richlistitem.section-header,
-richlistitem[selected="true"].section-header {
+richlistitem[selected].section-header {
   font-weight: bold;
   color: #000;
   background-color: lightgray;
 }
 
-richlistitem[selected="true"] .hide-on-select,
+richlistitem[selected] .hide-on-select,
 richlistitem .show-on-select {
   visibility: collapse;
 }
 
-richlistitem[selected="true"] .show-on-select,
+richlistitem[selected] .show-on-select,
 richlistitem .hide-on-select {
   visibility: visible;
 }
 
 richlistitem[typeName="message"] {
   border-bottom: 0;
 }
 
@@ -464,41 +464,41 @@ richgriditem .richgrid-item-content {
   -moz-box-sizing: border-box;
   padding: 10px 8px 6px 8px;
 }
 
 .richgrid-item-content {
   background: #fff;
 }
 
-richgriditem[selected="true"] .richgrid-item-content {
+richgriditem[selected] .richgrid-item-content {
   border: @metro_border_xthick@ solid @selected_color@;
   padding: @metro_spacing_xxsmall@;
 }
 
 richgriditem .richgrid-icon-container {
   padding-bottom: 2px;
 }
 
 richgriditem .richgrid-icon-box {
   padding: 4px;
   background: #fff;
   opacity: 1.0;
 }
 
 
-richgriditem[customColorPresent="true"] {
+richgriditem[customColorPresent] {
   color: #f1f1f1;
 }
 richgriditem[customImagePresent] {
   color: #1a1a1a;
 }
 
 
-richgriditem[customColorPresent="true"] .richgrid-icon-box {
+richgriditem[customColorPresent] .richgrid-icon-box {
   opacity: 0.8;
   background-color: #fff;
 }
 
 .richgrid-item-content[customImagePresent] {
   height: 120px;
   width: 200px;
   background-size: cover;
--- 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/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -1546,16 +1546,23 @@ public:
    * called yet.
    */
   bool IsShowing() const { return mIsShowing; }
   /**
    * Return whether the document is currently visible (in the sense of
    * OnPageHide having been called and OnPageShow not yet having been called)
    */
   bool IsVisible() const { return mVisible; }
+
+  /**
+   * Return whether the document and all its ancestors are visible in the sense of
+   * pageshow / hide.
+   */
+  bool IsVisibleConsideringAncestors() const;
+
   /**
    * Return true when this document is active, i.e., the active document
    * in a content viewer.
    */
   bool IsActive() const { return mDocumentContainer && !mRemovedFromDocShell; }
 
   void RegisterFreezableElement(nsIContent* aContent);
   bool UnregisterFreezableElement(nsIContent* aContent);
--- 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/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1917,16 +1917,29 @@ nsIDocument::GetExtraPropertyTable(uint1
 {
   NS_ASSERTION(aCategory > 0, "Category 0 should have already been handled");
   while (aCategory >= mExtraPropertyTables.Length() + 1) {
     mExtraPropertyTables.AppendElement(new nsPropertyTable());
   }
   return mExtraPropertyTables[aCategory - 1];
 }
 
+bool
+nsIDocument::IsVisibleConsideringAncestors() const
+{
+  const nsIDocument *parent = this;
+  do {
+    if (!parent->IsVisible()) {
+      return false;
+    }
+  } while ((parent = parent->GetParentDocument()));
+
+  return true;
+      }
+
 void
 nsDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup)
 {
   nsCOMPtr<nsIURI> uri;
   nsCOMPtr<nsIPrincipal> principal;
   if (aChannel) {
     // Note: this code is duplicated in nsXULDocument::StartDocumentLoad and
     // nsScriptSecurityManager::GetChannelPrincipal.
--- 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/nsDOMMouseEvent.cpp
+++ b/content/events/src/nsDOMMouseEvent.cpp
@@ -175,16 +175,49 @@ nsDOMMouseEvent::InitFromCtor(const nsAS
       break;
     default:
       break;
   }
 
   return NS_OK;
 }
 
+already_AddRefed<nsDOMMouseEvent>
+nsDOMMouseEvent::Constructor(const mozilla::dom::GlobalObject& aGlobal,
+                             const nsAString& aType,
+                             const mozilla::dom::MouseEventInit& aParam,
+                             mozilla::ErrorResult& aRv)
+{
+  nsCOMPtr<mozilla::dom::EventTarget> t = do_QueryInterface(aGlobal.Get());
+  nsRefPtr<nsDOMMouseEvent> e = new nsDOMMouseEvent(t, nullptr, nullptr);
+  e->SetIsDOMBinding();
+  bool trusted = e->Init(t);
+  e->InitMouseEvent(aType, aParam.mBubbles, aParam.mCancelable,
+                    aParam.mView, aParam.mDetail, aParam.mScreenX,
+                    aParam.mScreenY, aParam.mClientX, aParam.mClientY,
+                    aParam.mCtrlKey, aParam.mAltKey, aParam.mShiftKey,
+                    aParam.mMetaKey, aParam.mButton, aParam.mRelatedTarget,
+                    aRv);
+  e->SetTrusted(trusted);
+
+  switch (e->mEvent->eventStructType) {
+    case NS_MOUSE_EVENT:
+    case NS_MOUSE_SCROLL_EVENT:
+    case NS_WHEEL_EVENT:
+    case NS_DRAG_EVENT:
+    case NS_SIMPLE_GESTURE_EVENT:
+      static_cast<nsMouseEvent_base*>(e->mEvent)->buttons = aParam.mButtons;
+      break;
+    default:
+      break;
+  }
+
+  return e.forget();
+}
+
 NS_IMETHODIMP
 nsDOMMouseEvent::InitNSMouseEvent(const nsAString & aType, bool aCanBubble, bool aCancelable,
                                   nsIDOMWindow *aView, int32_t aDetail, int32_t aScreenX,
                                   int32_t aScreenY, int32_t aClientX, int32_t aClientY,
                                   bool aCtrlKey, bool aAltKey, bool aShiftKey,
                                   bool aMetaKey, uint16_t aButton, nsIDOMEventTarget *aRelatedTarget,
                                   float aPressure, uint16_t aInputSource)
 {
@@ -198,186 +231,224 @@ nsDOMMouseEvent::InitNSMouseEvent(const 
   static_cast<nsMouseEvent_base*>(mEvent)->inputSource = aInputSource;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetButton(uint16_t* aButton)
 {
   NS_ENSURE_ARG_POINTER(aButton);
+  *aButton = Button();
+  return NS_OK;
+}
+
+uint16_t
+nsDOMMouseEvent::Button()
+{
   switch(mEvent->eventStructType)
   {
     case NS_MOUSE_EVENT:
     case NS_MOUSE_SCROLL_EVENT:
     case NS_WHEEL_EVENT:
     case NS_DRAG_EVENT:
     case NS_SIMPLE_GESTURE_EVENT:
-      *aButton = static_cast<nsMouseEvent_base*>(mEvent)->button;
-      break;
+      return static_cast<nsMouseEvent_base*>(mEvent)->button;
     default:
       NS_WARNING("Tried to get mouse button for non-mouse event!");
-      *aButton = nsMouseEvent::eLeftButton;
-      break;
+      return nsMouseEvent::eLeftButton;
   }
-  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetButtons(uint16_t* aButtons)
 {
   NS_ENSURE_ARG_POINTER(aButtons);
+  *aButtons = Buttons();
+  return NS_OK;
+}
+
+uint16_t
+nsDOMMouseEvent::Buttons()
+{
   switch(mEvent->eventStructType)
   {
     case NS_MOUSE_EVENT:
     case NS_MOUSE_SCROLL_EVENT:
     case NS_WHEEL_EVENT:
     case NS_DRAG_EVENT:
     case NS_SIMPLE_GESTURE_EVENT:
-      *aButtons = static_cast<nsMouseEvent_base*>(mEvent)->buttons;
-      break;
+      return static_cast<nsMouseEvent_base*>(mEvent)->buttons;
     default:
       MOZ_NOT_REACHED("Tried to get mouse buttons for non-mouse event!");
-      *aButtons = 0;
-      break;
+      return 0;
   }
-  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetRelatedTarget(nsIDOMEventTarget** aRelatedTarget)
 {
   NS_ENSURE_ARG_POINTER(aRelatedTarget);
-  *aRelatedTarget = nullptr;
-  nsISupports* relatedTarget = nullptr;
+  *aRelatedTarget = GetRelatedTarget().get();
+  return NS_OK;
+}
+
+already_AddRefed<mozilla::dom::EventTarget>
+nsDOMMouseEvent::GetRelatedTarget()
+{
+  nsCOMPtr<mozilla::dom::EventTarget> relatedTarget;
   switch(mEvent->eventStructType)
   {
     case NS_MOUSE_EVENT:
     case NS_MOUSE_SCROLL_EVENT:
     case NS_WHEEL_EVENT:
     case NS_DRAG_EVENT:
     case NS_SIMPLE_GESTURE_EVENT:
-      relatedTarget = static_cast<nsMouseEvent_base*>(mEvent)->relatedTarget;
+      relatedTarget = do_QueryInterface(static_cast<nsMouseEvent_base*>(mEvent)->relatedTarget);
       break;
     default:
       break;
   }
 
   if (relatedTarget) {
     nsCOMPtr<nsIContent> content = do_QueryInterface(relatedTarget);
     if (content && content->ChromeOnlyAccess() &&
         !nsContentUtils::CanAccessNativeAnon()) {
-      relatedTarget = content->FindFirstNonChromeOnlyAccessContent();
-      if (!relatedTarget) {
-        return NS_OK;
-      }
+      relatedTarget = do_QueryInterface(content->FindFirstNonChromeOnlyAccessContent());
     }
 
-    CallQueryInterface(relatedTarget, aRelatedTarget);
+    if (relatedTarget) {
+      relatedTarget = relatedTarget->GetTargetForDOMEvent();
+    }
+    return relatedTarget.forget();
   }
-  return NS_OK;
+  return nullptr;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetMozMovementX(int32_t* aMovementX)
 {
   NS_ENSURE_ARG_POINTER(aMovementX);
-  *aMovementX = GetMovementPoint().x;
+  *aMovementX = MozMovementX();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetMozMovementY(int32_t* aMovementY)
 {
   NS_ENSURE_ARG_POINTER(aMovementY);
-  *aMovementY = GetMovementPoint().y;
+  *aMovementY = MozMovementY();
 
   return NS_OK;
 }
 
 NS_METHOD nsDOMMouseEvent::GetScreenX(int32_t* aScreenX)
 {
   NS_ENSURE_ARG_POINTER(aScreenX);
-  *aScreenX = nsDOMEvent::GetScreenCoords(mPresContext,
-                                          mEvent,
-                                          mEvent->refPoint).x;
+  *aScreenX = ScreenX();
   return NS_OK;
 }
 
+int32_t
+nsDOMMouseEvent::ScreenX()
+{
+  return nsDOMEvent::GetScreenCoords(mPresContext,
+                                     mEvent,
+                                     mEvent->refPoint).x;
+}
+
 NS_IMETHODIMP
 nsDOMMouseEvent::GetScreenY(int32_t* aScreenY)
 {
   NS_ENSURE_ARG_POINTER(aScreenY);
-  *aScreenY = nsDOMEvent::GetScreenCoords(mPresContext,
-                                          mEvent,
-                                          mEvent->refPoint).y;
+  *aScreenY = ScreenY();
   return NS_OK;
 }
 
+int32_t
+nsDOMMouseEvent::ScreenY()
+{
+  return nsDOMEvent::GetScreenCoords(mPresContext,
+                                     mEvent,
+                                     mEvent->refPoint).y;
+}
+
 
 NS_METHOD nsDOMMouseEvent::GetClientX(int32_t* aClientX)
 {
   NS_ENSURE_ARG_POINTER(aClientX);
-  *aClientX = nsDOMEvent::GetClientCoords(mPresContext,
-                                          mEvent,
-                                          mEvent->refPoint,
-                                          mClientPoint).x;
+  *aClientX = ClientX();
   return NS_OK;
 }
 
+int32_t
+nsDOMMouseEvent::ClientX()
+{
+  return nsDOMEvent::GetClientCoords(mPresContext,
+                                     mEvent,
+                                     mEvent->refPoint,
+                                     mClientPoint).x;
+}
+
 NS_IMETHODIMP
 nsDOMMouseEvent::GetClientY(int32_t* aClientY)
 {
   NS_ENSURE_ARG_POINTER(aClientY);
-  *aClientY = nsDOMEvent::GetClientCoords(mPresContext,
-                                          mEvent,
-                                          mEvent->refPoint,
-                                          mClientPoint).y;
+  *aClientY = ClientY();
   return NS_OK;
 }
 
+int32_t
+nsDOMMouseEvent::ClientY()
+{
+  return nsDOMEvent::GetClientCoords(mPresContext,
+                                     mEvent,
+                                     mEvent->refPoint,
+                                     mClientPoint).y;
+}
+
 NS_IMETHODIMP
 nsDOMMouseEvent::GetAltKey(bool* aIsDown)
 {
   NS_ENSURE_ARG_POINTER(aIsDown);
-  *aIsDown = static_cast<nsInputEvent*>(mEvent)->IsAlt();
+  *aIsDown = AltKey();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetCtrlKey(bool* aIsDown)
 {
   NS_ENSURE_ARG_POINTER(aIsDown);
-  *aIsDown = static_cast<nsInputEvent*>(mEvent)->IsControl();
+  *aIsDown = CtrlKey();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetShiftKey(bool* aIsDown)
 {
   NS_ENSURE_ARG_POINTER(aIsDown);
-  *aIsDown = static_cast<nsInputEvent*>(mEvent)->IsShift();
+  *aIsDown = ShiftKey();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetMetaKey(bool* aIsDown)
 {
   NS_ENSURE_ARG_POINTER(aIsDown);
-  *aIsDown = static_cast<nsInputEvent*>(mEvent)->IsMeta();
+  *aIsDown = MetaKey();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetModifierState(const nsAString& aKey,
                                   bool* aState)
 {
   NS_ENSURE_ARG_POINTER(aState);
 
-  *aState = GetModifierStateInternal(aKey);
+  *aState = GetModifierState(aKey);
   return NS_OK;
 }
 
 /* virtual */
 nsresult
 nsDOMMouseEvent::Which(uint32_t* aWhich)
 {
   NS_ENSURE_ARG_POINTER(aWhich);
@@ -386,28 +457,29 @@ nsDOMMouseEvent::Which(uint32_t* aWhich)
   *aWhich = button + 1;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetMozPressure(float* aPressure)
 {
   NS_ENSURE_ARG_POINTER(aPressure);
-  *aPressure = static_cast<nsMouseEvent_base*>(mEvent)->pressure;
+  *aPressure = MozPressure();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetMozInputSource(uint16_t* aInputSource)
 {
   NS_ENSURE_ARG_POINTER(aInputSource);
-  *aInputSource = static_cast<nsMouseEvent_base*>(mEvent)->inputSource;
+  *aInputSource = MozInputSource();
   return NS_OK;
 }
 
 nsresult NS_NewDOMMouseEvent(nsIDOMEvent** aInstancePtrResult,
                              mozilla::dom::EventTarget* aOwner,
                              nsPresContext* aPresContext,
                              nsInputEvent *aEvent)
 {
   nsDOMMouseEvent* it = new nsDOMMouseEvent(aOwner, aPresContext, aEvent);
+  it->SetIsDOMBinding();
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMMouseEvent.h
+++ b/content/events/src/nsDOMMouseEvent.h
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsDOMMouseEvent_h__
 #define nsDOMMouseEvent_h__
 
 #include "nsIDOMMouseEvent.h"
 #include "nsDOMUIEvent.h"
+#include "mozilla/dom/MouseEventBinding.h"
 
 class nsEvent;
 
 class nsDOMMouseEvent : public nsDOMUIEvent,
                         public nsIDOMMouseEvent
 {
 public:
   nsDOMMouseEvent(mozilla::dom::EventTarget* aOwner,
@@ -22,18 +23,102 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMMouseEvent Interface
   NS_DECL_NSIDOMMOUSEEVENT
 
   // Forward to base class
   NS_FORWARD_TO_NSDOMUIEVENT
 
+  virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope) MOZ_OVERRIDE
+  {
+    return mozilla::dom::MouseEventBinding::Wrap(aCx, aScope, this);
+  }
+
   virtual nsresult InitFromCtor(const nsAString& aType,
                                 JSContext* aCx, JS::Value* aVal);
+
+  // Web IDL binding methods
+  int32_t ScreenX();
+  int32_t ScreenY();
+  int32_t ClientX();
+  int32_t ClientY();
+  bool CtrlKey()
+  {
+    return static_cast<nsInputEvent*>(mEvent)->IsControl();
+  }
+  bool ShiftKey()
+  {
+    return static_cast<nsInputEvent*>(mEvent)->IsShift();
+  }
+  bool AltKey()
+  {
+    return static_cast<nsInputEvent*>(mEvent)->IsAlt();
+  }
+  bool MetaKey()
+  {
+    return static_cast<nsInputEvent*>(mEvent)->IsMeta();
+  }
+  uint16_t Button();
+  uint16_t Buttons();
+  already_AddRefed<mozilla::dom::EventTarget> GetRelatedTarget();
+  void InitMouseEvent(const nsAString & aType, bool aCanBubble, bool aCancelable,
+                      nsIDOMWindow* aView, int32_t aDetail, int32_t aScreenX,
+                      int32_t aScreenY, int32_t aClientX, int32_t aClientY,
+                      bool aCtrlKey, bool aAltKey, bool aShiftKey,
+                      bool aMetaKey, uint16_t aButton,
+                      mozilla::dom::EventTarget *aRelatedTarget,
+                      mozilla::ErrorResult& aRv)
+  {
+    aRv = InitMouseEvent(aType, aCanBubble, aCancelable,
+                         aView, aDetail, aScreenX, aScreenY,
+                         aClientX, aClientY, aCtrlKey, aAltKey,
+                         aShiftKey, aMetaKey, aButton,
+                         aRelatedTarget);
+  }
+  bool GetModifierState(const nsAString& aKeyArg)
+  {
+    return GetModifierStateInternal(aKeyArg);
+  }
+  static already_AddRefed<nsDOMMouseEvent> Constructor(const mozilla::dom::GlobalObject& aGlobal,
+                                                       const nsAString& aType,
+                                                       const mozilla::dom::MouseEventInit& aParam,
+                                                       mozilla::ErrorResult& aRv);
+  int32_t MozMovementX()
+  {
+    return GetMovementPoint().x;
+  }
+  int32_t MozMovementY()
+  {
+    return GetMovementPoint().y;
+  }
+  float MozPressure() const
+  {
+    return static_cast<nsMouseEvent_base*>(mEvent)->pressure;
+  }
+  uint16_t MozInputSource() const
+  {
+    return static_cast<nsMouseEvent_base*>(mEvent)->inputSource;
+  }
+  void InitNSMouseEvent(const nsAString & aType, bool aCanBubble, bool aCancelable,
+                        nsIDOMWindow *aView, int32_t aDetail, int32_t aScreenX,
+                        int32_t aScreenY, int32_t aClientX, int32_t aClientY,
+                        bool aCtrlKey, bool aAltKey, bool aShiftKey,
+                        bool aMetaKey, uint16_t aButton,
+                        mozilla::dom::EventTarget *aRelatedTarget,
+                        float aPressure, uint16_t aInputSource,
+                        mozilla::ErrorResult& aRv)
+  {
+    aRv = InitNSMouseEvent(aType, aCanBubble, aCancelable,
+                           aView, aDetail, aScreenX, aScreenY,
+                           aClientX, aClientY, aCtrlKey, aAltKey,
+                           aShiftKey, aMetaKey, aButton,
+                           aRelatedTarget, aPressure, aInputSource);
+  }
+
 protected:
   // Specific implementation for a mouse event.
   virtual nsresult Which(uint32_t* aWhich);
 
   nsresult InitMouseEvent(const nsAString& aType,
                           bool aCanBubble,
                           bool aCancelable,
                           nsIDOMWindow* aView,
--- 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;