Merge MC -> JM
authorBrian Hackett <bhackett1024@gmail.com>
Wed, 30 Nov 2011 12:45:27 -0800
changeset 82988 239e7d505041f16f5a727d388d4c4b8997f00163
parent 82987 6ad434f16abf9448174929d9d1f3761432635294 (current diff)
parent 82631 87da67ee3e59c01da745c148d147cd0bd688fc01 (diff)
child 82989 3dca8a1ee5febc58c7297986b6f1d219fc5a3321
push id519
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 00:38:35 +0000
treeherdermozilla-beta@788ea1ef610b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone11.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge MC -> JM
browser/devtools/webconsole/test/browser/browser_webconsole_storage_create_display.js
browser/devtools/webconsole/test/browser/browser_webconsole_storage_iteration.js
browser/devtools/webconsole/test/browser/browser_webconsole_storage_record_entry.js
browser/devtools/webconsole/test/browser/browser_webconsole_storage_record_many_entries.js
browser/themes/gnomestripe/feeds/audioFeedIcon.png
browser/themes/gnomestripe/feeds/audioFeedIcon16.png
browser/themes/gnomestripe/feeds/videoFeedIcon.png
browser/themes/gnomestripe/feeds/videoFeedIcon16.png
browser/themes/pinstripe/feeds/audioFeedIcon.png
browser/themes/pinstripe/feeds/audioFeedIcon16.png
browser/themes/pinstripe/feeds/videoFeedIcon.png
browser/themes/pinstripe/feeds/videoFeedIcon16.png
browser/themes/winstripe/aboutSessionRestore-window-icon.png
browser/themes/winstripe/feeds/audioFeedIcon-aero.png
browser/themes/winstripe/feeds/audioFeedIcon.png
browser/themes/winstripe/feeds/audioFeedIcon16-aero.png
browser/themes/winstripe/feeds/audioFeedIcon16.png
browser/themes/winstripe/feeds/videoFeedIcon-aero.png
browser/themes/winstripe/feeds/videoFeedIcon.png
browser/themes/winstripe/feeds/videoFeedIcon16-aero.png
browser/themes/winstripe/feeds/videoFeedIcon16.png
browser/themes/winstripe/places/searching_16-aero.png
browser/themes/winstripe/preferences/plugin-aero.png
dom/interfaces/base/nsIAnimationFrameListener.idl
extensions/pref/system-pref/src/Makefile.in
extensions/pref/system-pref/src/gconf/Makefile.in
extensions/pref/system-pref/src/gconf/gconf_pref_list.inc
extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp
extensions/pref/system-pref/src/gconf/nsSystemPrefService.h
extensions/pref/system-pref/src/nsSystemPref.cpp
extensions/pref/system-pref/src/nsSystemPref.h
extensions/pref/system-pref/src/nsSystemPrefFactory.cpp
extensions/pref/system-pref/src/nsSystemPrefLog.h
js/public/HashTable.h
js/src/ctypes/CTypes.cpp
js/src/frontend/BytecodeCompiler.cpp
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/FoldConstants.cpp
js/src/frontend/ParseNode.cpp
js/src/frontend/ParseNode.h
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
js/src/frontend/SemanticAnalysis.cpp
js/src/jsapi.h
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsgc.h
js/src/jsinfer.cpp
js/src/jsinterp.cpp
js/src/jsiter.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsprvtd.h
js/src/jsreflect.cpp
js/src/jsscope.h
js/src/jsscript.cpp
js/src/jsscript.h
js/src/methodjit/Compiler.cpp
js/src/methodjit/MethodJIT.cpp
js/src/methodjit/MethodJIT.h
js/src/shell/js.cpp
js/src/vm/RegExpObject-inl.h
js/src/vm/RegExpObject.cpp
js/src/vm/RegExpObject.h
js/src/vm/String.h
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCInlines.h
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCQuickStubs.cpp
js/xpconnect/src/XPCWrappedNativeInfo.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/dombindings.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
layout/xul/base/src/tree/src/nsITreeImageListener.h
toolkit/components/places/nsIDynamicContainer.idl
toolkit/components/places/tests/unit/nsDynamicContainerServiceSample.js
toolkit/components/places/tests/unit/nsDynamicContainerServiceSample.manifest
toolkit/components/places/tests/unit/test_457698_crash.js
toolkit/components/places/tests/unit/test_dynamic_containers.js
toolkit/content/tests/chrome/test_autocomplete.xul
toolkit/crashreporter/google-breakpad/src/common/md5.c
toolkit/mozapps/webapps/Makefile.in
toolkit/mozapps/webapps/OpenWebapps.idl
toolkit/mozapps/webapps/OpenWebapps.js
toolkit/mozapps/webapps/OpenWebapps.jsm
toolkit/mozapps/webapps/OpenWebapps.manifest
toolkit/themes/gnomestripe/global/icons/webconsole.png
toolkit/themes/gnomestripe/global/webConsole.css
toolkit/themes/gnomestripe/global/webConsole_networkPanel.css
toolkit/themes/gnomestripe/mozapps/extensions/category-extensions.png
toolkit/themes/gnomestripe/mozapps/extensions/category-languages.png
toolkit/themes/gnomestripe/mozapps/extensions/category-themes.png
toolkit/themes/gnomestripe/mozapps/passwordmgr/key.png
toolkit/themes/gnomestripe/mozapps/places/tagContainerIcon.png
toolkit/themes/gnomestripe/mozapps/plugins/pluginOutdated-16.png
toolkit/themes/pinstripe/global/dirListing/local.png
toolkit/themes/pinstripe/global/icons/webconsole.png
toolkit/themes/pinstripe/global/notification/question-icon.png
toolkit/themes/pinstripe/global/webConsole.css
toolkit/themes/pinstripe/global/webConsole_networkPanel.css
toolkit/themes/pinstripe/mozapps/extensions/category-extensions.png
toolkit/themes/pinstripe/mozapps/extensions/category-languages.png
toolkit/themes/pinstripe/mozapps/extensions/category-themes.png
toolkit/themes/pinstripe/mozapps/places/tagContainerIcon.png
toolkit/themes/winstripe/global/arrow/arrow-lft-hov.gif
toolkit/themes/winstripe/global/arrow/arrow-rit-hov.gif
toolkit/themes/winstripe/global/console/bullet-error-aero.png
toolkit/themes/winstripe/global/console/bullet-error.png
toolkit/themes/winstripe/global/console/bullet-question-aero.png
toolkit/themes/winstripe/global/console/bullet-question.png
toolkit/themes/winstripe/global/console/bullet-warning-aero.png
toolkit/themes/winstripe/global/console/bullet-warning.png
toolkit/themes/winstripe/global/icons/informationBar-30-aero.png
toolkit/themes/winstripe/global/icons/informationBar-30.png
toolkit/themes/winstripe/global/icons/informationBar-60-aero.png
toolkit/themes/winstripe/global/icons/informationBar-60.png
toolkit/themes/winstripe/global/icons/loading_16-aero.png
toolkit/themes/winstripe/global/icons/notfound-aero.png
toolkit/themes/winstripe/global/icons/notfound.png
toolkit/themes/winstripe/global/icons/notloading_16-aero.png
toolkit/themes/winstripe/global/icons/questionBar-30-aero.png
toolkit/themes/winstripe/global/icons/questionBar-30.png
toolkit/themes/winstripe/global/icons/questionBar-60-aero.png
toolkit/themes/winstripe/global/icons/questionBar-60.png
toolkit/themes/winstripe/global/icons/webconsole.png
toolkit/themes/winstripe/global/webConsole.css
toolkit/themes/winstripe/global/webConsole_networkPanel.css
toolkit/themes/winstripe/mozapps/extensions/category-extensions-aero.png
toolkit/themes/winstripe/mozapps/extensions/category-extensions.png
toolkit/themes/winstripe/mozapps/extensions/category-languages-aero.png
toolkit/themes/winstripe/mozapps/extensions/category-languages.png
toolkit/themes/winstripe/mozapps/extensions/category-themes-aero.png
toolkit/themes/winstripe/mozapps/extensions/category-themes.png
toolkit/themes/winstripe/mozapps/places/tagContainerIcon-aero.png
toolkit/themes/winstripe/mozapps/places/tagContainerIcon.png
toolkit/themes/winstripe/mozapps/plugins/pluginFinderWizard.css
toolkit/themes/winstripe/mozapps/plugins/pluginHelp-16-aero.png
toolkit/themes/winstripe/mozapps/plugins/pluginOutdated-16-aero.png
toolkit/themes/winstripe/mozapps/plugins/pluginOutdated-16.png
--- a/Makefile.in
+++ b/Makefile.in
@@ -61,17 +61,17 @@ TIERS += base
 tier_base_dirs = \
 	config \
 	build \
 	probes \
 	$(NULL)
 
 ifndef LIBXUL_SDK
 ifeq (android,$(MOZ_WIDGET_TOOLKIT))
-tier_base_dirs += other-licenses/android
+tier_base_dirs += other-licenses/android other-licenses/skia-npapi
 endif
 
 tier_base_dirs += memory
 endif
 
 ifdef COMPILE_ENVIRONMENT
 include $(topsrcdir)/$(MOZ_BUILD_APP)/build.mk
 endif
--- a/accessible/src/atk/nsApplicationAccessibleWrap.cpp
+++ b/accessible/src/atk/nsApplicationAccessibleWrap.cpp
@@ -39,37 +39,42 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsApplicationAccessibleWrap.h"
 
 #include "nsCOMPtr.h"
 #include "nsMai.h"
 #include "prlink.h"
 #include "prenv.h"
-#include "nsIPrefBranch.h"
+#include "mozilla/Preferences.h"
+#include "nsIGConfService.h"
 #include "nsIServiceManager.h"
 #include "nsAutoPtr.h"
 #include "nsAccessibilityService.h"
 #include "AtkSocketAccessible.h"
 
 #include <gtk/gtk.h>
 #include <atk/atk.h>
 
+using namespace mozilla;
+
 typedef GType (* AtkGetTypeType) (void);
 GType g_atk_hyperlink_impl_type = G_TYPE_INVALID;
 static bool sATKChecked = false;
 static PRLibrary *sATKLib = nsnull;
 static const char sATKLibName[] = "libatk-1.0.so.0";
 static const char sATKHyperlinkImplGetTypeSymbol[] =
     "atk_hyperlink_impl_get_type";
 static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
-static const char sSysPrefService [] =
-    "@mozilla.org/system-preference-service;1";
+static const char sUseSystemPrefsKey[] =
+    "config.use_system_prefs";
 static const char sAccessibilityKey [] =
     "config.use_system_prefs.accessibility";
+static const char sGconfAccessibilityKey[] =
+    "/desktop/gnome/interface/accessibility";
 
 /* gail function pointer */
 static guint (* gail_add_global_event_listener) (GSignalEmissionHook listener,
                                                  const gchar *event_type);
 static void (* gail_remove_global_event_listener) (guint remove_listener);
 static void (* gail_remove_key_event_listener) (guint remove_listener);
 static AtkObject * (*gail_get_root) (void);
 
@@ -620,21 +625,27 @@ nsApplicationAccessibleWrap::Init()
 
     // check if accessibility enabled/disabled by environment variable
     bool isGnomeATEnabled = false;
     const char *envValue = PR_GetEnv(sAccEnv);
     if (envValue) {
         isGnomeATEnabled = !!atoi(envValue);
     } else {
         //check gconf-2 setting
-        nsresult rv;
-        nsCOMPtr<nsIPrefBranch> sysPrefService =
-            do_GetService(sSysPrefService, &rv);
-        if (NS_SUCCEEDED(rv) && sysPrefService) {
-            sysPrefService->GetBoolPref(sAccessibilityKey, &isGnomeATEnabled);
+        if (Preferences::GetBool(sUseSystemPrefsKey, false)) {
+            nsresult rv;
+            nsCOMPtr<nsIGConfService> gconf =
+                do_GetService(NS_GCONFSERVICE_CONTRACTID, &rv);
+            if (NS_SUCCEEDED(rv) && gconf) {
+                gconf->GetBool(NS_LITERAL_CSTRING(sGconfAccessibilityKey),
+                               &isGnomeATEnabled);
+            }
+        } else {
+            isGnomeATEnabled =
+                Preferences::GetBool(sAccessibilityKey, false);
         }
     }
 
     if (isGnomeATEnabled) {
         // load and initialize gail library
         nsresult rv = LoadGtkModule(sGail);
         if (NS_SUCCEEDED(rv)) {
             (*sGail.init)();
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -45,16 +45,17 @@
 #include "nsApplicationAccessibleWrap.h"
 #include "nsARIAGridAccessibleWrap.h"
 #include "nsARIAMap.h"
 #include "FocusManager.h"
 
 #include "nsIContentViewer.h"
 #include "nsCURILoader.h"
 #include "nsDocAccessible.h"
+#include "nsHTMLCanvasAccessible.h"
 #include "nsHTMLImageMapAccessible.h"
 #include "nsHTMLLinkAccessible.h"
 #include "nsHTMLSelectAccessible.h"
 #include "nsHTMLTableAccessibleWrap.h"
 #include "nsHTMLTextAccessible.h"
 #include "nsHyperTextAccessibleWrap.h"
 #include "nsIAccessibilityService.h"
 #include "nsIAccessibleProvider.h"
@@ -271,16 +272,26 @@ nsAccessibilityService::CreateHTMLCombob
 {
   nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
   nsAccessible* accessible = new nsHTMLComboboxAccessible(aContent, weakShell);
   NS_IF_ADDREF(accessible);
   return accessible;
 }
 
 already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLCanvasAccessible(nsIContent* aContent,
+                                                   nsIPresShell* aPresShell)
+{
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLCanvasAccessible(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
+}
+
+already_AddRefed<nsAccessible>
 nsAccessibilityService::CreateHTMLImageAccessible(nsIContent* aContent,
                                                   nsIPresShell* aPresShell)
 {
   nsAutoString mapElmName;
   aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usemap, mapElmName);
   nsCOMPtr<nsIDOMHTMLMapElement> mapElm;
   if (nsIDocument* document = aContent->GetCurrentDoc()) {
     mapElm = do_QueryInterface(document->FindImageMap(mapElmName));
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -78,16 +78,18 @@ public:
                                                   bool aCanCreate);
 
   virtual already_AddRefed<nsAccessible>
     CreateHTMLBRAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   virtual already_AddRefed<nsAccessible>
     CreateHTML4ButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   virtual already_AddRefed<nsAccessible>
     CreateHTMLButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
+  already_AddRefed<nsAccessible>
+    CreateHTMLCanvasAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   virtual already_AddRefed<nsAccessible>
     CreateHTMLCaptionAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   virtual already_AddRefed<nsAccessible>
     CreateHTMLCheckboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   virtual already_AddRefed<nsAccessible>
     CreateHTMLComboboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   virtual already_AddRefed<nsAccessible>
     CreateHTMLGroupboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
--- a/accessible/src/html/Makefile.in
+++ b/accessible/src/html/Makefile.in
@@ -45,16 +45,17 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE = accessibility
 LIBRARY_NAME = accessibility_html_s
 LIBXUL_LIBRARY = 1
 
 
 
 CPPSRCS = \
+  nsHTMLCanvasAccessible.cpp \
   nsHTMLFormControlAccessible.cpp \
   nsHTMLImageAccessible.cpp \
   nsHTMLImageMapAccessible.cpp \
   nsHTMLLinkAccessible.cpp \
   nsHTMLSelectAccessible.cpp \
   nsHTMLTableAccessible.cpp \
   nsHTMLTextAccessible.cpp \
   nsHyperTextAccessible.cpp \
new file mode 100644
--- /dev/null
+++ b/accessible/src/html/nsHTMLCanvasAccessible.cpp
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsHTMLCanvasAccessible.h"
+
+using namespace mozilla::a11y;
+
+nsHTMLCanvasAccessible::
+  nsHTMLCanvasAccessible(nsIContent* aContent, nsIWeakReference* aShell) :
+  nsHyperTextAccessible(aContent, aShell)
+{
+}
+
+PRUint32
+nsHTMLCanvasAccessible::NativeRole()
+{
+  return nsIAccessibleRole::ROLE_CANVAS;
+}
new file mode 100644
--- /dev/null
+++ b/accessible/src/html/nsHTMLCanvasAccessible.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsHyperTextAccessible.h"
+
+#ifndef _nsHTMLCanvasAccessible_H_
+#define _nsHTMLCanvasAccessible_H_
+
+/**
+ * HTML canvas accessible (html:canvas).
+ */
+class nsHTMLCanvasAccessible : public nsHyperTextAccessible
+{
+public:
+  nsHTMLCanvasAccessible(nsIContent* aContent, nsIWeakReference* aShell);
+  virtual ~nsHTMLCanvasAccessible() { }
+
+  // nsAccessible
+  virtual PRUint32 NativeRole();
+};
+
+#endif
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -1409,16 +1409,19 @@ nsHTMLTableAccessible::IsProbablyForLayo
 
   if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::role)) {
     // Role attribute is present, but overridden roles have already been dealt with.
     // Only landmarks and other roles that don't override the role from native
     // markup are left to deal with here.
     RETURN_LAYOUT_ANSWER(false, "Has role attribute, weak role, and role is table");
   }
 
+  if (mContent->Tag() != nsGkAtoms::table)
+    RETURN_LAYOUT_ANSWER(true, "table built by CSS display:table style");
+
   // Check if datatable attribute has "0" value.
   if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::datatable,
                             NS_LITERAL_STRING("0"), eCaseMatters)) {
     RETURN_LAYOUT_ANSWER(true, "Has datatable = 0 attribute, it's for layout");
   }
 
   // Check for legitimate data table attributes.
   nsAutoString summary;
--- a/accessible/src/msaa/CAccessibleText.cpp
+++ b/accessible/src/msaa/CAccessibleText.cpp
@@ -171,16 +171,18 @@ CAccessibleText::get_characterExtents(lo
 
 STDMETHODIMP
 CAccessibleText::get_nSelections(long *aNSelections)
 {
 __try {
   *aNSelections = 0;
 
   nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
+  if (textAcc->IsDefunct())
+    return E_FAIL;
 
   PRInt32 selCount = 0;
   nsresult rv = textAcc->GetSelectionCount(&selCount);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aNSelections = selCount;
   return S_OK;
--- a/accessible/tests/mochitest/role.js
+++ b/accessible/tests/mochitest/role.js
@@ -2,16 +2,17 @@
 // Role constants
 
 const ROLE_ALERT = nsIAccessibleRole.ROLE_ALERT;
 const ROLE_ANIMATION = nsIAccessibleRole.ROLE_ANIMATION;
 const ROLE_APPLICATION = nsIAccessibleRole.ROLE_APPLICATION;
 const ROLE_APP_ROOT = nsIAccessibleRole.ROLE_APP_ROOT;
 const ROLE_AUTOCOMPLETE = nsIAccessibleRole.ROLE_AUTOCOMPLETE;
 const ROLE_BUTTONDROPDOWNGRID = nsIAccessibleRole.ROLE_BUTTONDROPDOWNGRID;
+const ROLE_CANVAS = nsIAccessibleRole.ROLE_CANVAS;
 const ROLE_CAPTION = nsIAccessibleRole.ROLE_CAPTION;
 const ROLE_CELL = nsIAccessibleRole.ROLE_CELL;
 const ROLE_CHECKBUTTON = nsIAccessibleRole.ROLE_CHECKBUTTON;
 const ROLE_CHROME_WINDOW = nsIAccessibleRole.ROLE_CHROME_WINDOW;
 const ROLE_COMBOBOX = nsIAccessibleRole.ROLE_COMBOBOX;
 const ROLE_COMBOBOX_LIST = nsIAccessibleRole.ROLE_COMBOBOX_LIST;
 const ROLE_COMBOBOX_OPTION = nsIAccessibleRole.ROLE_COMBOBOX_OPTION;
 const ROLE_COLUMNHEADER = nsIAccessibleRole.ROLE_COLUMNHEADER;
--- a/accessible/tests/mochitest/table/test_layoutguess.html
+++ b/accessible/tests/mochitest/table/test_layoutguess.html
@@ -93,16 +93,19 @@
       testAttrs("table21.3", attr, true);
       testAttrs("table21.4", attr, true);
       testAttrs("table21.5", attr, true);
       testAttrs("table21.6", attr, true);
 
       // layout table having datatable="0" attribute and containing data table structure (tfoot element)
       testAttrs("table22", attr, true);
 
+      // css table with non-table tag
+      testAttrs("table23", attr, true);
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
 <body>
@@ -112,16 +115,21 @@
      title="Don't treat tables that have a landmark role as layout table">
     Mozilla Bug 495388
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=690222"
      title="Data table elements used to determine layout-guess attribute shouldn't be picked from nested tables">
     Mozilla Bug 690222
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=693948"
+     title="Expose layout-guess: true object attribute on CSS table accessible">
+    Mozilla Bug 693948
+  </a>
 
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <!-- Table with role of grid -->
   <table id="table1" role="grid">
@@ -426,10 +434,19 @@
   <!-- layout table with datatable="0" and tfoot element-->
   <table id="table22" datatable="0">
     <tfoot>
       <tr>
         <td>Cell1</td><td>cell2</td>
       </tr>
     </tfoot>
   </table>
+
+  <!-- css table with noon-table tag -->
+  <div id="table23" style="display:table;">
+    <div style="display:table-row;">
+      <div style="display:table-cell;">Row 1, column 1</div>
+      <div style="display:table-cell;">Row 1, column 2</div>
+      <div style="display:table-cell;">Row 1, column 3</div>
+    </div>
+  </div>
 </body>
 </html>
--- a/accessible/tests/mochitest/tree/Makefile.in
+++ b/accessible/tests/mochitest/tree/Makefile.in
@@ -47,16 +47,17 @@ include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES =\
 		dockids.html \
 	$(warning test_applicationacc.xul temporarily disabled, see bug 561508) \
 		test_aria_globals.html \
 		test_aria_imgmap.html \
 		test_aria_presentation.html \
 		test_button.xul \
+		test_canvas.html \
 		test_combobox.xul \
 		test_cssoverflow.html \
 		test_dochierarchy.html \
 		test_dockids.html \
 		test_filectrl.html \
 		test_formctrl.html \
 		test_formctrl.xul \
 		test_gencontent.html \
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/tree/test_canvas.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=495912
+-->
+<head>
+  <title>File Input Control tests</title>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../role.js"></script>
+
+  <script type="application/javascript">
+    function doTest()
+    {
+      var accTree = {
+        role: ROLE_CANVAS,
+        children: [
+        ]
+      };
+      testAccessibleTree("canvas", accTree);
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+</head>
+<body>
+
+  <a target="_blank"
+     title="Expose alternative content in Canvas element to ATs"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=495912">Mozilla Bug 495912</a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <canvas id="canvas" tabindex="0">
+    fallback content.
+  </canvas>
+
+  <script type="text/javascript">
+    var c=document.getElementById("canvas");
+    var cxt=c.getContext("2d");
+    cxt.fillStyle="#005500";
+    cxt.fillRect(0,0,150,75);
+  </script>  
+
+</body>
+</html>
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -7,16 +7,17 @@ builtin(include, build/autoconf/glib.m4)
 builtin(include, build/autoconf/nspr.m4)dnl
 builtin(include, build/autoconf/nss.m4)dnl
 builtin(include, build/autoconf/pkg.m4)dnl
 builtin(include, build/autoconf/freetype2.m4)dnl
 builtin(include, build/autoconf/codeset.m4)dnl
 builtin(include, build/autoconf/altoptions.m4)dnl
 builtin(include, build/autoconf/mozprog.m4)dnl
 builtin(include, build/autoconf/mozheader.m4)dnl
+builtin(include, build/autoconf/mozcommonheader.m4)dnl
 builtin(include, build/autoconf/acwinpaths.m4)dnl
 builtin(include, build/autoconf/lto.m4)dnl
 builtin(include, build/autoconf/gcc-pr49911.m4)dnl
 builtin(include, build/autoconf/frameptr.m4)dnl
 
 MOZ_PROG_CHECKMSYS()
 
 # Read the user's .mozconfig script.  We can't do this in
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1318359094000">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1321712096000">
   <emItems>
       <emItem  blockID="i41" id="{99079a25-328f-4bd4-be04-00955acaa0a7}">
                         <versionRange  minVersion="0.1" maxVersion="4.3.1.00" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i8" id="{B13721C7-F507-4982-B2E5-502A71474FED}">
                         <versionRange  minVersion=" " severity="1">
                     </versionRange>
@@ -112,16 +112,23 @@
                               <versionRange  minVersion="3.5.7" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
                   </emItem>
       <emItem  blockID="i17" id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}">
                         <versionRange  minVersion="2.2" maxVersion="2.2">
                     </versionRange>
                   </emItem>
+      <emItem  blockID="i45" id="{22119944-ED35-4ab1-910B-E619EA06A115}">
+                        <versionRange  minVersion="0.1" maxVersion="7.6.1">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="8.0a1" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                  </emItem>
       <emItem  blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
                         <versionRange  minVersion="2.0" maxVersion="2.0">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
                         </emItem>
       <emItem  blockID="i24" id="{6E19037A-12E3-4295-8915-ED48BC341614}">
                         <versionRange  minVersion="0.1" maxVersion="1.3.328.4" severity="1">
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3476,17 +3476,16 @@ const BrowserSearch = {
     // SearchService._addEngineToStore() should fail for such an engine),
     // but let's be on the safe side.
     if (!submission)
       return;
 
     openLinkIn(submission.uri.spec,
                useNewTab ? "tab" : "current",
                { postData: submission.postData,
-                 inBackground: false,
                  relatedToCurrent: true });
   },
 
   /**
    * Returns the search bar element if it is present in the toolbar, null otherwise.
    */
   get searchBar() {
     return document.getElementById("searchbar");
@@ -3946,16 +3945,19 @@ var FullScreen = {
     let focusManger = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
     if (focusManger.activeWindow != window) {
       // The top-level window has lost focus since the request to enter
       // full-screen was made. Cancel full-screen.
       document.mozCancelFullScreen();
       return;
     }
 
+    if (gFindBarInitialized)
+      gFindBar.close();
+
     this.showWarning(true);
 
     // Exit DOM full-screen mode upon open, close, or change tab.
     gBrowser.tabContainer.addEventListener("TabOpen", this.exitDomFullScreen);
     gBrowser.tabContainer.addEventListener("TabClose", this.exitDomFullScreen);
     gBrowser.tabContainer.addEventListener("TabSelect", this.exitDomFullScreen);
 
     // Exit DOM full-screen mode when the browser window loses focus (ALT+TAB, etc).
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -49,17 +49,17 @@
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 <?xml-stylesheet href="chrome://browser/content/browser.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/content/places/places.css" type="text/css"?>
-<?xml-stylesheet href="chrome://global/skin/webConsole.css" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/skin/devtools/webconsole.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
 
 <?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
 <?xul-overlay href="chrome://browser/content/baseMenuOverlay.xul"?>
 <?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
 
 # All DTD information is stored in a separate file so that it can be shared by
 # hiddenWindow.xul.
--- a/browser/base/content/highlighter.css
+++ b/browser/base/content/highlighter.css
@@ -7,20 +7,20 @@
   top: 0;
   left: 0;
 }
 
 #highlighter-veil-container {
   overflow: hidden;
 }
 
-#highlighter-veil-container:not([locked]) > .highlighter-veil,
-#highlighter-veil-container:not([locked]) > #highlighter-veil-middlebox,
-#highlighter-veil-container:not([locked]) > #highlighter-veil-middlebox > .highlighter-veil,
-#highlighter-veil-container:not([locked]) > #highlighter-veil-middlebox > #highlighter-veil-transparentbox {
+#highlighter-veil-container:not([disable-transitions]) > .highlighter-veil,
+#highlighter-veil-container:not([disable-transitions]) > #highlighter-veil-middlebox,
+#highlighter-veil-container:not([disable-transitions]) > #highlighter-veil-middlebox > .highlighter-veil,
+#highlighter-veil-container:not([disable-transitions]) > #highlighter-veil-middlebox > #highlighter-veil-transparentbox {
   -moz-transition-property: width, height;
   -moz-transition-duration: 0.1s;
   -moz-transition-timing-function: linear;
 }
 
 #highlighter-veil-bottombox,
 #highlighter-veil-rightbox {
   -moz-box-flex: 1;
@@ -46,28 +46,39 @@
 /*
  * Node Infobar
  */
 
 #highlighter-nodeinfobar-container {
   position: absolute;
 }
 
-#highlighter-nodeinfobar-container:not([locked]) {
+#highlighter-nodeinfobar-container:not([disable-transitions]) {
   -moz-transition-property: top, left;
   -moz-transition-duration: 0.1s;
   -moz-transition-timing-function: linear;
 }
 
 #highlighter-nodeinfobar {
   display: block;
   white-space: nowrap;
   direction: ltr;
 }
 
+#highlighter-nodeinfobar-container[locked] > #highlighter-nodeinfobar {
+  pointer-events: auto;
+}
+
+#highlighter-nodeinfobar-id,
+.highlighter-nodeinfobar-class,
+#highlighter-nodeinfobar-tagname {
+  -moz-user-select: text;
+  cursor: text;
+}
+
 .highlighter-nodeinfobar-arrow {
   display: none;
 }
 
 #highlighter-nodeinfobar-container[position="top"]:not([hide-arrow]) > #highlighter-nodeinfobar-arrow-bottom {
   display: block;
 }
 
@@ -78,19 +89,11 @@
 #highlighter-nodeinfobar-container[disabled] {
   visibility: hidden;
 }
 
 #highlighter-nodeinfobar-id:empty {
   display: none;
 }
 
-#highlighter-nodeinfobar-id::before {
-  content: "#";
-}
-
-.highlighter-nodeinfobar-class::before {
-  content: ".";
-}
-
 #highlighter-nodeinfobar-tagname {
   text-transform: lowercase;
 }
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -854,25 +854,25 @@ nsContextMenu.prototype = {
     canvas.width = video.videoWidth;
     canvas.height = video.videoHeight;
     var ctxDraw = canvas.getContext("2d");
     ctxDraw.drawImage(video, 0, 0);
     saveImageURL(canvas.toDataURL("image/jpeg", ""), name, "SaveImageTitle", true, false, document.documentURIObject);
   },
 
   fullScreenVideo: function () {
-    let video = this.target;
+    let video = this.target;
     if (document.mozFullScreenEnabled)
       video.mozRequestFullScreen();
     else {
-      // Fallback for the legacy full-screen video implementation.
-      video.pause();
-      openDialog("chrome://browser/content/fullscreen-video.xhtml",
-                  "", "chrome,centerscreen,dialog=no", video);
-    }
+      // Fallback for the legacy full-screen video implementation.
+      video.pause();
+      openDialog("chrome://browser/content/fullscreen-video.xhtml",
+                  "", "chrome,centerscreen,dialog=no", video);
+    }
   },
 
   // Change current window to the URL of the background image.
   viewBGImage: function(e) {
     urlSecurityCheck(this.bgImageURL,
                      this.browser.contentPrincipal,
                      Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
     var doc = this.target.ownerDocument;
--- a/browser/build.mk
+++ b/browser/build.mk
@@ -50,16 +50,32 @@ tier_app_dirs += $(MOZ_BRANDING_DIRECTOR
 ifdef MOZ_SERVICES_SYNC
 tier_app_dirs += services
 endif
 
 tier_app_dirs += browser
 # Never add other tier_app_dirs after browser. They won't get packaged
 # properly on mac.
 
+################################################
+# Parallel build on Windows with GNU make check
+
+default::
+ifeq (,$(findstring pymake,$(MAKE)))
+ifeq ($(HOST_OS_ARCH),WINNT)
+ifneq (1,$(NUMBER_OF_PROCESSORS))
+	@echo $(if $(findstring -j,$(value MAKEFLAGS)), \
+$(error You are using GNU make to build Firefox with -jN on Windows. \
+This will randomly deadlock. To compile a parallel build on Windows \
+run "python -OO build/pymake/make.py -f client.mk build". \
+See https://developer.mozilla.org/en/pymake for more details.))
+endif
+endif
+endif
+
 installer:
 	@$(MAKE) -C browser/installer installer
 
 package:
 	@$(MAKE) -C browser/installer
 
 package-compare:
 	@$(MAKE) -C browser/installer package-compare
--- a/browser/components/migration/content/migration.js
+++ b/browser/components/migration/content/migration.js
@@ -335,16 +335,19 @@ var MigrationWizard = {
         source = "sourceNameIE";
         break;
       case "opera":
         source = "sourceNameOpera";
         break;
       case "safari":
         source = "sourceNameSafari";
         break;
+      case "chrome":
+        source = "sourceNameChrome";
+        break;
     }
 
     // semi-wallpaper for crash when multiple profiles exist, since we haven't initialized mSourceProfile in places
     this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate);
 
     var oldHomePageURL = this._migrator.sourceHomePageURL;
 
     if (oldHomePageURL && source) {
--- a/browser/components/migration/content/migration.xul
+++ b/browser/components/migration/content/migration.xul
@@ -74,16 +74,17 @@
 #elifdef XP_UNIX
       <radio id="opera"     label="&importFromOpera.label;"     accesskey="&importFromOpera.accesskey;"/>
 #elifdef XP_WIN
 #ifndef NO_IE_MIGRATOR
       <radio id="ie"        label="&importFromIE.label;"        accesskey="&importFromIE.accesskey;"/>
 #endif
       <radio id="opera"     label="&importFromOpera.label;"     accesskey="&importFromOpera.accesskey;"/>
 #endif
+      <radio id="chrome"    label="&importFromChrome.label;"    accesskey="&importFromChrome.accesskey;"/>
       <radio id="fromfile"  label="&importFromHTMLFile.label;"  accesskey="&importFromHTMLFile.accesskey;" hidden="true"/>
       <radio id="nothing"   label="&importFromNothing.label;"   accesskey="&importFromNothing.accesskey;" hidden="true"/>
     </radiogroup>
     <label id="noSources" hidden="true">&noMigrationSources.label;</label>
   </wizardpage>
 
   <wizardpage id="selectProfile" pageid="selectProfile" label="&selectProfile.title;"
               next="importItems"
new file mode 100644
--- /dev/null
+++ b/browser/components/migration/src/BrowserProfileMigrators.manifest
@@ -0,0 +1,2 @@
+component {4cec1de4-1671-4fc3-a53e-6c539dc77a26} ChromeProfileMigrator.js
+contract @mozilla.org/profile/migrator;1?app=browser&type=chrome {4cec1de4-1671-4fc3-a53e-6c539dc77a26}
new file mode 100644
--- /dev/null
+++ b/browser/components/migration/src/ChromeProfileMigrator.js
@@ -0,0 +1,532 @@
+/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=2 sts=2 et
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The Original Code is the Browser Profile Migrator.
+ *
+ * The Initial Developer of the Original Code is the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Makoto Kato <m_kato@ga2.so-net.ne.jp> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+const LOCAL_FILE_CID = "@mozilla.org/file/local;1";
+const FILE_INPUT_STREAM_CID = "@mozilla.org/network/file-input-stream;1";
+
+const BUNDLE_MIGRATION = "chrome://browser/locale/migration/migration.properties";
+
+const MIGRATE_ALL = 0x0000;
+const MIGRATE_SETTINGS = 0x0001;
+const MIGRATE_COOKIES = 0x0002;
+const MIGRATE_HISTORY = 0x0004;
+const MIGRATE_FORMDATA = 0x0008;
+const MIGRATE_PASSWORDS = 0x0010;
+const MIGRATE_BOOKMARKS = 0x0020;
+const MIGRATE_OTHERDATA = 0x0040;
+
+const S100NS_FROM1601TO1970 = 0x19DB1DED53E8000;
+const S100NS_PER_MS = 10;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
+Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
+Components.utils.import("resource://gre/modules/NetUtil.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "bookmarksSubfolderTitle", function () {
+  // get "import from google chrome" string for folder
+  let strbundle =
+    Services.strings.createBundle(BUNDLE_MIGRATION);
+  let sourceNameChrome = strbundle.GetStringFromName("sourceNameChrome");
+  return strbundle.formatStringFromName("importedBookmarksFolder",
+                                        [sourceNameChrome],
+                                        1);
+});
+
+/*
+ * Convert Chrome time format to Date object
+ *
+ * @param   aTime
+ *          Chrome time 
+ * @return  converted Date object
+ * @note    Google Chrome uses FILETIME / 10 as time.
+ *          FILETIME is based on same structure of Windows.
+ */
+function chromeTimeToDate(aTime)
+{
+  return new Date((aTime * S100NS_PER_MS - S100NS_FROM1601TO1970 ) / 10000);
+}
+
+/*
+ * Insert bookmark items into specific folder.
+ *
+ * @param   aFolderId
+ *          id of folder where items will be inserted
+ * @param   aItems
+ *          bookmark items to be inserted
+ */
+function insertBookmarkItems(aFolderId, aItems)
+{
+  for (let i = 0; i < aItems.length; i++) {
+    let item = aItems[i];
+
+    try {
+      if (item.type == "url") {
+        PlacesUtils.bookmarks.insertBookmark(aFolderId,
+                                             NetUtil.newURI(item.url),
+                                             PlacesUtils.bookmarks.DEFAULT_INDEX,
+                                             item.name);
+      } else if (item.type == "folder") {
+        let newFolderId =
+          PlacesUtils.bookmarks.createFolder(aFolderId,
+                                             item.name,
+                                             PlacesUtils.bookmarks.DEFAULT_INDEX);
+
+        insertBookmarkItems(newFolderId, item.children);
+      }
+    } catch (e) {
+      Cu.reportError(e);
+    }
+  }
+}
+
+function ChromeProfileMigrator()
+{
+}
+
+ChromeProfileMigrator.prototype = {
+  _paths: {
+    bookmarks : null,
+    cookies : null,
+    history : null,
+    prefs : null,
+  },
+
+  _homepageURL : null,
+  _replaceBookmarks : false,
+
+  /*
+   * Notify to observers to start migration
+   *
+   * @param   aType
+   *          notification type such as MIGRATE_BOOKMARKS
+   */
+
+  _notifyStart : function Chrome_notifyStart(aType)
+  {
+    Services.obs.notifyObservers(null, "Migration:ItemBeforeMigrate", aType);
+    this._pendingCount++;
+  },
+
+  /*
+   * Notify to observers to finish migration for item
+   * If all items are finished, it sends migration end notification.
+   *
+   * @param   aType
+   *          notification type such as MIGRATE_BOOKMARKS
+   */
+  _notifyCompleted : function Chrome_notifyIfCompleted(aType)
+  {
+    Services.obs.notifyObservers(null, "Migration:ItemAfterMigrate", aType);
+    if (--this._pendingCount == 0) {
+      // All items are migrated, so we have to send end notification.
+      Services.obs.notifyObservers(null, "Migration:Ended", null);
+    }
+  },
+
+  /*
+   * Migrating bookmark items
+   */
+  _migrateBookmarks : function Chrome_migrateBookmarks()
+  {
+    this._notifyStart(MIGRATE_BOOKMARKS);
+
+    try {
+      PlacesUtils.bookmarks.runInBatchMode({
+        _self : this,
+        runBatched : function (aUserData) {
+          let migrator = this._self;
+          let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+          file.initWithPath(migrator._paths.bookmarks);
+
+          NetUtil.asyncFetch(file, function(aInputStream, aResultCode) {
+            if (!Components.isSuccessCode(aResultCode)) {
+              migrator._notifyCompleted(MIGRATE_BOOKMARKS);
+              return;
+            }
+
+            // Parse Chrome bookmark file that is JSON format
+            let bookmarkJSON = NetUtil.readInputStreamToString(aInputStream,
+                                                               aInputStream.available(),
+                                                               { charset : "UTF-8" });
+            let roots = JSON.parse(bookmarkJSON).roots;
+
+            // Importing bookmark bar items
+            if (roots.bookmark_bar.children &&
+                roots.bookmark_bar.children.length > 0) {
+              // Toolbar
+              let parentId = PlacesUtils.toolbarFolderId;
+              if (!migrator._replaceBookmarks) { 
+                parentId =
+                  PlacesUtils.bookmarks.createFolder(parentId,
+                                                     bookmarksSubfolderTitle,
+                                                     PlacesUtils.bookmarks.DEFAULT_INDEX);
+              }
+              insertBookmarkItems(parentId, roots.bookmark_bar.children);
+            }
+
+            // Importing bookmark menu items
+            if (roots.other.children &&
+                roots.other.children.length > 0) {
+              // Bookmark menu
+              let parentId = PlacesUtils.bookmarksMenuFolderId;
+              if (!migrator._replaceBookmarks) { 
+                parentId =
+                  PlacesUtils.bookmarks.createFolder(parentId,
+                                                     bookmarksSubfolderTitle,
+                                                     PlacesUtils.bookmarks.DEFAULT_INDEX);
+              }
+              insertBookmarkItems(parentId, roots.other.children);
+            }
+
+            migrator._notifyCompleted(MIGRATE_BOOKMARKS);
+          });
+        }
+      }, null);
+    } catch (e) {
+      Cu.reportError(e);
+      this._notifyCompleted(MIGRATE_BOOKMARKS);
+    }
+  },
+
+  /*
+   * Migrating history
+   */
+  _migrateHistory : function Chrome_migrateHistory()
+  {
+    this._notifyStart(MIGRATE_HISTORY);
+
+    try {
+      PlacesUtils.history.runInBatchMode({
+        _self : this,
+        runBatched : function (aUserData) {
+          // access sqlite3 database of Chrome's history
+          let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+          file.initWithPath(this._self._paths.history);
+
+          let dbConn = Services.storage.openUnsharedDatabase(file);
+          let stmt = dbConn.createAsyncStatement(
+              "SELECT url, title, last_visit_time, typed_count FROM urls WHERE hidden = 0");
+
+          stmt.executeAsync({
+            _asyncHistory : Cc["@mozilla.org/browser/history;1"]
+                            .getService(Ci.mozIAsyncHistory),
+            _db : dbConn,
+            _self : this._self,
+            handleResult : function(aResults) {
+              let places = [];
+              for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) {
+                try {
+                  // if having typed_count, we changes transition type to typed.
+                  let transType = PlacesUtils.history.TRANSITION_LINK;
+                  if (row.getResultByName("typed_count") > 0)
+                    transType = PlacesUtils.history.TRANSITION_TYPED;
+
+                  places.push({
+                    uri: NetUtil.newURI(row.getResultByName("url")),
+                    title: row.getResultByName("title"),
+                    visits: [{
+                      transitionType: transType,
+                      visitDate: chromeTimeToDate(
+                                   row.getResultByName(
+                                     "last_visit_time")) * 1000,
+                    }],
+                  });
+                } catch (e) {
+                  Cu.reportError(e);
+                }
+              }
+
+              try {
+                this._asyncHistory.updatePlaces(places);
+              } catch (e) {
+                Cu.reportError(e);
+              }
+            },
+
+            handleError : function(aError) {
+              Cu.reportError("Async statement execution returned with '" +
+                             aError.result + "', '" + aError.message + "'");
+            },
+
+            handleCompletion : function(aReason) {
+              this._db.asyncClose();
+              this._self._notifyCompleted(MIGRATE_HISTORY);
+            }
+          });
+          stmt.finalize();
+        }
+      }, null);
+    } catch (e) {
+      Cu.reportError(e);
+      this._notifyCompleted(MIGRATE_HISTORY);
+    }
+  },
+
+  /*
+   * Migrating cookies
+   */
+  _migrateCookies : function Chrome_migrateCookies()
+  {
+    this._notifyStart(MIGRATE_COOKIES);
+
+    try {
+      // Access sqlite3 database of Chrome's cookie
+      let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+      file.initWithPath(this._paths.cookies);
+
+      let dbConn = Services.storage.openUnsharedDatabase(file);
+      let stmt = dbConn.createAsyncStatement(
+          "SELECT host_key, path, name, value, secure, httponly, expires_utc FROM cookies");
+
+      stmt.executeAsync({
+        _db : dbConn,
+        _self : this,
+        handleResult : function(aResults) {
+          for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) {
+            let host_key = row.getResultByName("host_key");
+            if (host_key.match(/^\./)) {
+              // 1st character of host_key may be ".", so we have to remove it
+              host_key = host_key.substr(1);
+            }
+
+            try {
+              let expiresUtc =
+                chromeTimeToDate(row.getResultByName("expires_utc")) / 1000;
+              Services.cookies.add(host_key,
+                                   row.getResultByName("path"),
+                                   row.getResultByName("name"),
+                                   row.getResultByName("value"),
+                                   row.getResultByName("secure"),
+                                   row.getResultByName("httponly"),
+                                   false,
+                                   parseInt(expiresUtc));
+            } catch (e) {
+              Cu.reportError(e);
+            }
+          }
+        },
+
+        handleError : function(aError) {
+          Cu.reportError("Async statement execution returned with '" +
+                         aError.result + "', '" + aError.message + "'");
+        },
+
+        handleCompletion : function(aReason) {
+          this._db.asyncClose();
+          this._self._notifyCompleted(MIGRATE_COOKIES);
+        },
+      });
+      stmt.finalize();
+    } catch (e) {
+      Cu.reportError(e);
+      this._notifyCompleted(MIGRATE_COOKIES);
+    }
+  },
+
+  /*
+   * nsIBrowserProfileMigrator interface implementation
+   */
+
+  /*
+   * Let's migrate all items
+   *
+   * @param   aItems
+   *          list of data items to migrate.  but this is unused.
+   * @param   aStartup
+   *          non-null if called during startup.
+   * @param   aProfile
+   *          this is unused due to single profile support only
+   */
+  migrate : function Chrome_migrate(aItems, aStartup, aProfile)
+  {
+    if (aStartup) {
+      aStartup.doStartup();
+      this._replaceBookmarks = true;
+    }
+
+    Services.obs.notifyObservers(null, "Migration:Started", null);
+
+    // Reset panding count.  If this count becomes 0, "Migration:Ended"
+    // notification is sent
+    this._pendingCount = 1;
+
+    if (aItems & MIGRATE_HISTORY)
+      this._migrateHistory();
+
+    if (aItems & MIGRATE_COOKIES)
+      this._migrateCookies();
+
+    if (aItems & MIGRATE_BOOKMARKS)
+      this._migrateBookmarks();
+
+    if (--this._pendingCount == 0) {
+      // When async imports are immeditelly completed unfortunately,
+      // this will be called.
+      // Usually, this notification is sent by _notifyCompleted()
+      Services.obs.notifyObservers(null, "Migration:Ended", null);
+    }
+  },
+
+  /*
+   * return supported migration types
+   *
+   * @param   aProfile
+   *          this is unused due to single profile support only
+   * @param   aDoingStartup
+   *          non-null if called during startup.
+   * @return  supported migration types
+   */
+  getMigrateData: function Chrome_getMigrateData(aProfile, aDoingStartup)
+  {
+#ifdef XP_WIN
+    let chromepath = Services.dirsvc.get("LocalAppData", Ci.nsIFile).path +
+                     "\\Google\\Chrome\\User Data\\Default\\";
+#elifdef XP_MACOSX
+    let chromepath = Services.dirsvc.get("Home", Ci.nsIFile).path +
+                     "/Library/Application Support/Google/Chrome/Default/";
+#else
+    let chromepath = Services.dirsvc.get("Home", Ci.nsIFile).path +
+                     "/.config/google-chrome/Default/";
+#endif
+
+    let result = 0;
+
+    // bookmark and preference are JSON format
+
+    try {
+      let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+      file.initWithPath(chromepath + "Bookmarks");
+      if (file.exists()) {
+        this._paths.bookmarks = file.path
+        result += MIGRATE_BOOKMARKS;
+      }
+    } catch (e) {
+      Cu.reportError(e);
+    }
+
+    if (!this._paths.prefs)
+      this._paths.prefs = chromepath + "Preferences";
+
+    // history and cookies are SQLite database
+
+    try {
+      let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+      file.initWithPath(chromepath + "History");
+      if (file.exists()) {
+        this._paths.history = file.path
+        result += MIGRATE_HISTORY;
+      }
+    } catch (e) {
+      Cu.reportError(e);
+    }
+
+    try {
+      let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+      file.initWithPath(chromepath + "Cookies");
+      if (file.exists()) {
+        this._paths.cookies = file.path
+        result += MIGRATE_COOKIES;
+      }
+    } catch (e) {
+      Cu.reportError(e);
+    }
+
+    return result;
+  },
+
+  /*
+   * Whether we support migration of Chrome
+   *
+   * @return true if supported
+   */
+  get sourceExists()
+  {
+    let result = this.getMigrateData(null, false);
+    return result != 0;
+  },
+
+  // Although Chrome supports multi-profiles, there is no way
+  // to get profile lists.
+  sourceHasMultipleProfiles: false,
+  sourceProfiles: null,
+
+  /*
+   * Return home page URL
+   *
+   * @return  home page URL
+   */
+  get sourceHomePageURL()
+  {
+    try  {
+      if (this._homepageURL)
+        return this._homepageURL;
+
+      if (!this._paths.prefs)
+        this.getMigrateData(null, false);
+
+      // XXX reading and parsing JSON is synchronous.
+      let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+      file.initWithPath(this._paths.prefs);
+      let fstream = Cc[FILE_INPUT_STREAM_CID].
+                    createInstance(Ci.nsIFileInputStream);
+      fstream.init(file, -1, 0, 0); 
+      this._homepageURL = JSON.parse(
+        NetUtil.readInputStreamToString(fstream, fstream.available(),
+                                        { charset: "UTF-8" })).homepage;
+      return this._homepageURL;
+    } catch (e) {
+      Cu.reportError(e);
+    }
+    return "";
+  },
+
+  QueryInterface: XPCOMUtils.generateQI([
+    Ci.nsIBrowserProfileMigrator
+  ]),
+
+  classDescription: "Chrome Profile Migrator",
+  contractID: "@mozilla.org/profile/migrator;1?app=browser&type=chrome",
+  classID: Components.ID("{4cec1de4-1671-4fc3-a53e-6c539dc77a26}")
+};
+
+const NSGetFactory = XPCOMUtils.generateNSGetFactory([ChromeProfileMigrator]);
--- a/browser/components/migration/src/Makefile.in
+++ b/browser/components/migration/src/Makefile.in
@@ -62,10 +62,18 @@ CPPSRCS += nsIEProfileMigrator.cpp \
            $(NULL)
 endif
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS += nsSafariProfileMigrator.cpp \
            $(NULL)
 endif            
 
+EXTRA_PP_COMPONENTS = \
+  ChromeProfileMigrator.js \
+  $(NULL)
+
+EXTRA_COMPONENTS = \
+	BrowserProfileMigrators.manifest \
+	$(NULL)
+
 include $(topsrcdir)/config/rules.mk
 
--- a/browser/components/migration/src/nsProfileMigrator.cpp
+++ b/browser/components/migration/src/nsProfileMigrator.cpp
@@ -158,16 +158,17 @@ nsProfileMigrator::Import()
 
 NS_IMPL_ISUPPORTS1(nsProfileMigrator, nsIProfileMigrator)
 
 #ifdef XP_WIN
 
 #define INTERNAL_NAME_IEXPLORE        "iexplore"
 #define INTERNAL_NAME_MOZILLA_SUITE   "apprunner"
 #define INTERNAL_NAME_OPERA           "opera"
+#define INTERNAL_NAME_CHROME          "chrome"
 #endif
 
 nsresult
 nsProfileMigrator::GetDefaultBrowserMigratorKey(nsACString& aKey,
                                                 nsCOMPtr<nsIBrowserProfileMigrator>& bpm)
 {
 #if XP_WIN
 
@@ -241,32 +242,37 @@ nsProfileMigrator::GetDefaultBrowserMigr
   if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_IEXPLORE)) {
     aKey = "ie";
     return NS_OK;
   }
   else if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_OPERA)) {
     aKey = "opera";
     return NS_OK;
   }
+  else if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_CHROME)) {
+    aKey = "chrome";
+    return NS_OK;
+  }
 
 #else
   bool exists = false;
 #define CHECK_MIGRATOR(browser) do {\
   bpm = do_CreateInstance(NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX browser);\
   if (bpm)\
     bpm->GetSourceExists(&exists);\
   if (exists) {\
     aKey = browser;\
     return NS_OK;\
   }} while(0)
 
 #if defined(XP_MACOSX)
   CHECK_MIGRATOR("safari");
 #endif
   CHECK_MIGRATOR("opera");
+  CHECK_MIGRATOR("chrome");
 
 #undef CHECK_MIGRATOR
 #endif
   return NS_ERROR_FAILURE;
 }
 
 bool
 nsProfileMigrator::ImportRegistryProfiles(const nsACString& aAppName)
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1527,39 +1527,39 @@ ContentPermissionPrompt.prototype = {
       },
     };
 
     var message;
     var secondaryActions = [];
 
     // Different message/options if it is a local file
     if (requestingURI.schemeIs("file")) {
-      message = browserBundle.formatStringFromName("geolocation.fileWantsToKnow",
+      message = browserBundle.formatStringFromName("geolocation.shareWithFile",
                                                    [requestingURI.path], 1);
     } else {
-      message = browserBundle.formatStringFromName("geolocation.siteWantsToKnow",
+      message = browserBundle.formatStringFromName("geolocation.shareWithSite",
                                                    [requestingURI.host], 1);
 
       // Don't offer to "always/never share" in PB mode
       var inPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
                               getService(Ci.nsIPrivateBrowsingService).
                               privateBrowsingEnabled;
 
       if (!inPrivateBrowsing) {
         secondaryActions.push({
-          label: browserBundle.GetStringFromName("geolocation.alwaysShare"),
-          accessKey: browserBundle.GetStringFromName("geolocation.alwaysShare.accesskey"),
+          label: browserBundle.GetStringFromName("geolocation.alwaysShareLocation"),
+          accessKey: browserBundle.GetStringFromName("geolocation.alwaysShareLocation.accesskey"),
           callback: function () {
             Services.perms.add(requestingURI, "geo", Ci.nsIPermissionManager.ALLOW_ACTION);
             request.allow();
           }
         });
         secondaryActions.push({
-          label: browserBundle.GetStringFromName("geolocation.neverShare"),
-          accessKey: browserBundle.GetStringFromName("geolocation.neverShare.accesskey"),
+          label: browserBundle.GetStringFromName("geolocation.neverShareLocation"),
+          accessKey: browserBundle.GetStringFromName("geolocation.neverShareLocation.accesskey"),
           callback: function () {
             Services.perms.add(requestingURI, "geo", Ci.nsIPermissionManager.DENY_ACTION);
             request.cancel();
           }
         });
       }
     }
 
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -442,17 +442,16 @@ PlacesController.prototype = {
    * Gathers information about the selected nodes according to the following
    * rules:
    *    "link"              node is a URI
    *    "bookmark"          node is a bookamrk
    *    "livemarkChild"     node is a child of a livemark
    *    "tagChild"          node is a child of a tag
    *    "folder"            node is a folder
    *    "query"             node is a query
-   *    "dynamiccontainer"  node is a dynamic container
    *    "separator"         node is a separator line
    *    "host"              node is a host
    *
    * @returns an array of objects corresponding the selected nodes. Each
    *          object has each of the properties above set if its corresponding
    *          node matches the rule. In addition, the annotations names for each
    *          node are set on its corresponding object as properties.
    * Notes:
@@ -485,19 +484,16 @@ PlacesController.prototype = {
                 break;
               case Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_SITE_QUERY:
               case Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_QUERY:
                 nodeData["day"] = true;
                 break;
             }
           }
           break;
-        case Ci.nsINavHistoryResultNode.RESULT_TYPE_DYNAMIC_CONTAINER:
-          nodeData["dynamiccontainer"] = true;
-          break;
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER:
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT:
           nodeData["folder"] = true;
           break;
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR:
           nodeData["separator"] = true;
           break;
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_URI:
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -354,17 +354,17 @@ SessionStoreService.prototype = {
           if (lastSessionCrashed) {
             this._recentCrashes = (this._initialState.session &&
                                    this._initialState.session.recentCrashes || 0) + 1;
             
             if (this._needsRestorePage(this._initialState, this._recentCrashes)) {
               // replace the crashed session with a restore-page-only session
               let pageData = {
                 url: "about:sessionrestore",
-                formdata: { "#sessionData": JSON.stringify(this._initialState) }
+                formdata: { "#sessionData": this._initialState }
               };
               this._initialState = { windows: [{ tabs: [{ entries: [pageData] }] }] };
             }
           }
 
           // Load the session start time from the previous state
           this._sessionStartTime = this._initialState.session &&
                                    this._initialState.session.startTime ||
@@ -2135,20 +2135,27 @@ SessionStoreService.prototype = {
     for (var i = 0; i < aContent.frames.length; i++) {
       if (aData.children && aData.children[i])
         this._updateTextAndScrollDataForFrame(aWindow, aContent.frames[i],
                                               aData.children[i], aUpdateFormData,
                                               aFullData, aIsPinned);
     }
     var isHTTPS = this._getURIFromString((aContent.parent || aContent).
                                          document.location.href).schemeIs("https");
-    if (aFullData || this._checkPrivacyLevel(isHTTPS, aIsPinned) ||
-        aContent.top.document.location.href == "about:sessionrestore") {
+    let isAboutSR = aContent.top.document.location.href == "about:sessionrestore";
+    if (aFullData || this._checkPrivacyLevel(isHTTPS, aIsPinned) || isAboutSR) {
       if (aFullData || aUpdateFormData) {
         let formData = this._collectFormDataForFrame(aContent.document);
+
+        // We want to avoid saving data for about:sessionrestore as a string.
+        // Since it's stored in the form as stringified JSON, stringifying further
+        // causes an explosion of escape characters. cf. bug 467409
+        if (formData && isAboutSR)
+          formData["#sessionData"] = JSON.parse(formData["#sessionData"]);
+
         if (formData)
           aData.formdata = formData;
         else if (aData.formdata)
           delete aData.formdata;
       }
       
       // designMode is undefined e.g. for XUL documents (as about:config)
       if ((aContent.document.designMode || "") == "on") {
@@ -2976,18 +2983,19 @@ SessionStoreService.prototype = {
    * @param aTabData
    *        Array of tab data
    * @param aIdMap
    *        Hash for ensuring unique frame IDs
    */
   restoreHistory:
     function sss_restoreHistory(aWindow, aTabs, aTabData, aIdMap, aDocIdentMap) {
     var _this = this;
-    while (aTabs.length > 0 && (!aTabs[0].linkedBrowser.__SS_tabStillLoading || !aTabs[0].parentNode)) {
-      aTabs.shift(); // this tab got removed before being completely restored
+    // if the tab got removed before being completely restored, then skip it
+    while (aTabs.length > 0 && !(this._canRestoreTabHistory(aTabs[0]))) {
+      aTabs.shift();
       aTabData.shift();
     }
     if (aTabs.length == 0) {
       // At this point we're essentially ready for consumers to read/write data
       // via the sessionstore API so we'll send the SSWindowStateReady event.
       this._setWindowStateReady(aWindow);
       return; // no more tabs to restore
     }
@@ -3374,16 +3382,23 @@ SessionStoreService.prototype = {
 
         let node = key.charAt(0) == "#" ? aDocument.getElementById(key.slice(1)) :
                                           XPathHelper.resolve(aDocument, key);
         if (!node)
           continue;
 
         let eventType;
         let value = aData[key];
+
+        // for about:sessionrestore we saved the field as JSON to avoid nested
+        // instances causing humongous sessionstore.js files. cf. bug 467409
+        if (aURL == "about:sessionrestore" && typeof value == "object") {
+          value = JSON.stringify(value);
+        }
+
         if (typeof value == "string" && node.type != "file") {
           if (node.value == value)
             continue; // don't dispatch an input event for no change
 
           node.value = value;
           eventType = "input";
         }
         else if (typeof value == "boolean") {
@@ -3992,16 +4007,30 @@ SessionStoreService.prototype = {
     // store this tab's data.
     return aTabState.entries.length &&
            !(aTabState.entries.length == 1 &&
              aTabState.entries[0].url == "about:blank" &&
              !aTabState.userTypedValue);
   },
 
   /**
+   * Determine if we can restore history into this tab.
+   * This will be false when a tab has been removed (usually between
+   * restoreHistoryPrecursor && restoreHistory) or if the tab is still marked
+   * as loading.
+   *
+   * @param aTab
+   * @returns boolean
+   */
+  _canRestoreTabHistory: function sss__canRestoreTabHistory(aTab) {
+    return aTab.parentNode && aTab.linkedBrowser &&
+           aTab.linkedBrowser.__SS_tabStillLoading;
+  },
+
+  /**
    * This is going to take a state as provided at startup (via
    * nsISessionStartup.state) and split it into 2 parts. The first part
    * (defaultState) will be a state that should still be restored at startup,
    * while the second part (state) is a state that should be saved for later.
    * defaultState will be comprised of windows with only pinned tabs, extracted
    * from state. It will contain the cookies that go along with the history
    * entries in those tabs. It will also contain window position information.
    *
--- a/browser/components/sessionstore/test/browser/Makefile.in
+++ b/browser/components/sessionstore/test/browser/Makefile.in
@@ -95,16 +95,17 @@ include $(topsrcdir)/config/rules.mk
 	browser_464620_a.html \
 	browser_464620_b.js \
 	browser_464620_b.html \
 	browser_464620_xd.html \
 	browser_465215.js \
 	browser_465223.js \
 	browser_466937.js \
 	browser_466937_sample.html \
+	browser_467409-backslashplosion.js \
 	browser_477657.js \
 	browser_480148.js \
 	browser_480893.js \
 	browser_483330.js \
 	browser_485482.js \
 	browser_485482_sample.html \
 	browser_485563.js \
 	browser_490040.js \
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser/browser_467409-backslashplosion.js
@@ -0,0 +1,90 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Test Summary:
+// 1.  Open about:sessionrestore via setBrowserState where formdata is a JS object, not a string
+// 1a. Check that #sessionData on the page is readable after JSON.parse (skipped, checking formdata is sufficient)
+// 1b. Check that there are no backslashes in the formdata
+// 1c. Check that formdata (via getBrowserState) doesn't require JSON.parse
+//
+// 2.  Use the current state (currently about:sessionrestore with data) and then open than in a new instance of about:sessionrestore
+// 2a. Check that there are no backslashes in the formdata
+// 2b. Check that formdata (via getBrowserState) doesn't require JSON.parse
+//
+// 3.  [backwards compat] Use a stringified state as formdata when opening about:sessionrestore
+// 3a. Make sure there are nodes in the tree on about:sessionrestore (skipped, checking formdata is sufficient)
+// 3b. Check that there are no backslashes in the formdata
+// 3c. Check that formdata (via getBrowserState) doesn't require JSON.parse
+
+function test() {
+  waitForExplicitFinish();
+
+  let blankState = { windows: [{ tabs: [{ entries: [{ url: "about:blank" }] }]}]};
+  let crashState = { windows: [{ tabs: [{ entries: [{ url: "about:mozilla" }] }]}]};
+
+  let pagedata = { url: "about:sessionrestore",
+                   formdata: { "#sessionData": crashState } };
+  let state = { windows: [{ tabs: [{ entries: [pagedata] }] }] };
+
+  // test1 calls test2 calls test3 calls finish
+  test1(state);
+
+
+  function test1(aState) {
+    waitForBrowserState(aState, function() {
+      checkState("test1", test2);
+    });
+  }
+
+  function test2(aState) {
+    let pagedata2 = { url: "about:sessionrestore",
+                      formdata: { "#sessionData": aState } };
+    let state2 = { windows: [{ tabs: [{ entries: [pagedata2] }] }] };
+
+    waitForBrowserState(state2, function() {
+      checkState("test2", test3);
+    });
+  }
+
+  function test3(aState) {
+    let pagedata3 = { url: "about:sessionrestore",
+                      formdata: { "#sessionData": JSON.stringify(crashState) } };
+    let state3 = { windows: [{ tabs: [{ entries: [pagedata3] }] }] };
+    waitForBrowserState(state3, function() {
+      // In theory we should do inspection of the treeview on about:sessionrestore,
+      // but we don't actually need to. If we fail tests in checkState then
+      // about:sessionrestore won't be able to turn the form value into a usable page.
+      checkState("test3", function() waitForBrowserState(blankState, finish));
+    });
+  }
+
+  function checkState(testName, callback) {
+    let curState = JSON.parse(ss.getBrowserState());
+    let formdata = curState.windows[0].tabs[0].entries[0].formdata;
+
+    ok(formdata["#sessionData"], testName + ": we have form data for about:sessionrestore");
+
+    let sessionData_raw = JSON.stringify(formdata["#sessionData"]);
+    ok(!/\\/.test(sessionData_raw), testName + ": #sessionData contains no backslashes");
+    info(sessionData_raw);
+
+    let gotError = false;
+    try {
+      JSON.parse(formdata["#sessionData"]);
+    }
+    catch (e) {
+      info(testName + ": got error: " + e);
+      gotError = true;
+    }
+    ok(gotError, testName + ": attempting to JSON.parse form data threw error");
+
+    // Panorama sticks JSON into extData, which we stringify causing the
+    // naive backslash check to fail. extData doesn't matter in the grand
+    // scheme here, so we'll delete the extData so doesn't end up in future states.
+    delete curState.windows[0].extData;
+    delete curState.windows[0].tabs[0].extData;
+    callback(curState);
+  }
+
+}
+
--- a/browser/components/sessionstore/test/browser/browser_590563.js
+++ b/browser/components/sessionstore/test/browser/browser_590563.js
@@ -7,17 +7,17 @@ function test() {
       tabs: [
         { entries: [{ url: "about:robots" }], hidden: true },
         { entries: [{ url: "about:blank" }], hidden: false }
       ]
     }]
   };
   let pageData = {
     url: "about:sessionrestore",
-    formdata: { "#sessionData": "(" + JSON.stringify(oldState) + ")" }
+    formdata: { "#sessionData": oldState }
   };
   let state = { windows: [{ tabs: [{ entries: [pageData] }] }] };
 
   waitForExplicitFinish();
 
   newWindowWithState(state, function (win) {
     registerCleanupFunction(function () win.close());
 
--- a/browser/components/tabview/groupitems.js
+++ b/browser/components/tabview/groupitems.js
@@ -1086,31 +1086,31 @@ GroupItem.prototype = Utils.extend(new I
   //   options - An optional object with settings for this call. See below.
   //
   // Possible options: 
   //   dontArrange - don't rearrange the remaining items
   //   dontClose - don't close the group even if it normally would
   //   immediately - don't animate
   remove: function GroupItem_remove(a, options) {
     try {
-      var $el;
-      var item;
+      let $el;
+      let item;
 
       if (a.isAnItem) {
         item = a;
         $el = iQ(item.container);
       } else {
         $el = iQ(a);
         item = Items.item($el);
       }
 
       if (!options)
         options = {};
 
-      var index = this._children.indexOf(item);
+      let index = this._children.indexOf(item);
       if (index != -1)
         this._children.splice(index, 1);
 
       if (item == this._activeTab || !this._activeTab) {
         if (this._children.length > 0)
           this._activeTab = this._children[0];
         else
           this._activeTab = null;
@@ -1137,17 +1137,19 @@ GroupItem.prototype = Utils.extend(new I
         item.setResizable(true, options.immediately);
 
       // if a blank tab is selected while restoring a tab the blank tab gets
       // removed. we need to keep the group alive for the restored tab.
       if (item.isRemovedAfterRestore)
         options.dontClose = true;
 
       let closed = options.dontClose ? false : this.closeIfEmpty();
-      if (closed) {
+      if (closed ||
+          (this._children.length == 0 && !gBrowser.selectedTab.pinned &&
+           !item.isDragging)) {
         this._makeLastActiveGroupItemActive();
       } else if (!options.dontArrange) {
         this.arrange({animate: !options.immediately});
         this._unfreezeItemSize({dontArrange: true});
       }
 
       this._sendToSubscribers("childRemoved",{ groupItemId: this.id, item: item });
     } catch(e) {
--- a/browser/components/tabview/tabitems.js
+++ b/browser/components/tabview/tabitems.js
@@ -255,19 +255,25 @@ TabItem.prototype = Utils.extend(new Ite
   // Loads the tabItems thumbnail.
   loadThumbnail: function TabItem_loadThumbnail(tabData) {
     Utils.assert(tabData, "invalid or missing argument <tabData>");
 
     let self = this;
 
     function TabItem_loadThumbnail_callback(error, imageData) {
       // we could have been unlinked while waiting for the thumbnail to load
-      if (error || !imageData || !self.tab)
+      if (!self.tab)
         return;
 
+      if (error || !imageData) {
+        // paint the canvas to avoid leaving traces when dragging tab over it
+        self.tabCanvas.paint();
+        return;
+      }
+
       self._sendToSubscribers("loadedCachedImageData");
 
       // If we have a cached image, then show it if the loaded URL matches
       // what the cache is from, OR the loaded URL is blank, which means
       // that the page hasn't loaded yet.
       let currentUrl = self.tab.linkedBrowser.currentURI.spec;
       if (tabData.url == currentUrl || currentUrl == "about:blank")
         self.showCachedData(tabData, imageData);
--- a/browser/components/tabview/test/Makefile.in
+++ b/browser/components/tabview/test/Makefile.in
@@ -159,16 +159,17 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_bug673729.js \
                  browser_tabview_bug677310.js \
                  browser_tabview_bug679853.js \
                  browser_tabview_bug681599.js \
                  browser_tabview_bug685476.js \
                  browser_tabview_bug685692.js \
                  browser_tabview_bug686654.js \
                  browser_tabview_bug697390.js \
+                 browser_tabview_bug705621.js \
                  browser_tabview_click_group.js \
                  browser_tabview_dragdrop.js \
                  browser_tabview_exit_button.js \
                  browser_tabview_expander.js \
                  browser_tabview_firstrun_pref.js \
                  browser_tabview_group.js \
                  browser_tabview_launch.js \
                  browser_tabview_multiwindow_search.js \
--- a/browser/components/tabview/test/browser_tabview_apptabs.js
+++ b/browser/components/tabview/test/browser_tabview_apptabs.js
@@ -44,16 +44,20 @@ function onTabViewWindowLoaded() {
   // create a second group and make sure it gets the icon too
   box.offset(box.width + 20, 0);
   let groupItemTwo = new contentWindow.GroupItem([],
       { bounds: box, title: "test2" });
   is(contentWindow.GroupItems.groupItems.length, 3, "we now have three groups");
   is(appTabCount(groupItemTwo), 1,
       "there's an app tab icon in the second group");
 
+  // When the tab was pinned, the last active group with an item got the focus.
+  // Therefore, switching the focus back to group item one.
+  contentWindow.UI.setActive(groupItemOne);
+
   // unpin the tab, make sure the icon goes away and the TabItem comes on
   gBrowser.unpinTab(xulTab);
   is(groupItemOne._children.length, 1, "the app tab's TabItem is back");
   is(appTabCount(groupItemOne), 0, "the icon is gone from group one");
   is(appTabCount(groupItemTwo), 0, "the icon is gone from group 2");
 
   // pin the tab again
   gBrowser.pinTab(xulTab);
--- a/browser/components/tabview/test/browser_tabview_bug595965.js
+++ b/browser/components/tabview/test/browser_tabview_bug595965.js
@@ -99,16 +99,20 @@ function onTabViewShown(win) {
   is(tray.css("-moz-column-count"), 1,
      "$appTabTray column count is 1");
 
   is(appTabCount(groupItem), 1, "there's now one app tab icon");
 
   ok(!trayContainer.hasClass("appTabTrayContainerTruncated"),
      "$appTabTray container does not have .appTabTrayContainerTruncated");
 
+  // When the tab was pinned, the last active group with an item got the focus.
+  // Therefore, switching the focus back to group item one.
+  contentWindow.UI.setActive(groupItem);
+
   // unpin the last remaining tab
   gBrowser.unpinTab(xulTabs[0]);
 
   is(parseInt(trayContainer.css("width")), 0,
      "$appTabTray container is not visible");
 
   is(appTabCount(groupItem), 0, "there are no app tab icons");
 
new file mode 100644
--- /dev/null
+++ b/browser/components/tabview/test/browser_tabview_bug705621.js
@@ -0,0 +1,30 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test() {
+  waitForExplicitFinish();
+
+  newWindowWithTabView(function(win) {
+    registerCleanupFunction(function() {
+      win.close();
+    });
+
+    let cw = win.TabView.getContentWindow();
+
+    let groupItemOne = cw.GroupItems.groupItems[0];
+    is(groupItemOne.getChildren().length, 1, "Group one has 1 tab item");
+
+    let groupItemTwo = createGroupItemWithBlankTabs(win, 300, 300, 40, 1);
+    is(groupItemTwo.getChildren().length, 1, "Group two has 2 tab items");
+
+    whenTabViewIsHidden(function() {
+      executeSoon(function() { 
+        win.gBrowser.removeTab(win.gBrowser.selectedTab);
+        is(cw.UI.getActiveTab(), groupItemOne.getChild(0), "TabItem in Group one is selected");
+        finish();
+      });
+    }, win);
+    groupItemTwo.getChild(0).zoomIn();
+  });
+}
+
--- a/browser/components/tabview/ui.js
+++ b/browser/components/tabview/ui.js
@@ -779,17 +779,17 @@ let UI = {
         // if not closing the last tab
         if (gBrowser.tabs.length > 1) {
           // Don't return to TabView if there are any app tabs
           for (let a = 0; a < gBrowser._numPinnedTabs; a++) {
             if (!gBrowser.tabs[a].closing)
               return;
           }
 
-          var groupItem = GroupItems.getActiveGroupItem();
+          let groupItem = GroupItems.getActiveGroupItem();
 
           // 1) Only go back to the TabView tab when there you close the last
           // tab of a groupItem.
           let closingLastOfGroup = (groupItem && 
               groupItem._children.length == 1 && 
               groupItem._children[0].tab == tab);
 
           // 2) When a blank tab is active while restoring a closed tab the
--- a/browser/devtools/highlighter/inspector.jsm
+++ b/browser/devtools/highlighter/inspector.jsm
@@ -142,19 +142,26 @@ Highlighter.prototype = {
     stack.appendChild(this.highlighterContainer);
 
     // The veil will make the whole page darker except
     // for the region of the selected box.
     this.buildVeil(this.veilContainer);
 
     this.buildInfobar(controlsBox);
 
+    if (!this.IUI.store.getValue(this.winID, "inspecting")) {
+      this.veilContainer.setAttribute("locked", true);
+      this.nodeInfo.container.setAttribute("locked", true);
+    }
+
     this.browser.addEventListener("resize", this, true);
     this.browser.addEventListener("scroll", this, true);
 
+    this.transitionDisabler = null;
+
     this.handleResize();
   },
 
   /**
    * Build the veil:
    *
    * <vbox id="highlighter-veil-container">
    *   <box id="highlighter-veil-topbox" class="highlighter-veil"/>
@@ -482,30 +489,30 @@ Highlighter.prototype = {
    * Update node information (tagName#id.class) 
    */
   updateInfobar: function Highlighter_updateInfobar()
   {
     // Tag name
     this.nodeInfo.tagNameLabel.textContent = this.node.tagName;
 
     // ID
-    this.nodeInfo.idLabel.textContent = this.node.id;
+    this.nodeInfo.idLabel.textContent = this.node.id ? "#" + this.node.id : "";
 
     // Classes
     let classes = this.nodeInfo.classesBox;
     while (classes.hasChildNodes()) {
       classes.removeChild(classes.firstChild);
     }
 
     if (this.node.className) {
       let fragment = this.chromeDoc.createDocumentFragment();
       for (let i = 0; i < this.node.classList.length; i++) {
         let classLabel = this.chromeDoc.createElement("label");
         classLabel.className = "highlighter-nodeinfobar-class plain";
-        classLabel.textContent = this.node.classList[i];
+        classLabel.textContent = "." + this.node.classList[i];
         fragment.appendChild(classLabel);
       }
       classes.appendChild(fragment);
     }
   },
 
   /**
    * Move the Infobar to the right place in the highlighter.
@@ -660,31 +667,53 @@ Highlighter.prototype = {
     switch (aEvent.type) {
       case "click":
         this.handleClick(aEvent);
         break;
       case "mousemove":
         this.handleMouseMove(aEvent);
         break;
       case "resize":
+        this.brieflyDisableTransitions();
         this.handleResize(aEvent);
         break;
       case "dblclick":
       case "mousedown":
       case "mouseup":
         aEvent.stopPropagation();
         aEvent.preventDefault();
         break;
       case "scroll":
+        this.brieflyDisableTransitions();
         this.highlight();
         break;
     }
   },
 
   /**
+   * Disable the CSS transitions for a short time to avoid laggy animations
+   * during scrolling or resizing.
+   */
+  brieflyDisableTransitions: function Highlighter_brieflyDisableTransitions()
+  {
+   if (this.transitionDisabler) {
+     this.IUI.win.clearTimeout(this.transitionDisabler);
+   } else {
+     this.veilContainer.setAttribute("disable-transitions", "true");
+     this.nodeInfo.container.setAttribute("disable-transitions", "true");
+   }
+   this.transitionDisabler =
+     this.IUI.win.setTimeout(function() {
+       this.veilContainer.removeAttribute("disable-transitions");
+       this.nodeInfo.container.removeAttribute("disable-transitions");
+       this.transitionDisabler = null;
+     }.bind(this), 500);
+  },
+
+  /**
    * Handle clicks.
    *
    * @param nsIDOMEvent aEvent
    *        The DOM event.
    */
   handleClick: function Highlighter_handleClick(aEvent)
   {
     // Stop inspection when the user clicks on a node.
@@ -958,16 +987,18 @@ InspectorUI.prototype = {
   },
 
   /**
    * Initialize highlighter.
    */
   initializeHighlighter: function IUI_initializeHighlighter()
   {
     this.highlighter = new Highlighter(this);
+    this.browser.addEventListener("keypress", this, true);
+    this.highlighter.highlighterContainer.addEventListener("keypress", this, true);
     this.highlighterReady();
   },
 
   /**
    * Initialize the InspectorStore.
    */
   initializeStore: function IUI_initializeStore()
   {
@@ -1081,20 +1112,16 @@ InspectorUI.prototype = {
   startInspecting: function IUI_startInspecting()
   {
     // if currently editing an attribute value, starting
     // "live inspection" mode closes the editor
     if (this.treePanel && this.treePanel.editingContext)
       this.treePanel.closeEditor();
 
     this.inspectToolbutton.checked = true;
-    // Attach event listeners to content window and child windows to enable
-    // highlighting and click to stop inspection.
-    this.browser.addEventListener("keypress", this, true);
-    this.highlighter.highlighterContainer.addEventListener("keypress", this, true);
     this.highlighter.attachInspectListeners();
 
     this.inspecting = true;
     this.toolsDim(true);
     this.highlighter.veilContainer.removeAttribute("locked");
     this.highlighter.nodeInfo.container.removeAttribute("locked");
   },
 
--- a/browser/devtools/highlighter/test/browser_inspector_infobar.js
+++ b/browser/devtools/highlighter/test/browser_inspector_infobar.js
@@ -19,19 +19,19 @@ function test()
   let style = "body{width:100%;height: 100%} div {position: absolute;height: 100px;width: 500px}#bottom {bottom: 0px}#vertical {height: 100%}";
   let html = "<style>" + style + "</style><div id=vertical></div><div id=top class='class1 class2'></div><div id=bottom></div>"
 
   content.location = "data:text/html," + encodeURIComponent(html);
 
   function setupInfobarTest()
   {
     nodes = [
-      {node: doc.querySelector("#top"), position: "bottom", tag: "DIV", id: "top", classes: "class1 class2"},
-      {node: doc.querySelector("#vertical"), position: "overlap", tag: "DIV", id: "vertical", classes: ""},
-      {node: doc.querySelector("#bottom"), position: "top", tag: "DIV", id: "bottom", classes: ""},
+      {node: doc.querySelector("#top"), position: "bottom", tag: "DIV", id: "#top", classes: ".class1 .class2"},
+      {node: doc.querySelector("#vertical"), position: "overlap", tag: "DIV", id: "#vertical", classes: ""},
+      {node: doc.querySelector("#bottom"), position: "top", tag: "DIV", id: "#bottom", classes: ""},
       {node: doc.querySelector("body"), position: "overlap", tag: "BODY", id: "", classes: ""},
     ]
 
     for (let i = 0; i < nodes.length; i++) {
       ok(nodes[i].node, "node " + i + " found");
     }
 
     Services.obs.addObserver(runTests,
--- a/browser/devtools/highlighter/test/browser_inspector_tab_switch.js
+++ b/browser/devtools/highlighter/test/browser_inspector_tab_switch.js
@@ -182,20 +182,28 @@ function inspectorFocusTab2()
 
   // Make sure the inspector is still open.
   ok(!InspectorUI.inspecting, "Inspector is not highlighting");
   ok(!InspectorUI.treePanel.isOpen(), "Inspector Tree Panel is not open");
   ok(!InspectorUI.isSidebarOpen, "Inspector Sidebar is not open");
   is(InspectorUI.store.length, 2, "Inspector.store.length is 2");
   isnot(InspectorUI.selection, div, "selection does not match the div element");
 
-  // Switch back to tab 1.
-  Services.obs.addObserver(inspectorSecondFocusTab1,
-    InspectorUI.INSPECTOR_NOTIFICATIONS.TREEPANELREADY, false);
-  gBrowser.selectedTab = tab1;
+  // Make sure keybindings still sork
+  EventUtils.synthesizeKey("VK_RETURN", { });
+
+  executeSoon(function() {
+    ok(InspectorUI.inspecting, "Inspector is highlighting");
+    InspectorUI.toggleInspection();
+
+    // Switch back to tab 1.
+    Services.obs.addObserver(inspectorSecondFocusTab1,
+      InspectorUI.INSPECTOR_NOTIFICATIONS.TREEPANELREADY, false);
+    gBrowser.selectedTab = tab1;
+  });
 }
 
 function inspectorSecondFocusTab1()
 {
   Services.obs.removeObserver(inspectorSecondFocusTab1,
     InspectorUI.INSPECTOR_NOTIFICATIONS.TREEPANELREADY);
 
   ok(InspectorUI.inspecting, "Inspector is highlighting");
--- a/browser/devtools/webconsole/HUDService.jsm
+++ b/browser/devtools/webconsole/HUDService.jsm
@@ -24,16 +24,17 @@
  *   David Dahl <ddahl@mozilla.com> (original author)
  *   Rob Campbell <rcampbell@mozilla.com>
  *   Johnathan Nightingale <jnightingale@mozilla.com>
  *   Patrick Walton <pcwalton@mozilla.com>
  *   Julian Viereck <jviereck@mozilla.com>
  *   Mihai Șucan <mihai.sucan@gmail.com>
  *   Michael Ratcliffe <mratcliffe@mozilla.com>
  *   Joe Walker <jwalker@mozilla.com>
+ *   Sonny Piers <sonny.piers@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -279,16 +280,19 @@ const ERRORS = { LOG_MESSAGE_MISSING_ARG
                  CANNOT_GET_HUD: "Cannot getHeads Up Display with provided ID",
                  MISSING_ARGS: "Missing arguments",
                  LOG_OUTPUT_FAILED: "Log Failure: Could not append messageNode to outputNode",
 };
 
 // The indent of a console group in pixels.
 const GROUP_INDENT = 12;
 
+// The pref prefix for webconsole filters
+const PREFS_PREFIX = "devtools.webconsole.filter.";
+
 /**
  * Implements the nsIStreamListener and nsIRequestObserver interface. Used
  * within the HS_httpObserverFactory function to get the response body of
  * requests.
  *
  * The code is mostly based on code listings from:
  *
  *   http://www.softwareishard.com/blog/firebug/
@@ -1785,19 +1789,28 @@ HUD_SERVICE.prototype =
    * @returns void
    */
   registerDisplay: function HS_registerDisplay(aHUDId)
   {
     // register a display DOM node Id with the service.
     if (!aHUDId){
       throw new Error(ERRORS.MISSING_ARGS);
     }
-    this.filterPrefs[aHUDId] = this.defaultFilterPrefs;
-    // init storage objects:
-    this.storage.createDisplay(aHUDId);
+    this.filterPrefs[aHUDId] = {
+      network: Services.prefs.getBoolPref(PREFS_PREFIX + "network"),
+      networkinfo: Services.prefs.getBoolPref(PREFS_PREFIX + "networkinfo"),
+      csserror: Services.prefs.getBoolPref(PREFS_PREFIX + "csserror"),
+      cssparser: Services.prefs.getBoolPref(PREFS_PREFIX + "cssparser"),
+      exception: Services.prefs.getBoolPref(PREFS_PREFIX + "exception"),
+      jswarn: Services.prefs.getBoolPref(PREFS_PREFIX + "jswarn"),
+      error: Services.prefs.getBoolPref(PREFS_PREFIX + "error"),
+      info: Services.prefs.getBoolPref(PREFS_PREFIX + "info"),
+      warn: Services.prefs.getBoolPref(PREFS_PREFIX + "warn"),
+      log: Services.prefs.getBoolPref(PREFS_PREFIX + "log"),
+    };
   },
 
   /**
    * When a display is being destroyed, unregister it first
    *
    * @param string aHUDId
    *        The ID of a HUD.
    * @returns void
@@ -1834,19 +1847,16 @@ HUD_SERVICE.prototype =
     }
 
     if (hud.jsterm) {
       hud.jsterm.autocompletePopup.destroy();
     }
 
     delete this.hudReferences[aHUDId];
 
-    // remove the related storage object
-    this.storage.removeDisplay(aHUDId);
-
     for (let windowID in this.windowIds) {
       if (this.windowIds[windowID] == aHUDId) {
         delete this.windowIds[windowID];
       }
     }
 
     this.unregisterActiveContext(aHUDId);
 
@@ -1877,20 +1887,16 @@ HUD_SERVICE.prototype =
    * @returns void
    */
   wakeup: function HS_wakeup()
   {
     if (Object.keys(this.hudReferences).length > 0) {
       return;
     }
 
-    this.storage = new ConsoleStorage();
-    this.defaultFilterPrefs = this.storage.defaultDisplayPrefs;
-    this.defaultGlobalConsolePrefs = this.storage.defaultGlobalConsolePrefs;
-
     // begin observing HTTP traffic
     this.startHTTPObservation();
 
     HUDWindowObserver.init();
     HUDConsoleObserver.init();
     ConsoleAPIObserver.init();
   },
 
@@ -1906,20 +1912,17 @@ HUD_SERVICE.prototype =
     delete this.httpObserver;
 
     Services.obs.removeObserver(this.httpResponseExaminer,
                                 "http-on-examine-response");
 
     this.openRequests = {};
     this.openResponseHeaders = {};
 
-    // delete the storage as it holds onto channels
-    delete this.storage;
     delete this.defaultFilterPrefs;
-    delete this.defaultGlobalConsolePrefs;
 
     delete this.lastFinishedRequestCallback;
 
     HUDWindowObserver.uninit();
     HUDConsoleObserver.uninit();
     ConsoleAPIObserver.shutdown();
   },
 
@@ -3933,40 +3936,40 @@ HeadsUpDisplay.prototype = {
     toolbarButton.setAttribute("tooltip", this.getStr("tip" + name));
     toolbarButton.setAttribute("category", aDescriptor.category);
     toolbarButton.setAttribute("hudId", this.hudId);
     toolbarButton.classList.add("webconsole-filter-button");
 
     let menuPopup = this.makeXULNode("menupopup");
     toolbarButton.appendChild(menuPopup);
 
-    let allChecked = true;
+    let someChecked = false;
     for (let i = 0; i < aDescriptor.severities.length; i++) {
       let severity = aDescriptor.severities[i];
       let menuItem = this.makeXULNode("menuitem");
       menuItem.setAttribute("label", this.getStr("btn" + severity.name));
       menuItem.setAttribute("type", "checkbox");
       menuItem.setAttribute("autocheck", "false");
       menuItem.setAttribute("hudId", this.hudId);
 
       let prefKey = severity.prefKey;
       menuItem.setAttribute("prefKey", prefKey);
 
       let checked = this.filterPrefs[prefKey];
       menuItem.setAttribute("checked", checked);
-      if (!checked) {
-        allChecked = false;
+      if (checked) {
+        someChecked = true;
       }
 
       menuItem.addEventListener("command", toggleFilter, false);
 
       menuPopup.appendChild(menuItem);
     }
 
-    toolbarButton.setAttribute("checked", allChecked);
+    toolbarButton.setAttribute("checked", someChecked);
   },
 
   /**
    * Creates the close button on the toolbar.
    *
    * @param nsIDOMNode aParent
    *        The toolbar to attach the close button to.
    * @return void
@@ -6326,185 +6329,16 @@ HeadsUpDisplayUICommands = {
         HUDService.saveRequestAndResponseBodies = checked;
         break;
       }
     }
   },
 
 };
 
-//////////////////////////////////////////////////////////////////////////
-// ConsoleStorage
-//////////////////////////////////////////////////////////////////////////
-
-var prefs = Services.prefs;
-
-const GLOBAL_STORAGE_INDEX_ID = "GLOBAL_CONSOLE";
-const PREFS_PREFIX = "devtools.webconsole.filter.";
-const PREFS = { network: PREFS_PREFIX + "network",
-                networkinfo: PREFS_PREFIX + "networkinfo",
-                csserror: PREFS_PREFIX + "csserror",
-                cssparser: PREFS_PREFIX + "cssparser",
-                exception: PREFS_PREFIX + "exception",
-                jswarn: PREFS_PREFIX + "jswarn",
-                error: PREFS_PREFIX + "error",
-                info: PREFS_PREFIX + "info",
-                warn: PREFS_PREFIX + "warn",
-                log: PREFS_PREFIX + "log",
-              };
-
-function ConsoleStorage()
-{
-  this.sequencer = null;
-  this.consoleDisplays = {};
-  // each display will have an index that tracks each ConsoleEntry
-  this.displayIndexes = {};
-  this.globalStorageIndex = [];
-  this.globalDisplay = {};
-  this.createDisplay(GLOBAL_STORAGE_INDEX_ID);
-  // TODO: need to create a method that truncates the message
-  // see bug 570543
-
-  this.defaultDisplayPrefs = {
-    network: prefs.getBoolPref(PREFS.network),
-    networkinfo: prefs.getBoolPref(PREFS.networkinfo),
-    csserror: prefs.getBoolPref(PREFS.csserror),
-    cssparser: prefs.getBoolPref(PREFS.cssparser),
-    exception: prefs.getBoolPref(PREFS.exception),
-    jswarn: prefs.getBoolPref(PREFS.jswarn),
-    error: prefs.getBoolPref(PREFS.error),
-    info: prefs.getBoolPref(PREFS.info),
-    warn: prefs.getBoolPref(PREFS.warn),
-    log: prefs.getBoolPref(PREFS.log),
-  };
-}
-
-ConsoleStorage.prototype = {
-
-  sequenceId: function CS_sequencerId()
-  {
-    if (!this.sequencer) {
-      this.sequencer = this.createSequencer();
-    }
-    return this.sequencer.next();
-  },
-
-  createSequencer: function CS_createSequencer()
-  {
-    function sequencer(aInt) {
-      while(1) {
-        aInt++;
-        yield aInt;
-      }
-    }
-    return sequencer(-1);
-  },
-
-  globalStore: function CS_globalStore(aIndex)
-  {
-    return this.displayStore(GLOBAL_CONSOLE_DOM_NODE_ID);
-  },
-
-  displayStore: function CS_displayStore(aId)
-  {
-    var self = this;
-    var idx = -1;
-    var id = aId;
-    var aLength = self.displayIndexes[id].length;
-
-    function displayStoreGenerator(aInt, aLength)
-    {
-      // create a generator object to iterate through any of the display stores
-      // from any index-starting-point
-      while(1) {
-        // throw if we exceed the length of displayIndexes?
-        aInt++;
-        var indexIt = self.displayIndexes[id];
-        var index = indexIt[aInt];
-        if (aLength < aInt) {
-          // try to see if we have more entries:
-          var newLength = self.displayIndexes[id].length;
-          if (newLength > aLength) {
-            aLength = newLength;
-          }
-          else {
-            throw new StopIteration();
-          }
-        }
-        var entry = self.consoleDisplays[id][index];
-        yield entry;
-      }
-    }
-
-    return displayStoreGenerator(-1, aLength);
-  },
-
-  recordEntries: function CS_recordEntries(aHUDId, aConfigArray)
-  {
-    var len = aConfigArray.length;
-    for (var i = 0; i < len; i++){
-      this.recordEntry(aHUDId, aConfigArray[i]);
-    }
-  },
-
-
-  recordEntry: function CS_recordEntry(aHUDId, aConfig)
-  {
-    var id = this.sequenceId();
-
-    this.globalStorageIndex[id] = { hudId: aHUDId };
-
-    var displayStorage = this.consoleDisplays[aHUDId];
-
-    var displayIndex = this.displayIndexes[aHUDId];
-
-    if (displayStorage && displayIndex) {
-      var entry = new ConsoleEntry(aConfig, id);
-      displayIndex.push(entry.id);
-      displayStorage[entry.id] = entry;
-      return entry;
-    }
-    else {
-      throw new Error("Cannot get displayStorage or index object for id " + aHUDId);
-    }
-  },
-
-  getEntry: function CS_getEntry(aId)
-  {
-    var display = this.globalStorageIndex[aId];
-    var storName = display.hudId;
-    return this.consoleDisplays[storName][aId];
-  },
-
-  updateEntry: function CS_updateEntry(aUUID)
-  {
-    // update an individual entry
-    // TODO: see bug 568634
-  },
-
-  createDisplay: function CS_createdisplay(aId)
-  {
-    if (!this.consoleDisplays[aId]) {
-      this.consoleDisplays[aId] = {};
-      this.displayIndexes[aId] = [];
-    }
-  },
-
-  removeDisplay: function CS_removeDisplay(aId)
-  {
-    try {
-      delete this.consoleDisplays[aId];
-      delete this.displayIndexes[aId];
-    }
-    catch (ex) {
-      Cu.reportError("Could not remove console display for id " + aId);
-    }
-  }
-};
-
 /**
  * A Console log entry
  *
  * @param JSObject aConfig, object literal with ConsolEntry properties
  * @param integer aId
  * @returns void
  */
 
--- a/browser/devtools/webconsole/NetworkPanel.xhtml
+++ b/browser/devtools/webconsole/NetworkPanel.xhtml
@@ -44,17 +44,17 @@
    - the terms of any one of the MPL, the GPL or the LGPL.
    -
    - ***** END LICENSE BLOCK ***** -->
 
 
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-  <link rel="stylesheet" href="chrome://global/skin/webConsole_networkPanel.css" type="text/css"/>
+  <link rel="stylesheet" href="chrome://browser/skin/devtools/webconsole_networkpanel.css" type="text/css"/>
 </head>
 <body role="application">
 <table id="header">
   <tr>
     <th class="property-name"
         scope="row">&networkPanel.requestURL;:</th>
     <td class="property-value"
         id="headUrl"></td>
--- a/browser/devtools/webconsole/test/browser/Makefile.in
+++ b/browser/devtools/webconsole/test/browser/Makefile.in
@@ -17,16 +17,17 @@
 # Portions created by the Initial Developer are Copyright (C) 2010
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #  David Dahl <ddahl@mozilla.com>
 #  Patrick Walton <pcwalton@mozilla.com>
 #  Mihai Șucan <mihai.sucan@gmail.com>
 #  Rob Campbell <rcampbell@mozilla.com>
+#  Sonny Piers <sonny.piers@gmail.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either of the GNU General Public License Version 2 or later (the "GPL"),
 # or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -76,20 +77,16 @@ include $(topsrcdir)/config/rules.mk
 	browser_webconsole_log_node_classes.js \
 	browser_webconsole_network_panel.js \
 	browser_webconsole_jsterm.js \
 	browser_webconsole_null_and_undefined_output.js \
 	browser_webconsole_output_order.js \
 	browser_webconsole_property_panel.js \
 	browser_webconsole_property_provider.js \
 	browser_webconsole_registries.js \
-	browser_webconsole_storage_create_display.js \
-	browser_webconsole_storage_iteration.js \
-	browser_webconsole_storage_record_entry.js \
-	browser_webconsole_storage_record_many_entries.js \
 	browser_webconsole_bug_587617_output_copy.js \
 	browser_webconsole_bug_585237_line_limit.js \
 	browser_webconsole_bug_581231_close_button.js \
 	browser_webconsole_bug_582201_duplicate_errors.js \
 	browser_webconsole_bug_580454_timestamp_l10n.js \
 	browser_webconsole_netlogging.js \
 	browser_webconsole_bug_583816_tab_focus.js \
 	browser_webconsole_bug_594477_clickable_output.js \
--- a/browser/devtools/webconsole/test/browser/browser_webconsole_bug_622303_persistent_filters.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_622303_persistent_filters.js
@@ -1,59 +1,116 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 function test() {
   let prefService = Services.prefs;
-  let prefs = [
-    "network",
-    "networkinfo",
-    "csserror",
-    "cssparser",
-    "exception",
-    "jswarn",
-    "error",
-    "warn",
-    "info",
-    "log"
-  ];
 
-  //Set all prefs to true
-  prefs.forEach(function(pref) {
-    prefService.setBoolPref("devtools.webconsole.filter." + pref, true);
-  });
+  let prefs = {
+    "net": [
+      "network",
+      "networkinfo"
+    ],
+    "css": [
+      "csserror",
+      "cssparser"
+    ],
+    "js": [
+      "exception",
+      "jswarn"
+    ],
+    "logging": [
+       "error",
+       "warn",
+       "info",
+       "log"
+    ]
+  };
+
+  // Set all prefs to true
+  for (let category in prefs) {
+    prefs[category].forEach(function(pref) {
+      prefService.setBoolPref("devtools.webconsole.filter." + pref, true);
+    });
+  }
 
   addTab("about:blank");
   openConsole();
-  
+
   let hud = HUDService.getHudByWindow(content);
-  let hudId = HUDService.getHudIdByWindow(content);
+
+  // Check if the filters menuitems exists and are checked
+  for (let category in prefs) {
+    let button = hud.HUDBox.querySelector(".webconsole-filter-button[category=\""
+                                           + category + "\"]");
+    ok(isChecked(button), "main button for " + category + " category is checked");
 
-  //Check if the filters menuitems exists and is checked
-  prefs.forEach(function(pref) {
-    let checked = hud.HUDBox.querySelector("menuitem[prefKey=" + pref + "]").
-      getAttribute("checked");
-    is(checked, "true", "menuitem for " + pref + " exists and is checked");
-  });
-  
-  //Set all prefs to false
-  prefs.forEach(function(pref) {
-    HUDService.setFilterState(hudId, pref, false);
-  });
+    prefs[category].forEach(function(pref) {
+      let menuitem = hud.HUDBox.querySelector("menuitem[prefKey=" + pref + "]");
+      ok(isChecked(menuitem), "menuitem for " + pref + " is checked");
+    });
+  }
+
+  // Set all prefs to false
+  for (let category in prefs) {
+    prefs[category].forEach(function(pref) {
+      HUDService.setFilterState(hud.hudId, pref, false);
+    });
+  }
 
   //Re-init the console
   closeConsole();
   openConsole();
 
   hud = HUDService.getHudByWindow(content);
-  
-  //Check if filters menuitems exists and are unchecked
-  prefs.forEach(function(pref) {
-    let checked = hud.HUDBox.querySelector("menuitem[prefKey=" + pref + "]").
-      getAttribute("checked");
-    is(checked, "false", "menuitem for " + pref + " exists and is not checked");
-    prefService.clearUserPref("devtools.webconsole.filter." + pref);
-  });
-  
+
+  // Check if the filter button and menuitems are unchecked
+  for (let category in prefs) {
+    let button = hud.HUDBox.querySelector(".webconsole-filter-button[category=\""
+                                           + category + "\"]");
+    ok(isUnchecked(button), "main button for " + category + " category is not checked");
+
+    prefs[category].forEach(function(pref) {
+      let menuitem = hud.HUDBox.querySelector("menuitem[prefKey=" + pref + "]");
+      ok(isUnchecked(menuitem), "menuitem for " + pref + " is not checked");
+    });
+  }
+
+  // Set first pref in each category to true
+  for (let category in prefs) {
+    HUDService.setFilterState(hud.hudId, prefs[category][0], true);
+  }
+
+  // Re-init the console
+  closeConsole();
+  openConsole();
+
+  hud = HUDService.getHudByWindow(content);
+
+  // Check the main category button is checked and first menuitem is checked
+  for (let category in prefs) {
+    let button = hud.HUDBox.querySelector(".webconsole-filter-button[category=\""
+                                           + category + "\"]");
+    ok(isChecked(button), category  + " button is checked when first pref is true");
+
+    let pref = prefs[category][0];
+    let menuitem = hud.HUDBox.querySelector("menuitem[prefKey=" + pref + "]");
+    ok(isChecked(menuitem), "first " + category + " menuitem is checked");
+  }
+
+  // Clear prefs
+  for (let category in prefs) {
+    prefs[category].forEach(function(pref) {
+      prefService.clearUserPref("devtools.webconsole.filter." + pref);
+    });
+  }
+
   gBrowser.removeCurrentTab();
-  
   finish();
 }
+
+function isChecked(aNode) {
+  return aNode.getAttribute("checked") === "true";
+}
+
+function isUnchecked(aNode) {
+  return aNode.getAttribute("checked") === "false";
+}
deleted file mode 100644
--- a/browser/devtools/webconsole/test/browser/browser_webconsole_storage_create_display.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is DevTools test code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *  David Dahl <ddahl@mozilla.com>
- *  Patrick Walton <pcwalton@mozilla.com>
- *  Julian Viereck <jviereck@mozilla.com>
- *  Mihai Sucan <mihai.sucan@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-// Tests that the console message store is initialized properly.
-
-const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
-
-function test() {
-  addTab(TEST_URI);
-  browser.addEventListener("DOMContentLoaded", testStorageCreateDisplay,
-                           false);
-}
-
-function testStorageCreateDisplay() {
-  browser.removeEventListener("DOMContentLoaded", testStorageCreateDisplay,
-                              false);
-
-  openConsole();
-
-  let cs = HUDService.storage;
-
-  ok(typeof cs.consoleDisplays == "object",
-     "consoledisplays exist");
-  ok(typeof cs.displayIndexes == "object",
-     "console indexes exist");
-  cs.createDisplay("foo");
-  ok(typeof cs.consoleDisplays["foo"] == "object",
-     "foo display exists");
-  ok(typeof cs.displayIndexes["foo"] == "object",
-     "foo index exists");
-
-  cs.removeDisplay("foo");
-
-  finishTest();
-}
-
deleted file mode 100644
--- a/browser/devtools/webconsole/test/browser/browser_webconsole_storage_iteration.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is DevTools test code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *  David Dahl <ddahl@mozilla.com>
- *  Patrick Walton <pcwalton@mozilla.com>
- *  Julian Viereck <jviereck@mozilla.com>
- *  Mihai Sucan <mihai.sucan@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-// Test that the iterator API of the console message store works.
-
-const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
-
-function test() {
-  addTab(TEST_URI);
-  browser.addEventListener("DOMContentLoaded", testStorageIteration, false);
-}
-
-function testStorageIteration() {
-  browser.removeEventListener("DOMContentLoaded", testStorageIteration,
-                              false);
-
-  openConsole();
-
-  let cs = HUDService.storage;
-
-  // Must have enough entries present to avoid exhausting the iterators below.
-  cs.createDisplay("foo");
-  for (let i = 0; i < 300; i++) {
-    cs.recordEntry("foo", { logLevel: "network", message: "foo" });
-  }
-
-  var id = "foo";
-  var it = cs.displayStore(id);
-  var entry = it.next();
-  var entry2 = it.next();
-
-  let entries = [];
-  for (var i = 0; i < 100; i++) {
-    let _entry = it.next();
-    entries.push(_entry);
-  }
-
-  ok(entries.length == 100, "entries length == 100");
-
-  let entries2 = [];
-
-  for (var i = 0; i < 100; i++){
-    let _entry = it.next();
-    entries2.push(_entry);
-  }
-
-  ok(entries[0].id != entries2[0].id,
-     "two distinct pages of log entries");
-
-  cs.removeDisplay("foo");
-  cs = null;
-  
-  finishTest();
-}
-
deleted file mode 100644
--- a/browser/devtools/webconsole/test/browser/browser_webconsole_storage_record_entry.js
+++ /dev/null
@@ -1,81 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is DevTools test code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *  David Dahl <ddahl@mozilla.com>
- *  Patrick Walton <pcwalton@mozilla.com>
- *  Julian Viereck <jviereck@mozilla.com>
- *  Mihai Sucan <mihai.sucan@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-// Tests that the recordEntry() method of the console store works.
-
-const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
-
-function test() {
-  addTab(TEST_URI);
-  browser.addEventListener("DOMContentLoaded", testStorageRecordEntry,
-                              false);
-}
-
-function testStorageRecordEntry() {
-  browser.removeEventListener("DOMContentLoaded", testStorageRecordEntry,
-                              false);
-  openConsole();
-
-  let cs = HUDService.storage;
-
-  cs.createDisplay("foo");
-
-  var config = {
-    logLevel: "network",
-    message: "HumminaHummina!",
-    activity: {
-      stage: "barStage",
-      data: "bar bar bar bar"
-    }
-  };
-  var entry = cs.recordEntry("foo", config);
-  var res = entry.id;
-  ok(entry.id != null, "Entry.id is: " + res);
-  ok(cs.displayIndexes["foo"].length == 1,
-     "We added one entry.");
-  entry = cs.getEntry(res);
-  ok(entry.id > -1,
-     "We got an entry through the global interface");
-
-  cs.removeDisplay("foo");
-  cs = null;
-  finishTest();
-}
-
deleted file mode 100644
--- a/browser/devtools/webconsole/test/browser/browser_webconsole_storage_record_many_entries.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is DevTools test code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *  David Dahl <ddahl@mozilla.com>
- *  Patrick Walton <pcwalton@mozilla.com>
- *  Julian Viereck <jviereck@mozilla.com>
- *  Mihai Sucan <mihai.sucan@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-// Test that the recordManyEntries() method of the console store works.
-
-const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
-
-function test() {
-  addTab(TEST_URI);
-  browser.addEventListener("DOMContentLoaded", testStorageRecordManyEntries,
-                           false);
-}
-
-function testStorageRecordManyEntries() {
-  browser.removeEventListener("DOMContentLoaded",
-                              testStorageRecordManyEntries, false);
-
-  openConsole();
-
-  let cs = HUDService.storage;
-
-  cs.createDisplay("foo");
-
-  var configArr = [];
-
-  for (var i = 0; i < 1000; i++){
-    let config = {
-      logLevel: "network",
-      message: "HumminaHummina!",
-      activity: {
-        stage: "barStage",
-        data: "bar bar bar bar"
-      }
-    };
-    configArr.push(config);
-  }
-
-  cs.recordEntries("foo", configArr);
-  ok(cs.displayIndexes["foo"].length == 1000,
-     "1000 entries in foo now");
-
-  cs.removeDisplay("foo");
-
-  finishTest();
-}
-
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -129,16 +129,17 @@
 @BINPATH@/components/content_htmldoc.xpt
 @BINPATH@/components/content_html.xpt
 @BINPATH@/components/content_xslt.xpt
 @BINPATH@/components/content_xtf.xpt
 @BINPATH@/components/cookie.xpt
 @BINPATH@/components/directory.xpt
 @BINPATH@/components/docshell.xpt
 @BINPATH@/components/dom.xpt
+@BINPATH@/components/dom_apps.xpt
 @BINPATH@/components/dom_base.xpt
 @BINPATH@/components/dom_battery.xpt
 @BINPATH@/components/dom_canvas.xpt
 @BINPATH@/components/dom_core.xpt
 @BINPATH@/components/dom_css.xpt
 @BINPATH@/components/dom_events.xpt
 @BINPATH@/components/dom_geolocation.xpt
 @BINPATH@/components/dom_notification.xpt
@@ -352,32 +353,36 @@
 @BINPATH@/components/satchel.manifest
 @BINPATH@/components/nsFormAutoComplete.js
 @BINPATH@/components/nsFormHistory.js
 @BINPATH@/components/nsInputListAutoComplete.js
 @BINPATH@/components/contentSecurityPolicy.manifest
 @BINPATH@/components/contentSecurityPolicy.js
 @BINPATH@/components/contentAreaDropListener.manifest
 @BINPATH@/components/contentAreaDropListener.js
+@BINPATH@/components/BrowserProfileMigrators.manifest
+@BINPATH@/components/ChromeProfileMigrator.js
 #ifdef XP_MACOSX
 @BINPATH@/components/libalerts_s.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
 @BINPATH@/components/SyncComponents.manifest
 @BINPATH@/components/Weave.js
 #endif
 @BINPATH@/components/TelemetryPing.js
 @BINPATH@/components/TelemetryPing.manifest
+@BINPATH@/components/Webapps.js
+@BINPATH@/components/Webapps.manifest
 
 ; Modules
 @BINPATH@/modules/*
 
 ; Safe Browsing
 @BINPATH@/components/nsSafebrowsingApplication.manifest
 @BINPATH@/components/nsSafebrowsingApplication.js
 @BINPATH@/components/nsURLClassifier.manifest
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -247,16 +247,17 @@ res/fonts/mathfontCMEX10.properties
 res/fonts/mathfontCMSY10.properties
 res/fonts/mathfontMTExtra.properties
 res/fonts/mathfontMath1.properties
 res/fonts/mathfontMath2.properties
 res/fonts/mathfontMath4.properties
 res/fonts/mathfontPUA.properties
 res/fonts/pangoFontEncoding.properties
 res/forms.css
+res/full-screen-override.css
 res/hiddenWindow.html
 res/html.css
 res/html/gopher-audio.gif
 res/html/gopher-binary.gif
 res/html/gopher-find.gif
 res/html/gopher-image.gif
 res/html/gopher-menu.gif
 res/html/gopher-movie.gif
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -239,28 +239,26 @@ pu.notifyButton.label=Details…
 pu.notifyButton.accesskey=D
 # LOCALIZATION NOTE %S will be replaced by the short name of the application.
 puNotifyText=%S has been updated
 puAlertTitle=%S Updated
 puAlertText=Click here for details
 
 # Geolocation UI
 
-# LOCALIZATION NOTE (geolocation.shareLocation geolocation.dontShareLocation geolocation.alwaysShare geolocation.neverShare): 
+# LOCALIZATION NOTE (geolocation.shareLocation geolocation.alwaysShareLocation geolocation.neverShareLocation):
 #If you're having trouble with the word Share, please use Allow and Block in your language.
 geolocation.shareLocation=Share Location
 geolocation.shareLocation.accesskey=a
-geolocation.dontShareLocation=Don't Share
-geolocation.dontShareLocation.accesskey=o
-geolocation.alwaysShare=Always Share
-geolocation.alwaysShare.accesskey=A
-geolocation.neverShare=Never Share
-geolocation.neverShare.accesskey=N
-geolocation.siteWantsToKnow=%S wants to know your location.
-geolocation.fileWantsToKnow=The file %S wants to know your location.
+geolocation.alwaysShareLocation=Always Share Location
+geolocation.alwaysShareLocation.accesskey=A
+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…
 
 # 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
--- a/browser/locales/en-US/chrome/browser/migration/migration.dtd
+++ b/browser/locales/en-US/chrome/browser/migration/migration.dtd
@@ -10,16 +10,18 @@
 <!ENTITY importFromNothing.label        "Don't import anything">
 <!ENTITY importFromNothing.accesskey    "D">
 <!ENTITY importFromSeamonkey.label      "Netscape 6, 7 or Mozilla 1.x">
 <!ENTITY importFromSeamonkey.accesskey  "N">
 <!ENTITY importFromOpera.label          "Opera">
 <!ENTITY importFromOpera.accesskey      "O">
 <!ENTITY importFromSafari.label         "Safari">
 <!ENTITY importFromSafari.accesskey     "S">
+<!ENTITY importFromChrome.label         "Chrome">
+<!ENTITY importFromChrome.accesskey     "C">
 <!ENTITY importFromHTMLFile.label       "From an HTML File">
 <!ENTITY importFromHTMLFile.accesskey   "F">
 
 <!ENTITY noMigrationSources.label       "No programs that contain bookmarks, history or password data could be found.">
 
 <!ENTITY importSource.title             "Import Settings and Data">
 <!ENTITY importItems.title              "Items to Import">
 <!ENTITY importItems.label              "Select which items to import:">
--- a/browser/locales/en-US/chrome/browser/migration/migration.properties
+++ b/browser/locales/en-US/chrome/browser/migration/migration.properties
@@ -1,54 +1,62 @@
 profileName_format=%S %S
 
 # Browser Specific
 sourceNameIE=Internet Explorer
 sourceNameSeamonkey=Netscape 6/7/Mozilla
 sourceNameOpera=Opera
 sourceNameSafari=Safari
+sourceNameChrome=Google Chrome
 
 importedBookmarksFolder=From %S
 importedSearchURLsFolder=Keyword Searches (From %S)
 importedSearchURLsTitle=Search on %S
 importedSearchUrlDesc=Type "%S <search query>" in the Location Bar to perform a search on %S.
 
 importedSeamonkeyBookmarksTitle=From Netscape 6/7/Mozilla
 importedSafariBookmarks=From Safari
 importedOperaHotlistTitle=From Opera
 importedOperaSearchUrls=Keyword Searches (From Opera)
 
 # Import Sources
 1_ie=Internet Options
 1_opera=Preferences
 1_seamonkey=Preferences
 1_safari=Preferences
+1_chrome=Preferences
 
 2_ie=Cookies
 2_opera=Cookies
 2_seamonkey=Cookies
 2_safari=Cookies
+2_chrome=Cookies
 
 4_ie=Browsing History
 4_opera=Browsing History
 4_seamonkey=Browsing History
 4_safari=Browsing History
+4_chrome=Browsing History
 
 8_ie=Saved Form History
 8_opera=Saved Form History
 8_seamonkey=Saved Form History
 8_safari=Saved Form History
+8_chrome=Saved Form History
 
 16_ie=Saved Passwords
 16_opera=Saved Passwords
 16_seamonkey=Saved Passwords
 16_safari=Saved Passwords
+16_chrome=Saved Passwords
 
 32_ie=Favorites
 32_opera=Bookmarks
 32_seamonkey=Bookmarks
 32_safari=Bookmarks
+32_chrome=Bookmarks
 
 64_ie=Other Data
 64_opera=Other Data
 64_seamonkey=Other Data
 64_safari=Other Data
+64_chrome=Other Data
 
--- a/browser/themes/gnomestripe/browser.css
+++ b/browser/themes/gnomestripe/browser.css
@@ -217,17 +217,17 @@ menuitem.bookmark-item {
   list-style-image: url("chrome://browser/skin/places/livemark-item.png");
 }
 
 .bookmark-item[container][query] {
   list-style-image: url("chrome://browser/skin/places/query.png");
 }
 
 .bookmark-item[query][tagContainer] {
-  list-style-image: url("chrome://mozapps/skin/places/tagContainerIcon.png");
+  list-style-image: url("chrome://browser/skin/places/tag.png");
 }
 
 .bookmark-item[query][dayContainer] {
   list-style-image: url("chrome://browser/skin/places/calendar.png");
 }
 
 .bookmark-item[query][hostContainer] {
   list-style-image: url("moz-icon://stock/gtk-directory?size=menu");
@@ -1954,17 +1954,17 @@ panel[dimmed="true"] {
   border-left-style: solid;
   border-top-left-radius: .3em;
   margin-left: 1em;
 }
 
 /* Highlighter */
 
 .highlighter-veil {
-  background-color: rgba(0, 0, 0, 0.5);
+  background-color: rgba(25, 25, 25, 0.5);
 }
 
 #highlighter-closebutton {
   list-style-image: url("moz-icon://stock/gtk-close?size=menu");
   margin-top: 0;
   margin-bottom: 0;
 }
 
rename from toolkit/themes/gnomestripe/global/webConsole.css
rename to browser/themes/gnomestripe/devtools/webconsole.css
--- a/toolkit/themes/gnomestripe/global/webConsole.css
+++ b/browser/themes/gnomestripe/devtools/webconsole.css
@@ -65,17 +65,17 @@
 
 .webconsole-timestamp {
   color: GrayText;
   margin-top: 0;
   margin-bottom: 0;
 }
 
 .hud-msg-node {
-  list-style-image: url(chrome://global/skin/icons/webconsole.png);
+  list-style-image: url(chrome://browser/skin/devtools/webconsole.png);
   -moz-image-region: rect(0, 1px, 0, 0);
 }
 
 .webconsole-msg-icon {
   margin: 3px 4px;
   width: 8px;
   height: 8px;
 }
@@ -157,17 +157,17 @@
 
 .webconsole-filter-button {
   margin: 0 3px;
 }
 
 .webconsole-filter-button > .toolbarbutton-menubutton-button,
 .webconsole-filter-button:not([type="menu-button"]) {
   -moz-box-orient: horizontal;
-  list-style-image: url("chrome://global/skin/icons/webconsole.png");
+  list-style-image: url("chrome://browser/skin/devtools/webconsole.png");
 }
 
 /* Network styles */
 .webconsole-filter-button[category="net"] {
   -moz-image-region: rect(0, 8px, 8px, 0);
 }
 
 .webconsole-msg-network > .webconsole-msg-icon-container {
rename from toolkit/themes/gnomestripe/global/icons/webconsole.png
rename to browser/themes/gnomestripe/devtools/webconsole.png
rename from toolkit/themes/gnomestripe/global/webConsole_networkPanel.css
rename to browser/themes/gnomestripe/devtools/webconsole_networkpanel.css
deleted file mode 100644
index a788fffb00e59e3fff6931ad34cbc12a59f34254..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index f8536a4e1f9301b9d1304e575d17214325f9652f..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index a788fffb00e59e3fff6931ad34cbc12a59f34254..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index f8536a4e1f9301b9d1304e575d17214325f9652f..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/gnomestripe/jar.mn
+++ b/browser/themes/gnomestripe/jar.mn
@@ -34,20 +34,20 @@ browser.jar:
   skin/classic/browser/Secure.png
   skin/classic/browser/Security-broken.png
   skin/classic/browser/setDesktopBackground.css
   skin/classic/browser/Toolbar.png
   skin/classic/browser/Toolbar-small.png
   skin/classic/browser/urlbar-arrow.png
   skin/classic/browser/feeds/feedIcon.png             (feeds/feedIcon.png)
   skin/classic/browser/feeds/feedIcon16.png           (feeds/feedIcon16.png)
-  skin/classic/browser/feeds/videoFeedIcon.png        (feeds/videoFeedIcon.png)
-  skin/classic/browser/feeds/videoFeedIcon16.png      (feeds/videoFeedIcon16.png)
-  skin/classic/browser/feeds/audioFeedIcon.png        (feeds/audioFeedIcon.png)
-  skin/classic/browser/feeds/audioFeedIcon16.png      (feeds/audioFeedIcon16.png)
+  skin/classic/browser/feeds/videoFeedIcon.png        (feeds/feedIcon.png)
+  skin/classic/browser/feeds/videoFeedIcon16.png      (feeds/feedIcon16.png)
+  skin/classic/browser/feeds/audioFeedIcon.png        (feeds/feedIcon.png)
+  skin/classic/browser/feeds/audioFeedIcon16.png      (feeds/feedIcon16.png)
   skin/classic/browser/feeds/subscribe.css            (feeds/subscribe.css)
   skin/classic/browser/feeds/subscribe-ui.css         (feeds/subscribe-ui.css)
   skin/classic/browser/places/bookmarksMenu.png       (places/bookmarksMenu.png)
   skin/classic/browser/places/bookmarksToolbar.png    (places/bookmarksToolbar.png)
   skin/classic/browser/places/calendar.png            (places/calendar.png)
 * skin/classic/browser/places/editBookmarkOverlay.css (places/editBookmarkOverlay.css)
   skin/classic/browser/places/livemark-item.png       (places/livemark-item.png)
   skin/classic/browser/places/pageStarred.png         (places/pageStarred.png)
@@ -81,16 +81,19 @@ browser.jar:
   skin/classic/browser/tabview/edit-light.png         (tabview/edit-light.png)
   skin/classic/browser/tabview/search.png             (tabview/search.png)
   skin/classic/browser/tabview/stack-expander.png     (tabview/stack-expander.png)
   skin/classic/browser/tabview/tabview.png            (tabview/tabview.png)
   skin/classic/browser/tabview/tabview.css            (tabview/tabview.css)
   skin/classic/browser/devtools/arrows.png            (devtools/arrows.png)
   skin/classic/browser/devtools/goto-mdn.png          (devtools/goto-mdn.png)
   skin/classic/browser/devtools/csshtmltree.css       (devtools/csshtmltree.css)
+  skin/classic/browser/devtools/webconsole.css                  (devtools/webconsole.css)
+  skin/classic/browser/devtools/webconsole_networkpanel.css     (devtools/webconsole_networkpanel.css)
+  skin/classic/browser/devtools/webconsole.png                  (devtools/webconsole.png)
   skin/classic/browser/devtools/gcli.css              (devtools/gcli.css)
   skin/classic/browser/devtools/breadcrumbs/ltr-end-pressed.png              (devtools/breadcrumbs/ltr-end-pressed.png)
   skin/classic/browser/devtools/breadcrumbs/ltr-end-selected-pressed.png     (devtools/breadcrumbs/ltr-end-selected-pressed.png)
   skin/classic/browser/devtools/breadcrumbs/ltr-end-selected.png             (devtools/breadcrumbs/ltr-end-selected.png)
   skin/classic/browser/devtools/breadcrumbs/ltr-end.png                      (devtools/breadcrumbs/ltr-end.png)
   skin/classic/browser/devtools/breadcrumbs/ltr-middle-pressed.png           (devtools/breadcrumbs/ltr-middle-pressed.png)
   skin/classic/browser/devtools/breadcrumbs/ltr-middle-selected-pressed.png  (devtools/breadcrumbs/ltr-middle-selected-pressed.png)
   skin/classic/browser/devtools/breadcrumbs/ltr-middle-selected.png          (devtools/breadcrumbs/ltr-middle-selected.png)
--- a/browser/themes/gnomestripe/places/places.css
+++ b/browser/themes/gnomestripe/places/places.css
@@ -72,17 +72,17 @@ treechildren::-moz-tree-image(title, que
 
 treechildren::-moz-tree-image(query, OrganizerQuery_Downloads) {
   list-style-image: url("chrome://browser/skin/places/downloads.png");
   -moz-image-region: auto;
 }
 
 treechildren::-moz-tree-image(title, query, tagContainer),
 treechildren::-moz-tree-image(query, OrganizerQuery_Tags) {
-  list-style-image: url("chrome://mozapps/skin/places/tagContainerIcon.png");
+  list-style-image: url("chrome://browser/skin/places/tag.png");
 }
 
 /* calendar icon for folders grouping items by date */
 treechildren::-moz-tree-image(title, query, dayContainer) {
   list-style-image: url("chrome://browser/skin/places/calendar.png");
 }
 
 treechildren::-moz-tree-image(title, query, hostContainer) {
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -83,16 +83,27 @@
   border-top: 1px solid rgba(0,0,0,0.65);
 }
 
 #navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
   -moz-box-align: center;
   padding: 2px 4px;
 }
 
+/* Because of -moz-box-align: center above, separators will be invisible unless
+   we set their min-height. See bug 583510 for more information. */
+toolbarseparator {
+  min-height: 22px;
+}
+
+/* We need more height when toolbar buttons show both icon and text. */
+toolbar[mode="full"] toolbarseparator {
+  min-height: 36px;
+}
+
 #nav-bar {
   padding-bottom: 4px !important;
 }
 
 #PersonalToolbar {
   -moz-appearance: none;
   margin-top: -2px; /* overlay the bottom border of the toolbar above us */
   padding-top: 1px !important;
@@ -226,17 +237,17 @@ toolbarbutton.bookmark-item > menupopup 
   list-style-image: url("chrome://browser/skin/page-livemarks.png");
 }
 
 .bookmark-item[query] {
   list-style-image: url("chrome://browser/skin/places/query.png");
 }
 
 .bookmark-item[query][tagContainer] {
-  list-style-image: url("chrome://mozapps/skin/places/tagContainerIcon.png");
+  list-style-image: url("chrome://browser/skin/places/tag.png");
 }
 
 .bookmark-item[query][dayContainer] {
   list-style-image: url("chrome://browser/skin/places/history.png");
 }
 
 .bookmark-item[query][hostContainer] {
   list-style-image: url("chrome://global/skin/tree/folder.png");
@@ -1897,16 +1908,17 @@ toolbarbutton.chevron > .toolbarbutton-m
   box-shadow: @focusRingShadow@;
 }
 
 .tabbrowser-tab:not([selected="true"]):not(:hover):not(:-moz-lwtheme) {
   color: #222;
 }
 
 .tabbrowser-tab[selected="true"] {
+  color: #000;
   z-index: 1;
   position: relative;
 }
 
 .tabbrowser-tab:-moz-lwtheme {
   color: inherit;
   text-shadow: inherit;
 }
@@ -2673,17 +2685,17 @@ panel[dimmed="true"] {
   border-top-left-radius: .3em;
   margin-left: 1em;
 }
 
 
 /* Highlighter */
 
 .highlighter-veil {
-  background-color: rgba(0, 0, 0, 0.5);
+  background-color: rgba(25, 25, 25, 0.5);
 }
 
 #highlighter-closebutton {
   list-style-image: url("chrome://browser/skin/devtools/toolbarbutton-close.png");
   -moz-image-region: rect(0, 16px, 16px, 0);
   min-width: 16px;
   width: 16px;
   margin: 0 4px;
rename from toolkit/themes/pinstripe/global/webConsole.css
rename to browser/themes/pinstripe/devtools/webconsole.css
--- a/toolkit/themes/pinstripe/global/webConsole.css
+++ b/browser/themes/pinstripe/devtools/webconsole.css
@@ -32,17 +32,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-%include shared.inc
+%include ../shared.inc
 
 .hud-box {
   border-bottom: 1px solid #aaa;
   text-shadow: none;
 }
 
 .hud-box.animated {
   -moz-transition: height 100ms;
@@ -68,17 +68,17 @@
 
 .webconsole-timestamp {
   color: GrayText;
   margin-top: 0;
   margin-bottom: 0;
 }
 
 .hud-msg-node {
-  list-style-image: url(chrome://global/skin/icons/webconsole.png);
+  list-style-image: url(chrome://browser/skin/devtools/webconsole.png);
   -moz-image-region: rect(0, 1px, 0, 0);
 }
 
 .webconsole-msg-icon {
   margin: 3px 4px;
   width: 8px;
   height: 8px;
 }
@@ -182,17 +182,17 @@
   box-shadow: @roundButtonPressedShadow@;
   background: #d0d0d0;
 }
 
 .webconsole-filter-button > .toolbarbutton-menubutton-button {
   -moz-appearance: none;
   margin: 0;
   padding: 1px 0;
-  list-style-image: url("chrome://global/skin/icons/webconsole.png");
+  list-style-image: url(chrome://browser/skin/devtools/webconsole.png);
   -moz-box-orient: horizontal;
 }
 
 .webconsole-filter-button:hover:active,
 .webconsole-clear-console-button:hover:active {
   text-shadow: @loweredShadow@;
   box-shadow: @roundButtonPressedShadow@;
   background: @roundButtonPressedBackground@;
rename from toolkit/themes/pinstripe/global/icons/webconsole.png
rename to browser/themes/pinstripe/devtools/webconsole.png
rename from toolkit/themes/pinstripe/global/webConsole_networkPanel.css
rename to browser/themes/pinstripe/devtools/webconsole_networkpanel.css
deleted file mode 100644
index 236b5f82106ed4e9f74eff40a29ee36701a894c2..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index a489de3bf858b6ea84d1470c17ab157f50adc01d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 236b5f82106ed4e9f74eff40a29ee36701a894c2..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index a489de3bf858b6ea84d1470c17ab157f50adc01d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/pinstripe/jar.mn
+++ b/browser/themes/pinstripe/jar.mn
@@ -46,20 +46,20 @@ browser.jar:
   skin/classic/browser/toolbarbutton-dropmarker.png
   skin/classic/browser/urlbar-history-dropmarker.png
   skin/classic/browser/urlbar-arrow.png
   skin/classic/browser/urlbar-popup-blocked.png
   skin/classic/browser/feeds/subscribe.css                  (feeds/subscribe.css)
   skin/classic/browser/feeds/subscribe-ui.css               (feeds/subscribe-ui.css)
   skin/classic/browser/feeds/feedIcon.png                   (feeds/feedIcon.png)
   skin/classic/browser/feeds/feedIcon16.png                 (feeds/feedIcon16.png)
-  skin/classic/browser/feeds/videoFeedIcon.png              (feeds/videoFeedIcon.png)
-  skin/classic/browser/feeds/videoFeedIcon16.png            (feeds/videoFeedIcon16.png)
-  skin/classic/browser/feeds/audioFeedIcon.png              (feeds/audioFeedIcon.png)
-  skin/classic/browser/feeds/audioFeedIcon16.png            (feeds/audioFeedIcon16.png)
+  skin/classic/browser/feeds/videoFeedIcon.png              (feeds/feedIcon.png)
+  skin/classic/browser/feeds/videoFeedIcon16.png            (feeds/feedIcon16.png)
+  skin/classic/browser/feeds/audioFeedIcon.png              (feeds/feedIcon.png)
+  skin/classic/browser/feeds/audioFeedIcon16.png            (feeds/feedIcon16.png)
   skin/classic/browser/setDesktopBackground.css
   skin/classic/browser/inspector.css
   skin/classic/browser/monitor.png
   skin/classic/browser/monitor_16-10.png
   skin/classic/browser/places/allBookmarks.png              (places/allBookmarks.png)
 * skin/classic/browser/places/places.css                    (places/places.css)
 * skin/classic/browser/places/organizer.css                 (places/organizer.css)
   skin/classic/browser/places/query.png                     (places/query.png)
@@ -122,16 +122,19 @@ browser.jar:
   skin/classic/browser/tabview/stack-expander.png           (tabview/stack-expander.png)
   skin/classic/browser/tabview/tabview.png                  (tabview/tabview.png)
   skin/classic/browser/tabview/tabview.css                  (tabview/tabview.css)
   skin/classic/browser/devtools/arrows.png                  (devtools/arrows.png)
   skin/classic/browser/devtools/goto-mdn.png                (devtools/goto-mdn.png)
   skin/classic/browser/devtools/csshtmltree.css             (devtools/csshtmltree.css)
   skin/classic/browser/devtools/gcli.css                    (devtools/gcli.css)
   skin/classic/browser/devtools/toolbarbutton-close.png     (devtools/toolbarbutton-close.png)
+* skin/classic/browser/devtools/webconsole.css                  (devtools/webconsole.css)
+  skin/classic/browser/devtools/webconsole_networkpanel.css     (devtools/webconsole_networkpanel.css)
+  skin/classic/browser/devtools/webconsole.png                  (devtools/webconsole.png)
   skin/classic/browser/devtools/breadcrumbs/ltr-end-pressed.png              (devtools/breadcrumbs/ltr-end-pressed.png)
   skin/classic/browser/devtools/breadcrumbs/ltr-end-selected-pressed.png     (devtools/breadcrumbs/ltr-end-selected-pressed.png)
   skin/classic/browser/devtools/breadcrumbs/ltr-end-selected.png             (devtools/breadcrumbs/ltr-end-selected.png)
   skin/classic/browser/devtools/breadcrumbs/ltr-end.png                      (devtools/breadcrumbs/ltr-end.png)
   skin/classic/browser/devtools/breadcrumbs/ltr-middle-pressed.png           (devtools/breadcrumbs/ltr-middle-pressed.png)
   skin/classic/browser/devtools/breadcrumbs/ltr-middle-selected-pressed.png  (devtools/breadcrumbs/ltr-middle-selected-pressed.png)
   skin/classic/browser/devtools/breadcrumbs/ltr-middle-selected.png          (devtools/breadcrumbs/ltr-middle-selected.png)
   skin/classic/browser/devtools/breadcrumbs/ltr-middle.png                   (devtools/breadcrumbs/ltr-middle.png)
--- a/browser/themes/pinstripe/places/places.css
+++ b/browser/themes/pinstripe/places/places.css
@@ -1,18 +1,12 @@
 %include ../shared.inc
 
 /* Sidebars */
 
-.sidebar-placesTree {
-  background-color: transparent !important;
-  -moz-appearance: none !important;
-  border: none !important;
-}
-
 #bookmarksPanel, 
 #history-panel,
 #sidebar-search-container {
   -moz-appearance: none !important;
   background-color: transparent !important;
   border-top: none !important;
 }
 
@@ -145,17 +139,17 @@ treechildren::-moz-tree-image(query) {
 }
 
 treechildren::-moz-tree-image(query, OrganizerQuery_Downloads) {
   list-style-image: url("chrome://browser/skin/places/downloads.png");
 }
 
 treechildren::-moz-tree-image(title, query, tagContainer),
 treechildren::-moz-tree-image(query, OrganizerQuery_Tags) {
-  list-style-image: url("chrome://mozapps/skin/places/tagContainerIcon.png");
+  list-style-image: url("chrome://browser/skin/places/tag.png");
 }
 
 /* calendar icon for folders grouping items by date */
 treechildren::-moz-tree-image(title, query, dayContainer) {
   list-style-image: url("chrome://browser/skin/places/history.png");
 }
 
 treechildren::-moz-tree-image(title, query, hostContainer) {
deleted file mode 100644
index ff2ecc2f351ef37d250264aa2bb273de08518165..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/winstripe/browser-aero.css
+++ b/browser/themes/winstripe/browser-aero.css
@@ -70,16 +70,21 @@
     border: 0;
     -moz-border-end: 1px solid #A9B7C9;
     min-width: 0;
     width: 3px;
     background-color: transparent;
     -moz-margin-start: -3px;
     position: relative;
   }
+
+  .menu-accel,
+  .menu-iconic-accel {
+    color: graytext;
+  }
 }
 
 @media all and (-moz-windows-compositor) {
   /* These should be hidden w/ glass enabled. Windows draws its own buttons. */
   .titlebar-button {
     display: none;
   }
 
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -616,17 +616,17 @@ menuitem.bookmark-item {
 }
 
 .bookmark-item[container][query] {
   list-style-image: url("chrome://browser/skin/places/query.png");
   -moz-image-region: auto;
 }
 
 .bookmark-item[query][tagContainer] {
-  list-style-image: url("chrome://mozapps/skin/places/tagContainerIcon.png");
+  list-style-image: url("chrome://browser/skin/places/tag.png");
   -moz-image-region: auto;
 }
 
 .bookmark-item[query][dayContainer] {
   list-style-image: url("chrome://browser/skin/places/calendar.png");
   -moz-image-region: auto;
 }
 
@@ -2620,17 +2620,17 @@ panel[dimmed="true"] {
   border-left-style: solid;
   border-top-left-radius: .3em;
   margin-left: 1em;
 }
 
 /* Highlighter */
 
 .highlighter-veil {
-  background-color: rgba(0, 0, 0, 0.5);
+  background-color: rgba(25, 25, 25, 0.5);
 }
 
 #highlighter-closebutton {
   list-style-image: url("chrome://browser/skin/devtools/toolbarbutton-close.png");
   -moz-image-region: rect(0, 16px, 16px, 0);
   min-width: 16px;
   width: 16px;
   -moz-appearance: none;
rename from toolkit/themes/winstripe/global/webConsole.css
rename to browser/themes/winstripe/devtools/webconsole.css
--- a/toolkit/themes/winstripe/global/webConsole.css
+++ b/browser/themes/winstripe/devtools/webconsole.css
@@ -64,17 +64,17 @@
 
 .webconsole-timestamp {
   color: GrayText;
   margin-top: 0;
   margin-bottom: 0;
 }
 
 .hud-msg-node {
-  list-style-image: url(chrome://global/skin/icons/webconsole.png);
+  list-style-image: url(chrome://browser/skin/devtools/webconsole.png);
   -moz-image-region: rect(0, 1px, 0, 0);
 }
 
 .webconsole-msg-icon {
   margin: 3px 4px;
   width: 8px;
   height: 8px;
 }
@@ -151,17 +151,17 @@
 }
 
 .webconsole-clear-console-button > .toolbarbutton-icon {
   display: none;
 }
 
 .webconsole-filter-button > .toolbarbutton-menubutton-button {
   -moz-box-orient: horizontal;
-  list-style-image: url("chrome://global/skin/icons/webconsole.png");
+  list-style-image: url("chrome://browser/skin/devtools/webconsole.png");
 }
 
 .webconsole-filter-button > .toolbarbutton-menubutton-button,
 .webconsole-filter-button > .toolbarbutton-menubutton-button:hover:active {
   -moz-padding-start: 6px;
   -moz-padding-end: 3px;
 }
 
rename from toolkit/themes/winstripe/global/icons/webconsole.png
rename to browser/themes/winstripe/devtools/webconsole.png
rename from toolkit/themes/winstripe/global/webConsole_networkPanel.css
rename to browser/themes/winstripe/devtools/webconsole_networkpanel.css
deleted file mode 100644
index b4d5994995f24adf40fe10f407c9644e802b140d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index e69bc4496139006ad20e34db308bfcc0cbc396c2..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 7c3aceb66f351208cf25ff02abe617cbb5e56456..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index d778807532bc0a1d47ac82370255600d503d66eb..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index b4d5994995f24adf40fe10f407c9644e802b140d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index e69bc4496139006ad20e34db308bfcc0cbc396c2..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 7c3aceb66f351208cf25ff02abe617cbb5e56456..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index d778807532bc0a1d47ac82370255600d503d66eb..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/winstripe/jar.mn
+++ b/browser/themes/winstripe/jar.mn
@@ -1,17 +1,17 @@
 browser.jar:
 % skin browser classic/1.0 %skin/classic/browser/ os=WINNT osversion<6
 % skin browser classic/1.0 %skin/classic/browser/ os!=WINNT
 # NOTE: If you add a new file here, you'll need to add it to the aero
 # section at the bottom of this file
         skin/classic/browser/sanitizeDialog.css                      (sanitizeDialog.css)
 *       skin/classic/browser/aboutPrivateBrowsing.css                (aboutPrivateBrowsing.css)
 *       skin/classic/browser/aboutSessionRestore.css                 (aboutSessionRestore.css)
-        skin/classic/browser/aboutSessionRestore-window-icon.png     (aboutSessionRestore-window-icon.png)
+        skin/classic/browser/aboutSessionRestore-window-icon.png     (preferences/application.png)
         skin/classic/browser/aboutCertError.css                      (aboutCertError.css)
 #ifdef MOZ_SERVICES_SYNC
         skin/classic/browser/aboutSyncTabs.css
 #endif
         skin/classic/browser/actionicon-tab.png
         skin/classic/browser/appmenu-icons.png
         skin/classic/browser/appmenu-dropmarker.png
 *       skin/classic/browser/browser.css                             (browser.css)
@@ -46,20 +46,20 @@ browser.jar:
         skin/classic/browser/menu-forward.png                        (menu-forward.png)
         skin/classic/browser/monitor.png
         skin/classic/browser/monitor_16-10.png
         skin/classic/browser/urlbar-arrow.png
         skin/classic/browser/urlbar-popup-blocked.png
         skin/classic/browser/urlbar-history-dropmarker.png
         skin/classic/browser/feeds/feedIcon.png                      (feeds/feedIcon.png)
         skin/classic/browser/feeds/feedIcon16.png                    (feeds/feedIcon16.png)
-        skin/classic/browser/feeds/audioFeedIcon.png                 (feeds/audioFeedIcon.png)
-        skin/classic/browser/feeds/audioFeedIcon16.png               (feeds/audioFeedIcon16.png)
-        skin/classic/browser/feeds/videoFeedIcon.png                 (feeds/videoFeedIcon.png)
-        skin/classic/browser/feeds/videoFeedIcon16.png               (feeds/videoFeedIcon16.png)
+        skin/classic/browser/feeds/audioFeedIcon.png                 (feeds/feedIcon.png)
+        skin/classic/browser/feeds/audioFeedIcon16.png               (feeds/feedIcon16.png)
+        skin/classic/browser/feeds/videoFeedIcon.png                 (feeds/feedIcon.png)
+        skin/classic/browser/feeds/videoFeedIcon16.png               (feeds/feedIcon16.png)
         skin/classic/browser/feeds/subscribe.css                     (feeds/subscribe.css)
         skin/classic/browser/feeds/subscribe-ui.css                  (feeds/subscribe-ui.css)
         skin/classic/browser/inspector.css
         skin/classic/browser/places/places.css                       (places/places.css)
 *       skin/classic/browser/places/organizer.css                    (places/organizer.css)
         skin/classic/browser/places/bookmark.png                     (places/bookmark.png)
         skin/classic/browser/places/editBookmark.png                 (places/editBookmark.png)
         skin/classic/browser/places/query.png                        (places/query.png)
@@ -106,16 +106,19 @@ browser.jar:
         skin/classic/browser/tabview/tabview.png                    (tabview/tabview.png)
         skin/classic/browser/tabview/tabview-inverted.png           (tabview/tabview-inverted.png)
         skin/classic/browser/tabview/tabview.css                    (tabview/tabview.css)
         skin/classic/browser/devtools/arrows.png                    (devtools/arrows.png)
         skin/classic/browser/devtools/goto-mdn.png                  (devtools/goto-mdn.png)
         skin/classic/browser/devtools/csshtmltree.css               (devtools/csshtmltree.css)
         skin/classic/browser/devtools/gcli.css                      (devtools/gcli.css)
         skin/classic/browser/devtools/toolbarbutton-close.png       (devtools/toolbarbutton-close.png)
+        skin/classic/browser/devtools/webconsole.css                  (devtools/webconsole.css)
+        skin/classic/browser/devtools/webconsole_networkpanel.css     (devtools/webconsole_networkpanel.css)
+        skin/classic/browser/devtools/webconsole.png                  (devtools/webconsole.png)
         skin/classic/browser/devtools/breadcrumbs/ltr-end-pressed.png              (devtools/breadcrumbs/ltr-end-pressed.png)
         skin/classic/browser/devtools/breadcrumbs/ltr-end-selected-pressed.png     (devtools/breadcrumbs/ltr-end-selected-pressed.png)
         skin/classic/browser/devtools/breadcrumbs/ltr-end-selected.png             (devtools/breadcrumbs/ltr-end-selected.png)
         skin/classic/browser/devtools/breadcrumbs/ltr-end.png                      (devtools/breadcrumbs/ltr-end.png)
         skin/classic/browser/devtools/breadcrumbs/ltr-middle-pressed.png           (devtools/breadcrumbs/ltr-middle-pressed.png)
         skin/classic/browser/devtools/breadcrumbs/ltr-middle-selected-pressed.png  (devtools/breadcrumbs/ltr-middle-selected-pressed.png)
         skin/classic/browser/devtools/breadcrumbs/ltr-middle-selected.png          (devtools/breadcrumbs/ltr-middle-selected.png)
         skin/classic/browser/devtools/breadcrumbs/ltr-middle.png                   (devtools/breadcrumbs/ltr-middle.png)
@@ -199,20 +202,20 @@ browser.jar:
         skin/classic/aero/browser/menu-forward.png                   (menu-forward-aero.png)
         skin/classic/aero/browser/monitor.png
         skin/classic/aero/browser/monitor_16-10.png
         skin/classic/aero/browser/urlbar-arrow.png
         skin/classic/aero/browser/urlbar-popup-blocked.png
         skin/classic/aero/browser/urlbar-history-dropmarker.png
         skin/classic/aero/browser/feeds/feedIcon.png                 (feeds/feedIcon-aero.png)
         skin/classic/aero/browser/feeds/feedIcon16.png               (feeds/feedIcon16-aero.png)
-        skin/classic/aero/browser/feeds/audioFeedIcon.png            (feeds/audioFeedIcon-aero.png)
-        skin/classic/aero/browser/feeds/audioFeedIcon16.png          (feeds/audioFeedIcon16-aero.png)
-        skin/classic/aero/browser/feeds/videoFeedIcon.png            (feeds/videoFeedIcon-aero.png)
-        skin/classic/aero/browser/feeds/videoFeedIcon16.png          (feeds/videoFeedIcon16-aero.png)
+        skin/classic/aero/browser/feeds/audioFeedIcon.png            (feeds/feedIcon-aero.png)
+        skin/classic/aero/browser/feeds/audioFeedIcon16.png          (feeds/feedIcon16-aero.png)
+        skin/classic/aero/browser/feeds/videoFeedIcon.png            (feeds/feedIcon-aero.png)
+        skin/classic/aero/browser/feeds/videoFeedIcon16.png          (feeds/feedIcon16-aero.png)
         skin/classic/aero/browser/feeds/subscribe.css                (feeds/subscribe.css)
         skin/classic/aero/browser/feeds/subscribe-ui.css             (feeds/subscribe-ui.css)
         skin/classic/aero/browser/inspector.css
 *       skin/classic/aero/browser/places/places.css                  (places/places-aero.css)
 *       skin/classic/aero/browser/places/organizer.css               (places/organizer-aero.css)
         skin/classic/aero/browser/places/bookmark.png                (places/bookmark.png)
         skin/classic/aero/browser/places/editBookmark.png            (places/editBookmark.png)
         skin/classic/aero/browser/places/query.png                   (places/query-aero.png)
@@ -223,26 +226,25 @@ browser.jar:
         skin/classic/aero/browser/places/editBookmarkOverlay.css     (places/editBookmarkOverlay.css)
         skin/classic/aero/browser/places/libraryToolbar.png          (places/libraryToolbar-aero.png)
         skin/classic/aero/browser/places/starred48.png               (places/starred48-aero.png)
         skin/classic/aero/browser/places/unstarred48.png             (places/unstarred48.png)
         skin/classic/aero/browser/places/tag.png                     (places/tag-aero.png)
         skin/classic/aero/browser/places/history.png                 (places/history-aero.png)
         skin/classic/aero/browser/places/allBookmarks.png            (places/allBookmarks-aero.png)
         skin/classic/aero/browser/places/unsortedBookmarks.png       (places/unsortedBookmarks-aero.png)
-        skin/classic/aero/browser/places/searching_16.png            (places/searching_16-aero.png)
+        skin/classic/aero/browser/places/searching_16.png            (places/searching_16.png)
         skin/classic/aero/browser/places/downloads.png               (places/downloads.png)
         skin/classic/aero/browser/preferences/alwaysAsk.png          (preferences/alwaysAsk-aero.png)
         skin/classic/aero/browser/preferences/application.png        (preferences/application-aero.png)
         skin/classic/aero/browser/preferences/mail.png               (preferences/mail-aero.png)
         skin/classic/aero/browser/preferences/Options.png            (preferences/Options-aero.png)
 #ifdef MOZ_SERVICES_SYNC
         skin/classic/aero/browser/preferences/Options-sync.png       (preferences/Options-sync.png)
 #endif
-        skin/classic/aero/browser/preferences/plugin.png             (preferences/plugin-aero.png)
         skin/classic/aero/browser/preferences/saveFile.png           (preferences/saveFile-aero.png)
 *       skin/classic/aero/browser/preferences/preferences.css        (preferences/preferences.css)
         skin/classic/aero/browser/preferences/applications.css       (preferences/applications.css)
         skin/classic/aero/browser/preferences/aboutPermissions.css   (preferences/aboutPermissions.css)
         skin/classic/aero/browser/tabbrowser/alltabs.png             (tabbrowser/alltabs.png)
         skin/classic/aero/browser/tabbrowser/newtab.png              (tabbrowser/newtab.png)
         skin/classic/aero/browser/tabbrowser/newtab-inverted.png     (tabbrowser/newtab-inverted.png)
         skin/classic/aero/browser/tabbrowser/connecting.png          (tabbrowser/connecting.png)
@@ -260,16 +262,19 @@ browser.jar:
         skin/classic/aero/browser/tabview/tabview.png                (tabview/tabview.png)
         skin/classic/aero/browser/tabview/tabview-inverted.png       (tabview/tabview-inverted.png)
         skin/classic/aero/browser/tabview/tabview.css                (tabview/tabview.css)
         skin/classic/aero/browser/devtools/arrows.png                (devtools/arrows.png)
         skin/classic/aero/browser/devtools/goto-mdn.png              (devtools/goto-mdn.png)
         skin/classic/aero/browser/devtools/csshtmltree.css           (devtools/csshtmltree.css)
         skin/classic/aero/browser/devtools/gcli.css                  (devtools/gcli.css)
         skin/classic/aero/browser/devtools/toolbarbutton-close.png   (devtools/toolbarbutton-close.png)
+        skin/classic/aero/browser/devtools/webconsole.css                  (devtools/webconsole.css)
+        skin/classic/aero/browser/devtools/webconsole_networkpanel.css     (devtools/webconsole_networkpanel.css)
+        skin/classic/aero/browser/devtools/webconsole.png                  (devtools/webconsole.png)
         skin/classic/aero/browser/devtools/breadcrumbs/ltr-end-pressed.png              (devtools/breadcrumbs/ltr-end-pressed.png)
         skin/classic/aero/browser/devtools/breadcrumbs/ltr-end-selected-pressed.png     (devtools/breadcrumbs/ltr-end-selected-pressed.png)
         skin/classic/aero/browser/devtools/breadcrumbs/ltr-end-selected.png             (devtools/breadcrumbs/ltr-end-selected.png)
         skin/classic/aero/browser/devtools/breadcrumbs/ltr-end.png                      (devtools/breadcrumbs/ltr-end.png)
         skin/classic/aero/browser/devtools/breadcrumbs/ltr-middle-pressed.png           (devtools/breadcrumbs/ltr-middle-pressed.png)
         skin/classic/aero/browser/devtools/breadcrumbs/ltr-middle-selected-pressed.png  (devtools/breadcrumbs/ltr-middle-selected-pressed.png)
         skin/classic/aero/browser/devtools/breadcrumbs/ltr-middle-selected.png          (devtools/breadcrumbs/ltr-middle-selected.png)
         skin/classic/aero/browser/devtools/breadcrumbs/ltr-middle.png                   (devtools/breadcrumbs/ltr-middle.png)
--- a/browser/themes/winstripe/places/places.css
+++ b/browser/themes/winstripe/places/places.css
@@ -76,17 +76,17 @@ treechildren::-moz-tree-image(container,
 /* query-nodes should be styled even if they're not expandable */
 treechildren::-moz-tree-image(title, query) {
   list-style-image: url("chrome://browser/skin/places/query.png");
   -moz-image-region: auto;
 }
 
 treechildren::-moz-tree-image(title, query, tagContainer),
 treechildren::-moz-tree-image(query, OrganizerQuery_Tags) {
-  list-style-image: url("chrome://mozapps/skin/places/tagContainerIcon.png");
+  list-style-image: url("chrome://browser/skin/places/tag.png");
   -moz-image-region: auto;
 }
 
 treechildren::-moz-tree-image(query, OrganizerQuery_Downloads) {
   list-style-image: url("chrome://browser/skin/places/downloads.png");
   -moz-image-region: auto;
 }
 
deleted file mode 100644
index 2f97e742a3f0855c97a356c9f699b3bda3ac7c7b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 5d796cc4c57dd3da1669fd4e51ba8d954ed4c866..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
new file mode 100644
--- /dev/null
+++ b/build/autoconf/mozcommonheader.m4
@@ -0,0 +1,41 @@
+dnl ***** BEGIN LICENSE BLOCK *****
+dnl Version: MPL 1.1/GPL 2.0/LGPL 2.1
+dnl
+dnl The contents of this file are subject to the Mozilla Public License Version
+dnl 1.1 (the "License"); you may not use this file except in compliance with
+dnl the License. You may obtain a copy of the License at
+dnl http://www.mozilla.org/MPL/
+dnl
+dnl Software distributed under the License is distributed on an "AS IS" basis,
+dnl WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+dnl for the specific language governing rights and limitations under the
+dnl License.
+dnl
+dnl The Original Code is mozilla.org code.
+dnl
+dnl The Initial Developer of the Original Code is the
+dnl Mozilla Foundation <http://www.mozilla.org>
+dnl
+dnl Portions created by the Initial Developer are Copyright (C) 2009
+dnl the Initial Developer. All Rights Reserved.
+dnl
+dnl
+dnl Alternatively, the contents of this file may be used under the terms of
+dnl either of the GNU General Public License Version 2 or later (the "GPL"),
+dnl or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+dnl in which case the provisions of the GPL or the LGPL are applicable instead
+dnl of those above. If you wish to allow use of your version of this file only
+dnl under the terms of either the GPL or the LGPL, and not to allow others to
+dnl use your version of this file under the terms of the MPL, indicate your
+dnl decision by deleting the provisions above and replace them with the notice
+dnl and other provisions required by the GPL or the LGPL. If you do not delete
+dnl the provisions above, a recipient may use your version of this file under
+dnl the terms of any one of the MPL, the GPL or the LGPL.
+dnl
+dnl ***** END LICENSE BLOCK *****
+
+AC_DEFUN(MOZ_CHECK_COMMON_HEADERS,
+	MOZ_CHECK_HEADERS(sys/byteorder.h compat.h getopt.h sys/bitypes.h \
+        memory.h unistd.h gnu/libc-version.h nl_types.h malloc.h \
+        X11/XKBlib.h io.h cpuid.h)
+)
--- a/build/autoconf/mozheader.m4
+++ b/build/autoconf/mozheader.m4
@@ -31,35 +31,36 @@ dnl under the terms of either the GPL or
 dnl use your version of this file under the terms of the MPL, indicate your
 dnl decision by deleting the provisions above and replace them with the notice
 dnl and other provisions required by the GPL or the LGPL. If you do not delete
 dnl the provisions above, a recipient may use your version of this file under
 dnl the terms of any one of the MPL, the GPL or the LGPL.
 dnl
 dnl ***** END LICENSE BLOCK *****
 
-dnl MOZ_CHECK_HEADER(HEADER-FILE, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+dnl MOZ_CHECK_HEADER(HEADER-FILE, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, INCLUDES]]])
 AC_DEFUN([MOZ_CHECK_HEADER],
 [ dnl Do the transliteration at runtime so arg 1 can be a shell variable.
   ac_safe=`echo "$1" | sed 'y%./+-%__p_%'`
   AC_MSG_CHECKING([for $1])
   AC_CACHE_VAL(ac_cv_header_$ac_safe,
- [ AC_TRY_COMPILE([#include <$1>], ,
+ [ AC_TRY_COMPILE([$4
+#include <$1>], ,
                   eval "ac_cv_header_$ac_safe=yes",
                   eval "ac_cv_header_$ac_safe=no") ])
   if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
     AC_MSG_RESULT(yes)
     ifelse([$2], , :, [$2])
   else
     AC_MSG_RESULT(no)
     ifelse([$3], , , [$3])
   fi
 ])
 
-dnl MOZ_CHECK_HEADERS(HEADER-FILE... [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+dnl MOZ_CHECK_HEADERS(HEADER-FILE... [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, INCLUDES]]])
 AC_DEFUN([MOZ_CHECK_HEADERS],
 [ for ac_hdr in $1
   do
     MOZ_CHECK_HEADER($ac_hdr,
                      [ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
-                       AC_DEFINE_UNQUOTED($ac_tr_hdr) $2], $3)
+                       AC_DEFINE_UNQUOTED($ac_tr_hdr) $2], $3, [$4])
   done
 ])
--- a/build/automationutils.py
+++ b/build/automationutils.py
@@ -133,17 +133,18 @@ class ZipFileReader(object):
 
     for name in self._zipfile.namelist():
       self._extractname(name, path)
 
 log = logging.getLogger()
 
 def isURL(thing):
   """Return True if |thing| looks like a URL."""
-  return urlparse(thing).scheme != ''
+  # We want to download URLs like http://... but not Windows paths like c:\...
+  return len(urlparse(thing).scheme) >= 2
 
 def addCommonOptions(parser, defaults={}):
   parser.add_option("--xre-path",
                     action = "store", type = "string", dest = "xrePath",
                     # individual scripts will set a sane default
                     default = None,
                     help = "absolute path to directory containing XRE (probably xulrunner)")
   if 'SYMBOLS_PATH' not in defaults:
@@ -279,17 +280,17 @@ def getDebuggerInfo(directory, debugger,
       "interactive" : getDebuggerInfo("interactive", False),
       "args": getDebuggerInfo("args", "").split()
     }
 
     if debuggerArgs:
       debuggerInfo["args"] = debuggerArgs.split()
     if debuggerInteractive:
       debuggerInfo["interactive"] = debuggerInteractive
-  
+
   return debuggerInfo
 
 
 def dumpLeakLog(leakLogFile, filter = False):
   """Process the leak log, without parsing it.
 
   Use this function if you want the raw log only.
   Use it preferably with the |XPCOM_MEM_LEAK_LOG| environment variable.
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -114,17 +114,16 @@ MOZ_MEMORY      = @MOZ_MEMORY@
 MOZ_PROFILING   = @MOZ_PROFILING@
 MOZ_ENABLE_PROFILER_SPS = @MOZ_ENABLE_PROFILER_SPS@
 MOZ_JPROF       = @MOZ_JPROF@
 MOZ_SHARK       = @MOZ_SHARK@
 MOZ_CALLGRIND   = @MOZ_CALLGRIND@
 MOZ_VTUNE       = @MOZ_VTUNE@
 MOZ_ETW         = @MOZ_ETW@
 MOZ_TRACE_JSCALLS = @MOZ_TRACE_JSCALLS@
-MOZ_TRACEVIS    = @MOZ_TRACEVIS@
 DEHYDRA_PATH    = @DEHYDRA_PATH@
 
 NS_TRACE_MALLOC = @NS_TRACE_MALLOC@
 USE_ELF_DYNSTR_GC = @USE_ELF_DYNSTR_GC@
 USE_ELF_HACK = @USE_ELF_HACK@
 STDCXX_COMPAT = @STDCXX_COMPAT@
 MOZ_LIBSTDCXX_TARGET_VERSION=@MOZ_LIBSTDCXX_TARGET_VERSION@
 MOZ_LIBSTDCXX_HOST_VERSION=@MOZ_LIBSTDCXX_HOST_VERSION@
--- a/configure.in
+++ b/configure.in
@@ -3404,22 +3404,17 @@ dnl Checks for header files.
 dnl ========================================================
 AC_HEADER_DIRENT
 case "$target_os" in
 freebsd*|openbsd*)
 # for stuff like -lXshm
     CPPFLAGS="${CPPFLAGS} ${X_CFLAGS}"
     ;;
 esac
-MOZ_CHECK_HEADERS(sys/byteorder.h compat.h getopt.h)
-MOZ_CHECK_HEADERS(sys/bitypes.h memory.h unistd.h)
-MOZ_CHECK_HEADERS(gnu/libc-version.h nl_types.h)
-MOZ_CHECK_HEADERS(malloc.h)
-MOZ_CHECK_HEADERS(X11/XKBlib.h)
-MOZ_CHECK_HEADERS(io.h)
+MOZ_CHECK_COMMON_HEADERS
 
 dnl These are all the places some variant of statfs can be hiding.
 MOZ_CHECK_HEADERS(sys/statvfs.h sys/statfs.h sys/vfs.h sys/mount.h)
 
 dnl Quota support
 MOZ_CHECK_HEADERS(sys/quota.h sys/sysmacros.h)
 MOZ_CHECK_HEADERS(linux/quota.h)
 
@@ -5930,22 +5925,21 @@ MOZ_ARG_DISABLE_BOOL(xtf,
 [  --disable-xtf           Disable XTF (pluggable xml tags) support],
     MOZ_XTF=,
     MOZ_XTF=1 )
 if test "$MOZ_XTF"; then
   AC_DEFINE(MOZ_XTF)
 fi
 
 dnl ========================================================
-dnl Pref extensions (autoconfig and system-pref)
+dnl Pref extensions (autoconfig)
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(pref-extensions,
 [  --disable-pref-extensions
-                          Disable pref extensions such as autoconfig and
-                          system-pref],
+                          Disable pref extensions such as autoconfig],
   MOZ_PREF_EXTENSIONS=,
   MOZ_PREF_EXTENSIONS=1 )
 
 dnl ========================================================
 dnl Searching of system directories for extensions.
 dnl Note: this switch is meant to be used for test builds
 dnl whose behavior should not depend on what happens to be
 dnl installed on the local machine.
@@ -7322,27 +7316,16 @@ MOZ_ARG_ENABLE_BOOL(trace-jscalls,
 [  --enable-trace-jscalls  Enable JS call enter/exit callback (default=no)],
     MOZ_TRACE_JSCALLS=1,
     MOZ_TRACE_JSCALLS= )
 if test -n "$MOZ_TRACE_JSCALLS"; then
     AC_DEFINE(MOZ_TRACE_JSCALLS)
 fi
 
 dnl ========================================================
-dnl = Use TraceVis
-dnl ========================================================
-MOZ_ARG_ENABLE_BOOL(tracevis,
-[  --enable-tracevis       Enable TraceVis tracing tool (default=no)],
-    MOZ_TRACEVIS=1,
-    MOZ_TRACEVIS= )
-if test -n "$MOZ_TRACEVIS"; then
-    AC_DEFINE(MOZ_TRACEVIS)
-fi
-
-dnl ========================================================
 dnl = Use incremental GC
 dnl ========================================================
 JSGC_INCREMENTAL=1
 MOZ_ARG_DISABLE_BOOL(gcincremental,
 [  --disable-gcincremental Disable incremental GC],
     JSGC_INCREMENTAL= )
 if test -n "$JSGC_INCREMENTAL"; then
     AC_DEFINE(JSGC_INCREMENTAL)
@@ -8756,18 +8739,18 @@ if test -n "$MOZ_WEBGL_GLX"; then
     fi
 fi # MOZ_WEBGL_GLX
 fi # COMPILE_ENVIRONMENT
 
 if test "$USE_FC_FREETYPE"; then
     if test "$COMPILE_ENVIRONMENT"; then
     	_SAVE_CPPFLAGS="$CPPFLAGS"
     	CPPFLAGS="$CPPFLAGS $FT2_CFLAGS $XCFLAGS"
-        AC_CHECK_HEADERS(fontconfig/fcfreetype.h, ,
-            [AC_MSG_ERROR(Can't find header fontconfig/fcfreetype.h.)])
+        MOZ_CHECK_HEADERS([fontconfig/fcfreetype.h], ,
+            [AC_MSG_ERROR(Can't find header fontconfig/fcfreetype.h.)], [#include <fontconfig/fontconfig.h>])
     	CPPFLAGS="$_SAVE_CPPFLAGS"
     else
         AC_DEFINE(HAVE_FONTCONFIG_FCFREETYPE_H)
     fi
 fi
 
 dnl Set various defines and substitutions
 dnl ========================================================
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1285,21 +1285,16 @@ public:
 #endif
     }
   }
   static void ReleaseWrapper(nsISupports* aScriptObjectHolder,
                              nsWrapperCache* aCache);
   static void TraceWrapper(nsWrapperCache* aCache, TraceCallback aCallback,
                            void *aClosure);
 
-  /**
-   * Convert nsIContent::IME_STATUS_* to nsIWidget::IME_STATUS_*
-   */
-  static PRUint32 GetWidgetStatusFromIMEStatus(PRUint32 aState);
-
   /*
    * Notify when the first XUL menu is opened and when the all XUL menus are
    * closed. At opening, aInstalling should be TRUE, otherwise, it should be
    * FALSE.
    */
   static void NotifyInstalledMenuKeyboardListener(bool aInstalling);
 
   /**
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -58,37 +58,42 @@ class nsTextFragment;
 class nsIDocShell;
 class nsIFrame;
 class nsISMILAttr;
 class nsIDOMCSSStyleDeclaration;
 
 namespace mozilla {
 namespace css {
 class StyleRule;
-}
-}
+} // namespace css
+namespace widget {
+struct IMEState;
+} // namespace widget
+} // namespace mozilla
 
 enum nsLinkState {
   eLinkState_Unknown    = 0,
   eLinkState_Unvisited  = 1,
   eLinkState_Visited    = 2,
   eLinkState_NotLink    = 3
 };
 
 // IID for the nsIContent interface
 #define NS_ICONTENT_IID \
-{ 0x3128b3a0, 0xb609, 0x44e3, \
-  { 0xad, 0x91, 0xdc, 0xf1, 0x4a, 0x3f, 0xf6, 0xa0 } }
+{ 0xed40a3e5, 0xd7ed, 0x473e, \
+ { 0x85, 0xe3, 0x82, 0xc3, 0xf0, 0x41, 0xdb, 0x52 } }
 
 /**
  * A node of content in a document's content model. This interface
  * is supported by all content objects.
  */
 class nsIContent : public nsINode {
 public:
+  typedef mozilla::widget::IMEState IMEState;
+
 #ifdef MOZILLA_INTERNAL_API
   // If you're using the external API, the only thing you can know about
   // nsIContent is that it exists with an IID
 
   nsIContent(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsINode(aNodeInfo),
       mPrimaryFrame(nsnull)
   {
@@ -599,50 +604,28 @@ public:
                                 bool aIsTrustedEvent)
   {
   }
 
   /*
    * Get desired IME state for the content.
    *
    * @return The desired IME status for the content.
-   *         This is a combination of IME_STATUS_* flags,
-   *         controlling what happens to IME when the content takes focus.
-   *         If this is IME_STATUS_NONE, IME remains in its current state.
-   *         IME_STATUS_ENABLE and IME_STATUS_DISABLE must not be set
-   *         together; likewise IME_STATUS_OPEN and IME_STATUS_CLOSE must
-   *         not be set together.
-   *         If you return IME_STATUS_DISABLE, you should not set the
-   *         OPEN or CLOSE flag; that way, when IME is next enabled,
-   *         the previous OPEN/CLOSE state will be restored (unless the newly
-   *         focused content specifies the OPEN/CLOSE state by setting the OPEN
-   *         or CLOSE flag with the ENABLE flag).
-   *         IME_STATUS_PASSWORD should be returned only from password editor,
-   *         this value has a special meaning. It is used as alternative of
-   *         IME_STATUS_DISABLED.
-   *         IME_STATUS_PLUGIN should be returned only when plug-in has focus.
-   *         When a plug-in is focused content, we should send native events
-   *         directly. Because we don't process some native events, but they may
-   *         be needed by the plug-in.
+   *         This is a combination of an IME enabled value and
+   *         an IME open value of widget::IMEState.
+   *         If you return DISABLED, you should not set the OPEN and CLOSE
+   *         value.
+   *         PASSWORD should be returned only from password editor, this value
+   *         has a special meaning. It is used as alternative of DISABLED.
+   *         PLUGIN should be returned only when plug-in has focus.  When a
+   *         plug-in is focused content, we should send native events directly.
+   *         Because we don't process some native events, but they may be needed
+   *         by the plug-in.
    */
-  enum {
-    IME_STATUS_NONE     = 0x0000,
-    IME_STATUS_ENABLE   = 0x0001,
-    IME_STATUS_DISABLE  = 0x0002,
-    IME_STATUS_PASSWORD = 0x0004,
-    IME_STATUS_PLUGIN   = 0x0008,
-    IME_STATUS_OPEN     = 0x0010,
-    IME_STATUS_CLOSE    = 0x0020
-  };
-  enum {
-    IME_STATUS_MASK_ENABLED = IME_STATUS_ENABLE | IME_STATUS_DISABLE |
-                              IME_STATUS_PASSWORD | IME_STATUS_PLUGIN,
-    IME_STATUS_MASK_OPENED  = IME_STATUS_OPEN | IME_STATUS_CLOSE
-  };
-  virtual PRUint32 GetDesiredIMEState();
+  virtual IMEState GetDesiredIMEState();
 
   /**
    * Gets content node with the binding (or native code, possibly on the
    * frame) responsible for our construction (and existence).  Used by
    * anonymous content (both XBL-generated and native-anonymous).
    *
    * null for all explicit content (i.e., content reachable from the top
    * of its GetParent() chain via child lists).
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -59,17 +59,17 @@
 #include "nsIVariant.h"
 #include "nsIObserver.h"
 #include "nsGkAtoms.h"
 #include "nsAutoPtr.h"
 #include "nsPIDOMWindow.h"
 #include "nsSMILAnimationController.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIDocumentEncoder.h"
-#include "nsIAnimationFrameListener.h"
+#include "nsIFrameRequestCallback.h"
 #include "nsEventStates.h"
 #include "nsIStructuredCloneContainer.h"
 #include "nsIBFCacheEntry.h"
 #include "nsDOMMemoryReporter.h"
 
 class nsIContent;
 class nsPresContext;
 class nsIPresShell;
@@ -1513,28 +1513,24 @@ public:
    * Lookup an image element using its associated ID, which is usually provided
    * by |-moz-element()|. Similar to GetElementById, with the difference that
    * elements set using mozSetImageElement have higher priority.
    * @param aId the ID associated the element we want to lookup
    * @return the element associated with |aId|
    */
   virtual Element* LookupImageElement(const nsAString& aElementId) = 0;
 
-  void ScheduleBeforePaintEvent(nsIAnimationFrameListener* aListener);
-  void BeforePaintEventFiring()
-  {
-    mHavePendingPaint = false;
-  }
+  void ScheduleFrameRequestCallback(nsIFrameRequestCallback* aCallback);
 
-  typedef nsTArray< nsCOMPtr<nsIAnimationFrameListener> > AnimationListenerList;
+  typedef nsTArray< nsCOMPtr<nsIFrameRequestCallback> > FrameRequestCallbackList;
   /**
-   * Put this documents animation frame listeners into the provided
+   * Put this document's frame request callbacks into the provided
    * list, and forget about them.
    */
-  void TakeAnimationFrameListeners(AnimationListenerList& aListeners);
+  void TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks);
 
   // This returns true when the document tree is being teared down.
   bool InUnlinkOrDeletion() { return mInUnlinkOrDeletion; }
 
   /*
    * Image Tracking
    *
    * Style and content images register their imgIRequests with their document
@@ -1741,19 +1737,16 @@ protected:
   bool mCreatingStaticClone;
 
   // True iff the document is being unlinked or deleted.
   bool mInUnlinkOrDeletion;
 
   // True if document has ever had script handling object.
   bool mHasHadScriptHandlingObject;
 
-  // True if we're waiting for a before-paint event.
-  bool mHavePendingPaint;
-
   // True if we're an SVG document being used as an image.
   bool mIsBeingUsedAsImage;
 
   // True is this document is synthetic : stand alone image, video, audio
   // file, etc.
   bool mIsSyntheticDocument;
 
   // True if this document has links whose state needs updating
@@ -1807,17 +1800,17 @@ protected:
   PRUint32 mExternalScriptsBeingEvaluated;
 
   // Weak reference to mScriptGlobalObject QI:d to nsPIDOMWindow,
   // updated on every set of mSecriptGlobalObject.
   nsPIDOMWindow *mWindow;
 
   nsCOMPtr<nsIDocumentEncoder> mCachedEncoder;
 
-  AnimationListenerList mAnimationFrameListeners;
+  FrameRequestCallbackList mFrameRequestCallbacks;
 
   // This object allows us to evict ourself from the back/forward cache.  The
   // pointer is non-null iff we're currently in the bfcache.
   nsIBFCacheEntry *mBFCacheEntry;
 
   // Our base target.
   nsString mBaseTarget;
 
--- a/content/base/src/nsCCUncollectableMarker.cpp
+++ b/content/base/src/nsCCUncollectableMarker.cpp
@@ -46,16 +46,19 @@
 #include "nsIWindowMediator.h"
 #include "nsPIDOMWindow.h"
 #include "nsIWebNavigation.h"
 #include "nsISHistory.h"
 #include "nsISHEntry.h"
 #include "nsISHContainer.h"
 #include "nsIWindowWatcher.h"
 #include "mozilla/Services.h"
+#include "nsIXULWindow.h"
+#include "nsIAppShellService.h"
+#include "nsAppShellCID.h"
 
 static bool sInited = 0;
 PRUint32 nsCCUncollectableMarker::sGeneration = 0;
 
 NS_IMPL_ISUPPORTS1(nsCCUncollectableMarker, nsIObserver)
 
 /* static */
 nsresult
@@ -226,11 +229,24 @@ nsCCUncollectableMarker::Observe(nsISupp
     do_GetService(NS_WINDOWWATCHER_CONTRACTID);
   if (ww) {
     rv = ww->GetWindowEnumerator(getter_AddRefs(windowList));
     NS_ENSURE_SUCCESS(rv, rv);
 
     MarkWindowList(windowList);
   }
 
+  nsCOMPtr<nsIAppShellService> appShell = 
+    do_GetService(NS_APPSHELLSERVICE_CONTRACTID);
+  if (appShell) {
+    nsCOMPtr<nsIXULWindow> hw;
+    appShell->GetHiddenWindow(getter_AddRefs(hw));
+    if (hw) {
+      nsCOMPtr<nsIDocShell> shell;
+      hw->GetDocShell(getter_AddRefs(shell));
+      nsCOMPtr<nsIDocShellTreeNode> shellTreeNode = do_QueryInterface(shell);
+      MarkDocShell(shellTreeNode);
+    }
+  }
+
   return NS_OK;
 }
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -207,16 +207,17 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_
 #include "nsIObjectLoadingContent.h"
 
 #include "mozilla/Preferences.h"
 
 #include "nsWrapperCacheInlines.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::layers;
+using namespace mozilla::widget;
 using namespace mozilla;
 
 const char kLoadAsData[] = "loadAsData";
 
 static const char kJSStackContractID[] = "@mozilla.org/js/xpc/ContextStack;1";
 static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
 static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
 
@@ -4022,35 +4023,16 @@ nsContentUtils::DropJSObjects(void* aScr
   nsresult rv = sXPConnect->RemoveJSHolder(aScriptObjectHolder);
   if (--sJSGCThingRootCount == 0) {
     nsLayoutStatics::Release();
   }
   return rv;
 }
 
 /* static */
-PRUint32
-nsContentUtils::GetWidgetStatusFromIMEStatus(PRUint32 aState)
-{
-  switch (aState & nsIContent::IME_STATUS_MASK_ENABLED) {
-    case nsIContent::IME_STATUS_DISABLE:
-      return nsIWidget::IME_STATUS_DISABLED;
-    case nsIContent::IME_STATUS_ENABLE:
-      return nsIWidget::IME_STATUS_ENABLED;
-    case nsIContent::IME_STATUS_PASSWORD:
-      return nsIWidget::IME_STATUS_PASSWORD;
-    case nsIContent::IME_STATUS_PLUGIN:
-      return nsIWidget::IME_STATUS_PLUGIN;
-    default:
-      NS_ERROR("The given state doesn't have valid enable state");
-      return nsIWidget::IME_STATUS_ENABLED;
-  }
-}
-
-/* static */
 void
 nsContentUtils::NotifyInstalledMenuKeyboardListener(bool aInstalling)
 {
   nsIMEStateManager::OnInstalledMenuKeyboardListener(aInstalling);
 }
 
 static bool SchemeIs(nsIURI* aURI, const char* aScheme)
 {
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1876,19 +1876,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFullScreenElement)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mStateObjectCached)
 
   // Traverse all our nsCOMArrays.
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mStyleSheets)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mCatalogSheets)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mPreloadingImages)
 
-  for (PRUint32 i = 0; i < tmp->mAnimationFrameListeners.Length(); ++i) {
-    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mAnimationFrameListeners[i]");
-    cb.NoteXPCOMChild(tmp->mAnimationFrameListeners[i]);
+  for (PRUint32 i = 0; i < tmp->mFrameRequestCallbacks.Length(); ++i) {
+    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mFrameRequestCallbacks[i]");
+    cb.NoteXPCOMChild(tmp->mFrameRequestCallbacks[i]);
   }
 
   // Traverse animation components
   if (tmp->mAnimationController) {
     tmp->mAnimationController->Traverse(&cb);
   }
 
   if (tmp->mSubDocuments && tmp->mSubDocuments->ops) {
@@ -1946,17 +1946,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
     tmp->mListenerManager = nsnull;
   }
 
   if (tmp->mSubDocuments) {
     PL_DHashTableDestroy(tmp->mSubDocuments);
     tmp->mSubDocuments = nsnull;
   }
 
-  tmp->mAnimationFrameListeners.Clear();
+  tmp->mFrameRequestCallbacks.Clear();
 
   tmp->mRadioGroups.Clear();
   
   // nsDocument has a pretty complex destructor, so we're going to
   // assume that *most* cycles you actually want to break somewhere
   // else, and not unlink an awful lot here.
 
   tmp->mIdentifierMap.Clear();
@@ -3209,51 +3209,45 @@ void
 nsDocument::MaybeRescheduleAnimationFrameNotifications()
 {
   if (!mPresShell || !IsEventHandlingEnabled()) {
     // bail out for now, until one of those conditions changes
     return;
   }
 
   nsRefreshDriver* rd = mPresShell->GetPresContext()->RefreshDriver();
-  if (mHavePendingPaint) {
-    rd->ScheduleBeforePaintEvent(this);
-  }
-  if (!mAnimationFrameListeners.IsEmpty()) {
-    rd->ScheduleAnimationFrameListeners(this);
-  }
-}
-
-void
-nsIDocument::TakeAnimationFrameListeners(AnimationListenerList& aListeners)
-{
-  aListeners.AppendElements(mAnimationFrameListeners);
-  mAnimationFrameListeners.Clear();
+  if (!mFrameRequestCallbacks.IsEmpty()) {
+    rd->ScheduleFrameRequestCallbacks(this);
+  }
+}
+
+void
+nsIDocument::TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks)
+{
+  aCallbacks.AppendElements(mFrameRequestCallbacks);
+  mFrameRequestCallbacks.Clear();
 }
 
 void
 nsDocument::DeleteShell()
 {
   mExternalResourceMap.HideViewers();
   if (IsEventHandlingEnabled()) {
     RevokeAnimationFrameNotifications();
   }
 
   mPresShell = nsnull;
 }
 
 void
 nsDocument::RevokeAnimationFrameNotifications()
 {
-  if (mHavePendingPaint) {
-    mPresShell->GetPresContext()->RefreshDriver()->RevokeBeforePaintEvent(this);
-  }
-  if (!mAnimationFrameListeners.IsEmpty()) {
+  if (!mFrameRequestCallbacks.IsEmpty()) {
     mPresShell->GetPresContext()->RefreshDriver()->
-      RevokeAnimationFrameListeners(this);
+      RevokeFrameRequestCallbacks(this);
   }
 }
 
 static void
 SubDocClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
 {
   SubDocMapEntry *e = static_cast<SubDocMapEntry *>(entry);
 
@@ -8069,40 +8063,24 @@ nsIDocument::CreateStaticClone(nsISuppor
       }
     }
   }
   mCreatingStaticClone = false;
   return clonedDoc.forget();
 }
 
 void
-nsIDocument::ScheduleBeforePaintEvent(nsIAnimationFrameListener* aListener)
-{
-  if (aListener) {
-    bool alreadyRegistered = !mAnimationFrameListeners.IsEmpty();
-    if (mAnimationFrameListeners.AppendElement(aListener) &&
-        !alreadyRegistered && mPresShell && IsEventHandlingEnabled()) {
-      mPresShell->GetPresContext()->RefreshDriver()->
-        ScheduleAnimationFrameListeners(this);
-    }
-
-    return;
-  }
-
-  if (!mHavePendingPaint) {
-    // We don't want to use GetShell() here, because we want to schedule the
-    // paint even if we're frozen.  Either we'll get unfrozen and then the
-    // event will fire, or we'll quietly go away at some point.
-    mHavePendingPaint =
-      !mPresShell ||
-      !IsEventHandlingEnabled() ||
-      mPresShell->GetPresContext()->RefreshDriver()->
-        ScheduleBeforePaintEvent(this);
-  }
-
+nsIDocument::ScheduleFrameRequestCallback(nsIFrameRequestCallback* aCallback)
+{
+  bool alreadyRegistered = !mFrameRequestCallbacks.IsEmpty();
+  if (mFrameRequestCallbacks.AppendElement(aCallback) &&
+      !alreadyRegistered && mPresShell && IsEventHandlingEnabled()) {
+    mPresShell->GetPresContext()->RefreshDriver()->
+      ScheduleFrameRequestCallbacks(this);
+  }
 }
 
 nsresult
 nsDocument::GetStateObject(nsIVariant** aState)
 {
   // Get the document's current state object. This is the object backing both
   // history.state and popStateEvent.state.
   //
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -46,16 +46,19 @@
 #include "nsJSUtils.h"
 #include "nsNetUtil.h"
 #include "nsScriptLoader.h"
 #include "nsIJSContextStack.h"
 #include "nsIXULRuntime.h"
 #include "nsIScriptError.h"
 #include "nsIConsoleService.h"
 #include "nsIProtocolHandler.h"
+#include "nsIScriptSecurityManager.h"
+#include "nsIJSRuntimeService.h"
+#include "xpcpublic.h"
 
 #ifdef ANDROID
 #include <android/log.h>
 #endif
 
 static bool
 IsChromeProcess()
 {
@@ -803,16 +806,68 @@ nsFrameScriptExecutor::LoadFrameScriptIn
         JSPRINCIPALS_DROP(mCx, jsprin);
       }
     } 
     JSContext* unused;
     nsContentUtils::ThreadJSContextStack()->Pop(&unused);
   }
 }
 
+bool
+nsFrameScriptExecutor::InitTabChildGlobalInternal(nsISupports* aScope)
+{
+  
+  nsCOMPtr<nsIJSRuntimeService> runtimeSvc = 
+    do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
+  NS_ENSURE_TRUE(runtimeSvc, false);
+
+  JSRuntime* rt = nsnull;
+  runtimeSvc->GetRuntime(&rt);
+  NS_ENSURE_TRUE(rt, false);
+
+  JSContext* cx = JS_NewContext(rt, 8192);
+  NS_ENSURE_TRUE(cx, false);
+
+  mCx = cx;
+
+  nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(mPrincipal));
+
+  JS_SetNativeStackQuota(cx, 128 * sizeof(size_t) * 1024);
+
+  JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_PRIVATE_IS_NSISUPPORTS);
+  JS_SetVersion(cx, JSVERSION_LATEST);
+  JS_SetErrorReporter(cx, ContentScriptErrorReporter);
+
+  xpc_LocalizeContext(cx);
+
+  JSAutoRequest ar(cx);
+  nsIXPConnect* xpc = nsContentUtils::XPConnect();
+  const PRUint32 flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES |
+                         nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT;
+
+  
+  JS_SetContextPrivate(cx, aScope);
+
+  nsresult rv =
+    xpc->InitClassesWithNewWrappedGlobal(cx, aScope,
+                                         NS_GET_IID(nsISupports),
+                                         mPrincipal, nsnull,
+                                         flags, getter_AddRefs(mGlobal));
+  NS_ENSURE_SUCCESS(rv, false);
+
+    
+  JSObject* global = nsnull;
+  rv = mGlobal->GetJSObject(&global);
+  NS_ENSURE_SUCCESS(rv, false);
+
+  JS_SetGlobalObject(cx, global);
+  DidCreateCx();
+  return true;
+}
+
 // static
 void
 nsFrameScriptExecutor::Traverse(nsFrameScriptExecutor *tmp,
                                 nsCycleCollectionTraversalCallback &cb)
 {
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mGlobal)
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCx");
   nsContentUtils::XPConnect()->NoteJSContext(tmp->mCx, cb);
--- a/content/base/src/nsFrameMessageManager.h
+++ b/content/base/src/nsFrameMessageManager.h
@@ -226,16 +226,17 @@ protected:
                             mDelayedCxDestroy(false)
   { MOZ_COUNT_CTOR(nsFrameScriptExecutor); }
   ~nsFrameScriptExecutor()
   { MOZ_COUNT_DTOR(nsFrameScriptExecutor); }
   void DidCreateCx();
   // Call this when you want to destroy mCx.
   void DestroyCx();
   void LoadFrameScriptInternal(const nsAString& aURL);
+  bool InitTabChildGlobalInternal(nsISupports* aScope);
   static void Traverse(nsFrameScriptExecutor *tmp,
                        nsCycleCollectionTraversalCallback &cb);
   nsCOMPtr<nsIXPConnectJSObjectHolder> mGlobal;
   JSContext* mCx;
   PRUint32 mCxStackRefCnt;
   bool mDelayedCxDestroy;
   nsCOMPtr<nsIPrincipal> mPrincipal;
   static nsDataHashtable<nsStringHashKey, nsFrameJSScriptExecutorHolder*>* sCachedScripts;
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -104,16 +104,17 @@
 #include "nsGkAtoms.h"
 #include "nsContentUtils.h"
 #include "nsIJSContextStack.h"
 
 #include "nsIServiceManager.h"
 #include "nsIDOMEventListener.h"
 #include "nsIWebNavigation.h"
 #include "nsIBaseWindow.h"
+#include "nsIWidget.h"
 
 #include "jsapi.h"
 
 #include "nsNodeInfoManager.h"
 #include "nsICategoryManager.h"
 #include "nsIDOMDocumentType.h"
 #include "nsIDOMUserDataHandler.h"
 #include "nsGenericHTMLElement.h"
@@ -1358,53 +1359,50 @@ nsIContent::GetFlattenedTreeParent() con
       doc->BindingManager()->GetNestedInsertionPoint(parent, this);
     if (insertionElement) {
       parent = insertionElement;
     }
   }
   return parent;
 }
 
-PRUint32
+nsIContent::IMEState
 nsIContent::GetDesiredIMEState()
 {
   if (!IsEditableInternal()) {
-    return IME_STATUS_DISABLE;
+    return IMEState(IMEState::DISABLED);
   }
   // NOTE: The content for independent editors (e.g., input[type=text],
   // textarea) must override this method, so, we don't need to worry about
   // that here.
   nsIContent *editableAncestor = GetEditingHost();
 
   // This is in another editable content, use the result of it.
   if (editableAncestor && editableAncestor != this) {
     return editableAncestor->GetDesiredIMEState();
   }
   nsIDocument* doc = GetCurrentDoc();
   if (!doc) {
-    return IME_STATUS_DISABLE;
+    return IMEState(IMEState::DISABLED);
   }
   nsIPresShell* ps = doc->GetShell();
   if (!ps) {
-    return IME_STATUS_DISABLE;
+    return IMEState(IMEState::DISABLED);
   }
   nsPresContext* pc = ps->GetPresContext();
   if (!pc) {
-    return IME_STATUS_DISABLE;
+    return IMEState(IMEState::DISABLED);
   }
   nsIEditor* editor = GetHTMLEditor(pc);
   nsCOMPtr<nsIEditorIMESupport> imeEditor = do_QueryInterface(editor);
   if (!imeEditor) {
-    return IME_STATUS_DISABLE;
-  }
-  // Use "enable" for the default value because IME is disabled unexpectedly,
-  // it makes serious a11y problem.
-  PRUint32 state = IME_STATUS_ENABLE;
-  nsresult rv = imeEditor->GetPreferredIMEState(&state);
-  NS_ENSURE_SUCCESS(rv, IME_STATUS_ENABLE);
+    return IMEState(IMEState::DISABLED);
+  }
+  IMEState state;
+  imeEditor->GetPreferredIMEState(&state);
   return state;
 }
 
 bool
 nsIContent::HasIndependentSelection()
 {
   nsIFrame* frame = GetPrimaryFrame();
   return (frame && frame->GetStateBits() & NS_FRAME_INDEPENDENT_SELECTION);
--- a/content/base/src/nsInProcessTabChildGlobal.cpp
+++ b/content/base/src/nsInProcessTabChildGlobal.cpp
@@ -288,63 +288,20 @@ nsInProcessTabChildGlobal::PreHandleEven
 #endif
 
   return NS_OK;
 }
 
 nsresult
 nsInProcessTabChildGlobal::InitTabChildGlobal()
 {
-  nsCOMPtr<nsIJSRuntimeService> runtimeSvc = 
-    do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
-  NS_ENSURE_STATE(runtimeSvc);
-
-  JSRuntime* rt = nsnull;
-  runtimeSvc->GetRuntime(&rt);
-  NS_ENSURE_STATE(rt);
-
-  JSContext* cx = JS_NewContext(rt, 8192);
-  NS_ENSURE_STATE(cx);
-
-  mCx = cx;
-
-  nsContentUtils::XPConnect()->SetSecurityManagerForJSContext(cx, nsContentUtils::GetSecurityManager(), 0);
-  nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(mPrincipal));
-
-  JS_SetNativeStackQuota(cx, 128 * sizeof(size_t) * 1024);
-
-  JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_JIT | JSOPTION_PRIVATE_IS_NSISUPPORTS);
-  JS_SetVersion(cx, JSVERSION_LATEST);
-  JS_SetErrorReporter(cx, ContentScriptErrorReporter);
-
-  xpc_LocalizeContext(cx);
-
-  JSAutoRequest ar(cx);
-  nsIXPConnect* xpc = nsContentUtils::XPConnect();
-  const PRUint32 flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES |
-                         /*nsIXPConnect::OMIT_COMPONENTS_OBJECT ?  |*/
-                         nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT;
 
   nsISupports* scopeSupports =
     NS_ISUPPORTS_CAST(nsIDOMEventTarget*, this);
-  JS_SetContextPrivate(cx, scopeSupports);
-
-  nsresult rv =
-    xpc->InitClassesWithNewWrappedGlobal(cx, scopeSupports,
-                                         NS_GET_IID(nsISupports),
-                                         GetPrincipal(), nsnull,
-                                         flags, getter_AddRefs(mGlobal));
-  NS_ENSURE_SUCCESS(rv, false);
-
-  JSObject* global = nsnull;
-  rv = mGlobal->GetJSObject(&global);
-  NS_ENSURE_SUCCESS(rv, false);
-
-  JS_SetGlobalObject(cx, global);
-  DidCreateCx();
+  NS_ENSURE_STATE(InitTabChildGlobalInternal(scopeSupports));
   return NS_OK;
 }
 
 class nsAsyncScriptLoad : public nsRunnable
 {
 public:
   nsAsyncScriptLoad(nsInProcessTabChildGlobal* aTabChild, const nsAString& aURL)
   : mTabChild(aTabChild), mURL(aURL) {}
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -2486,16 +2486,26 @@ nsXMLHttpRequest::Send(nsIVariant *aBody
       if (!charset.IsEmpty()) {
         nsCAutoString specifiedCharset;
         bool haveCharset;
         PRInt32 charsetStart, charsetEnd;
         rv = NS_ExtractCharsetFromContentType(contentType, specifiedCharset,
                                               &haveCharset, &charsetStart,
                                               &charsetEnd);
         if (NS_SUCCEEDED(rv)) {
+          // special case: the extracted charset is quoted with single quotes
+          // -- for the purpose of preserving what was set we want to handle
+          // them as delimiters (although they aren't really)
+          if (specifiedCharset.Length() >= 2 &&
+              specifiedCharset.First() == '\'' &&
+              specifiedCharset.Last() == '\'') {
+            specifiedCharset = Substring(specifiedCharset, 1,
+                                         specifiedCharset.Length() - 2);
+          }
+
           // If the content-type the page set already has a charset parameter,
           // and it's the same charset, up to case, as |charset|, just send the
           // page-set content-type header.  Apparently at least
           // google-web-toolkit is broken and relies on the exact case of its
           // charset parameter, which makes things break if we use |charset|
           // (which is always a fully resolved charset per our charset alias
           // table, hence might be differently cased).
           if (!specifiedCharset.Equals(charset,
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -1082,19 +1082,20 @@ public:
         return mImageInfos.ElementAt(level * mFacesCount + face);
     }
 
     const ImageInfo& ImageInfoAt(size_t level, size_t face) const {
         return const_cast<WebGLTexture*>(this)->ImageInfoAt(level, face);
     }
 
     bool HasImageInfoAt(size_t level, size_t face) const {
-        return level <= mMaxLevelWithCustomImages &&
-               face < mFacesCount &&
-               ImageInfoAt(level, 0).mIsDefined;
+        CheckedUint32 checked_index = CheckedUint32(level) * mFacesCount + face;
+        return checked_index.valid() &&
+               checked_index.value() < mImageInfos.Length() &&
+               ImageInfoAt(level, face).mIsDefined;
     }
 
     static size_t FaceForTarget(WebGLenum target) {
         return target == LOCAL_GL_TEXTURE_2D ? 0 : target - LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
     }
 
     PRInt64 MemoryUsage() const {
         PRInt64 result = 0;
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -400,17 +400,17 @@ nsEventListenerManager::SetJSEventListen
 {
   nsresult rv = NS_OK;
   PRUint32 eventType = nsContentUtils::GetEventId(aName);
   nsListenerStruct* ls = FindJSEventListener(eventType, aName);
 
   if (!ls) {
     // If we didn't find a script listener or no listeners existed
     // create and add a new one.
-    nsCOMPtr<nsIDOMEventListener> scriptListener;
+    nsCOMPtr<nsIJSEventListener> scriptListener;
     rv = NS_NewJSEventListener(aContext, aScopeObject, mTarget, aName,
                                aHandler, getter_AddRefs(scriptListener));
     if (NS_SUCCEEDED(rv)) {
       AddEventListener(scriptListener, eventType, aName,
                        NS_EVENT_FLAG_BUBBLE | NS_PRIV_EVENT_FLAG_SCRIPT);
 
       ls = FindJSEventListener(eventType, aName);
     }
@@ -696,20 +696,18 @@ nsEventListenerManager::CompileEventHand
       NS_ENSURE_SUCCESS(result, result);
     }
   }
 
   if (handler) {
     // Bind it
     nsScriptObjectHolder boundHandler(context);
     context->BindCompiledEventHandler(mTarget, listener->GetEventScope(),
-                                      handler, boundHandler);
-    listener->SetHandler(
-      static_cast<JSObject*>(
-        static_cast<void*>(boundHandler)));
+                                      handler.getObject(), boundHandler);
+    listener->SetHandler(boundHandler.getObject());
   }
 
   return result;
 }
 
 nsresult
 nsEventListenerManager::HandleEventSubType(nsListenerStruct* aListenerStruct,
                                            nsIDOMEventListener* aListener,
--- a/content/events/src/nsEventListenerManager.h
+++ b/content/events/src/nsEventListenerManager.h
@@ -58,28 +58,36 @@ class nsIWidget;
 struct nsPoint;
 struct EventTypeData;
 class nsEventTargetChainItem;
 class nsPIDOMWindow;
 class nsCxPusher;
 class nsIEventListenerInfo;
 class nsIDocument;
 
-typedef struct {
+struct nsListenerStruct
+{
   nsRefPtr<nsIDOMEventListener> mListener;
   PRUint32                      mEventType;
   nsCOMPtr<nsIAtom>             mTypeAtom;
   PRUint16                      mFlags;
   bool                          mHandlerIsString;
 
   nsIJSEventListener* GetJSListener() const {
     return (mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) ?
       static_cast<nsIJSEventListener *>(mListener.get()) : nsnull;
   }
-} nsListenerStruct;
+
+  ~nsListenerStruct()
+  {
+    if ((mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) && mListener) {
+      static_cast<nsIJSEventListener*>(mListener.get())->Disconnect();
+    }
+  }
+};
 
 /*
  * Event listener manager
  */
 
 class nsEventListenerManager
 {
 
--- a/content/events/src/nsIMEStateManager.cpp
+++ b/content/events/src/nsIMEStateManager.cpp
@@ -35,27 +35,28 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIMEStateManager.h"
 #include "nsCOMPtr.h"
-#include "nsIWidget.h"
 #include "nsIViewManager.h"
 #include "nsIPresShell.h"
 #include "nsISupports.h"
 #include "nsPIDOMWindow.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIEditorDocShell.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsPresContext.h"
 #include "nsIDOMWindow.h"
+#include "nsIDOMMouseEvent.h"
+#include "nsIDOMNSEvent.h"
 #include "nsContentUtils.h"
 #include "nsINode.h"
 #include "nsIFrame.h"
 #include "nsRange.h"
 #include "nsIDOMRange.h"
 #include "nsISelection.h"
 #include "nsISelectionPrivate.h"
 #include "nsISelectionListener.h"
@@ -63,16 +64,18 @@
 #include "nsIMutationObserver.h"
 #include "nsContentEventHandler.h"
 #include "nsIObserverService.h"
 #include "mozilla/Services.h"
 #include "nsIFormControl.h"
 #include "nsIForm.h"
 #include "nsHTMLFormElement.h"
 
+using namespace mozilla::widget;
+
 /******************************************************************/
 /* nsIMEStateManager                                              */
 /******************************************************************/
 
 nsIContent*    nsIMEStateManager::sContent      = nsnull;
 nsPresContext* nsIMEStateManager::sPresContext  = nsnull;
 bool           nsIMEStateManager::sInstalledMenuKeyboardListener = false;
 bool           nsIMEStateManager::sInSecureInputMode = false;
@@ -82,18 +85,20 @@ nsTextStateManager* nsIMEStateManager::s
 nsresult
 nsIMEStateManager::OnDestroyPresContext(nsPresContext* aPresContext)
 {
   NS_ENSURE_ARG_POINTER(aPresContext);
   if (aPresContext != sPresContext)
     return NS_OK;
   nsCOMPtr<nsIWidget> widget = GetWidget(sPresContext);
   if (widget) {
-    PRUint32 newState = GetNewIMEState(sPresContext, nsnull);
-    SetIMEState(newState, nsnull, widget, IMEContext::FOCUS_REMOVED);
+    IMEState newState = GetNewIMEState(sPresContext, nsnull);
+    InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
+                              InputContextAction::LOST_FOCUS);
+    SetIMEState(newState, nsnull, widget, action);
   }
   sContent = nsnull;
   sPresContext = nsnull;
   OnTextStateBlur(nsnull, nsnull);
   return NS_OK;
 }
 
 nsresult
@@ -107,30 +112,41 @@ nsIMEStateManager::OnRemoveContent(nsPre
     return NS_OK;
 
   // Current IME transaction should commit
   nsCOMPtr<nsIWidget> widget = GetWidget(sPresContext);
   if (widget) {
     nsresult rv = widget->CancelIMEComposition();
     if (NS_FAILED(rv))
       widget->ResetInputState();
-    PRUint32 newState = GetNewIMEState(sPresContext, nsnull);
-    SetIMEState(newState, nsnull, widget, IMEContext::FOCUS_REMOVED);
+    IMEState newState = GetNewIMEState(sPresContext, nsnull);
+    InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
+                              InputContextAction::LOST_FOCUS);
+    SetIMEState(newState, nsnull, widget, action);
   }
 
   sContent = nsnull;
   sPresContext = nsnull;
 
   return NS_OK;
 }
 
 nsresult
 nsIMEStateManager::OnChangeFocus(nsPresContext* aPresContext,
                                  nsIContent* aContent,
-                                 PRUint32 aReason)
+                                 InputContextAction::Cause aCause)
+{
+  InputContextAction action(aCause);
+  return OnChangeFocusInternal(aPresContext, aContent, action);
+}
+
+nsresult
+nsIMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
+                                         nsIContent* aContent,
+                                         InputContextAction aAction)
 {
   NS_ENSURE_ARG_POINTER(aPresContext);
 
   nsCOMPtr<nsIWidget> widget = GetWidget(aPresContext);
   if (!widget) {
     return NS_OK;
   }
 
@@ -152,121 +168,155 @@ nsIMEStateManager::OnChangeFocus(nsPresC
   } else {
     if (contentIsPassword) {
       if (NS_SUCCEEDED(widget->BeginSecureKeyboardInput())) {
         sInSecureInputMode = true;
       }
     }
   }
 
-  PRUint32 newState = GetNewIMEState(aPresContext, aContent);
+  IMEState newState = GetNewIMEState(aPresContext, aContent);
   if (aPresContext == sPresContext && aContent == sContent) {
     // actual focus isn't changing, but if IME enabled state is changing,
     // we should do it.
-    PRUint32 newEnabledState = newState & nsIContent::IME_STATUS_MASK_ENABLED;
-    if (newEnabledState == 0) {
-      // the enabled state isn't changing, we should do nothing.
-      return NS_OK;
-    }
-    IMEContext context;
-    if (!widget || NS_FAILED(widget->GetInputMode(context))) {
-      // this platform doesn't support IME controlling
-      return NS_OK;
-    }
-    if (context.mStatus ==
-        nsContentUtils::GetWidgetStatusFromIMEStatus(newEnabledState)) {
+    InputContext context = widget->GetInputContext();
+    if (context.mIMEState.mEnabled == newState.mEnabled) {
       // the enabled state isn't changing.
       return NS_OK;
     }
+    aAction.mFocusChange = InputContextAction::FOCUS_NOT_CHANGED;
+  } else if (aAction.mFocusChange == InputContextAction::FOCUS_NOT_CHANGED) {
+    // If aContent isn't null or aContent is null but editable, somebody gets
+    // focus.
+    bool gotFocus = aContent || (newState.mEnabled == IMEState::ENABLED);
+    aAction.mFocusChange =
+      gotFocus ? InputContextAction::GOT_FOCUS : InputContextAction::LOST_FOCUS;
   }
 
   // Current IME transaction should commit
   if (sPresContext) {
     nsCOMPtr<nsIWidget> oldWidget;
     if (sPresContext == aPresContext)
       oldWidget = widget;
     else
       oldWidget = GetWidget(sPresContext);
     if (oldWidget)
       oldWidget->ResetInputState();
   }
 
-  if (newState != nsIContent::IME_STATUS_NONE) {
-    // Update IME state for new focus widget
-    SetIMEState(newState, aContent, widget, aReason);
-  }
+  // Update IME state for new focus widget
+  SetIMEState(newState, aContent, widget, aAction);
 
   sPresContext = aPresContext;
   sContent = aContent;
 
   return NS_OK;
 }
 
 void
 nsIMEStateManager::OnInstalledMenuKeyboardListener(bool aInstalling)
 {
   sInstalledMenuKeyboardListener = aInstalling;
 
-  PRUint32 reason = aInstalling ? IMEContext::FOCUS_MOVED_TO_MENU
-                                : IMEContext::FOCUS_MOVED_FROM_MENU;
-  OnChangeFocus(sPresContext, sContent, reason);
+  InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
+    aInstalling ? InputContextAction::MENU_GOT_PSEUDO_FOCUS :
+                  InputContextAction::MENU_LOST_PSEUDO_FOCUS);
+  OnChangeFocusInternal(sPresContext, sContent, action);
 }
 
 void
-nsIMEStateManager::UpdateIMEState(PRUint32 aNewIMEState, nsIContent* aContent)
+nsIMEStateManager::OnClickInEditor(nsPresContext* aPresContext,
+                                   nsIContent* aContent,
+                                   nsIDOMMouseEvent* aMouseEvent)
+{
+  if (sPresContext != aPresContext || sContent != aContent) {
+    return;
+  }
+
+  nsCOMPtr<nsIWidget> widget = GetWidget(aPresContext);
+  NS_ENSURE_TRUE(widget, );
+
+  bool isTrusted;
+  nsCOMPtr<nsIDOMNSEvent> NSEvent = do_QueryInterface(aMouseEvent);
+  nsresult rv = NSEvent->GetIsTrusted(&isTrusted);
+  NS_ENSURE_SUCCESS(rv, );
+  if (!isTrusted) {
+    return; // ignore untrusted event.
+  }
+
+  PRUint16 button;
+  rv = aMouseEvent->GetButton(&button);
+  NS_ENSURE_SUCCESS(rv, );
+  if (button != 0) {
+    return; // not a left click event.
+  }
+
+  PRInt32 clickCount;
+  rv = aMouseEvent->GetDetail(&clickCount);
+  NS_ENSURE_SUCCESS(rv, );
+  if (clickCount != 1) {
+    return; // should notify only first click event.
+  }
+
+  InputContextAction action(InputContextAction::CAUSE_MOUSE,
+                            InputContextAction::FOCUS_NOT_CHANGED);
+  IMEState newState = GetNewIMEState(aPresContext, aContent);
+  SetIMEState(newState, aContent, widget, action);
+}
+
+void
+nsIMEStateManager::UpdateIMEState(const IMEState &aNewIMEState,
+                                  nsIContent* aContent)
 {
   if (!sPresContext) {
     NS_WARNING("ISM doesn't know which editor has focus");
     return;
   }
-  NS_PRECONDITION(aNewIMEState != 0, "aNewIMEState doesn't specify new state.");
   nsCOMPtr<nsIWidget> widget = GetWidget(sPresContext);
   if (!widget) {
     NS_WARNING("focused widget is not found");
     return;
   }
 
   // Don't update IME state when enabled state isn't actually changed.
-  IMEContext context;
-  nsresult rv = widget->GetInputMode(context);
-  if (NS_FAILED(rv)) {
-    return; // This platform doesn't support controling the IME state.
-  }
-  PRUint32 newEnabledState = aNewIMEState & nsIContent::IME_STATUS_MASK_ENABLED;
-  if (context.mStatus ==
-        nsContentUtils::GetWidgetStatusFromIMEStatus(newEnabledState)) {
+  InputContext context = widget->GetInputContext();
+  if (context.mIMEState.mEnabled == aNewIMEState.mEnabled) {
     return;
   }
 
   // commit current composition
   widget->ResetInputState();
 
-  SetIMEState(aNewIMEState, aContent, widget, IMEContext::EDITOR_STATE_MODIFIED);
+  InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
+                            InputContextAction::FOCUS_NOT_CHANGED);
+  SetIMEState(aNewIMEState, aContent, widget, action);
 }
 
-PRUint32
+IMEState
 nsIMEStateManager::GetNewIMEState(nsPresContext* aPresContext,
                                   nsIContent*    aContent)
 {
   // On Printing or Print Preview, we don't need IME.
   if (aPresContext->Type() == nsPresContext::eContext_PrintPreview ||
       aPresContext->Type() == nsPresContext::eContext_Print) {
-    return nsIContent::IME_STATUS_DISABLE;
+    return IMEState(IMEState::DISABLED);
   }
 
-  if (sInstalledMenuKeyboardListener)
-    return nsIContent::IME_STATUS_DISABLE;
+  if (sInstalledMenuKeyboardListener) {
+    return IMEState(IMEState::DISABLED);
+  }
 
   if (!aContent) {
     // Even if there are no focused content, the focused document might be
     // editable, such case is design mode.
     nsIDocument* doc = aPresContext->Document();
-    if (doc && doc->HasFlag(NODE_IS_EDITABLE))
-      return nsIContent::IME_STATUS_ENABLE;
-    return nsIContent::IME_STATUS_DISABLE;
+    if (doc && doc->HasFlag(NODE_IS_EDITABLE)) {
+      return IMEState(IMEState::ENABLED);
+    }
+    return IMEState(IMEState::DISABLED);
   }
 
   return aContent->GetDesiredIMEState();
 }
 
 // Helper class, used for IME enabled state change notification
 class IMEEnabledStateChangedEvent : public nsRunnable {
 public:
@@ -285,75 +335,72 @@ public:
     return NS_OK;
   }
 
 private:
   PRUint32 mState;
 };
 
 void
-nsIMEStateManager::SetIMEState(PRUint32 aState,
+nsIMEStateManager::SetIMEState(const IMEState &aState,
                                nsIContent* aContent,
                                nsIWidget* aWidget,
-                               PRUint32 aReason)
+                               InputContextAction aAction)
 {
-  if (aState & nsIContent::IME_STATUS_MASK_ENABLED) {
-    if (!aWidget)
-      return;
+  NS_ENSURE_TRUE(aWidget, );
+
+  InputContext oldContext = aWidget->GetInputContext();
 
-    PRUint32 state = nsContentUtils::GetWidgetStatusFromIMEStatus(aState);
-    IMEContext context;
-    context.mStatus = state;
-    
-    if (aContent && aContent->GetNameSpaceID() == kNameSpaceID_XHTML &&
-        (aContent->Tag() == nsGkAtoms::input ||
-         aContent->Tag() == nsGkAtoms::textarea)) {
-      aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type,
-                        context.mHTMLInputType);
-      aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::moz_action_hint,
-                        context.mActionHint);
+  InputContext context;
+  context.mIMEState = aState;
+
+  if (aContent && aContent->GetNameSpaceID() == kNameSpaceID_XHTML &&
+      (aContent->Tag() == nsGkAtoms::input ||
+       aContent->Tag() == nsGkAtoms::textarea)) {
+    aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type,
+                      context.mHTMLInputType);
+    aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::moz_action_hint,
+                      context.mActionHint);
 
-      // if we don't have an action hint and  return won't submit the form use "next"
-      if (context.mActionHint.IsEmpty() && aContent->Tag() == nsGkAtoms::input) {
-        bool willSubmit = false;
-        nsCOMPtr<nsIFormControl> control(do_QueryInterface(aContent));
-        mozilla::dom::Element* formElement = control->GetFormElement();
-        nsCOMPtr<nsIForm> form;
-        if (control) {
-          // is this a form and does it have a default submit element?
-          if ((form = do_QueryInterface(formElement)) && form->GetDefaultSubmitElement()) {
-            willSubmit = true;
-          // is this an html form and does it only have a single text input element?
-          } else if (formElement && formElement->Tag() == nsGkAtoms::form && formElement->IsHTML() &&
-                     static_cast<nsHTMLFormElement*>(formElement)->HasSingleTextControl()) {
-            willSubmit = true;
-          }
+    // if we don't have an action hint and  return won't submit the form use "next"
+    if (context.mActionHint.IsEmpty() && aContent->Tag() == nsGkAtoms::input) {
+      bool willSubmit = false;
+      nsCOMPtr<nsIFormControl> control(do_QueryInterface(aContent));
+      mozilla::dom::Element* formElement = control->GetFormElement();
+      nsCOMPtr<nsIForm> form;
+      if (control) {
+        // is this a form and does it have a default submit element?
+        if ((form = do_QueryInterface(formElement)) && form->GetDefaultSubmitElement()) {
+          willSubmit = true;
+        // is this an html form and does it only have a single text input element?
+        } else if (formElement && formElement->Tag() == nsGkAtoms::form && formElement->IsHTML() &&
+                   static_cast<nsHTMLFormElement*>(formElement)->HasSingleTextControl()) {
+          willSubmit = true;
         }
-        context.mActionHint.Assign(willSubmit ? control->GetType() == NS_FORM_INPUT_SEARCH
-                                                  ? NS_LITERAL_STRING("search")
-                                                  : NS_LITERAL_STRING("go")
-                                              : formElement
-                                                  ? NS_LITERAL_STRING("next")
-                                                  : EmptyString());
       }
+      context.mActionHint.Assign(willSubmit ? control->GetType() == NS_FORM_INPUT_SEARCH
+                                                ? NS_LITERAL_STRING("search")
+                                                : NS_LITERAL_STRING("go")
+                                            : formElement
+                                                ? NS_LITERAL_STRING("next")
+                                                : EmptyString());
     }
+  }
 
-    if (XRE_GetProcessType() == GeckoProcessType_Content) {
-      context.mReason = aReason | IMEContext::FOCUS_FROM_CONTENT_PROCESS;
-    } else {
-      context.mReason = aReason;
-    }
+  // XXX I think that we should use nsContentUtils::IsCallerChrome() instead
+  //     of the process type.
+  if (aAction.mCause == InputContextAction::CAUSE_UNKNOWN &&
+      XRE_GetProcessType() != GeckoProcessType_Content) {
+    aAction.mCause = InputContextAction::CAUSE_UNKNOWN_CHROME;
+  }
 
-    aWidget->SetInputMode(context);
-
-    nsContentUtils::AddScriptRunner(new IMEEnabledStateChangedEvent(state));
-  }
-  if (aState & nsIContent::IME_STATUS_MASK_OPENED) {
-    bool open = !!(aState & nsIContent::IME_STATUS_OPEN);
-    aWidget->SetIMEOpenState(open);
+  aWidget->SetInputContext(context, aAction);
+  if (oldContext.mIMEState.mEnabled != context.mIMEState.mEnabled) {
+    nsContentUtils::AddScriptRunner(
+      new IMEEnabledStateChangedEvent(context.mIMEState.mEnabled));
   }
 }
 
 nsIWidget*
 nsIMEStateManager::GetWidget(nsPresContext* aPresContext)
 {
   nsIPresShell* shell = aPresContext->GetPresShell();
   NS_ENSURE_TRUE(shell, nsnull);
--- a/content/events/src/nsIMEStateManager.h
+++ b/content/events/src/nsIMEStateManager.h
@@ -35,37 +35,48 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsIMEStateManager_h__
 #define nsIMEStateManager_h__
 
 #include "nscore.h"
+#include "nsIWidget.h"
 
 class nsIContent;
+class nsIDOMMouseEvent;
 class nsPIDOMWindow;
 class nsPresContext;
-class nsIWidget;
 class nsTextStateManager;
 class nsISelection;
 
 /*
  * IME state manager
  */
 
 class nsIMEStateManager
 {
+protected:
+  typedef mozilla::widget::IMEState IMEState;
+  typedef mozilla::widget::InputContext InputContext;
+  typedef mozilla::widget::InputContextAction InputContextAction;
+
 public:
   static nsresult OnDestroyPresContext(nsPresContext* aPresContext);
   static nsresult OnRemoveContent(nsPresContext* aPresContext,
                                   nsIContent* aContent);
+  /**
+   * OnChangeFocus() should be called when focused content is changed or
+   * IME enabled state is changed.  If focus isn't actually changed and IME
+   * enabled state isn't changed, this will do nothing.
+   */
   static nsresult OnChangeFocus(nsPresContext* aPresContext,
                                 nsIContent* aContent,
-                                PRUint32 aReason);
+                                InputContextAction::Cause aCause);
   static void OnInstalledMenuKeyboardListener(bool aInstalling);
 
   // These two methods manage focus and selection/text observers.
   // They are separate from OnChangeFocus above because this offers finer
   // control compared to having the two methods incorporated into OnChangeFocus
 
   // OnTextStateBlur should be called *before* NS_BLUR_CONTENT fires
   // aPresContext is the nsPresContext receiving focus (not lost focus)
@@ -80,24 +91,37 @@ public:
                                    nsIContent* aContent);
   // Get the focused editor's selection and root
   static nsresult GetFocusSelectionAndRoot(nsISelection** aSel,
                                            nsIContent** aRoot);
   // This method updates the current IME state.  However, if the enabled state
   // isn't changed by the new state, this method does nothing.
   // Note that this method changes the IME state of the active element in the
   // widget.  So, the caller must have focus.
-  // aNewIMEState must have an enabled state of nsIContent::IME_STATUS_*.
-  // And optionally, it can have an open state of nsIContent::IME_STATUS_*.
-  static void UpdateIMEState(PRUint32 aNewIMEState, nsIContent* aContent);
+  static void UpdateIMEState(const IMEState &aNewIMEState,
+                             nsIContent* aContent);
+
+  // This method is called when user clicked in an editor.
+  // aContent must be:
+  //   If the editor is for <input> or <textarea>, the element.
+  //   If the editor is for contenteditable, the active editinghost.
+  //   If the editor is for designMode, NULL.
+  static void OnClickInEditor(nsPresContext* aPresContext,
+                              nsIContent* aContent,
+                              nsIDOMMouseEvent* aMouseEvent);
 
 protected:
-  static void SetIMEState(PRUint32 aState, nsIContent* aContent,
-                          nsIWidget* aWidget, PRUint32 aReason);
-  static PRUint32 GetNewIMEState(nsPresContext* aPresContext,
+  static nsresult OnChangeFocusInternal(nsPresContext* aPresContext,
+                                        nsIContent* aContent,
+                                        InputContextAction aAction);
+  static void SetIMEState(const IMEState &aState,
+                          nsIContent* aContent,
+                          nsIWidget* aWidget,
+                          InputContextAction aAction);
+  static IMEState GetNewIMEState(nsPresContext* aPresContext,
                                  nsIContent* aContent);
 
   static nsIWidget* GetWidget(nsPresContext* aPresContext);
 
   static nsIContent*    sContent;
   static nsPresContext* sPresContext;
   static bool           sInstalledMenuKeyboardListener;
   static bool           sInSecureInputMode;
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -66,16 +66,17 @@
 #include "nsIStyleRule.h"
 #include "nsIURL.h"
 #include "nsNetUtil.h"
 #include "nsEscape.h"
 #include "nsIFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsIView.h"
 #include "nsIViewManager.h"
+#include "nsIWidget.h"
 #include "nsRange.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsINameSpaceManager.h"
 #include "nsDOMError.h"
 #include "nsScriptLoader.h"
@@ -2647,27 +2648,27 @@ nsGenericHTMLFormElement::GetFormElement
 nsresult
 nsGenericHTMLFormElement::GetForm(nsIDOMHTMLFormElement** aForm)
 {
   NS_ENSURE_ARG_POINTER(aForm);
   NS_IF_ADDREF(*aForm = mForm);
   return NS_OK;
 }
 
-PRUint32
+nsIContent::IMEState
 nsGenericHTMLFormElement::GetDesiredIMEState()
 {
   nsCOMPtr<nsIEditor> editor = nsnull;
   nsresult rv = GetEditorInternal(getter_AddRefs(editor));
   if (NS_FAILED(rv) || !editor)
     return nsGenericHTMLElement::GetDesiredIMEState();
   nsCOMPtr<nsIEditorIMESupport> imeEditor = do_QueryInterface(editor);
   if (!imeEditor)
     return nsGenericHTMLElement::GetDesiredIMEState();
-  PRUint32 state;
+  IMEState state;
   rv = imeEditor->GetPreferredIMEState(&state);
   if (NS_FAILED(rv))
     return nsGenericHTMLElement::GetDesiredIMEState();
   return state;
 }
 
 bool
 nsGenericHTMLFrameElement::IsHTMLFocusable(bool aWithMouse,
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -879,17 +879,17 @@ public:
   }
 
   // nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers);
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true);
-  virtual PRUint32 GetDesiredIMEState();
+  virtual IMEState GetDesiredIMEState();
   virtual nsEventStates IntrinsicState() const;
 
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
 
   virtual bool IsDisabled() const;
 
   /**
    * This callback is called by a fieldest on all its elements whenever its
--- a/content/html/content/src/nsHTMLCanvasElement.cpp
+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
@@ -501,45 +501,47 @@ nsHTMLCanvasElement::GetContext(const ns
         contextProps = do_CreateInstance("@mozilla.org/hash-property-bag;1");
 
         JSObject *opts = JSVAL_TO_OBJECT(aContextOptions);
         JSIdArray *props = JS_Enumerate(cx, opts);
         for (int i = 0; props && i < JS_IdArrayLength(cx, props); ++i) {
           jsid propid = JS_IdArrayGet(cx, props, i);
           jsval propname, propval;
           if (!JS_IdToValue(cx, propid, &propname) ||
-              !JS_GetPropertyById(cx, opts, propid, &propval))
-          {
+              !JS_GetPropertyById(cx, opts, propid, &propval)) {
             continue;
           }
 
           JSString *propnameString = JS_ValueToString(cx, propname);
           nsDependentJSString pstr;
           if (!propnameString || !pstr.init(cx, propnameString)) {
+            JS_DestroyIdArray(cx, props);
             mCurrentContext = nsnull;
             return NS_ERROR_FAILURE;
           }
 
           if (JSVAL_IS_BOOLEAN(propval)) {
             contextProps->SetPropertyAsBool(pstr, propval == JSVAL_TRUE ? true : false);
           } else if (JSVAL_IS_INT(propval)) {
             contextProps->SetPropertyAsInt32(pstr, JSVAL_TO_INT(propval));
           } else if (JSVAL_IS_DOUBLE(propval)) {
             contextProps->SetPropertyAsDouble(pstr, JSVAL_TO_DOUBLE(propval));
           } else if (JSVAL_IS_STRING(propval)) {
             JSString *propvalString = JS_ValueToString(cx, propval);
             nsDependentJSString vstr;
             if (!propvalString || !vstr.init(cx, propvalString)) {
+              JS_DestroyIdArray(cx, props);
               mCurrentContext = nsnull;
               return NS_ERROR_FAILURE;
             }
 
             contextProps->SetPropertyAsAString(pstr, vstr);
           }
         }
+        JS_DestroyIdArray(cx, props);
       }
     }
 
     rv = UpdateContext(contextProps);
     if (NS_FAILED(rv)) {
       if (!forceThebes) {
         // Try again with a Thebes context
         forceThebes = true;
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -2059,16 +2059,20 @@ void nsHTMLMediaElement::ProcessMediaFra
 
 void nsHTMLMediaElement::MetadataLoaded(PRUint32 aChannels, PRUint32 aRate)
 {
   mChannels = aChannels;
   mRate = aRate;
   ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
   DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
   DispatchAsyncEvent(NS_LITERAL_STRING("loadedmetadata"));
+  if (!mBegun) {
+    // Something ended our downloaded. We're probably done with downloading already.
+    ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA);
+  }
   if (mDecoder && mDecoder->IsSeekable()) {
     ProcessMediaFragmentURI();
     mDecoder->SetEndTime(mFragmentEnd);
   }
 }
 
 void nsHTMLMediaElement::FirstFrameLoaded(bool aResourceFullyLoaded)
 {
--- a/content/html/content/src/nsHTMLObjectElement.cpp
+++ b/content/html/content/src/nsHTMLObjectElement.cpp
@@ -47,16 +47,17 @@
 #include "nsIDOMDocument.h"
 #include "nsIDOMSVGDocument.h"
 #include "nsIDOMGetSVGDocument.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsFormSubmission.h"
 #include "nsIObjectFrame.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsIConstraintValidation.h"
+#include "nsIWidget.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 class nsHTMLObjectElement : public nsGenericHTMLFormElement
                           , public nsObjectLoadingContent
                           , public nsIDOMHTMLObjectElement
                           , public nsIConstraintValidation
@@ -111,17 +112,17 @@ public:
                               bool aNullParent = true);
   virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom *aName,
                            nsIAtom *aPrefix, const nsAString &aValue,
                            bool aNotify);
   virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
                              bool aNotify);
 
   virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, PRInt32 *aTabIndex);
-  virtual PRUint32 GetDesiredIMEState();
+  virtual IMEState GetDesiredIMEState();
 
   // Overriden nsIFormControl methods
   NS_IMETHOD_(PRUint32) GetType() const
   {
     return NS_FORM_OBJECT;
   }
 
   NS_IMETHOD Reset();
@@ -371,21 +372,21 @@ nsHTMLObjectElement::IsHTMLFocusable(boo
 
   if (aTabIndex && *aIsFocusable) {
     *aTabIndex = attrVal->GetIntegerValue();
   }
 
   return false;
 }
 
-PRUint32
+nsIContent::IMEState
 nsHTMLObjectElement::GetDesiredIMEState()
 {
   if (Type() == eType_Plugin) {
-    return nsIContent::IME_STATUS_PLUGIN;
+    return IMEState(IMEState::PLUGIN);
   }
    
   return nsGenericHTMLFormElement::GetDesiredIMEState();
 }
 
 NS_IMETHODIMP
 nsHTMLObjectElement::Reset()
 {
--- a/content/html/content/src/nsHTMLSharedObjectElement.cpp
+++ b/content/html/content/src/nsHTMLSharedObjectElement.cpp
@@ -45,16 +45,17 @@
 #include "nsIDocument.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"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 class nsHTMLSharedObjectElement : public nsGenericHTMLElement
                                 , public nsObjectLoadingContent
                                 , public nsIDOMHTMLAppletElement
                                 , public nsIDOMHTMLEmbedElement
@@ -114,17 +115,17 @@ public:
                               bool aCompileEventHandlers);
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true);
   virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom *aName,
                            nsIAtom *aPrefix, const nsAString &aValue,
                            bool aNotify);
 
   virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, PRInt32 *aTabIndex);
-  virtual PRUint32 GetDesiredIMEState();
+  virtual IMEState GetDesiredIMEState();
 
   virtual void DoneAddingChildren(bool aHaveNotified);
   virtual bool IsDoneAddingChildren();
 
   virtual bool ParseAttribute(PRInt32 aNamespaceID,
                                 nsIAtom *aAttribute,
                                 const nsAString &aValue,
                                 nsAttrValue &aResult);
@@ -360,21 +361,21 @@ nsHTMLSharedObjectElement::IsHTMLFocusab
 
     // Let the plugin decide, so override.
     return true;
   }
 
   return nsGenericHTMLElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex);
 }
 
-PRUint32
+nsIContent::IMEState
 nsHTMLSharedObjectElement::GetDesiredIMEState()
 {
   if (Type() == eType_Plugin) {
-    return nsIContent::IME_STATUS_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)
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -1288,22 +1288,20 @@ nsHTMLDocument::GetURL(nsAString& aURL)
   }
 
   CopyUTF8toUTF16(str, aURL);
 
   return NS_OK;
 }
 
 nsIContent*
-nsHTMLDocument::GetBody(nsresult *aResult)
+nsHTMLDocument::GetBody()
 {
   Element* body = GetBodyElement();
 
-  *aResult = NS_OK;
-
   if (body) {
     // There is a body element, return that as the body.
     return body;
   }
 
   // The document is most likely a frameset document so look for the
   // outer most frameset element
   nsRefPtr<nsContentList> nodeList =
@@ -1312,20 +1310,19 @@ nsHTMLDocument::GetBody(nsresult *aResul
   return nodeList->GetNodeAt(0);
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::GetBody(nsIDOMHTMLElement** aBody)
 {
   *aBody = nsnull;
 
-  nsresult rv;
-  nsIContent *body = GetBody(&rv);
-
-  return body ? CallQueryInterface(body, aBody) : rv;
+  nsIContent *body = GetBody();
+
+  return body ? CallQueryInterface(body, aBody) : NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::SetBody(nsIDOMHTMLElement* aBody)
 {
   nsCOMPtr<nsIContent> newBody = do_QueryInterface(aBody);
   Element* root = GetRootElement();
 
--- a/content/html/document/src/nsHTMLDocument.h
+++ b/content/html/document/src/nsHTMLDocument.h
@@ -130,17 +130,18 @@ public:
    * Returns the result of document.all[aID] which can either be a node
    * or a nodelist depending on if there are multiple nodes with the same
    * id.
    */
   nsISupports *GetDocumentAllResult(const nsAString& aID,
                                     nsWrapperCache **aCache,
                                     nsresult *aResult);
 
-  nsIContent *GetBody(nsresult *aResult);
+  nsIContent *GetBody();
+  Element *GetHead() { return GetHeadElement(); }
   already_AddRefed<nsContentList> GetElementsByName(const nsAString & aName)
   {
     return NS_GetFuncStringContentList(this, MatchNameAttribute, nsnull,
                                        UseExistingNameString, aName);
   }
 
 
   virtual nsresult ResolveName(const nsAString& aName,
--- a/content/media/test/manifest.js
+++ b/content/media/test/manifest.js
@@ -336,42 +336,47 @@ function MediaTestManager() {
   this.runTests = function(tests, startTest) {
     this.startTime = new Date();
     SimpleTest.info("Started " + this.startTime + " (" + this.startTime.getTime()/1000 + "s)");
     this.testNum = 0;
     this.tests = tests;
     this.startTest = startTest;
     this.tokens = [];
     this.isShutdown = false;
+    this.numTestsRunning = 0;
     // Always wait for explicit finish.
     SimpleTest.waitForExplicitFinish();
     this.nextTest();
   }
   
   // Registers that the test corresponding to 'token' has been started.
   // Don't call more than once per token.
   this.started = function(token) {
     this.tokens.push(token);
+    this.numTestsRunning++;
+    is(this.numTestsRunning, this.tokens.length, "[started " + token + "] Length of array should match number of running tests");
   }
   
   // Registers that the test corresponding to 'token' has finished. Call when
   // you've finished your test. If all tests are complete this will finish the
   // run, otherwise it may start up the next run. It's ok to call multiple times
   // per token.
   this.finished = function(token) {
     var i = this.tokens.indexOf(token);
     if (i != -1) {
       // Remove the element from the list of running tests.
       this.tokens.splice(i, 1);
     }
+    this.numTestsRunning--;
+    is(this.numTestsRunning, this.tokens.length, "[finished " + token + "] Length of array should match number of running tests");
     if (this.tokens.length < PARALLEL_TESTS) {
       this.nextTest();
     }
   }
-  
+
   // Starts the next batch of tests, or finishes if they're all done.
   // Don't call this directly, call finished(token) when you're done.
   this.nextTest = function() {
     // Force a GC after every completed testcase. This ensures that any decoders
     // with live threads waiting for the GC are killed promptly, to free up the
     // thread stacks' address space.
     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
     Components.utils.forceGC();
--- a/content/media/test/test_playback.html
+++ b/content/media/test/test_playback.html
@@ -30,32 +30,32 @@ function startTest(test, token) {
     if (test.duration) {
       ok(Math.abs(v.currentTime - test.duration) < 0.1,
          test.name + " current time at end: " + v.currentTime + " should be: " + test.duration);
     }
     is(test.name, v.name, "Name should match test.name #2");
     is(v.readyState, v.HAVE_CURRENT_DATA, test.name + " checking readyState");
     ok(v.readyState != v.NETWORK_LOADED, test.name + " shouldn't report NETWORK_LOADED");
     ok(v.ended, test.name + " checking playback has ended");
-    if (v.ended && v.seenSuspend) {
-      if (v.parentNode)
-        v.parentNode.removeChild(v);
+    if (v.ended && v.seenSuspend && !v.finished) {
+      v.finished = true;
+      v.parentNode.removeChild(v);
       manager.finished(v.token);
     }
   }}(test, v);
   var checkSuspended = function(test, v) { return function() {
     is(test.name, v.name, "Name should match test.name #3");
     if (v.seenSuspend)
       return;
 
     v.seenSuspend = true;
     ok(true, test.name + " got suspend");
-    if (v.ended && v.seenSuspend) {
-      if (v.parentNode)
-        v.parentNode.removeChild(v);
+    if (v.ended && !v.finished) {
+      v.finished = true;
+      v.parentNode.removeChild(v);
       manager.finished(v.token);
     }
   }}(test, v);
   v.prevTime = 0;
   var timeUpdate = function(test, v) { return function() {
     is(test.name, v.name, "Name should match test.name #4");
     checkMetadata(test.name, v, test);
     ok(v.prevTime <= v.currentTime,
--- a/content/media/test/test_preload_actions.html
+++ b/content/media/test/test_preload_actions.html
@@ -40,51 +40,52 @@ var finished = false;
 addLoadEvent(function() {gotLoadEvent=true;});
 
 function log(m) {
   var l = document.getElementById("log");
   l.innerHTML += m;
 }
 
 function maybeFinish(v, n) {
+  if (v._finished) {
+    return;
+  }
+  v._finished = true;
   log(n + ",");
   if (v.parentNode) {
     v.parentNode.removeChild(v);
   }
   manager.finished(v.token);
 }
 
 function filename(uri) {
   return uri.substr(uri.lastIndexOf("/")+1);
 }
 
-// Every test must have a setup(v) function, and must set _finished field on target v to
-// true when test is complete.
+// Every test must have a setup(v) function, and must call maybeFinish() when test is complete.
 var tests = [
   {
     // 1. Add preload:none video with src to document. Load should halt at NETWORK_IDLE and HAVE_NOTHING,
     // after receiving a suspend event. Should not receive loaded events until after we call load().
     // Note the suspend event is explictly sent by our "stop the load" code, but other tests can't rely
     // on it for the preload:metadata case, as there can be multiple suspend events when loading metadata.
     suspend:
     function(e) {
       var v = e.target;
       is(v._gotLoadStart, true, "(1) Must get loadstart.");
       is(v._gotLoadedMetaData, false, "(1) Must not get loadedmetadata.");
       is(v.readyState, v.HAVE_NOTHING, "(1) ReadyState must be HAVE_NOTHING");
       is(v.networkState, v.NETWORK_IDLE, "(1) NetworkState must be NETWORK_IDLE");
-      v._finished = true;
       maybeFinish(v, 1);
     },
     
     setup:
     function(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
-      v._finished = false;
       v.preload = "none";
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
       v.addEventListener("suspend", this.suspend, false);
       v.src = test.name;
       document.body.appendChild(v); // Causes implicit load, which will be halted due to preload:none.
     },
   },
@@ -93,50 +94,46 @@ var tests = [
     // after suspend event and after loadedmetadata.
     loadeddata:
     function(e) {
       var v = e.target;
       is(v._gotLoadStart, true, "(2) Must get loadstart.");
       is(v._gotLoadedMetaData, true, "(2) Must get loadedmetadata.");
       ok(v.readyState >= v.HAVE_CURRENT_DATA, "(2) ReadyState must be >= HAVE_CURRENT_DATA");
       is(v.networkState, v.NETWORK_IDLE, "(2) NetworkState must be NETWORK_IDLE");
-      v._finished = true;
       maybeFinish(v, 2);
     },
     
     setup:
     function(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
-      v._finished = false;
       v.preload = "metadata";
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
       v.addEventListener("loadeddata", this.loadeddata, false);
       v.src = test.name;
       document.body.appendChild(v); // Causes implicit load, which will be halted after
                                      // metadata due to preload:metadata.
     },
   },
   {
     // 3. Add preload:auto to document. Should receive canplaythrough eventually.
     canplaythrough:
     function(e) {
       var v = e.target;
       is(v._gotLoadStart, true, "(3) Must get loadstart.");
       is(v._gotLoadedMetaData, true, "(3) Must get loadedmetadata.");
-      v._finished = true;
       maybeFinish(v, 3);
     },
     
     setup:
     function(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
-      v._finished = false;
       v.preload = "auto";
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
       v.addEventListener("canplaythrough", this.canplaythrough, false);
       v.src = test.name; // Causes implicit load.
       document.body.appendChild(v);
     },
   },
@@ -154,26 +151,24 @@ var tests = [
       is(v.readyState, v.HAVE_NOTHING, "(4) ReadyState must be HAVE_NOTHING");
       is(v.networkState, v.NETWORK_IDLE, "(4) NetworkState must be NETWORK_IDLE");
       v.play(); // Should load and play through.
     },
     
     ended:
     function(e) {
       ok(true, "(4) Got playback ended");
-      e.target._finished = true;
       maybeFinish(e.target, 4);
     },
       
     setup:
     function(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
       v._gotSuspend = false;
-      v._finished = false;
       v.preload = "none";
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
       v.addEventListener("suspend", this.suspend, false);
       v.addEventListener("ended", this.ended, false);
       v.src = test.name;
       document.body.appendChild(v);
     },
@@ -183,25 +178,23 @@ var tests = [
     // preload:none load. Add a src, it shouldn't load.
     suspend:
     function(e) {
       var v = e.target;
       is(v._gotLoadStart, true, "(5) Must get loadstart.");
       is(v._gotLoadedMetaData, false, "(5) Must not get loadedmetadata.");
       is(v.readyState, v.HAVE_NOTHING, "(5) ReadyState must be HAVE_NOTHING");
       is(v.networkState, v.NETWORK_IDLE, "(5) NetworkState must be NETWORK_IDLE");
-      v._finished = true;
       maybeFinish(v, 5);
     },
       
     setup:
     function(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
-      v._finished = false;
       v.preload = "none";
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
       v.addEventListener("suspend", this.suspend, false);
       document.body.appendChild(v); // Causes implicit load, which will be halted due to no resource.
       v.src = test.name; // Load should start, and halt at preload:none.
     },
   },
@@ -210,25 +203,23 @@ var tests = [
     // preload:none load. Add a source, it shouldn't load.
     suspend:
     function(e) {
       var v = e.target;
       is(v._gotLoadStart, true, "(6) Must get loadstart.");
       is(v._gotLoadedMetaData, false, "(6) Must not get loadedmetadata.");
       is(v.readyState, v.HAVE_NOTHING, "(6) ReadyState must be HAVE_NOTHING");
       is(v.networkState, v.NETWORK_IDLE, "(6) NetworkState must be NETWORK_IDLE");
-      v._finished = true;
       maybeFinish(v, 6);
     },
       
     setup:
     function(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
-      v._finished = false;
       v.preload = "none";
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
       v.addEventListener("suspend", this.suspend, false);
       document.body.appendChild(v); // Causes implicit load, which will be halted due to no resource.
       var s = document.createElement("source");
       s.src = test.name;
       s.type = test.type;
@@ -250,26 +241,24 @@ var tests = [
       is(v.networkState, v.NETWORK_IDLE, "(7) NetworkState must be NETWORK_IDLE");
       v.play(); // Should load and play through.
     },
 
     ended:
     function(e) {
       ok(true, "(7) Got playback ended");
       var v = e.target;
-      v._finished = true;
       is(v._gotErrorEvent, true, "(7) Should get error event from first source load failure");      
       maybeFinish(v, 7);
     },
       
     setup:
     function(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
-      v._finished = false;
       v.preload = "none";
       v._gotErrorEvent = false;
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
       v.addEventListener("suspend", this.suspend, false);
       v.addEventListener("ended", this.ended, false);
       var s1 = document.createElement("source");
       s1.src = "not-a-real-file.404"
@@ -286,124 +275,112 @@ var tests = [
   {
     // 8. Change preload value from none to metadata should cause metadata to be loaded.
     loadeddata:
     function(e) {
       var v = e.target;
       is(v._gotLoadedMetaData, true, "(8) Must get loadedmetadata.");
       ok(v.readyState >= v.HAVE_CURRENT_DATA, "(8) ReadyState must be >= HAVE_CURRENT_DATA on suspend.");
       is(v.networkState, v.NETWORK_IDLE, "(8) NetworkState must be NETWORK_IDLE when load is halted");
-      v._finished = true;
       maybeFinish(v, 8);
     },
     
     setup:
     function(v) {
       v._gotLoadedMetaData = false;
-      v._finished = false;
       v.preload = "none";
       v.addEventListener("loadstart", function(e){v.preload = "metadata";}, false);
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
       v.addEventListener("loadeddata", this.loadeddata, false);
       v.src = test.name; // Causes implicit load.
       document.body.appendChild(v);
     },
   },
   /*{
     // 9. Change preload value from metadata to auto should cause entire media to be loaded.
     // For some reason we don't always receive the canplaythrough event, particuarly on this test.
     // We've disabled this test until bug 568402 is fixed.
     canplaythrough:
     function(e) {
       var v = e.target;
-      if (v._finished)
-        return;
       is(v._gotLoadStart, true, "(9) Must get loadstart.");
       is(v._gotLoadedMetaData, true, "(9) Must get loadedmetadata.");
-      v._finished = true;
       maybeFinish(v, 9);
     },
     
     setup:
     function(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
-      v._finished = false;
       v.preload = "metadata";
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
       v.addEventListener("loadeddata", function(){v.preload = "auto"}, false);
       v.addEventListener("canplaythrough", this.canplaythrough, false);
       v.src = test.name; // Causes implicit load.
       document.body.appendChild(v);
     },
   },*/
   {
     // 10. Change preload value from none to auto should cause entire media to be loaded.
     canplaythrough:
     function(e) {
       var v = e.target;
       is(v._gotLoadedMetaData, true, "(10) Must get loadedmetadata.");
-      v._finished = true;
       maybeFinish(v, 10);
     },
     
     setup:
     function(v) {
       v._gotLoadedMetaData = false;
-      v._finished = false;
       v.preload = "none";
       v.addEventListener("loadstart", function(e){v.preload = "auto";}, false);
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
       v.addEventListener("canplaythrough", this.canplaythrough, false);
       v.src = test.name; // Causes implicit load.
       document.body.appendChild(v);
     },
   },
   {
     // 11. Change preload value from none to metadata should cause metadata to load.
     loadeddata:
     function(e) {
       var v = e.target;
       is(v._gotLoadedMetaData, true, "(11) Must get loadedmetadata.");
       ok(v.readyState >= v.HAVE_CURRENT_DATA, "(11) ReadyState must be >= HAVE_CURRENT_DATA.");
       is(v.networkState, v.NETWORK_IDLE, "(11) NetworkState must be NETWORK_IDLE.");
-      v._finished = true;
       maybeFinish(v, 11);
     },
 
     setup:
     function(v) {
       v._gotLoadedMetaData = false;
-      v._finished = false;
       v.preload = "none";
       v.addEventListener("loadstart", function(e){v.preload = "metadata";}, false);
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
       v.addEventListener("loadeddata", this.loadeddata, false);
       v.src = test.name; // Causes implicit load.
       document.body.appendChild(v);
     },
   },
   {
     // 12. Change preload value from auto to metadata after load started,
     // should still do full load, should not halt after metadata only.
     canplaythrough:
     function(e) {
       var v = e.target;
       is(v._gotLoadedMetaData, true, "(12) Must get loadedmetadata.");
       is(v._gotLoadStart, true, "(12) Must get loadstart.");
-      v._finished = true;
       maybeFinish(v, 12);
     },
 
     setup:
     function(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
-      v._finished = false;
       v.preload = "auto";
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
       v.addEventListener("canplaythrough", this.canplaythrough, false);
       v.src = test.name; // Causes implicit load.
       document.body.appendChild(v);
       v.preload = "metadata";
     },
@@ -414,25 +391,23 @@ var tests = [
     // should still load up to metadata, should not halt immediately.
     loadeddata:
     function(e) {
       var v = e.target;
       is(v._gotLoadStart, true, "(13) Must get loadstart.");
       is(v._gotLoadedMetaData, true, "(13) Must get loadedmetadata.");
       ok(v.readyState >= v.HAVE_CURRENT_DATA, "(13) ReadyState must be >= HAVE_CURRENT_DATA.");
       is(v.networkState, v.NETWORK_IDLE, "(13) NetworkState must be NETWORK_IDLE.");
-      v._finished = true;
       maybeFinish(v, 13);
     },
 
     setup:
     function(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
-      v._finished = false;
       v.preload = "metadata";
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
       v.addEventListener("loadeddata", this.loadeddata, false);
       v.src = test.name; // Causes implicit load.
       document.body.appendChild(v);
       v.preload = "none";
     },
@@ -448,114 +423,104 @@ var tests = [
       is(v.networkState, v.NETWORK_IDLE, "(14) NetworkState must be NETWORK_IDLE");
       v.play();
     },
     
     ended:
     function(e) {
       ok(true, "(14) Got playback ended");
       var v = e.target;
-      v._finished = true;
       maybeFinish(v, 14);
     },
 
     setup:
     function(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
-      v._finished = false;
       v.preload = "metadata";
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
       v.addEventListener("ended", this.ended, false);
       v.addEventListener("loadeddata", this.loadeddata, false);
       v.src = test.name;
       document.body.appendChild(v); // Causes implicit load, which will be halted after
                                      // metadata due to preload:metadata.
     },
   },
   {
     // 15. Autoplay should override preload:none.
     ended:
     function(e) {
       ok(true, "(15) Got playback ended.");
       var v = e.target;
-      v._finished = true;
       maybeFinish(v, 15);
     },
     
     setup:
     function(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
-      v._finished = false;
       v.preload = "none";
       v.autoplay = true;
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
       v.addEventListener("ended", this.ended, false);
       v.src = test.name; // Causes implicit load.
       document.body.appendChild(v);
     },
   },
   {
     // 16. Autoplay should override preload:metadata.
     ended:
     function(e) {
       ok(true, "(16) Got playback ended.");
       var v = e.target;
-      v._finished = true;
       maybeFinish(v, 16);
     },
     
     setup:
     function(v) {
-      v._finished = false;
       v.preload = "metadata";
       v.autoplay = true;
       v.addEventListener("ended", this.ended, false);
       v.src = test.name; // Causes implicit load.
       document.body.appendChild(v);
     },
   },
   {
     // 17. On a preload:none video, adding autoplay should disable preload none, i.e. don't break autoplay!
     ended:
     function(e) {
       ok(true, "(17) Got playback ended.");
       var v = e.target;
-      v._finished = true;
       maybeFinish(v, 17);
     },
     
     setup:
     function(v) {
       v.addEventListener("ended", this.ended, false);
-      v._finished = false;
       v.preload = "none";
       document.body.appendChild(v); // Causes implicit load, which will be halted due to preload:none.
       v.autoplay = true;
       v.src = test.name;
     },    
   },
   {
     // 18. On a preload='none' video, call play() before load algorithms's sync
     // has run, the play() call should override preload='none'.
     ended:
     function(e) {
       ok(true, "(18) Got playback ended.");
       var v = e.target;
-      v._finished = true;
       maybeFinish(v, 18);
     },
     
     setup:
     function(v) {
       v.addEventListener("ended", this.ended, false);
-      v._finished = false;
       v.preload = "none";
       v.src = test.name; // Schedules async section to continue load algorithm.
       document.body.appendChild(v);
       v.play(); // Should cause preload:none to be overridden.
     },  
     }
 ];
 
--- a/content/media/test/test_timeupdate_small_files.html
+++ b/content/media/test/test_timeupdate_small_files.html
@@ -41,29 +41,39 @@ function ended(e) {
       v.removeEventListener("ended", ended, false);
       v.removeEventListener("timeupdate", timeupdate, false);
       v.parentNode.removeChild(v);
       manager.finished(v.token);
     },
     500);
 }
 
+var eventsToLog = ["play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
+  "loadeddata", "playing", "progress", "timeupdate", "ended", "suspend", "error", "stalled", "emptied", "abort",
+  "waiting", "pause"];
+function logEvent(event) {
+  ok(true, event.target.currentSrc + " got " + event.type);
+}
+
 function startTest(test, token) {
   var type = /^video/.test(test.type) ? "video" : "audio";
   var v = document.createElement(type);
   v.token = token;
   manager.started(token);
   v.src = test.name;
   v._name = test.name;
   v._timeupdateCount = 0;
   v._finished = false;
   v.gotEnded = false;
   v.autoplay = true;
   v.addEventListener("ended", ended, false);
   v.addEventListener("timeupdate", timeupdate, false);
+  for (var i = 0; i < eventsToLog.length; ++i) {
+    v.addEventListener(eventsToLog[i], logEvent, false);
+  }
   document.body.appendChild(v);
 }
 
 manager.runTests(gSmallTests, startTest);
 
 </script>
 </pre>
 </body>
--- a/content/smil/nsSMILTimeValueSpec.cpp
+++ b/content/smil/nsSMILTimeValueSpec.cpp
@@ -329,16 +329,21 @@ nsSMILTimeValueSpec::RegisterEventListen
     "Attempting to register event-listener for unexpected nsSMILTimeValueSpec"
     " type");
   NS_ABORT_IF_FALSE(mParams.mEventSymbol,
     "Attempting to register event-listener but there is no event name");
 
   if (!aTarget)
     return;
 
+  // Don't listen for accessKey events if script is disabled. (see bug 704482)
+  if (mParams.mType == nsSMILTimeValueSpecParams::ACCESSKEY &&
+      !aTarget->GetOwnerDocument()->IsScriptEnabled())
+    return;
+
   if (!mEventListener) {
     mEventListener = new EventListener(this);
   }
 
   nsEventListenerManager* elm = GetEventListenerManager(aTarget);
   if (!elm)
     return;
 
--- a/content/svg/content/src/DOMSVGLengthList.cpp
+++ b/content/svg/content/src/DOMSVGLengthList.cpp
@@ -139,17 +139,17 @@ DOMSVGLengthList::InternalListLengthWill
 
   // If our length has increased, null out the new pointers:
   for (PRUint32 i = oldLength; i < aNewLength; ++i) {
     mItems[i] = nsnull;
   }
 }
 
 SVGLengthList&
-DOMSVGLengthList::InternalList()
+DOMSVGLengthList::InternalList() const
 {
   SVGAnimatedLengthList *alist = Element()->GetAnimatedLengthList(AttrEnum());
   return IsAnimValList() && alist->mAnimVal ? *alist->mAnimVal : alist->mBaseVal;
 }
 
 // ----------------------------------------------------------------------------
 // nsIDOMSVGLengthList implementation:
 
--- a/content/svg/content/src/DOMSVGLengthList.h
+++ b/content/svg/content/src/DOMSVGLengthList.h
@@ -98,30 +98,29 @@ public:
   };
 
   /**
    * This will normally be the same as InternalList().Length(), except if we've
    * hit OOM in which case our length will be zero.
    */
   PRUint32 Length() const {
     NS_ABORT_IF_FALSE(mItems.Length() == 0 ||
-                      mItems.Length() ==
-                        const_cast<DOMSVGLengthList*>(this)->InternalList().Length(),
+                      mItems.Length() == InternalList().Length(),
                       "DOM wrapper's list length is out of sync");
     return mItems.Length();
   }
 
   nsIDOMSVGLength* GetItemWithoutAddRef(PRUint32 aIndex);
 
   /// Called to notify us to syncronize our length and detach excess items.
   void InternalListLengthWillChange(PRUint32 aNewLength);
 
 private:
 
-  nsSVGElement* Element() {
+  nsSVGElement* Element() const {
     return mAList->mElement;
   }
 
   PRUint8 AttrEnum() const {
     return mAList->mAttrEnum;
   }
 
   PRUint8 Axis() const {
@@ -138,17 +137,17 @@ private:
   /**
    * Get a reference to this object's corresponding internal SVGLengthList.
    *
    * To simplify the code we just have this one method for obtaining both
    * baseVal and animVal internal lists. This means that animVal lists don't
    * get const protection, but our setter methods guard against changing
    * animVal lists.
    */
-  SVGLengthList& InternalList();
+  SVGLengthList& InternalList() const;
 
   /// Creates a DOMSVGLength for aIndex, if it doesn't already exist.
   void EnsureItemAt(PRUint32 aIndex);
 
   void MaybeInsertNullInAnimValListAt(PRUint32 aIndex);
   void MaybeRemoveItemFromAnimValListAt(PRUint32 aIndex);
 
   // Weak refs to our DOMSVGLength items. The items are friends and take care
--- a/content/svg/content/src/DOMSVGNumberList.cpp
+++ b/content/svg/content/src/DOMSVGNumberList.cpp
@@ -139,17 +139,17 @@ DOMSVGNumberList::InternalListLengthWill
 
   // If our length has increased, null out the new pointers:
   for (PRUint32 i = oldLength; i < aNewLength; ++i) {
     mItems[i] = nsnull;
   }
 }
 
 SVGNumberList&
-DOMSVGNumberList::InternalList()
+DOMSVGNumberList::InternalList() const
 {
   SVGAnimatedNumberList *alist = Element()->GetAnimatedNumberList(AttrEnum());
   return IsAnimValList() && alist->mAnimVal ? *alist->mAnimVal : alist->mBaseVal;
 }
 
 // ----------------------------------------------------------------------------
 // nsIDOMSVGNumberList implementation:
 
--- a/content/svg/content/src/DOMSVGNumberList.h
+++ b/content/svg/content/src/DOMSVGNumberList.h
@@ -97,30 +97,29 @@ public:
   }
 
   /**
    * This will normally be the same as InternalList().Length(), except if we've
    * hit OOM in which case our length will be zero.
    */
   PRUint32 Length() const {
     NS_ABORT_IF_FALSE(mItems.Length() == 0 ||
-                      mItems.Length() ==
-                        const_cast<DOMSVGNumberList*>(this)->InternalList().Length(),
+                      mItems.Length() == InternalList().Length(),
                       "DOM wrapper's list length is out of sync");
     return mItems.Length();
   }
 
   nsIDOMSVGNumber* GetItemWithoutAddRef(PRUint32 aIndex);
 
   /// Called to notify us to syncronize our length and detach excess items.
   void InternalListLengthWillChange(PRUint32 aNewLength);
 
 private:
 
-  nsSVGElement* Element() {
+  nsSVGElement* Element() const {
     return mAList->mElement;
   }
 
   PRUint8 AttrEnum() const {
     return mAList->mAttrEnum;
   }
 
   /// Used to determine if this list is the baseVal or animVal list.
@@ -133,17 +132,17 @@ private:
   /**
    * Get a reference to this object's corresponding internal SVGNumberList.
    *
    * To simplify the code we just have this one method for obtaining both
    * baseVal and animVal internal lists. This means that animVal lists don't
    * get const protection, but our setter methods guard against changing
    * animVal lists.
    */
-  SVGNumberList& InternalList();
+  SVGNumberList& InternalList() const;
 
   /// Creates a DOMSVGNumber for aIndex, if it doesn't already exist.
   void EnsureItemAt(PRUint32 aIndex);
 
   void MaybeInsertNullInAnimValListAt(PRUint32 aIndex);
   void MaybeRemoveItemFromAnimValListAt(PRUint32 aIndex);
 
   // Weak refs to our DOMSVGNumber items. The items are friends and take care
--- a/content/svg/content/src/DOMSVGPathSegList.cpp
+++ b/content/svg/content/src/DOMSVGPathSegList.cpp
@@ -225,28 +225,28 @@ DOMSVGPathSegList::InternalListWillChang
 
   NS_ABORT_IF_FALSE(dataIndex == dataLength, "Serious processing error");
   NS_ABORT_IF_FALSE(index == length, "Serious counting error");
 }
 
 bool
 DOMSVGPathSegList::AttrIsAnimating() const
 {
-  return const_cast<DOMSVGPathSegList*>(this)->InternalAList().IsAnimating();
+  return InternalAList().IsAnimating();
 }
 
 SVGPathData&
-DOMSVGPathSegList::InternalList()
+DOMSVGPathSegList::InternalList() const
 {
   SVGAnimatedPathSegList *alist = mElement->GetAnimPathSegList();
   return mIsAnimValList && alist->IsAnimating() ? *alist->mAnimVal : alist->mBaseVal;
 }
 
 SVGAnimatedPathSegList&
-DOMSVGPathSegList::InternalAList()
+DOMSVGPathSegList::InternalAList() const
 {
   NS_ABORT_IF_FALSE(mElement->GetAnimPathSegList(), "Internal error");
   return *mElement->GetAnimPathSegList();
 }
 
 // ----------------------------------------------------------------------------
 // nsIDOMSVGPathSegList implementation:
 
--- a/content/svg/content/src/DOMSVGPathSegList.h
+++ b/content/svg/content/src/DOMSVGPathSegList.h
@@ -115,18 +115,17 @@ public:
   GetDOMWrapperIfExists(void *aList);
 
   /**
    * This will normally be the same as InternalList().CountItems(), except if
    * we've hit OOM, in which case our length will be zero.
    */
   PRUint32 Length() const {
     NS_ABORT_IF_FALSE(mItems.Length() == 0 ||
-                      mItems.Length() ==
-                        const_cast<DOMSVGPathSegList*>(this)->InternalList().CountItems(),
+                      mItems.Length() == InternalList().CountItems(),
                       "DOM wrapper's list length is out of sync");
     return mItems.Length();
   }
 
   nsIDOMSVGPathSeg* GetItemWithoutAddRef(PRUint32 aIndex);
 
   /**
    * WATCH OUT! If you add code to call this on a baseVal wrapper, then you
@@ -179,19 +178,19 @@ private:
   /**
    * Get a reference to this object's corresponding internal SVGPathData.
    *
    * To simplify the code we just have this one method for obtaining both
    * base val and anim val internal lists. This means that anim val lists don't
    * get const protection, but our setter methods guard against changing
    * anim val lists.
    */
-  SVGPathData& InternalList();
+  SVGPathData& InternalList() const;
 
-  SVGAnimatedPathSegList& InternalAList();
+  SVGAnimatedPathSegList& InternalAList() const;
 
   /// Creates an instance of the appropriate DOMSVGPathSeg sub-class for
   // aIndex, if it doesn't already exist.
   void EnsureItemAt(PRUint32 aIndex);
 
   void MaybeInsertNullInAnimValListAt(PRUint32 aIndex,
                                       PRUint32 aInternalIndex,
                                       PRUint32 aArgCountForItem);
--- a/content/svg/content/src/DOMSVGPointList.cpp
+++ b/content/svg/content/src/DOMSVGPointList.cpp
@@ -170,28 +170,28 @@ DOMSVGPointList::InternalListWillChangeT
   for (PRUint32 i = oldLength; i < newLength; ++i) {
     mItems[i] = nsnull;
   }
 }
 
 bool
 DOMSVGPointList::AttrIsAnimating() const
 {
-  return const_cast<DOMSVGPointList*>(this)->InternalAList().IsAnimating();
+  return InternalAList().IsAnimating();
 }
 
 SVGPointList&
-DOMSVGPointList::InternalList()
+DOMSVGPointList::InternalList() const
 {
   SVGAnimatedPointList *alist = mElement->GetAnimatedPointList();
   return mIsAnimValList && alist->IsAnimating() ? *alist->mAnimVal : alist->mBaseVal;
 }
 
 SVGAnimatedPointList&
-DOMSVGPointList::InternalAList()
+DOMSVGPointList::InternalAList() const
 {
   NS_ABORT_IF_FALSE(mElement->GetAnimatedPointList(), "Internal error");
   return *mElement->GetAnimatedPointList();
 }
 
 // ----------------------------------------------------------------------------
 // nsIDOMSVGPointList implementation:
 
--- a/content/svg/content/src/DOMSVGPointList.h
+++ b/content/svg/content/src/DOMSVGPointList.h
@@ -115,18 +115,17 @@ public:
   GetDOMWrapperIfExists(void *aList);
 
   /**
    * This will normally be the same as InternalList().Length(), except if
    * we've hit OOM, in which case our length will be zero.
    */
   PRUint32 Length() const {
     NS_ABORT_IF_FALSE(mItems.Length() == 0 ||
-                      mItems.Length() ==
-                        const_cast<DOMSVGPointList*>(this)->InternalList().Length(),
+                      mItems.Length() == InternalList().Length(),
                       "DOM wrapper's list length is out of sync");
     return mItems.Length();
   }
 
   nsIDOMSVGPoint* GetItemWithoutAddRef(PRUint32 aIndex);
 
   /**
    * WATCH OUT! If you add code to call this on a baseVal wrapper, then you
@@ -179,19 +178,19 @@ private:
   /**
    * Get a reference to this object's corresponding internal SVGPointList.
    *
    * To simplify the code we just have this one method for obtaining both
    * base val and anim val internal lists. This means that anim val lists don't
    * get const protection, but our setter methods guard against changing
    * anim val lists.
    */
-  SVGPointList& InternalList();
+  SVGPointList& InternalList() const;
 
-  SVGAnimatedPointList& InternalAList();
+  SVGAnimatedPointList& InternalAList() const;
 
   /// Creates a DOMSVGPoint for aIndex, if it doesn't already exist.
   void EnsureItemAt(PRUint32 aIndex);
 
   void MaybeInsertNullInAnimValListAt(PRUint32 aIndex);
   void MaybeRemoveItemFromAnimValListAt(PRUint32 aIndex);
 
   // Weak refs to our DOMSVGPoint items. The items are friends and take care
--- a/content/svg/content/src/DOMSVGTransformList.cpp
+++ b/content/svg/content/src/DOMSVGTransformList.cpp
@@ -141,17 +141,17 @@ DOMSVGTransformList::InternalListLengthW
 
   // If our length has increased, null out the new pointers:
   for (PRUint32 i = oldLength; i < aNewLength; ++i) {
     mItems[i] = nsnull;
   }
 }
 
 SVGTransformList&
-DOMSVGTransformList::InternalList()
+DOMSVGTransformList::InternalList() const
 {
   SVGAnimatedTransformList *alist = Element()->GetAnimatedTransformList();
   return IsAnimValList() && alist->mAnimVal ?
     *alist->mAnimVal :
     alist->mBaseVal;
 }
 
 //----------------------------------------------------------------------
--- a/content/svg/content/src/DOMSVGTransformList.h
+++ b/content/svg/content/src/DOMSVGTransformList.h
@@ -92,30 +92,29 @@ public:
   }
 
   /**
    * This will normally be the same as InternalList().Length(), except if we've
    * hit OOM in which case our length will be zero.
    */
   PRUint32 Length() const {
     NS_ABORT_IF_FALSE(mItems.IsEmpty() ||
-      mItems.Length() ==
-        const_cast<DOMSVGTransformList*>(this)->InternalList().Length(),
+      mItems.Length() == InternalList().Length(),
       "DOM wrapper's list length is out of sync");
     return mItems.Length();
   }
 
   nsIDOMSVGTransform* GetItemWithoutAddRef(PRUint32 aIndex);
 
   /// Called to notify us to synchronize our length and detach excess items.
   void InternalListLengthWillChange(PRUint32 aNewLength);
 
 private:
 
-  nsSVGElement* Element() {
+  nsSVGElement* Element() const {
     return mAList->mElement;
   }
 
   /// Used to determine if this list is the baseVal or animVal list.
   bool IsAnimValList() const {
     NS_ABORT_IF_FALSE(this == mAList->mBaseVal || this == mAList->mAnimVal,
                       "Calling IsAnimValList() too early?!");
     return this == mAList->mAnimVal;
@@ -124,17 +123,17 @@ private:
   /**
    * Get a reference to this object's corresponding internal SVGTransformList.
    *
    * To simplify the code we just have this one method for obtaining both
    * baseVal and animVal internal lists. This means that animVal lists don't
    * get const protection, but our setter methods guard against changing
    * animVal lists.
    */
-  SVGTransformList& InternalList();
+  SVGTransformList& InternalList() const;
 
   /// Creates a DOMSVGTransform for aIndex, if it doesn't already exist.
   void EnsureItemAt(PRUint32 aIndex);
 
   void MaybeInsertNullInAnimValListAt(PRUint32 aIndex);
   void MaybeRemoveItemFromAnimValListAt(PRUint32 aIndex);
 
   // Weak refs to our DOMSVGTransform items. The items are friends and take care
--- a/content/svg/content/src/nsSVGPathElement.cpp
+++ b/content/svg/content/src/nsSVGPathElement.cpp
@@ -434,17 +434,17 @@ nsSVGPathElement::GetPathLengthScale(Pat
   if (mPathLength.IsExplicitlySet()) {
     float authorsPathLengthEstimate = mPathLength.GetAnimValue();
     if (authorsPathLengthEstimate > 0) {
       gfxMatrix matrix;
       if (aFor == eForTextPath) {
         // For textPath, a transform on the referenced path affects the
         // textPath layout, so when calculating the actual path length
         // we need to take that into account.
-        matrix = PrependLocalTransformTo(gfxMatrix());
+        matrix = PrependLocalTransformTo(matrix);
       }
       nsRefPtr<gfxFlattenedPath> path = GetFlattenedPath(matrix);
       if (path) {
         return path->GetLength() / authorsPathLengthEstimate;
       }
     }
   }
   return 1.0;
--- a/content/xbl/src/nsXBLProtoImplMember.h
+++ b/content/xbl/src/nsXBLProtoImplMember.h
@@ -110,17 +110,17 @@ public:
 
   virtual nsresult InstallMember(nsIScriptContext* aContext,
                                  nsIContent* aBoundElement, 
                                  void* aScriptObject,
                                  void* aTargetClassObject,
                                  const nsCString& aClassStr) = 0;
   virtual nsresult CompileMember(nsIScriptContext* aContext,
                                  const nsCString& aClassStr,
-                                 void* aClassObject)=0;
+                                 JSObject* aClassObject) = 0;
 
   virtual void Trace(TraceCallback aCallback, void *aClosure) const = 0;
 
   virtual nsresult Write(nsIScriptContext* aContext,
                          nsIObjectOutputStream* aStream)
   {
     return NS_OK;
   }
--- a/content/xbl/src/nsXBLProtoImplMethod.cpp
+++ b/content/xbl/src/nsXBLProtoImplMethod.cpp
@@ -168,17 +168,17 @@ nsXBLProtoImplMethod::InstallMember(nsIS
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
   return NS_OK;
 }
 
 nsresult 
 nsXBLProtoImplMethod::CompileMember(nsIScriptContext* aContext, const nsCString& aClassStr,
-                                    void* aClassObject)
+                                    JSObject* aClassObject)
 {
   NS_TIME_FUNCTION_MIN(5);
   NS_PRECONDITION(!IsCompiled(),
                   "Trying to compile an already-compiled method");
   NS_PRECONDITION(aClassObject,
                   "Must have class object to compile");
 
   nsXBLUncompiledMethod* uncompiledMethod = GetUncompiledMethod();
@@ -234,23 +234,23 @@ nsXBLProtoImplMethod::CompileMember(nsIS
   if (hash != kNotFound) {
     functionUri.Truncate(hash);
   }
 
   JSObject* methodObject = nsnull;
   nsresult rv = aContext->CompileFunction(aClassObject,
                                           cname,
                                           paramCount,
-                                          (const char**)args,
+                                          const_cast<const char**>(args),
                                           body, 
                                           functionUri.get(),
                                           uncompiledMethod->mBodyText.GetLineNumber(),
                                           JSVERSION_LATEST,
                                           true,
-                                          (void **) &methodObject);
+                                          &methodObject);
 
   // Destroy our uncompiled method and delete our arg list.
   delete uncompiledMethod;
   delete [] args;
   if (NS_FAILED(rv)) {
     SetUncompiledMethod(nsnull);
     return rv;
   }
--- a/content/xbl/src/nsXBLProtoImplMethod.h
+++ b/content/xbl/src/nsXBLProtoImplMethod.h
@@ -122,17 +122,17 @@ public:
   
   virtual nsresult InstallMember(nsIScriptContext* aContext,
                                  nsIContent* aBoundElement, 
                                  void* aScriptObject,
                                  void* aTargetClassObject,
                                  const nsCString& aClassStr);
   virtual nsresult CompileMember(nsIScriptContext* aContext,
                                  const nsCString& aClassStr,
-                                 void* aClassObject);
+                                 JSObject* aClassObject);
 
   virtual void Trace(TraceCallback aCallback, void *aClosure) const;
 
   nsresult Read(nsIScriptContext* aContext, nsIObjectInputStream* aStream);
   virtual nsresult Write(nsIScriptContext* aContext, nsIObjectOutputStream* aStream);
 
   bool IsCompiled() const
   {
--- a/content/xbl/src/nsXBLProtoImplProperty.cpp
+++ b/content/xbl/src/nsXBLProtoImplProperty.cpp
@@ -217,17 +217,17 @@ nsXBLProtoImplProperty::InstallMember(ns
                                mJSAttributes))
       return NS_ERROR_OUT_OF_MEMORY;
   }
   return NS_OK;
 }
 
 nsresult 
 nsXBLProtoImplProperty::CompileMember(nsIScriptContext* aContext, const nsCString& aClassStr,
-                                      void* aClassObject)
+                                      JSObject* aClassObject)
 {
   NS_PRECONDITION(!mIsCompiled,
                   "Trying to compile an already-compiled property");
   NS_PRECONDITION(aClassObject,
                   "Must have class object to compile");
 
   if (!mName)
     return NS_ERROR_FAILURE; // Without a valid name, we can't install the member.
@@ -255,17 +255,17 @@ nsXBLProtoImplProperty::CompileMember(ns
                                      NS_ConvertUTF16toUTF8(mName),
                                      0,
                                      nsnull,
                                      getter, 
                                      functionUri.get(),
                                      mGetterText->GetLineNumber(),
                                      JSVERSION_LATEST,
                                      true,
-                                     (void **) &getterObject);
+                                     &getterObject);
 
       // Make sure we free mGetterText here before setting mJSGetterObject, since
       // that'll overwrite mGetterText
       delete mGetterText;
       deletedGetter = true;
       mJSGetterObject = getterObject;
     
       if (mJSGetterObject && NS_SUCCEEDED(rv)) {
@@ -305,17 +305,17 @@ nsXBLProtoImplProperty::CompileMember(ns
                                      NS_ConvertUTF16toUTF8(mName),
                                      1,
                                      gPropertyArgs,
                                      setter, 
                                      functionUri.get(),
                                      mSetterText->GetLineNumber(),
                                      JSVERSION_LATEST,
                                      true,
-                                     (void **) &setterObject);
+                                     &setterObject);
 
       // Make sure we free mSetterText here before setting mJSGetterObject, since
       // that'll overwrite mSetterText
       delete mSetterText;
       deletedSetter = true;
       mJSSetterObject = setterObject;
 
       if (mJSSetterObject && NS_SUCCEEDED(rv)) {
--- a/content/xbl/src/nsXBLProtoImplProperty.h
+++ b/content/xbl/src/nsXBLProtoImplProperty.h
@@ -67,17 +67,17 @@ public:
 
   virtual nsresult InstallMember(nsIScriptContext* aContext,
                                  nsIContent* aBoundElement, 
                                  void* aScriptObject,
                                  void* aTargetClassObject,
                                  const nsCString& aClassStr);
   virtual nsresult CompileMember(nsIScriptContext* aContext,
                                  const nsCString& aClassStr,
-                                 void* aClassObject);
+                                 JSObject* aClassObject);
 
   virtual void Trace(TraceCallback aCallback, void *aClosure) const;
 
   nsresult Read(nsIScriptContext* aContext,
                 nsIObjectInputStream* aStream,
                 XBLBindingSerializeDetails aType);
   virtual nsresult Write(nsIScriptContext* aContext,
                          nsIObjectOutputStream* aStream);
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -318,45 +318,45 @@ nsXBLPrototypeHandler::ExecuteHandler(ns
 
   rv = EnsureEventHandler(boundGlobal, boundContext, onEventAtom, handler);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Bind it to the bound element
   JSObject* scope = boundGlobal->GetGlobalJSObject();
   nsScriptObjectHolder boundHandler(boundContext);
   rv = boundContext->BindCompiledEventHandler(scriptTarget, scope,
-                                              handler, boundHandler);
+                                              handler.getObject(), boundHandler);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Execute it.
-  nsCOMPtr<nsIDOMEventListener> eventListener;
+  nsCOMPtr<nsIJSEventListener> eventListener;
   rv = NS_NewJSEventListener(boundContext, scope,
                              scriptTarget, onEventAtom,
-                             static_cast<JSObject*>(
-                               static_cast<void*>(boundHandler)),
+                             boundHandler.getObject(),
                              getter_AddRefs(eventListener));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Handle the event.
   eventListener->HandleEvent(aEvent);
+  eventListener->Disconnect();
   return NS_OK;
 }
 
 nsresult
 nsXBLPrototypeHandler::EnsureEventHandler(nsIScriptGlobalObject* aGlobal,
                                           nsIScriptContext *aBoundContext,
                                           nsIAtom *aName,
                                           nsScriptObjectHolder &aHandler)
 {
   // Check to see if we've already compiled this
   nsCOMPtr<nsPIDOMWindow> pWindow = do_QueryInterface(aGlobal);
   if (pWindow) {
-    void* cachedHandler = pWindow->GetCachedXBLPrototypeHandler(this);
+    JSObject* cachedHandler = pWindow->GetCachedXBLPrototypeHandler(this);
     if (cachedHandler) {
-      aHandler.set(cachedHandler);
+      aHandler.setObject(cachedHandler);
       return aHandler ? NS_OK : NS_ERROR_FAILURE;
     }
   }
 
   // Ensure that we have something to compile
   nsDependentString handlerText(mHandlerText);
   if (handlerText.IsEmpty())
     return NS_ERROR_FAILURE;
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -722,17 +722,17 @@ nsScriptEventHandlerOwnerTearoff::GetCom
 {
     XUL_PROTOTYPE_ATTRIBUTE_METER(gNumCacheTests);
     aHandler.drop();
 
     nsXULPrototypeAttribute *attr =
         mElement->FindPrototypeAttribute(kNameSpaceID_None, aName);
     if (attr) {
         XUL_PROTOTYPE_ATTRIBUTE_METER(gNumCacheHits);
-        aHandler.set(attr->mEventHandler);
+        aHandler.setObject(attr->mEventHandler);
     }
 
     return NS_OK;
 }
 
 nsresult
 nsScriptEventHandlerOwnerTearoff::CompileEventHandler(
                                                 nsIScriptContext* aContext,
@@ -810,17 +810,17 @@ nsScriptEventHandlerOwnerTearoff::Compil
                                                   elem,
                                                   &NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode),
                                                   aHandler,
                                                   elem->mHoldsScriptObject);
             if (NS_FAILED(rv)) return rv;
 
             elem->mHoldsScriptObject = true;
         }
-        attr->mEventHandler = (void *)aHandler;
+        attr->mEventHandler = aHandler.getObject();
     }
 
     return NS_OK;
 }
 
 void
 nsXULElement::AddListenerFor(const nsAttrName& aName,
                              bool aCompileEventHandlers)
@@ -2562,17 +2562,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_TRACE_NATIVE_BEGIN(nsXULPrototypeNode)
     if (tmp->mType == nsXULPrototypeNode::eType_Element) {
         nsXULPrototypeElement *elem =
             static_cast<nsXULPrototypeElement*>(tmp);
         if (elem->mHoldsScriptObject) {
             PRUint32 i;
             for (i = 0; i < elem->mNumAttributes; ++i) {
-                void *handler = elem->mAttributes[i].mEventHandler;
+                JSObject* handler = elem->mAttributes[i].mEventHandler;
                 NS_IMPL_CYCLE_COLLECTION_TRACE_CALLBACK(elem->mScriptTypeID,
                                                         handler,
                                                         "mAttributes[i].mEventHandler")
             }
         }
     }
     else if (tmp->mType == nsXULPrototypeNode::eType_Script) {
         nsXULPrototypeScript *script =
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -121,17 +121,17 @@ public:
 
     ~nsXULPrototypeAttribute();
 
     nsAttrName mName;
     nsAttrValue mValue;
     // mEventHandler is only valid for the language ID specified in the
     // containing nsXULPrototypeElement.  We would ideally use
     // nsScriptObjectHolder, but want to avoid the extra lang ID.
-    void* mEventHandler;
+    JSObject* mEventHandler;
 
 #ifdef XUL_PROTOTYPE_ATTRIBUTE_METERING
     /**
       If enough attributes, on average, are event handlers, it pays to keep
       mEventHandler here, instead of maintaining a separate mapping in each
       nsXULElement associating those mName values with their mEventHandlers.
       Assume we don't need to keep mNameSpaceID along with mName in such an
       event-handler-only name-to-function-pointer mapping.
--- a/dom/Makefile.in
+++ b/dom/Makefile.in
@@ -61,16 +61,17 @@ DIRS = \
   interfaces/xul \
   interfaces/storage \
   interfaces/json \
   interfaces/offline \
   interfaces/geolocation \
   interfaces/notification \
   interfaces/svg \
   interfaces/smil \
+  interfaces/apps \
   $(NULL)
 
 DIRS += \
   base \
   battery \
   sms \
   src \
   locales \
--- a/dom/base/Makefile.in
+++ b/dom/base/Makefile.in
@@ -47,17 +47,23 @@ LIBRARY_NAME	= jsdombase_s
 LIBXUL_LIBRARY	= 1
 FORCE_STATIC_LIB = 1
 
 EXTRA_PP_COMPONENTS = \
 		ConsoleAPI.js \
 		ConsoleAPI.manifest \
 		$(NULL)
 
+EXTRA_COMPONENTS = \
+	        Webapps.js \
+	        Webapps.manifest \
+		$(NULL)
+
 EXTRA_JS_MODULES = ConsoleAPIStorage.jsm \
+                Webapps.jsm \
 		$(NULL)
 
 XPIDLSRCS = \
   nsIEntropyCollector.idl \
   nsIScriptChannel.idl \
   $(NULL)
 
 EXPORTS = \
new file mode 100644
--- /dev/null
+++ b/dom/base/Webapps.js
@@ -0,0 +1,346 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Open Web Apps.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Fabrice Desré <fabrice@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+const Cr = Components.results;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+function WebappsRegistry() {
+  this.messages = ["Webapps:Install:Return:OK", "Webapps:Install:Return:KO",
+                   "Webapps:Uninstall:Return:OK", "Webapps:Uninstall:Return:KO",
+                   "Webapps:Enumerate:Return:OK", "Webapps:Enumerate:Return:KO"];
+
+  this.mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
+
+  this.messages.forEach((function(msgName) {
+    this.mm.addMessageListener(msgName, this);
+  }).bind(this));
+
+  this._window = null;
+  this._id = this._getRandomId();
+  this._callbacks = [];
+}
+
+WebappsRegistry.prototype = {
+  _onerror: null,
+  _oninstall: null,
+  _onuninstall: null,
+
+  /** from https://developer.mozilla.org/en/OpenWebApps/The_Manifest
+   * only the name property is mandatory
+   */
+  checkManifest: function(aManifest, aInstallOrigin) {
+    // TODO : check for install_allowed_from
+    if (aManifest.name == undefined)
+      return false;
+    
+    if (aManifest.installs_allowed_from) {
+      ok = false;
+      aManifest.installs_allowed_from.forEach(function(aOrigin) {
+        if (aOrigin == "*" || aOrigin == aInstallOrigin)
+          ok = true;
+      });
+      return ok;
+    }
+    return true;
+  },
+  
+  getCallbackId: function(aCallback) {
+    let id = "id" + this._getRandomId();
+    this._callbacks[id] = aCallback;
+    return id;
+  },
+  
+  getCallback: function(aId) {
+    return this._callbacks[aId];
+  },
+
+  removeCallback: function(aId) {
+    if (this._callbacks[aId])
+      delete this._callbacks[aId];
+  },
+  
+  _getRandomId: function() {
+    return Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString();
+  },
+
+  _convertAppsArray: function(aApps) {
+    let apps = new Array();
+    for (let i = 0; i < aApps.length; i++) {
+      let app = aApps[i];
+      apps.push(new WebappsApplication(app.origin, app.manifest, app.receipt, app.installOrigin, app.installTime));
+    }
+    return apps;
+  },
+
+  set oninstall(aCallback) {
+    if (this.hasPrivileges)
+      this._oninstall = aCallback;
+    else
+      throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+  },
+  
+  set onuninstall(aCallback) {
+    if (this.hasPrivileges)
+      this._onuninstall = aCallback;
+    else
+      throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+  },
+
+  set onerror(aCallback) {
+    this._onerror = aCallback;
+  },
+
+  receiveMessage: function(aMessage) {
+    let msg = aMessage.json;
+    if (!(msg.oid == this._id || aMessage.name == "Webapps:Install:Return:OK" || aMessage.name == "Webapps:Uninstall:Return:OK"))
+      return
+    let app = msg.app;
+    let cb;
+    switch (aMessage.name) {
+      case "Webapps:Install:Return:OK":
+        if (this._oninstall)
+          this._oninstall.handleEvent(new WebappsApplication(app.origin, app.manifest, app.receipt,
+                                                app.installOrigin, app.installTime));
+        break;
+      case "Webapps:Install:Return:KO":
+        if (this._onerror)
+          this._onerror.handleEvent(new RegistryError(Ci.mozIDOMApplicationRegistryError.DENIED));
+        break;
+      case "Webapps:Uninstall:Return:OK":
+        if (this._onuninstall)
+          this._onuninstall.handleEvent(new WebappsApplication(msg.origin, null, null, null, 0));
+        break;
+      case "Webapps:Uninstall:Return:KO":
+        if (this._onerror)
+          this._onerror.handleEvent(new RegistryError(Ci.mozIDOMApplicationRegistryError.PERMISSION_DENIED));
+        break;
+      case "Webapps:Enumerate:Return:OK":
+        cb = this.getCallback(msg.callbackID);
+        if (cb.success) {
+          let apps = this._convertAppsArray(msg.apps);
+          cb.success.handleEvent(apps, apps.length);
+        }
+        break;
+      case "Webapps:Enumerate:Return:KO":
+        cb = this.getCallback(msg.callbackID);
+        if (cb.error)
+          cb.error.handleEvent(new RegistryError(Ci.mozIDOMApplicationRegistryError.PERMISSION_DENIED));
+        break;
+    }
+    this.removeCallback(msg.callbackID);
+  },
+  
+  _fireError: function(aCode) {
+    if (!this._onerror)
+      return;
+    this._onerror.handleEvent(new RegistryError(aCode));
+  },
+
+  _getOrigin: function(aURL) {
+    let uri = Services.io.newURI(aURL, null, null);
+    return uri.prePath; 
+  },
+
+  // mozIDOMApplicationRegistry implementation
+  
+  install: function(aURL, aReceipt) {
+    let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
+    xhr.open("GET", aURL, true);
+
+    xhr.addEventListener("load", (function() {
+      if (xhr.status == 200) {
+        try {
+          let installOrigin = this._getOrigin(this._window.location.href);
+          let manifest = JSON.parse(xhr.responseText, installOrigin);
+          if (!this.checkManifest(manifest, installOrigin)) {
+            this._fireError(Ci.mozIDOMApplicationRegistryError.INVALID_MANIFEST);
+          } else {
+            this.mm.sendAsyncMessage("Webapps:Install", { app: { installOrigin: installOrigin,
+                                                          origin: this._getOrigin(aURL),
+                                                          manifest: manifest,
+                                                          receipt: aReceipt },
+                                                          from: this._window.location.href,
+                                                          oid: this._id });
+          }
+        } catch(e) {
+          this._fireError(Ci.mozIDOMApplicationRegistryError.MANIFEST_PARSE_ERROR);
+        }
+      }
+      else {
+        this._fireError(Ci.mozIDOMApplicationRegistryError.MANIFEST_URL_ERROR);
+      }      
+    }).bind(this), false);
+
+    xhr.addEventListener("error", (function() {
+      this._fireError(Ci.mozIDOMApplicationRegistryError.NETWORK_ERROR);
+    }).bind(this), false);
+
+    xhr.send(null);
+  },
+
+  uninstall: function(aOrigin) {
+    if (this.hasPrivileges)
+      this.mm.sendAsyncMessage("Webapps:Uninstall", { from: this._window.location.href,
+                                                      origin: aOrigin,
+                                                      oid: this._id });
+    else
+      throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+  },
+
+  launch: function(aOrigin) {
+    this.mm.sendAsyncMessage("Webapps:Launch", { origin: aOrigin,
+                                                 from: this._window.location.href});
+  },
+  
+  enumerate: function(aSuccess, aError) {
+    this.mm.sendAsyncMessage("Webapps:Enumerate", { from: this._window.location.href,
+                                                    origin: this._getOrigin(this._window.location.href),
+                                                    oid: this._id,
+                                                    callbackID:  this.getCallbackId({ success: aSuccess, error: aError }) });
+  },
+
+  handleEvent: function(aEvent) {
+    if (aEvent.type == "unload") {
+      // remove all callbacks and event handlers so we don't call anything on a cleared scope
+      try {
+        this._oninstall = null;
+        this._onuninstall = null;
+        this._onerror = null;
+        this._callbacks = [];
+      } catch(e) {
+        dump("WebappsRegistry error:" + e + "\n");
+      }
+    }
+  },
+  
+  // nsIDOMGlobalPropertyInitializer implementation
+  init: function(aWindow) {
+    dump("DOMApplicationRegistry::init() " + aWindow + "\n");
+    this._window = aWindow;
+    this._window.addEventListener("unload", this, false);
+    this._window.appId = this._id;
+    let from = Services.io.newURI(this._window.location.href, null, null);
+    let perm = Services.perms.testExactPermission(from, "webapps-manage");
+
+    //only pages with perm set and chrome or about pages can uninstall, enumerate all set oninstall an onuninstall
+    this.hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION || from.schemeIs("chrome") || from.schemeIs("about");
+  },
+  
+  classID: Components.ID("{fff440b3-fae2-45c1-bf03-3b5a2e432270}"),
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationRegistry, Ci.nsIDOMGlobalPropertyInitializer]),
+  
+  classInfo: XPCOMUtils.generateCI({classID: Components.ID("{fff440b3-fae2-45c1-bf03-3b5a2e432270}"),
+                                    contractID: "@mozilla.org/webapps;1",
+                                    interfaces: [Ci.mozIDOMApplicationRegistry],
+                                    flags: Ci.nsIClassInfo.DOM_OBJECT,
+                                    classDescription: "Webapps Registry"})
+}
+
+function WebappsApplication(aOrigin, aManifest, aReceipt, aInstallOrigin, aInstallTime) {
+  this._origin = aOrigin;
+  this._manifest = aManifest;
+  this._receipt = aReceipt;
+  this._installOrigin = aInstallOrigin;
+  this._installTime = aInstallTime;
+}
+
+WebappsApplication.prototype = {
+  _origin: null,
+  _manifest: null,
+  _receipt: null,
+  _installOrigin: null,
+  _installTime: 0,
+
+  get origin() {
+    return this._origin;
+  },
+
+  get manifest() {
+    return this._manifest;
+  },
+
+  get receipt() {
+    return this._receipt;
+  },
+
+  get installOrigin() {
+    return this._installOrigin;
+  },
+  
+  get installTime() {
+    return this._installTime;
+  },
+
+  classID: Components.ID("{723ed303-7757-4fb0-b261-4f78b1f6bd22}"),
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplication]),
+
+  classInfo: XPCOMUtils.generateCI({classID: Components.ID("{723ed303-7757-4fb0-b261-4f78b1f6bd22}"),
+                                    contractID: "@mozilla.org/webapps/application;1",
+                                    interfaces: [Ci.mozIDOMApplication],
+                                    flags: Ci.nsIClassInfo.DOM_OBJECT,
+                                    classDescription: "Webapps Application"})
+}
+
+function RegistryError(aCode) {
+  this._code = aCode;
+}
+
+RegistryError.prototype = {
+  _code: null,
+  
+  get code() {
+    return this._code;
+  },
+  
+  classID: Components.ID("{b4937718-11a3-400b-a69f-ab442a418569}"),
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationRegistryError]),
+
+  classInfo: XPCOMUtils.generateCI({classID: Components.ID("{b4937718-11a3-400b-a69f-ab442a418569}"),
+                                    contractID: "@mozilla.org/webapps/error;1",
+                                    interfaces: [Ci.mozIDOMApplicationRegistryError],
+                                    flags: Ci.nsIClassInfo.DOM_OBJECT,
+                                    classDescription: "Webapps Registry Error"})
+}
+
+const NSGetFactory = XPCOMUtils.generateNSGetFactory([WebappsRegistry, WebappsApplication, RegistryError]);
new file mode 100644
--- /dev/null
+++ b/dom/base/Webapps.jsm
@@ -0,0 +1,380 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Mobile Browser.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Fabrice Desré <fabrice@mozilla.com>
+ *   Mark Finkle <mfinkle@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Cu = Components.utils; 
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+let EXPORTED_SYMBOLS = ["DOMApplicationRegistry", "DOMApplicationManifest"];
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
+  Cu.import("resource://gre/modules/NetUtil.jsm");
+  return NetUtil;
+});
+
+let DOMApplicationRegistry = {
+  appsDir: null,
+  appsFile: null,
+  webapps: { },
+
+  init: function() {
+    this.mm = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
+    let messages = ["Webapps:Install", "Webapps:Uninstall",
+                    "Webapps:Enumerate", "Webapps:Launch"];
+
+    messages.forEach((function(msgName) {
+      this.mm.addMessageListener(msgName, this);
+    }).bind(this));
+
+    let file =  Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties).get("ProfD", Ci.nsIFile);
+    file.append("webapps");
+    if (!file.exists() || !file.isDirectory()) {
+      file.create(Ci.nsIFile.DIRECTORY_TYPE, 0700);
+    }
+    this.appsDir = file;
+    this.appsFile = file.clone();
+    this.appsFile.append("webapps.json");
+    if (!this.appsFile.exists())
+      return;
+    
+    try {
+      let channel = NetUtil.newChannel(this.appsFile);
+      channel.contentType = "application/json";
+      let self = this;
+      NetUtil.asyncFetch(channel, function(aStream, aResult) {
+        if (!Components.isSuccessCode(aResult)) {
+          Cu.reportError("DOMApplicationRegistry: Could not read from json file " + this.appsFile.path);
+          return;
+        }
+
+        // Read json file into a string
+        let data = null;
+        try {
+          self.webapps = JSON.parse(NetUtil.readInputStreamToString(aStream, aStream.available()) || "");
+          aStream.close();
+        } catch (ex) {
+          Cu.reportError("DOMApplicationRegistry: Could not parse JSON: " + ex);
+        }
+      });
+    } catch (ex) {
+      Cu.reportError("DOMApplicationRegistry: Could not read from " + aFile.path + " : " + ex);
+    }
+  },
+
+  receiveMessage: function(aMessage) {
+    let msg = aMessage.json;
+    let from = Services.io.newURI(msg.from, null, null);
+    let perm = Services.perms.testExactPermission(from, "webapps-manage");
+
+    //only pages with perm set and chrome or about pages can uninstall, enumerate all set oninstall an onuninstall
+    let hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION || from.schemeIs("chrome") || from.schemeIs("about");
+
+    switch (aMessage.name) {
+      case "Webapps:Install":
+        // always ask for UI to install
+        Services.obs.notifyObservers(this, "webapps-ask-install", JSON.stringify(msg));
+        break;
+      case "Webapps:Uninstall":
+        if (hasPrivileges)
+          this.uninstall(msg);
+        break;
+      case "Webapps:Launch":
+        Services.obs.notifyObservers(this, "webapps-launch", JSON.stringify(msg));
+        break;
+      case "Webapps:Enumerate":
+        if (hasPrivileges)
+          this.enumerateAll(msg)
+        else
+          this.enumerate(msg);
+        break;
+    }
+  },
+
+  _writeFile: function ss_writeFile(aFile, aData, aCallbak) {
+    // Initialize the file output stream.
+    let ostream = Cc["@mozilla.org/network/safe-file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
+    ostream.init(aFile, 0x02 | 0x08 | 0x20, 0600, ostream.DEFER_OPEN);
+
+    // Obtain a converter to convert our data to a UTF-8 encoded input stream.
+    let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
+    converter.charset = "UTF-8";
+
+    // Asynchronously copy the data to the file.
+    let istream = converter.convertToInputStream(aData);
+    NetUtil.asyncCopy(istream, ostream, function(rc) {
+      if (aCallbak)
+        aCallbak();
+    });
+  },
+  
+  // clones a app object, without the manifest
+  _cloneAppObject: function(aApp) {
+    let clone = {
+      installOrigin: aApp.installOrigin,
+      origin: aApp.origin,
+      receipt: aApp.receipt,
+      installTime: aApp.installTime
+    };
+    return clone;
+  },
+  
+  denyInstall: function(aData) {
+    this.mm.sendAsyncMessage("Webapps:Install:Return:KO", aData);
+  },
+  
+  confirmInstall: function(aData) {
+    let app = aData.app;
+    let id = this._appId(app.origin);
+
+    // install an application again is considered as an update
+    if (id) {
+      let dir = this.appsDir.clone();
+      dir.append(id);
+      try {
+        dir.remove(true);
+      } catch(e) {
+      }
+    }
+    else {
+      let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
+      id = uuidGenerator.generateUUID().toString();
+    }
+
+    let dir = this.appsDir.clone();
+    dir.append(id);
+    dir.create(Ci.nsIFile.DIRECTORY_TYPE, 0700);
+    
+    let manFile = dir.clone();
+    manFile.append("manifest.json");
+    this._writeFile(manFile, JSON.stringify(app.manifest));
+
+    this.webapps[id] = this._cloneAppObject(app);
+    delete this.webapps[id].manifest;
+    this.webapps[id].installTime = (new Date()).getTime()
+
+    this._writeFile(this.appsFile, JSON.stringify(this.webapps), (function() {
+      this.mm.sendAsyncMessage("Webapps:Install:Return:OK", aData);
+    }).bind(this));
+  },
+ 
+  _appId: function(aURI) {
+    for (let id in this.webapps) {
+      if (this.webapps[id].origin == aURI)
+        return id;
+    }
+    return null;
+  },
+
+  _readManifest: function(aId) {
+    let file = this.appsDir.clone();
+    file.append(aId);
+    file.append("manifest.json");
+    let data = "";  
+    let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
+    var cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
+    fstream.init(file, -1, 0, 0);
+    cstream.init(fstream, "UTF-8", 0, 0);
+    let (str = {}) {  
+      let read = 0;  
+      do {   
+        read = cstream.readString(0xffffffff, str); // read as much as we can and put it in str.value  
+        data += str.value;  
+      } while (read != 0);  
+    }  
+    cstream.close(); // this closes fstream  
+    try {
+      return JSON.parse(data);
+    } catch(e) {
+      return null;
+    }
+  },
+  
+  uninstall: function(aData) {
+    for (let id in this.webapps) {
+      let app = this.webapps[id];
+      if (app.origin == aData.origin) {
+        delete this.webapps[id];
+        this._writeFile(this.appsFile, JSON.stringify(this.webapps));
+        let dir = this.appsDir.clone();
+        dir.append(id);
+        try {
+          dir.remove(true);
+        } catch (e) {
+        }
+        this.mm.sendAsyncMessage("Webapps:Uninstall:Return:OK", aData);
+      }
+    }
+  },
+  
+  enumerate: function(aData) {
+    aData.apps = [];
+
+    let id = this._appId(aData.origin);
+    // if it's an app, add itself to the result
+    if (id) {
+      let app = this._cloneAppObject(this.webapps[id]);
+      app.manifest = this._readManifest(id);
+      aData.apps.push(app);
+    }
+
+    // check if it's a store.
+    let isStore = false;
+    for (id in this.webapps) {
+      let app = this._cloneAppObject(this.webapps[id]);
+      if (app.installOrigin == aData.origin) {
+        isStore = true;
+        break;
+      }
+    }
+
+    // add all the apps from this store
+    if (isStore) {
+      for (id in this.webapps) {
+        let app = this._cloneAppObject(this.webapps[id]);
+        if (app.installOrigin == aData.origin) {
+          app.manifest = this._readManifest(id);
+          aData.apps.push(app);
+        }
+      }
+    }
+
+    this.mm.sendAsyncMessage("Webapps:Enumerate:Return:OK", aData);
+  },
+
+  denyEnumerate: function(aData) {
+    this.mm.sendAsyncMessage("Webapps:Enumerate:Return:KO", aData);
+  },
+
+  enumerateAll: function(aData) {
+    aData.apps = [];
+
+    for (id in this.webapps) {
+      let app = this._cloneAppObject(this.webapps[id]);
+      app.manifest = this._readManifest(id);
+      aData.apps.push(app);
+    }
+
+    this.mm.sendAsyncMessage("Webapps:Enumerate:Return:OK", aData);
+  },
+
+  getManifestFor: function(aOrigin) {
+    let id = this._appId(aOrigin);
+    if (!id)
+      return null;
+    return this._readManifest(id);
+  }
+};
+
+/**
+ * Helper object to access manifest information with locale support
+ */
+DOMApplicationManifest = function(aManifest, aOrigin) {
+  this._origin = Services.io.newURI(aOrigin, null, null);
+  this._manifest = aManifest;
+  let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry)
+                                                          .QueryInterface(Ci.nsIToolkitChromeRegistry);
+  let locale = chrome.getSelectedLocale("browser").toLowerCase();
+  this._localeRoot = this._manifest;
+  
+  if (this._manifest.locales && this._manifest.locales[locale]) {
+    this._localeRoot = this._manifest.locales[locale];
+  }
+  else if (this._manifest.locales) {
+    // try with the language part of the locale ("en" for en-GB) only
+    let lang = locale.split('-')[0];
+    if (land != locale && this._manifest.locales[lang])
+      this._localeRoot = this._manifest.locales[lang];
+  }
+}
+
+DOMApplicationManifest.prototype = {
+  _localeProp: function(aProp) {
+    if (this._localeRoot[aProp] != undefined)
+      return this._localeRoot[aProp];
+    return this._manifest[aProp];
+  },
+
+  get name() {
+    return this._localeProp("name");
+  },
+  
+  get description() {
+    return this._localeProp("description");
+  },
+  
+  get version() {
+    return this._localeProp("version");
+  },
+  
+  get launch_path() {
+    return this._localeProp("launch_path");
+  },
+  
+  get developer() {
+    return this._localeProp("developer");
+  },
+  
+  get icons() {
+    return this._localeProp("icons");
+  },
+  
+  iconURLForSize: function(aSize) {
+    let icons = this._localeProp("icons");
+    if (!icons)
+      return null;
+    let dist = 100000;
+    let icon = null;
+    for (let size in icons) {
+      let iSize = parseInt(size);
+      if (Math.abs(iSize - aSize) < dist) {
+        icon = this._origin.resolve(icons[size]);
+        dist = Math.abs(iSize - aSize);
+      }
+    }
+    return icon;
+  },
+  
+  fullLaunchPath: function() {
+    let launchPath = this._localeProp("launch_path");
+    return this._origin.resolve(launchPath ? launchPath : "");
+  }
+}
+
+DOMApplicationRegistry.init();
new file mode 100644
--- /dev/null
+++ b/dom/base/Webapps.manifest
@@ -0,0 +1,10 @@
+# Webapps.js
+component {fff440b3-fae2-45c1-bf03-3b5a2e432270} Webapps.js
+contract @mozilla.org/webapps;1 {fff440b3-fae2-45c1-bf03-3b5a2e432270}
+category JavaScript-navigator-property mozApps @mozilla.org/webapps;1
+
+component {723ed303-7757-4fb0-b261-4f78b1f6bd22} Webapps.js
+contract @mozilla.org/webapps/application;1 {723ed303-7757-4fb0-b261-4f78b1f6bd22}
+
+component {b4937718-11a3-400b-a69f-ab442a418569} Webapps.js
+contract @mozilla.org/webapps/error;1 {b4937718-11a3-400b-a69f-ab442a418569}
--- a/dom/base/nsDOMScriptObjectHolder.h
+++ b/dom/base/nsDOMScriptObjectHolder.h
@@ -81,26 +81,36 @@ public:
     return !mObject;
   }
   operator void *() const {
     return mObject;
   }
   JSScript* getScript() const {
     return static_cast<JSScript*>(mObject);
   }
+  JSObject* getObject() const {
+    return static_cast<JSObject*>(mObject);
+  }
 
   // Drop the script object - but *not* the nsIScriptContext.
   nsresult drop() {
     nsresult rv = NS_OK;
     if (mObject) {
       rv = mContext->DropScriptObject(mObject);
       mObject = nsnull;
     }
     return rv;
   }
+
+  nsresult setScript(JSScript* aScript) {
+    return set(aScript);
+  }
+  nsresult setObject(JSObject* aObject) {
+    return set(aObject);
+  }
   nsresult set(void *object) {
     NS_ASSERTION(getScriptTypeID() != nsIProgrammingLanguage::UNKNOWN,
                  "Must know the language!");
     nsresult rv = drop();
     if (NS_FAILED(rv))
       return rv;
     if (object) {
       rv = mContext->HoldScriptObject(object);
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -81,16 +81,17 @@
 
 #include "Layers.h"
 #include "nsIIOService.h"
 
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::layers;
+using namespace mozilla::widget;
 
 static bool IsUniversalXPConnectCapable()
 {
   bool hasCap = false;
   nsresult rv = nsContentUtils::GetSecurityManager()->
                   IsCapabilityEnabled("UniversalXPConnect", &hasCap);
   NS_ENSURE_SUCCESS(rv, false);
   return hasCap;
@@ -1034,56 +1035,53 @@ nsDOMWindowUtils::GetIMEIsOpen(bool *aSt
 {
   NS_ENSURE_ARG_POINTER(aState);
 
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget)
     return NS_ERROR_FAILURE;
 
   // Open state should not be available when IME is not enabled.
-  IMEContext context;
-  nsresult rv = widget->GetInputMode(context);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (context.mStatus != nsIWidget::IME_STATUS_ENABLED)
+  InputContext context = widget->GetInputContext();
+  if (context.mIMEState.mEnabled != IMEState::ENABLED) {
     return NS_ERROR_NOT_AVAILABLE;
+  }
 
-  return widget->GetIMEOpenState(aState);
+  if (context.mIMEState.mOpen == IMEState::OPEN_STATE_NOT_SUPPORTED) {
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+  *aState = (context.mIMEState.mOpen == IMEState::OPEN);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetIMEStatus(PRUint32 *aState)
 {
   NS_ENSURE_ARG_POINTER(aState);
 
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget)
     return NS_ERROR_FAILURE;
 
-  IMEContext context;
-  nsresult rv = widget->GetInputMode(context);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *aState = context.mStatus;
+  InputContext context = widget->GetInputContext();
+  *aState = static_cast<PRUint32>(context.mIMEState.mEnabled);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetFocusedInputType(char** aType)
 {
   NS_ENSURE_ARG_POINTER(aType);
 
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget) {
     return NS_ERROR_FAILURE;
   }
 
-  IMEContext context;
-  nsresult rv = widget->GetInputMode(context);
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  InputContext context = widget->GetInputContext();
   *aType = ToNewCString(context.mHTMLInputType);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::FindElementWithViewId(nsViewID aID,
                                         nsIDOMElement** aResult)
 {
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -67,17 +67,16 @@
 #include "nsIContentViewer.h"
 #include "nsFrameTraversal.h"
 #include "nsObjectFrame.h"
 #include "nsEventDispatcher.h"
 #include "nsEventStateManager.h"
 #include "nsIMEStateManager.h"
 #include "nsIWebNavigation.h"
 #include "nsCaret.h"
-#include "nsIWidget.h"
 #include "nsIBaseWindow.h"
 #include "nsIViewManager.h"
 #include "nsFrameSelection.h"
 #include "nsXULPopupManager.h"
 #include "nsIDOMNodeFilter.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIPrincipal.h"
 #include "mozilla/dom/Element.h"
@@ -91,16 +90,17 @@
 #endif
 
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::dom;
+using namespace mozilla::widget;
 
 //#define DEBUG_FOCUS 1
 //#define DEBUG_FOCUS_NAVIGATION 1
 #define PRINTTAGF(format, content)                     \
   {                                                    \
     nsAutoString tag(NS_LITERAL_STRING("(none)"));     \
     if (content)                                       \
       content->Tag()->ToString(tag);                   \
@@ -332,29 +332,25 @@ nsFocusManager::GetRedirectedFocus(nsICo
     }
   }
 #endif
 
   return nsnull;
 }
 
 // static
-PRUint32
-nsFocusManager::GetFocusMoveReason(PRUint32 aFlags)
+InputContextAction::Cause
+nsFocusManager::GetFocusMoveActionCause(PRUint32 aFlags)
 {
-  PRUint32 reason = IMEContext::FOCUS_MOVED_UNKNOWN;
   if (aFlags & nsIFocusManager::FLAG_BYMOUSE) {
-    reason = IMEContext::FOCUS_MOVED_BY_MOUSE;
+    return InputContextAction::CAUSE_MOUSE;
   } else if (aFlags & nsIFocusManager::FLAG_BYKEY) {
-    reason = IMEContext::FOCUS_MOVED_BY_KEY;
-  } else if (aFlags & nsIFocusManager::FLAG_BYMOVEFOCUS) {
-    reason = IMEContext::FOCUS_MOVED_BY_MOVEFOCUS;
+    return InputContextAction::CAUSE_KEY;
   }
-
-  return reason;
+  return InputContextAction::CAUSE_UNKNOWN;
 }
 
 NS_IMETHODIMP
 nsFocusManager::GetActiveWindow(nsIDOMWindow** aWindow)
 {
   NS_IF_ADDREF(*aWindow = mActiveWindow);
   return NS_OK;
 }
@@ -959,17 +955,18 @@ nsFocusManager::WindowHidden(nsIDOMWindo
   }
 
   nsCOMPtr<nsIDocShell> focusedDocShell = mFocusedWindow->GetDocShell();
   nsCOMPtr<nsIPresShell> presShell;
   focusedDocShell->GetPresShell(getter_AddRefs(presShell));
 
   nsIMEStateManager::OnTextStateBlur(nsnull, nsnull);
   if (presShell) {
-    nsIMEStateManager::OnChangeFocus(presShell->GetPresContext(), nsnull, IMEContext::FOCUS_REMOVED);
+    nsIMEStateManager::OnChangeFocus(presShell->GetPresContext(), nsnull,
+                                     GetFocusMoveActionCause(0));
     SetCaretVisible(presShell, false, nsnull);
   }
 
   // if the docshell being hidden is being destroyed, then we want to move
   // focus somewhere else. Call ClearFocus on the toplevel window, which
   // will have the effect of clearing the focus and moving the focused window
   // to the toplevel window. But if the window isn't being destroyed, we are
   // likely just loading a new document in it, so we want to maintain the
@@ -1518,18 +1515,20 @@ nsFocusManager::Blur(nsPIDOMWindow* aWin
     mFirstBlurEvent = content;
     clearFirstBlurEvent = true;
   }
 
   // if there is still an active window, adjust the IME state.
   // This has to happen before the focus is cleared below, otherwise, the IME
   // compositionend event won't get fired at the element being blurred.
   nsIMEStateManager::OnTextStateBlur(nsnull, nsnull);
-  if (mActiveWindow)
-    nsIMEStateManager::OnChangeFocus(presShell->GetPresContext(), nsnull, IMEContext::FOCUS_REMOVED);
+  if (mActiveWindow) {
+    nsIMEStateManager::OnChangeFocus(presShell->GetPresContext(), nsnull,
+                                     GetFocusMoveActionCause(0));
+  }
 
   // now adjust the actual focus, by clearing the fields in the focus manager
   // and in the window.
   mFocusedContent = nsnull;
   bool shouldShowFocusRing = window->ShouldShowFocusRing();
   if (aWindowToClear)
     aWindowToClear->SetFocusedNode(nsnull);
 
@@ -1781,34 +1780,35 @@ nsFocusManager::Focus(nsPIDOMWindow* aWi
         if (remote) {
           remote->Activate();
 #ifdef DEBUG_FOCUS
           printf("*Remote browser activated\n");
 #endif
         }
       }
 
-      PRUint32 reason = GetFocusMoveReason(aFlags);
-      nsIMEStateManager::OnChangeFocus(presContext, aContent, reason);
+      nsIMEStateManager::OnChangeFocus(presContext, aContent,
+                                       GetFocusMoveActionCause(aFlags));
 
       // as long as this focus wasn't because a window was raised, update the
       // commands
       // XXXndeakin P2 someone could adjust the focus during the update
       if (!aWindowRaised)
         aWindow->UpdateCommands(NS_LITERAL_STRING("focus"));
 
       SendFocusOrBlurEvent(NS_FOCUS_CONTENT, presShell,
                            aContent->GetCurrentDoc(),
                            aContent, aFlags & FOCUSMETHOD_MASK,
                            aWindowRaised, isRefocus);
 
       nsIMEStateManager::OnTextStateFocus(presContext, aContent);
     } else {
       nsIMEStateManager::OnTextStateBlur(presContext, nsnull);
-      nsIMEStateManager::OnChangeFocus(presContext, nsnull, IMEContext::FOCUS_REMOVED);
+      nsIMEStateManager::OnChangeFocus(presContext, nsnull,
+                                       GetFocusMoveActionCause(aFlags));
       if (!aWindowRaised) {
         aWindow->UpdateCommands(NS_LITERAL_STRING("focus"));
       }
     }
   }
   else {
     // If the window focus event (fired above when aIsNewDocument) caused
     // the plugin not to be focusable, update the system focus by focusing
@@ -1821,17 +1821,18 @@ nsFocusManager::Focus(nsPIDOMWindow* aWi
         vm->GetRootWidget(getter_AddRefs(widget));
         if (widget)
           widget->SetFocus(false);
       }
     }
 
     nsPresContext* presContext = presShell->GetPresContext();
     nsIMEStateManager::OnTextStateBlur(presContext, nsnull);
-    nsIMEStateManager::OnChangeFocus(presContext, nsnull, IMEContext::FOCUS_REMOVED);
+    nsIMEStateManager::OnChangeFocus(presContext, nsnull,
+                                     GetFocusMoveActionCause(aFlags));
 
     if (!aWindowRaised)
       aWindow->UpdateCommands(NS_LITERAL_STRING("focus"));
   }
 
   // update the caret visibility and position to match the newly focused
   // element. However, don't update the position if this was a focus due to a
   // mouse click as the selection code would already have moved the caret as
--- a/dom/base/nsFocusManager.h
+++ b/dom/base/nsFocusManager.h
@@ -36,16 +36,17 @@
 
 #ifndef nsFocusManager_h___
 #define nsFocusManager_h___
 
 #include "nsIFocusManager.h"
 #include "nsWeakReference.h"
 #include "nsIObserver.h"
 #include "nsIContent.h"
+#include "nsIWidget.h"
 
 #define FOCUSMETHOD_MASK 0xF000
 #define FOCUSMETHODANDRING_MASK 0xF0F000
 
 #define FOCUSMANAGER_CONTRACTID "@mozilla.org/focus-manager;1"
 
 class nsIDocShellTreeItem;
 class nsPIDOMWindow;
@@ -62,16 +63,18 @@ struct nsDelayedBlurOrFocusEvent;
  * The focus manager keeps track of where the focus is, that is, the node
  * which receives key events.
  */
 
 class nsFocusManager : public nsIFocusManager,
                        public nsIObserver,
                        public nsSupportsWeakReference
 {
+  typedef mozilla::widget::InputContextAction InputContextAction;
+
 public:
 
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFocusManager, nsIFocusManager)
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_NSIOBSERVER
   NS_DECL_NSIFOCUSMANAGER
 
   // called to initialize and stop the focus manager at startup and shutdown
@@ -126,21 +129,19 @@ public:
    * aContent must be non-null.
    *
    * XXXndeakin this should be removed eventually but I want to do that as
    * followup work.
    */
   static nsIContent* GetRedirectedFocus(nsIContent* aContent);
 
   /**
-   * Returns a flag indicating the source and/or reason of the focus change.
-   * This is used to indicate to the IME code if the focus come from a user 
-   * input or a script for example.
+   * Returns an InputContextAction cause for aFlags.
    */
-  static PRUint32 GetFocusMoveReason(PRUint32 aFlags);
+  static InputContextAction::Cause GetFocusMoveActionCause(PRUint32 aFlags);
 
   static bool sMouseFocusesFormControl;
 
 protected:
 
   nsFocusManager();
   ~nsFocusManager();
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1487,17 +1487,17 @@ struct TraceData
   TraceData(TraceCallback& aCallback, void* aClosure) :
     callback(aCallback), closure(aClosure) {}
 
   TraceCallback& callback;
   void* closure;
 };
 
 static PLDHashOperator
-TraceXBLHandlers(const void* aKey, void* aData, void* aClosure)
+TraceXBLHandlers(const void* aKey, JSObject* aData, void* aClosure)
 {
   TraceData* data = static_cast<TraceData*>(aClosure);
   data->callback(nsIProgrammingLanguage::JAVASCRIPT, aData,
                  "Cached XBL prototype handler", data->closure);
   return PL_DHASH_NEXT;
 }
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGlobalWindow)
@@ -2072,23 +2072,22 @@ nsGlobalWindow::SetNewDocument(nsIDocume
       // cx->globalObject, i.e. this outer window].
 
       mInnerWindow = nsnull;
 
       Freeze();
       mCreatingInnerWindow = true;
       // Every script context we are initialized with must create a
       // new global.
-      void *&newGlobal = (void *&)newInnerWindow->mJSObject;
       nsCOMPtr<nsIXPConnectJSObjectHolder> &holder = mInnerWindowHolder;
       rv = mContext->CreateNativeGlobalForInner(sgo, isChrome,
                                                 aDocument->NodePrincipal(),
-                                                &newGlobal,
+                                                &newInnerWindow->mJSObject,
                                                 getter_AddRefs(holder));
-      NS_ASSERTION(NS_SUCCEEDED(rv) && newGlobal && holder,
+      NS_ASSERTION(NS_SUCCEEDED(rv) && newInnerWindow->mJSObject && holder,
                    "Failed to get script global and holder");
 
       mCreatingInnerWindow = false;
       Thaw();
 
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
@@ -3953,26 +3952,26 @@ nsGlobalWindow::GetMozPaintCount(PRUint6
   if (!presShell)
     return NS_OK;
 
   *aResult = presShell->GetPaintCount();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsGlobalWindow::MozRequestAnimationFrame(nsIAnimationFrameListener* aListener)
-{
-  FORWARD_TO_INNER(MozRequestAnimationFrame, (aListener),
+nsGlobalWindow::MozRequestAnimationFrame(nsIFrameRequestCallback* aCallback)
+{
+  FORWARD_TO_INNER(MozRequestAnimationFrame, (aCallback),
                    NS_ERROR_NOT_INITIALIZED);
 
   if (!mDoc) {
     return NS_OK;
   }
 
-  mDoc->ScheduleBeforePaintEvent(aListener);
+  mDoc->ScheduleFrameRequestCallback(aCallback);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::GetMozAnimationStartTime(PRInt64 *aTime)
 {
   FORWARD_TO_INNER(GetMozAnimationStartTime, (aTime), NS_ERROR_NOT_INITIALIZED);
 
@@ -5555,25 +5554,33 @@ nsGlobalWindow::ScrollByPages(PRInt32 nu
     sf->ScrollBy(nsIntPoint(0, numPages), nsIScrollableFrame::PAGES,
                  nsIScrollableFrame::INSTANT);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsGlobalWindow::ClearTimeout()
-{
-  return ClearTimeoutOrInterval();
-}
-
-NS_IMETHODIMP
-nsGlobalWindow::ClearInterval()
-{
-  return ClearTimeoutOrInterval();
+nsGlobalWindow::ClearTimeout(PRInt32 aHandle)
+{
+  if (aHandle <= 0) {
+    return NS_OK;
+  }
+
+  return ClearTimeoutOrInterval(aHandle);
+}
+
+NS_IMETHODIMP
+nsGlobalWindow::ClearInterval(PRInt32 aHandle)
+{
+  if (aHandle <= 0) {
+    return NS_OK;
+  }
+
+  return ClearTimeoutOrInterval(aHandle);
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::SetTimeout(PRInt32 *_retval)
 {
   return SetTimeoutOrInterval(false, _retval);
 }
 
@@ -6925,20 +6932,20 @@ nsGlobalWindow::InitJavaProperties()
     return;
   }
 
   // No NPRuntime enabled Java plugin found, null out the owner we
   // would have used in that case as it's no longer needed.
   mDummyJavaPluginOwner = nsnull;
 }
 
-void*
+JSObject*
 nsGlobalWindow::GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey)
 {
-  void* handler = nsnull;
+  JSObject* handler = nsnull;
   if (mCachedXBLPrototypeHandlers.IsInitialized()) {
     mCachedXBLPrototypeHandlers.Get(aKey, &handler);
   }
   return handler;
 }
 
 void
 nsGlobalWindow::CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
@@ -6965,17 +6972,17 @@ nsGlobalWindow::CacheXBLPrototypeHandler
 
     nsresult rv = nsContentUtils::HoldJSObjects(thisSupports, participant);
     if (NS_FAILED(rv)) {
       NS_ERROR("nsContentUtils::HoldJSObjects failed!");
       return;
     }
   }
 
-  mCachedXBLPrototypeHandlers.Put(aKey, aHandler);
+  mCachedXBLPrototypeHandlers.Put(aKey, aHandler.getObject());
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::GetFrameElement(nsIDOMElement** aFrameElement)
 {
   FORWARD_TO_OUTER(GetFrameElement, (aFrameElement), NS_ERROR_NOT_INITIALIZED);
 
   *aFrameElement = nsnull;
@@ -9300,17 +9307,17 @@ nsGlobalWindow::RunTimeout(nsTimeout *aT
     bool trackNestingLevel = !timeout->mIsInterval;
     PRUint32 nestingLevel;
     if (trackNestingLevel) {
       nestingLevel = sNestingLevel;
       sNestingLevel = timeout->mNestingLevel;
     }
 
     nsCOMPtr<nsIScriptTimeoutHandler> handler(timeout->mScriptHandler);
-    void *scriptObject = handler->GetScriptObject();
+    JSObject* scriptObject = static_cast<JSObject*>(handler->GetScriptObject());
     if (!scriptObject) {
       // Evaluate the timeout expression.
       const PRUnichar *script = handler->GetHandlerText();
       NS_ASSERTION(script, "timeout has no script nor handler text!");
 
       const char *filename = nsnull;
       PRUint32 lineNo = 0;
       handler->GetLocation(&filename, &lineNo);
@@ -9644,68 +9651,16 @@ nsresult nsGlobalWindow::ResetTimersForN
     } else {
       timeout = timeout->Next();
     }
   }
 
   return NS_OK;
 }
 
-// A JavaScript specific version.
-nsresult
-nsGlobalWindow::ClearTimeoutOrInterval()
-{
-  FORWARD_TO_INNER(ClearTimeoutOrInterval, (), NS_ERROR_NOT_INITIALIZED);
-
-  nsresult rv = NS_OK;
-  nsAXPCNativeCallContext *ncc = nsnull;
-
-  rv = nsContentUtils::XPConnect()->
-    GetCurrentNativeCallContext(&ncc);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (!ncc)
-    return NS_ERROR_NOT_AVAILABLE;
-
-  JSContext *cx = nsnull;
-
-  rv = ncc->GetJSContext(&cx);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  PRUint32 argc;
-
-  ncc->GetArgc(&argc);
-
-  if (argc < 1) {
-    // No arguments, return early.
-
-    return NS_OK;
-  }
-
-  jsval *argv = nsnull;
-
-  ncc->GetArgvPtr(&argv);
-
-  int32 timer_id;
-
-  JSAutoRequest ar(cx);
-
-  // XXXjst: Can we deal with this w/o using GetCurrentNativeCallContext()
-  if (argv[0] == JSVAL_VOID || !::JS_ValueToInt32(cx, argv[0], &timer_id) ||
-      timer_id <= 0) {
-    // Undefined or non-positive number passed as argument, return
-    // early. Make sure that JS_ValueToInt32 didn't set an exception.
-
-    ::JS_ClearPendingException(cx);
-    return NS_OK;
-  }
-
-  return ClearTimeoutOrInterval(timer_id);
-}
-
 void
 nsGlobalWindow::ClearAllTimeouts()
 {
   nsTimeout *timeout, *nextTimeout;
 
   for (timeout = FirstTimeout(); IsTimeout(timeout); timeout = nextTimeout) {
     /* If RunTimeout() is higher up on the stack for this
        window, e.g. as a result of document.write from a timeout,
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -508,17 +508,17 @@ public:
 
   friend class WindowStateHolder;
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsGlobalWindow,
                                                          nsIScriptGlobalObject)
 
   void InitJavaProperties();
 
-  virtual NS_HIDDEN_(void*)
+  virtual NS_HIDDEN_(JSObject*)
     GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey);
 
   virtual NS_HIDDEN_(void)
     CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
                              nsScriptObjectHolder& aHandler);
 
   virtual bool TakeFocus(bool aFocus, PRUint32 aFocusMethod);
   virtual void SetReadyForFocus();
@@ -679,17 +679,16 @@ protected:
   // |interval| is in milliseconds.
   nsresult SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler,
                                 PRInt32 interval,
                                 bool aIsInterval, PRInt32 *aReturn);
   nsresult ClearTimeoutOrInterval(PRInt32 aTimerID);
 
   // JS specific timeout functions (JS args grabbed from context).
   nsresult SetTimeoutOrInterval(bool aIsInterval, PRInt32* aReturn);
-  nsresult ClearTimeoutOrInterval();
   nsresult ResetTimersForNonBackgroundWindow();
 
   // The timeout implementation functions.
   void RunTimeout(nsTimeout *aTimeout);
   void RunTimeout() { RunTimeout(nsnull); }
 
   void ClearAllTimeouts();
   // Insert aTimeout into the list, before all timeouts that would
@@ -971,17 +970,17 @@ protected:
   bool mSetOpenerWindowCalled;
   nsCOMPtr<nsIURI> mLastOpenedURI;
 #endif
 
   bool mCleanedUp, mCallCleanUpAfterModalDialogCloses;
 
   nsCOMPtr<nsIDOMOfflineResourceList> mApplicationCache;
 
-  nsDataHashtable<nsVoidPtrHashKey, void*> mCachedXBLPrototypeHandlers;
+  nsDataHashtable<nsVoidPtrHashKey, JSObject*> mCachedXBLPrototypeHandlers;
 
   nsCOMPtr<nsIDocument> mSuspendedDoc;
 
   nsCOMPtr<nsIIDBFactory> mIndexedDB;
 
   // In the case of a "trusted" dialog (@see PopupControlState), we
   // set this counter to ensure a max of MAX_DIALOG_LIMIT
   PRUint32                      mDialogAbuseCount;
--- a/dom/base/nsIJSEventListener.h
+++ b/dom/base/nsIJSEventListener.h
@@ -41,45 +41,54 @@
 #include "nsIScriptContext.h"
 #include "jsapi.h"
 #include "nsIDOMEventListener.h"
 
 class nsIScriptObjectOwner;
 class nsIAtom;
 
 #define NS_IJSEVENTLISTENER_IID \
-{ 0xafc5d047, 0xdb6b, 0x4076, \
-  { 0xb3, 0xfa, 0x57, 0x96, 0x1e, 0x21, 0x48, 0x42 } }
+{ 0x92f9212b, 0xa6aa, 0x4867, \
+  { 0x93, 0x8a, 0x56, 0xbe, 0x17, 0x67, 0x4f, 0xd4 } }
 
 // Implemented by script event listeners. Used to retrieve the
 // script object corresponding to the event target and the handler itself.
 // (Note this interface is now used to store script objects for all
 // script languages, so is no longer JS specific)
+//
+// Note, mTarget is a raw pointer and the owner of the nsIJSEventListener object
+// is expected to call Disconnect()!
 class nsIJSEventListener : public nsIDOMEventListener
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IJSEVENTLISTENER_IID)
 
   nsIJSEventListener(nsIScriptContext* aContext, JSObject* aScopeObject,
                      nsISupports *aTarget, JSObject *aHandler)
-    : mContext(aContext), mScopeObject(aScopeObject),
-      mTarget(do_QueryInterface(aTarget)), mHandler(aHandler)
+    : mContext(aContext), mScopeObject(aScopeObject), mHandler(aHandler)
   {
+    nsCOMPtr<nsISupports> base = do_QueryInterface(aTarget);
+    mTarget = base.get();
   }
 
   nsIScriptContext *GetEventContext() const
   {
     return mContext;
   }
 
   nsISupports *GetEventTarget() const
   {
     return mTarget;
   }
 
+  void Disconnect()
+  {
+    mTarget = nsnull;
+  }
+
   JSObject* GetEventScope() const
   {
     return mScopeObject;
   }
 
   JSObject *GetHandler() const
   {
     return mHandler;
@@ -89,24 +98,25 @@ public:
   // there is already a handler!  The handler must already be bound to
   // the right target.
   virtual void SetHandler(JSObject *aHandler) = 0;
 
   virtual PRInt64 SizeOf() const = 0;
 protected:
   virtual ~nsIJSEventListener()
   {
+    NS_ASSERTION(!mTarget, "Should have called Disconnect()!");
   }
   nsCOMPtr<nsIScriptContext> mContext;
   JSObject* mScopeObject;
-  nsCOMPtr<nsISupports> mTarget;
+  nsISupports* mTarget;
   JSObject *mHandler;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIJSEventListener, NS_IJSEVENTLISTENER_IID)
 
 /* factory function.  aHandler must already be bound to aTarget */
 nsresult NS_NewJSEventListener(nsIScriptContext *aContext,
                                JSObject* aScopeObject, nsISupports* aTarget,
                                nsIAtom* aType, JSObject* aHandler,
-                               nsIDOMEventListener **aReturn);
+                               nsIJSEventListener **aReturn);
 
 #endif // nsIJSEventListener_h__
--- a/dom/base/nsIScriptContext.h
+++ b/dom/base/nsIScriptContext.h
@@ -69,18 +69,18 @@ public:
 
   virtual nsIScriptObjectPrincipal* GetObjectPrincipal() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContextPrincipal,
                               NS_ISCRIPTCONTEXTPRINCIPAL_IID)
 
 #define NS_ISCRIPTCONTEXT_IID \
-{ 0x164ea909, 0x5cee, 0x4e20, \
-  { 0x9f, 0xed, 0x43, 0x13, 0xab, 0xac, 0x1c, 0xd3 } }
+{ 0x39b3ea7c, 0xdc26, 0x4756, \
+  { 0xa0, 0x3c, 0x13, 0xa0, 0x42, 0x03, 0x07, 0x6a } }
 
 /* This MUST match JSVERSION_DEFAULT.  This version stuff if we don't
    know what language we have is a little silly... */
 #define SCRIPTVERSION_DEFAULT JSVERSION_DEFAULT
 
 /**
  * It is used by the application to initialize a runtime and run scripts.
  * A script runtime would implement this interface.
@@ -216,17 +216,17 @@ public:
    * @param aScript an object telling the scope in which to call the compiled
    *        event handler function.
    * @param aHandler function object (function and static scope) to invoke.
    * @param argv array of arguments.  Note each element is assumed to
    *        be an nsIVariant.
    * @param rval out parameter returning result
    **/
   virtual nsresult CallEventHandler(nsISupports* aTarget,
-                                    JSObject* aScope, void* aHandler,
+                                    JSObject* aScope, JSObject* aHandler,
                                     nsIArray *argv, nsIVariant **rval) = 0;
 
   /**
    * Bind an already-compiled event handler function to the given
    * target.  Scripting languages with static scoping must re-bind the
    * scope chain for aHandler to begin (after the activation scope for
    * aHandler itself, typically) with aTarget's scope.
    *
@@ -242,36 +242,36 @@ public:
    *        looked for.
    * @param aHandler the function object to bind, created by an earlier call to
    *        CompileEventHandler
    * @param aBoundHandler [out] the result of the bind operation.
    * @return NS_OK if the function was successfully bound
    */
   virtual nsresult BindCompiledEventHandler(nsISupports* aTarget,
                                             JSObject* aScope,
-                                            void* aHandler,
+                                            JSObject* aHandler,
                                             nsScriptObjectHolder& aBoundHandler) = 0;
 
   /**
    * Compile a function that isn't used as an event handler.
    *
    * NOTE: Not yet language agnostic (main problem is XBL - not yet agnostic)
    * Caller must make sure aFunctionObject is a JS GC root.
    *
    **/
-  virtual nsresult CompileFunction(void* aTarget,
+  virtual nsresult CompileFunction(JSObject* aTarget,
                                    const nsACString& aName,
                                    PRUint32 aArgCount,
                                    const char** aArgArray,
                                    const nsAString& aBody,
                                    const char* aURL,
                                    PRUint32 aLineNo,
                                    PRUint32 aVersion,
                                    bool aShared,
-                                   void **aFunctionObject) = 0;
+                                   JSObject** aFunctionObject) = 0;
 
   /**
    * Set the default scripting language version for this context, which must
    * be a context specific to a particular scripting language.
    *
    **/
   virtual void SetDefaultLanguageVersion(PRUint32 aVersion) = 0;
 
@@ -297,26 +297,26 @@ public:
    * Create a new global object that will be used for an inner window.
    * Return the native global and an nsISupports 'holder' that can be used
    * to manage the lifetime of it.
    */
   virtual nsresult CreateNativeGlobalForInner(
                                       nsIScriptGlobalObject *aNewInner,
                                       bool aIsChrome,
                                       nsIPrincipal *aPrincipal,
-                                      void **aNativeGlobal,
+                                      JSObject** aNativeGlobal,
                                       nsISupports **aHolder) = 0;
 
   /**
    * Connect this context to a new inner window, to allow "prototype"
    * chaining from the inner to the outer.
    * Called after both the the inner and outer windows are initialized
    **/
   virtual nsresult ConnectToInner(nsIScriptGlobalObject *aNewInner,
-                                  void *aOuterGlobal) = 0;
+                                  JSObject *aOuterGlobal) = 0;
 
 
   /**
    * Initialize the context generally. Does not create a global object.
    **/
   virtual nsresult InitContext() = 0;
 
   /**
@@ -325,17 +325,17 @@ public:
    * @param aGlobalObject The script global object to use as our global.
    */
   virtual nsresult CreateOuterObject(nsIScriptGlobalObject *aGlobalObject,
                                      nsIScriptGlobalObject *aCurrentInner) = 0;
 
   /**
    * Given an outer object, updates this context with that outer object.
    */
-  virtual nsresult SetOuterObject(void *aOuterObject) = 0;
+  virtual nsresult SetOuterObject(JSObject* aOuterObject) = 0;
 
   /**
    * Prepares this context for use with the current inner window for the
    * context's global object. This must be called after CreateOuterObject.
    */
   virtual nsresult InitOuterWindow() = 0;
 
   /**
@@ -423,17 +423,17 @@ public:
   virtual void SetGCOnDestruction(bool aGCOnDestruction) = 0;
 
   /**
    * Initialize DOM classes on aGlobalObj, always call
    * WillInitializeContext() before calling InitContext(), and always
    * call DidInitializeContext() when a context is fully
    * (successfully) initialized.
    */
-  virtual nsresult InitClasses(void *aGlobalObj) = 0;
+  virtual nsresult InitClasses(JSObject* aGlobalObj) = 0;
 
   /**
    * Clear the scope object - may be called either as we are being torn down,
    * or before we are attached to a different document.
    *
    * aClearFromProtoChain is probably somewhat JavaScript specific.  It
    * indicates that the global scope polluter should be removed from the
    * prototype chain and that the objects in the prototype chain should
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -189,17 +189,17 @@ public:
 
 NS_IMPL_ISUPPORTS1(nsMemoryPressureObserver, nsIObserver)
 
 NS_IMETHODIMP
 nsMemoryPressureObserver::Observe(nsISupports* aSubject, const char* aTopic,
                                   const PRUnichar* aData)
 {
   if (sGCOnMemoryPressure) {
-    nsJSContext::GarbageCollectNow();
+    nsJSContext::GarbageCollectNow(true);
     nsJSContext::CycleCollectNow();
   }
   return NS_OK;
 }
 
 class nsRootedJSValueArray {
 public:
   explicit nsRootedJSValueArray(JSContext *cx) : avr(cx, vals.Length(), vals.Elements()) {}
@@ -924,18 +924,16 @@ static const char js_werror_option_str[]
 static const char js_relimit_option_str[]= JS_OPTIONS_DOT_STR "relimit";
 #ifdef JS_GC_ZEAL
 static const char js_zeal_option_str[]        = JS_OPTIONS_DOT_STR "gczeal";
 static const char js_zeal_frequency_str[]     = JS_OPTIONS_DOT_STR "gczeal.frequency";
 static const char js_zeal_compartment_str[]   = JS_OPTIONS_DOT_STR "gczeal.compartment_gc";
 #endif
 static const char js_methodjit_content_str[]  = JS_OPTIONS_DOT_STR "methodjit.content";
 static const char js_methodjit_chrome_str[]   = JS_OPTIONS_DOT_STR "methodjit.chrome";
-static const char js_profiling_content_str[]  = JS_OPTIONS_DOT_STR "jitprofiling.content";
-static const char js_profiling_chrome_str[]   = JS_OPTIONS_DOT_STR "jitprofiling.chrome";
 static const char js_methodjit_always_str[]   = JS_OPTIONS_DOT_STR "methodjit_always";
 static const char js_typeinfer_str[]          = JS_OPTIONS_DOT_STR "typeinference";
 static const char js_pccounts_content_str[]   = JS_OPTIONS_DOT_STR "pccounts.content";
 static const char js_pccounts_chrome_str[]    = JS_OPTIONS_DOT_STR "pccounts.chrome";
 static const char js_jit_hardening_str[]      = JS_OPTIONS_DOT_STR "jit_hardening";
 static const char js_memlog_option_str[] = JS_OPTIONS_DOT_STR "mem.log";
 
 int
@@ -956,49 +954,40 @@ nsJSContext::JSOptionChangedCallback(con
   nsIScriptGlobalObject *global = context->GetGlobalObject();
   // XXX should we check for sysprin instead of a chrome window, to make
   // XXX components be covered by the chrome pref instead of the content one?
   nsCOMPtr<nsIDOMChromeWindow> chromeWindow(do_QueryInterface(global));
 
   bool useMethodJIT = Preferences::GetBool(chromeWindow ?
                                                js_methodjit_chrome_str :
                                                js_methodjit_content_str);
-  bool useProfiling = Preferences::GetBool(chromeWindow ?
-                                               js_profiling_chrome_str :
-                                               js_profiling_content_str);
   bool usePCCounts = Preferences::GetBool(chromeWindow ?
                                             js_pccounts_chrome_str :
                                             js_pccounts_content_str);
   bool useMethodJITAlways = Preferences::GetBool(js_methodjit_always_str);
   bool useTypeInference = !chromeWindow && Preferences::GetBool(js_typeinfer_str);
   bool useHardening = Preferences::GetBool(js_jit_hardening_str);
   nsCOMPtr<nsIXULRuntime> xr = do_GetService(XULRUNTIME_SERVICE_CONTRACTID);
   if (xr) {
     bool safeMode = false;
     xr->GetInSafeMode(&safeMode);
     if (safeMode) {
       useMethodJIT = false;
-      useProfiling = false;
       usePCCounts = false;
       useTypeInference = false;
       useMethodJITAlways = true;
       useHardening = false;
     }
   }    
 
   if (useMethodJIT)
     newDefaultJSOptions |= JSOPTION_METHODJIT;
   else
     newDefaultJSOptions &= ~JSOPTION_METHODJIT;
 
-  if (useProfiling)
-    newDefaultJSOptions |= JSOPTION_PROFILING;
-  else
-    newDefaultJSOptions &= ~JSOPTION_PROFILING;
-
   if (usePCCounts)
     newDefaultJSOptions |= JSOPTION_PCCOUNT;
   else
     newDefaultJSOptions &= ~JSOPTION_PCCOUNT;
 
   if (useMethodJITAlways)
     newDefaultJSOptions |= JSOPTION_METHODJIT_ALWAYS;
   else
@@ -1573,17 +1562,17 @@ nsJSContext::CompileScript(const PRUnich
                                                  static_cast<const jschar*>(aText),
                                                  aTextLength,
                                                  aURL,
                                                  aLineNo,
                                                  JSVersion(aVersion));
     if (script) {
       NS_ASSERTION(aScriptObject.getScriptTypeID()==JAVASCRIPT,
                    "Expecting JS script object holder");
-      rv = aScriptObject.set(script);
+      rv = aScriptObject.setScript(script);
     } else {
       rv = NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   // Whew!  Finally done.
   JSPRINCIPALS_DROP(mContext, jsprin);
   return rv;
@@ -1773,36 +1762,39 @@ nsJSContext::CompileEventHandler(nsIAtom
   if (!fun) {
     ReportPendingException();
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
   JSObject *handler = ::JS_GetFunctionObject(fun);
   NS_ASSERTION(aHandler.getScriptTypeID()==JAVASCRIPT,
                "Expecting JS script object holder");
-  return aHandler.set((void *)handler);
+  return aHandler.setObject(handler);
 }
 
 // XXX - note that CompileFunction doesn't yet play the nsScriptObjectHolder
 // game - caller must still ensure JS GC root.
 nsresult
-nsJSContext::CompileFunction(void* aTarget,
+nsJSContext::CompileFunction(JSObject* aTarget,
                              const nsACString& aName,
                              PRUint32 aArgCount,
                              const char** aArgArray,
                              const nsAString& aBody,
                              const char* aURL,
                              PRUint32 aLineNo,
                              PRUint32 aVersion,
                              bool aShared,
-                             void** aFunctionObject)
+                             JSObject** aFunctionObject)
 {
   NS_TIME_FUNCTION_FMT(1.0, "%s (line %d) (function: %s, url: %s, line: %d)", MOZ_FUNCTION_NAME,
                        __LINE__, aName.BeginReading(), aURL, aLineNo);
 
+  NS_ABORT_IF_FALSE(aFunctionObject,
+    "Shouldn't call CompileFunction with null return value.");
+
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
 
   // Don't compile if aVersion is unknown.  Since the caller is responsible for
   // parsing the version strings, we just check it isn't JSVERSION_UNKNOWN.
   if ((JSVersion)aVersion == JSVERSION_UNKNOWN) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
@@ -1815,54 +1807,53 @@ nsJSContext::CompileFunction(void* aTarg
     if (globalData) {
       nsIPrincipal *prin = globalData->GetPrincipal();
       if (!prin)
         return NS_ERROR_FAILURE;
       prin->GetJSPrincipals(mContext, &jsprin);
     }
   }
 
-  JSObject *target = (JSObject*)aTarget;
+  JSObject *target = aTarget;
 
   JSAutoRequest ar(mContext);
 
   JSFunction* fun =
       ::JS_CompileUCFunctionForPrincipalsVersion(mContext,
                                                  aShared ? nsnull : target, jsprin,
                                                  PromiseFlatCString(aName).get(),
                                                  aArgCount, aArgArray,
-                                                 (jschar*)PromiseFlatString(aBody).get(),
+                                                 static_cast<const jschar*>(PromiseFlatString(aBody).get()),
                                                  aBody.Length(),
                                                  aURL, aLineNo,
                                                  JSVersion(aVersion));
 
   if (jsprin)
     JSPRINCIPALS_DROP(mContext, jsprin);
   if (!fun)
     return NS_ERROR_FAILURE;
 
-  JSObject *handler = ::JS_GetFunctionObject(fun);
-  if (aFunctionObject)
-    *aFunctionObject = (void*) handler;
+  *aFunctionObject = JS_GetFunctionObject(fun);
   return NS_OK;
 }
 
 nsresult
 nsJSContext::CallEventHandler(nsISupports* aTarget, JSObject* aScope,
-                              void *aHandler, nsIArray *aargv, nsIVariant **arv)
+                              JSObject* aHandler, nsIArray* aargv,
+                              nsIVariant** arv)
 {
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
 
   if (!mScriptsEnabled) {
     return NS_OK;
   }
 
 #ifdef NS_FUNCTION_TIMER
   {
-    JSObject *obj = static_cast<JSObject *>(aHandler);
+    JSObject *obj = aHandler;
     if (js::IsFunctionProxy(obj))
       obj = js::UnwrapObject(obj);
     JSString *id = JS_GetFunctionId(static_cast<JSFunction *>(JS_GetPrivate(mContext, obj)));
     JSAutoByteString bytes;
     const char *name = !id ? "anonymous" : bytes.encode(mContext, id) ? bytes.ptr() : "<error>";
     NS_TIME_FUNCTION_FMT(1.0, "%s (line %d) (function: %s)", MOZ_FUNCTION_NAME, __LINE__, name);
   }
 #endif
@@ -1889,17 +1880,17 @@ nsJSContext::CallEventHandler(nsISupport
 
   nsJSContext::TerminationFuncHolder holder(this);
 
   if (NS_SUCCEEDED(rv)) {
     // Convert args to jsvals.
     PRUint32 argc = 0;
     jsval *argv = nsnull;
 
-    JSObject *funobj = static_cast<JSObject *>(aHandler);
+    JSObject *funobj = aHandler;
     nsCOMPtr<nsIPrincipal> principal;
     rv = sSecurityManager->GetObjectPrincipal(mContext, funobj,
                                               getter_AddRefs(principal));
     NS_ENSURE_SUCCESS(rv, rv);
 
     JSStackFrame *currentfp = nsnull;
     rv = sSecurityManager->PushContextPrincipal(mContext,
                                                 JS_FrameIterator(mContext, &currentfp),
@@ -1959,58 +1950,60 @@ nsJSContext::CallEventHandler(nsISupport
   // ScriptEvaluated needs to come after we pop the stack
   ScriptEvaluated(true);
 
   return rv;
 }
 
 nsresult
 nsJSContext::BindCompiledEventHandler(nsISupports* aTarget, JSObject* aScope,
-                                      void *aHandler,
+                                      JSObject* aHandler,
                                       nsScriptObjectHolder& aBoundHandler)
 {
   NS_ENSURE_ARG(aHandler);
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
   NS_PRECONDITION(!aBoundHandler, "Shouldn't already have a bound handler!");
 
   JSAutoRequest ar(mContext);
 
   // Get the jsobject associated with this target
   JSObject *target = nsnull;
   nsresult rv = JSObjectFromInterface(aTarget, aScope, &target);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  JSObject *funobj = (JSObject*) aHandler;
-
 #ifdef DEBUG
   {
     JSAutoEnterCompartment ac;
-    if (!ac.enter(mContext, funobj)) {
+    if (!ac.enter(mContext, aHandler)) {
       return NS_ERROR_FAILURE;
     }
 
     NS_ASSERTION(JS_TypeOfValue(mContext,
-                                OBJECT_TO_JSVAL(funobj)) == JSTYPE_FUNCTION,
+                                OBJECT_TO_JSVAL(aHandler)) == JSTYPE_FUNCTION,
                  "Event handler object not a function");
   }
 #endif
 
   JSAutoEnterCompartment ac;
   if (!ac.enter(mContext, target)) {
     return NS_ERROR_FAILURE;
   }
 
+  JSObject* funobj;
   // Make sure the handler function is parented by its event target object
-  if (funobj) { // && ::JS_GetParent(mContext, funobj) != target) {
-    funobj = ::JS_CloneFunctionObject(mContext, funobj, target);
-    if (!funobj)
+  if (aHandler) {
+    funobj = JS_CloneFunctionObject(mContext, aHandler, target);
+    if (!funobj) {
       rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+  } else {
+    funobj = NULL;
   }
 
-  aBoundHandler.set(funobj);
+  aBoundHandler.setObject(funobj);
 
   return rv;
 }
 
 // serialization
 nsresult
 nsJSContext::Serialize(nsIObjectOutputStream* aStream, JSScript* aScriptObject)
 {
@@ -2058,32 +2051,30 @@ nsJSContext::Serialize(nsIObjectOutputSt
 
     return rv;
 }
 
 nsresult
 nsJSContext::Deserialize(nsIObjectInputStream* aStream,
                          nsScriptObjectHolder &aResult)
 {
-    JSScript *result = nsnull;
-    nsresult rv;
-
     NS_TIME_FUNCTION_MIN(1.0);
 
     PRUint32 size;
-    rv = aStream->Read32(&size);
+    nsresult rv = aStream->Read32(&size);
     if (NS_FAILED(rv)) return rv;
 
     char* data;
     rv = aStream->ReadBytes(size, &data);
     if (NS_FAILED(rv)) return rv;
 
     JSContext* cx = mContext;
 
     JSXDRState *xdr = ::JS_XDRNewMem(cx, JSXDR_DECODE);
+    JSScript *result = nsnull;
     if (! xdr) {
         rv = NS_ERROR_OUT_OF_MEMORY;
     } else {
         xdr->userdata = (void*) aStream;
         JSAutoRequest ar(cx);
         ::JS_XDRMemSetData(xdr, data, size);
 
         if (! ::JS_XDRScript(xdr, &result)) {
@@ -2123,17 +2114,17 @@ nsJSContext::Deserialize(nsIObjectInputS
         nsMemory::Free(data);
     NS_ASSERTION(aResult.getScriptTypeID()==JAVASCRIPT,
                  "Expecting JS script object holder");
 
     // Now that we've cleaned up, handle the case when rv is a failure
     // code, which could happen for all sorts of reasons above.
     NS_ENSURE_SUCCESS(rv, rv);
 
-    return aResult.set(result);