Merge from mozilla-central to jsdbg2.
authorJason Orendorff <jorendorff@mozilla.com>
Tue, 12 Jul 2011 10:47:31 -0500
changeset 75200 5e59a54938405c523d0a36b40a3e9b2f5e1442de
parent 75199 5230957a9741940f6d2316a6ae741706a694bb3c (current diff)
parent 72663 8e599595723343118290e0f7a42e96b73d952ef1 (diff)
child 75201 40e989742b4d82cd4f57743899cf86f86fe3aefd
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
milestone8.0a1
Merge from mozilla-central to jsdbg2.
browser/app/README.txt
browser/base/content/browser.js
browser/base/content/highlighter.xhtml
browser/locales/en-US/README.txt
browser/themes/gnomestripe/browser/highlighter.css
browser/themes/pinstripe/browser/highlighter.css
browser/themes/winstripe/browser/highlighter.css
content/html/content/test/test_bug601061.html
content/html/content/test/test_bug630889.html
dom/base/nsDOMClassInfo.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
js/src/Makefile.in
js/src/jsapi-tests/Makefile.in
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jscntxt.h
js/src/jsdbg.cpp
js/src/jsemit.cpp
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsgc.cpp
js/src/jsgcmark.cpp
js/src/jsinterp.cpp
js/src/jsobj.h
js/src/jsopcode.cpp
js/src/jsparse.cpp
js/src/jsproxy.cpp
js/src/jsregexp.cpp
js/src/jsregexpinlines.h
js/src/jsscope.cpp
js/src/jsstr.cpp
js/src/jstracer.cpp
js/src/jstypedarray.cpp
js/src/jsvalue.h
js/src/jswrapper.cpp
js/src/jswrapper.h
js/src/methodjit/InvokeHelpers.cpp
js/src/methodjit/MethodJIT.cpp
js/src/methodjit/MonoIC.cpp
js/src/methodjit/StubCalls.cpp
js/src/shell/js.cpp
js/src/tests/e4x/XML/jstests.list
js/src/tests/js1_5/Array/regress-350256-03.js
js/src/tests/js1_8_5/extensions/jstests.list
js/src/tests/js1_8_5/regress/jstests.list
js/src/vm/GlobalObject.cpp
js/src/vm/GlobalObject.h
js/src/vm/Stack-inl.h
js/src/vm/Stack.cpp
js/src/vm/Stack.h
js/src/xpconnect/shell/xpcshell.cpp
js/src/xpconnect/src/xpcjsruntime.cpp
js/src/xpconnect/src/xpcprivate.h
layout/xul/base/public/nsIMenuFrame.h
layout/xul/base/src/nsIBoxLayout.h
layout/xul/base/src/nsIScrollbarFrame.h
modules/libpref/src/init/all.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_642108_refForOutputNode.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_display_accessors.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_get_content_window_from_hud_id.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_get_heads_up_display.js
toolkit/components/console/hudservice/tests/browser/test-bug-595934-getselection.html
toolkit/components/console/hudservice/tests/browser/test-bug-595934-getselection.js
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -62,17 +62,17 @@
 #include "nsIDOMNSEvent.h"
 #include "nsIDOMXULMenuListElement.h"
 #include "nsIDOMXULMultSelectCntrlEl.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
 #include "nsIDOMXULPopupElement.h"
 #include "nsIDocument.h"
 #include "nsEventListenerManager.h"
 #include "nsIFrame.h"
-#include "nsIMenuFrame.h"
+#include "nsMenuFrame.h"
 #include "nsIHTMLDocument.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsISelectionPrivate.h"
 #include "nsIServiceManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsReadableUtils.h"
 #include "nsRootAccessible.h"
@@ -683,26 +683,23 @@ nsRootAccessible::ProcessDOMEvent(nsIDOM
   else if (eventType.EqualsLiteral("DOMMenuItemActive")) {
     PRBool fireFocus = PR_FALSE;
     if (!treeItemAccessible) {
 #ifdef MOZ_XUL
       if (isTree) {
         return; // Tree with nothing selected
       }
 #endif
-      nsIFrame* menuFrame = accessible->GetFrame();
-      if (!menuFrame)
-        return;
 
-      nsIMenuFrame* imenuFrame = do_QueryFrame(menuFrame);
-      if (imenuFrame)
+      nsMenuFrame* menuFrame = do_QueryFrame(accessible->GetFrame());
+      if (menuFrame)
         fireFocus = PR_TRUE;
-      // QI failed for nsIMenuFrame means it's not on menu bar
-      if (imenuFrame && imenuFrame->IsOnMenuBar() &&
-                       !imenuFrame->IsOnActiveMenuBar()) {
+      // QI failed for nsMenuFrame means it's not on menu bar
+      if (menuFrame && menuFrame->IsOnMenuBar() &&
+                       !menuFrame->IsOnActiveMenuBar()) {
         // It is a top level menuitem. Only fire a focus event when the menu bar
         // is active.
         return;
       } else {
         nsAccessible *containerAccessible = accessible->GetParent();
         if (!containerAccessible)
           return;
         // It is not top level menuitem
deleted file mode 100644
--- a/browser/app/README.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-For information about installing, running and configuring Firefox 
-including a list of known issues and troubleshooting information, 
-refer to: http://getfirefox.com/releases/
-
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,193 +1,201 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1306529826000">
   <emItems>
-    <emItem id="fdm_ffext@freedownloadmanager.org">
-      <versionRange minVersion="1.0" maxVersion="1.3.1">
-        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-           <versionRange minVersion="3.0a1" maxVersion="*"/>
-        </targetApplication>
-      </versionRange>
-    </emItem>
-    <emItem id="firefox@bandoo.com">
-      <versionRange minVersion="5.0" maxVersion="5.0" severity="1">
-        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-           <versionRange minVersion="3.7a1pre" maxVersion="*"/>
-        </targetApplication>
-      </versionRange>
-    </emItem>
-    <emItem id="langpack-vi-VN@firefox.mozilla.org">
-      <versionRange minVersion="2.0" maxVersion="2.0"/>
-    </emItem>
-    <emItem id="masterfiler@gmail.com">
-      <versionRange severity="3"/>
-    </emItem>
-    <emItem id="mozilla_cc@internetdownloadmanager.com">
-      <versionRange minVersion=" " maxVersion="6.9.8">
-        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-           <versionRange minVersion="3.7a1pre" maxVersion="*"/>
-        </targetApplication>
-      </versionRange>
-      <versionRange minVersion="2.1" maxVersion="3.3">
-        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-           <versionRange minVersion="3.0a1" maxVersion="*"/>
-        </targetApplication>
-      </versionRange>
-    </emItem>
-    <emItem id="msntoolbar@msn.com">
-      <versionRange minVersion=" " maxVersion="6.*"/>
-    </emItem>
-    <emItem id="personas@christopher.beard">
-      <versionRange minVersion="1.6" maxVersion="1.6">
-        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-           <versionRange minVersion="3.6" maxVersion="3.6.*"/>
-        </targetApplication>
-      </versionRange>
-    </emItem>
-    <emItem id="ShopperReports@ShopperReports.com">
-      <versionRange minVersion="3.1.22.0" maxVersion="3.1.22.0"/>
-    </emItem>
-    <emItem id="support@daemon-tools.cc">
-      <versionRange minVersion=" " maxVersion="1.0.0.5"/>
-    </emItem>
-    <emItem id="support@update-firefox.com"/>
-    <emItem id="yslow@yahoo-inc.com">
-      <versionRange minVersion="2.0.5" maxVersion="2.0.5">
-        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-           <versionRange minVersion="3.5.7" maxVersion="*"/>
-        </targetApplication>
-      </versionRange>
-    </emItem>
-    <emItem id="{2224e955-00e9-4613-a844-ce69fccaae91}"/>
-    <emItem id="{27182e60-b5f3-411c-b545-b44205977502}">
-      <versionRange minVersion="1.0" maxVersion="1.0"/>
-    </emItem>
-    <emItem id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}">
-      <versionRange minVersion="2.2" maxVersion="2.2"/>
-    </emItem>
-    <emItem id="{3f963a5b-e555-4543-90e2-c3908898db71}">
-      <versionRange minVersion=" " maxVersion="8.5"/>
-    </emItem>
-    <emItem id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
-      <versionRange minVersion="1.1b1" maxVersion="1.1b1"/>
-    </emItem>
-    <emItem id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
-      <versionRange minVersion="1.2" maxVersion="1.2">
-        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-           <versionRange minVersion="3.0a1" maxVersion="*"/>
-        </targetApplication>
-      </versionRange>
-    </emItem>
-    <emItem id="{6E19037A-12E3-4295-8915-ED48BC341614}">
-      <versionRange minVersion="0.1" maxVersion="1.3.328.4" severity="1">
-        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-           <versionRange minVersion="3.7a1pre" maxVersion="*"/>
-        </targetApplication>
-      </versionRange>
-    </emItem>
-    <emItem id="{8CE11043-9A15-4207-A565-0C94C42D590D}"/>
-    <emItem id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
-      <versionRange minVersion="0.1" maxVersion="5.2.0.7164" severity="1"/>
-    </emItem>
-    <emItem id="{B13721C7-F507-4982-B2E5-502A71474FED}">
-      <versionRange severity="1"/>
-    </emItem>
-    <emItem id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
-      <versionRange minVersion="0.1" maxVersion="3.3.0.*">
-        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-           <versionRange minVersion="3.7a1" maxVersion="*"/>
-        </targetApplication>
-      </versionRange>
-      <versionRange minVersion="3.3.1" maxVersion="*">
-        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-           <versionRange minVersion="5.0a1" maxVersion="*"/>
-        </targetApplication>
-      </versionRange>
-    </emItem>
-    <emItem id="{E8E88AB0-7182-11DF-904E-6045E0D72085}"/>
-  </emItems>
-<pluginItems>
-  <pluginItem>
-    <match name="name" exp="^Yahoo Application State Plugin$"/>
-    <match name="description" exp="^Yahoo Application State Plugin$"/>
-    <match name="filename" exp="npYState.dll"/>
-    <versionRange>
-      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-        <versionRange minVersion="3.0a1" maxVersion="3.*"/>
-      </targetApplication>
-    </versionRange>
-  </pluginItem>
-  <pluginItem>
-    <match name="name" exp="QuickTime Plug-in 7[.]1[.]"/>
-    <match name="filename" exp="npqtplugin.?[.]dll"/>
-    <versionRange>
-      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-        <versionRange minVersion="3.0a1" maxVersion="3.*"/>
-      </targetApplication>
-    </versionRange>
-  </pluginItem>
-  <pluginItem>
-    <match name="filename" exp="NPFFAddOn.dll"/>
-    <versionRange>
-    </versionRange>
-  </pluginItem>
-  <pluginItem>
-    <match name="filename" exp="NPMySrch.dll"/>
-    <versionRange>
-    </versionRange>
-  </pluginItem>
-  <pluginItem>
-    <match name="filename" exp="npViewpoint.dll"/>
-    <versionRange>
-      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-        <versionRange minVersion="3.0" maxVersion="*"/>
-      </targetApplication>
-    </versionRange>
-  </pluginItem>
-  <pluginItem>
-    <match name="name" exp="[0-6]\.0\.[01]\d{2}\.\d+"/>
-    <match name="filename" exp="npdeploytk.dll"/>
-    <versionRange severity="1">
-    </versionRange>
-  </pluginItem>
-  <pluginItem>
-    <match name="filename" exp="[Nn][Pp][Jj][Pp][Ii]1[56]0_[0-9]+\.[Dd][Ll][Ll]"/>
-    <versionRange>
-      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-        <versionRange minVersion="3.6a1pre" maxVersion="*"/>
-      </targetApplication>
-    </versionRange>
-  </pluginItem>
-</pluginItems>
-<gfxItems>
-  <gfxBlacklistEntry>
-    <os>WINNT 6.1</os>
-    <vendor>0x10de</vendor>
-    <devices>
-      <device>0x0a6c</device>
-    </devices>
-    <feature>DIRECT2D</feature>
-    <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
-    <driverVersion>8.17.12.5896</driverVersion>
-    <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
-  </gfxBlacklistEntry>
-  <gfxBlacklistEntry>
-    <os>WINNT 6.1</os>
-    <vendor>0x10de</vendor>
-    <devices>
-      <device>0x0a6c</device>
-    </devices>
-    <feature>DIRECT3D_9_LAYERS</feature>
-    <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
-    <driverVersion>8.17.12.5896</driverVersion>
-    <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
-  </gfxBlacklistEntry>
-  <gfxBlacklistEntry>
-    <os>WINNT 5.1</os>
-    <vendor>0x10de</vendor>
-    <feature>DIRECT3D_9_LAYERS</feature>
-    <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
-    <driverVersion>7.0.0.0</driverVersion>
-    <driverVersionComparator>GREATER_THAN_OR_EQUAL</driverVersionComparator>
-  </gfxBlacklistEntry>
-</gfxItems>
-</blocklist>
+      <emItem  blockID="i8" id="{B13721C7-F507-4982-B2E5-502A71474FED}">
+                        <versionRange  minVersion=" " severity="1">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
+                        <versionRange  minVersion="0.1" maxVersion="3.3.0.*">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="3.7a1" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                                <versionRange  minVersion="3.3.1" maxVersion="*">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="5.0a1" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
+                        <versionRange  minVersion="1.1b1" maxVersion="1.1b1">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i16" id="{27182e60-b5f3-411c-b545-b44205977502}">
+                        <versionRange  minVersion="1.0" maxVersion="1.0">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i10" id="{8CE11043-9A15-4207-A565-0C94C42D590D}">
+                        </emItem>
+      <emItem  blockID="i1" id="mozilla_cc@internetdownloadmanager.com">
+                        <versionRange  minVersion="2.1" maxVersion="3.3">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="3.0a1" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                                <versionRange  minVersion=" " maxVersion="6.9.8">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i18" id="msntoolbar@msn.com">
+                        <versionRange  minVersion=" " maxVersion="6.*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i13" id="{E8E88AB0-7182-11DF-904E-6045E0D72085}">
+                        </emItem>
+      <emItem  blockID="i4" id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
+                        <versionRange  minVersion="1.2" maxVersion="1.2">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="3.0a1" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i23" id="firefox@bandoo.com">
+                        <versionRange  minVersion="5.0" maxVersion="5.0" severity="1">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i22" id="ShopperReports@ShopperReports.com">
+                        <versionRange  minVersion="3.1.22.0" maxVersion="3.1.22.0">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i2" id="fdm_ffext@freedownloadmanager.org">
+                        <versionRange  minVersion="1.0" maxVersion="1.3.1">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="3.0a1" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i5" id="support@daemon-tools.cc">
+                        <versionRange  minVersion=" " maxVersion="1.0.0.5">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i6" id="{3f963a5b-e555-4543-90e2-c3908898db71}">
+                        <versionRange  minVersion=" " maxVersion="8.5">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i12" id="masterfiler@gmail.com">
+                        <versionRange  severity="3">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i20" id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
+                        <versionRange  minVersion="0.1" maxVersion="5.2.0.7164" severity="1">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i11" id="yslow@yahoo-inc.com">
+                        <versionRange  minVersion="2.0.5" maxVersion="2.0.5">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <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="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">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i15" id="personas@christopher.beard">
+                        <versionRange  minVersion="1.6" maxVersion="1.6">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="3.6" maxVersion="3.6.*" />
+                          </targetApplication>
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i21" id="support@update-firefox.com">
+                        </emItem>
+    </emItems>
+
+  <pluginItems>
+      <pluginItem  blockID="p26">
+      <match name="name" exp="^Yahoo Application State Plugin$" />      <match name="description" exp="^Yahoo Application State Plugin$" />      <match name="filename" exp="npYState.dll" />              <versionRange >
+                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+              <versionRange  minVersion="3.0a1" maxVersion="3.*" />
+            </targetApplication>
+                  </versionRange>
+          </pluginItem>
+      <pluginItem  blockID="p27">
+      <match name="name" exp="QuickTime Plug-in 7[.]1[.]" />            <match name="filename" exp="npqtplugin.?[.]dll" />              <versionRange >
+                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+              <versionRange  minVersion="3.0a1" maxVersion="3.*" />
+            </targetApplication>
+                  </versionRange>
+          </pluginItem>
+      <pluginItem  blockID="p28">
+                  <match name="filename" exp="NPFFAddOn.dll" />              <versionRange >
+                  </versionRange>
+          </pluginItem>
+      <pluginItem  blockID="p31">
+                  <match name="filename" exp="NPMySrch.dll" />              <versionRange >
+                  </versionRange>
+          </pluginItem>
+      <pluginItem  blockID="p32">
+                  <match name="filename" exp="npViewpoint.dll" />              <versionRange >
+                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+              <versionRange  minVersion="3.0" maxVersion="*" />
+            </targetApplication>
+                  </versionRange>
+          </pluginItem>
+      <pluginItem  blockID="p33">
+      <match name="name" exp="[0-6]\.0\.[01]\d{2}\.\d+" />            <match name="filename" exp="npdeploytk.dll" />              <versionRange  severity="1">
+                  </versionRange>
+          </pluginItem>
+      <pluginItem  blockID="p34">
+                  <match name="filename" exp="[Nn][Pp][Jj][Pp][Ii]1[56]0_[0-9]+\.[Dd][Ll][Ll]" />              <versionRange >
+                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+              <versionRange  minVersion="3.6a1pre" maxVersion="*" />
+            </targetApplication>
+                  </versionRange>
+          </pluginItem>
+    </pluginItems>
+
+  <gfxItems>
+    <gfxBlacklistEntry  blockID="g35">
+      <os>WINNT 6.1</os>
+      <vendor>0x10de</vendor>
+              <devices>
+                      <device>0x0a6c</device>
+                  </devices>
+            <feature>DIRECT2D</feature>
+      <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
+      <driverVersion>8.17.12.5896</driverVersion>
+      <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
+    </gfxBlacklistEntry>
+    <gfxBlacklistEntry  blockID="g36">
+      <os>WINNT 6.1</os>
+      <vendor>0x10de</vendor>
+              <devices>
+                      <device>0x0a6c</device>
+                  </devices>
+            <feature>DIRECT3D_9_LAYERS</feature>
+      <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
+      <driverVersion>8.17.12.5896</driverVersion>
+      <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
+    </gfxBlacklistEntry>
+    <gfxBlacklistEntry  blockID="g37">
+      <os>WINNT 5.1</os>
+      <vendor>0x10de</vendor>
+            <feature>DIRECT3D_9_LAYERS</feature>
+      <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
+      <driverVersion>7.0.0.0</driverVersion>
+      <driverVersionComparator>GREATER_THAN_OR_EQUAL</driverVersionComparator>
+    </gfxBlacklistEntry>
+    </gfxItems>
+
+
+</blocklist>
\ No newline at end of file
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -895,16 +895,20 @@ pref("dom.ipc.plugins.enabled.i386.flash
 pref("dom.ipc.plugins.enabled.i386.javaplugin2_npapi.plugin", true);
 pref("dom.ipc.plugins.enabled.i386.javaappletplugin.plugin", true);
 // x86_64 ipc preferences
 pref("dom.ipc.plugins.enabled.x86_64", true);
 #else
 pref("dom.ipc.plugins.enabled", true);
 #endif
 
+#ifdef MOZ_E10S_COMPAT
+pref("browser.tabs.remote", true);
+#endif
+
 // This pref governs whether we attempt to work around problems caused by
 // plugins using OS calls to manipulate the cursor while running out-of-
 // process.  These workarounds all involve intercepting (hooking) certain
 // OS calls in the plugin process, then arranging to make certain OS calls
 // in the browser process.  Eventually plugins will be required to use the
 // NPAPI to manipulate the cursor, and these workarounds will be removed.
 // See bug 621117.
 #ifdef XP_MACOSX
--- a/browser/base/content/browser-tabPreviews.js
+++ b/browser/base/content/browser-tabPreviews.js
@@ -590,16 +590,17 @@ var allTabs = {
   get container () {
     delete this.container;
     return this.container = document.getElementById("allTabs-container");
   },
   get tabCloseButton () {
     delete this.tabCloseButton;
     return this.tabCloseButton = document.getElementById("allTabs-tab-close-button");
   },
+  get toolbarButton() document.getElementById("alltabs-button"),
   get previews () this.container.getElementsByClassName("allTabs-preview"),
   get isOpen () this.panel.state == "open" || this.panel.state == "showing",
 
   init: function allTabs_init() {
     if (this._initiated)
       return;
     this._initiated = true;
 
@@ -627,17 +628,17 @@ var allTabs = {
     while (this.container.hasChildNodes())
       this.container.removeChild(this.container.firstChild);
 
     this._initiated = false;
   },
 
   prefName: "browser.allTabs.previews",
   readPref: function allTabs_readPref() {
-    var allTabsButton = document.getElementById("alltabs-button");
+    var allTabsButton = this.toolbarButton;
     if (!allTabsButton)
       return;
 
     if (gPrefService.getBoolPref(this.prefName)) {
       allTabsButton.removeAttribute("type");
       allTabsButton.setAttribute("command", "Browser:ShowAllTabs");
     } else {
       allTabsButton.setAttribute("type", "menu");
@@ -692,16 +693,27 @@ var allTabs = {
         preview.hidden = false;
       }
     }, this);
 
     this._reflow();
   },
 
   open: function allTabs_open() {
+    var allTabsButton = this.toolbarButton;
+    if (allTabsButton &&
+        allTabsButton.getAttribute("type") == "menu") {
+      // Without setTimeout, the menupopup won't stay open when invoking
+      // "View > Show All Tabs" and the menu bar auto-hides.
+      setTimeout(function () {
+        allTabsButton.open = true;
+      }, 0);
+      return;
+    }
+
     this.init();
 
     if (this.isOpen)
       return;
 
     this._maxPanelHeight = Math.max(gBrowser.clientHeight, screen.availHeight / 2);
     this._maxPanelWidth = Math.max(gBrowser.clientWidth, screen.availWidth / 2);
 
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -495,8 +495,11 @@ statuspanel[label=""] {
   height: 3em;
   width: 100%;
   -moz-box-align: end;
 }
 
 .panel-inner-arrowcontentfooter[footertype="promobox"] {
   -moz-binding: url("chrome://browser/content/urlbarBindings.xml#promobox");
 }
+
+/* highlighter */
+%include highlighter.css
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1454,19 +1454,23 @@ function prepareForStartup() {
 
   // enable global history
   try {
     gBrowser.docShell.QueryInterface(Components.interfaces.nsIDocShellHistory).useGlobalHistory = true;
   } catch(ex) {
     Components.utils.reportError("Places database may be locked: " + ex);
   }
 
+#ifdef MOZ_E10S_COMPAT
+  // Bug 666801 - WebProgress support for e10s
+#else
   // hook up UI through progress listener
   gBrowser.addProgressListener(window.XULBrowserWindow);
   gBrowser.addTabsProgressListener(window.TabsProgressListener);
+#endif
 
   // setup our common DOMLinkAdded listener
   gBrowser.addEventListener("DOMLinkAdded", DOMLinkHandler, false);
 
   // setup our MozApplicationManifest listener
   gBrowser.addEventListener("MozApplicationManifest",
                             OfflineApps, false);
 
@@ -1578,19 +1582,23 @@ function delayedStartup(isLoadingBlank, 
   // apply full zoom settings to tabs restored by the session restore service.
   try {
     FullZoom.init();
   }
   catch(ex) {
     Components.utils.reportError("Failed to init content pref service:\n" + ex);
   }
 
+#ifdef MOZ_E10S_COMPAT
+  // Bug 666804 - NetworkPrioritizer support for e10s
+#else
   let NP = {};
   Cu.import("resource:///modules/NetworkPrioritizer.jsm", NP);
   NP.trackBrowserWindow(window);
+#endif
 
   // initialize the session-restore service (in case it's not already running)
   try {
     Cc["@mozilla.org/browser/sessionstore;1"]
       .getService(Ci.nsISessionStore)
       .init(window);
   } catch (ex) {
     dump("nsSessionStore could not be initialized: " + ex + "\n");
@@ -1631,18 +1639,22 @@ function delayedStartup(isLoadingBlank, 
   placesContext.addEventListener("popupshowing", updateEditUIVisibility, false);
   placesContext.addEventListener("popuphiding", updateEditUIVisibility, false);
 #endif
 
   gBrowser.mPanelContainer.addEventListener("InstallBrowserTheme", LightWeightThemeWebInstaller, false, true);
   gBrowser.mPanelContainer.addEventListener("PreviewBrowserTheme", LightWeightThemeWebInstaller, false, true);
   gBrowser.mPanelContainer.addEventListener("ResetBrowserThemePreview", LightWeightThemeWebInstaller, false, true);
 
+#ifdef MOZ_E10S_COMPAT
+  // Bug 666808 - AeroPeek support for e10s
+#else
   if (Win7Features)
     Win7Features.onOpenWindow();
+#endif
 
   // called when we go into full screen, even if it is
   // initiated by a web page script
   window.addEventListener("fullscreen", onFullScreen, true);
   if (window.fullScreen)
     onFullScreen();
 
 #ifdef MOZ_SERVICES_SYNC
@@ -4152,21 +4164,25 @@ var XULBrowserWindow = {
     delete this._uriFixup;
     return this._uriFixup = Cc["@mozilla.org/docshell/urifixup;1"]
                               .getService(Ci.nsIURIFixup);
   },
 
   init: function () {
     this.throbberElement = document.getElementById("navigator-throbber");
 
+#ifdef MOZ_E10S_COMPAT
+    // Bug 666809 - SecurityUI support for e10s
+#else
     // Initialize the security button's state and tooltip text.  Remember to reset
     // _hostChanged, otherwise onSecurityChange will short circuit.
     var securityUI = gBrowser.securityUI;
     this._hostChanged = true;
     this.onSecurityChange(null, null, securityUI.state);
+#endif
   },
 
   destroy: function () {
     // XXXjag to avoid leaks :-/, see bug 60729
     delete this.throbberElement;
     delete this.stopCommand;
     delete this.reloadCommand;
     delete this.statusTextField;
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -1019,20 +1019,14 @@
       <svg:rect x="6" y="1" width="5" height="5" fill="white"/>
       <svg:circle cx="11" cy="6" r="5"/>
       <svg:rect x="0" y="0" width="12" height="1" fill="white"/>
     </svg:mask>
   </svg:svg>
 #endif
 
 </vbox>
-# <iframe id="highlighter-frame"
-#   transparent="true"
-#   type="content"
-#   src="chrome://content/base/highlighter.html"/> is dynamically appended as
-#     the last child of #tab-view-deck, only when it is needed, for minimal
-#     performance impact.
 # <iframe id="tab-view"> is dynamically appended as the 2nd child of #tab-view-deck.
 #     Introducing the iframe dynamically, as needed, was found to be better than
 #     starting with an empty iframe here in browser.xul from a Ts standpoint.
 </deck>
 
 </window>
new file mode 100644
--- /dev/null
+++ b/browser/base/content/highlighter.css
@@ -0,0 +1,36 @@
+#highlighter-container {
+  pointer-events: none;
+}
+
+#highlighter-controls {
+  position: absolute;
+  top: 0;
+  left: 0;
+}
+
+#highlighter-veil-container {
+  overflow: hidden;
+}
+
+.highlighter-veil,
+#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;
+}
+
+#highlighter-veil-middlebox:-moz-locale-dir(rtl) {
+  -moz-box-direction: reverse;
+}
+
+#highlighter-close-button {
+  position: absolute;
+  pointer-events: auto;
+  z-index: 1;
+}
deleted file mode 100644
--- a/browser/base/content/highlighter.xhtml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html>
-<!-- ***** 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 Inspector Highlighter code.
-   -
-   - 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):
-   -   Rob Campbell <rcampbell@mozilla.com> (Original Author)
-   -   Paul Rouget <paul@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 LGPL or the GPL. 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 ***** -->
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-  <link rel="stylesheet" href="chrome://browser/skin/highlighter.css" type="text/css"/>
-</head>
-<body>
-<div id="close-button" role="button" class="clickable"/>
-
-<!--
-    To darken the page around the selected node, we use black-transparent
-    divs, organized in 3 rows, keeping the div in the middle transparent.
--->
-<div id="veil-container">
-  <div id="veil">
-    <div id="veil-topbox" class="veil"/>
-    <div id="veil-middlebox">
-      <div id="veil-leftbox" class="veil"/>
-      <div id="veil-transparentbox"/>
-      <div id="veil-rightbox" class="veil"/>
-    </div>
-    <div id="veil-bottombox" class="veil"/>
-  </div>
-</div>
-
-</body>
-</html>
--- a/browser/base/content/inspector.js
+++ b/browser/base/content/inspector.js
@@ -53,114 +53,178 @@ const INSPECTOR_INVISIBLE_ELEMENTS = {
   "meta": true,
   "script": true,
   "style": true,
   "title": true,
 };
 
 // Inspector notifications dispatched through the nsIObserverService.
 const INSPECTOR_NOTIFICATIONS = {
-  // Fires once the Inspector highlighter is initialized and ready for use.
-  HIGHLIGHTER_READY: "highlighter-ready",
-
   // Fires once the Inspector highlights an element in the page.
   HIGHLIGHTING: "inspector-highlighting",
 
   // Fires once the Inspector stops highlighting any element.
   UNHIGHLIGHTING: "inspector-unhighlighting",
 
   // Fires once the Inspector completes the initialization and opens up on
   // screen.
   OPENED: "inspector-opened",
 
   // Fires once the Inspector is closed.
   CLOSED: "inspector-closed",
 };
 
 ///////////////////////////////////////////////////////////////////////////
-//// IFrameHighlighter
+//// Highlighter
 
 /**
- * A highlighter mechanism using a transparent xul iframe.
+ * A highlighter mechanism.
+ *
+ * The highlighter is built dynamically once the Inspector is invoked:
+ * <stack id="highlighter-container">
+ *   <vbox id="highlighter-veil-container">...</vbox>
+ *   <box id="highlighter-controls>...</vbox>
+ * </stack>
  *
  * @param nsIDOMNode aBrowser
  *        The xul:browser object for the content window being highlighted.
  */
-function IFrameHighlighter(aBrowser)
+function Highlighter(aBrowser)
 {
   this._init(aBrowser);
 }
 
-IFrameHighlighter.prototype = {
+Highlighter.prototype = {
 
-  _init: function IFH__init(aBrowser)
+  _init: function Highlighter__init(aBrowser)
   {
     this.browser = aBrowser;
     let stack = this.browser.parentNode;
     this.win = this.browser.contentWindow;
     this._highlighting = false;
 
-    let div = document.createElement("div");
-    div.flex = 1;
-    div.setAttribute("style", "pointer-events: none; -moz-user-focus: ignore");
+    this.highlighterContainer = document.createElement("stack");
+    this.highlighterContainer.id = "highlighter-container";
+
+    let veilBox = document.createElement("vbox");
+    veilBox.id = "highlighter-veil-container";
+
+    let controlsBox = document.createElement("box");
+    controlsBox.id = "highlighter-controls";
+
+    // The veil will make the whole page darker except
+    // for the region of the selected box.
+    this.buildVeil(veilBox);
 
-    let iframe = document.createElement("iframe");
-    iframe.setAttribute("id", "highlighter-frame");
-    iframe.setAttribute("transparent", "true");
-    iframe.setAttribute("type", "content");
-    iframe.addEventListener("DOMTitleChanged", function(aEvent) {
-      aEvent.stopPropagation();
-    }, true);
-    iframe.flex = 1;
-    iframe.setAttribute("style", "-moz-user-focus: ignore");
+    // The controlsBox will host the different interactive
+    // elements of the highlighter (buttons, toolbars, ...).
+    this.buildControls(controlsBox);
+
+    this.highlighterContainer.appendChild(veilBox);
+    this.highlighterContainer.appendChild(controlsBox);
 
-    this.listenOnce(iframe, "load", (function iframeLoaded() {
-      this.iframeDoc = iframe.contentDocument;
+    stack.appendChild(this.highlighterContainer);
+
+    this.browser.addEventListener("resize", this, true);
+    this.browser.addEventListener("scroll", this, true);
+
+    this.handleResize();
+  },
+
 
-      this.veilTopDiv = this.iframeDoc.getElementById("veil-topbox");
-      this.veilLeftDiv = this.iframeDoc.getElementById("veil-leftbox");
-      this.veilMiddleDiv = this.iframeDoc.getElementById("veil-middlebox");
-      this.veilTransparentDiv = this.iframeDoc.getElementById("veil-transparentbox");
+  /**
+   * Build the veil:
+   *
+   * <vbox id="highlighter-veil-container">
+   *   <box id="highlighter-veil-topbox" class="highlighter-veil"/>
+   *   <hbox id="highlighter-veil-middlebox">
+   *     <box id="highlighter-veil-leftbox" class="highlighter-veil"/>
+   *     <box id="highlighter-veil-transparentbox"/>
+   *     <box id="highlighter-veil-rightbox" class="highlighter-veil"/>
+   *   </hbox>
+   *   <box id="highlighter-veil-bottombox" class="highlighter-veil"/>
+   * </vbox>
+   *
+   * @param nsIDOMNode aParent
+   */
+  buildVeil: function Highlighter_buildVeil(aParent)
+  {
 
-      let closeButton = this.iframeDoc.getElementById("close-button");
-      this.listenOnce(closeButton, "click",
-        InspectorUI.closeInspectorUI.bind(InspectorUI, false), false);
+    // We will need to resize these boxes to surround a node.
+    // See highlightRectangle().
+
+    this.veilTopBox = document.createElement("box");
+    this.veilTopBox.id = "highlighter-veil-topbox";
+    this.veilTopBox.className = "highlighter-veil";
 
-      this.browser.addEventListener("click", this, true);
-      iframe.contentWindow.addEventListener("resize", this, false);
-      this.handleResize();
-      Services.obs.notifyObservers(null,
-        INSPECTOR_NOTIFICATIONS.HIGHLIGHTER_READY, null);
-    }).bind(this), true);
+    this.veilMiddleBox = document.createElement("hbox");
+    this.veilMiddleBox.id = "highlighter-veil-middlebox";
+
+    this.veilLeftBox = document.createElement("box");
+    this.veilLeftBox.id = "highlighter-veil-leftbox";
+    this.veilLeftBox.className = "highlighter-veil";
+
+    this.veilTransparentBox = document.createElement("box");
+    this.veilTransparentBox.id = "highlighter-veil-transparentbox";
+
+    // We don't need any references to veilRightBox and veilBottomBox.
+    // These boxes are automatically resized (flex=1)
 
-    iframe.setAttribute("src", "chrome://browser/content/highlighter.xhtml");
+    let veilRightBox = document.createElement("box");
+    veilRightBox.id = "highlighter-veil-rightbox";
+    veilRightBox.className = "highlighter-veil";
+
+    let veilBottomBox = document.createElement("box");
+    veilBottomBox.id = "highlighter-veil-bottombox";
+    veilBottomBox.className = "highlighter-veil";
 
-    div.appendChild(iframe);
-    stack.appendChild(div);
-    this.iframe = iframe;
-    this.iframeContainer = div;
+    this.veilMiddleBox.appendChild(this.veilLeftBox);
+    this.veilMiddleBox.appendChild(this.veilTransparentBox);
+    this.veilMiddleBox.appendChild(veilRightBox);
+
+    aParent.appendChild(this.veilTopBox);
+    aParent.appendChild(this.veilMiddleBox);
+    aParent.appendChild(veilBottomBox);
   },
 
   /**
-   * Destroy the iframe and its nodes.
+   * Build the controls:
+   *
+   * <box id="highlighter-close-button"/>
+   *
+   * @param nsIDOMNode aParent
    */
-  destroy: function IFH_destroy()
+  buildControls: function Highlighter_buildControls(aParent)
   {
-    this.browser.removeEventListener("click", this, true);
+    let closeButton = document.createElement("box");
+    closeButton.id = "highlighter-close-button";
+    closeButton.appendChild(document.createElement("image"));
+
+    closeButton.setAttribute("onclick", "InspectorUI.closeInspectorUI(false);");
+
+    aParent.appendChild(closeButton);
+  },
+
+
+  /**
+   * Destroy the nodes.
+   */
+  destroy: function Highlighter_destroy()
+  {
+    this.browser.removeEventListener("scroll", this, true);
+    this.browser.removeEventListener("resize", this, true);
     this._highlightRect = null;
     this._highlighting = false;
-    this.veilTopDiv = null;
-    this.veilLeftDiv = null;
-    this.veilMiddleDiv = null;
-    this.veilTransparentDiv = null;
+    this.veilTopBox = null;
+    this.veilLeftBox = null;
+    this.veilMiddleBox = null;
+    this.veilTransparentBox = null;
     this.node = null;
-    this.iframeDoc = null;
-    this.browser.parentNode.removeChild(this.iframeContainer);
-    this.iframeContainer = null;
-    this.iframe = null;
+    this.highlighterContainer.parentNode.removeChild(this.highlighterContainer);
+    this.highlighterContainer = null;
     this.win = null
     this.browser = null;
   },
 
   /**
    * Is the highlighter highlighting? Public method for querying the state
    * of the highlighter.
    */
@@ -169,36 +233,30 @@ IFrameHighlighter.prototype = {
   },
 
   /**
    * Highlight this.node, unhilighting first if necessary.
    *
    * @param boolean aScroll
    *        Boolean determining whether to scroll or not.
    */
-  highlight: function IFH_highlight(aScroll)
+  highlight: function Highlighter_highlight(aScroll)
   {
     // node is not set or node is not highlightable, bail
     if (!this.node || !this.isNodeHighlightable()) {
       return;
     }
 
     let clientRect = this.node.getBoundingClientRect();
 
     // clientRect is read-only, we need to be able to change properties.
     let rect = {top: clientRect.top,
                 left: clientRect.left,
                 width: clientRect.width,
                 height: clientRect.height};
-    let oldRect = this._highlightRect;
-
-    if (oldRect && rect.top == oldRect.top && rect.left == oldRect.left &&
-        rect.width == oldRect.width && rect.height == oldRect.height) {
-      return; // same rectangle
-    }
 
     if (aScroll) {
       this.node.scrollIntoView();
     }
 
     // Go up in the tree of frames to determine the correct rectangle
     // coordinates and size.
     let frameWin = this.node.ownerDocument.defaultView;
@@ -243,74 +301,81 @@ IFrameHighlighter.prototype = {
   /**
    * Highlight the given node.
    *
    * @param nsIDOMNode aNode
    *        a DOM element to be highlighted
    * @param object aParams
    *        extra parameters object
    */
-  highlightNode: function IFH_highlightNode(aNode, aParams)
+  highlightNode: function Highlighter_highlightNode(aNode, aParams)
   {
     this.node = aNode;
     this.highlight(aParams && aParams.scroll);
   },
 
   /**
    * Highlight a rectangular region.
    *
    * @param object aRect
    *        The rectangle region to highlight.
    * @returns boolean
    *          True if the rectangle was highlighted, false otherwise.
    */
-  highlightRectangle: function IFH_highlightRectangle(aRect)
+  highlightRectangle: function Highlighter_highlightRectangle(aRect)
   {
+    let oldRect = this._highlightRect;
+
+    if (oldRect && aRect.top == oldRect.top && aRect.left == oldRect.left &&
+        aRect.width == oldRect.width && aRect.height == oldRect.height) {
+      return this._highlighting; // same rectangle
+    }
+
     if (aRect.left >= 0 && aRect.top >= 0 &&
         aRect.width > 0 && aRect.height > 0) {
       // The bottom div and the right div are flexibles (flex=1).
       // We don't need to resize them.
-      this.veilTopDiv.style.height = aRect.top + "px";
-      this.veilLeftDiv.style.width = aRect.left + "px";
-      this.veilMiddleDiv.style.height = aRect.height + "px";
-      this.veilTransparentDiv.style.width = aRect.width + "px";
+      this.veilTopBox.style.height = aRect.top + "px";
+      this.veilLeftBox.style.width = aRect.left + "px";
+      this.veilMiddleBox.style.height = aRect.height + "px";
+      this.veilTransparentBox.style.width = aRect.width + "px";
 
       this._highlighting = true;
     } else {
       this.unhighlight();
     }
 
     this._highlightRect = aRect;
 
     return this._highlighting;
   },
 
   /**
    * Clear the highlighter surface.
    */
-  unhighlight: function IFH_unhighlight()
+  unhighlight: function Highlighter_unhighlight()
   {
     this._highlighting = false;
-    this.veilMiddleDiv.style.height = 0;
-    this.veilTransparentDiv.style.width = 0;
+    this.veilMiddleBox.style.height = 0;
+    this.veilTransparentBox.style.width = 0;
     Services.obs.notifyObservers(null,
       INSPECTOR_NOTIFICATIONS.UNHIGHLIGHTING, null);
   },
 
   /**
    * Return the midpoint of a line from pointA to pointB.
    *
    * @param object aPointA
    *        An object with x and y properties.
    * @param object aPointB
    *        An object with x and y properties.
    * @returns object
    *          An object with x and y properties.
    */
-  midPoint: function IFH_midPoint(aPointA, aPointB)
+  midPoint: function Highlighter_midPoint(aPointA, aPointB)
   {
     let pointC = { };
     pointC.x = (aPointB.x - aPointA.x) / 2 + aPointA.x;
     pointC.y = (aPointB.y - aPointA.y) / 2 + aPointA.y;
     return pointC;
   },
 
   /**
@@ -347,51 +412,54 @@ IFrameHighlighter.prototype = {
   },
 
   /**
    * Is this.node highlightable?
    *
    * @returns boolean
    *          True if the node is highlightable or false otherwise.
    */
-  isNodeHighlightable: function IFH_isNodeHighlightable()
+  isNodeHighlightable: function Highlighter_isNodeHighlightable()
   {
     if (!this.node || this.node.nodeType != Node.ELEMENT_NODE) {
       return false;
     }
     let nodeName = this.node.nodeName.toLowerCase();
     return !INSPECTOR_INVISIBLE_ELEMENTS[nodeName];
   },
 
   /////////////////////////////////////////////////////////////////////////
   //// Event Handling
 
-  attachInspectListeners: function IFH_attachInspectListeners()
+  attachInspectListeners: function Highlighter_attachInspectListeners()
   {
     this.browser.addEventListener("mousemove", this, true);
+    this.browser.addEventListener("click", this, true);
     this.browser.addEventListener("dblclick", this, true);
     this.browser.addEventListener("mousedown", this, true);
     this.browser.addEventListener("mouseup", this, true);
   },
 
-  detachInspectListeners: function IFH_detachInspectListeners()
+  detachInspectListeners: function Highlighter_detachInspectListeners()
   {
     this.browser.removeEventListener("mousemove", this, true);
+    this.browser.removeEventListener("click", this, true);
     this.browser.removeEventListener("dblclick", this, true);
     this.browser.removeEventListener("mousedown", this, true);
     this.browser.removeEventListener("mouseup", this, true);
   },
 
+
   /**
    * Generic event handler.
    *
    * @param nsIDOMEvent aEvent
    *        The DOM event object.
    */
-  handleEvent: function IFH_handleEvent(aEvent)
+  handleEvent: function Highlighter_handleEvent(aEvent)
   {
     switch (aEvent.type) {
       case "click":
         this.handleClick(aEvent);
         break;
       case "mousemove":
         this.handleMouseMove(aEvent);
         break;
@@ -399,150 +467,61 @@ IFrameHighlighter.prototype = {
         this.handleResize(aEvent);
         break;
       case "dblclick":
       case "mousedown":
       case "mouseup":
         aEvent.stopPropagation();
         aEvent.preventDefault();
         break;
+      case "scroll":
+        this.highlight();
+        break;
     }
   },
 
   /**
-   * Handle clicks on the iframe.
+   * Handle clicks.
    *
    * @param nsIDOMEvent aEvent
    *        The DOM event.
    */
-  handleClick: function IFH_handleClick(aEvent)
+  handleClick: function Highlighter_handleClick(aEvent)
   {
-    // Proxy the click event to the iframe.
-    let x = aEvent.clientX;
-    let y = aEvent.clientY;
-    let frameWin = aEvent.view;
-    while (frameWin != this.win) {
-      if (frameWin.frameElement) {
-        let frameRect = frameWin.frameElement.getBoundingClientRect();
-        x += frameRect.left;
-        y += frameRect.top;
-      }
-      frameWin = frameWin.parent;
+    // Stop inspection when the user clicks on a node.
+    if (aEvent.button == 0) {
+      let win = aEvent.target.ownerDocument.defaultView;
+      InspectorUI.stopInspecting();
+      win.focus();
     }
-
-    let element = this.iframeDoc.elementFromPoint(x, y);
-    if (element && element.classList &&
-        element.classList.contains("clickable")) {
-      let newEvent = this.iframeDoc.createEvent("MouseEvents");
-      newEvent.initMouseEvent(aEvent.type, aEvent.bubbles, aEvent.cancelable,
-        this.iframeDoc.defaultView, aEvent.detail, aEvent.screenX,
-        aEvent.screenY, x, y, aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey,
-        aEvent.metaKey, aEvent.button, null);
-      element.dispatchEvent(newEvent);
-      aEvent.preventDefault();
-      aEvent.stopPropagation();
-      return;
-    }
-
-    // Stop inspection when the user clicks on a node.
-    if (InspectorUI.inspecting) {
-      if (aEvent.button == 0) {
-        let win = aEvent.target.ownerDocument.defaultView;
-        InspectorUI.stopInspecting();
-        win.focus();
-      }
-      aEvent.preventDefault();
-      aEvent.stopPropagation();
-    }
+    aEvent.preventDefault();
+    aEvent.stopPropagation();
   },
 
   /**
    * Handle mousemoves in panel when InspectorUI.inspecting is true.
    *
    * @param nsiDOMEvent aEvent
    *        The MouseEvent triggering the method.
    */
-  handleMouseMove: function IFH_handleMouseMove(aEvent)
+  handleMouseMove: function Highlighter_handleMouseMove(aEvent)
   {
-    if (!InspectorUI.inspecting) {
-      return;
-    }
-
     let element = InspectorUI.elementFromPoint(aEvent.target.ownerDocument,
       aEvent.clientX, aEvent.clientY);
     if (element && element != this.node) {
       InspectorUI.inspectNode(element);
     }
   },
 
   /**
    * Handle window resize events.
    */
-  handleResize: function IFH_handleResize()
-  {
-    let style = this.iframeContainer.style;
-    if (this.win.scrollMaxY && this.win.scrollbars.visible) {
-      style.paddingRight = this.getScrollbarWidth() + "px";
-    } else {
-      style.paddingRight = 0;
-    }
-    if (this.win.scrollMaxX && this.win.scrollbars.visible) {
-      style.paddingBottom = this.getScrollbarWidth() + "px";
-    } else {
-      style.paddingBottom = 0;
-    }
-
-    this.highlight();
-  },
-
-  /**
-   * Determine the scrollbar width in the current document.
-   *
-   * @returns number
-   *          The scrollbar width in pixels.
-   */
-  getScrollbarWidth: function IFH_getScrollbarWidth()
+  handleResize: function Highlighter_handleResize()
   {
-    if (this._scrollbarWidth) {
-      return this._scrollbarWidth;
-    }
-
-    let hbox = document.createElement("hbox");
-    hbox.setAttribute("style", "height: 0%; overflow: hidden");
-
-    let scrollbar = document.createElement("scrollbar");
-    scrollbar.setAttribute("orient", "vertical");
-    hbox.appendChild(scrollbar);
-
-    document.documentElement.appendChild(hbox);
-    this._scrollbarWidth = scrollbar.clientWidth;
-    document.documentElement.removeChild(hbox);
-
-    return this._scrollbarWidth;
-  },
-
-  /**
-   * Helper to listen for an event only once.
-   *
-   * @param nsIDOMEventTarget aTarget
-   *        The DOM event target you want to add an event listener to.
-   * @param string aName
-   *        The event name you want to listen for.
-   * @param function aCallback
-   *        The function you want to execute once for the given event.
-   * @param boolean aCapturing
-   *        Tells if you want to use capture for the event listener.
-   * @returns void
-   */
-  listenOnce: function IFH_listenOnce(aTarget, aName, aCallback, aCapturing)
-  {
-    aTarget.addEventListener(aName, function listenOnce_handler(aEvent) {
-      aTarget.removeEventListener(aName, listenOnce_handler, aCapturing);
-      aCallback.call(this, aEvent);
-    }, aCapturing);
+    this.highlight();
   },
 };
 
 ///////////////////////////////////////////////////////////////////////////
 //// InspectorUI
 
 /**
  * Main controller class for the Inspector.
@@ -780,28 +759,26 @@ var InspectorUI = {
     this.winID = this.getWindowID(this.win);
     if (!this.domplate) {
       Cu.import("resource:///modules/domplate.jsm", this);
       this.domplateUtils.setDOM(window);
     }
 
     this.openTreePanel();
 
-    this.browser.addEventListener("scroll", this, true);
     this.inspectCmd.setAttribute("checked", true);
   },
 
   /**
    * Initialize highlighter.
    */
   initializeHighlighter: function IUI_initializeHighlighter()
   {
-    Services.obs.addObserver(this.highlighterReady,
-      INSPECTOR_NOTIFICATIONS.HIGHLIGHTER_READY, false);
-    this.highlighter = new IFrameHighlighter(this.browser);
+    this.highlighter = new Highlighter(this.browser);
+    this.highlighterReady();
   },
 
   /**
    * Initialize the InspectorStore.
    */
   initializeStore: function IUI_initializeStore()
   {
     // First time opened, add the TabSelect listener
@@ -852,17 +829,16 @@ var InspectorUI = {
       }
       InspectorStore.setValue(this.winID, "inspecting", this.inspecting);
     }
 
     if (InspectorStore.isEmpty()) {
       gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
     }
 
-    this.browser.removeEventListener("scroll", this, true);
     this.stopInspecting();
     if (this.highlighter) {
       this.highlighter.destroy();
       this.highlighter = null;
     }
 
     if (this.treePanelDiv) {
       this.treePanelDiv.ownerPanel = null;
@@ -948,36 +924,29 @@ var InspectorUI = {
       }
       this.ioBox.select(this.selection, true, true, aScroll);
     }
   },
 
   /////////////////////////////////////////////////////////////////////////
   //// Event Handling
 
-  notifyReady: function IUI_notifyReady()
+  highlighterReady: function IUI_highlighterReady()
   {
     // Setup the InspectorStore or restore state
     this.initializeStore();
 
     if (InspectorStore.getValue(this.winID, "inspecting")) {
       this.startInspecting();
     }
 
     this.win.focus();
     Services.obs.notifyObservers(null, INSPECTOR_NOTIFICATIONS.OPENED, null);
   },
 
-  highlighterReady: function IUI_highlighterReady()
-  {
-    Services.obs.removeObserver(InspectorUI.highlighterReady,
-      INSPECTOR_NOTIFICATIONS.HIGHLIGHTER_READY, false);
-    InspectorUI.notifyReady();
-  },
-
   /**
    * Main callback handler for events.
    *
    * @param event
    *        The event to be handled.
    */
   handleEvent: function IUI_handleEvent(event)
   {
@@ -1035,19 +1004,16 @@ var InspectorUI = {
             if (this.inspecting) {
               this.stopInspecting();
               event.preventDefault();
               event.stopPropagation();
             }
             break;
         }
         break;
-      case "scroll":
-        this.highlighter.highlight();
-        break;
     }
   },
 
   /**
    * Handle click events in the html tree panel.
    * @param aEvent
    *        The mouse event.
    */
--- a/browser/base/content/openLocation.js
+++ b/browser/base/content/openLocation.js
@@ -91,27 +91,32 @@ function doEnabling()
 {
     dialog.open.disabled = !dialog.input.value;
 }
 
 function open()
 {
   var url;
   var postData = {};
+  var mayInheritPrincipal = {value: false};
   if (browser)
-    url = browser.getShortcutOrURI(dialog.input.value, postData);
+    url = browser.getShortcutOrURI(dialog.input.value, postData, mayInheritPrincipal);
   else
     url = dialog.input.value;
 
   try {
     // Whichever target we use for the load, we allow third-party services to
     // fixup the URI
     switch (dialog.openWhereList.value) {
       case "0":
-        browser.loadURI(url, null, postData.value, true);
+        var webNav = Components.interfaces.nsIWebNavigation;
+        var flags = webNav.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
+        if (!mayInheritPrincipal.value)
+          flags |= webNav.LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
+        browser.gBrowser.loadURIWithFlags(url, flags, null, null, postData.value);
         break;
       case "1":
         window.opener.delayedOpenWindow(getBrowserURL(), "all,dialog=no",
                                         url, postData.value, null, null, true);
         break;
       case "3":
         browser.delayedOpenTab(url, null, null, postData.value, true);
         break;
--- a/browser/base/content/scratchpad.js
+++ b/browser/base/content/scratchpad.js
@@ -638,16 +638,19 @@ var Scratchpad = {
       Services.prefs.clearUserPref(PREF_TABSIZE);
       tabsize = Services.prefs.getIntPref(PREF_TABSIZE);
     }
 
     let expandtab = Services.prefs.getBoolPref(PREF_EXPANDTAB);
     this._tabCharacter = expandtab ? (new Array(tabsize + 1)).join(" ") : "\t";
     this.textbox.style.MozTabSize = tabsize;
 
+    // Force LTR direction (otherwise the textbox inherits the locale direction)
+    this.textbox.style.direction = "ltr";
+
     this.insertIntro();
 
     // Make the Tab key work.
     this.textbox.addEventListener("keypress", this.onKeypress.bind(this), false);
 
     this.textbox.focus();
   },
 
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -772,22 +772,20 @@
         </body>
       </method>
 
       <method name="getWindowTitleForBrowser">
         <parameter name="aBrowser"/>
         <body>
           <![CDATA[
             var newTitle = "";
-            var docTitle;
             var docElement = this.ownerDocument.documentElement;
             var sep = docElement.getAttribute("titlemenuseparator");
 
-            if (aBrowser.docShell.contentViewer)
-              docTitle = aBrowser.contentTitle;
+            var docTitle = aBrowser.contentTitle;
 
             if (!docTitle)
               docTitle = docElement.getAttribute("titledefault");
 
             var modifier = docElement.getAttribute("titlemodifier");
             if (docTitle) {
               newTitle += docElement.getAttribute("titlepreface");
               newTitle += docTitle;
@@ -854,59 +852,69 @@
               if (this._lastRelatedTab != this.selectedTab)
                 this._lastRelatedTab.owner = null;
               this._lastRelatedTab = null;
             }
 
             var oldBrowser = this.mCurrentBrowser;
             if (oldBrowser) {
               oldBrowser.setAttribute("type", "content-targetable");
-              oldBrowser.docShell.isActive = false;
+              oldBrowser.docShellIsActive = false;
             }
 
             var updatePageReport = false;
             if (!oldBrowser ||
                 (oldBrowser.pageReport && !newBrowser.pageReport) ||
                 (!oldBrowser.pageReport && newBrowser.pageReport))
               updatePageReport = true;
 
             newBrowser.setAttribute("type", "content-primary");
-            newBrowser.docShell.isActive = true;
+            newBrowser.docShellIsActive =
+              (window.windowState != window.STATE_MINIMIZED);
             this.mCurrentBrowser = newBrowser;
             this.mCurrentTab = this.selectedTab;
             this.showTab(this.mCurrentTab);
 
             if (updatePageReport)
               this.mCurrentBrowser.updatePageReport();
 
             // Update the URL bar.
             var loc = this.mCurrentBrowser.currentURI;
 
+#ifdef MOZ_E10S_COMPAT
+            // Bug 666801 - WebProgress support for e10s and
+            // Bug 666809 - SecurityUI support for e10s
+#else
             var webProgress = this.mCurrentBrowser.webProgress;
             var securityUI = this.mCurrentBrowser.securityUI;
 
             this._callProgressListeners(null, "onLocationChange",
                                         [webProgress, null, loc], true, false);
 
             if (securityUI) {
               this._callProgressListeners(null, "onSecurityChange",
                                           [webProgress, null, securityUI.state], true, false);
             }
+#endif
 
             var listener = this.mTabListeners[this.tabContainer.selectedIndex] || null;
             if (listener && listener.mStateFlags) {
               this._callProgressListeners(null, "onUpdateCurrentBrowser",
                                           [listener.mStateFlags, listener.mStatus,
                                            listener.mMessage, listener.mTotalProgress],
                                           true, false);
             }
 
             // Don't switch the fast find or update the titlebar (bug 540248) - this tab switch is temporary
             if (!this._previewMode) {
+#ifdef MOZ_E10S_COMPAT
+              // Bug 666816 - TypeAheadFind support for e10s
+#else
               this._fastFind.setDocShell(this.mCurrentBrowser.docShell);
+#endif
 
               this.updateTitlebar();
 
               this.mCurrentTab.removeAttribute("titlechanged");
             }
 
             // If the new tab is busy, and our current state is not busy, then
             // we need to fire a start to all progress listeners.
@@ -1258,16 +1266,21 @@
             var b = document.createElementNS(
               "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                                              "browser");
             b.setAttribute("type", "content-targetable");
             b.setAttribute("message", "true");
             b.setAttribute("contextmenu", this.getAttribute("contentcontextmenu"));
             b.setAttribute("tooltip", this.getAttribute("contenttooltip"));
 
+            if (Services.prefs.getPrefType("browser.tabs.remote") == Services.prefs.PREF_BOOL &&
+                Services.prefs.getBoolPref("browser.tabs.remote")) {
+              b.setAttribute("remote", "true");
+            }
+
             if (window.gShowPageResizers && document.getElementById("addon-bar").collapsed &&
                 window.windowState == window.STATE_NORMAL) {
               b.setAttribute("showresizer", "true");
             }
 
             if (this.hasAttribute("autocompletepopup"))
               b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
             b.setAttribute("autoscrollpopup", this._autoScrollPopup.id);
@@ -1305,17 +1318,21 @@
 
             this.tabContainer.updateVisibility();
 
             // wire up a progress listener for the new browser object.
             var tabListener = this.mTabProgressListener(t, b, blank);
             const filter = Components.classes["@mozilla.org/appshell/component/browser-status-filter;1"]
                                      .createInstance(Components.interfaces.nsIWebProgress);
             filter.addProgressListener(tabListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
+#ifdef MOZ_E10S_COMPAT
+            // Bug 666801 - WebProgress support for e10s
+#else
             b.webProgress.addProgressListener(filter, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
+#endif
             this.mTabListeners[position] = tabListener;
             this.mTabFilters[position] = filter;
 
             b._fastFind = this.fastFind;
             b.droppedLinkHandler = handleDroppedLink;
 
             // Dispatch a new tab notification.  We do this once we're
             // entirely done, so that things are in a consistent state
@@ -1343,17 +1360,17 @@
                 b.loadURIWithFlags(aURI, flags, aReferrerURI, aCharset, aPostData);
               } catch (ex) {
                 Cu.reportError(ex);
               }
             }
 
             // We start our browsers out as inactive, and then maintain
             // activeness in the tab switcher.
-            b.docShell.isActive = false;
+            b.docShellIsActive = false;
 
             // Check if we're opening a tab related to the current tab and
             // move it to after the current tab.
             // aReferrerURI is null or undefined if the tab is opened from
             // an external application or bookmark, i.e. somewhere other
             // than the current tab.
             if ((aRelatedToCurrent == null ? aReferrerURI : aRelatedToCurrent) &&
                 Services.prefs.getBoolPref("browser.tabs.insertRelatedAfterCurrent")) {
@@ -1562,17 +1579,21 @@
             // We dispatch it before any teardown so that event listeners can
             // inspect the tab that's about to close.
             var evt = document.createEvent("UIEvent");
             evt.initUIEvent("TabClose", true, false, window, aTabWillBeMoved ? 1 : 0);
             aTab.dispatchEvent(evt);
 
             // Remove the tab's filter and progress listener.
             const filter = this.mTabFilters[aTab._tPos];
+#ifdef MOZ_E10S_COMPAT
+            // Bug 666801 - WebProgress support for e10s
+#else 
             browser.webProgress.removeProgressListener(filter);
+#endif
             filter.removeProgressListener(this.mTabListeners[aTab._tPos]);
             this.mTabListeners[aTab._tPos].destroy();
 
             if (browser.registeredOpenURI && !aTabWillBeMoved) {
               this._placesAutocomplete.unregisterOpenPage(browser.registeredOpenURI);
               delete browser.registeredOpenURI;
             }
 
@@ -2438,25 +2459,32 @@
 
       <method name="handleEvent">
         <parameter name="aEvent"/>
         <body><![CDATA[
           switch (aEvent.type) {
             case "keypress":
               this._handleKeyEvent(aEvent);
               break;
+            case "sizemodechange":
+              if (aEvent.target == window) {
+                this.mCurrentBrowser.docShellIsActive =
+                  (window.windowState != window.STATE_MINIMIZED);
+              }
+              break;
           }
         ]]></body>
       </method>
 
       <constructor>
         <![CDATA[
           this.mCurrentBrowser = this.mPanelContainer.childNodes[0].firstChild.firstChild;
           this.mCurrentTab = this.tabContainer.firstChild;
           document.addEventListener("keypress", this, false);
+          window.addEventListener("sizemodechange", this, false);
 
           var uniqueId = "panel" + Date.now();
           this.mPanelContainer.childNodes[0].id = uniqueId;
           this.mCurrentTab.linkedPanel = uniqueId;
           this.mCurrentTab._tPos = 0;
           this.mCurrentTab._fullyOpen = true;
           this.mCurrentTab.linkedBrowser = this.mCurrentBrowser;
 
@@ -2509,16 +2537,17 @@
             }
             browser.webProgress.removeProgressListener(this.mTabFilters[i]);
             this.mTabFilters[i].removeProgressListener(this.mTabListeners[i]);
             this.mTabFilters[i] = null;
             this.mTabListeners[i].destroy();
             this.mTabListeners[i] = null;
           }
           document.removeEventListener("keypress", this, false);
+          window.removeEventListener("sizemodechange", this, false);
         ]]>
       </destructor>
 
       <!-- Deprecated stuff, implemented for backwards compatibility. -->
       <method name="enterTabbedMode">
         <body>
           Application.console.log("enterTabbedMode is an obsolete method and " +
                                   "will be removed in a future release.");
--- a/browser/base/content/tabview/tabitems.js
+++ b/browser/base/content/tabview/tabitems.js
@@ -260,18 +260,21 @@ TabItem.prototype = Utils.extend(new Ite
   // treats it as a new tab. 
   _reconnect: function TabItem__reconnect() {
     Utils.assertThrow(!this._reconnected, "shouldn't already be reconnected");
     Utils.assertThrow(this.tab, "should have a xul:tab");
 
     let tabData = null;
     let self = this;
     let imageDataCb = function(imageData) {
+      // we could have been unlinked while waiting for the thumbnail to load
+      if (!self.tab)
+        return;
+
       Utils.assertThrow(tabData, "tabData");
-      
       tabData.imageData = imageData;
 
       let currentUrl = self.tab.linkedBrowser.currentURI.spec;
       // 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.
       if (tabData.imageData &&
           (tabData.url == currentUrl || currentUrl == 'about:blank')) {
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -215,16 +215,17 @@ endif
                  browser_scope.js \
                  browser_selectTabAtIndex.js \
                  browser_tab_dragdrop.js \
                  browser_tab_dragdrop2.js \
                  browser_tab_dragdrop2_frame1.xul \
                  browser_tabfocus.js \
                  browser_tabs_isActive.js \
                  browser_tabs_owner.js \
+                 browser_urlbarCopying.js \
                  browser_urlbarTrimURLs.js \
                  browser_urlHighlight.js \
                  browser_visibleFindSelection.js \
                  browser_visibleTabs.js \
                  browser_visibleTabs_contextMenu.js \
                  browser_visibleTabs_bookmarkAllPages.js \
                  browser_visibleTabs_bookmarkAllTabs.js \
                  browser_visibleTabs_tabPreview.js \
@@ -250,16 +251,17 @@ endif
                  browser_aboutHome.js \
                  app_bug575561.html \
                  app_subframe_bug575561.html \
                  browser_contentAreaClick.js \
                  browser_addon_bar_close_button.js \
                  browser_addon_bar_shortcut.js \
                  browser_addon_bar_aomlistener.js \
                  test_bug628179.html \
+                 browser_minimize.js \
                  $(NULL)
 
 ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 _BROWSER_FILES += \
 		browser_bug462289.js \
 		$(NULL)
 else
 _BROWSER_FILES += \
--- a/browser/base/content/test/browser_allTabsPanel.js
+++ b/browser/base/content/test/browser_allTabsPanel.js
@@ -1,10 +1,16 @@
 function test() {
   waitForExplicitFinish();
+
+  Services.prefs.setBoolPref(allTabs.prefName, true);
+  registerCleanupFunction(function () {
+    Services.prefs.clearUserPref(allTabs.prefName);
+  });
+
   allTabs.init();
   nextSequence();
 }
 
 var sequences = 3;
 var chars = "ABCDEFGHI";
 var closedTabs;
 var history;
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_minimize.js
@@ -0,0 +1,33 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+function waitForActive() {
+    if (!gBrowser.docShell.isActive) {
+        executeSoon(waitForActive);
+        return;
+    }
+    is(gBrowser.docShell.isActive, true, "Docshell should be active again");
+    finish();
+}
+
+function waitForInactive() {
+    if (gBrowser.docShell.isActive) {
+        executeSoon(waitForInactive);
+        return;
+    }
+    is(gBrowser.docShell.isActive, false, "Docshell should be inactive");
+    window.restore();
+    waitForActive();
+}
+
+function test() {
+    waitForExplicitFinish();
+    is(gBrowser.docShell.isActive, true, "Docshell should be active");
+    window.minimize();
+    // XXX On Linux minimize/restore seem to be very very async, but
+    // our window.windowState changes sync.... so we can't rely on the
+    // latter correctly reflecting the state of the former.  In
+    // particular, a restore() call before minimizing is done will not
+    // actually restore the window, but change the window state.  As a
+    // result, just poll waiting for our expected isActive values.
+    waitForInactive();
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_urlbarCopying.js
@@ -0,0 +1,165 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const trimPref = "browser.urlbar.trimURLs";
+
+function test() {
+
+  gBrowser.selectedTab = gBrowser.addTab();
+
+  registerCleanupFunction(function () {
+    gBrowser.removeCurrentTab();
+    Services.prefs.clearUserPref(trimPref);
+    URLBarSetURI();
+  });
+
+  Services.prefs.setBoolPref(trimPref, true);
+
+  waitForExplicitFinish();
+
+  nextTest();
+}
+
+var tests = [
+  // pageproxystate="invalid"
+  {
+    setURL: "http://example.com/",
+    expectedURL: "example.com",
+    copyExpected: "example.com"
+  },
+  {
+    copyVal: "<e>xample.com",
+    copyExpected: "e"
+  },
+
+
+  // pageproxystate="valid" from this point on (due to the load)
+  {
+    loadURL: "http://example.com/",
+    expectedURL: "example.com",
+    copyExpected: "http://example.com/"
+  },
+  {
+    copyVal: "<example.co>m",
+    copyExpected: "http://example.co"
+  },
+  {
+    copyVal: "e<x>ample.com",
+    copyExpected: "x"
+  },
+  {
+    copyVal: "<e>xample.com",
+    copyExpected: "http://e"
+  },
+
+  // Test escaping
+  {
+    loadURL: "http://example.com/()%C3%A9",
+    expectedURL: "example.com/()\xe9",
+    copyExpected: "http://example.com/%28%29%C3%A9"
+  },
+  {
+    copyVal: "<example.com/(>)\xe9",
+    copyExpected: "http://example.com/("
+  },
+  {
+    copyVal: "e<xample.com/(>)\xe9",
+    copyExpected: "xample.com/("
+  },
+
+  {
+    loadURL: "http://example.com/%C3%A9%C3%A9",
+    expectedURL: "example.com/\xe9\xe9",
+    copyExpected: "http://example.com/%C3%A9%C3%A9"
+  },
+  {
+    copyVal: "e<xample.com/\xe9>\xe9",
+    copyExpected: "xample.com/\xe9"
+  },
+  {
+    copyVal: "<example.com/\xe9>\xe9",
+    copyExpected: "http://example.com/\xe9"
+  },
+
+  // data: and javsacript: URIs shouldn't be encoded
+  {
+    loadURL: "javascript:('%C3%A9')",
+    expectedURL: "javascript:('\xe9')",
+    copyExpected: "javascript:('\xe9')"
+  },
+  {
+    copyVal: "<javascript:(>'\xe9')",
+    copyExpected: "javascript:("
+  },
+
+  {
+    loadURL: "data:text/html,(%C3%A9)",
+    expectedURL: "data:text/html,(\xe9)",
+    copyExpected: "data:text/html,(\xe9)"
+  },
+  {
+    copyVal: "<data:text/html,(>\xe9)",
+    copyExpected: "data:text/html,("
+  },
+  {
+    copyVal: "data:<text/html,(\xe9>)",
+    copyExpected: "text/html,(\xe9"
+  }
+];
+
+function nextTest() {
+  let test = tests.shift();
+  if (tests.length == 0)
+    runTest(test, finish);
+  else
+    runTest(test, nextTest);
+}
+
+function runTest(test, cb) {
+  function doCheck() {
+    if (test.setURL || test.loadURL)
+      is(gURLBar.value, test.expectedURL, "url bar value set");
+
+    testCopy(test.copyVal, test.copyExpected, cb);
+  }
+
+  if (test.loadURL) {
+    loadURL(test.loadURL, doCheck);
+  } else {
+    if (test.setURL)
+      gURLBar.value = test.setURL;
+    doCheck();
+  }
+}
+
+function testCopy(copyVal, targetValue, cb) {
+  info("Expecting copy of: " + targetValue);
+  waitForClipboard(targetValue, function () {
+    gURLBar.focus();
+    if (copyVal) {
+      let startBracket = copyVal.indexOf("<");
+      let endBracket = copyVal.indexOf(">");
+      if (startBracket == -1 || endBracket == -1 ||
+          startBracket > endBracket ||
+          copyVal.replace("<", "").replace(">", "") != gURLBar.value) {
+        ok(false, "invalid copyVal: " + copyVal);
+      }
+      gURLBar.selectionStart = startBracket;
+      gURLBar.selectionEnd = endBracket - 1;
+    } else {
+      gURLBar.select();
+    }
+
+    goDoCommand("cmd_copy");
+  }, cb, cb);
+}
+
+function loadURL(aURL, aCB) {
+  gBrowser.selectedBrowser.addEventListener("load", function () {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+    is(gBrowser.currentURI.spec, aURL, "loaded expected URL");
+    aCB();
+  }, true);
+
+  gBrowser.loadURI(aURL);
+}
--- a/browser/base/content/test/browser_urlbarTrimURLs.js
+++ b/browser/base/content/test/browser_urlbarTrimURLs.js
@@ -1,15 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 function testVal(originalValue, targetValue) {
   gURLBar.value = originalValue;
-  is(gURLBar.value, targetValue || originalValue, "original value: " + originalValue);
+  is(gURLBar.value, targetValue || originalValue, "url bar value set");
 }
 
 function test() {
   const prefname = "browser.urlbar.trimURLs";
 
   gBrowser.selectedTab = gBrowser.addTab();
 
   registerCleanupFunction(function () {
@@ -67,15 +67,15 @@ function test() {
     });
   }, true);
 
   gBrowser.loadURI("http://example.com/");
 }
 
 function testCopy(originalValue, targetValue, cb) {
   waitForClipboard(targetValue, function () {
-    is(gURLBar.value, originalValue);
+    is(gURLBar.value, originalValue, "url bar copy value set");
 
     gURLBar.focus();
     gURLBar.select();
     goDoCommand("cmd_copy");
   }, cb, cb);
 }
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -500,33 +500,50 @@
           }
         ]]></body>
       </method>
 
       <method name="_getSelectedValueForClipboard">
         <body><![CDATA[
           // Grab the actual input field's value, not our value, which could include moz-action:
           var inputVal = this.inputField.value;
-          var val = inputVal.substring(this.selectionStart, this.selectionEnd);
+          var selectedVal = inputVal.substring(this.selectionStart, this.selectionEnd);
+
+          // If the selection doesn't start at the beginning or URL bar is
+          // modified, nothing else to do here.
+          if (this.getAttribute("pageproxystate") != "valid" || this.selectionStart > 0)
+            return selectedVal;
+
+          let uri = gBrowser.currentURI;
 
-          // If the entire value is selected and it's a valid non-javascript,
-          // non-data URI, encode it.
-          if (val == inputVal &&
-              this.getAttribute("pageproxystate") == "valid") {
-            let uri = gBrowser.currentURI;
+          // If the entire URL is selected, just use the actual loaded URI.
+          if (inputVal == selectedVal) {
+            // ... but only if  isn't a javascript: or data: URI, since those
+            // are hard to read when encoded
+            if (!uri.schemeIs("javascript") && !uri.schemeIs("data")) {
+              // Parentheses are known to confuse third-party applications (bug 458565).
+              selectedVal = uri.spec.replace(/[()]/g, function (c) escape(c));
+            }
 
-            if (uri && !uri.schemeIs("javascript") && !uri.schemeIs("data")) {
-              val = uri.spec;
-
-              // Parentheses are known to confuse third-party applications (bug 458565).
-              val = val.replace(/[()]/g, function (c) escape(c));
-            }
+            return selectedVal;
           }
 
-          return val;
+          // Just the beginning of the URL is selected, check for a trimmed
+          // value
+          let spec = uri.spec;
+          let trimmedSpec = this.trimValue(spec);
+          if (spec != trimmedSpec) {
+            // Prepend the portion that trimValue removed from the beginning.
+            // This assumes trimValue will only truncate the URL at
+            // the beginning or end (or both).
+            let trimmedSegments = spec.split(trimmedSpec);
+            selectedVal = trimmedSegments[0] + selectedVal;
+          }
+
+          return selectedVal;
         ]]></body>
       </method>
 
       <field name="_copyCutController"><![CDATA[
         ({
           urlbar: this,
           doCommand: function(aCommand) {
             var urlbar = this.urlbar;
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -25,17 +25,16 @@ browser.jar:
         content/browser/aboutHome-snippet2.png        (content/aboutHome-snippet2.png)
         content/browser/aboutRobots-icon.png          (content/aboutRobots-icon.png)
         content/browser/aboutRobots-widget-left.png   (content/aboutRobots-widget-left.png)
 *       content/browser/browser.css                   (content/browser.css)
 *       content/browser/browser.js                    (content/browser.js)
 *       content/browser/browser.xul                   (content/browser.xul)
 *       content/browser/browser-tabPreviews.xml       (content/browser-tabPreviews.xml)
 *       content/browser/fullscreen-video.xhtml        (content/fullscreen-video.xhtml)
-        content/browser/highlighter.xhtml             (content/highlighter.xhtml)
 *       content/browser/inspector.html                (content/inspector.html)
 *       content/browser/scratchpad.xul                (content/scratchpad.xul)
 *       content/browser/scratchpad.js                 (content/scratchpad.js)
 *       content/browser/pageinfo/pageInfo.xul         (content/pageinfo/pageInfo.xul)
 *       content/browser/pageinfo/pageInfo.js          (content/pageinfo/pageInfo.js)
 *       content/browser/pageinfo/pageInfo.css         (content/pageinfo/pageInfo.css)
 *       content/browser/pageinfo/pageInfo.xml         (content/pageinfo/pageInfo.xml)
 *       content/browser/pageinfo/feeds.js             (content/pageinfo/feeds.js)
--- a/browser/branding/aurora/pref/firefox-branding.js
+++ b/browser/branding/aurora/pref/firefox-branding.js
@@ -4,17 +4,17 @@ pref("startup.homepage_welcome_url","");
 // The time interval between checks for a new version (in seconds)
 // nightly=8 hours, official=24 hours
 pref("app.update.interval", 28800);
 // The time interval between the downloading of mar file chunks in the
 // background (in seconds)
 pref("app.update.download.backgroundInterval", 60);
 // URL user can browse to manually if for some reason all update installation
 // attempts fail.
-pref("app.update.url.manual", "http://nightly.mozilla.org/");
+pref("app.update.url.manual", "http://www.mozilla.com/firefox/channel/");
 // A default value for the "More information about this update" link
 // supplied in the "An update is available" page of the update wizard. 
 pref("app.update.url.details", "http://www.mozilla.org/projects/%APP%/");
 
 // Release notes and vendor URLs
 pref("app.releaseNotesURL", "http://www.mozilla.org/projects/%APP%/%VERSION%/releasenotes/");
 pref("app.vendorURL", "http://www.mozilla.org/projects/%APP%/");
 
--- a/browser/components/places/tests/browser/browser_410196_paste_into_tags.js
+++ b/browser/components/places/tests/browser/browser_410196_paste_into_tags.js
@@ -19,22 +19,20 @@ Components.utils.import("resource://gre/
 const TEST_URL = "http://example.com/";
 const MOZURISPEC = "http://mozilla.com/";
 
 let gLibrary;
 let PlacesOrganizer;
 
 function test() {
   waitForExplicitFinish();
-  openLibrary(onLibraryReady);
+  gLibrary = openLibrary(onLibraryReady);
 }
 
-function onLibraryReady(library) {
-  gLibrary = library;
-
+function onLibraryReady() {
   ok(PlacesUtils, "PlacesUtils in scope");
   ok(PlacesUIUtils, "PlacesUIUtils in scope");
 
   PlacesOrganizer = gLibrary.PlacesOrganizer;
   ok(PlacesOrganizer, "Places organizer in scope");
 
   tests.makeHistVisit();
   tests.makeTag();
--- a/browser/components/places/tests/browser/browser_416459_cut.js
+++ b/browser/components/places/tests/browser/browser_416459_cut.js
@@ -1,23 +1,24 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 const TEST_URL = "http://example.com/";
 
 let gLibrary;
 let gItemId;
+let PlacesOrganizer;
 
 function test() {
   waitForExplicitFinish();
   gLibrary = openLibrary(onLibraryReady);
 }
 
-function onLibraryReady(library) {
+function onLibraryReady() {
   PlacesOrganizer = gLibrary.PlacesOrganizer;
 
   // Sanity checks.
   ok(PlacesUtils, "PlacesUtils in scope");
   ok(PlacesUIUtils, "PlacesUIUtils in scope");
   ok(PlacesOrganizer, "PlacesOrganizer in scope");
 
   gItemId = PlacesUtils.bookmarks.insertBookmark(
--- a/browser/components/places/tests/browser/browser_library_batch_delete.js
+++ b/browser/components/places/tests/browser/browser_library_batch_delete.js
@@ -91,26 +91,23 @@ gTests.push({
 
 function test() {
   waitForExplicitFinish();
   registerCleanupFunction(function () {
     PlacesUtils.bookmarks
                .removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
   });
 
-  openLibrary(function (library) {
-    gLibrary = library;
-    executeSoon(nextTest);
-  });
+  gLibrary = openLibrary(nextTest);
 }
 
 function nextTest() {
   if (gTests.length) {
     var test = gTests.shift();
     info("Start of test: " + test.desc);
     test.run();
   }
   else {
     // Close Library window.
     gLibrary.close();
-    executeSoon(finish);
+    finish();
   }
 }
--- a/browser/components/places/tests/browser/browser_library_left_pane_commands.js
+++ b/browser/components/places/tests/browser/browser_library_left_pane_commands.js
@@ -175,13 +175,10 @@ function nextTest() {
 
 function test() {
   waitForExplicitFinish();
   // Sanity checks.
   ok(PlacesUtils, "PlacesUtils is running in chrome context");
   ok(PlacesUIUtils, "PlacesUIUtils is running in chrome context");
 
   // Open Library.
-  openLibrary(function (library) {
-    gLibrary = library;
-    nextTest();
-  });
+  gLibrary = openLibrary(nextTest);
 }
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -40,16 +40,19 @@
 #ifndef MOZ_STATIC_JS
 @BINPATH@/@DLL_PREFIX@mozjs@DLL_SUFFIX@
 #endif
 @BINPATH@/@DLL_PREFIX@plc4@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@plds4@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@xpcom@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@nspr4@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@mozalloc@DLL_SUFFIX@
+#ifdef MOZ_MEMORY_DARWIN
+@BINPATH@/@DLL_PREFIX@jemalloc@DLL_SUFFIX@
+#endif
 #ifdef XP_MACOSX
 @BINPATH@/XUL
 #else
 @BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@
 #endif
 #ifdef XP_MACOSX
 @BINPATH@/@MOZ_CHILD_PROCESS_NAME@.app/
 @BINPATH@/@DLL_PREFIX@plugin_child_interpose@DLL_SUFFIX@
@@ -93,17 +96,16 @@
 #endif
 @BINPATH@/application.ini
 @BINPATH@/platform.ini
 #ifndef XP_OS2
 @BINPATH@/@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@
 #else
 @BINPATH@/mozsqlt3@DLL_SUFFIX@
 #endif
-@BINPATH@/README.txt
 @BINPATH@/blocklist.xml
 #ifdef XP_UNIX
 @BINPATH@/run-mozilla.sh
 #ifndef XP_MACOSX
 @BINPATH@/mozilla-xremote-client
 #endif
 #endif
 #ifdef MOZ_SPLASHSCREEN
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -224,16 +224,17 @@ extensions/testpilot@labs.mozilla.com/sk
 extensions/testpilot@labs.mozilla.com/tests/test_data_store.js
 greprefs/all.js
 greprefs/security-prefs.js
 greprefs/xpinstall.js
 install.rdf
 modules/JSON.jsm
 mozilla-runtime@BIN_SUFFIX@
 old-homepage-default.properties
+README.txt
 res/arrow.gif
 res/arrowd.gif
 res/broken-image.gif
 res/broken-image.png
 res/charsetData.properties
 res/charsetalias.properties
 res/cmessage.txt
 res/fonts/fontEncoding.properties
--- a/browser/locales/Makefile.in
+++ b/browser/locales/Makefile.in
@@ -120,37 +120,23 @@ libs::
 	    $(LOCALE_SRCDIR)/existing-profile-defaults.js > $(FINAL_TARGET)/defaults/existing-profile-defaults.js; \
 	fi
 install::
 	@if test -f "$(LOCALE_SRCDIR)/existing-profile-defaults.js"; then \
 	  $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
 	    $(LOCALE_SRCDIR)/existing-profile-defaults.js > $(DESTDIR)$(mozappdir)/defaults/existing-profile-defaults.js; \
 	fi
 
-README_FILE = $(call MERGE_FILE,README.txt)
-
 PROFILE_FILES = \
 	localstore.rdf \
 	mimeTypes.rdf \
 	$(NULL)
 
 PROFILE_CHROME = userChrome-example.css userContent-example.css
 
-libs:: $(README_FILE)
-ifeq ($(OS_ARCH),WINNT)
-	$(EXIT_ON_ERROR) \
-	for file in $^; do \
-	  $(PERL) -pe 's/(?<!\r)\n/\r\n/g;' < $$file > $(FINAL_TARGET)/`basename $$file`; \
-	done
-else
-ifneq ($(OS_ARCH),OS2)
-	$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)
-endif
-endif
-
 NO_JA_JP_MAC_AB_CD := $(if $(filter ja-JP-mac, $(AB_CD)),ja,$(AB_CD))
 
 %/defaults/profile/bookmarks.html: bookmarks.inc generic/profile/bookmarks.html.in
 	$(SYSINSTALL) -D $(dir $@)
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py \
 	  -I $< \
 	  -DAB_CD=$(NO_JA_JP_MAC_AB_CD) \
 	  $(srcdir)/generic/profile/bookmarks.html.in \
deleted file mode 100644
--- a/browser/locales/en-US/README.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-For information about installing, running and configuring Firefox 
-including a list of known issues and troubleshooting information, 
-refer to: http://getfirefox.com/releases/
-
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -1930,8 +1930,32 @@ panel[dimmed="true"] {
 }
 
 .statuspanel-label:-moz-locale-dir(rtl):not([mirror]),
 .statuspanel-label:-moz-locale-dir(ltr)[mirror] {
   border-left-style: solid;
   border-top-left-radius: .3em;
   margin-left: 1em;
 }
+
+/* Highlighter */
+
+.highlighter-veil {
+  background-color: rgba(0, 0, 0, 0.5);
+}
+
+#highlighter-close-button {
+  list-style-image: url("chrome://browser/skin/KUI-close.png");
+  top: 12px;
+  right: 12px;
+  cursor: pointer;
+}
+
+#highlighter-close-button:-moz-locale-dir(rtl)  {
+  right: auto;
+  left: 12px;
+}
+
+#highlighter-veil-transparentbox {
+  box-shadow: 0 0 0 1px rgba(0,0,0,0.5);
+  outline: 1px dashed rgba(255,255,255,0.5);
+  outline-offset: -1px;
+}
deleted file mode 100644
--- a/browser/themes/gnomestripe/browser/highlighter.css
+++ /dev/null
@@ -1,104 +0,0 @@
-/* ***** 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 Mozilla Inspector Module.
- *
- * 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):
- *   Rob Campbell <rcampbell@mozilla.com> (original author)
- *   Paul Rouget <paul@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 ***** */
-
-body {
-  margin: 0;
-  overflow: hidden;
-}
-
-#close-button {
-  background-image: url("KUI-close.png");
-  border: none;
-  padding: 0;
-  width: 24px;
-  height: 24px;
-  position: fixed;
-  top: 12px;
-  right: 12px;
-  z-index: 1;
-  cursor: pointer;
-}
-
-.veil {
-  background-color: rgba(0, 0, 0, 0.5);
-}
-
-.veil, #veil-middlebox, #veil-transparentbox {
-  -moz-transition: 0.1s;
-  -moz-transition-timing-function: linear;
-}
-
-#veil-container {
-  position: absolute;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-}
-
-#veil {
-  width: 100%;
-  height: 100%;
-  display: -moz-box;
-  -moz-box-orient: vertical;
-}
-
-#veil-topbox, #veil-bottombox {
-  width: 100%;
-}
-
-#veil-bottombox {
-  -moz-box-flex: 1;
-}
-
-#veil-middlebox {
-  display: -moz-box;
-  -moz-box-orient: horizontal;
-}
-
-#veil-leftbox, #veil-rightbox {
-  height: 100%;
-}
-
-#veil-rightbox {
-  -moz-box-flex: 1;
-}
-
-#veil {
-  vertical-align: top;
-}
--- a/browser/themes/gnomestripe/browser/jar.mn
+++ b/browser/themes/gnomestripe/browser/jar.mn
@@ -12,17 +12,16 @@ browser.jar:
   skin/classic/browser/actionicon-tab.png
 * skin/classic/browser/browser.css                    (browser.css)
 * skin/classic/browser/engineManager.css              (engineManager.css)
   skin/classic/browser/fullscreen-video.css
   skin/classic/browser/inspector.css
   skin/classic/browser/Geolocation-16.png
   skin/classic/browser/Geolocation-64.png
   skin/classic/browser/Go-arrow.png
-* skin/classic/browser/highlighter.css
   skin/classic/browser/identity.png
   skin/classic/browser/Info.png
   skin/classic/browser/KUI-close.png
   skin/classic/browser/monitor.png
   skin/classic/browser/monitor_16-10.png
 * skin/classic/browser/pageInfo.css
   skin/classic/browser/pageInfo.png
   skin/classic/browser/page-livemarks.png
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -2503,8 +2503,33 @@ panel[dimmed="true"] {
 }
 
 .statuspanel-label:-moz-locale-dir(rtl):not([mirror]),
 .statuspanel-label:-moz-locale-dir(ltr)[mirror] {
   border-left-style: solid;
   border-top-left-radius: .3em;
   margin-left: 1em;
 }
+
+
+/* Highlighter */
+
+.highlighter-veil {
+  background-color: rgba(0, 0, 0, 0.5);
+}
+
+#highlighter-close-button {
+  list-style-image: url("chrome://browser/skin/KUI-close.png");
+  top: 12px;
+  right: 12px;
+  cursor: pointer;
+}
+
+#highlighter-close-button:-moz-locale-dir(rtl)  {
+  right: auto;
+  left: 12px;
+}
+
+#highlighter-veil-transparentbox {
+  box-shadow: 0 0 0 1px rgba(0,0,0,0.5);
+  outline: 1px dashed rgba(255,255,255,0.5);
+  outline-offset: -1px;
+}
deleted file mode 100644
--- a/browser/themes/pinstripe/browser/highlighter.css
+++ /dev/null
@@ -1,104 +0,0 @@
-/* ***** 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 Mozilla Inspector Module.
- *
- * 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):
- *   Rob Campbell <rcampbell@mozilla.com> (original author)
- *   Paul Rouget <paul@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 ***** */
-
-body {
-  margin: 0;
-  overflow: hidden;
-}
-
-#close-button {
-  background-image: url("KUI-close.png");
-  border: none;
-  padding: 0;
-  width: 24px;
-  height: 24px;
-  position: fixed;
-  top: 12px;
-  right: 12px;
-  z-index: 1;
-  cursor: pointer;
-}
-
-.veil {
-  background-color: rgba(0, 0, 0, 0.5);
-}
-
-.veil, #veil-middlebox, #veil-transparentbox {
-  -moz-transition: 0.1s;
-  -moz-transition-timing-function: linear;
-}
-
-#veil-container {
-  position: absolute;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-}
-
-#veil {
-  width: 100%;
-  height: 100%;
-  display: -moz-box;
-  -moz-box-orient: vertical;
-}
-
-#veil-topbox, #veil-bottombox {
-  width: 100%;
-}
-
-#veil-bottombox {
-  -moz-box-flex: 1;
-}
-
-#veil-middlebox {
-  display: -moz-box;
-  -moz-box-orient: horizontal;
-}
-
-#veil-leftbox, #veil-rightbox {
-  height: 100%;
-}
-
-#veil-rightbox {
-  -moz-box-flex: 1;
-}
-
-#veil {
-  vertical-align: top;
-}
--- a/browser/themes/pinstripe/browser/jar.mn
+++ b/browser/themes/pinstripe/browser/jar.mn
@@ -10,17 +10,16 @@ browser.jar:
 #endif
   skin/classic/browser/actionicon-tab.png
 * skin/classic/browser/browser.css                          (browser.css)
 * skin/classic/browser/engineManager.css                    (engineManager.css)
   skin/classic/browser/fullscreen-video.css
   skin/classic/browser/Geolocation-16.png
   skin/classic/browser/Geolocation-64.png
   skin/classic/browser/Go-arrow.png
-* skin/classic/browser/highlighter.css
   skin/classic/browser/home.png
   skin/classic/browser/hud-style-check-box-checked.png
   skin/classic/browser/hud-style-check-box-empty.png
   skin/classic/browser/hud-style-dropmarker-double-arrows.png
   skin/classic/browser/hud-style-expander-closed.png
   skin/classic/browser/hud-style-expander-open.png
   skin/classic/browser/hud-style-new-folder-plus-sign.png
   skin/classic/browser/hud-style-twisties.png
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -597,18 +597,18 @@ menuitem.bookmark-item {
 }
 
 #navigator-toolbox[iconsize=small] > #nav-bar {
   padding-top: 1px;
   padding-bottom: 1px;
 }
 
 #navigator-toolbox[iconsize=large][mode=icons] > #nav-bar {
-  padding-left: 2px;
-  padding-right: 2px;
+  -moz-padding-start: 0;
+  -moz-padding-end: 2px;
 }
 
 #nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button,
 #nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker,
 #nav-bar .toolbarbutton-1 {
   -moz-appearance: none;
   padding: 1px 5px;
   background: rgba(151,152,153,.05)
@@ -660,27 +660,28 @@ menuitem.bookmark-item {
 
 #nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button:-moz-locale-dir(rtl),
 #nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:-moz-locale-dir(ltr) {
   border-top-left-radius: 0;
   border-bottom-left-radius: 0;
 }
 
 #nav-bar .toolbarbutton-1[disabled="true"] {
-  opacity: .8;
+  opacity: .4;
 }
 
 #nav-bar .toolbarbutton-1[disabled="true"] > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
 #nav-bar .toolbarbutton-1[disabled="true"] > .toolbarbutton-icon {
-  opacity: .5;
+  opacity: 1;
 }
 
 #nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled="true"]):not(:active):hover,
 #nav-bar .toolbarbutton-1:not([open="true"]):not(:active):hover > .toolbarbutton-menubutton-dropmarker:not([disabled="true"]),
-#nav-bar .toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):not([checked="true"]):not([open="true"]):not(:active):hover {
+#nav-bar .toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):not([checked="true"]):not([open="true"]):not(:active):hover,
+#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:not([disabled="true"]):not([open]):not(:active):hover > .toolbarbutton-icon {
   background-color: hsla(190,60%,70%,.5);
   border-color: hsla(190,50%,65%,.8) hsla(190,50%,50%,.8) hsla(190,50%,40%,.8);
   box-shadow: 0 0 0 1px rgba(255,255,255,.3) inset,
               0 0 0 1.5px rgba(255,255,255,.1) inset,
               0 0 3.5px hsl(190,90%,80%);
   -moz-transition: background-color .4s ease-in,
                    border-color .3s ease-in,
                    box-shadow .3s ease-in;
@@ -789,45 +790,57 @@ toolbar[mode="full"] .toolbarbutton-1 > 
 
 #nav-bar #back-button:-moz-locale-dir(rtl),
 #nav-bar #forward-button {
   border-top-left-radius: 0;
   border-bottom-left-radius: 0;
 }
 
 #navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button {
-  border-radius: 10000px;
-  padding: 0;
-  width: 30px;
-  height: 30px;
+  margin: -5px 0;
+  padding-top: 0;
+  padding-bottom: 0;
+  -moz-padding-start: 5px;
+  -moz-padding-end: 0;
   position: relative;
   z-index: 1;
-  margin-top: -2px;
-  margin-bottom: -2px;
+  border-radius: 0 10000px 10000px 0;
+  background: transparent;
+  border: none;
+  box-shadow: none;
+}
+
+#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:-moz-locale-dir(rtl) {
+  border-radius: 10000px 0 0 10000px;
+}
+
+#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button > .toolbarbutton-icon {
+  border-radius: 10000px;
+  padding: 5px;
   border: none;
   background-image: -moz-linear-gradient(rgba(251,252,253,.97), rgba(246,247,248,.5) 49%, 
                                          rgba(231,232,233,.45) 51%, rgba(225,226,229,.2));
   box-shadow: 0 0 0 1px rgba(255,255,255,.3) inset,
               0 0 0 2px rgba(255,255,255,.1) inset,
               0 0 0 1px rgba(0,0,0,.15),
               0 1px 0 rgba(0,0,0,.4),
               0 1px 1px rgba(0,0,0,.3);
 }
 
-#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:not([disabled="true"]):not([open="true"]):not(:active):hover {
+#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:not([disabled="true"]):not([open="true"]):not(:active):hover > .toolbarbutton-icon {
   box-shadow: 0 0 0 1px rgba(255,255,255,.3) inset,
               0 0 0 2px rgba(255,255,255,.1) inset,
               0 0 0 1px hsla(190,50%,40%,.3),
               0 1px 0 rgba(0,0,0,.4),
               0 1px 1px rgba(0,0,0,.3),
               0 0 5px 1px hsl(190,90%,80%);
 }
 
-#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:not([disabled="true"]):hover:active,
-#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button[open="true"] {
+#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:not([disabled="true"]):hover:active > .toolbarbutton-icon,
+#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button[open="true"] > .toolbarbutton-icon {
   box-shadow: 0 0 6.5px rgba(0,0,0,.4) inset,
               0 0 2px rgba(0,0,0,.4) inset,
               0 0 0 1px rgba(0,0,0,.65),
               0 2px 0 rgba(255,255,255,.4);
 }
 
 #navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar[currentset*="unified-back-forward-button"],
 #navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar:not([currentset]) {
@@ -2416,8 +2429,32 @@ panel[dimmed="true"] {
 }
 
 .statuspanel-label:-moz-locale-dir(rtl):not([mirror]),
 .statuspanel-label:-moz-locale-dir(ltr)[mirror] {
   border-left-style: solid;
   border-top-left-radius: .3em;
   margin-left: 1em;
 }
+
+/* Highlighter */
+
+.highlighter-veil {
+  background-color: rgba(0, 0, 0, 0.5);
+}
+
+#highlighter-close-button {
+  list-style-image: url("chrome://browser/skin/KUI-close.png");
+  top: 12px;
+  right: 12px;
+  cursor: pointer;
+}
+
+#highlighter-close-button:-moz-locale-dir(rtl)  {
+  right: auto;
+  left: 12px;
+}
+
+#highlighter-veil-transparentbox {
+  box-shadow: 0 0 0 1px rgba(0,0,0,0.5);
+  outline: 1px dashed rgba(255,255,255,0.5);
+  outline-offset: -1px;
+}
deleted file mode 100644
--- a/browser/themes/winstripe/browser/highlighter.css
+++ /dev/null
@@ -1,105 +0,0 @@
-/* ***** 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 Mozilla Inspector Module.
- *
- * 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):
- *   Rob Campbell <rcampbell@mozilla.com> (original author)
- *   Paul Rouget <paul@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 ***** */
-
-body {
-  margin: 0;
-  overflow: hidden;
-}
-
-#close-button {
-  background-image: url("KUI-close.png");
-  border: none;
-  padding: 0;
-  width: 24px;
-  height: 24px;
-  position: fixed;
-  top: 12px;
-  right: 12px;
-  z-index: 1;
-  cursor: pointer;
-}
-
-.veil {
-  background-color: rgba(0, 0, 0, 0.5);
-}
-
-.veil, #veil-middlebox, #veil-transparentbox {
-  -moz-transition: 0.1s;
-  -moz-transition-timing-function: linear;
-}
-
-#veil-container {
-  position: absolute;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-}
-
-#veil {
-  width: 100%;
-  height: 100%;
-  display: -moz-box;
-  -moz-box-orient: vertical;
-}
-
-#veil-topbox, #veil-bottombox {
-  width: 100%;
-}
-
-#veil-bottombox {
-  -moz-box-flex: 1;
-}
-
-#veil-middlebox {
-  display: -moz-box;
-  -moz-box-orient: horizontal;
-}
-
-#veil-leftbox, #veil-rightbox {
-  height: 100%;
-}
-
-#veil-rightbox {
-  -moz-box-flex: 1;
-}
-
-#veil {
-  vertical-align: top;
-}
-
--- a/browser/themes/winstripe/browser/jar.mn
+++ b/browser/themes/winstripe/browser/jar.mn
@@ -14,17 +14,16 @@ browser.jar:
         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)
 *       skin/classic/browser/engineManager.css                       (engineManager.css)
         skin/classic/browser/fullscreen-video.css
         skin/classic/browser/Geolocation-16.png
         skin/classic/browser/Geolocation-64.png
-*       skin/classic/browser/highlighter.css
         skin/classic/browser/Info.png                                (Info.png)
         skin/classic/browser/identity.png                            (identity.png)
         skin/classic/browser/keyhole-forward-mask.svg
         skin/classic/browser/KUI-background.png
         skin/classic/browser/KUI-close.png
         skin/classic/browser/mainwindow-dropdown-arrow.png
         skin/classic/browser/pageInfo.css
         skin/classic/browser/pageInfo.png                            (pageInfo.png)
@@ -129,17 +128,16 @@ browser.jar:
         skin/classic/aero/browser/actionicon-tab.png                 (actionicon-tab.png)
         skin/classic/aero/browser/appmenu-dropmarker.png
         skin/classic/aero/browser/appmenu-icons.png
 *       skin/classic/aero/browser/browser.css                        (browser-aero.css)
 *       skin/classic/aero/browser/engineManager.css                  (engineManager.css)
         skin/classic/aero/browser/fullscreen-video.css
         skin/classic/aero/browser/Geolocation-16.png
         skin/classic/aero/browser/Geolocation-64.png
-*       skin/classic/aero/browser/highlighter.css
         skin/classic/aero/browser/Info.png                           (Info-aero.png)
         skin/classic/aero/browser/identity.png                       (identity-aero.png)
         skin/classic/aero/browser/keyhole-forward-mask.svg
         skin/classic/aero/browser/KUI-background.png
         skin/classic/aero/browser/KUI-close.png
         skin/classic/aero/browser/mainwindow-dropdown-arrow.png      (mainwindow-dropdown-arrow-aero.png)
         skin/classic/aero/browser/pageInfo.css
         skin/classic/aero/browser/pageInfo.png                       (pageInfo-aero.png)
--- a/build/autoconf/libstdcxx.py
+++ b/build/autoconf/libstdcxx.py
@@ -62,12 +62,12 @@ def find_version(e):
 
     p = subprocess.Popen(['readelf', '-V', libstdcxx], stdout=subprocess.PIPE)
     versions = [parse_readelf_line(x)
                 for x in p.stdout.readlines() if 'Name: GLIBCXX' in x]
     last_version = sorted(versions, cmp = cmp_ver)[-1]
     return encode_ver(last_version)
 
 if __name__ == '__main__':
-    cxx_env = os.environ.get('CXX', 'c++')
+    cxx_env = os.environ['CXX']
     print 'MOZ_LIBSTDCXX_TARGET_VERSION=%s' % find_version(cxx_env)
     host_cxx_env = os.environ.get('HOST_CXX', cxx_env)
     print 'MOZ_LIBSTDCXX_HOST_VERSION=%s' % find_version(host_cxx_env)
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -758,17 +758,17 @@ user_pref("camino.use_system_proxy_setti
         logsource = stackFixerProcess.stdout
 
       (line, didTimeout) = self.readWithTimeout(logsource, timeout)
       while line != "" and not didTimeout:
         if "TEST-START" in line and "|" in line:
           self.lastTestSeen = line.split("|")[1].strip()
         if stackFixerFunction:
           line = stackFixerFunction(line)
-        self.log.info(line.rstrip())
+        self.log.info(line.rstrip().decode("UTF-8", "ignore"))
         if self.UNIXISH and not debuggerInfo and not self.haveDumpedScreen and "TEST-UNEXPECTED-FAIL" in line and "Test timed out" in line:
           self.dumpScreen(utilityPath)
 
         (line, didTimeout) = self.readWithTimeout(logsource, timeout)
         if not hitMaxTime and maxTime and datetime.now() - startTime > timedelta(seconds = maxTime):
           # Kill the application, but continue reading from stack fixer so as not to deadlock on stackFixerProcess.wait().
           hitMaxTime = True
           self.log.info("TEST-UNEXPECTED-FAIL | %s | application ran for longer than allowed maximum time of %d seconds", self.lastTestSeen, int(maxTime))
--- a/build/mobile/devicemanagerADB.py
+++ b/build/mobile/devicemanagerADB.py
@@ -34,16 +34,17 @@ class DeviceManagerADB(DeviceManager):
 
   # external function
   # returns:
   #  success: directory name
   #  failure: None
   def mkDir(self, name):
     try:
       self.checkCmd(["shell", "mkdir", name])
+      self.chmodDir(name)
       return name
     except:
       return None
 
   # make directory structure on the device
   # external function
   # returns:
   #  success: directory structure that we created
--- a/build/pgo/profileserver.py
+++ b/build/pgo/profileserver.py
@@ -86,26 +86,26 @@ if __name__ == '__main__':
           options.debuggerInteractive)
 
   httpd = EasyServer(("", PORT), SimpleHTTPServer.SimpleHTTPRequestHandler)
   t = threading.Thread(target=httpd.serve_forever)
   t.setDaemon(True) # don't hang on exit
   t.start()
   
   automation.setServerInfo("localhost", PORT)
-  automation.initializeProfile(PROFILE_DIRECTORY)
   browserEnv = automation.environment()
   browserEnv["XPCOM_DEBUG_BREAK"] = "warn"
   browserEnv["MOZ_JAR_LOG_DIR"] = MOZ_JAR_LOG_DIR
 
   url = "http://localhost:%d/index.html" % PORT
   appPath = os.path.join(SCRIPT_DIR, automation.DEFAULT_APP)
 
   for i in range(0, num_runs):
       if num_runs != 1:
           print "Starting profiling run %d of %d" % (i + 1, num_runs)
+      automation.initializeProfile(PROFILE_DIRECTORY)
       status = automation.runApp(url, browserEnv, appPath, PROFILE_DIRECTORY, {},
                                  debuggerInfo=debuggerInfo,
                                  # the profiling HTML doesn't output anything,
                                  # so let's just run this without a timeout
                                  timeout = None)
       if status != 0:
           sys.exit(status)
--- a/caps/include/nsSystemPrincipal.h
+++ b/caps/include/nsSystemPrincipal.h
@@ -54,17 +54,17 @@ class nsSystemPrincipal : public nsIPrin
 {
 public:
     // Our refcount is managed by mJSPrincipals.  Use this macro to avoid
     // an extra refcount member.
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSIPRINCIPAL
     NS_DECL_NSISERIALIZABLE
 
-    nsresult Init();
+    nsresult Init(JSPrincipals **jsprin);
 
     nsSystemPrincipal();
 
 protected:
     virtual ~nsSystemPrincipal(void);
 
     nsJSPrincipals mJSPrincipals;
     // XXX Probably unnecessary.  See bug 143559.
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -3374,17 +3374,18 @@ nsresult nsScriptSecurityManager::Init()
 
     rv = bundleService->CreateBundle("chrome://global/locale/security/caps.properties", &sStrBundle);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Create our system principal singleton
     nsRefPtr<nsSystemPrincipal> system = new nsSystemPrincipal();
     NS_ENSURE_TRUE(system, NS_ERROR_OUT_OF_MEMORY);
 
-    rv = system->Init();
+    JSPrincipals *jsprin;
+    rv = system->Init(&jsprin);
     NS_ENSURE_SUCCESS(rv, rv);
 
     mSystemPrincipal = system;
 
     //-- Register security check callback in the JS engine
     //   Currently this is used to control access to function.caller
     nsCOMPtr<nsIJSRuntimeService> runtimeService =
         do_QueryInterface(sXPConnect, &rv);
@@ -3401,16 +3402,18 @@ nsresult nsScriptSecurityManager::Init()
     };
 
 #ifdef DEBUG
     JSSecurityCallbacks *oldcallbacks =
 #endif
     JS_SetRuntimeSecurityCallbacks(sRuntime, &securityCallbacks);
     NS_ASSERTION(!oldcallbacks, "Someone else set security callbacks!");
 
+    JS_SetTrustedPrincipals(sRuntime, jsprin);
+
     return NS_OK;
 }
 
 static nsScriptSecurityManager *gScriptSecMan = nsnull;
 
 jsid nsScriptSecurityManager::sEnabledID   = JSID_VOID;
 
 nsScriptSecurityManager::~nsScriptSecurityManager(void)
@@ -3424,16 +3427,17 @@ nsScriptSecurityManager::~nsScriptSecuri
     gScriptSecMan = nsnull;
 }
 
 void
 nsScriptSecurityManager::Shutdown()
 {
     if (sRuntime) {
         JS_SetRuntimeSecurityCallbacks(sRuntime, NULL);
+        JS_SetTrustedPrincipals(sRuntime, NULL);
         sRuntime = nsnull;
     }
     sEnabledID = JSID_VOID;
 
     NS_IF_RELEASE(sIOService);
     NS_IF_RELEASE(sXPConnect);
     NS_IF_RELEASE(sJSContextStack);
     NS_IF_RELEASE(sStrBundle);
--- a/caps/src/nsSystemPrincipal.cpp
+++ b/caps/src/nsSystemPrincipal.cpp
@@ -309,24 +309,28 @@ nsSystemPrincipal::nsSystemPrincipal()
 }
 
 // Don't rename the system principal!
 // The JS engine (NewCompartment) relies on this name. 
 // XXX: bug 669123 will fix this hack.
 #define SYSTEM_PRINCIPAL_SPEC "[System Principal]"
 
 nsresult
-nsSystemPrincipal::Init()
+nsSystemPrincipal::Init(JSPrincipals **jsprin)
 {
     // Use an nsCString so we only do the allocation once here and then
     // share with nsJSPrincipals
     nsCString str(SYSTEM_PRINCIPAL_SPEC);
     if (!str.EqualsLiteral(SYSTEM_PRINCIPAL_SPEC)) {
         NS_WARNING("Out of memory initializing system principal");
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
-    return mJSPrincipals.Init(this, str);
+    nsresult rv = mJSPrincipals.Init(this, str);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    *jsprin = &mJSPrincipals;
+    return NS_OK;
 }
 
 nsSystemPrincipal::~nsSystemPrincipal(void)
 {
 }
--- a/configure.in
+++ b/configure.in
@@ -5676,16 +5676,33 @@ MOZ_ARG_ENABLE_BOOL(ipdl-tests,
 
 if test -n "$MOZ_IPDL_TESTS"; then
     AC_DEFINE(MOZ_IPDL_TESTS)
 fi
 
 AC_SUBST(MOZ_IPDL_TESTS)
 
 dnl ========================================================
+dnl = Turns off code necessary for e10s compatibility
+dnl ========================================================
+dnl This is a temporary flag to be removed in bug 662601 when
+dnl it's no longer needed
+
+MOZ_E10S_COMPAT=
+
+MOZ_ARG_ENABLE_BOOL(e10s-compat,
+[  --enable-e10s-compat     Turns off code for e10s compat],
+    MOZ_E10S_COMPAT=1,
+    MOZ_E10S_COMPAT=)
+
+if test -n "$MOZ_E10S_COMPAT"; then
+    AC_DEFINE(MOZ_E10S_COMPAT)
+fi
+
+dnl ========================================================
 dnl = Disable building dbm
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(dbm,
 [  --disable-dbm           Disable building dbm],
     NSS_DISABLE_DBM=1,
     NSS_DISABLE_DBM=)
 
 dnl bi-directional support always on
@@ -7454,22 +7471,22 @@ else
     DLLFLAGS="$DLLFLAGS $MOZ_MEMORY_LDFLAGS"
     export DLLFLAGS
     ;;
   *)
     AC_MSG_ERROR([--enable-jemalloc not supported on ${target}])
     ;;
   esac
 
-  if test "$OS_ARCH" != "Darwin"; then
+  if test "$OS_ARCH" != "WINNT"; then
     dnl NB: this must be kept in sync with jemalloc.h
     AC_DEFINE(HAVE_JEMALLOC_VALLOC)
-    AC_DEFINE(HAVE_JEMALLOC_POSIX_MEMALIGN)
-    AC_DEFINE(HAVE_JEMALLOC_MEMALIGN)
   fi
+  AC_DEFINE(HAVE_JEMALLOC_POSIX_MEMALIGN)
+  AC_DEFINE(HAVE_JEMALLOC_MEMALIGN)
 fi # MOZ_MEMORY
 AC_SUBST(MOZ_MEMORY)
 AC_SUBST(MOZ_MEMORY_LDFLAGS)
 AC_SUBST(WIN32_OLD_STYLE_JEMALLOC)
 AC_SUBST(WIN32_CRT_LIBS)
 AC_SUBST(WIN32_CRT_SRC_DIR)
 dnl Need to set this for make because NSS doesn't have configure
 AC_SUBST(DLLFLAGS)
@@ -7676,17 +7693,17 @@ dnl ====================================
 STDCXX_COMPAT=
 MOZ_ARG_ENABLE_BOOL(stdcxx-compat,
 [  --enable-stdcxx-compat  Enable compatibility with older libstdc++],
     STDCXX_COMPAT=stdc++compat.cpp)
 
 AC_SUBST(STDCXX_COMPAT)
 
 if test -n "$STDCXX_COMPAT"; then
-   eval $($PYTHON $_topsrcdir/build/autoconf/libstdcxx.py)
+   eval $(CXX="$CXX" $PYTHON $_topsrcdir/build/autoconf/libstdcxx.py)
    AC_SUBST(MOZ_LIBSTDCXX_TARGET_VERSION)
    AC_SUBST(MOZ_LIBSTDCXX_HOST_VERSION)
 fi
 
 dnl ========================================================
 dnl = 
 dnl = Profiling and Instrumenting
 dnl = 
--- a/content/base/public/nsDOMFile.h
+++ b/content/base/public/nsDOMFile.h
@@ -49,145 +49,213 @@
 #include "nsCOMArray.h"
 #include "nsCOMPtr.h"
 #include "mozilla/AutoRestore.h"
 #include "nsString.h"
 #include "nsIXMLHttpRequest.h"
 #include "prmem.h"
 #include "nsAutoPtr.h"
 
+#ifndef PR_UINT64_MAX
+#define PR_UINT64_MAX (~(PRUint64)(0))
+#endif
+
 class nsIFile;
 class nsIInputStream;
 class nsIClassInfo;
 class nsIBlobBuilder;
 
 nsresult NS_NewBlobBuilder(nsISupports* *aSupports);
-void ParseSize(PRInt64 aSize, PRInt64& aStart, PRInt64& aEnd);
 
-class nsDOMFile : public nsIDOMFile,
-                  public nsIXHRSendable,
-                  public nsIJSNativeInitializer
+class nsDOMFileBase : public nsIDOMFile,
+                      public nsIXHRSendable
 {
 public:
+
+  nsDOMFileBase(const nsAString& aName, const nsAString& aContentType,
+                PRUint64 aLength)
+    : mIsFile(true), mContentType(aContentType), mName(aName),
+      mStart(0), mLength(aLength)
+  {
+    // Ensure non-null mContentType by default
+    mContentType.SetIsVoid(PR_FALSE);
+  }
+
+  nsDOMFileBase(const nsAString& aContentType, PRUint64 aLength)
+    : mIsFile(false), mContentType(aContentType),
+      mStart(0), mLength(aLength)
+  {
+    // Ensure non-null mContentType by default
+    mContentType.SetIsVoid(PR_FALSE);
+  }
+
+  nsDOMFileBase(const nsAString& aContentType,
+                PRUint64 aStart, PRUint64 aLength)
+    : mIsFile(false), mContentType(aContentType),
+      mStart(aStart), mLength(aLength)
+  {
+    NS_ASSERTION(aLength != PR_UINT64_MAX,
+                 "Must know length when creating slice");
+    // Ensure non-null mContentType by default
+    mContentType.SetIsVoid(PR_FALSE);
+  }
+
+  virtual ~nsDOMFileBase() {}
+
+  virtual already_AddRefed<nsIDOMBlob>
+  CreateSlice(PRUint64 aStart, PRUint64 aLength,
+              const nsAString& aContentType) = 0;
+
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMBLOB
   NS_DECL_NSIDOMFILE
   NS_DECL_NSIXHRSENDABLE
 
-  nsDOMFile(nsIFile *aFile, const nsAString& aContentType,
-            nsISupports *aCacheToken = nsnull)
-    : mFile(aFile),
-      mCacheToken(aCacheToken),
-      mContentType(aContentType),
-      mIsFullFile(true)
-  {}
+protected:
+  bool IsSizeUnknown()
+  {
+    return mLength == PR_UINT64_MAX;
+  }
+
+  bool mIsFile;
+  nsString mContentType;
+  nsString mName;
 
-  nsDOMFile(nsIFile *aFile)
-    : mFile(aFile),
-      mIsFullFile(true)
-  {}
+  PRUint64 mStart;
+  PRUint64 mLength;
+};
 
-  nsDOMFile(const nsDOMFile* aOther, PRUint64 aStart, PRUint64 aLength,
-            const nsAString& aContentType)
-    : mFile(aOther->mFile),
-      mCacheToken(aOther->mCacheToken),
-      mStart(aOther->mIsFullFile ? aStart :
-                                   (aOther->mStart + aStart)),
-      mLength(aLength),
-      mContentType(aContentType),
-      mIsFullFile(false)
+class nsDOMFileFile : public nsDOMFileBase,
+                      public nsIJSNativeInitializer
+{
+public:
+  // Create as a file
+  nsDOMFileFile(nsIFile *aFile)
+    : nsDOMFileBase(EmptyString(), EmptyString(), PR_UINT64_MAX),
+      mFile(aFile), mWholeFile(true)
   {
     NS_ASSERTION(mFile, "must have file");
-    // Ensure non-null mContentType
-    mContentType.SetIsVoid(PR_FALSE);
+    // Lazily get the content type and size
+    mContentType.SetIsVoid(PR_TRUE);
+    mFile->GetLeafName(mName);
   }
 
-  virtual ~nsDOMFile() {}
+  // Create as a blob
+  nsDOMFileFile(nsIFile *aFile, const nsAString& aContentType,
+                nsISupports *aCacheToken = nsnull)
+    : nsDOMFileBase(aContentType, PR_UINT64_MAX),
+      mFile(aFile), mWholeFile(true),
+      mCacheToken(aCacheToken)
+  {
+    NS_ASSERTION(mFile, "must have file");
+  }
+
+  // Create as a file to be later initialized
+  nsDOMFileFile()
+    : nsDOMFileBase(EmptyString(), EmptyString(), PR_UINT64_MAX),
+      mWholeFile(true)
+  {
+    // Lazily get the content type and size
+    mContentType.SetIsVoid(PR_TRUE);
+    mName.SetIsVoid(PR_TRUE);
+  }
+
+  NS_DECL_ISUPPORTS_INHERITED
 
   // nsIJSNativeInitializer
   NS_IMETHOD Initialize(nsISupports* aOwner,
                         JSContext* aCx,
                         JSObject* aObj,
                         PRUint32 aArgc,
                         jsval* aArgv);
 
+  // Overrides
+  NS_IMETHOD GetSize(PRUint64* aSize);
+  NS_IMETHOD GetType(nsAString& aType);
+  NS_IMETHOD GetMozFullPathInternal(nsAString& aFullPath);
+  NS_IMETHOD GetInternalStream(nsIInputStream**);
+
   // DOMClassInfo constructor (for File("foo"))
   static nsresult
   NewFile(nsISupports* *aNewObject);
 
 protected:
-  nsCOMPtr<nsIFile> mFile;
-  nsCOMPtr<nsISupports> mCacheToken;
+  // Create slice
+  nsDOMFileFile(const nsDOMFileFile* aOther, PRUint64 aStart, PRUint64 aLength,
+                const nsAString& aContentType)
+    : nsDOMFileBase(aContentType, aOther->mStart + aStart, aLength),
+      mFile(aOther->mFile), mWholeFile(false),
+      mCacheToken(aOther->mCacheToken)
+  {
+    NS_ASSERTION(mFile, "must have file");
+  }
+  virtual already_AddRefed<nsIDOMBlob>
+  CreateSlice(PRUint64 aStart, PRUint64 aLength,
+              const nsAString& aContentType);
 
-  // start and length in 
-  PRUint64 mStart;
-  PRUint64 mLength;
-
-  nsString mContentType;
-  
-  bool mIsFullFile;
+  nsCOMPtr<nsIFile> mFile;
+  bool mWholeFile;
+  nsCOMPtr<nsISupports> mCacheToken;
 };
 
-class nsDOMMemoryFile : public nsDOMFile
+class nsDOMMemoryFile : public nsDOMFileBase
 {
 public:
+  // Create as file
   nsDOMMemoryFile(void *aMemoryBuffer,
                   PRUint64 aLength,
                   const nsAString& aName,
                   const nsAString& aContentType)
-    : nsDOMFile(nsnull, aContentType),
-      mDataOwner(new DataOwner(aMemoryBuffer)),
-      mName(aName)
+    : nsDOMFileBase(aName, aContentType, aLength),
+      mDataOwner(new DataOwner(aMemoryBuffer))
   {
-    mStart = 0;
-    mLength = aLength;
+    NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
   }
 
+  // Create as blob
+  nsDOMMemoryFile(void *aMemoryBuffer,
+                  PRUint64 aLength,
+                  const nsAString& aContentType)
+    : nsDOMFileBase(aContentType, aLength),
+      mDataOwner(new DataOwner(aMemoryBuffer))
+  {
+    NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
+  }
+
+  NS_IMETHOD GetInternalStream(nsIInputStream**);
+
+protected:
+  // Create slice
   nsDOMMemoryFile(const nsDOMMemoryFile* aOther, PRUint64 aStart,
                   PRUint64 aLength, const nsAString& aContentType)
-    : nsDOMFile(nsnull, aContentType),
+    : nsDOMFileBase(aContentType, aOther->mStart + aStart, aLength),
       mDataOwner(aOther->mDataOwner)
   {
     NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
-
-    mIsFullFile = false;
-    mStart = aOther->mStart + aStart;
-    mLength = aLength;
-
-    // Ensure non-null mContentType
-    mContentType.SetIsVoid(PR_FALSE);
   }
+  virtual already_AddRefed<nsIDOMBlob>
+  CreateSlice(PRUint64 aStart, PRUint64 aLength,
+              const nsAString& aContentType);
 
-  NS_IMETHOD GetName(nsAString&);
-  NS_IMETHOD GetSize(PRUint64*);
-  NS_IMETHOD GetInternalStream(nsIInputStream**);
-  NS_IMETHOD GetMozFullPathInternal(nsAString&);
-  NS_IMETHOD MozSlice(PRInt64 aStart, PRInt64 aEnd,
-                      const nsAString& aContentType, PRUint8 optional_argc,
-                      nsIDOMBlob **aBlob);
-
-protected:
   friend class DataOwnerAdapter; // Needs to see DataOwner
   class DataOwner {
   public:
     NS_INLINE_DECL_REFCOUNTING(DataOwner)
     DataOwner(void* aMemoryBuffer)
       : mData(aMemoryBuffer)
     {
     }
     ~DataOwner() {
       PR_Free(mData);
     }
     void* mData;
   };
 
   // Used when backed by a memory store
   nsRefPtr<DataOwner> mDataOwner;
-
-  nsString mName;
 };
 
 class nsDOMFileList : public nsIDOMFileList
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMFILELIST
 
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -38,16 +38,17 @@
 #define nsIContent_h___
 
 #include "nsCOMPtr.h" // for already_AddRefed
 #include "nsStringGlue.h"
 #include "nsCaseTreatment.h"
 #include "nsChangeHint.h"
 #include "nsINode.h"
 #include "nsIDocument.h" // for IsInHTMLDocument
+#include "nsDOMMemoryReporter.h"
 
 // Forward declarations
 class nsIAtom;
 class nsIDOMEvent;
 class nsIContent;
 class nsEventListenerManager;
 class nsIURI;
 class nsRuleWalker;
@@ -71,18 +72,18 @@ enum nsLinkState {
   eLinkState_Unknown    = 0,
   eLinkState_Unvisited  = 1,
   eLinkState_Visited    = 2,
   eLinkState_NotLink    = 3
 };
 
 // IID for the nsIContent interface
 #define NS_ICONTENT_IID       \
-{ 0x860ee35b, 0xe505, 0x438f, \
- { 0xa7, 0x7b, 0x65, 0xb9, 0xf5, 0x0b, 0xe5, 0x29 } }
+{ 0x4aad2c06, 0xd6c3, 0x4f44, \
+ { 0x94, 0xf9, 0xd5, 0xac, 0xe5, 0x04, 0x67, 0xec } }
 
 /**
  * A node of content in a document's content model. This interface
  * is supported by all content objects.
  */
 class nsIContent : public nsINode {
 public:
 #ifdef MOZILLA_INTERNAL_API
@@ -95,16 +96,18 @@ public:
   {
     NS_ASSERTION(mNodeInfo,
                  "No nsINodeInfo passed to nsIContent, PREPARE TO CRASH!!!");
   }
 #endif // MOZILLA_INTERNAL_API
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENT_IID)
 
+  NS_DECL_AND_IMPL_DOM_MEMORY_REPORTER_SIZEOF(nsIContent, nsINode);
+
   /**
    * Bind this content node to a tree.  If this method throws, the caller must
    * call UnbindFromTree() on the node.  In the typical case of a node being
    * appended to a parent, this will be called after the node has been added to
    * the parent's child list and before nsIDocumentObserver notifications for
    * the addition are dispatched.
    * @param aDocument The new document for the content node.  Must match the
    *                  current document of aParent, if aParent is not null.
@@ -941,20 +944,16 @@ public:
    */
   nsIContent* GetEditingHost();
 
   // Overloaded from nsINode
   virtual already_AddRefed<nsIURI> GetBaseURI() const;
 
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
 
-  PRInt64 SizeOf() const {
-    return sizeof(*this);
-  }
-
 protected:
   /**
    * Hook for implementing GetID.  This is guaranteed to only be
    * called if HasID() is true.
    */
   virtual nsIAtom* DoGetID() const = 0;
 
 private:
--- a/content/base/public/nsIDOMFile.idl
+++ b/content/base/public/nsIDOMFile.idl
@@ -42,40 +42,41 @@
 %}
 
 interface nsIDOMFileError;
 interface nsIInputStream;
 interface nsIURI;
 interface nsIPrincipal;
 interface nsIDOMBlob;
 
-[scriptable, uuid(d5237f31-443a-460b-9e42-449a135346f0)]
+[scriptable, builtinclass, uuid(d5237f31-443a-460b-9e42-449a135346f0)]
 interface nsIDOMBlob : nsISupports
 {
   readonly attribute unsigned long long size;
   readonly attribute DOMString type;
 
   [noscript] readonly attribute nsIInputStream internalStream;
   // The caller is responsible for releasing the internalUrl from the
   // moz-filedata: protocol handler
   [noscript] DOMString getInternalUrl(in nsIPrincipal principal);
 
-  [optional_argc] nsIDOMBlob mozSlice(in long long start,
+  [optional_argc] nsIDOMBlob mozSlice([optional] in long long start,
                                       [optional] in long long end,
                                       [optional] in DOMString contentType);
 };
 
-[scriptable, uuid(b096ef67-7b77-47f8-8e70-5d8ee36416bf)]
+[scriptable, builtinclass, uuid(b096ef67-7b77-47f8-8e70-5d8ee36416bf)]
 interface nsIDOMFile : nsIDOMBlob
 {
   readonly attribute DOMString name;
   readonly attribute DOMString mozFullPath;
 
   // This performs no security checks!
   [noscript] readonly attribute DOMString mozFullPathInternal;
 };
 
-[scriptable, uuid(c4a77171-039b-4f84-97f9-820fb51626af)]
+[scriptable, builtinclass, uuid(006d2cde-ec18-41d4-acc3-43682dd418e2)]
 interface nsIDOMMozBlobBuilder : nsISupports
 {
   nsIDOMBlob getBlob([optional] in DOMString contentType);
+  nsIDOMFile getFile(in DOMString name, [optional] in DOMString contentType);
   [implicit_jscontext] void append(in jsval data);
 };
--- a/content/base/public/nsIFrameLoader.idl
+++ b/content/base/public/nsIFrameLoader.idl
@@ -136,17 +136,17 @@ interface nsIContentViewManager : nsISup
                          [retval, array, size_is(aLength)] out nsIContentView aResult);
 
   /**
    * The root content view.
    */
   readonly attribute nsIContentView rootContentView;
 };
 
-[scriptable, uuid(13c512d6-fba0-402a-9244-fe7941c43965)]
+[scriptable, uuid(12905a29-4246-475a-81d4-fc389197df02)]
 interface nsIFrameLoader : nsISupports
 {
   /**
    * Get the docshell from the frame loader.
    */
   readonly attribute nsIDocShell docShell;
 
   /**
@@ -183,16 +183,22 @@ interface nsIFrameLoader : nsISupports
 
   /**
    * Activate remote frame.
    * Throws an exception with non-remote frames.
    */
   void activateRemoteFrame();
 
   /**
+   * Deactivate remote frame.
+   * Throws an exception with non-remote frames.
+   */
+  void deactivateRemoteFrame();
+
+  /**
    * @see nsIDOMWindowUtils sendMouseEvent.
    */
   void sendCrossProcessMouseEvent(in AString aType,
                                   in float aX,
                                   in float aY,
                                   in long aButton,
                                   in long aClickCount,
                                   in long aModifiers,
@@ -229,16 +235,34 @@ interface nsIFrameLoader : nsISupports
    *
    * NB: when async scrolling is enabled, it's the *user's*
    * responsibility to update the target scroll offset.  In effect,
    * the platform hands over control of scroll offset to the user.
    */
   const unsigned long RENDER_MODE_ASYNC_SCROLL   = 0x00000001;
 
   attribute unsigned long renderMode;
+
+  /**
+   * The default event mode automatically forwards the events
+   * handled in nsEventStateManager::HandleCrossProcessEvent to
+   * the child content process when these events are targeted to
+   * the remote browser element.
+   *
+   * Used primarly for input events (mouse, keyboard)
+   */
+  const unsigned long EVENT_MODE_NORMAL_DISPATCH = 0x00000000;
+
+  /**
+   * With this event mode, it's the application's responsability to 
+   * convert and forward events to the content process
+   */
+  const unsigned long EVENT_MODE_DONT_FORWARD_TO_CHILD = 0x00000001;
+
+  attribute unsigned long eventMode;
 };
 
 native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);
 
 [scriptable, uuid(5879040e-83e9-40e3-b2bb-5ddf43b76e47)]
 interface nsIFrameLoaderOwner : nsISupports
 {
   /**
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -275,30 +275,34 @@ private:
 #define DOM_USER_DATA         1
 #define DOM_USER_DATA_HANDLER 2
 #ifdef MOZ_SMIL
 #define SMIL_MAPPED_ATTR_ANIMVAL 3
 #endif // MOZ_SMIL
 
 // IID for the nsINode interface
 #define NS_INODE_IID \
-{ 0x4776aa9a, 0xa886, 0x40c9, \
- { 0xae, 0x4c, 0x4d, 0x92, 0xe2, 0xf0, 0xd9, 0x61 } }
+{ 0xc7abbb40, 0x2571, 0x4d12, \
+ { 0x8f, 0x89, 0x0d, 0x4f, 0x55, 0xc0, 0x92, 0xf6 } }
 
 /**
  * An internal interface that abstracts some DOMNode-related parts that both
  * nsIContent and nsIDocument share.  An instance of this interface has a list
  * of nsIContent children and provides access to them.
  */
 class nsINode : public nsIDOMEventTarget,
                 public nsWrapperCache
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODE_IID)
 
+  virtual PRInt64 SizeOf() const {
+    return sizeof(*this);
+  }
+
   friend class nsNodeUtils;
   friend class nsNodeWeakReference;
   friend class nsNodeSupportsWeakRefTearoff;
   friend class nsAttrAndChildArray;
 
 #ifdef MOZILLA_INTERNAL_API
   nsINode(already_AddRefed<nsINodeInfo> aNodeInfo)
   : mNodeInfo(aNodeInfo),
--- a/content/base/src/nsDOMBlobBuilder.cpp
+++ b/content/base/src/nsDOMBlobBuilder.cpp
@@ -47,74 +47,75 @@
 #include "CheckedInt.h"
 
 // XXXkhuey shamelessly stolen from VideoUtils.h.  We should patch NSPR.
 #define PR_INT64_MAX (~((PRInt64)(1) << 63))
 #define PR_INT64_MIN (-PR_INT64_MAX - 1)
 
 using namespace mozilla;
 
-class nsDOMMultipartBlob : public nsDOMFile
+class nsDOMMultipartFile : public nsDOMFileBase
 {
 public:
-  nsDOMMultipartBlob(nsTArray<nsCOMPtr<nsIDOMBlob> > aBlobs,
+  // Create as a file
+  nsDOMMultipartFile(nsTArray<nsCOMPtr<nsIDOMBlob> > aBlobs,
+                     const nsAString& aName,
                      const nsAString& aContentType)
-    : nsDOMFile(nsnull, aContentType),
+    : nsDOMFileBase(aName, aContentType, PR_UINT64_MAX),
       mBlobs(aBlobs)
   {
-    mIsFullFile = false;
-    mStart = 0;
-    mLength = 0;
   }
 
+  // Create as a blob
+  nsDOMMultipartFile(nsTArray<nsCOMPtr<nsIDOMBlob> > aBlobs,
+                     const nsAString& aContentType)
+    : nsDOMFileBase(aContentType, PR_UINT64_MAX),
+      mBlobs(aBlobs)
+  {
+  }
+
+  already_AddRefed<nsIDOMBlob>
+  CreateSlice(PRUint64 aStart, PRUint64 aLength, const nsAString& aContentType);
+
   NS_IMETHOD GetSize(PRUint64*);
   NS_IMETHOD GetInternalStream(nsIInputStream**);
-  NS_IMETHOD MozSlice(PRInt64 aStart, PRInt64 aEnd,
-                      const nsAString& aContentType, PRUint8 optional_argc,
-                      nsIDOMBlob **aBlob);
 
 protected:
   nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs;
 };
 
 NS_IMETHODIMP
-nsDOMMultipartBlob::GetSize(PRUint64* aLength)
+nsDOMMultipartFile::GetSize(PRUint64* aLength)
 {
-  nsresult rv;
-  *aLength = 0;
+  if (mLength == PR_UINT64_MAX) {
+    CheckedUint64 length = 0;
+  
+    PRUint32 i;
+    PRUint32 len = mBlobs.Length();
+    for (i = 0; i < len; i++) {
+      nsIDOMBlob* blob = mBlobs.ElementAt(i).get();
+      PRUint64 l = 0;
+  
+      nsresult rv = blob->GetSize(&l);
+      NS_ENSURE_SUCCESS(rv, rv);
+  
+      length += l;
+    }
+  
+    NS_ENSURE_TRUE(length.valid(), NS_ERROR_FAILURE);
 
-  if (mLength) {
-    *aLength = mLength;
-    return NS_OK;
+    mLength = length.value();
   }
 
-  CheckedUint64 length = 0;
-
-  PRUint32 i;
-  PRUint32 len = mBlobs.Length();
-  for (i = 0; i < len; i++) {
-    nsIDOMBlob* blob = mBlobs.ElementAt(i).get();
-    PRUint64 l = 0;
-
-    rv = blob->GetSize(&l);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    length += l;
-  }
-
-  if (!length.valid())
-    return NS_ERROR_FAILURE;
-
-  mLength = length.value();
   *aLength = mLength;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMMultipartBlob::GetInternalStream(nsIInputStream** aStream)
+nsDOMMultipartFile::GetInternalStream(nsIInputStream** aStream)
 {
   nsresult rv;
   *aStream = nsnull;
 
   nsCOMPtr<nsIMultiplexInputStream> stream =
     do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
   NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE);
 
@@ -128,102 +129,81 @@ nsDOMMultipartBlob::GetInternalStream(ns
 
     rv = stream->AppendStream(scratchStream);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return CallQueryInterface(stream, aStream);
 }
 
-NS_IMETHODIMP
-nsDOMMultipartBlob::MozSlice(PRInt64 aStart, PRInt64 aEnd,
-                             const nsAString& aContentType,
-                             PRUint8 optional_argc,
-                             nsIDOMBlob **aBlob)
+already_AddRefed<nsIDOMBlob>
+nsDOMMultipartFile::CreateSlice(PRUint64 aStart, PRUint64 aLength,
+                                const nsAString& aContentType)
 {
-  nsresult rv;
-  *aBlob = nsnull;
-
-  // Truncate aStart and aEnd so that we stay within this file.
-  PRUint64 thisLength;
-  rv = GetSize(&thisLength);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (!optional_argc) {
-    aEnd = (PRInt64)thisLength;
-  }
-
-  // Modifies aStart and aEnd.
-  ParseSize((PRInt64)thisLength, aStart, aEnd);
-
   // If we clamped to nothing we create an empty blob
   nsTArray<nsCOMPtr<nsIDOMBlob> > blobs;
 
-  PRUint64 length = aEnd - aStart;
+  PRUint64 length = aLength;
   PRUint64 skipStart = aStart;
 
-  NS_ABORT_IF_FALSE(PRUint64(aStart) + length <= thisLength, "Er, what?");
-
   // Prune the list of blobs if we can
   PRUint32 i;
   for (i = 0; length && skipStart && i < mBlobs.Length(); i++) {
     nsIDOMBlob* blob = mBlobs[i].get();
 
     PRUint64 l;
-    rv = blob->GetSize(&l);
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsresult rv = blob->GetSize(&l);
+    NS_ENSURE_SUCCESS(rv, nsnull);
 
     if (skipStart < l) {
       PRUint64 upperBound = NS_MIN<PRUint64>(l - skipStart, length);
 
       nsCOMPtr<nsIDOMBlob> firstBlob;
-      rv = mBlobs.ElementAt(i)->MozSlice(skipStart, skipStart + upperBound,
-                                         aContentType, 2,
-                                         getter_AddRefs(firstBlob));
-      NS_ENSURE_SUCCESS(rv, rv);
+      rv = blob->MozSlice(skipStart, skipStart + upperBound,
+                          aContentType, 3,
+                          getter_AddRefs(firstBlob));
+      NS_ENSURE_SUCCESS(rv, nsnull);
 
-      // Avoid wrapping a single blob inside an nsDOMMultipartBlob
+      // Avoid wrapping a single blob inside an nsDOMMultipartFile
       if (length == upperBound) {
-        firstBlob.forget(aBlob);
-        return NS_OK;
+        return firstBlob.forget();
       }
 
       blobs.AppendElement(firstBlob);
       length -= upperBound;
       i++;
       break;
     }
     skipStart -= l;
   }
 
   // Now append enough blobs until we're done
   for (; length && i < mBlobs.Length(); i++) {
     nsIDOMBlob* blob = mBlobs[i].get();
 
     PRUint64 l;
-    rv = blob->GetSize(&l);
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsresult rv = blob->GetSize(&l);
+    NS_ENSURE_SUCCESS(rv, nsnull);
 
     if (length < l) {
       nsCOMPtr<nsIDOMBlob> lastBlob;
-      rv = mBlobs.ElementAt(i)->MozSlice(0, length, aContentType, 2,
-                                         getter_AddRefs(lastBlob));
-      NS_ENSURE_SUCCESS(rv, rv);
+      rv = blob->MozSlice(0, length, aContentType, 3,
+                          getter_AddRefs(lastBlob));
+      NS_ENSURE_SUCCESS(rv, nsnull);
 
       blobs.AppendElement(lastBlob);
     } else {
       blobs.AppendElement(blob);
     }
     length -= NS_MIN<PRUint64>(l, length);
   }
 
   // we can create our blob now
-  nsCOMPtr<nsIDOMBlob> blob = new nsDOMMultipartBlob(blobs, aContentType);
-  blob.forget(aBlob);
-  return NS_OK;
+  nsCOMPtr<nsIDOMBlob> blob = new nsDOMMultipartFile(blobs, aContentType);
+  return blob.forget();
 }
 
 class nsDOMBlobBuilder : public nsIDOMMozBlobBuilder
 {
 public:
   nsDOMBlobBuilder()
     : mData(nsnull), mDataLen(0), mDataBufferLen(0)
   {}
@@ -341,29 +321,53 @@ nsDOMBlobBuilder::AppendArrayBuffer(JSOb
 NS_IMETHODIMP
 nsDOMBlobBuilder::GetBlob(const nsAString& aContentType,
                           nsIDOMBlob** aBlob)
 {
   NS_ENSURE_ARG(aBlob);
 
   Flush();
 
-  nsCOMPtr<nsIDOMBlob> blob = new nsDOMMultipartBlob(mBlobs,
+  nsCOMPtr<nsIDOMBlob> blob = new nsDOMMultipartFile(mBlobs,
                                                      aContentType);
   blob.forget(aBlob);
 
   // NB: This is a willful violation of the spec.  The spec says that
   // the existing contents of the BlobBuilder should be included
   // in the next blob produced.  This seems silly and has been raised
   // on the WHATWG listserv.
   mBlobs.Clear();
 
   return NS_OK;
 }
 
+/* nsIDOMBlob getFile (in DOMString name, [optional] in DOMString contentType); */
+NS_IMETHODIMP
+nsDOMBlobBuilder::GetFile(const nsAString& aName,
+                          const nsAString& aContentType,
+                          nsIDOMFile** aFile)
+{
+  NS_ENSURE_ARG(aFile);
+
+  Flush();
+
+  nsCOMPtr<nsIDOMFile> file = new nsDOMMultipartFile(mBlobs,
+                                                     aName,
+                                                     aContentType);
+  file.forget(aFile);
+
+  // NB: This is a willful violation of the spec.  The spec says that
+  // the existing contents of the BlobBuilder should be included
+  // in the next blob produced.  This seems silly and has been raised
+  // on the WHATWG listserv.
+  mBlobs.Clear();
+
+  return NS_OK;
+}
+
 /* [implicit_jscontext] void append (in jsval data); */
 NS_IMETHODIMP
 nsDOMBlobBuilder::Append(const jsval& aData, JSContext* aCx)
 {
   // We need to figure out what our jsval is
 
   // Is it an object?
   if (JSVAL_IS_OBJECT(aData)) {
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -127,129 +127,78 @@ nsresult DataOwnerAdapter::Create(DataOw
                              NS_ASSIGNMENT_DEPEND);
   NS_ENSURE_SUCCESS(rv, rv);
 
   NS_ADDREF(*_retval = new DataOwnerAdapter(aDataOwner, stream));
 
   return NS_OK;
 }
 
-// nsDOMFile implementation
+////////////////////////////////////////////////////////////////////////////
+// nsDOMFileBase implementation
 
-DOMCI_DATA(File, nsDOMFile)
-DOMCI_DATA(Blob, nsDOMFile)
+DOMCI_DATA(File, nsDOMFileBase)
+DOMCI_DATA(Blob, nsDOMFileBase)
 
-NS_INTERFACE_MAP_BEGIN(nsDOMFile)
+NS_INTERFACE_MAP_BEGIN(nsDOMFileBase)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFile)
   NS_INTERFACE_MAP_ENTRY(nsIDOMBlob)
-  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIDOMFile, mIsFullFile)
+  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIDOMFile, mIsFile)
   NS_INTERFACE_MAP_ENTRY(nsIXHRSendable)
-  NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(File, mIsFullFile)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(Blob, !mIsFullFile)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(File, mIsFile)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(Blob, !mIsFile)
 NS_INTERFACE_MAP_END
 
-NS_IMPL_ADDREF(nsDOMFile)
-NS_IMPL_RELEASE(nsDOMFile)
-
-static nsresult
-DOMFileResult(nsresult rv)
-{
-  if (rv == NS_ERROR_FILE_NOT_FOUND) {
-    return NS_ERROR_DOM_FILE_NOT_FOUND_ERR;
-  }
+NS_IMPL_ADDREF(nsDOMFileBase)
+NS_IMPL_RELEASE(nsDOMFileBase)
 
-  if (NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_FILES) {
-    return NS_ERROR_DOM_FILE_NOT_READABLE_ERR;
-  }
-
-  return rv;
-}
-
-/* static */ nsresult
-nsDOMFile::NewFile(nsISupports* *aNewObject)
+NS_IMETHODIMP
+nsDOMFileBase::GetName(nsAString &aFileName)
 {
-  nsCOMPtr<nsISupports> file = do_QueryObject(new nsDOMFile(nsnull));
-  file.forget(aNewObject);
+  NS_ASSERTION(mIsFile, "Should only be called on files");
+  aFileName = mName;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMFile::GetName(nsAString &aFileName)
+nsDOMFileBase::GetMozFullPath(nsAString &aFileName)
 {
-  NS_ASSERTION(mIsFullFile, "Should only be called on files");
-  return mFile->GetLeafName(aFileName);
-}
-
-NS_IMETHODIMP
-nsDOMFile::GetMozFullPath(nsAString &aFileName)
-{
-  NS_ASSERTION(mIsFullFile, "Should only be called on files");
+  NS_ASSERTION(mIsFile, "Should only be called on files");
   if (nsContentUtils::IsCallerTrustedForCapability("UniversalFileRead")) {
     return GetMozFullPathInternal(aFileName);
   }
   aFileName.Truncate();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMFile::GetMozFullPathInternal(nsAString &aFilename)
-{
-  NS_ASSERTION(mIsFullFile, "Should only be called on files");
-  return mFile->GetPath(aFilename);
-}
-
-NS_IMETHODIMP
-nsDOMFile::GetSize(PRUint64 *aFileSize)
+nsDOMFileBase::GetMozFullPathInternal(nsAString &aFileName)
 {
-  if (mIsFullFile) {
-    PRInt64 fileSize;
-    nsresult rv = mFile->GetFileSize(&fileSize);
-    NS_ENSURE_SUCCESS(rv, rv);
-  
-    if (fileSize < 0) {
-      return NS_ERROR_FAILURE;
-    }
-  
-    *aFileSize = fileSize;
-  }
-  else {
-    *aFileSize = mLength;
-  }
-
+  NS_ASSERTION(mIsFile, "Should only be called on files");
+  aFileName.Truncate();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMFile::GetType(nsAString &aType)
+nsDOMFileBase::GetSize(PRUint64 *aSize)
 {
-  if (mContentType.IsEmpty() && mFile && mIsFullFile) {
-    nsresult rv;
-    nsCOMPtr<nsIMIMEService> mimeService =
-      do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
+  *aSize = mLength;
+  return NS_OK;
+}
 
-    nsCAutoString mimeType;
-    rv = mimeService->GetTypeFromFile(mFile, mimeType);
-    if (NS_FAILED(rv)) {
-      aType.Truncate();
-      return NS_OK;
-    }
-
-    AppendUTF8toUTF16(mimeType, mContentType);
-  }
-
+NS_IMETHODIMP
+nsDOMFileBase::GetType(nsAString &aType)
+{
   aType = mContentType;
-
   return NS_OK;
 }
 
 // Makes sure that aStart and aEnd is less then or equal to aSize and greater
 // than 0
-void
+static void
 ParseSize(PRInt64 aSize, PRInt64& aStart, PRInt64& aEnd)
 {
   CheckedInt64 newStartOffset = aStart;
   if (aStart < -aSize) {
     newStartOffset = 0;
   }
   else if (aStart < 0) {
     newStartOffset += aSize;
@@ -275,55 +224,51 @@ ParseSize(PRInt64 aSize, PRInt64& aStart
   }
   else {
     aStart = newStartOffset.value();
     aEnd = newEndOffset.value();
   }
 }
 
 NS_IMETHODIMP
-nsDOMFile::MozSlice(PRInt64 aStart, PRInt64 aEnd,
-                    const nsAString& aContentType, PRUint8 optional_argc,
-                    nsIDOMBlob **aBlob)
+nsDOMFileBase::MozSlice(PRInt64 aStart, PRInt64 aEnd,
+                        const nsAString& aContentType, PRUint8 optional_argc,
+                        nsIDOMBlob **aBlob)
 {
   *aBlob = nsnull;
 
   // Truncate aStart and aEnd so that we stay within this file.
   PRUint64 thisLength;
   nsresult rv = GetSize(&thisLength);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (!optional_argc) {
+  if (optional_argc < 2) {
     aEnd = (PRInt64)thisLength;
   }
 
   ParseSize((PRInt64)thisLength, aStart, aEnd);
   
   // Create the new file
-  NS_ADDREF(*aBlob = new nsDOMFile(this, aStart, aEnd - aStart, aContentType));
-  
-  return NS_OK;
-}
+  *aBlob = CreateSlice((PRUint64)aStart, (PRUint64)(aEnd - aStart),
+                       aContentType).get();
 
-const PRUint32 sFileStreamFlags =
-  nsIFileInputStream::CLOSE_ON_EOF |
-  nsIFileInputStream::REOPEN_ON_REWIND |
-  nsIFileInputStream::DEFER_OPEN;
-
-NS_IMETHODIMP
-nsDOMFile::GetInternalStream(nsIInputStream **aStream)
-{
-  return mIsFullFile ?
-    NS_NewLocalFileInputStream(aStream, mFile, -1, -1, sFileStreamFlags) :
-    NS_NewPartialLocalFileInputStream(aStream, mFile, mStart, mLength,
-                                      -1, -1, sFileStreamFlags);
+  return *aBlob ? NS_OK : NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
-nsDOMFile::GetInternalUrl(nsIPrincipal* aPrincipal, nsAString& aURL)
+nsDOMFileBase::GetInternalStream(nsIInputStream **aStream)
+{
+  // Must be overridden
+  NS_NOTREACHED("Must override GetInternalStream");
+  
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsDOMFileBase::GetInternalUrl(nsIPrincipal* aPrincipal, nsAString& aURL)
 {
   NS_ENSURE_STATE(aPrincipal);
 
   nsresult rv;
   nsCOMPtr<nsIUUIDGenerator> uuidgen =
     do_GetService("@mozilla.org/uuid-generator;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   
@@ -341,19 +286,19 @@ nsDOMFile::GetInternalUrl(nsIPrincipal* 
                                               aPrincipal);
 
   CopyASCIItoUTF16(url, aURL);
   
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMFile::GetSendInfo(nsIInputStream** aBody,
-                       nsACString& aContentType,
-                       nsACString& aCharset)
+nsDOMFileBase::GetSendInfo(nsIInputStream** aBody,
+                           nsACString& aContentType,
+                           nsACString& aCharset)
 {
   nsresult rv;
 
   nsCOMPtr<nsIInputStream> stream;
   rv = this->GetInternalStream(getter_AddRefs(stream));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsString contentType;
@@ -363,22 +308,113 @@ nsDOMFile::GetSendInfo(nsIInputStream** 
   CopyUTF16toUTF8(contentType, aContentType);
 
   aCharset.Truncate();
 
   stream.forget(aBody);
   return NS_OK;
 }
 
+////////////////////////////////////////////////////////////////////////////
+// nsDOMFileFile implementation
+
+NS_IMPL_ISUPPORTS_INHERITED1(nsDOMFileFile, nsDOMFileBase,
+                             nsIJSNativeInitializer)
+
+already_AddRefed<nsIDOMBlob>
+nsDOMFileFile::CreateSlice(PRUint64 aStart, PRUint64 aLength,
+                           const nsAString& aContentType)
+{
+  nsCOMPtr<nsIDOMBlob> t = new nsDOMFileFile(this, aStart, aLength, aContentType);
+  return t.forget();
+}
+
+/* static */ nsresult
+nsDOMFileFile::NewFile(nsISupports* *aNewObject)
+{
+  nsCOMPtr<nsISupports> file = do_QueryObject(new nsDOMFileFile());
+  file.forget(aNewObject);
+  return NS_OK;
+}
+
 NS_IMETHODIMP
-nsDOMFile::Initialize(nsISupports* aOwner,
-                      JSContext* aCx,
-                      JSObject* aObj,
-                      PRUint32 aArgc,
-                      jsval* aArgv)
+nsDOMFileFile::GetMozFullPathInternal(nsAString &aFilename)
+{
+  NS_ASSERTION(mIsFile, "Should only be called on files");
+  return mFile->GetPath(aFilename);
+}
+
+NS_IMETHODIMP
+nsDOMFileFile::GetSize(PRUint64 *aFileSize)
+{
+  if (IsSizeUnknown()) {
+    NS_ASSERTION(mWholeFile,
+                 "Should only use lazy size when using the whole file");
+    PRInt64 fileSize;
+    nsresult rv = mFile->GetFileSize(&fileSize);
+    NS_ENSURE_SUCCESS(rv, rv);
+  
+    if (fileSize < 0) {
+      return NS_ERROR_FAILURE;
+    }
+  
+    mLength = fileSize;
+  }
+
+  *aFileSize = mLength;
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMFileFile::GetType(nsAString &aType)
+{
+  if (mContentType.IsVoid()) {
+    NS_ASSERTION(mWholeFile,
+                 "Should only use lazy ContentType when using the whole file");
+    nsresult rv;
+    nsCOMPtr<nsIMIMEService> mimeService =
+      do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsCAutoString mimeType;
+    rv = mimeService->GetTypeFromFile(mFile, mimeType);
+    if (NS_FAILED(rv)) {
+      mimeType.Truncate();
+    }
+
+    AppendUTF8toUTF16(mimeType, mContentType);
+    mContentType.SetIsVoid(PR_FALSE);
+  }
+
+  aType = mContentType;
+
+  return NS_OK;
+}
+
+const PRUint32 sFileStreamFlags =
+  nsIFileInputStream::CLOSE_ON_EOF |
+  nsIFileInputStream::REOPEN_ON_REWIND |
+  nsIFileInputStream::DEFER_OPEN;
+
+NS_IMETHODIMP
+nsDOMFileFile::GetInternalStream(nsIInputStream **aStream)
+{
+  return mWholeFile ?
+    NS_NewLocalFileInputStream(aStream, mFile, -1, -1, sFileStreamFlags) :
+    NS_NewPartialLocalFileInputStream(aStream, mFile, mStart, mLength,
+                                      -1, -1, sFileStreamFlags);
+}
+
+NS_IMETHODIMP
+nsDOMFileFile::Initialize(nsISupports* aOwner,
+                          JSContext* aCx,
+                          JSObject* aObj,
+                          PRUint32 aArgc,
+                          jsval* aArgv)
 {
   nsresult rv;
 
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR; // Real short trip
   }
 
   NS_ENSURE_TRUE(aArgc > 0, NS_ERROR_UNEXPECTED);
@@ -419,74 +455,49 @@ nsDOMFile::Initialize(nsISupports* aOwne
     NS_ASSERTION(file, "This should never happen");
   }
 
   PRBool exists;
   rv = file->Exists(&exists);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(exists, NS_ERROR_FILE_NOT_FOUND);
 
-  mFile = file;
-  return NS_OK;
-}
+  PRBool isDir;
+  rv = file->IsDirectory(&isDir);
+  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_FALSE(isDir, NS_ERROR_FILE_IS_DIRECTORY);
 
-// nsDOMMemoryFile Implementation
-NS_IMETHODIMP
-nsDOMMemoryFile::GetName(nsAString &aFileName)
-{
-  NS_ASSERTION(mIsFullFile, "Should only be called on files");
-  aFileName = mName;
-  return NS_OK;
-}
+  mFile = file;
+  file->GetLeafName(mName);
 
-NS_IMETHODIMP
-nsDOMMemoryFile::GetSize(PRUint64 *aFileSize)
-{
-  *aFileSize = mLength;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDOMMemoryFile::MozSlice(PRInt64 aStart, PRInt64 aEnd,
-                          const nsAString& aContentType, PRUint8 optional_argc,
-                          nsIDOMBlob **aBlob)
-{
-  *aBlob = nsnull;
+////////////////////////////////////////////////////////////////////////////
+// nsDOMMemoryFile implementation
 
-  if (!optional_argc) {
-    aEnd = (PRInt64)mLength;
-  }
-
-  // Truncate aLength and aStart so that we stay within this file.
-  ParseSize((PRInt64)mLength, aStart, aEnd);
-
-  // Create the new file
-  NS_ADDREF(*aBlob = new nsDOMMemoryFile(this, aStart, aEnd - aStart,
-                                         aContentType));
-  
-  return NS_OK;
+already_AddRefed<nsIDOMBlob>
+nsDOMMemoryFile::CreateSlice(PRUint64 aStart, PRUint64 aLength,
+                             const nsAString& aContentType)
+{
+  nsCOMPtr<nsIDOMBlob> t =
+    new nsDOMMemoryFile(this, aStart, aLength, aContentType);
+  return t.forget();
 }
 
 NS_IMETHODIMP
 nsDOMMemoryFile::GetInternalStream(nsIInputStream **aStream)
 {
   if (mLength > PR_INT32_MAX)
     return NS_ERROR_FAILURE;
 
   return DataOwnerAdapter::Create(mDataOwner, mStart, mLength, aStream);
 }
 
-NS_IMETHODIMP
-nsDOMMemoryFile::GetMozFullPathInternal(nsAString &aFilename)
-{
-  NS_ASSERTION(mIsFullFile, "Should only be called on files");
-  aFilename.Truncate();
-  return NS_OK;
-}
-
+////////////////////////////////////////////////////////////////////////////
 // nsDOMFileList implementation
 
 DOMCI_DATA(FileList, nsDOMFileList)
 
 NS_INTERFACE_MAP_BEGIN(nsDOMFileList)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFileList)
   NS_INTERFACE_MAP_ENTRY(nsIDOMFileList)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(FileList)
@@ -506,16 +517,17 @@ nsDOMFileList::GetLength(PRUint32* aLeng
 NS_IMETHODIMP
 nsDOMFileList::Item(PRUint32 aIndex, nsIDOMFile **aFile)
 {
   NS_IF_ADDREF(*aFile = GetItemAt(aIndex));
 
   return NS_OK;
 }
 
+////////////////////////////////////////////////////////////////////////////
 // nsDOMFileError implementation
 
 DOMCI_DATA(FileError, nsDOMFileError)
 
 NS_INTERFACE_MAP_BEGIN(nsDOMFileError)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFileError)
   NS_INTERFACE_MAP_ENTRY(nsIDOMFileError)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(FileError)
@@ -526,16 +538,19 @@ NS_IMPL_RELEASE(nsDOMFileError)
 
 NS_IMETHODIMP
 nsDOMFileError::GetCode(PRUint16* aCode)
 {
   *aCode = mCode;
   return NS_OK;
 }
 
+////////////////////////////////////////////////////////////////////////////
+// nsDOMFileInternalUrlHolder implementation
+
 nsDOMFileInternalUrlHolder::nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile,
                                                        nsIPrincipal* aPrincipal
                                                        MOZILLA_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) {
   MOZILLA_GUARD_OBJECT_NOTIFIER_INIT;
   aFile->GetInternalUrl(aPrincipal, mUrl);
 }
  
 nsDOMFileInternalUrlHolder::~nsDOMFileInternalUrlHolder() {
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -322,16 +322,17 @@ nsFrameLoader::nsFrameLoader(nsIContent 
   , mHideCalled(PR_FALSE)
   , mNetworkCreated(aNetworkCreated)
   , mDelayRemoteDialogs(PR_FALSE)
   , mRemoteBrowserShown(PR_FALSE)
   , mRemoteFrame(false)
   , mCurrentRemoteFrame(nsnull)
   , mRemoteBrowser(nsnull)
   , mRenderMode(RENDER_MODE_DEFAULT)
+  , mEventMode(EVENT_MODE_NORMAL_DISPATCH)
 {
 }
 
 nsFrameLoader*
 nsFrameLoader::Create(nsIContent* aOwner, PRBool aNetworkCreated)
 {
   NS_ENSURE_TRUE(aOwner, nsnull);
   nsIDocument* doc = aOwner->GetOwnerDoc();
@@ -532,36 +533,37 @@ nsFrameLoader::CheckURILoad(nsIURI* aURI
   }
   return CheckForRecursiveLoad(aURI);
 }
 
 NS_IMETHODIMP
 nsFrameLoader::GetDocShell(nsIDocShell **aDocShell)
 {
   *aDocShell = nsnull;
+  nsresult rv = NS_OK;
 
   // If we have an owner, make sure we have a docshell and return
   // that. If not, we're most likely in the middle of being torn down,
   // then we just return null.
   if (mOwnerContent) {
     nsresult rv = MaybeCreateDocShell();
     if (NS_FAILED(rv))
       return rv;
     if (mRemoteFrame) {
       NS_WARNING("No docshells for remote frames!");
-      return NS_ERROR_NOT_AVAILABLE;
+      return rv;
     }
     NS_ASSERTION(mDocShell,
                  "MaybeCreateDocShell succeeded, but null mDocShell");
   }
 
   *aDocShell = mDocShell;
   NS_IF_ADDREF(*aDocShell);
 
-  return NS_OK;
+  return rv;
 }
 
 void
 nsFrameLoader::Finalize()
 {
   nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
   if (base_win) {
     base_win->Destroy();
@@ -1335,46 +1337,29 @@ nsFrameLoader::SetOwnerContent(nsIConten
   if (RenderFrameParent* rfp = GetCurrentRemoteFrame()) {
     rfp->OwnerContentChanged(aContent);
   }
 }
 
 bool
 nsFrameLoader::ShouldUseRemoteProcess()
 {
-  // Check for *disabled* multi-process first: environment, prefs, attribute
-  // Then check for *enabled* multi-process pref: attribute, prefs
+  // Check for *disabled* multi-process first: environment, pref
+  // Then check for *enabled* multi-process attribute
   // Default is not-remote.
 
-  if (PR_GetEnv("MOZ_DISABLE_OOP_TABS")) {
-    return false;
-  }
-
-  PRBool remoteDisabled =
-    Preferences::GetBool("dom.ipc.tabs.disabled", PR_FALSE);
-  if (remoteDisabled) {
+  if (PR_GetEnv("MOZ_DISABLE_OOP_TABS") ||
+      Preferences::GetBool("dom.ipc.tabs.disabled", PR_FALSE)) {
     return false;
   }
 
-  static nsIAtom* const *const remoteValues[] = {
-    &nsGkAtoms::_false,
-    &nsGkAtoms::_true,
-    nsnull
-  };
-
-  switch (mOwnerContent->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::Remote,
-                                         remoteValues, eCaseMatters)) {
-  case 0:
-    return false;
-  case 1:
-    return true;
-  }
-
-  PRBool remoteEnabled = Preferences::GetBool("dom.ipc.tabs.enabled", PR_FALSE);
-  return (bool) remoteEnabled;
+  return (bool) mOwnerContent->AttrValueIs(kNameSpaceID_None,
+                                           nsGkAtoms::Remote,
+                                           nsGkAtoms::_true,
+                                           eCaseMatters);
 }
 
 nsresult
 nsFrameLoader::MaybeCreateDocShell()
 {
   if (mDocShell) {
     return NS_OK;
   }
@@ -1671,16 +1656,30 @@ nsFrameLoader::SetRenderMode(PRUint32 aR
     return NS_OK;
   }
 
   mRenderMode = aRenderMode;
   InvalidateFrame(GetPrimaryFrameOfOwningContent());
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsFrameLoader::GetEventMode(PRUint32* aEventMode)
+{
+  *aEventMode = mEventMode;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsFrameLoader::SetEventMode(PRUint32 aEventMode)
+{
+  mEventMode = aEventMode;
+  return NS_OK;
+}
+
 nsIntSize
 nsFrameLoader::GetSubDocumentSize(const nsIFrame *aIFrame)
 {
   nsSize docSizeAppUnits;
   nsPresContext* presContext = aIFrame->PresContext();
   nsCOMPtr<nsIDOMHTMLFrameElement> frameElem = 
     do_QueryInterface(aIFrame->GetContent());
   if (frameElem) {
@@ -1783,16 +1782,25 @@ nsFrameLoader::ActivateRemoteFrame() {
   if (mRemoteBrowser) {
     mRemoteBrowser->Activate();
     return NS_OK;
   }
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
+nsFrameLoader::DeactivateRemoteFrame() {
+  if (mRemoteBrowser) {
+    mRemoteBrowser->Deactivate();
+    return NS_OK;
+  }
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
 nsFrameLoader::SendCrossProcessMouseEvent(const nsAString& aType,
                                           float aX,
                                           float aY,
                                           PRInt32 aButton,
                                           PRInt32 aClickCount,
                                           PRInt32 aModifiers,
                                           PRBool aIgnoreRootScrollFrame)
 {
--- a/content/base/src/nsFrameLoader.h
+++ b/content/base/src/nsFrameLoader.h
@@ -337,11 +337,15 @@ private:
   nsCOMPtr<nsIObserver> mChildHost;
   RenderFrameParent* mCurrentRemoteFrame;
   TabParent* mRemoteBrowser;
 
   // See nsIFrameLoader.idl.  Short story, if !(mRenderMode &
   // RENDER_MODE_ASYNC_SCROLL), all the fields below are ignored in
   // favor of what content tells.
   PRUint32 mRenderMode;
+
+  // See nsIFrameLoader.idl. EVENT_MODE_NORMAL_DISPATCH automatically
+  // forwards some input events to out-of-process content.
+  PRUint32 mEventMode;
 };
 
 #endif
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -510,30 +510,28 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
     nodeInfo = newNodeInfo;
   }
 
   nsGenericElement *elem = aNode->IsElement() ?
                            static_cast<nsGenericElement*>(aNode) :
                            nsnull;
 
   nsCOMPtr<nsINode> clone;
-  PRBool isDeepDocumentClone = PR_FALSE;
   if (aClone) {
     rv = aNode->Clone(nodeInfo, getter_AddRefs(clone));
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (aParent) {
       // If we're cloning we need to insert the cloned children into the cloned
       // parent.
       rv = aParent->AppendChildTo(static_cast<nsIContent*>(clone.get()),
                                   PR_FALSE);
       NS_ENSURE_SUCCESS(rv, rv);
     }
     else if (aDeep && clone->IsNodeOfType(nsINode::eDOCUMENT)) {
-      isDeepDocumentClone = PR_TRUE;
       // After cloning the document itself, we want to clone the children into
       // the cloned document (somewhat like cloning and importing them into the
       // cloned document).
       nodeInfoManager = clone->mNodeInfo->NodeInfoManager();
     }
   }
   else if (nodeInfoManager) {
     nsIDocument* oldDoc = aNode->GetOwnerDoc();
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -1309,21 +1309,22 @@ nsScriptLoader::ParsingComplete(PRBool a
   // onload and all.
   ProcessPendingRequests();
 }
 
 void
 nsScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
                            const nsAString &aType)
 {
-  nsRefPtr<nsScriptLoadRequest> request = new nsScriptLoadRequest(nsnull, 0);
-  if (!request) {
+  // Check to see if scripts has been turned off.
+  if (!mEnabled || !mDocument->IsScriptEnabled()) {
     return;
   }
 
+  nsRefPtr<nsScriptLoadRequest> request = new nsScriptLoadRequest(nsnull, 0);
   request->mURI = aURI;
   request->mIsInline = PR_FALSE;
   request->mLoading = PR_TRUE;
   nsresult rv = StartLoad(request, aType);
   if (NS_FAILED(rv)) {
     return;
   }
 
--- a/content/base/src/nsWebSocket.cpp
+++ b/content/base/src/nsWebSocket.cpp
@@ -1346,16 +1346,28 @@ nsWebSocket::Init(nsIPrincipal* aPrincip
 
     mWindowID = nsJSUtils::GetCurrentlyRunningCodeWindowID(cx);
   }
 
   // parses the url
   rv = ParseURL(PromiseFlatString(aURL));
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // Don't allow https:// to open ws://
+  nsCOMPtr<nsIURI> originURI;
+  PRBool originHTTPS;
+  if (!mSecure && 
+      !Preferences::GetBool("network.websocket.allowInsecureFromHTTPS",
+                            PR_FALSE) &&
+      NS_SUCCEEDED(NS_NewURI(getter_AddRefs(originURI), mUTF16Origin)) &&
+      NS_SUCCEEDED(originURI->SchemeIs("https", &originHTTPS)) &&
+      originHTTPS) {
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+
   // sets the protocol
   if (!aProtocol.IsEmpty()) {
     rv = SetProtocol(PromiseFlatString(aProtocol));
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // the constructor should throw a SYNTAX_ERROR only if it fails to parse the
   // url parameter, so we don't care about the EstablishConnection result.
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -1595,51 +1595,32 @@ nsXMLHttpRequest::StreamReaderFunc(nsIIn
 }
 
 void nsXMLHttpRequest::CreateResponseBlob(nsIRequest *request)
 {
   nsCOMPtr<nsIFile> file;
   nsCOMPtr<nsICachingChannel> cc(do_QueryInterface(request));
   if (cc) {
     cc->GetCacheFile(getter_AddRefs(file));
-    if (!file) {
-      // cacheAsFile returns false if caching is inhibited
-      PRBool cacheAsFile = PR_FALSE;
-      if (NS_SUCCEEDED(cc->GetCacheAsFile(&cacheAsFile)) && cacheAsFile) {
-        
-      }
-    }
   } else {
     nsCOMPtr<nsIFileChannel> fc = do_QueryInterface(request);
     if (fc) {
       fc->GetFile(getter_AddRefs(file));
     }
   }
   if (file) {
     nsCAutoString contentType;
     mChannel->GetContentType(contentType);
     nsCOMPtr<nsISupports> cacheToken;
     if (cc) {
       cc->GetCacheToken(getter_AddRefs(cacheToken));
     }
 
-    NS_ConvertASCIItoUTF16 wideContentType(contentType);
-
-    nsCOMPtr<nsIDOMBlob> blob =
-      new nsDOMFile(file, wideContentType, cacheToken);
-
-    // XXXkhuey this is a complete hack ... but we need to get 6 out the door
-    // The response blob here should not be a File object, it should only
-    // be a Blob.  Unfortunately, because nsDOMFile has grown through
-    // accretion over the years and is in dangerous need of a refactoring,
-    // slicing it is the easiest way to get there ...
-    PRUint64 size = 0;
-    blob->GetSize(&size);
-    blob->MozSlice(0, size, wideContentType, 2, getter_AddRefs(mResponseBlob));
-    
+    mResponseBlob =
+      new nsDOMFileFile(file, NS_ConvertASCIItoUTF16(contentType), cacheToken);
     mResponseBody.Truncate();
     mResponseBodyUnicode.SetIsVoid(PR_TRUE);
   }
 }
 
 /* void onDataAvailable (in nsIRequest request, in nsISupports ctxt, in nsIInputStream inStr, in unsigned long sourceOffset, in unsigned long count); */
 NS_IMETHODIMP
 nsXMLHttpRequest::OnDataAvailable(nsIRequest *request, nsISupports *ctxt, nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count)
@@ -1901,29 +1882,19 @@ nsXMLHttpRequest::OnStopRequest(nsIReque
       mChannel->GetContentType(contentType);
       // XXX We should change mResponseBody to be a raw malloc'ed buffer
       //     to avoid copying the data.
       PRUint32 blobLen = mResponseBody.Length();
       void *blobData = PR_Malloc(blobLen);
       if (blobData) {
         memcpy(blobData, mResponseBody.BeginReading(), blobLen);
 
-        NS_ConvertASCIItoUTF16 wideContentType(contentType);
-        nsCOMPtr<nsIDOMBlob> blob =
-          new nsDOMMemoryFile(blobData, blobLen, EmptyString(),
-                              wideContentType);
-
-        // XXXkhuey this is a complete hack ... but we need to get 6 out the door
-        // The response blob here should not be a File object, it should only
-        // be a Blob.  Unfortunately, because nsDOMFile has grown through
-        // accretion over the years and is in dangerous need of a refactoring,
-        // slicing it is the easiest way to get there ...
-        blob->MozSlice(0, blobLen, wideContentType,
-                       2, getter_AddRefs(mResponseBlob));
-
+        mResponseBlob =
+          new nsDOMMemoryFile(blobData, blobLen,
+                              NS_ConvertASCIItoUTF16(contentType));
         mResponseBody.Truncate();
       }
       NS_ASSERTION(mResponseBodyUnicode.IsVoid(),
                    "mResponseBodyUnicode should be empty");
     }
   }
 
   channel->SetNotificationCallbacks(nsnull);
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -497,16 +497,17 @@ include $(topsrcdir)/config/rules.mk
 		forRemoval.resource^headers^ \
 		accesscontrol.resource \
 		accesscontrol.resource^headers^ \
 		invalid_accesscontrol.resource \
 		invalid_accesscontrol.resource^headers^ \
 		somedatas.resource \
 		somedatas.resource^headers^ \
 		delayedServerEvents.sjs \
+		test_bug664916.html \
 		test_bug666604.html \
 		$(NULL)
 
 _CHROME_FILES =	\
 		test_bug357450.js \
 		$(NULL)
 
 # This test fails on the Mac for some reason
--- a/content/base/test/chrome/test_fileconstructor.xul
+++ b/content/base/test/chrome/test_fileconstructor.xul
@@ -59,15 +59,24 @@ try {
 } catch (e) {
   ok(true, "Botched file constructor attempts throw and do not crash.");
 }
 
 try {
   var nonexistentfile = new File("i/sure/hope/this/does/not/exist/anywhere.txt");
   ok(false, "This should never be reached!");
 } catch (e) {
-  ok(true, "Attempt to construct a non-existent file should fail.")
+  ok(true, "Attempt to construct a non-existent file should fail.");
 }
 
+try {
+  var dir = Components.classes["@mozilla.org/file/directory_service;1"]
+                      .getService(Components.interfaces.nsIProperties)
+                      .get("CurWorkD", Components.interfaces.nsIFile);
+  var dirfile = new File(dir);
+  ok(false, "This should never be reached!");
+} catch (e) {
+  ok(true, "Attempt to construct a file from a directory should fail.");
+}
 ]]>
 </script>
 
 </window>
--- a/content/base/test/fileutils.js
+++ b/content/base/test/fileutils.js
@@ -215,41 +215,48 @@ function testSlice(file, size, type, con
   slice = file.mozSlice(0, 5432, "foo/bar");
   is(slice.type, "foo/bar", fileType + " sized slice foo/bar type");
   
   is(slice.mozSlice(0, 10).type, "", fileType + " slice-slice type");
   is(slice.mozSlice(0, 10).size, 10, fileType + " slice-slice size");
   is(slice.mozSlice(0, 10, "hello/world").type, "hello/world", fileType + " slice-slice hello/world type");
   is(slice.mozSlice(0, 10, "hello/world").size, 10, fileType + " slice-slice hello/world size");
 
+  // Start, end, expected size
   var indexes = [[0, size, size],
                  [0, 1234, 1234],
                  [size-500, size, 500],
                  [size-500, size+500, 500],
                  [size+500, size+1500, 0],
                  [0, 0, 0],
                  [1000, 1000, 0],
                  [size, size, 0],
+                 [undefined, undefined, size],
                  [0, undefined, size],
                  [100, undefined, size-100],
                  [-100, undefined, 100],
                  [100, -100, size-200],
                  [-size-100, undefined, size],
                  [-2*size-100, 500, 500],
                  [0, -size-100, 0],
                  [100, -size-100, 0],
                  [50, -size+100, 50],
                  [0, 33000, 33000],
                  [1000, 34000, 33000],
                 ];
   
   for (var i = 0; i < indexes.length; ++i) {
     var sliceContents;
     var testName;
-    if (indexes[i][1] == undefined) {
+    if (indexes[i][0] == undefined) {
+      slice = file.mozSlice();
+      sliceContents = contents.slice();
+      testName = fileType + " slice()";
+    }
+    else if (indexes[i][1] == undefined) {
       slice = file.mozSlice(indexes[i][0]);
       sliceContents = contents.slice(indexes[i][0]);
       testName = fileType + " slice(" + indexes[i][0] + ")";
     }
     else {
       slice = file.mozSlice(indexes[i][0], indexes[i][1]);
       sliceContents = contents.slice(indexes[i][0], indexes[i][1]);
       testName = fileType + " slice(" + indexes[i][0] + ", " + indexes[i][1] + ")";
--- a/content/base/test/test_blobbuilder.html
+++ b/content/base/test/test_blobbuilder.html
@@ -23,73 +23,109 @@ https://bugzilla.mozilla.org/show_bug.cg
 window.BlobBuilder = window.MozBlobBuilder;
 
 /** Test for Bug 648997 **/
 var blobBuilder = BlobBuilder();
 ok(blobBuilder, "BlobBuilder should exist");
 
 ok(blobBuilder.append, "BlobBuilder should have an append method");
 ok(blobBuilder.getBlob, "BlobBuilder should have a getBlob method");
+ok(blobBuilder.getFile, "BlobBuilder should have a getFile method");
 
 try {
 blobBuilder.append();
 ok(false, "NOT REACHED");
 } catch(e) {
 ok(true, "an empty argument to append should throw");
 }
 
 blobBuilder.append("squiggle");
 let blob1 = blobBuilder.getBlob();
+ok(blob1 instanceof Blob, "getBlob should produce Blobs");
+ok(!(blob1 instanceof File), "getBlob should not produce Files");
+is(blob1.type, "", "getBlob with no argument should return Blob with empty type");
+is(blob1.size, 8, "getBlob should return Blob with correct size");
+
 blobBuilder.append("ohai");
-let blob2 = blobBuilder.getBlob();
+let blob2 = blobBuilder.getFile("thefilename");
+ok(blob2 instanceof Blob, "getFile should produce Blobs");
+ok(blob2 instanceof File, "getFile should produce Files");
+is(blob2.name, "thefilename", "getFile should produces Files with correct name");
+is(blob2.type, "", "getFile with no second argument should return File with empty type");
+is(blob2.size, 4, "getFile should return Blob with correct size");
+
+blobBuilder.append("steak");
+let blob3 = blobBuilder.getBlob("content/type");
+ok(blob3 instanceof Blob, "getBlob should produce Blobs");
+ok(!(blob3 instanceof File), "getBlob should not produce Files");
+is(blob3.type, "content/type", "getBlob with no argument should return Blob with empty type");
+is(blob3.size, 5, "getBlob should return Blob with correct size");
+
+blobBuilder.append("apples");
+let blob4 = blobBuilder.getFile("the other filename", "text/plain");
+ok(blob4 instanceof Blob, "getFile should produce Blobs");
+ok(blob4 instanceof File, "getFile should produce Files");
+is(blob4.name, "the other filename", "getFile should produces Files with correct name");
+is(blob4.type, "text/plain", "getFile with second argument should return File with correct type");
+is(blob4.size, 6, "getFile should return Blob with correct size");
+
+blobBuilder.append("boletes");
+let blob5 = blobBuilder.getFile("");
+ok(blob5 instanceof Blob, "getFile should produce Blobs");
+ok(blob5 instanceof File, "getFile should produce Files");
+is(blob5.name, "", "getFile with empty name should produces Files with empty name");
+is(blob5.type, "", "getFile with no second argument should return File with correct type");
+is(blob5.size, 7, "getFile should return Blob with correct size");
+testFile(blob5, "boletes", "Test empty-named File from BlobBuilder.getFile");
+
 
 let aB = new ArrayBuffer(16);
 var int8View = new Int8Array(aB);
 for (var i = 0; i < 16; i++) {
   int8View[i] = i+65;
 }
 
 let testData = 
  [
     // Test 3 strings
     [["foo", "bar", "baz"], [{start: 0, length: 9, contents: "foobarbaz"},
                              {start: 0, length: 3, contents: "foo"},
                              {start: 3, length:6, contents:  "barbaz"},
                              {start: 6, length: 3, contents:  "baz"},
-                             {start: 6, length: 6, elength: 3, contents: "baz"},
+                             {start: 6, length: 6, contents: "baz"},
                              {start: 0, length: 9, contents:  "foobarbaz"},
-                             {start: 0, length: 11, elength: 9, contents: "foobarbaz"},
-                             {start: 10, length: 5, elength: 0, contents: ""}]],
+                             {start: 0, length: 11, contents: "foobarbaz"},
+                             {start: 10, length: 5, contents: ""}]],
     // Test string, Blob, string
     [["foo", blob1, "baz"], [{start: 0, length: 3, contents:  "foo"},
                              {start: 3, length: 8, contents:  "squiggle"},
                              {start: 2, length: 2, contents:  "os"},
                              {start: 10, length: 2, contents: "eb"}]],
     // Test blob, string, blob
     [[blob1, "foo", blob1], [{start: 0, length: 8, contents:  "squiggle"},
                              {start: 7, length: 2, contents:  "ef"},
                              {start: 10, length: 2, contents: "os"},
                              {start: 1, length: 3, contents:  "qui"},
                              {start: 12, length: 3, contents: "qui"},
-                             {start: 40, length: 20, elength: 0, contents: ""}]],
+                             {start: 40, length: 20, contents: ""}]],
     // Test blobs all the way down
     [[blob2, blob1, blob2], [{start: 0, length: 4, contents:  "ohai"},
                              {start: 4, length: 8, contents:  "squiggle"},
                              {start: 12, length: 4, contents: "ohai"},
                              {start: 1, length: 2, contents:  "ha"},
                              {start: 5, length: 4, contents:  "quig"}]],
     // Test an array buffer
     [[aB, blob1, "foo"],    [{start: 0, length: 8, contents:  "ABCDEFGH"},
                              {start: 8, length:10, contents:  "IJKLMNOPsq"},
                              {start: 17, length: 3, contents: "qui"},
                              {start: 4, length: 8, contents:  "EFGHIJKL"}]],
     // Test type coercion of a number
     [[3, aB, "foo"],        [{start: 0, length: 8, contents:  "3ABCDEFG"},
                              {start: 8, length:10, contents:  "HIJKLMNOPf"},
-                             {start: 17, length: 4, elength: 3, contents: "foo"},
+                             {start: 17, length: 4, contents: "foo"},
                              {start: 4, length: 8, contents:  "DEFGHIJK"}]]
  ];
 
 let testCounter = 0;
 
 function doTest(data) {
   testCounter++;
 
@@ -105,27 +141,26 @@ function doTest(data) {
 	  blob.expando = bb; // Do we leak?
     }
 
     blobs.forEach(doAppend);
     ok(true, "Test " + testCounter + " appended all successfully");
     let blob = bb.getBlob();
     ok(blob, "Test " + testCounter + " got blob");
     ok(blob instanceof Blob, "Test " + testCounter + " blob is a Blob");
-    //ok(!(blob instanceof File), "Test " + testCounter + " blob is not a File");
+    ok(!(blob instanceof File), "Test " + testCounter + " blob is not a File");
 
     let slice = blob.mozSlice(test.start, test.start + test.length);
     ok(slice, "Test " + testCounter + " got slice");
     ok(slice instanceof Blob, "Test " + testCounter + " slice is a Blob");
-    //ok(!(slice instanceof File), "Test " + testCounter + " slice is not a File");
-    is(slice.size,"elength" in test ? test.elength : test.length,
+    ok(!(slice instanceof File), "Test " + testCounter + " slice is not a File");
+    is(slice.size, test.contents.length,
        "Test " + testCounter + " slice is correct size");
 
-    testFile(slice, test.contents, "Test " + testCounter,
-             "elength" in test ? test.elength : test.length);
+    testFile(slice, test.contents, "Test " + testCounter);
   }
   tests.forEach(runTest);
   SpecialPowers.gc();
 }
 
 SimpleTest.waitForExplicitFinish();
 testData.forEach(doTest);
 
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug664916.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=664916
+-->
+<head>
+  <title>Test for Bug 664916</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=664916">Mozilla Bug 664916</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+
+/** Test for Bug 664916 **/
+var div = document.createElement("div");
+var textNode = document.createTextNode("x")
+var tagNameGetter = div.__lookupGetter__("tagName");
+
+var tagName = "";
+try {
+  tagName = tagNameGetter.call(textNode);
+  ok(false, "Should throw when calling tagname getter on text node");
+} catch(e) {
+  ok(true, "Should throw when calling tagname getter on text node");
+}
+is(tagName, "", "Should not have changed tagName yet");
+tagName = tagNameGetter.call(div);
+is(tagName, "DIV", "Should get the right tag name");
+</script>
+</pre>
+</body>
+</html>
--- a/content/base/test/test_bug666604.html
+++ b/content/base/test/test_bug666604.html
@@ -18,16 +18,28 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a href="javascript:activationListener()" id="testlink">test</a>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 666604 **/
 
 SimpleTest.waitForExplicitFinish();
 
+function hitEventLoop(times, next)
+{
+  if (times == 0) {
+     next();
+     return;
+   }
+ 
+  SimpleTest.executeSoon(function() {
+    hitEventLoop(times - 1, next);
+  });
+}
+
 var activationListener;
 
 function dispatchClick(target, ctrl) {
   var e = document.createEvent("MouseEvent");
   e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, 
                    ctrl, false, false, false, 0, null);
   target.dispatchEvent(e);
 }
@@ -66,27 +78,27 @@ function test2() {
 
 function test3() {
   activationListener =
   function() {
     ok(false, "Untrusted click+ctrl should not activate a link");
     test4();
   }
   dispatchClick(testlink, true);
-  setTimeout(test4, 1000);
+  hitEventLoop(10, test4);
 }
 
 function test4() {
   activationListener =
     function() {
       ok(false, "Untrusted return keypress+ctrl should not activate a link");
       test5();
     }
   dispatchReturn(testlink, true);
-  setTimeout(test5, 1000);
+  hitEventLoop(10, test5);
 }
 
 function test5() {
   activationListener =
     function() {
       ok(true, "click() should activate a link");
       test6();
     }
@@ -97,28 +109,46 @@ function test6() {
   activationListener =
     function() {
       ok(true, "Untrusted DOMActivate should activate a link");
       test7();
     }
   dispatchDOMActivate(testlink);
 }
 
+var oldPref;
 function test7() {
+  oldPref = SpecialPowers.getBoolPref("dom.disable_open_during_load");
+  SpecialPowers.setBoolPref("dom.disable_open_during_load", false);
   testlink.href = "javascript:opener.activationListener(); window.close();";
   testlink.target = "_blank";
   activationListener =
     function() {
       ok(true, "Click() should activate a link");
-      setTimeout(test9, 0);
+      setTimeout(test8, 0);
     }
   testlink.click();
 }
 
+function test8() {
+  SpecialPowers.setBoolPref("dom.disable_open_during_load", true);
+  testlink.href = "javascript:opener.activationListener(); window.close();";
+  testlink.target = "_blank";
+  activationListener =
+    function() {
+      ok(false, "Click() should not activate a link");
+      setTimeout(test9, 0);
+    }
+  testlink.click();  
+  hitEventLoop(10, test9);
+} 
+
+
 function test9() {
+  SpecialPowers.setBoolPref("dom.disable_open_during_load", oldPref);
   SimpleTest.finish();
 }
 
 addLoadEvent(test1);
 
 </script>
 </pre>
 </body>
--- a/content/canvas/public/nsICanvasRenderingContextInternal.h
+++ b/content/canvas/public/nsICanvasRenderingContextInternal.h
@@ -117,16 +117,21 @@ public:
   NS_IMETHOD Reset() = 0;
 
   // Return the CanvasLayer for this context, creating
   // one for the given layer manager if not available.
   virtual already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                                        CanvasLayer *aOldLayer,
                                                        LayerManager *aManager) = 0;
 
+  // Return true if the canvas should be forced to be "inactive" to ensure
+  // it can be drawn to the screen even if it's too large to be blitted by
+  // an accelerated CanvasLayer.
+  virtual PRBool ShouldForceInactiveLayer(LayerManager *aManager) { return PR_FALSE; }
+
   virtual void MarkContextClean() = 0;
 
   // Redraw the dirty rectangle of this canvas.
   NS_IMETHOD Redraw(const gfxRect &dirty) = 0;
 
   // Passes a generic nsIPropertyBag options argument, along with the
   // previous one, if any.  Optional.
   NS_IMETHOD SetContextOptions(nsIPropertyBag *aNewOptions) { return NS_OK; }
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -35,17 +35,16 @@
  * 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 "WebGLContext.h"
 
 #include "nsIConsoleService.h"
-#include "nsIPrefService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIClassInfoImpl.h"
 #include "nsContentUtils.h"
 #include "nsIXPConnect.h"
 #include "nsDOMError.h"
 #include "nsIGfxInfo.h"
 
 #include "nsIPropertyBag.h"
@@ -63,20 +62,150 @@
 #include "GLContextProvider.h"
 
 #include "gfxCrashReporterUtils.h"
 
 #include "nsSVGEffects.h"
 
 #include "prenv.h"
 
+#include "mozilla/Preferences.h"
+
 using namespace mozilla;
 using namespace mozilla::gl;
 using namespace mozilla::layers;
 
+WebGLMemoryReporter* WebGLMemoryReporter::sUniqueInstance = nsnull;
+
+NS_MEMORY_REPORTER_IMPLEMENT(WebGLTextureMemoryUsed,
+                             "webgl-texture-memory",
+                             KIND_OTHER,
+                             UNITS_BYTES,
+                             WebGLMemoryReporter::GetTextureMemoryUsed,
+                             "Memory used by WebGL textures. The OpenGL implementation is free to store these textures in either video memory or main memory. This measurement is only a lower bound, actual memory usage may be higher for example if the storage is strided.")
+
+NS_MEMORY_REPORTER_IMPLEMENT(WebGLTextureCount,
+                             "webgl-texture-count",
+                             KIND_OTHER,
+                             UNITS_COUNT,
+                             WebGLMemoryReporter::GetTextureCount,
+                             "Number of WebGL textures.")
+
+NS_MEMORY_REPORTER_IMPLEMENT(WebGLBufferMemoryUsed,
+                             "webgl-buffer-memory",
+                             KIND_OTHER,
+                             UNITS_BYTES,
+                             WebGLMemoryReporter::GetBufferMemoryUsed,
+                             "Memory used by WebGL buffers. The OpenGL implementation is free to store these buffers in either video memory or main memory. This measurement is only a lower bound, actual memory usage may be higher for example if the storage is strided.")
+
+NS_MEMORY_REPORTER_IMPLEMENT(WebGLBufferCacheMemoryUsed,
+                             "webgl-buffer-cache-memory",
+                             KIND_HEAP,
+                             UNITS_BYTES,
+                             WebGLMemoryReporter::GetBufferCacheMemoryUsed,
+                             "Memory used by WebGL buffer caches. The WebGL implementation caches the contents of element array buffers only. This adds up with the webgl-buffer-memory value, but contrary to it, this one represents bytes on the heap, not managed by OpenGL.")
+
+NS_MEMORY_REPORTER_IMPLEMENT(WebGLBufferCount,
+                             "webgl-buffer-count",
+                             KIND_OTHER,
+                             UNITS_COUNT,
+                             WebGLMemoryReporter::GetBufferCount,
+                             "Number of WebGL buffers.")
+
+NS_MEMORY_REPORTER_IMPLEMENT(WebGLRenderbufferMemoryUsed,
+                             "webgl-renderbuffer-memory",
+                             KIND_OTHER,
+                             UNITS_BYTES,
+                             WebGLMemoryReporter::GetRenderbufferMemoryUsed,
+                             "Memory used by WebGL renderbuffers. The OpenGL implementation is free to store these renderbuffers in either video memory or main memory. This measurement is only a lower bound, actual memory usage may be higher for example if the storage is strided.")
+
+NS_MEMORY_REPORTER_IMPLEMENT(WebGLRenderbufferCount,
+                             "webgl-renderbuffer-count",
+                             KIND_OTHER,
+                             UNITS_COUNT,
+                             WebGLMemoryReporter::GetRenderbufferCount,
+                             "Number of WebGL renderbuffers.")
+
+NS_MEMORY_REPORTER_IMPLEMENT(WebGLShaderSourcesSize,
+                             "webgl-shader-sources-size",
+                             KIND_HEAP,
+                             UNITS_BYTES,
+                             WebGLMemoryReporter::GetShaderSourcesSize,
+                             "Combined size of WebGL shader ASCII sources, cached on the heap. This should always be at most a few kilobytes, or dozen kilobytes for very shader-intensive WebGL demos.")
+
+NS_MEMORY_REPORTER_IMPLEMENT(WebGLShaderTranslationLogsSize,
+                             "webgl-shader-translationlogs-size",
+                             KIND_HEAP,
+                             UNITS_BYTES,
+                             WebGLMemoryReporter::GetShaderTranslationLogsSize,
+                             "Combined size of WebGL shader ASCII translation logs, cached on the heap.")
+
+NS_MEMORY_REPORTER_IMPLEMENT(WebGLShaderCount,
+                             "webgl-shader-count",
+                             KIND_OTHER,
+                             UNITS_COUNT,
+                             WebGLMemoryReporter::GetShaderCount,
+                             "Number of WebGL shaders.")
+
+NS_MEMORY_REPORTER_IMPLEMENT(WebGLContextCount,
+                             "webgl-context-count",
+                             KIND_OTHER,
+                             UNITS_COUNT,
+                             WebGLMemoryReporter::GetContextCount,
+                             "Number of WebGL contexts.")
+
+WebGLMemoryReporter* WebGLMemoryReporter::UniqueInstance()
+{
+    if (!sUniqueInstance) {
+        sUniqueInstance = new WebGLMemoryReporter;
+    }
+    return sUniqueInstance;
+}
+
+WebGLMemoryReporter::WebGLMemoryReporter()
+    : mTextureMemoryUsageReporter(new NS_MEMORY_REPORTER_NAME(WebGLTextureMemoryUsed))
+    , mTextureCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLTextureCount))
+    , mBufferMemoryUsageReporter(new NS_MEMORY_REPORTER_NAME(WebGLBufferMemoryUsed))
+    , mBufferCacheMemoryUsageReporter(new NS_MEMORY_REPORTER_NAME(WebGLBufferCacheMemoryUsed))
+    , mBufferCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLBufferCount))
+    , mRenderbufferMemoryUsageReporter(new NS_MEMORY_REPORTER_NAME(WebGLRenderbufferMemoryUsed))
+    , mRenderbufferCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLRenderbufferCount))
+    , mShaderSourcesSizeReporter(new NS_MEMORY_REPORTER_NAME(WebGLShaderSourcesSize))
+    , mShaderTranslationLogsSizeReporter(new NS_MEMORY_REPORTER_NAME(WebGLShaderTranslationLogsSize))
+    , mShaderCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLShaderCount))
+    , mContextCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLContextCount))
+{
+    NS_RegisterMemoryReporter(mTextureMemoryUsageReporter);
+    NS_RegisterMemoryReporter(mTextureCountReporter);
+    NS_RegisterMemoryReporter(mBufferMemoryUsageReporter);
+    NS_RegisterMemoryReporter(mBufferCacheMemoryUsageReporter);    
+    NS_RegisterMemoryReporter(mBufferCountReporter);
+    NS_RegisterMemoryReporter(mRenderbufferMemoryUsageReporter);
+    NS_RegisterMemoryReporter(mRenderbufferCountReporter);
+    NS_RegisterMemoryReporter(mShaderSourcesSizeReporter);
+    NS_RegisterMemoryReporter(mShaderTranslationLogsSizeReporter);
+    NS_RegisterMemoryReporter(mShaderCountReporter);
+    NS_RegisterMemoryReporter(mContextCountReporter);
+}
+
+WebGLMemoryReporter::~WebGLMemoryReporter()
+{
+    NS_UnregisterMemoryReporter(mTextureMemoryUsageReporter);
+    NS_UnregisterMemoryReporter(mTextureCountReporter);
+    NS_UnregisterMemoryReporter(mBufferMemoryUsageReporter);
+    NS_UnregisterMemoryReporter(mBufferCacheMemoryUsageReporter);
+    NS_UnregisterMemoryReporter(mBufferCountReporter);
+    NS_UnregisterMemoryReporter(mRenderbufferMemoryUsageReporter);
+    NS_UnregisterMemoryReporter(mRenderbufferCountReporter);
+    NS_UnregisterMemoryReporter(mShaderSourcesSizeReporter);
+    NS_UnregisterMemoryReporter(mShaderTranslationLogsSizeReporter);
+    NS_UnregisterMemoryReporter(mShaderCountReporter);
+    NS_UnregisterMemoryReporter(mContextCountReporter);
+}
+
 nsresult NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult);
 
 nsresult
 NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult)
 {
     nsIDOMWebGLRenderingContext* ctx = new WebGLContext();
     if (!ctx)
         return NS_ERROR_OUT_OF_MEMORY;
@@ -92,17 +221,17 @@ WebGLContext::WebGLContext()
     mWidth = mHeight = 0;
     mGeneration = 0;
     mInvalidated = PR_FALSE;
     mResetLayer = PR_TRUE;
     mVerbose = PR_FALSE;
     mOptionsFrozen = PR_FALSE;
 
     mActiveTexture = 0;
-    mSynthesizedGLError = LOCAL_GL_NO_ERROR;
+    mWebGLError = LOCAL_GL_NO_ERROR;
     mPixelStoreFlipY = PR_FALSE;
     mPixelStorePremultiplyAlpha = PR_FALSE;
     mPixelStoreColorspaceConversion = BROWSER_DEFAULT_WEBGL;
 
     mShaderValidation = PR_TRUE;
 
     mMapBuffers.Init();
     mMapTextures.Init();
@@ -159,21 +288,24 @@ WebGLContext::WebGLContext()
     mGLMaxVertexTextureImageUnits = 0;
     mGLMaxVaryingVectors = 0;
     mGLMaxFragmentUniformVectors = 0;
     mGLMaxVertexUniformVectors = 0;
     
     // See OpenGL ES 2.0.25 spec, 6.2 State Tables, table 6.13
     mPixelStorePackAlignment = 4;
     mPixelStoreUnpackAlignment = 4;
+    
+    WebGLMemoryReporter::AddWebGLContext(this);
 }
 
 WebGLContext::~WebGLContext()
 {
     DestroyResourcesAndContext();
+    WebGLMemoryReporter::RemoveWebGLContext(this);
 }
 
 static PLDHashOperator
 DeleteTextureFunction(const PRUint32& aKey, WebGLTexture *aValue, void *aData)
 {
     gl::GLContext *gl = (gl::GLContext *) aData;
     NS_ASSERTION(!aValue->Deleted(), "Texture is still in mMapTextures, but is deleted?");
     GLuint name = aValue->GLName();
@@ -408,32 +540,30 @@ WebGLContext::SetDimensions(PRInt32 widt
 
     ScopedGfxFeatureReporter reporter("WebGL");
 
     // At this point we know that the old context is not going to survive, even though we still don't
     // know if creating the new context will succeed.
     DestroyResourcesAndContext();
 
     // Get some prefs for some preferred/overriden things
-    nsCOMPtr<nsIPrefBranch> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
-    NS_ENSURE_TRUE(prefService != nsnull, NS_ERROR_FAILURE);
+    NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_FAILURE);
 
-    PRBool forceOSMesa = PR_FALSE;
-    PRBool preferEGL = PR_FALSE;
-    PRBool preferOpenGL = PR_FALSE;
-    PRBool forceEnabled = PR_FALSE;
-    PRBool disabled = PR_FALSE;
-    PRBool verbose = PR_FALSE;
-
-    prefService->GetBoolPref("webgl.force_osmesa", &forceOSMesa);
-    prefService->GetBoolPref("webgl.prefer-egl", &preferEGL);
-    prefService->GetBoolPref("webgl.prefer-native-gl", &preferOpenGL);
-    prefService->GetBoolPref("webgl.force-enabled", &forceEnabled);
-    prefService->GetBoolPref("webgl.disabled", &disabled);
-    prefService->GetBoolPref("webgl.verbose", &verbose);
+    PRBool forceOSMesa =
+        Preferences::GetBool("webgl.force_osmesa", PR_FALSE);
+    PRBool preferEGL =
+        Preferences::GetBool("webgl.prefer-egl", PR_FALSE);
+    PRBool preferOpenGL =
+        Preferences::GetBool("webgl.prefer-native-gl", PR_FALSE);
+    PRBool forceEnabled =
+        Preferences::GetBool("webgl.force-enabled", PR_FALSE);
+    PRBool disabled =
+        Preferences::GetBool("webgl.disabled", PR_FALSE);
+    PRBool verbose =
+        Preferences::GetBool("webgl.verbose", PR_FALSE);
 
     if (disabled)
         return NS_ERROR_FAILURE;
 
     mVerbose = verbose;
 
     // We're going to create an entirely new context.  If our
     // generation is not 0 right now (that is, if this isn't the first
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -51,16 +51,17 @@
 #include "nsIDocShell.h"
 
 #include "nsIDOMWebGLRenderingContext.h"
 #include "nsICanvasRenderingContextInternal.h"
 #include "nsHTMLCanvasElement.h"
 #include "nsWeakReference.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIJSNativeInitializer.h"
+#include "nsIMemoryReporter.h"
 
 #include "GLContextProvider.h"
 #include "Layers.h"
 
 #include "CheckedInt.h"
 
 class nsIDocShell;
 class nsIPropertyBag;
@@ -315,16 +316,18 @@ struct WebGLContextOptions {
     bool preserveDrawingBuffer;
 };
 
 class WebGLContext :
     public nsIDOMWebGLRenderingContext,
     public nsICanvasRenderingContextInternal,
     public nsSupportsWeakReference
 {
+    friend class WebGLMemoryReporter;
+
 public:
     WebGLContext();
     virtual ~WebGLContext();
 
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
     NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(WebGLContext, nsIDOMWebGLRenderingContext)
 
@@ -362,16 +365,18 @@ public:
 
     nsresult ErrorInvalidEnum(const char *fmt = 0, ...);
     nsresult ErrorInvalidOperation(const char *fmt = 0, ...);
     nsresult ErrorInvalidValue(const char *fmt = 0, ...);
     nsresult ErrorInvalidEnumInfo(const char *info, PRUint32 enumvalue) {
         return ErrorInvalidEnum("%s: invalid enum value 0x%x", info, enumvalue);
     }
     nsresult ErrorOutOfMemory(const char *fmt = 0, ...);
+    
+    const char *ErrorName(GLenum error);
 
     WebGLTexture *activeBoundTextureForTarget(WebGLenum target) {
         return target == LOCAL_GL_TEXTURE_2D ? mBound2DTextures[mActiveTexture]
                                              : mBoundCubeMapTextures[mActiveTexture];
     }
 
     already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                                  CanvasLayer *aOldLayer,
@@ -387,16 +392,33 @@ public:
     // WebGL has more complex needs than GLContext as content controls GL state.
     void ForceClearFramebufferWithDefaultValues(PRUint32 mask, const nsIntRect& viewportRect);
 
     // if the preserveDrawingBuffer context option is false, we need to clear the back buffer
     // after it's been presented to the compositor. This function does that if needed.
     // See section 2.2 in the WebGL spec.
     void EnsureBackbufferClearedAsNeeded();
 
+    // checks for GL errors, clears any pending GL error, stores the current GL error in currentGLError,
+    // and copies it into mWebGLError if it doesn't already have an error set
+    void UpdateWebGLErrorAndClearGLError(GLenum *currentGLError) {
+        // get and clear GL error in ALL cases
+        *currentGLError = gl->GetAndClearError();
+        // only store in mWebGLError if is hasn't already recorded an error
+        if (!mWebGLError)
+            mWebGLError = *currentGLError;
+    }
+    
+    // checks for GL errors, clears any pending GL error,
+    // and stores the current GL error into mWebGLError if it doesn't already have an error set
+    void UpdateWebGLErrorAndClearGLError() {
+        GLenum currentGLError;
+        UpdateWebGLErrorAndClearGLError(&currentGLError);
+    }
+
 protected:
     void SetDontKnowIfNeedFakeBlack() {
         mFakeBlackStatus = DontKnowIfNeedFakeBlack;
     }
 
     PRBool NeedFakeBlack();
     void BindFakeBlackTextures();
     void UnbindFakeBlackTextures();
@@ -419,17 +441,17 @@ protected:
     WebGLContextOptions mOptions;
 
     PRPackedBool mInvalidated;
     PRPackedBool mResetLayer;
     PRPackedBool mVerbose;
     PRPackedBool mOptionsFrozen;
 
     WebGLuint mActiveTexture;
-    WebGLenum mSynthesizedGLError;
+    WebGLenum mWebGLError;
 
     // whether shader validation is supported
     PRBool mShaderValidation;
 
     // some GL constants
     PRInt32 mGLMaxVertexAttribs;
     PRInt32 mGLMaxTextureUnits;
     PRInt32 mGLMaxTextureSize;
@@ -463,16 +485,18 @@ protected:
     PRBool ValidateStencilOpEnum(WebGLenum action, const char *info);
     PRBool ValidateFaceEnum(WebGLenum face, const char *info);
     PRBool ValidateBufferUsageEnum(WebGLenum target, const char *info);
     PRBool ValidateTexFormatAndType(WebGLenum format, WebGLenum type, int jsArrayType,
                                       PRUint32 *texelSize, const char *info);
     PRBool ValidateDrawModeEnum(WebGLenum mode, const char *info);
     PRBool ValidateAttribIndex(WebGLuint index, const char *info);
     PRBool ValidateStencilParamsForDrawCall();
+    
+    static PRUint32 GetTexelSize(WebGLenum format, WebGLenum type);
 
     void Invalidate();
     void DestroyResourcesAndContext();
 
     void MakeContextCurrent() { gl->MakeCurrent(); }
 
     // helpers
     nsresult TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum internalformat,
@@ -543,16 +567,34 @@ protected:
     PRBool CanGetConcreteObject(const char *info,
                                 BaseInterfaceType *aInterface,
                                 PRBool *isNull = 0,
                                 PRBool *isDeleted = 0);
 
     PRInt32 MaxTextureSizeForTarget(WebGLenum target) const {
         return target == LOCAL_GL_TEXTURE_2D ? mGLMaxTextureSize : mGLMaxCubeMapTextureSize;
     }
+    
+    /** like glBufferData but if the call may change the buffer size, checks any GL error generated
+     * by this glBufferData call and returns it */
+    GLenum CheckedBufferData(GLenum target,
+                             GLsizeiptr size,
+                             const GLvoid *data,
+                             GLenum usage);
+    /** like glTexImage2D but if the call may change the texture size, checks any GL error generated
+     * by this glTexImage2D call and returns it */
+    GLenum CheckedTexImage2D(GLenum target,
+                             GLint level,
+                             GLenum internalFormat,
+                             GLsizei width,
+                             GLsizei height,
+                             GLint border,
+                             GLenum format,
+                             GLenum type,
+                             const GLvoid *data);
 
     // the buffers bound to the current program's attribs
     nsTArray<WebGLVertexAttribData> mAttribBuffers;
 
     // the textures bound to any sampler uniforms
     nsTArray<WebGLObjectRefPtr<WebGLTexture> > mUniformTextures;
 
     // textures bound to 
@@ -654,20 +696,20 @@ protected:
 // that we need to track.
 class WebGLRectangleObject
 {
 protected:
     WebGLRectangleObject()
         : mWidth(0), mHeight(0) { }
 
 public:
-    WebGLsizei width() { return mWidth; }
+    WebGLsizei width() const { return mWidth; }
     void width(WebGLsizei value) { mWidth = value; }
 
-    WebGLsizei height() { return mHeight; }
+    WebGLsizei height() const { return mHeight; }
     void height(WebGLsizei value) { mHeight = value; }
 
     void setDimensions(WebGLsizei width, WebGLsizei height) {
         mWidth = width;
         mHeight = height;
     }
 
     void setDimensions(WebGLRectangleObject *rect) {
@@ -675,16 +717,20 @@ public:
             mWidth = rect->width();
             mHeight = rect->height();
         } else {
             mWidth = 0;
             mHeight = 0;
         }
     }
 
+    bool HasSameDimensionsAs(const WebGLRectangleObject& other) const {
+        return width() == other.width() && height() == other.height(); 
+    }
+
 protected:
     WebGLsizei mWidth;
     WebGLsizei mHeight;
 };
 
 // This class is a mixin for objects that are tied to a specific
 // context (which is to say, all of them).  They provide initialization
 // as well as comparison with the current context.
@@ -715,17 +761,17 @@ class WebGLBuffer :
 {
 public:
     NS_DECLARE_STATIC_IID_ACCESSOR(WEBGLBUFFER_PRIVATE_IID)
 
     WebGLBuffer(WebGLContext *context, WebGLuint name) :
         WebGLContextBoundObject(context),
         mName(name), mDeleted(PR_FALSE), mHasEverBeenBound(PR_FALSE),
         mByteLength(0), mTarget(LOCAL_GL_NONE), mData(nsnull)
-    { }
+    {}
 
     ~WebGLBuffer() {
         Delete();
     }
 
     void Delete() {
         if (mDeleted)
             return;
@@ -838,17 +884,16 @@ protected:
 
 NS_DEFINE_STATIC_IID_ACCESSOR(WebGLBuffer, WEBGLBUFFER_PRIVATE_IID)
 
 #define WEBGLTEXTURE_PRIVATE_IID \
     {0x4c19f189, 0x1f86, 0x4e61, {0x96, 0x21, 0x0a, 0x11, 0xda, 0x28, 0x10, 0xdd}}
 class WebGLTexture :
     public nsIWebGLTexture,
     public WebGLZeroingObject,
-    public WebGLRectangleObject,
     public WebGLContextBoundObject
 {
 public:
     NS_DECLARE_STATIC_IID_ACCESSOR(WEBGLTEXTURE_PRIVATE_IID)
 
     WebGLTexture(WebGLContext *context, WebGLuint name) :
         WebGLContextBoundObject(context),
         mDeleted(PR_FALSE), mHasEverBeenBound(PR_FALSE), mName(name),
@@ -885,18 +930,24 @@ protected:
 
     PRBool mDeleted;
     PRBool mHasEverBeenBound;
     WebGLuint mName;
 
     // we store information about the various images that are part of
     // this texture (cubemap faces, mipmap levels)
 
+public:
+
     struct ImageInfo {
         ImageInfo() : mWidth(0), mHeight(0), mFormat(0), mType(0), mIsDefined(PR_FALSE) {}
+        ImageInfo(WebGLsizei width, WebGLsizei height,
+                  WebGLenum format, WebGLenum type)
+            : mWidth(width), mHeight(height), mFormat(format), mType(type), mIsDefined(PR_TRUE) {}
+
         PRBool operator==(const ImageInfo& a) const {
             return mWidth == a.mWidth && mHeight == a.mHeight &&
                    mFormat == a.mFormat && mType == a.mType;
         }
         PRBool operator!=(const ImageInfo& a) const {
             return !(*this == a);
         }
         PRBool IsSquare() const {
@@ -904,23 +955,27 @@ protected:
         }
         PRBool IsPositive() const {
             return mWidth > 0 && mHeight > 0;
         }
         PRBool IsPowerOfTwo() const {
             return is_pot_assuming_nonnegative(mWidth) &&
                    is_pot_assuming_nonnegative(mHeight); // negative sizes should never happen (caught in texImage2D...)
         }
+        PRInt64 MemoryUsage() const {
+            if (!mIsDefined)
+                return 0;
+            PRInt64 texelSize = WebGLContext::GetTexelSize(mFormat, mType);
+            return PRInt64(mWidth) * PRInt64(mHeight) * texelSize;
+        }
         WebGLsizei mWidth, mHeight;
         WebGLenum mFormat, mType;
         PRBool mIsDefined;
     };
 
-public:
-
     ImageInfo& ImageInfoAt(size_t level, size_t face = 0) {
 #ifdef DEBUG
         if (face >= mFacesCount)
             NS_ERROR("wrong face index, must be 0 for TEXTURE_2D and at most 5 for cube maps");
 #endif
         // no need to check level as a wrong value would be caught by ElementAt().
         return mImageInfos.ElementAt(level * mFacesCount + face);
     }
@@ -934,16 +989,32 @@ public:
                face < mFacesCount &&
                ImageInfoAt(level, 0).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;
+        for(size_t face = 0; face < mFacesCount; face++) {
+            if (mHaveGeneratedMipmap) {
+                // Each mipmap level is 1/4 the size of the previous level
+                // 1 + x + x^2 + ... = 1/(1-x)
+                // for x = 1/4, we get 1/(1-1/4) = 4/3
+                result += ImageInfoAt(0, face).MemoryUsage() * 4 / 3;
+            } else {
+                for(size_t level = 0; level <= mMaxLevelWithCustomImages; level++)
+                    result += ImageInfoAt(level, face).MemoryUsage();
+            }
+        }
+        return result;
+    }
+
 protected:
 
     WebGLenum mTarget;
     WebGLenum mMinFilter, mMagFilter, mWrapS, mWrapT;
 
     size_t mFacesCount, mMaxLevelWithCustomImages;
     nsTArray<ImageInfo> mImageInfos;
 
@@ -1030,33 +1101,26 @@ public:
                 mContext->gl->fTexParameteri(mTarget, LOCAL_GL_TEXTURE_WRAP_R, LOCAL_GL_CLAMP_TO_EDGE);
         }
 
         mHasEverBeenBound = PR_TRUE;
     }
 
     void SetImageInfo(WebGLenum aTarget, WebGLint aLevel,
                       WebGLsizei aWidth, WebGLsizei aHeight,
-                      WebGLenum aFormat = 0, WebGLenum aType = 0)
+                      WebGLenum aFormat, WebGLenum aType)
     {
         if ( (aTarget == LOCAL_GL_TEXTURE_2D) != (mTarget == LOCAL_GL_TEXTURE_2D) )
             return;
 
         size_t face = FaceForTarget(aTarget);
 
         EnsureMaxLevelWithCustomImagesAtLeast(aLevel);
 
-        ImageInfo& imageInfo = ImageInfoAt(aLevel, face);
-        imageInfo.mWidth  = aWidth;
-        imageInfo.mHeight = aHeight;
-        if (aFormat)
-            imageInfo.mFormat = aFormat;
-        if (aType)
-            imageInfo.mType = aType;
-        imageInfo.mIsDefined = PR_TRUE;
+        ImageInfoAt(aLevel, face) = ImageInfo(aWidth, aHeight, aFormat, aType);
 
         if (aLevel > 0)
             SetCustomMipmap();
 
         SetDontKnowIfNeedFakeBlack();
     }
 
     void SetMinFilter(WebGLenum aMinFilter) {
@@ -1461,16 +1525,17 @@ class WebGLRenderbuffer :
 {
 public:
     NS_DECLARE_STATIC_IID_ACCESSOR(WEBGLRENDERBUFFER_PRIVATE_IID)
 
     WebGLRenderbuffer(WebGLContext *context, WebGLuint name, WebGLuint secondBufferName = 0) :
         WebGLContextBoundObject(context),
         mName(name),
         mInternalFormat(0),
+        mInternalFormatForGL(0),
         mDeleted(PR_FALSE), mHasEverBeenBound(PR_FALSE), mInitialized(PR_FALSE)
     { }
 
     void Delete() {
         if (mDeleted)
             return;
         ZeroOwners();
         mDeleted = PR_TRUE;
@@ -1480,34 +1545,62 @@ public:
     void SetHasEverBeenBound(PRBool x) { mHasEverBeenBound = x; }
     WebGLuint GLName() const { return mName; }
 
     PRBool Initialized() const { return mInitialized; }
     void SetInitialized(PRBool aInitialized) { mInitialized = aInitialized; }
 
     WebGLenum InternalFormat() const { return mInternalFormat; }
     void SetInternalFormat(WebGLenum aInternalFormat) { mInternalFormat = aInternalFormat; }
+    
+    WebGLenum InternalFormatForGL() const { return mInternalFormatForGL; }
+    void SetInternalFormatForGL(WebGLenum aInternalFormatForGL) { mInternalFormatForGL = aInternalFormatForGL; }
+    
+    PRInt64 MemoryUsage() const {
+        PRInt64 pixels = PRInt64(width()) * PRInt64(height());
+        switch (mInternalFormatForGL) {
+            case LOCAL_GL_STENCIL_INDEX8:
+                return pixels;
+            case LOCAL_GL_RGBA4:
+            case LOCAL_GL_RGB5_A1:
+            case LOCAL_GL_RGB565:
+            case LOCAL_GL_DEPTH_COMPONENT16:
+                return 2 * pixels;
+            case LOCAL_GL_RGB8:
+            case LOCAL_GL_DEPTH_COMPONENT24:
+                return 3*pixels;
+            case LOCAL_GL_RGBA8:
+            case LOCAL_GL_DEPTH24_STENCIL8:
+                return 4*pixels;
+            default:
+                break;
+        }
+        NS_ABORT();
+        return 0;
+    }
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIWEBGLRENDERBUFFER
 
 protected:
     WebGLuint mName;
     WebGLenum mInternalFormat;
+    WebGLenum mInternalFormatForGL;
 
     PRBool mDeleted;
     PRBool mHasEverBeenBound;
     PRBool mInitialized;
 
     friend class WebGLFramebuffer;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(WebGLRenderbuffer, WEBGLRENDERBUFFER_PRIVATE_IID)
 
 class WebGLFramebufferAttachment
+    : public WebGLRectangleObject
 {
     // deleting a texture or renderbuffer immediately detaches it
     WebGLObjectRefPtr<WebGLTexture> mTexturePtr;
     WebGLObjectRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
     WebGLenum mAttachmentPoint;
     WebGLint mTextureLevel;
     WebGLenum mTextureCubeMapFace;
 
@@ -1533,20 +1626,27 @@ public:
                format == LOCAL_GL_RGB5_A1;
     }
 
     void SetTexture(WebGLTexture *tex, WebGLint level, WebGLenum face) {
         mTexturePtr = tex;
         mRenderbufferPtr = nsnull;
         mTextureLevel = level;
         mTextureCubeMapFace = face;
+        if (tex) {
+            const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(level, face);
+            setDimensions(imageInfo.mWidth, imageInfo.mHeight);
+        } else {
+            setDimensions(0, 0);
+        }
     }
     void SetRenderbuffer(WebGLRenderbuffer *rb) {
         mTexturePtr = nsnull;
         mRenderbufferPtr = rb;
+        setDimensions(rb);
     }
     WebGLTexture *Texture() const {
         return mTexturePtr.get();
     }
     WebGLRenderbuffer *Renderbuffer() const {
         return mRenderbufferPtr.get();
     }
     WebGLint TextureLevel() const {
@@ -1586,17 +1686,16 @@ public:
     }
 };
 
 #define WEBGLFRAMEBUFFER_PRIVATE_IID \
     {0x0052a16f, 0x4bc9, 0x4a55, {0x9d, 0xa3, 0x54, 0x95, 0xaa, 0x4e, 0x80, 0xb9}}
 class WebGLFramebuffer :
     public nsIWebGLFramebuffer,
     public WebGLZeroingObject,
-    public WebGLRectangleObject,
     public WebGLContextBoundObject
 {
 public:
     NS_DECLARE_STATIC_IID_ACCESSOR(WEBGLFRAMEBUFFER_PRIVATE_IID)
 
     WebGLFramebuffer(WebGLContext *context, WebGLuint name) :
         WebGLContextBoundObject(context),
         mName(name), mDeleted(PR_FALSE), mHasEverBeenBound(PR_FALSE),
@@ -1611,16 +1710,19 @@ public:
             return;
         ZeroOwners();
         mDeleted = PR_TRUE;
     }
     PRBool Deleted() { return mDeleted; }
     PRBool HasEverBeenBound() { return mHasEverBeenBound; }
     void SetHasEverBeenBound(PRBool x) { mHasEverBeenBound = x; }
     WebGLuint GLName() { return mName; }
+    
+    WebGLsizei width() { return mColorAttachment.width(); }
+    WebGLsizei height() { return mColorAttachment.height(); }
 
     nsresult FramebufferRenderbuffer(WebGLenum target,
                                      WebGLenum attachment,
                                      WebGLenum rbtarget,
                                      nsIWebGLRenderbuffer *rbobj)
     {
         WebGLuint renderbuffername;
         PRBool isNull;
@@ -1647,21 +1749,17 @@ public:
             break;
         case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
             mDepthStencilAttachment.SetRenderbuffer(wrb);
             break;
         default:
             // finish checking that the 'attachment' parameter is among the allowed values
             if (attachment != LOCAL_GL_COLOR_ATTACHMENT0)
                 return mContext->ErrorInvalidEnumInfo("framebufferRenderbuffer: attachment", attachment);
-            if (!isNull) {
-                // ReadPixels needs alpha and size information, but only
-                // for COLOR_ATTACHMENT0
-                setDimensions(wrb);
-            }
+
             mColorAttachment.SetRenderbuffer(wrb);
             break;
         }
 
         mContext->MakeContextCurrent();
         if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
             mContext->gl->fFramebufferRenderbuffer(target, LOCAL_GL_DEPTH_ATTACHMENT, rbtarget, renderbuffername);
             mContext->gl->fFramebufferRenderbuffer(target, LOCAL_GL_STENCIL_ATTACHMENT, rbtarget, renderbuffername);
@@ -1686,42 +1784,39 @@ public:
                                                   tobj, &wtex, &texturename, &isNull))
         {
             return NS_OK;
         }
 
         if (target != LOCAL_GL_FRAMEBUFFER)
             return mContext->ErrorInvalidEnumInfo("framebufferTexture2D: target", target);
 
-        if (!isNull && textarget != LOCAL_GL_TEXTURE_2D &&
+        if (textarget != LOCAL_GL_TEXTURE_2D &&
             (textarget < LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
-            textarget > LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))
+             textarget > LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))
             return mContext->ErrorInvalidEnumInfo("framebufferTexture2D: invalid texture target", textarget);
 
-        if (!isNull && level > 0)
+        if (level != 0)
             return mContext->ErrorInvalidValue("framebufferTexture2D: level must be 0");
 
-        WebGLint face = (textarget == LOCAL_GL_TEXTURE_2D) ? 0 : textarget;
+        size_t face = WebGLTexture::FaceForTarget(textarget);
         switch (attachment) {
         case LOCAL_GL_DEPTH_ATTACHMENT:
             mDepthAttachment.SetTexture(wtex, level, face);
             break;
         case LOCAL_GL_STENCIL_ATTACHMENT:
             mStencilAttachment.SetTexture(wtex, level, face);
             break;
         case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
             mDepthStencilAttachment.SetTexture(wtex, level, face);
             break;
         default:
             if (attachment != LOCAL_GL_COLOR_ATTACHMENT0)
                 return mContext->ErrorInvalidEnumInfo("framebufferTexture2D: attachment", attachment);
 
-            // keep data for readPixels, function only uses COLOR_ATTACHMENT0
-            setDimensions(wtex);
-
             mColorAttachment.SetTexture(wtex, level, face);
             break;
         }
 
         mContext->MakeContextCurrent();
         if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
             mContext->gl->fFramebufferTexture2D(target, LOCAL_GL_DEPTH_ATTACHMENT, textarget, texturename, level);
             mContext->gl->fFramebufferTexture2D(target, LOCAL_GL_STENCIL_ATTACHMENT, textarget, texturename, level);
@@ -1754,23 +1849,32 @@ public:
         if (mColorAttachment.IsIncompatibleWithAttachmentPoint() ||
             mDepthAttachment.IsIncompatibleWithAttachmentPoint() ||
             mStencilAttachment.IsIncompatibleWithAttachmentPoint() ||
             mDepthStencilAttachment.IsIncompatibleWithAttachmentPoint())
         {
             // some attachment is incompatible with its attachment point
             return PR_TRUE;
         }
-        else if (int(mDepthAttachment.IsNull()) +
-                 int(mStencilAttachment.IsNull()) +
-                 int(mDepthStencilAttachment.IsNull()) <= 1)
+        
+        if (int(mDepthAttachment.IsNull()) +
+            int(mStencilAttachment.IsNull()) +
+            int(mDepthStencilAttachment.IsNull()) <= 1)
         {
             // has at least two among Depth, Stencil, DepthStencil
             return PR_TRUE;
         }
+        
+        if (!mDepthAttachment.IsNull() && !mDepthAttachment.HasSameDimensionsAs(mColorAttachment))
+            return PR_TRUE;
+        if (!mStencilAttachment.IsNull() && !mStencilAttachment.HasSameDimensionsAs(mColorAttachment))
+            return PR_TRUE;
+        if (!mDepthStencilAttachment.IsNull() && !mDepthStencilAttachment.HasSameDimensionsAs(mColorAttachment))
+            return PR_TRUE;
+        
         else return PR_FALSE;
     }
 
     const WebGLFramebufferAttachment& ColorAttachment() const {
         return mColorAttachment;
     }
 
     const WebGLFramebufferAttachment& DepthAttachment() const {
@@ -2061,11 +2165,204 @@ WebGLContext::CanGetConcreteObject(const
                               BaseInterfaceType *aInterface,
                               PRBool *isNull,
                               PRBool *isDeleted)
 {
     ConcreteObjectType *aConcreteObject;
     return GetConcreteObject(info, aInterface, &aConcreteObject, isNull, isDeleted, PR_FALSE);
 }
 
+class WebGLMemoryReporter
+{
+    WebGLMemoryReporter();
+    ~WebGLMemoryReporter();
+    static WebGLMemoryReporter* sUniqueInstance;
+
+    // here we store plain pointers, not RefPtrs: we don't want the WebGLMemoryReporter unique instance to keep alive all
+    // WebGLContexts ever created.
+    typedef nsTArray<const WebGLContext*> ContextsArrayType;
+    ContextsArrayType mContexts;
+    
+    nsIMemoryReporter *mTextureMemoryUsageReporter;
+    nsIMemoryReporter *mTextureCountReporter;
+    nsIMemoryReporter *mBufferMemoryUsageReporter;
+    nsIMemoryReporter *mBufferCacheMemoryUsageReporter;
+    nsIMemoryReporter *mBufferCountReporter;
+    nsIMemoryReporter *mRenderbufferMemoryUsageReporter;
+    nsIMemoryReporter *mRenderbufferCountReporter;
+    nsIMemoryReporter *mShaderSourcesSizeReporter;
+    nsIMemoryReporter *mShaderTranslationLogsSizeReporter;
+    nsIMemoryReporter *mShaderCountReporter;
+    nsIMemoryReporter *mContextCountReporter;
+
+    static WebGLMemoryReporter* UniqueInstance();
+
+    static ContextsArrayType & Contexts() { return UniqueInstance()->mContexts; }
+
+  public:
+
+    static void AddWebGLContext(const WebGLContext* c) {
+        Contexts().AppendElement(c);
+    }
+
+    static void RemoveWebGLContext(const WebGLContext* c) {
+        ContextsArrayType & contexts = Contexts();
+        contexts.RemoveElement(c);
+        if (contexts.IsEmpty()) {
+            delete sUniqueInstance;
+            sUniqueInstance = nsnull;
+        }
+    }
+
+    static PLDHashOperator TextureMemoryUsageFunction(const PRUint32&, WebGLTexture *aValue, void *aData)
+    {
+        PRInt64 *result = (PRInt64*) aData;
+        *result += aValue->MemoryUsage();
+        return PL_DHASH_NEXT;
+    }
+
+    static PRInt64 GetTextureMemoryUsed() {
+        const ContextsArrayType & contexts = Contexts();
+        PRInt64 result = 0;
+        for(size_t i = 0; i < contexts.Length(); ++i) {
+            PRInt64 textureMemoryUsageForThisContext = 0;
+            contexts[i]->mMapTextures.EnumerateRead(TextureMemoryUsageFunction, &textureMemoryUsageForThisContext);
+            result += textureMemoryUsageForThisContext;
+        }
+        return result;
+    }
+    
+    static PRInt64 GetTextureCount() {
+        const ContextsArrayType & contexts = Contexts();
+        PRInt64 result = 0;
+        for(size_t i = 0; i < contexts.Length(); ++i) {
+            result += contexts[i]->mMapTextures.Count();
+        }
+        return result;
+    }
+    
+    static PLDHashOperator BufferMemoryUsageFunction(const PRUint32&, WebGLBuffer *aValue, void *aData)
+    {
+        PRInt64 *result = (PRInt64*) aData;
+        *result += aValue->ByteLength();
+        return PL_DHASH_NEXT;
+    }
+
+    static PRInt64 GetBufferMemoryUsed() {
+        const ContextsArrayType & contexts = Contexts();
+        PRInt64 result = 0;
+        for(size_t i = 0; i < contexts.Length(); ++i) {
+            PRInt64 bufferMemoryUsageForThisContext = 0;
+            contexts[i]->mMapBuffers.EnumerateRead(BufferMemoryUsageFunction, &bufferMemoryUsageForThisContext);
+            result += bufferMemoryUsageForThisContext;
+        }
+        return result;
+    }
+    
+    static PLDHashOperator BufferCacheMemoryUsageFunction(const PRUint32&, WebGLBuffer *aValue, void *aData)
+    {
+        PRInt64 *result = (PRInt64*) aData;
+        // element array buffers are cached in the WebGL implementation. Other buffers aren't.
+        if (aValue->Target() == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
+          *result += aValue->ByteLength();
+        return PL_DHASH_NEXT;
+    }
+
+    static PRInt64 GetBufferCacheMemoryUsed() {
+        const ContextsArrayType & contexts = Contexts();
+        PRInt64 result = 0;
+        for(size_t i = 0; i < contexts.Length(); ++i) {
+            PRInt64 bufferCacheMemoryUsageForThisContext = 0;
+            contexts[i]->mMapBuffers.EnumerateRead(BufferCacheMemoryUsageFunction, &bufferCacheMemoryUsageForThisContext);
+            result += bufferCacheMemoryUsageForThisContext;
+        }
+        return result;
+    }
+
+    static PRInt64 GetBufferCount() {
+        const ContextsArrayType & contexts = Contexts();
+        PRInt64 result = 0;
+        for(size_t i = 0; i < contexts.Length(); ++i) {
+            result += contexts[i]->mMapBuffers.Count();
+        }
+        return result;
+    }
+    
+    static PLDHashOperator RenderbufferMemoryUsageFunction(const PRUint32&, WebGLRenderbuffer *aValue, void *aData)
+    {
+        PRInt64 *result = (PRInt64*) aData;
+        *result += aValue->MemoryUsage();
+        return PL_DHASH_NEXT;
+    }
+
+    static PRInt64 GetRenderbufferMemoryUsed() {
+        const ContextsArrayType & contexts = Contexts();
+        PRInt64 result = 0;
+        for(size_t i = 0; i < contexts.Length(); ++i) {
+            PRInt64 bufferMemoryUsageForThisContext = 0;
+            contexts[i]->mMapRenderbuffers.EnumerateRead(RenderbufferMemoryUsageFunction, &bufferMemoryUsageForThisContext);
+            result += bufferMemoryUsageForThisContext;
+        }
+        return result;
+    }
+    
+    static PRInt64 GetRenderbufferCount() {
+        const ContextsArrayType & contexts = Contexts();
+        PRInt64 result = 0;
+        for(size_t i = 0; i < contexts.Length(); ++i) {
+            result += contexts[i]->mMapRenderbuffers.Count();
+        }
+        return result;
+    }
+
+    static PLDHashOperator ShaderSourceSizeFunction(const PRUint32&, WebGLShader *aValue, void *aData)
+    {
+        PRInt64 *result = (PRInt64*) aData;
+        *result += aValue->Source().Length();
+        return PL_DHASH_NEXT;
+    }
+
+    static PLDHashOperator ShaderTranslationLogSizeFunction(const PRUint32&, WebGLShader *aValue, void *aData)
+    {
+        PRInt64 *result = (PRInt64*) aData;
+        *result += aValue->TranslationLog().Length();
+        return PL_DHASH_NEXT;
+    }
+
+    static PRInt64 GetShaderSourcesSize() {
+        const ContextsArrayType & contexts = Contexts();
+        PRInt64 result = 0;
+        for(size_t i = 0; i < contexts.Length(); ++i) {
+            PRInt64 shaderSourcesSizeForThisContext = 0;
+            contexts[i]->mMapShaders.EnumerateRead(ShaderSourceSizeFunction, &shaderSourcesSizeForThisContext);
+            result += shaderSourcesSizeForThisContext;
+        }
+        return result;
+    }
+    
+    static PRInt64 GetShaderTranslationLogsSize() {
+        const ContextsArrayType & contexts = Contexts();
+        PRInt64 result = 0;
+        for(size_t i = 0; i < contexts.Length(); ++i) {
+            PRInt64 shaderTranslationLogsSizeForThisContext = 0;
+            contexts[i]->mMapShaders.EnumerateRead(ShaderTranslationLogSizeFunction, &shaderTranslationLogsSizeForThisContext);
+            result += shaderTranslationLogsSizeForThisContext;
+        }
+        return result;
+    }
+    
+    static PRInt64 GetShaderCount() {
+        const ContextsArrayType & contexts = Contexts();
+        PRInt64 result = 0;
+        for(size_t i = 0; i < contexts.Length(); ++i) {
+            result += contexts[i]->mMapShaders.Count();
+        }
+        return result;
+    }
+
+    static PRInt64 GetContextCount() {
+        return Contexts().Length();
+    }
+};
+
 }
 
 #endif
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -36,16 +36,17 @@
  * 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 "WebGLContext.h"
 
 #include "nsString.h"
+#include "nsDebug.h"
 
 #include "gfxImageSurface.h"
 #include "gfxContext.h"
 #include "gfxPlatform.h"
 //#include "nsIDOMHTMLCanvasElement.h"
 
 #include "nsContentUtils.h"
 #include "nsDOMError.h"
@@ -362,16 +363,42 @@ WebGLContext::BlendFuncSeparate(WebGLenu
     if (!ValidateBlendFuncEnumsCompatibility(srcRGB, dstRGB, "blendFuncSeparate: srcRGB and dstRGB"))
         return NS_OK;
 
     MakeContextCurrent();
     gl->fBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
     return NS_OK;
 }
 
+GLenum WebGLContext::CheckedBufferData(GLenum target,
+                                       GLsizeiptr size,
+                                       const GLvoid *data,
+                                       GLenum usage)
+{
+    WebGLBuffer *boundBuffer = NULL;
+    if (target == LOCAL_GL_ARRAY_BUFFER) {
+        boundBuffer = mBoundArrayBuffer;
+    } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
+        boundBuffer = mBoundElementArrayBuffer;
+    }
+    NS_ABORT_IF_FALSE(boundBuffer != nsnull, "no buffer bound for this target");
+    
+    bool sizeChanges = PRUint32(size) != boundBuffer->ByteLength();
+    if (sizeChanges) {
+        UpdateWebGLErrorAndClearGLError();
+        gl->fBufferData(target, size, data, usage);
+        GLenum error = LOCAL_GL_NO_ERROR;
+        UpdateWebGLErrorAndClearGLError(&error);
+        return error;
+    } else {
+        gl->fBufferData(target, size, data, usage);
+        return LOCAL_GL_NO_ERROR;
+    }
+}
+
 NS_IMETHODIMP
 WebGLContext::BufferData(PRInt32 dummy)
 {
     // this should never be called
     LogMessageIfVerbose("BufferData");
     return NS_ERROR_FAILURE;
 }
 
@@ -401,23 +428,27 @@ WebGLContext::BufferData_size(WebGLenum 
 
     if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
         return NS_OK;
 
     if (!boundBuffer)
         return ErrorInvalidOperation("BufferData: no buffer bound!");
 
     MakeContextCurrent();
+    
+    GLenum error = CheckedBufferData(target, size, 0, usage);
+    if (error) {
+        LogMessageIfVerbose("bufferData generated error %s", ErrorName(error));
+        return NS_OK;
+    }
 
     boundBuffer->SetByteLength(size);
+    boundBuffer->InvalidateCachedMaxElements();
     if (!boundBuffer->ZeroDataIfElementArray())
         return ErrorOutOfMemory("bufferData: out of memory");
-    boundBuffer->InvalidateCachedMaxElements();
-
-    gl->fBufferData(target, size, 0, usage);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::BufferData_buf(WebGLenum target, JSObject *wb, WebGLenum usage)
 {
     WebGLBuffer *boundBuffer = NULL;
@@ -433,22 +464,29 @@ WebGLContext::BufferData_buf(WebGLenum t
     if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
         return NS_OK;
 
     if (!boundBuffer)
         return ErrorInvalidOperation("BufferData: no buffer bound!");
 
     MakeContextCurrent();
 
+    GLenum error = CheckedBufferData(target,
+                                     JS_GetArrayBufferByteLength(wb),
+                                     JS_GetArrayBufferData(wb),
+                                     usage);
+    if (error) {
+        LogMessageIfVerbose("bufferData generated error %s", ErrorName(error));
+        return NS_OK;
+    }
+
     boundBuffer->SetByteLength(JS_GetArrayBufferByteLength(wb));
+    boundBuffer->InvalidateCachedMaxElements();
     if (!boundBuffer->CopyDataIfElementArray(JS_GetArrayBufferData(wb)))
         return ErrorOutOfMemory("bufferData: out of memory");
-    boundBuffer->InvalidateCachedMaxElements();
-
-    gl->fBufferData(target, JS_GetArrayBufferByteLength(wb), JS_GetArrayBufferData(wb), usage);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::BufferData_array(WebGLenum target, js::TypedArray *wa, WebGLenum usage)
 {
     WebGLBuffer *boundBuffer = NULL;
@@ -464,22 +502,29 @@ WebGLContext::BufferData_array(WebGLenum
     if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
         return NS_OK;
 
     if (!boundBuffer)
         return ErrorInvalidOperation("BufferData: no buffer bound!");
 
     MakeContextCurrent();
 
+    GLenum error = CheckedBufferData(target,
+                                     wa->byteLength,
+                                     wa->data,
+                                     usage);
+    if (error) {
+        LogMessageIfVerbose("bufferData generated error %s", ErrorName(error));
+        return NS_OK;
+    }
+
     boundBuffer->SetByteLength(wa->byteLength);
+    boundBuffer->InvalidateCachedMaxElements();
     if (!boundBuffer->CopyDataIfElementArray(wa->data))
         return ErrorOutOfMemory("bufferData: out of memory");
-    boundBuffer->InvalidateCachedMaxElements();
-
-    gl->fBufferData(target, wa->byteLength, wa->data, usage);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::BufferSubData(PRInt32)
 {
     return NS_ERROR_FAILURE;
@@ -680,19 +725,19 @@ WebGLContext::CopyTexSubImage2D_base(Web
     WebGLsizei framebufferHeight = mBoundFramebuffer ? mBoundFramebuffer->height() : mHeight;
 
     const char *info = sub ? "copyTexSubImage2D" : "copyTexImage2D";
 
     MakeContextCurrent();
 
     if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, framebufferWidth, framebufferHeight)) {
         if (sub)
-          gl->fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+            gl->fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
         else
-          gl->fCopyTexImage2D(target, level, internalformat, x, y, width, height, 0);
+            gl->fCopyTexImage2D(target, level, internalformat, x, y, width, height, 0);
     } else {
 
         // the rect doesn't fit in the framebuffer
 
         /*** first, we initialize the texture as black ***/
 
         // first, compute the size of the buffer we should allocate to initialize the texture as black
 
@@ -723,20 +768,21 @@ WebGLContext::CopyTexSubImage2D_base(Web
         // Hopefully calloc will just mmap zero pages here.
         void *tempZeroData = calloc(1, bytesNeeded);
         if (!tempZeroData)
             return ErrorOutOfMemory("%s: could not allocate %d bytes (for zero fill)", info, bytesNeeded);
 
         // now initialize the texture as black
 
         if (sub)
-          gl->fTexSubImage2D(target, level, 0, 0, width, height, internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
+            gl->fTexSubImage2D(target, level, 0, 0, width, height,
+                               internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
         else
-          gl->fTexImage2D(target, level, internalformat, width, height, 0, internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
-
+            gl->fTexImage2D(target, level, internalformat, width, height,
+                            0, internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
         free(tempZeroData);
 
         // if we are completely outside of the framebuffer, we can exit now with our black texture
         if (   x >= framebufferWidth
             || x+width <= 0
             || y >= framebufferHeight
             || y+height <= 0)
         {
@@ -825,19 +871,41 @@ WebGLContext::CopyTexImage2D(WebGLenum t
 
     if (mBoundFramebuffer && !mBoundFramebuffer->CheckAndInitializeRenderbuffers())
         return NS_OK;
 
     WebGLTexture *tex = activeBoundTextureForTarget(target);
     if (!tex)
         return ErrorInvalidOperation("copyTexImage2D: no texture bound to this target");
 
-    tex->SetImageInfo(target, level, width, height);
-
-    return CopyTexSubImage2D_base(target, level, internalformat, 0, 0, x, y, width, height, false);
+    const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(level, WebGLTexture::FaceForTarget(target));
+
+    // copyTexImage2D only generates textures with type = UNSIGNED_BYTE
+    GLenum type = LOCAL_GL_UNSIGNED_BYTE;
+
+    bool sizeMayChange = width != imageInfo.mWidth ||
+                         height != imageInfo.mHeight ||
+                         internalformat != imageInfo.mFormat ||
+                         type != imageInfo.mType;
+
+    if (sizeMayChange) {
+        UpdateWebGLErrorAndClearGLError();
+        CopyTexSubImage2D_base(target, level, internalformat, 0, 0, x, y, width, height, false);
+        GLenum error = LOCAL_GL_NO_ERROR;
+        UpdateWebGLErrorAndClearGLError(&error);
+        if (error) {
+            LogMessageIfVerbose("copyTexImage2D generated error %s", ErrorName(error));
+            return NS_OK;
+        }          
+    } else {
+        CopyTexSubImage2D_base(target, level, internalformat, 0, 0, x, y, width, height, false);
+    }
+    
+    tex->SetImageInfo(target, level, width, height, internalformat, type);
+    return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::CopyTexSubImage2D(WebGLenum target,
                                 WebGLint level,
                                 WebGLint xoffset,
                                 WebGLint yoffset,
                                 WebGLint x,
@@ -2221,28 +2289,19 @@ WebGLContext::CreateTexture(nsIWebGLText
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::GetError(WebGLenum *_retval)
 {
     MakeContextCurrent();
 
-    // Always call glGetError to clear any pending
-    // real GL error.
-    WebGLenum err = gl->fGetError();
-
-    // mSynthesizedGLError has the first error that occurred,
-    // whether synthesized or real; if it's not NO_ERROR, use it.
-    if (mSynthesizedGLError != LOCAL_GL_NO_ERROR) {
-        err = mSynthesizedGLError;
-        mSynthesizedGLError = LOCAL_GL_NO_ERROR;
-    }
-
-    *_retval = err;
+    UpdateWebGLErrorAndClearGLError();
+    *_retval = mWebGLError;
+    mWebGLError = LOCAL_GL_NO_ERROR;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::GetProgramParameter(nsIWebGLProgram *pobj, PRUint32 pname, nsIVariant **retval)
 {
     *retval = nsnull;
@@ -3102,18 +3161,16 @@ WebGLContext::RenderbufferStorage(WebGLe
         return ErrorInvalidEnumInfo("renderbufferStorage: target", target);
 
     if (width <= 0 || height <= 0)
         return ErrorInvalidValue("renderbufferStorage: width and height must be > 0");
 
     if (!mBoundRenderbuffer || !mBoundRenderbuffer->GLName())
         return ErrorInvalidOperation("renderbufferStorage called on renderbuffer 0");
 
-    MakeContextCurrent();
-
     // certain OpenGL ES renderbuffer formats may not exist on desktop OpenGL
     WebGLenum internalformatForGL = internalformat;
 
     switch (internalformat) {
     case LOCAL_GL_RGBA4:
     case LOCAL_GL_RGB5_A1:
         // 16-bit RGBA formats are not supported on desktop GL
         if (!gl->IsGLES2()) internalformatForGL = LOCAL_GL_RGBA8;
@@ -3139,19 +3196,36 @@ WebGLContext::RenderbufferStorage(WebGLe
         // So we just use it hoping that it's available (perhaps as an extension) and if it's not available,
         // we just let the GL generate an error and don't do anything about it ourselves.
         internalformatForGL = LOCAL_GL_DEPTH24_STENCIL8;
         break;
     default:
         return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", internalformat);
     }
 
-    gl->fRenderbufferStorage(target, internalformatForGL, width, height);
+    MakeContextCurrent();
+
+    bool sizeChanges = width != mBoundRenderbuffer->width() ||
+                       height != mBoundRenderbuffer->height() ||
+                       internalformat != mBoundRenderbuffer->InternalFormat();
+    if (sizeChanges) {
+        UpdateWebGLErrorAndClearGLError();
+        gl->fRenderbufferStorage(target, internalformatForGL, width, height);
+        GLenum error = LOCAL_GL_NO_ERROR;
+        UpdateWebGLErrorAndClearGLError(&error);
+        if (error) {
+            LogMessageIfVerbose("bufferData generated error %s", ErrorName(error));
+            return NS_OK;
+        }
+    } else {
+        gl->fRenderbufferStorage(target, internalformatForGL, width, height);
+    }
 
     mBoundRenderbuffer->SetInternalFormat(internalformat);
+    mBoundRenderbuffer->SetInternalFormatForGL(internalformatForGL);
     mBoundRenderbuffer->setDimensions(width, height);
     mBoundRenderbuffer->SetInitialized(PR_FALSE);
 
     return NS_OK;
 }
 
 GL_SAME_METHOD_2(SampleCoverage, SampleCoverage, WebGLfloat, WebGLboolean)
 
@@ -4039,21 +4113,29 @@ WebGLContext::GetShaderSource(nsIWebGLSh
 
 NS_IMETHODIMP
 WebGLContext::ShaderSource(nsIWebGLShader *sobj, const nsAString& source)
 {
     WebGLShader *shader;
     WebGLuint shadername;
     if (!GetConcreteObjectAndGLName("shaderSource: shader", sobj, &shader, &shadername))
         return NS_OK;
-
-    if (!NS_IsAscii(nsPromiseFlatString(source).get()))
+    
+    const nsPromiseFlatString& flatSource = PromiseFlatString(source);
+
+    if (!NS_IsAscii(flatSource.get()))
         return ErrorInvalidValue("shaderSource: non-ascii characters found in source");
 
-    shader->SetSource(NS_LossyConvertUTF16toASCII(source));
+    const nsCString& sourceCString = NS_LossyConvertUTF16toASCII(flatSource);
+    
+    const PRUint32 maxSourceLength = (PRUint32(1)<<18) - 1;
+    if (sourceCString.Length() > maxSourceLength)
+        return ErrorInvalidValue("shaderSource: source has more than %d characters", maxSourceLength);
+    
+    shader->SetSource(sourceCString);
 
     shader->SetNeedsTranslation();
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::VertexAttribPointer(WebGLuint index, WebGLint size, WebGLenum type,
@@ -4131,16 +4213,45 @@ WebGLContext::VertexAttribPointer(WebGLu
 }
 
 NS_IMETHODIMP
 WebGLContext::TexImage2D(PRInt32)
 {
     return NS_ERROR_FAILURE;
 }
 
+GLenum WebGLContext::CheckedTexImage2D(GLenum target,
+                                       GLint level,
+                                       GLenum internalFormat,
+                                       GLsizei width,
+                                       GLsizei height,
+                                       GLint border,
+                                       GLenum format,
+                                       GLenum type,
+                                       const GLvoid *data)
+{
+    WebGLTexture *tex = activeBoundTextureForTarget(target);
+    NS_ABORT_IF_FALSE(tex != nsnull, "no texture bound");
+    const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(level, WebGLTexture::FaceForTarget(target));
+    bool sizeMayChange = width != imageInfo.mWidth ||
+                         height != imageInfo.mHeight ||
+                         format != imageInfo.mFormat ||
+                         type != imageInfo.mType;
+    if (sizeMayChange) {
+        UpdateWebGLErrorAndClearGLError();
+        gl->fTexImage2D(target, level, internalFormat, width, height, border, format, type, data);
+        GLenum error = LOCAL_GL_NO_ERROR;
+        UpdateWebGLErrorAndClearGLError(&error);
+        return error;
+    } else {
+        gl->fTexImage2D(target, level, internalFormat, width, height, border, format, type, data);
+        return LOCAL_GL_NO_ERROR;
+    }
+}
+
 nsresult
 WebGLContext::TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum internalformat,
                               WebGLsizei width, WebGLsizei height, WebGLsizei srcStrideOrZero,
                               WebGLint border,
                               WebGLenum format, WebGLenum type,
                               void *data, PRUint32 byteLength,
                               int jsArrayType, // a TypedArray format enum, or -1 if not relevant
                               int srcFormat, PRBool srcPremultiplied)
@@ -4222,64 +4333,72 @@ WebGLContext::TexImage2D_base(WebGLenum 
         return ErrorInvalidOperation("TexImage2D: not enough data for operation (need %d, have %d)",
                                  bytesNeeded, byteLength);
 
     WebGLTexture *tex = activeBoundTextureForTarget(target);
 
     if (!tex)
         return ErrorInvalidOperation("texImage2D: no texture is bound to this target");
 
-    tex->SetImageInfo(target, level, width, height, format, type);
-
     MakeContextCurrent();
 
     // Handle ES2 and GL differences in floating point internal formats.  Note that
     // format == internalformat, as checked above and as required by ES.
     internalformat = InternalFormatForFormatAndType(format, type, gl->IsGLES2());
 
+    GLenum error = LOCAL_GL_NO_ERROR;
+
     if (byteLength) {
         int dstFormat = GetWebGLTexelFormat(format, type);
         int actualSrcFormat = srcFormat == WebGLTexelFormat::Auto ? dstFormat : srcFormat;
         size_t srcStride = srcStrideOrZero ? srcStrideOrZero : checked_alignedRowSize.value();
 
         size_t dstPlainRowSize = texelSize * width;
         size_t unpackAlignment = mPixelStoreUnpackAlignment;
         size_t dstStride = ((dstPlainRowSize + unpackAlignment-1) / unpackAlignment) * unpackAlignment;
 
         if (actualSrcFormat == dstFormat &&
             srcPremultiplied == mPixelStorePremultiplyAlpha &&
             srcStride == dstStride &&
             !mPixelStoreFlipY)
         {
             // no conversion, no flipping, so we avoid copying anything and just pass the source pointer
-            gl->fTexImage2D(target, level, internalformat, width, height, border, format, type, data);
+            error = CheckedTexImage2D(target, level, internalformat,
+                                      width, height, border, format, type, data);
         }
         else
         {
             nsAutoArrayPtr<PRUint8> convertedData(new PRUint8[bytesNeeded]);
             ConvertImage(width, height, srcStride, dstStride,
-                         (PRUint8*)data, convertedData,
-                         actualSrcFormat, srcPremultiplied,
-                         dstFormat, mPixelStorePremultiplyAlpha, texelSize);
-            gl->fTexImage2D(target, level, internalformat, width, height, border, format, type, convertedData);
+                        (PRUint8*)data, convertedData,
+                        actualSrcFormat, srcPremultiplied,
+                        dstFormat, mPixelStorePremultiplyAlpha, texelSize);
+            error = CheckedTexImage2D(target, level, internalformat,
+                                      width, height, border, format, type, convertedData);
         }
     } else {
         // We need some zero pages, because GL doesn't guarantee the
         // contents of a texture allocated with NULL data.
         // Hopefully calloc will just mmap zero pages here.
         void *tempZeroData = calloc(1, bytesNeeded);
         if (!tempZeroData)
             return ErrorOutOfMemory("texImage2D: could not allocate %d bytes (for zero fill)", bytesNeeded);
 
-        gl->fTexImage2D(target, level, internalformat, width, height, border, format, type, tempZeroData);
+        error = CheckedTexImage2D(target, level, internalformat,
+                                  width, height, border, format, type, tempZeroData);
 
         free(tempZeroData);
     }
-
-    tex->setDimensions(width, height);
+    
+    if (error) {
+        LogMessageIfVerbose("texImage2D generated error %s", ErrorName(error));
+        return NS_OK;
+    }
+
+    tex->SetImageInfo(target, level, width, height, format, type);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::TexImage2D_buf(WebGLenum target, WebGLint level, WebGLenum internalformat,
                              WebGLsizei width, WebGLsizei height, WebGLint border,
                              WebGLenum format, WebGLenum type,
@@ -4413,20 +4532,21 @@ WebGLContext::TexSubImage2D_base(WebGLen
     if (byteLength < bytesNeeded)
         return ErrorInvalidOperation("texSubImage2D: not enough data for operation (need %d, have %d)", bytesNeeded, byteLength);
 
     WebGLTexture *tex = activeBoundTextureForTarget(target);
 
     if (!tex)
         return ErrorInvalidOperation("texSubImage2D: no texture is bound to this target");
 
-    if (!CanvasUtils::CheckSaneSubrectSize(xoffset, yoffset, width, height, tex->width(), tex->height()))
+    size_t face = WebGLTexture::FaceForTarget(target);
+    const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(level, face);
+    if (!CanvasUtils::CheckSaneSubrectSize(xoffset, yoffset, width, height, imageInfo.mWidth, imageInfo.mHeight))
         return ErrorInvalidValue("texSubImage2D: subtexture rectangle out of bounds");
 
-
     MakeContextCurrent();
 
     int dstFormat = GetWebGLTexelFormat(format, type);
     int actualSrcFormat = srcFormat == WebGLTexelFormat::Auto ? dstFormat : srcFormat;
     size_t srcStride = srcStrideOrZero ? srcStrideOrZero : checked_alignedRowSize.value();
 
     size_t dstPlainRowSize = texelSize * width;
     size_t dstStride = ((dstPlainRowSize + unpackAlignment-1) / unpackAlignment) * unpackAlignment;
--- a/content/canvas/src/WebGLContextUtils.cpp
+++ b/content/canvas/src/WebGLContextUtils.cpp
@@ -41,29 +41,27 @@
 
 #include "WebGLContext.h"
 
 #include "prprf.h"
 
 #include "nsIJSContextStack.h"
 #include "jsapi.h"
 #include "nsIScriptSecurityManager.h"
-#include "nsIPrefBranch.h"
 #include "nsServiceManagerUtils.h"
-#include "nsIPrefBranch.h"
-#include "nsIPrefService.h"
 #include "nsIVariant.h"
 
 #include "nsIDOMDocument.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIPrivateDOMEvent.h"
 #include "nsIDOMDataContainerEvent.h"
 
 #include "nsContentUtils.h"
+#include "mozilla/Preferences.h"
 
 #if 0
 #include "nsIContentURIGrouper.h"
 #include "nsIContentPrefService.h"
 #endif
 
 using namespace mozilla;
 
@@ -121,25 +119,23 @@ WebGLContext::LogMessageIfVerbose(const 
 
 nsresult
 WebGLContext::SynthesizeGLError(WebGLenum err)
 {
     // If there is already a pending error, don't overwrite it;
     // but if there isn't, then we need to check for a gl error
     // that may have occurred before this one and use that code
     // instead.
-
-    if (mSynthesizedGLError == LOCAL_GL_NO_ERROR) {
-        MakeContextCurrent();
+    
+    MakeContextCurrent();
 
-        mSynthesizedGLError = gl->fGetError();
+    UpdateWebGLErrorAndClearGLError();
 
-        if (mSynthesizedGLError == LOCAL_GL_NO_ERROR)
-            mSynthesizedGLError = err;
-    }
+    if (!mWebGLError)
+        mWebGLError = err;
 
     return NS_OK;
 }
 
 nsresult
 WebGLContext::SynthesizeGLError(WebGLenum err, const char *fmt, ...)
 {
     va_list va;
@@ -189,8 +185,29 @@ WebGLContext::ErrorOutOfMemory(const cha
     va_list va;
     va_start(va, fmt);
     LogMessageIfVerbose(fmt, va);
     va_end(va);
 
     return SynthesizeGLError(LOCAL_GL_OUT_OF_MEMORY);
 }
 
+const char *
+WebGLContext::ErrorName(GLenum error)
+{
+    switch(error) {
+        case LOCAL_GL_INVALID_ENUM:
+            return "INVALID_ENUM";
+        case LOCAL_GL_INVALID_OPERATION:
+            return "INVALID_OPERATION";
+        case LOCAL_GL_INVALID_VALUE:
+            return "INVALID_VALUE";
+        case LOCAL_GL_OUT_OF_MEMORY:
+            return "OUT_OF_MEMORY";
+        case LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION:
+            return "INVALID_FRAMEBUFFER_OPERATION";
+        case LOCAL_GL_NO_ERROR:
+            return "NO_ERROR";
+        default:
+            NS_ABORT();
+            return "[unknown WebGL error!]";
+    }
+};
--- a/content/canvas/src/WebGLContextValidate.cpp
+++ b/content/canvas/src/WebGLContextValidate.cpp
@@ -34,18 +34,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 ***** */
 
 #include "WebGLContext.h"
 
-#include "nsIPrefService.h"
-#include "nsServiceManagerUtils.h"
+#include "mozilla/Preferences.h"
 
 #include "CheckedInt.h"
 
 #include "jstypedarray.h"
 
 #if defined(USE_ANGLE)
 #include "angle/ShaderLang.h"
 #endif
@@ -324,16 +323,44 @@ PRBool WebGLContext::ValidateDrawModeEnu
         case LOCAL_GL_LINES:
             return PR_TRUE;
         default:
             ErrorInvalidEnumInfo(info, mode);
             return PR_FALSE;
     }
 }
 
+PRUint32 WebGLContext::GetTexelSize(WebGLenum format, WebGLenum type)
+{
+    if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT) {
+        int multiplier = type == LOCAL_GL_FLOAT ? 4 : 1;
+        switch (format) {
+            case LOCAL_GL_ALPHA:
+            case LOCAL_GL_LUMINANCE:
+                return 1 * multiplier;
+            case LOCAL_GL_LUMINANCE_ALPHA:
+                return 2 * multiplier;
+            case LOCAL_GL_RGB:
+                return 3 * multiplier;
+            case LOCAL_GL_RGBA:
+                return 4 * multiplier;
+            default:
+                break;
+        }
+    } else if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
+               type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
+               type == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
+    {
+        return 2;
+    }
+
+    NS_ABORT();
+    return 0;
+}
+
 PRBool WebGLContext::ValidateTexFormatAndType(WebGLenum format, WebGLenum type, int jsArrayType,
                                               PRUint32 *texelSize, const char *info)
 {
     if (type == LOCAL_GL_UNSIGNED_BYTE ||
         (IsExtensionEnabled(WebGL_OES_texture_float) && type == LOCAL_GL_FLOAT))
     {
         if (jsArrayType != -1) {
             if ((type == LOCAL_GL_UNSIGNED_BYTE && jsArrayType != js::TypedArray::TYPE_UINT8) ||
@@ -444,17 +471,17 @@ WebGLContext::InitAndValidateGL()
 
     GLenum error = gl->fGetError();
     if (error != LOCAL_GL_NO_ERROR) {
         LogMessage("GL error 0x%x occurred during OpenGL context initialization, before WebGL initialization!", error);
         return PR_FALSE;
     }
 
     mActiveTexture = 0;
-    mSynthesizedGLError = LOCAL_GL_NO_ERROR;
+    mWebGLError = LOCAL_GL_NO_ERROR;
 
     mAttribBuffers.Clear();
 
     mUniformTextures.Clear();
     mBound2DTextures.Clear();
     mBoundCubeMapTextures.Clear();
 
     mBoundArrayBuffer = nsnull;
@@ -514,17 +541,17 @@ WebGLContext::InitAndValidateGL()
         gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS, &mGLMaxVertexUniformVectors);
         mGLMaxVertexUniformVectors /= 4;
 
         // we are now going to try to read GL_MAX_VERTEX_OUTPUT_COMPONENTS and GL_MAX_FRAGMENT_INPUT_COMPONENTS,
         // however these constants only entered the OpenGL standard at OpenGL 3.2. So we will try reading,
         // and check OpenGL error for INVALID_ENUM.
 
         // before we start, we check that no error already occurred, to prevent hiding it in our subsequent error handling
-        error = gl->fGetError();
+        error = gl->GetAndClearError();
         if (error != LOCAL_GL_NO_ERROR) {
             LogMessage("GL error 0x%x occurred during WebGL context initialization!", error);
             return PR_FALSE;
         }
 
         // On the public_webgl list, "problematic GetParameter pnames" thread, the following formula was given:
         //   mGLMaxVaryingVectors = min (GL_MAX_VERTEX_OUTPUT_COMPONENTS, GL_MAX_FRAGMENT_INPUT_COMPONENTS) / 4
         GLint maxVertexOutputComponents,
@@ -567,33 +594,33 @@ WebGLContext::InitAndValidateGL()
             // gl_PointCoord is always available in ES2 GLSL and in newer desktop GLSL versions, but apparently
             // not in OpenGL 2 and apparently not (due to a driver bug) on certain NVIDIA setups. See:
             //   http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=261472
             gl->fEnable(LOCAL_GL_POINT_SPRITE);
         }
     }
 
     // Check the shader validator pref
-    nsCOMPtr<nsIPrefBranch> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
-    NS_ENSURE_TRUE(prefService != nsnull, NS_ERROR_FAILURE);
+    NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_FAILURE);
 
-    prefService->GetBoolPref("webgl.shader_validator", &mShaderValidation);
+    mShaderValidation =
+        Preferences::GetBool("webgl.shader_validator", mShaderValidation);
 
 #if defined(USE_ANGLE)
     // initialize shader translator
     if (mShaderValidation) {
         if (!ShInitialize()) {
             LogMessage("GLSL translator initialization failed!");
             return PR_FALSE;
         }
     }
 #endif
 
-    // notice that the point of calling GetError here is not only to check for error,
-    // it is also to reset the error flag so that a subsequent WebGL getError call will give the correct result.
-    error = gl->fGetError();
+    // notice that the point of calling GetAndClearError here is not only to check for error,
+    // it is also to reset the error flags so that a subsequent WebGL getError call will give the correct result.
+    error = gl->GetAndClearError();
     if (error != LOCAL_GL_NO_ERROR) {
         LogMessage("GL error 0x%x occurred during WebGL context initialization!", error);
         return PR_FALSE;
     }
 
     return PR_TRUE;
 }
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -344,20 +344,21 @@ public:
                               const PRUnichar* aEncoderOptions,
                               nsIInputStream **aStream);
     NS_IMETHOD GetThebesSurface(gfxASurface **surface);
     mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot()
         { return nsnull; }
 
     NS_IMETHOD SetIsOpaque(PRBool isOpaque);
     NS_IMETHOD Reset();
-    already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
-                                                 CanvasLayer *aOldLayer,
-                                                 LayerManager *aManager);
-    void MarkContextClean();
+    virtual already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
+                                                         CanvasLayer *aOldLayer,
+                                                         LayerManager *aManager);
+    virtual PRBool ShouldForceInactiveLayer(LayerManager *aManager);
+    virtual void MarkContextClean();
     NS_IMETHOD SetIsIPC(PRBool isIPC);
     // this rect is in canvas device space
     NS_IMETHOD Redraw(const gfxRect &r);
     // this rect is in mThebes's current user space
     NS_IMETHOD RedrawUser(const gfxRect &r);
 
     // nsISupports interface + CC
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -1066,19 +1067,17 @@ nsCanvasRenderingContext2D::SetDimension
         if (height == 0 || width == 0) {
             mZero = PR_TRUE;
             height = 1;
             width = 1;
         }
 
         gfxASurface::gfxImageFormat format = GetImageFormat();
 
-        if (PR_GetEnv("MOZ_CANVAS_IMAGE_SURFACE")) {
-            surface = new gfxImageSurface(gfxIntSize(width, height), format);
-        } else {
+        if (!PR_GetEnv("MOZ_CANVAS_IMAGE_SURFACE")) {
             nsCOMPtr<nsIContent> content =
                 do_QueryInterface(static_cast<nsIDOMHTMLCanvasElement*>(mCanvasElement));
             nsIDocument* ownerDoc = nsnull;
             if (content)
                 ownerDoc = content->GetOwnerDoc();
             nsRefPtr<LayerManager> layerManager = nsnull;
 
             if (ownerDoc)
@@ -1088,18 +1087,25 @@ nsCanvasRenderingContext2D::SetDimension
             if (layerManager) {
               surface = layerManager->CreateOptimalSurface(gfxIntSize(width, height), format);
             } else {
               surface = gfxPlatform::GetPlatform()->
                 CreateOffscreenSurface(gfxIntSize(width, height), gfxASurface::ContentFromFormat(format));
             }
         }
 
-        if (surface && surface->CairoStatus() != 0)
-            surface = NULL;
+        if (!surface || surface->CairoStatus()) {
+            // If we couldn't create a surface of the type we want, fall back
+            // to an image surface. This lets us handle surface sizes that
+            // the underlying cairo backend might not handle.
+            surface = new gfxImageSurface(gfxIntSize(width, height), format);
+            if (!surface || surface->CairoStatus()) {
+                surface = nsnull;
+            }
+        }
     }
     if (surface) {
         if (gCanvasMemoryReporter == nsnull) {
             gCanvasMemoryReporter = new NS_MEMORY_REPORTER_NAME(CanvasMemory);
             NS_RegisterMemoryReporter(gCanvasMemoryReporter);
         }
 
         gCanvasMemoryUsed += width * height * 4;
@@ -4012,16 +4018,22 @@ nsCanvasRenderingContext2D::GetCanvasLay
     canvasLayer->SetContentFlags(flags);
     canvasLayer->Updated();
 
     mResetLayer = PR_FALSE;
 
     return canvasLayer.forget();
 }
 
+PRBool
+nsCanvasRenderingContext2D::ShouldForceInactiveLayer(LayerManager *aManager)
+{
+    return !aManager->CanUseCanvasLayerForSize(gfxIntSize(mWidth, mHeight));
+}
+
 void
 nsCanvasRenderingContext2D::MarkContextClean()
 {
     if (mInvalidateCount > 0) {
         mPredictManyRedrawCalls = mInvalidateCount > kCanvasMaxInvalidateCount;
     }
     mIsEntireFrameInvalid = PR_FALSE;
     mInvalidateCount = 0;
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
@@ -189,89 +189,16 @@ public:
 
     mStops = aRT->CreateGradientStops(mRawStops.Elements(), mRawStops.Length());
 
     return mStops;
   }
 
   NS_DECL_ISUPPORTS
 
-protected:
-  nsCanvasGradientAzure(Type aType) : mType(aType)
-  {}
-
-  nsTArray<GradientStop> mRawStops;
-  RefPtr<GradientStops> mStops;
-  Type mType;
-};
-
-class nsCanvasRadialGradientAzure : public nsCanvasGradientAzure
-{
-public:
-  nsCanvasRadialGradientAzure(const Point &aBeginOrigin, Float aBeginRadius,
-                              const Point &aEndOrigin, Float aEndRadius)
-    : nsCanvasGradientAzure(RADIAL)
-    , mCenter(aEndOrigin)
-    , mRadius(aEndRadius)
-  {
-    mOffsetStart = aBeginRadius / mRadius;
-
-    mOffsetRatio = 1 - mOffsetStart;
-    mOrigin = ((mCenter * aBeginRadius) - (aBeginOrigin * mRadius)) /
-              (aBeginRadius - mRadius);
-  }
-
-
-  /* nsIDOMCanvasGradient */
-  NS_IMETHOD AddColorStop (float offset,
-                            const nsAString& colorstr)
-  {
-    if (!FloatValidate(offset) || offset < 0.0 || offset > 1.0) {
-      return NS_ERROR_DOM_INDEX_SIZE_ERR;
-    }
-
-    nscolor color;
-    nsCSSParser parser;
-    nsresult rv = parser.ParseColorString(nsString(colorstr),
-                                          nsnull, 0, &color);
-    if (NS_FAILED(rv)) {
-      return NS_ERROR_DOM_SYNTAX_ERR;
-    }
-
-    mStops = nsnull;
-
-    GradientStop newStop;
-
-    newStop.offset = offset * mOffsetRatio + mOffsetStart;
-    newStop.color = Color::FromABGR(color);
-
-    mRawStops.AppendElement(newStop);
-
-    return NS_OK;
-  }
-
-  // XXX - Temporary gradient code, this will be fixed soon as per bug 666097
-  Point mCenter;
-  Float mRadius;
-  Point mOrigin;
-
-  Float mOffsetStart;
-  Float mOffsetRatio;
-};
-
-class nsCanvasLinearGradientAzure : public nsCanvasGradientAzure
-{
-public:
-  nsCanvasLinearGradientAzure(const Point &aBegin, const Point &aEnd)
-    : nsCanvasGradientAzure(LINEAR)
-    , mBegin(aBegin)
-    , mEnd(aEnd)
-  {
-  }
-
   /* nsIDOMCanvasGradient */
   NS_IMETHOD AddColorStop (float offset,
                             const nsAString& colorstr)
   {
     if (!FloatValidate(offset) || offset < 0.0 || offset > 1.0) {
       return NS_ERROR_DOM_INDEX_SIZE_ERR;
     }
 
@@ -291,16 +218,54 @@ public:
     newStop.color = Color::FromABGR(color);
 
     mRawStops.AppendElement(newStop);
 
     return NS_OK;
   }
 
 protected:
+  nsCanvasGradientAzure(Type aType) : mType(aType)
+  {}
+
+  nsTArray<GradientStop> mRawStops;
+  RefPtr<GradientStops> mStops;
+  Type mType;
+};
+
+class nsCanvasRadialGradientAzure : public nsCanvasGradientAzure
+{
+public:
+  nsCanvasRadialGradientAzure(const Point &aBeginOrigin, Float aBeginRadius,
+                              const Point &aEndOrigin, Float aEndRadius)
+    : nsCanvasGradientAzure(RADIAL)
+    , mCenter1(aBeginOrigin)
+    , mCenter2(aEndOrigin)
+    , mRadius1(aBeginRadius)
+    , mRadius2(aEndRadius)
+  {
+  }
+
+  Point mCenter1;
+  Point mCenter2;
+  Float mRadius1;
+  Float mRadius2;
+};
+
+class nsCanvasLinearGradientAzure : public nsCanvasGradientAzure
+{
+public:
+  nsCanvasLinearGradientAzure(const Point &aBegin, const Point &aEnd)
+    : nsCanvasGradientAzure(LINEAR)
+    , mBegin(aBegin)
+    , mEnd(aEnd)
+  {
+  }
+
+protected:
   friend class nsCanvasRenderingContext2DAzure;
 
   // Beginning of linear gradient.
   Point mBegin;
   // End of linear gradient.
   Point mEnd;
 };
 
@@ -822,18 +787,18 @@ protected:
           LinearGradientPattern(gradient->mBegin, gradient->mEnd,
                                 gradient->GetGradientStopsForTarget(aRT));
       } else if (state.gradientStyles[aStyle] &&
                  state.gradientStyles[aStyle]->GetType() == nsCanvasGradientAzure::RADIAL) {
         nsCanvasRadialGradientAzure *gradient =
           static_cast<nsCanvasRadialGradientAzure*>(state.gradientStyles[aStyle].get());
 
         mPattern = new (mRadialGradientPattern.addr())
-          RadialGradientPattern(gradient->mCenter, gradient->mOrigin, gradient->mRadius,
-                                gradient->GetGradientStopsForTarget(aRT));
+          RadialGradientPattern(gradient->mCenter1, gradient->mCenter2, gradient->mRadius1,
+                                gradient->mRadius2, gradient->GetGradientStopsForTarget(aRT));
       } else if (state.patternStyles[aStyle]) {
         if (aCtx->mCanvasElement) {
           CanvasUtils::DoDrawImageSecurityCheck(aCtx->HTMLCanvasElement(),
                                                 state.patternStyles[aStyle]->mPrincipal,
                                                 state.patternStyles[aStyle]->mForceWriteOnly);
         }
 
         ExtendMode mode;
--- a/content/canvas/test/test_2d.gradient.radial.cone.top.html
+++ b/content/canvas/test/test_2d.gradient.radial.cone.top.html
@@ -1,27 +1,16 @@
 <!DOCTYPE HTML>
 <title>Canvas test: 2d.gradient.radial.cone.top</title>
 <script src="/MochiKit/packed.js"></script>
 <script src="/tests/SimpleTest/SimpleTest.js"></script>
 <link rel="stylesheet" href="/tests/SimpleTest/test.css">
 <body>
 <canvas id="c" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
 <script>
-
-function IsAzureEnabled() {
-  var enabled = false;
-
-  try {
-    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-    enabled = Components.classes["@mozilla.org/gfx/info;1"].getService(Components.interfaces.nsIGfxInfo).AzureEnabled;
-  } catch (e) { }
-
-  return enabled;
-}
 
 function isPixel(ctx, x,y, r,g,b,a, pos, colour, d) {
     var pixel = ctx.getImageData(x, y, 1, 1);
     var pr = pixel.data[0],
         pg = pixel.data[1],
         pb = pixel.data[2],
         pa = pixel.data[3];
     ok(r-d <= pr && pr <= r+d &&
@@ -54,36 +43,23 @@ ctx.fillStyle = '#f00';
 ctx.fillRect(0, 0, 100, 50);
 
 var g = ctx.createRadialGradient(230, 25, 100, 100, 25, 101);
 g.addColorStop(0, '#f00');
 g.addColorStop(1, '#0f0');
 ctx.fillStyle = g;
 ctx.fillRect(0, 0, 100, 50);
 
-if (IsAzureEnabled()) {
-  // XXX - See Bug 666097.
-  todo_isPixel(ctx, 1,1, 0,255,0,255, "1,1", "0,255,0,255", 0);
-  todo_isPixel(ctx, 50,1, 0,255,0,255, "50,1", "0,255,0,255", 0);
-  todo_isPixel(ctx, 98,1, 0,255,0,255, "98,1", "0,255,0,255", 0);
-  todo_isPixel(ctx, 1,25, 0,255,0,255, "1,25", "0,255,0,255", 0);
-  todo_isPixel(ctx, 50,25, 0,255,0,255, "50,25", "0,255,0,255", 0);
-  todo_isPixel(ctx, 98,25, 0,255,0,255, "98,25", "0,255,0,255", 0);
-  todo_isPixel(ctx, 1,48, 0,255,0,255, "1,48", "0,255,0,255", 0);
-  todo_isPixel(ctx, 50,48, 0,255,0,255, "50,48", "0,255,0,255", 0);
-  todo_isPixel(ctx, 98,48, 0,255,0,255, "98,48", "0,255,0,255", 0);
-} else {
-  isPixel(ctx, 1,1, 0,255,0,255, "1,1", "0,255,0,255", 0);
-  isPixel(ctx, 50,1, 0,255,0,255, "50,1", "0,255,0,255", 0);
-  isPixel(ctx, 98,1, 0,255,0,255, "98,1", "0,255,0,255", 0);
-  isPixel(ctx, 1,25, 0,255,0,255, "1,25", "0,255,0,255", 0);
-  isPixel(ctx, 50,25, 0,255,0,255, "50,25", "0,255,0,255", 0);
-  isPixel(ctx, 98,25, 0,255,0,255, "98,25", "0,255,0,255", 0);
-  isPixel(ctx, 1,48, 0,255,0,255, "1,48", "0,255,0,255", 0);
-  isPixel(ctx, 50,48, 0,255,0,255, "50,48", "0,255,0,255", 0);
-  isPixel(ctx, 98,48, 0,255,0,255, "98,48", "0,255,0,255", 0);
-}
+isPixel(ctx, 1,1, 0,255,0,255, "1,1", "0,255,0,255", 0);
+isPixel(ctx, 50,1, 0,255,0,255, "50,1", "0,255,0,255", 0);
+isPixel(ctx, 98,1, 0,255,0,255, "98,1", "0,255,0,255", 0);
+isPixel(ctx, 1,25, 0,255,0,255, "1,25", "0,255,0,255", 0);
+isPixel(ctx, 50,25, 0,255,0,255, "50,25", "0,255,0,255", 0);
+isPixel(ctx, 98,25, 0,255,0,255, "98,25", "0,255,0,255", 0);
+isPixel(ctx, 1,48, 0,255,0,255, "1,48", "0,255,0,255", 0);
+isPixel(ctx, 50,48, 0,255,0,255, "50,48", "0,255,0,255", 0);
+isPixel(ctx, 98,48, 0,255,0,255, "98,48", "0,255,0,255", 0);
 
 SimpleTest.finish();
 
 });
 </script>
 
--- a/content/canvas/test/test_canvas.html
+++ b/content/canvas/test/test_canvas.html
@@ -6394,38 +6394,25 @@ ctx.fillStyle = '#f00';
 ctx.fillRect(0, 0, 100, 50);
 
 var g = ctx.createRadialGradient(210, 25, 100, 230, 25, 100);
 g.addColorStop(0, '#0f0');
 g.addColorStop(1, '#f00');
 ctx.fillStyle = g;
 ctx.fillRect(0, 0, 100, 50);
 
-if (IsAzureEnabled()) {
-  // XXX - See Bug 666097.
-  todo_isPixel(ctx, 1, 1, 0, 255, 0, 255, 0);
-  todo_isPixel(ctx, 50, 1, 0, 255, 0, 255, 0);
-  todo_isPixel(ctx, 98, 1, 0, 255, 0, 255, 0);
-  todo_isPixel(ctx, 1, 25, 0, 255, 0, 255, 0);
-  todo_isPixel(ctx, 50, 25, 0, 255, 0, 255, 0);
-  todo_isPixel(ctx, 98, 25, 0, 255, 0, 255, 0);
-  todo_isPixel(ctx, 1, 48, 0, 255, 0, 255, 0);
-  todo_isPixel(ctx, 50, 48, 0, 255, 0, 255, 0);
-  todo_isPixel(ctx, 98, 48, 0, 255, 0, 255, 0);
-} else {
-  isPixel(ctx, 1, 1, 0, 255, 0, 255, 0);
-  isPixel(ctx, 50, 1, 0, 255, 0, 255, 0);
-  isPixel(ctx, 98, 1, 0, 255, 0, 255, 0);
-  isPixel(ctx, 1, 25, 0, 255, 0, 255, 0);
-  isPixel(ctx, 50, 25, 0, 255, 0, 255, 0);
-  isPixel(ctx, 98, 25, 0, 255, 0, 255, 0);
-  isPixel(ctx, 1, 48, 0, 255, 0, 255, 0);
-  isPixel(ctx, 50, 48, 0, 255, 0, 255, 0);
-  isPixel(ctx, 98, 48, 0, 255, 0, 255, 0);
-}
+isPixel(ctx, 1, 1, 0, 255, 0, 255, 0);
+isPixel(ctx, 50, 1, 0, 255, 0, 255, 0);
+isPixel(ctx, 98, 1, 0, 255, 0, 255, 0);
+isPixel(ctx, 1, 25, 0, 255, 0, 255, 0);
+isPixel(ctx, 50, 25, 0, 255, 0, 255, 0);
+isPixel(ctx, 98, 25, 0, 255, 0, 255, 0);
+isPixel(ctx, 1, 48, 0, 255, 0, 255, 0);
+isPixel(ctx, 50, 48, 0, 255, 0, 255, 0);
+isPixel(ctx, 98, 48, 0, 255, 0, 255, 0);
 
 }
 </script>
 
 <!-- [[[ test_2d.gradient.radial.cone.front.html ]]] -->
 
 <p>Canvas test: 2d.gradient.radial.cone.front</p>
 <canvas id="c235" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
@@ -6565,39 +6552,25 @@ ctx.fillStyle = '#f00';
 ctx.fillRect(0, 0, 100, 50);
 
 var g = ctx.createRadialGradient(230, 25, 100, 100, 25, 101);
 g.addColorStop(0, '#f00');
 g.addColorStop(1, '#0f0');
 ctx.fillStyle = g;
 ctx.fillRect(0, 0, 100, 50);
 
-
-if (IsAzureEnabled()) {
-  // XXX - See Bug 666097.
-  todo_isPixel(ctx, 1, 1, 0, 255, 0, 255, 0);
-  todo_isPixel(ctx, 50, 1, 0, 255, 0, 255, 0);
-  todo_isPixel(ctx, 98, 1, 0, 255, 0, 255, 0);
-  todo_isPixel(ctx, 1, 25, 0, 255, 0, 255, 0);
-  todo_isPixel(ctx, 50, 25, 0, 255, 0, 255, 0);
-  todo_isPixel(ctx, 98, 25, 0, 255, 0, 255, 0);
-  todo_isPixel(ctx, 1, 48, 0, 255, 0, 255, 0);
-  todo_isPixel(ctx, 50, 48, 0, 255, 0, 255, 0);
-  todo_isPixel(ctx, 98, 48, 0, 255, 0, 255, 0);
-} else {
-  isPixel(ctx, 1, 1, 0, 255, 0, 255, 0);
-  isPixel(ctx, 50, 1, 0, 255, 0, 255, 0);
-  isPixel(ctx, 98, 1, 0, 255, 0, 255, 0);
-  isPixel(ctx, 1, 25, 0, 255, 0, 255, 0);
-  isPixel(ctx, 50, 25, 0, 255, 0, 255, 0);
-  isPixel(ctx, 98, 25, 0, 255, 0, 255, 0);
-  isPixel(ctx, 1, 48, 0, 255, 0, 255, 0);
-  isPixel(ctx, 50, 48, 0, 255, 0, 255, 0);
-  isPixel(ctx, 98, 48, 0, 255, 0, 255, 0);
-}
+isPixel(ctx, 1, 1, 0, 255, 0, 255, 0);
+isPixel(ctx, 50, 1, 0, 255, 0, 255, 0);
+isPixel(ctx, 98, 1, 0, 255, 0, 255, 0);
+isPixel(ctx, 1, 25, 0, 255, 0, 255, 0);
+isPixel(ctx, 50, 25, 0, 255, 0, 255, 0);
+isPixel(ctx, 98, 25, 0, 255, 0, 255, 0);
+isPixel(ctx, 1, 48, 0, 255, 0, 255, 0);
+isPixel(ctx, 50, 48, 0, 255, 0, 255, 0);
+isPixel(ctx, 98, 48, 0, 255, 0, 255, 0);
 
 }
 </script>
 
 <!-- [[[ test_2d.gradient.radial.equal.html ]]] -->
 
 <p>Canvas test: 2d.gradient.radial.equal</p>
 <canvas id="c239" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
--- a/content/canvas/test/webgl/failing_tests_linux.txt
+++ b/content/canvas/test/webgl/failing_tests_linux.txt
@@ -1,17 +1,16 @@
 conformance/gl-getshadersource.html
 conformance/gl-get-active-attribute.html
 conformance/gl-uniform-bool.html
 conformance/glsl-2types-of-textures-on-same-unit.html
 conformance/glsl-conformance.html
 conformance/invalid-passed-params.html
 conformance/more/conformance/quickCheckAPI.html
 conformance/more/functions/copyTexImage2D.html
-conformance/more/functions/copyTexSubImage2DBadArgs.html
 conformance/more/functions/copyTexSubImage2D.html
 conformance/more/functions/deleteBufferBadArgs.html
 conformance/more/functions/texImage2DBadArgs.html
 conformance/more/functions/texSubImage2DBadArgs.html
 conformance/more/functions/texSubImage2DHTMLBadArgs.html
 conformance/more/functions/uniformfArrayLen1.html
 conformance/object-deletion-behaviour.html
 conformance/read-pixels-test.html
--- a/content/canvas/test/webgl/failing_tests_mac.txt
+++ b/content/canvas/test/webgl/failing_tests_mac.txt
@@ -2,18 +2,16 @@ conformance/gl-getshadersource.html
 conformance/gl-object-get-calls.html
 conformance/texture-npot.html
 conformance/glsl-conformance.html
 conformance/invalid-passed-params.html
 conformance/object-deletion-behaviour.html
 conformance/read-pixels-test.html
 conformance/tex-input-validation.html
 conformance/tex-sub-image-2d-bad-args.html
-conformance/uninitialized-test.html
 conformance/more/functions/copyTexImage2D.html
 conformance/more/functions/copyTexSubImage2D.html
-conformance/more/functions/copyTexSubImage2DBadArgs.html
 conformance/more/functions/deleteBufferBadArgs.html
 conformance/more/functions/texImage2DBadArgs.html
 conformance/more/functions/texSubImage2DBadArgs.html
 conformance/more/functions/texSubImage2DHTMLBadArgs.html
 conformance/more/functions/uniformfBadArgs.html
 conformance/more/functions/uniformiBadArgs.html
\ No newline at end of file
--- a/content/canvas/test/webgl/failing_tests_windows.txt
+++ b/content/canvas/test/webgl/failing_tests_windows.txt
@@ -1,16 +1,14 @@
 conformance/gl-getshadersource.html
 conformance/glsl-conformance.html
 conformance/invalid-passed-params.html
 conformance/object-deletion-behaviour.html
 conformance/read-pixels-test.html
 conformance/tex-sub-image-2d-bad-args.html
-conformance/uninitialized-test.html
 conformance/more/conformance/quickCheckAPI.html
 conformance/more/functions/copyTexImage2D.html
 conformance/more/functions/copyTexSubImage2D.html
-conformance/more/functions/copyTexSubImage2DBadArgs.html
 conformance/more/functions/deleteBufferBadArgs.html
 conformance/more/functions/texImage2DBadArgs.html
 conformance/more/functions/texSubImage2DBadArgs.html
 conformance/more/functions/texSubImage2DHTMLBadArgs.html
 conformance/more/functions/uniformfArrayLen1.html
--- a/content/canvas/test/webgl/test_webgl_conformance_test_suite.html
+++ b/content/canvas/test/webgl/test_webgl_conformance_test_suite.html
@@ -363,16 +363,17 @@ function start() {
                             .replace(/\r/g, '') // convert to unix line breaks
                             .split('\n');
 
   if (kIsWindows && !kIsWindowsVistaOrHigher) {
     testsExpectedToFail.push('conformance/framebuffer-object-attachment.html'); // NVIDIA 190.42 doesnt support DEPTH_STENCIL
     testsExpectedToFail.push('conformance/gl-get-active-attribute.html'); // bug in NVIDIA 190.42, fixed in newer drivers
     testsExpectedToFail.push('conformance/gl-uniform-bool.html'); // bug in NVIDIA 190.42, fixed in newer drivers
     testsExpectedToFail.push('conformance/tex-image-and-sub-image-2d-with-array-buffer-view.html'); // ???
+    testsExpectedToFail.push('conformance/uninitialized-test.html'); // bug in NVIDIA 190.42, fixed in newer drivers
   }
 
   var testsToIgnore = [];
 
   var testsSuccessful = [];
 
   runTestSuite();
 }
--- a/content/events/src/nsDOMDataTransfer.cpp
+++ b/content/events/src/nsDOMDataTransfer.cpp
@@ -250,17 +250,17 @@ nsDOMDataTransfer::GetFiles(nsIDOMFileLi
       if (NS_FAILED(rv))
         continue;
 
       nsCOMPtr<nsIFile> file = do_QueryInterface(supports);
 
       if (!file)
         continue;
 
-      nsRefPtr<nsDOMFile> domFile = new nsDOMFile(file);
+      nsRefPtr<nsDOMFileFile> domFile = new nsDOMFileFile(file);
 
       if (!mFiles->Append(domFile))
         return NS_ERROR_FAILURE;
     }
   }
 
   *aFileList = mFiles;
   NS_ADDREF(*aFileList);
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -1652,16 +1652,103 @@ nsEventStateManager::HandleAccessKey(nsP
 
       if (esm)
         esm->HandleAccessKey(parentPC, aEvent, aStatus, docShell,
                              eAccessKeyProcessingUp, aModifierMask);
     }
   }// if end. bubble up process
 }// end of HandleAccessKey
 
+void
+nsEventStateManager::DispatchCrossProcessEvent(nsEvent* aEvent, nsIFrameLoader* frameLoader) {
+  nsFrameLoader* fml = static_cast<nsFrameLoader*>(frameLoader);
+  PBrowserParent* remoteBrowser = fml->GetRemoteBrowser();
+  TabParent* remote = static_cast<TabParent*>(remoteBrowser);
+  if (!remote) {
+    return;
+  }
+
+  if (aEvent->eventStructType == NS_MOUSE_EVENT) {
+    nsMouseEvent* mouseEvent = static_cast<nsMouseEvent*>(aEvent);
+    remote->SendRealMouseEvent(*mouseEvent);
+  }
+
+  if (aEvent->eventStructType == NS_KEY_EVENT) {
+    nsKeyEvent* keyEvent = static_cast<nsKeyEvent*>(aEvent);
+    remote->SendRealKeyEvent(*keyEvent);
+  }
+
+  if (aEvent->eventStructType == NS_MOUSE_SCROLL_EVENT) {
+    nsMouseScrollEvent* scrollEvent = static_cast<nsMouseScrollEvent*>(aEvent);
+    remote->SendMouseScrollEvent(*scrollEvent);
+  }
+}
+
+PRBool
+nsEventStateManager::IsRemoteTarget(nsIContent* target) {
+  return target &&
+         target->Tag() == nsGkAtoms::browser &&
+         target->IsXUL() &&
+         target->AttrValueIs(kNameSpaceID_None, nsGkAtoms::Remote,
+                             nsGkAtoms::_true, eIgnoreCase);
+}
+
+
+PRBool
+nsEventStateManager::HandleCrossProcessEvent(nsEvent *aEvent,
+                                             nsIFrame* aTargetFrame,
+                                             nsEventStatus *aStatus) {
+
+  switch (aEvent->eventStructType) {
+    case NS_KEY_EVENT:
+    case NS_MOUSE_SCROLL_EVENT:
+      break;
+    case NS_MOUSE_EVENT:
+      if (aEvent->message == NS_MOUSE_BUTTON_DOWN ||
+          aEvent->message == NS_MOUSE_BUTTON_UP ||
+          aEvent->message == NS_MOUSE_MOVE) {
+        break;
+      }
+    default:
+      return PR_FALSE;
+  }
+
+  nsIContent* target = mCurrentTargetContent;
+  if (!target && aTargetFrame) {
+    target = aTargetFrame->GetContent();
+  }
+
+  if (*aStatus == nsEventStatus_eConsumeNoDefault ||
+      !target ||
+      !IsRemoteTarget(target)) {
+    return PR_FALSE;
+  }
+
+  nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(target);
+  if (!loaderOwner) {
+    return PR_FALSE;
+  }
+
+  nsRefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
+  if (!frameLoader) {
+    return PR_FALSE;
+  }
+
+  PRUint32 eventMode;
+  frameLoader->GetEventMode(&eventMode);
+  if (eventMode == nsIFrameLoader::EVENT_MODE_DONT_FORWARD_TO_CHILD) {
+    return PR_FALSE;
+  }
+
+  nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, aTargetFrame);
+  aEvent->refPoint = pt.ToNearestPixels(mPresContext->AppUnitsPerDevPixel());
+
+  DispatchCrossProcessEvent(aEvent, frameLoader);
+  return PR_TRUE;
+}
 
 //
 // CreateClickHoldTimer
 //
 // Fire off a timer for determining if the user wants click-hold. This timer
 // is a one-shot that will be cancelled when the user moves enough to fire
 // a drag.
 //
@@ -2900,16 +2987,18 @@ nsEventStateManager::PostHandleEvent(nsP
                                      nsEvent *aEvent,
                                      nsIFrame* aTargetFrame,
                                      nsEventStatus* aStatus,
                                      nsIView* aView)
 {
   NS_ENSURE_ARG(aPresContext);
   NS_ENSURE_ARG_POINTER(aStatus);
 
+  HandleCrossProcessEvent(aEvent, aTargetFrame, aStatus);
+
   mCurrentTarget = aTargetFrame;
   mCurrentTargetContent = nsnull;
 
   // Most of the events we handle below require a frame.
   // Add special cases here.
   if (!mCurrentTarget && aEvent->message != NS_MOUSE_BUTTON_UP &&
       aEvent->message != NS_MOUSE_BUTTON_DOWN) {
     return NS_OK;
@@ -3415,16 +3504,20 @@ nsEventStateManager::ClearFrameRefs(nsIF
   }
 }
 
 void
 nsEventStateManager::UpdateCursor(nsPresContext* aPresContext,
                                   nsEvent* aEvent, nsIFrame* aTargetFrame,
                                   nsEventStatus* aStatus)
 {
+  if (aTargetFrame && IsRemoteTarget(aTargetFrame->GetContent())) {
+    return;
+  }
+
   PRInt32 cursor = NS_STYLE_CURSOR_DEFAULT;
   imgIContainer* container = nsnull;
   PRBool haveHotspot = PR_FALSE;
   float hotspotX = 0.0f, hotspotY = 0.0f;
 
   //If cursor is locked just use the locked one
   if (mLockCursor) {
     cursor = mLockCursor;
--- a/content/events/src/nsEventStateManager.h
+++ b/content/events/src/nsEventStateManager.h
@@ -44,16 +44,17 @@
 #include "nsIContent.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
 #include "nsHashtable.h"
 #include "nsITimer.h"
 #include "nsCOMPtr.h"
 #include "nsIDocument.h"
 #include "nsCOMArray.h"
+#include "nsIFrameLoader.h"
 #include "nsIFrame.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIMarkupDocumentViewer.h"
 #include "nsIScrollableFrame.h"
 #include "nsFocusManager.h"
 #include "nsIDocument.h"
 #include "nsEventStates.h"
 
@@ -422,16 +423,22 @@ protected:
 
   void DoQueryScrollTargetInfo(nsQueryContentEvent* aEvent,
                                nsIFrame* aTargetFrame);
 
   PRBool RemoteQueryContentEvent(nsEvent *aEvent);
   mozilla::dom::TabParent *GetCrossProcessTarget();
   PRBool IsTargetCrossProcess(nsGUIEvent *aEvent);
 
+  void DispatchCrossProcessEvent(nsEvent* aEvent, nsIFrameLoader* remote);
+  PRBool IsRemoteTarget(nsIContent* target);
+  PRBool HandleCrossProcessEvent(nsEvent *aEvent,
+                                 nsIFrame* aTargetFrame,
+                                 nsEventStatus *aStatus);
+
 private:
   static inline void DoStateChange(mozilla::dom::Element* aElement,
                                    nsEventStates aState, PRBool aAddState);
   static inline void DoStateChange(nsIContent* aContent, nsEventStates aState,
                                    PRBool aAddState);
   static void UpdateAncestorState(nsIContent* aStartNode,
                                   nsIContent* aStopBefore,
                                   nsEventStates aState,
--- a/content/html/content/public/nsHTMLCanvasElement.h
+++ b/content/html/content/public/nsHTMLCanvasElement.h
@@ -165,16 +165,20 @@ public:
 
   /*
    * Helpers called by various users of Canvas
    */
 
   already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                                CanvasLayer *aOldLayer,
                                                LayerManager *aManager);
+  // Should return true if the canvas layer should always be marked inactive.
+  // We should return true here if we can't do accelerated compositing with
+  // a non-BasicCanvasLayer.
+  PRBool ShouldForceInactiveLayer(LayerManager *aManager);
 
   // Call this whenever we need future changes to the canvas
   // to trigger fresh invalidation requests. This needs to be called
   // whenever we render the canvas contents to the screen, or whenever we
   // take a snapshot of the canvas that needs to be "live" (e.g. -moz-element).
   void MarkContextClean();
 
   virtual nsXPCClassInfo* GetClassInfo();
@@ -188,16 +192,17 @@ protected:
                        bool& aFellBackToPNG);
   nsresult ToDataURLImpl(const nsAString& aMimeType,
                          nsIVariant* aEncoderOptions,
                          nsAString& aDataURL);
   nsresult MozGetAsFileImpl(const nsAString& aName,
                             const nsAString& aType,
                             nsIDOMFile** aResult);
   nsresult GetContextHelper(const nsAString& aContextId,
+                            PRBool aForceThebes,
                             nsICanvasRenderingContextInternal **aContext);
 
   nsString mCurrentContextId;
   nsCOMPtr<nsICanvasRenderingContextInternal> mCurrentContext;
   
 public:
   // Record whether this canvas should be write-only or not.
   // We set this when script paints an image from a different origin.
--- a/content/html/content/reftests/autofocus/input-load.html
+++ b/content/html/content/reftests/autofocus/input-load.html
@@ -1,13 +1,13 @@
 <!DOCTYPE html>
 <html class="reftest-wait">
   <link rel='stylesheet' type='text/css' href='style.css'>
   <script>
     function focusHandler()
     {
-      setTimeout(document.documentElement.removeAttribute('class'), 0);
+      document.documentElement.removeAttribute('class');
     }
   </script>
   <body>
     <input><input autofocus onfocus="focusHandler();"><input autofocus onfocus="focusHandler();">
   </body>
 </html>
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -2099,27 +2099,16 @@ nsGenericHTMLElement::GetAttrHelper(nsIA
 
 nsresult
 nsGenericHTMLElement::SetAttrHelper(nsIAtom* aAttr, const nsAString& aValue)
 {
   return SetAttr(kNameSpaceID_None, aAttr, aValue, PR_TRUE);
 }
 
 nsresult
-nsGenericHTMLElement::GetStringAttrWithDefault(nsIAtom* aAttr,
-                                               const char* aDefault,
-                                               nsAString& aResult)
-{
-  if (!GetAttr(kNameSpaceID_None, aAttr, aResult)) {
-    CopyASCIItoUTF16(aDefault, aResult);
-  }
-  return NS_OK;
-}
-
-nsresult
 nsGenericHTMLElement::SetBoolAttr(nsIAtom* aAttr, PRBool aValue)
 {
   if (aValue) {
     return SetAttr(kNameSpaceID_None, aAttr, EmptyString(), PR_TRUE);
   }
 
   return UnsetAttr(kNameSpaceID_None, aAttr, PR_TRUE);
 }
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -605,29 +605,16 @@ protected:
    *
    * @param aAttr    name of attribute.
    * @param aDefault default-value to return if attribute isn't set.
    * @param aResult  result value [out]
    */
   NS_HIDDEN_(nsresult) SetAttrHelper(nsIAtom* aAttr, const nsAString& aValue);
 
   /**
-   * Helper method for NS_IMPL_STRING_ATTR_DEFAULT_VALUE macro.
-   * Gets the value of an attribute, returns specified default value if the
-   * attribute isn't set. Only works for attributes in null namespace.
-   *
-   * @param aAttr    name of attribute.
-   * @param aDefault default-value to return if attribute isn't set.
-   * @param aResult  result value [out]
-   */
-  NS_HIDDEN_(nsresult) GetStringAttrWithDefault(nsIAtom* aAttr,
-                                                const char* aDefault,
-                                                nsAString& aResult);
-
-  /**
    * Helper method for NS_IMPL_BOOL_ATTR macro.
    * Gets value of boolean attribute. Only works for attributes in null
    * namespace.
    *
    * @param aAttr    name of attribute.
    * @param aValue   Boolean value of attribute.
    */
   NS_HIDDEN_(nsresult) GetBoolAttr(nsIAtom* aAttr, PRBool* aValue) const;
@@ -1080,33 +1067,16 @@ protected:
   }                                                                  \
   NS_IMETHODIMP                                                      \
   _class::Set##_method(const nsAString& aValue)                      \
   {                                                                  \
     return SetAttrHelper(nsGkAtoms::_atom, aValue);                  \
   }
 
 /**
- * A macro to implement the getter and setter for a given string
- * valued content property with a default value.
- * The method uses the generic GetAttr and SetAttr methods.
- */
-#define NS_IMPL_STRING_ATTR_DEFAULT_VALUE(_class, _method, _atom, _default) \
-  NS_IMETHODIMP                                                      \
-  _class::Get##_method(nsAString& aValue)                            \
-  {                                                                  \
-    return GetStringAttrWithDefault(nsGkAtoms::_atom, _default, aValue);\
-  }                                                                  \
-  NS_IMETHODIMP                                                      \
-  _class::Set##_method(const nsAString& aValue)                      \
-  {                                                                  \
-    return SetAttrHelper(nsGkAtoms::_atom, aValue);                \
-  }
-
-/**
  * A macro to implement the getter and setter for a given boolean
  * valued content property. The method uses the generic GetAttr and
  * SetAttr methods.
  */
 #define NS_IMPL_BOOL_ATTR(_class, _method, _atom)                     \
   NS_IMETHODIMP                                                       \
   _class::Get##_method(PRBool* aValue)                                \
   {                                                                   \
--- a/content/html/content/src/nsHTMLCanvasElement.cpp
+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
@@ -375,21 +375,22 @@ nsHTMLCanvasElement::MozGetAsFileImpl(co
   nsRefPtr<nsDOMMemoryFile> file =
     new nsDOMMemoryFile(imgData, imgSize, aName, type);
 
   return CallQueryInterface(file, aResult);
 }
 
 nsresult
 nsHTMLCanvasElement::GetContextHelper(const nsAString& aContextId,
+                                      PRBool aForceThebes,
                                       nsICanvasRenderingContextInternal **aContext)
 {
   NS_ENSURE_ARG(aContext);
 
-  NS_LossyConvertUTF16toASCII ctxId(aContextId);
+  NS_ConvertUTF16toUTF8 ctxId(aContextId);
 
   // check that ctxId is clamped to A-Za-z0-9_-
   for (PRUint32 i = 0; i < ctxId.Length(); i++) {
     if ((ctxId[i] < 'A' || ctxId[i] > 'Z') &&
         (ctxId[i] < 'a' || ctxId[i] > 'z') &&
         (ctxId[i] < '0' || ctxId[i] > '9') &&
         (ctxId[i] != '-') &&
         (ctxId[i] != '_'))
@@ -397,16 +398,20 @@ nsHTMLCanvasElement::GetContextHelper(co
       // XXX ERRMSG we need to report an error to developers here! (bug 329026)
       return NS_OK;
     }
   }
 
   nsCString ctxString("@mozilla.org/content/canvas-rendering-context;1?id=");
   ctxString.Append(ctxId);
 
+  if (aForceThebes && ctxId.EqualsASCII("2d")) {
+    ctxString.AssignASCII("@mozilla.org/content/2dthebes-canvas-rendering-context;1");
+  }
+
   nsresult rv;
   nsCOMPtr<nsICanvasRenderingContextInternal> ctx =
     do_CreateInstance(ctxString.get(), &rv);
   if (rv == NS_ERROR_OUT_OF_MEMORY) {
     *aContext = nsnull;
     return NS_ERROR_OUT_OF_MEMORY;
   }
   if (NS_FAILED(rv)) {
@@ -428,18 +433,20 @@ nsHTMLCanvasElement::GetContextHelper(co
 
 NS_IMETHODIMP
 nsHTMLCanvasElement::GetContext(const nsAString& aContextId,
                                 const jsval& aContextOptions,
                                 nsISupports **aContext)
 {
   nsresult rv;
 
-  if (mCurrentContextId.IsEmpty()) {
-    rv = GetContextHelper(aContextId, getter_AddRefs(mCurrentContext));
+  PRBool forceThebes = PR_FALSE;
+
+  while (mCurrentContextId.IsEmpty()) {
+    rv = GetContextHelper(aContextId, forceThebes, getter_AddRefs(mCurrentContext));
     NS_ENSURE_SUCCESS(rv, rv);
     if (!mCurrentContext) {
       return NS_OK;
     }
 
     // Ensure that the context participates in CC.  Note that returning a
     // CC participant from QI doesn't addref.
     nsXPCOMCycleCollectionParticipant *cp = nsnull;
@@ -501,21 +508,28 @@ nsHTMLCanvasElement::GetContext(const ns
       }
 
       contextProps = newProps;
     }
 
     rv = UpdateContext(contextProps);
     if (NS_FAILED(rv)) {
       mCurrentContext = nsnull;
+      if (!forceThebes) {
+        // Try again with a Thebes context
+        forceThebes = PR_TRUE;
+        continue;
+      }
       return rv;
     }
 
     mCurrentContextId.Assign(aContextId);
-  } else if (!mCurrentContextId.Equals(aContextId)) {
+    break;
+  }
+  if (!mCurrentContextId.Equals(aContextId)) {
     //XXX eventually allow for more than one active context on a given canvas
     return NS_OK;
   }
 
   NS_ADDREF (*aContext = mCurrentContext);
   return NS_OK;
 }
 
@@ -530,17 +544,17 @@ nsHTMLCanvasElement::MozGetIPCContext(co
 
   // We only support 2d shmem contexts for now.
   if (!aContextId.Equals(NS_LITERAL_STRING("2d")))
     return NS_ERROR_INVALID_ARG;
 
   nsresult rv;
 
   if (mCurrentContextId.IsEmpty()) {
-    rv = GetContextHelper(aContextId, getter_AddRefs(mCurrentContext));
+    rv = GetContextHelper(aContextId, PR_FALSE, getter_AddRefs(mCurrentContext));
     NS_ENSURE_SUCCESS(rv, rv);
     if (!mCurrentContext) {
       return NS_OK;
     }
 
     mCurrentContext->SetIsIPC(PR_TRUE);
 
     rv = UpdateContext();
@@ -695,16 +709,22 @@ nsHTMLCanvasElement::GetCanvasLayer(nsDi
                                     LayerManager *aManager)
 {
   if (!mCurrentContext)
     return nsnull;
 
   return mCurrentContext->GetCanvasLayer(aBuilder, aOldLayer, aManager);
 }
 
+PRBool
+nsHTMLCanvasElement::ShouldForceInactiveLayer(LayerManager *aManager)
+{
+  return !mCurrentContext || mCurrentContext->ShouldForceInactiveLayer(aManager);
+}
+
 void
 nsHTMLCanvasElement::MarkContextClean()
 {
   if (!mCurrentContext)
     return;
 
   mCurrentContext->MarkContextClean();
 }
--- a/content/html/content/src/nsHTMLImageElement.cpp
+++ b/content/html/content/src/nsHTMLImageElement.cpp
@@ -282,47 +282,49 @@ nsHTMLImageElement::GetWidthHeight()
     if ((value = GetParsedAttr(nsGkAtoms::height)) &&
         value->Type() == nsAttrValue::eInteger) {
       size.height = value->GetIntegerValue();
     } else if (image) {
       image->GetHeight(&size.height);
     }
   }
 
+  NS_ASSERTION(size.width >= 0, "negative width");
+  NS_ASSERTION(size.height >= 0, "negative height");
   return size;
 }
 
 NS_IMETHODIMP
-nsHTMLImageElement::GetHeight(PRInt32* aHeight)
+nsHTMLImageElement::GetHeight(PRUint32* aHeight)
 {
   *aHeight = GetWidthHeight().height;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLImageElement::SetHeight(PRInt32 aHeight)
+nsHTMLImageElement::SetHeight(PRUint32 aHeight)
 {
   nsAutoString val;
   val.AppendInt(aHeight);
 
   return nsGenericHTMLElement::SetAttr(kNameSpaceID_None, nsGkAtoms::height,
                                        val, PR_TRUE);
 }
 
 NS_IMETHODIMP
-nsHTMLImageElement::GetWidth(PRInt32* aWidth)
+nsHTMLImageElement::GetWidth(PRUint32* aWidth)
 {
   *aWidth = GetWidthHeight().width;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLImageElement::SetWidth(PRInt32 aWidth)
+nsHTMLImageElement::SetWidth(PRUint32 aWidth)
 {
   nsAutoString val;
   val.AppendInt(aWidth);
 
   return nsGenericHTMLElement::SetAttr(kNameSpaceID_None, nsGkAtoms::width,
                                        val, PR_TRUE);
 }
 
@@ -571,54 +573,60 @@ nsHTMLImageElement::Initialize(nsISuppor
 
     rv = SetIntAttr(nsGkAtoms::height, static_cast<PRInt32>(height));
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
-nsHTMLImageElement::GetNaturalHeight(PRInt32* aNaturalHeight)
+nsHTMLImageElement::GetNaturalHeight(PRUint32* aNaturalHeight)
 {
   NS_ENSURE_ARG_POINTER(aNaturalHeight);
 
   *aNaturalHeight = 0;
 
   if (!mCurrentRequest) {
     return NS_OK;
   }
   
   nsCOMPtr<imgIContainer> image;
   mCurrentRequest->GetImage(getter_AddRefs(image));
   if (!image) {
     return NS_OK;
   }
 
-  image->GetHeight(aNaturalHeight);
+  PRInt32 height;
+  if (NS_SUCCEEDED(image->GetHeight(&height))) {
+    *aNaturalHeight = height;
+  }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLImageElement::GetNaturalWidth(PRInt32* aNaturalWidth)
+nsHTMLImageElement::GetNaturalWidth(PRUint32* aNaturalWidth)
 {
   NS_ENSURE_ARG_POINTER(aNaturalWidth);
 
   *aNaturalWidth = 0;
 
   if (!mCurrentRequest) {
     return NS_OK;
   }
   
   nsCOMPtr<imgIContainer> image;
   mCurrentRequest->GetImage(getter_AddRefs(image));
   if (!image) {
     return NS_OK;
   }
 
-  image->GetWidth(aNaturalWidth);
+  PRInt32 width;
+  if (NS_SUCCEEDED(image->GetWidth(&width))) {
+    *aNaturalWidth = width;
+  }
   return NS_OK;
 }
 
 nsresult
 nsHTMLImageElement::CopyInnerTo(nsGenericElement* aDest) const
 {
   if (aDest->GetOwnerDoc()->IsStaticDocument()) {
     CreateStaticImageClone(static_cast<nsHTMLImageElement*>(aDest));
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -399,17 +399,17 @@ AsyncClickHandler::Run()
     while (NS_SUCCEEDED(iter->HasMoreElements(&loop)) && loop) {
       iter->GetNext(getter_AddRefs(tmp));
       nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(tmp);
       if (localFile) {
         nsString unicodePath;
         rv = localFile->GetPath(unicodePath);
         if (!unicodePath.IsEmpty()) {
           nsCOMPtr<nsIDOMFile> domFile =
-            do_QueryObject(new nsDOMFile(localFile));
+            do_QueryObject(new nsDOMFileFile(localFile));
           newFiles.AppendObject(domFile);
         }
         if (!prefSaved) {
           // Store the last used directory using the content pref service
           nsHTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(doc->GetDocumentURI(),
                                                                      localFile);
           prefSaved = PR_TRUE;
         }
@@ -419,17 +419,17 @@ AsyncClickHandler::Run()
   else {
     nsCOMPtr<nsILocalFile> localFile;
     rv = filePicker->GetFile(getter_AddRefs(localFile));
     if (localFile) {
       nsString unicodePath;
       rv = localFile->GetPath(unicodePath);
       if (!unicodePath.IsEmpty()) {
         nsCOMPtr<nsIDOMFile> domFile=
-          do_QueryObject(new nsDOMFile(localFile));
+          do_QueryObject(new nsDOMFileFile(localFile));
         newFiles.AppendObject(domFile);
       }
       // Store the last used directory using the content pref service
       nsHTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(doc->GetDocumentURI(),
                                                                  localFile);
     }
   }
 
@@ -902,16 +902,18 @@ nsHTMLInputElement::AfterSetAttr(PRInt32
       // This *has* to be called *after* validity has changed.
       if (aName == nsGkAtoms::readonly || aName == nsGkAtoms::disabled) {
         UpdateBarredFromConstraintValidation();
       }
     } else if (MaxLengthApplies() && aName == nsGkAtoms::maxlength) {
       UpdateTooLongValidityState();
     } else if (aName == nsGkAtoms::pattern) {
       UpdatePatternMismatchValidityState();
+    } else if (aName == nsGkAtoms::multiple) {
+      UpdateTypeMismatchValidityState();
     }
 
     UpdateEditableState(aNotify);
     UpdateState(aNotify);
   }
 
   return nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName,
                                                 aValue, aNotify);
@@ -1142,17 +1144,17 @@ nsHTMLInputElement::MozSetFileNameArray(
       // this is no "file://", try as local file
       nsCOMPtr<nsILocalFile> localFile;
       NS_NewLocalFile(nsDependentString(aFileNames[i]),
                       PR_FALSE, getter_AddRefs(localFile));
       file = do_QueryInterface(localFile);
     }
 
     if (file) {
-      nsCOMPtr<nsIDOMFile> domFile = new nsDOMFile(file);
+      nsCOMPtr<nsIDOMFile> domFile = new nsDOMFileFile(file);
       files.AppendObject(domFile);
     } else {
       continue; // Not much we can do if the file doesn't exist
     }
 
   }
 
   SetFiles(files, true);
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -1982,21 +1982,21 @@ void nsHTMLMediaElement::ResourceLoaded(
 
 void nsHTMLMediaElement::NetworkError()
 {
   Error(nsIDOMMediaError::MEDIA_ERR_NETWORK);
 }
 
 void nsHTMLMediaElement::DecodeError()
 {
+  if (mDecoder) {
+    mDecoder->Shutdown();
+    mDecoder = nsnull;
+  }
   if (mIsLoadingFromSourceChildren) {
-    if (mDecoder) {
-      mDecoder->Shutdown();
-      mDecoder = nsnull;
-    }
     mError = nsnull;
     if (mSourceLoadCandidate) {
       DispatchAsyncSourceError(mSourceLoadCandidate);
       QueueLoadFromSourceTask();
     } else {
       NS_WARNING("Should know the source we were loading from!");
     }
   } else {
--- a/content/html/content/src/nsHTMLTableCellElement.cpp
+++ b/content/html/content/src/nsHTMLTableCellElement.cpp
@@ -217,25 +217,25 @@ nsHTMLTableCellElement::WalkContentStyle
 
   return rv;
 }
 
 
 NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, Abbr, abbr)
 NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, Axis, axis)
 NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, BgColor, bgcolor)
-NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableCellElement, Ch, _char, ".")
+NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, Ch, _char)
 NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, ChOff, charoff)
 NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLTableCellElement, ColSpan, colspan, 1)
 NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, Headers, headers)
 NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, Height, height)
 NS_IMPL_BOOL_ATTR(nsHTMLTableCellElement, NoWrap, nowrap)
 NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLTableCellElement, RowSpan, rowspan, 1)
 NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, Scope, scope)
-NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableCellElement, VAlign, valign, "middle")
+NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, VAlign, valign)
 NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, Width, width)
 
 
 NS_IMETHODIMP
 nsHTMLTableCellElement::GetAlign(nsAString& aValue)
 {
   if (!GetAttr(kNameSpaceID_None, nsGkAtoms::align, aValue)) {
     // There's no align attribute, ask the row for the alignment.
--- a/content/html/content/src/nsHTMLTableColElement.cpp
+++ b/content/html/content/src/nsHTMLTableColElement.cpp
@@ -106,21 +106,21 @@ NS_INTERFACE_TABLE_HEAD(nsHTMLTableColEl
                                    nsIDOMHTMLTableColElement)
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLTableColElement,
                                                nsGenericHTMLElement)
 NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLTableColElement)
 
 NS_IMPL_ELEMENT_CLONE(nsHTMLTableColElement)
 
 
-NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableColElement, Align, align, "left")
-NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableColElement, Ch, _char, ".")
+NS_IMPL_STRING_ATTR(nsHTMLTableColElement, Align, align)
+NS_IMPL_STRING_ATTR(nsHTMLTableColElement, Ch, _char)
 NS_IMPL_STRING_ATTR(nsHTMLTableColElement, ChOff, charoff)
 NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLTableColElement, Span, span, 1)
-NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableColElement, VAlign, valign, "middle")
+NS_IMPL_STRING_ATTR(nsHTMLTableColElement, VAlign, valign)
 NS_IMPL_STRING_ATTR(nsHTMLTableColElement, Width, width)
 
 
 PRBool
 nsHTMLTableColElement::ParseAttribute(PRInt32 aNamespaceID,
                                       nsIAtom* aAttribute,
                                       const nsAString& aValue,
                                       nsAttrValue& aResult)
--- a/content/html/content/src/nsHTMLTableElement.cpp
+++ b/content/html/content/src/nsHTMLTableElement.cpp
@@ -960,42 +960,33 @@ nsHTMLTableElement::ParseAttribute(PRInt
                                    nsAttrValue& aResult)
 {
   /* ignore summary, just a string */
   if (aNamespaceID == kNameSpaceID_None) {
     if (aAttribute == nsGkAtoms::cellspacing ||
         aAttribute == nsGkAtoms::cellpadding) {
       return aResult.ParseSpecialIntValue(aValue);
     }
-    if (aAttribute == nsGkAtoms::cols) {
+    if (aAttribute == nsGkAtoms::cols ||
+        aAttribute == nsGkAtoms::border) {
       return aResult.ParseIntWithBounds(aValue, 0);
     }
-    if (aAttribute == nsGkAtoms::border) {
-      if (!aResult.ParseIntWithBounds(aValue, 0)) {
-        // XXX this should really be NavQuirks only to allow non numeric value
-        aResult.SetTo(1);
-      }
-
-      return PR_TRUE;
-    }
     if (aAttribute == nsGkAtoms::height) {
       return aResult.ParseSpecialIntValue(aValue);
     }
     if (aAttribute == nsGkAtoms::width) {
       if (aResult.ParseSpecialIntValue(aValue)) {
         // treat 0 width as auto
         nsAttrValue::ValueType type = aResult.Type();
-        if ((type == nsAttrValue::eInteger &&
-             aResult.GetIntegerValue() == 0) ||
-            (type == nsAttrValue::ePercent &&
-             aResult.GetPercentValue() == 0.0f)) {
-          return PR_FALSE;
-        }
+        return !((type == nsAttrValue::eInteger &&
+                  aResult.GetIntegerValue() == 0) ||
+                 (type == nsAttrValue::ePercent &&
+                  aResult.GetPercentValue() == 0.0f));
       }
-      return PR_TRUE;
+      return PR_FALSE;
     }
     
     if (aAttribute == nsGkAtoms::align) {
       return ParseTableHAlignValue(aValue, aResult);
     }
     if (aAttribute == nsGkAtoms::bgcolor ||
         aAttribute == nsGkAtoms::bordercolor) {
       return aResult.ParseColor(aValue);
--- a/content/html/content/src/nsHTMLTableRowElement.cpp
+++ b/content/html/content/src/nsHTMLTableRowElement.cpp
@@ -354,21 +354,21 @@ nsHTMLTableRowElement::DeleteCell(PRInt3
   if (!cell) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   nsCOMPtr<nsIDOMNode> retChild;
   return RemoveChild(cell, getter_AddRefs(retChild));
 }
 
-NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableRowElement, Align, align, "left")
+NS_IMPL_STRING_ATTR(nsHTMLTableRowElement, Align, align)
 NS_IMPL_STRING_ATTR(nsHTMLTableRowElement, BgColor, bgcolor)
-NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableRowElement, Ch, _char, ".")
+NS_IMPL_STRING_ATTR(nsHTMLTableRowElement, Ch, _char)
 NS_IMPL_STRING_ATTR(nsHTMLTableRowElement, ChOff, charoff)
-NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableRowElement, VAlign, valign, "middle")
+NS_IMPL_STRING_ATTR(nsHTMLTableRowElement, VAlign, valign)
 
 
 PRBool
 nsHTMLTableRowElement::ParseAttribute(PRInt32 aNamespaceID,
                                       nsIAtom* aAttribute,
                                       const nsAString& aValue,
                                       nsAttrValue& aResult)
 {
--- a/content/html/content/src/nsHTMLTableSectionElement.cpp
+++ b/content/html/content/src/nsHTMLTableSectionElement.cpp
@@ -115,19 +115,19 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLTableSectionElement,
                                                nsGenericHTMLElement)
 NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLTableSectionElement)
 
 
 NS_IMPL_ELEMENT_CLONE(nsHTMLTableSectionElement)
 
 
-NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableSectionElement, Align, align, "left")
-NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableSectionElement, VAlign, valign, "middle")
-NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableSectionElement, Ch, _char, ".")
+NS_IMPL_STRING_ATTR(nsHTMLTableSectionElement, Align, align)
+NS_IMPL_STRING_ATTR(nsHTMLTableSectionElement, VAlign, valign)
+NS_IMPL_STRING_ATTR(nsHTMLTableSectionElement, Ch, _char)
 NS_IMPL_STRING_ATTR(nsHTMLTableSectionElement, ChOff, charoff)
 
 
 NS_IMETHODIMP
 nsHTMLTableSectionElement::GetRows(nsIDOMHTMLCollection** aValue)
 {
   *aValue = nsnull;
 
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -236,17 +236,16 @@ include $(topsrcdir)/config/rules.mk
 		test_bug596350.html \
 		test_bug598833-1.html \
 		test_bug600155.html \
 		test_bug556007.html \
 		test_bug606817.html \
 		test_bug297761.html \
 		file_bug297761.html \
 		test_bug607145.html \
-		test_bug601061.html \
 		test_bug596511.html \
 		reflect.js \
 		test_bug611189.html \
 		test_bug613113.html \
 		test_bug605124-1.html \
 		test_bug605124-2.html \
 		test_bug605125-1.html \
 		test_bug605125-2.html \
@@ -257,26 +256,26 @@ include $(topsrcdir)/config/rules.mk
 		test_bug601030.html \
 		test_bug610687.html \
 		test_bug618948.html \
 		test_bug623291.html \
 		test_bug619278.html \
 		test_bug622558.html \
 		test_bug622597.html \
 		test_bug636336.html \
-		test_bug630889.html \
 		test_bug610212.html \
 		test_bug633058.html \
 		test_bug641219.html \
 		test_bug643051.html \
 		test_bug583514.html \
 		test_bug514437.html \
 		test_bug560112.html \
 		test_bug649134.html \
 		test_bug658746.html \
 		test_bug659596.html \
 		test_bug659743.xml \
 		test_bug660663.html \
+		test_bug586786.html \
 		test_restore_from_parser_fragment.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
--- a/content/html/content/test/forms/Makefile.in
+++ b/content/html/content/test/forms/Makefile.in
@@ -53,13 +53,14 @@ include $(topsrcdir)/config/rules.mk
 		test_pattern_attribute.html \
 		test_required_attribute.html \
 		test_novalidate_attribute.html \
 		test_formaction_attribute.html \
 		test_formnovalidate_attribute.html \
 		test_label_control_attribute.html \
 		test_output_element.html \
 		test_button_attributes_reflection.html \
+		test_textarea_attributes_reflection.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
 
--- a/content/html/content/test/forms/test_button_attributes_reflection.html
+++ b/content/html/content/test/forms/test_button_attributes_reflection.html
@@ -16,18 +16,20 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="content" style="display: none">
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 551670 **/
 
 // .type
-reflectLimitedEnumerated(document.createElement("button"),
-                         "type",
-                         [ "submit", "reset", "button" ],
-                         [ "this-is-probably-a-wrong-type", "", "tulip" ],
-                         "submit");
+reflectLimitedEnumerated({
+  element: document.createElement("button"),
+  attribute: "type",
+  validValues: [ "submit", "reset", "button" ],
+  invalidValues: [ "this-is-probably-a-wrong-type", "", "tulip" ],
+  defaultValue: "submit",
+});
 
 </script>
 </pre>
 </body>
 </html>
--- a/content/html/content/test/forms/test_input_attributes_reflection.html
+++ b/content/html/content/test/forms/test_input_attributes_reflection.html
@@ -1,108 +1,150 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=551670
--->
 <head>
-  <title>Test for Bug 551670</title>
+  <title>Test for HTMLInputElement attributes reflection</title>
   <script type="application/javascript" src="/MochiKit/packed.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="../reflect.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=551670">Mozilla Bug 551670</a>
 <p id="display"></p>
 <div id="content" style="display: none">
 </div>
 <pre id="test">
 <script type="application/javascript">
 
-/** Test for Bug 551670 **/
+/** Test for HTMLInputElement attributes reflection **/
 
 // TODO: maybe make those reflections be tested against all input types.
 
 // .accept
-reflectString(document.createElement("input"), "accept",
-              [ "audio/*", "video/*", "image/*", "image/png",
-                "application/msword", "appplication/pdf" ]);
+reflectString({
+  element: document.createElement("input"),
+  attribute: "accept",
+  otherValues: [ "audio/*", "video/*", "image/*", "image/png",
+                 "application/msword", "appplication/pdf" ],
+});
 
 // .alt
-reflectString(document.createElement("input"), "alt");
+reflectString({
+  element: document.createElement("input"),
+  attribute: "alt",
+});
 
 // .autocomplete
-reflectLimitedEnumerated(document.createElement("input"), "autocomplete",
-                         [ "on", "off" ], [ "", "default", "foo", "tulip" ]);
+reflectLimitedEnumerated({
+  element: document.createElement("input"),
+  attribute: "autocomplete",
+  validValues: [ "on", "off" ],
+  invalidValues: [ "", "default", "foo", "tulip" ],
+});
 
 // TODO: autofocus (boolean)
 // TODO: defaultChecked (boolean)
 // TODO: checked (boolean)
 // TODO: dirName (not implemented)
 // TODO: disabled (boolean)
 // TODO: form (HTMLFormElement)
 // TODO: files (FileList)
 // TODO: formAction (URL)
 
 // .formEnctype
-reflectLimitedEnumerated(document.createElement("input"), "formEnctype",
-                         [ "application/x-www-form-urlencoded",
-                           "multipart/form-data", "text/plain" ],
-                         [ "", "foo", "tulip", "multipart/foo" ],
-                         "application/x-www-form-urlencoded");
+reflectLimitedEnumerated({
+  element: document.createElement("input"),
+  attribute: "formEnctype",
+  validValues: [ "application/x-www-form-urlencoded", "multipart/form-data",
+                 "text/plain" ],
+  invalidValues: [ "", "foo", "tulip", "multipart/foo" ],
+  defaultValue: "application/x-www-form-urlencoded"
+});
 
 // .formMethod
-reflectLimitedEnumerated(document.createElement("input"), "formMethod",
-                         [ "get", "post" ], [ "", "foo", "tulip" ], "get");
+reflectLimitedEnumerated({
+  element: document.createElement("input"),
+  attribute: "formMethod",
+  validValues: [ "get", "post" ],
+  invalidValues: [ "", "foo", "tulip" ],
+  defaultValue: "get"
+});
 
 // TODO: formNoValidate (boolean)
 
 // .formTarget
-reflectString(document.createElement("input"), "formTarget",
-              [ "_blank", "_self", "_parent", "_top" ]);
+reflectString({
+  element: document.createElement("input"),
+  attribute: "formTarget",
+  otherValues: [ "_blank", "_self", "_parent", "_top" ],
+});
 
 // TODO: height (non-negative integer)
 // TODO: indeterminate (boolean)
 // TODO: list (HTMLElement)
 // TODO: max (not implemented)
 // TODO: maxLength (long)
 // TODO: min (not implemented)
 // TODO: multiple (boolean)
 
 // .name
-reflectString(document.createElement("input"), "name",
-              [ "isindex", "_charset_" ]);
+reflectString({
+  element: document.createElement("input"),
+  attribute: "name",
+  otherValues: [ "isindex", "_charset_" ],
+});
 
 // .pattern
-reflectString(document.createElement("input"), "pattern",
-              [ "[0-9][A-Z]{3}" ]);
+reflectString({
+  element: document.createElement("input"),
+  attribute: "pattern",
+  otherValues: [ "[0-9][A-Z]{3}" ],
+});
 
 // .placeholder
-reflectString(document.createElement("input"), "placeholder",
-              [ "foo\nbar", "foo\rbar", "foo\r\nbar" ]);
+reflectString({
+  element: document.createElement("input"),
+  attribute: "placeholder",
+  otherValues: [ "foo\nbar", "foo\rbar", "foo\r\nbar" ],
+});
 
 // TODO: readOnly (boolean)
 // TODO: required (boolean)
-// TODO: size (unsigned long)
+
+// .size
+reflectUnsignedInt({
+  element: document.createElement("input"),
+  attribute: "size",
+  nonZero: true,
+  defaultValue: 20,
+});
+
 // TODO: src (URL)
 // TODO: step (not implemented)
 
 // .type
-reflectLimitedEnumerated(document.createElement("input"),
-                         "type",
-                         [ "hidden", "text", "search", "tel", "url", "email",
-                           "password", "checkbox", "radio", "file", "submit",
-                           "image", "reset", "button" ],
-                         [ "this-is-probably-a-wrong-type", "", "tulip" ],
-                         "text",
-                         [ "datetime", "date", "month", "week", "time",
-                           "datetime-local", "number", "range", "color" ]);
+reflectLimitedEnumerated({
+  element: document.createElement("input"),
+  attribute: "type",
+  validValues: [ "hidden", "text", "search", "tel", "url", "email", "password",
+                 "checkbox", "radio", "file", "submit", "image", "reset",
+                 "button" ],
+  invalidValues: [ "this-is-probably-a-wrong-type", "", "tulip" ],
+  defaultValue: "text",
+  unsupportedValues: [ "datetime", "date", "month", "week", "time",
+                       "datetime-local", "number", "range", "color" ]
+});
 
-// TODO: defaultValue (reflects @value)
+// .defaultValue
+reflectString({
+  element: document.createElement("input"),
+  attribute: { idl: "defaultValue", content: "value" },
+  otherValues: [ "foo\nbar", "foo\rbar", "foo\r\nbar" ],
+});
+
 // .value doesn't reflect a content attribute.
 // TODO: valueAsDate (not implemented)
 // TODO: valueAsNumber (not implemented)
 // TODO: selectedOption (not implemented)
 // TODO: width (non-negative integer)
 // .willValidate doesn't reflect a content attribute.
 // .validity doesn't reflect a content attribute.
 // .validationMessage doesn't reflect a content attribute.
--- a/content/html/content/test/forms/test_input_email.html
+++ b/content/html/content/test/forms/test_input_email.html
@@ -1,38 +1,33 @@
 <!DOCTYPE HTML>
 <html>
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=555559
+https://bugzilla.mozilla.org/show_bug.cgi?id=668817
 -->
 <head>
-  <title>Test for Bug 555559</title>
+  <title>Test for &lt;input type='email'&gt; validity</title>
   <script type="application/javascript" src="/MochiKit/packed.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <style>
-    input { background-color: rgb(0,0,0) !important; }
-    input:valid   { background-color: rgb(0,255,0) !important; }
-    input:invalid { background-color: rgb(255,0,0) !important; }
-  </style>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=555559">Mozilla Bug 555559</a>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=668817">Mozilla Bug 668817</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   <form>
     <input type='email' name='email' id='i' oninvalid="invalidEventHandler(event);">
   <form>
 </div>
 <pre id="test">
 <script type="application/javascript">
 
-/** Test for Bug 555559 **/
-
-// More checks are done in test_bug551670.html.
+/** Test for <input type='email'> validity **/
 
 var gInvalid = false;
 
 function invalidEventHandler(e)
 {
   is(e.type, "invalid", "Invalid event type should be invalid");
   gInvalid = true;
 }
@@ -42,200 +37,152 @@ function checkValidEmailAddress(element)
   gInvalid = false;
   ok(!element.validity.typeMismatch,
      "Element should not suffer from type mismatch (with value='"+element.value+"')");
   ok(element.validity.valid, "Element should be valid");
   ok(element.checkValidity(), "Element should be valid");
   ok(!gInvalid, "The invalid event should not have been thrown");
   is(element.validationMessage, '',
      "Validation message should be the empty string");
-  is(window.getComputedStyle(element, null).getPropertyValue('background-color'),
-     "rgb(0, 255, 0)", ":valid pseudo-class should apply");
+  ok(element.mozMatchesSelector(":valid"), ":valid pseudo-class should apply");
 }
 
 function checkInvalidEmailAddress(element)
 {
   gInvalid = false;
   ok(element.validity.typeMismatch,
      "Element should suffer from type mismatch (with value='"+element.value+"')");
   ok(!element.validity.valid, "Element should not be valid");
   ok(!element.checkValidity(), "Element should not be valid");
   ok(gInvalid, "The invalid event should have been thrown");
   is(element.validationMessage, "Please enter an email address.",
      "Validation message is not valid");
-  is(window.getComputedStyle(element, null).getPropertyValue('background-color'),
-     "rgb(255, 0, 0)", ":invalid pseudo-class should apply");
+  ok(element.mozMatchesSelector(":invalid"), ":invalid pseudo-class should apply");
+}
+
+function testEmailAddress(aElement, aValue, aMultiple, aValidity)
+{
+  aElement.multiple = aMultiple;
+  aElement.value = aValue;
+
+  if (aValidity) {
+    checkValidEmailAddress(aElement);
+  } else {
+    checkInvalidEmailAddress(aElement);
+  }
 }
 
 var email = document.forms[0].elements[0];
-is(email.type, 'email', "email state should be recognized");
-
-// This is not really a valid email address
-// but it should not be considered as invalid.
-email.value = '';
-checkValidEmailAddress(email);
-
-email.value = 'foo@bar.com';
-checkValidEmailAddress(email);
 
-email.value = ' foo@bar.com';
-checkInvalidEmailAddress(email);
-
-email.value = 'foo@bar.com ';
-checkInvalidEmailAddress(email);
+// Simple values, checking the e-mail syntax validity.
+var values = [
+  [ '', true ], // The empty string shouldn't be considered as invalid.
+  [ 'foo@bar.com', true ],
+  [ ' foo@bar.com', false ],
+  [ 'foo@bar.com ', false ],
+  [ 'tulip', false ],
+  // Some checks on the user part of the address.
+  [ '@bar.com', false ],
+  [ 'f\noo@bar.com', true ],
+  [ 'f\roo@bar.com', true ],
+  [ 'f\r\noo@bar.com', true ],
+  // Some checks for the domain part.
+  [ 'foo@bar', true ],
+  [ 'foo@b', true ],
+  [ 'foo@', false ],
+  [ 'foo@bar.', false ],
+  [ 'foo@foo.bar', true ],
+  [ 'foo@foo..bar', false ],
+  [ 'foo@.bar', false ],
+  [ 'foo@tulip.foo.bar', true ],
+  [ 'foo@tulip.foo-bar', true ],
+  [ 'foo@1.2', true ],
+  [ 'foo@127.0.0.1', true ],
+  [ 'foo@1.2.3', true ],
+  [ 'foo@b\nar.com', true ],
+  [ 'foo@b\rar.com', true ],
+  [ 'foo@b\r\nar.com', true ],
+  [ 'foo@.', false ],
+];
 
-email.value = 'tulip';
-checkInvalidEmailAddress(email);
+// Multiple values, we don't check e-mail validity, only multiple stuff.
+var multipleValues = [
+  [ 'foo@bar.com, foo@bar.com', true ],
+  [ 'foo@bar.com,foo@bar.com', true ],
+  [ 'foo@bar.com,foo@bar.com,foo@bar.com', true ],
+  [ '     foo@bar.com     ,     foo@bar.com    ', true ],
+  [ '\tfoo@bar.com\t,\tfoo@bar.com\t', true ],
+  [ '\rfoo@bar.com\r,\rfoo@bar.com\r', true ],
+  [ '\nfoo@bar.com\n,\nfoo@bar.com\n', true ],
+  [ '\ffoo@bar.com\f,\ffoo@bar.com\f', true ],
+  [ '\t foo@bar.com\r,\nfoo@bar.com\f', true ],
+  [ 'foo@b,ar.com,foo@bar.com', false ],
+  [ 'foo@bar.com,foo@bar.com,', false ],
+  [ '   foo@bar.com   ,   foo@bar.com   ,   ', false ],
+  [ ',foo@bar.com,foo@bar.com', false ],
+  [ ',foo@bar.com,foo@bar.com', false ],
+  [ 'foo@bar.com,,,foo@bar.com', false ],
+  [ 'foo@bar.com;foo@bar.com', false ],
+  [ '<foo@bar.com>, <foo@bar.com>', false ],
+  [ 'foo@bar, foo@bar.com', true ],
+  [ 'foo@bar.com, foo', false ],
+  [ 'foo, foo@bar.com', false ],
+];
 
-// Some checks on the user part of the address.
-email.value = '@bar.com';
-checkInvalidEmailAddress(email);
+/* Additional username checks. */
 
 var legalCharacters = "abcdefghijklmnopqrstuvwxyz";
 legalCharacters += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 legalCharacters += "0123456789";
 legalCharacters += "!#$%&'*+-/=?^_`{|}~.";
 
-for each (c in legalCharacters)
-{
-  email.value = c + '@bar.com';
-  checkValidEmailAddress(email);
+// Add all username legal characters individually to the list.
+for each (c in legalCharacters) {
+  values.push([c + "@bar.com", true]);
 }
-
-email.value = legalCharacters + '@bar.com';
-checkValidEmailAddress(email);
+// Add the concatenation of all legal characters too.
+values.push([legalCharacters + "@bar.com", true]);
 
-// Checking stripped characters.
-email.value = 'f\noo@bar.com';
-checkValidEmailAddress(email);
-
-email.value = 'f\roo@bar.com';
-checkValidEmailAddress(email);
-
-// Testing some illegal characters.
-var illegalCharacters = "()<>[]:;@\, \t";
-
-for each (c in illegalCharacters)
-{
-  email.value = c + '@bar.com';
-  checkInvalidEmailAddress(email);
+// Add username illegal characters, the same way.
+var illegalCharacters = "()<>[]:;@\\, \t";
+for each (c in illegalCharacters) {
+  values.push([illegalCharacters + "@bar.com", false]);
 }
 
-// Some checks on the domain part of the address.
-email.value = 'foo@bar';
-checkValidEmailAddress(email);
-
-email.value = 'foo@b';
-checkValidEmailAddress(email);
-
-email.value = 'foo@';
-checkInvalidEmailAddress(email);
+/* Additional domain checks. */
 
-email.value = 'foo@bar.';
-checkInvalidEmailAddress(email);
-
-email.value = 'foo@foo.bar';
-checkValidEmailAddress(email);
-
-email.value = 'foo@foo..bar';
-checkInvalidEmailAddress(email);
-
-email.value = 'foo@.bar';
-checkInvalidEmailAddress(email);
-
-email.value = 'foo@tulip.foo.bar';
-checkValidEmailAddress(email);
+legalCharacters = "abcdefghijklmnopqrstuvwxyz";
+legalCharacters += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+legalCharacters += "0123456789";
+legalCharacters += "-";
 
-email.value = 'foo@tulip.foo-bar';
-checkValidEmailAddress(email);
-
-email.value = 'foo@1.2';
-checkValidEmailAddress(email);
-
-email.value = 'foo@127.0.0.1';
-checkValidEmailAddress(email);
-
-email.value = 'foo@1.2.3.';
-checkInvalidEmailAddress(email);
+// Add domain legal characters (except '.' because it's special).
+for each (c in legalCharacters) {
+  values.push(["foo@foo.bar" + c, true]);
+}
+// Add the concatenation of all legal characters too.
+values.push(["foo@bar.com" + legalCharacters, true]);
 
-// Checking stripped characters.
-email.value = 'foo@b\nar.com';
-checkValidEmailAddress(email);
-
-email.value = 'foo@b\rar.com';
-checkValidEmailAddress(email);
-
-// Testing some illegal characters.
-illegalCharacters = "()<>[]:;@\,!#$%&'*+/=?^_`{|}~ \t";
-
-for each (c in illegalCharacters)
-{
-  email.value = 'foo@foo.bar' + c;
-  checkInvalidEmailAddress(email);
+// Add domain illegal characters.
+illegalCharacters = "()<>[]:;@\\,!#$%&'*+/=?^_`{|}~ \t";
+for each (c in illegalCharacters) {
+  values.push(['foo@foo.bar' + c, false]);
 }
 
-// Testing multiple: we are not going to re-test email validity, just multiple.
-email.multiple = true;
-
-email.value = 'foo@bar.com, foo@bar.com';
-checkValidEmailAddress(email);
-
-email.value = 'foo@bar.com,foo@bar.com';
-checkValidEmailAddress(email);
-
-email.value = 'foo@bar.com,foo@bar.com,foo@bar.com';
-checkValidEmailAddress(email);
-
-email.value = '     foo@bar.com     ,     foo@bar.com    ';
-checkValidEmailAddress(email);
-
-email.value = '\tfoo@bar.com\t,\tfoo@bar.com\t';
-checkValidEmailAddress(email);
-
-email.value = '\rfoo@bar.com\r,\rfoo@bar.com\r';
-checkValidEmailAddress(email);
-
-email.value = '\nfoo@bar.com\n,\nfoo@bar.com\n';
-checkValidEmailAddress(email);
-
-email.value = '\ffoo@bar.com\f,\ffoo@bar.com\f';
-checkValidEmailAddress(email);
-
-email.value = '\t foo@bar.com\r,\nfoo@bar.com\f';
-checkValidEmailAddress(email);
+values.forEach(function([value, valid]) {
+  testEmailAddress(email, value, false, valid);
+});
 
-email.value = 'foo@b,ar.com,foo@bar.com';
-checkInvalidEmailAddress(email);
-
-email.value = 'foo@bar.com,foo@bar.com,';
-checkInvalidEmailAddress(email);
-
-email.value = '   foo@bar.com   ,   foo@bar.com   ,   ';
-checkInvalidEmailAddress(email);
-
-email.value = ',foo@bar.com,foo@bar.com';
-checkInvalidEmailAddress(email);
-
-email.value = ',foo@bar.com,foo@bar.com';
-checkInvalidEmailAddress(email);
+multipleValues.forEach(function([value, valid]) {
+  testEmailAddress(email, value, true, valid);
+});
 
-email.value = 'foo@bar.com,,,foo@bar.com';
-checkInvalidEmailAddress(email);
-
-email.value = 'foo@bar.com;foo@bar.com';
-checkInvalidEmailAddress(email);
-
-email.value = '<foo@bar.com>, <foo@bar.com>';
+// Make sure setting multiple changes the value.
+email.multiple = false;
+email.value = "foo@bar.com, foo@bar.com";
 checkInvalidEmailAddress(email);
-
-email.value = 'foo@bar, foo@bar.com';
+email.multiple = true;
 checkValidEmailAddress(email);
 
-email.value = 'foo@bar.com, foo';
-checkInvalidEmailAddress(email);
-
-email.value = 'foo, foo@bar.com';
-checkInvalidEmailAddress(email);
-
 </script>
 </pre>
 </body>
 </html>
rename from content/html/content/test/test_bug630889.html
rename to content/html/content/test/forms/test_textarea_attributes_reflection.html
--- a/content/html/content/test/test_bug630889.html
+++ b/content/html/content/test/forms/test_textarea_attributes_reflection.html
@@ -1,28 +1,36 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=630889
--->
 <head>
-  <title>Test for Bug 630889</title>
+  <title>Test for HTMLTextAreaElement attributes reflection</title>
   <script type="application/javascript" src="/MochiKit/packed.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="reflect.js"></script>
+  <script type="application/javascript" src="../reflect.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=630889">Mozilla Bug 630889</a>
 <p id="display"></p>
 <pre id="test">
 <script type="application/javascript">
 
-/** Test for Bug 630889 **/
+/** Test for HTMLTextAreaElement attributes reflection **/
+
+var textarea = document.createElement("textarea");
 
-var textarea = document.createElement('textarea');
-reflectUnsignedInt(textarea, "rows", true, 2);
-reflectUnsignedInt(textarea, "cols", true, 20);
+reflectUnsignedInt({
+  element: textarea,
+  attribute: "rows",
+  nonZero: true,
+  defaultValue: 2,
+});
+
+reflectUnsignedInt({
+  element: textarea,
+  attribute: "cols",
+  nonZero: true,
+  defaultValue: 20,
+});
 
 </script>
 </pre>
 </body>
 </html>
--- a/content/html/content/test/reflect.js
+++ b/content/html/content/test/reflect.js
@@ -3,66 +3,78 @@
 
 /**
  * reflect.js is a collection of methods to test HTML attribute reflection.
  * Each of attribute is reflected differently, depending on various parameters,
  * see:
  * http://www.whatwg.org/html/#reflecting-content-attributes-in-idl-attributes
  *
  * Do not forget to add these line at the beginning of each new reflect* method:
- * ok(aAttr in aElement, aAttr + " should be an IDL attribute of this element");
- * is(typeof aElement[aAttr], <type>, aAttr + " IDL attribute should be a <type>");
+ * ok(attr in element, attr + " should be an IDL attribute of this element");
+ * is(typeof element[attr], <type>, attr + " IDL attribute should be a <type>");
  */
 
 /**
  * Checks that a given attribute is correctly reflected as a string.
  *
- * @param aElement      Element   node to test
- * @param aAttr         String    name of the attribute
- * @param aOtherValues  Array     other values to test in addition of the default ones [optional]
+ * @param aParameters   Object    object containing the parameters, which are:
+ *  - element           Element   node to test
+ *  - attribute         String    name of the attribute
+ *     OR
+ *    attribute         Object    object containing two attributes, 'content' and 'idl'
+ *  - otherValues       Array     [optional] other values to test in addition of the default ones
  */
-function reflectString(aElement, aAttr, aOtherValues)
+function reflectString(aParameters)
 {
-  var otherValues = aOtherValues !== undefined ? aOtherValues : [];
+  var element = aParameters.element;
+  var contentAttr = typeof aParameters.attribute === "string"
+                      ? aParameters.attribute : aParameters.attribute.content;
+  var idlAttr = typeof aParameters.attribute === "string"
+                  ? aParameters.attribute : aParameters.attribute.idl;
+  var otherValues = aParameters.otherValues !== undefined
+                      ? aParameters.otherValues : [];
 
-  ok(aAttr in aElement, aAttr + " should be an IDL attribute of this element");
-  is(typeof aElement[aAttr], "string", aAttr + " IDL attribute should be a string");
+  ok(idlAttr in element,
+     idlAttr + " should be an IDL attribute of this element");
+  is(typeof element[idlAttr], "string",
+     idlAttr + " IDL attribute should be a string");
 
   // Tests when the attribute isn't set.
-  is(aElement.getAttribute(aAttr), null,
-     "When not set, the content attribute should be undefined.");
-  is(aElement[aAttr], "",
+  is(element.getAttribute(contentAttr), null,
+     "When not set, the content attribute should be null.");
+  is(element[idlAttr], "",
      "When not set, the IDL attribute should return the empty string");
 
   /**
-   * TODO: as long as null stringification doesn't fallow the webidl specs,
-   * don't add it to the loop below and keep it here.
+   * TODO: as long as null stringification doesn't follow the WebIDL
+   * specifications, don't add it to the loop below and keep it here.
    */
-  aElement.setAttribute(aAttr, null);
-  todo_is(aElement.getAttribute(aAttr), "null",
+  element.setAttribute(contentAttr, null);
+  todo_is(element.getAttribute(contentAttr), "null",
      "null should have been stringified to 'null'");
-  todo_is(aElement[aAttr], "null",
+  todo_is(element[idlAttr], "null",
      "null should have been stringified to 'null'");
-  aElement.removeAttribute(aAttr);
+  element.removeAttribute(contentAttr);
 
-  aElement[aAttr] = null;
-  todo_is(aElement.getAttribute(aAttr), "null",
+  element[idlAttr] = null;
+  todo_is(element.getAttribute(contentAttr), "null",
      "null should have been stringified to 'null'");
-  todo_is(aElement[aAttr], "null",
+  todo_is(element[idlAttr], "null",
      "null should have been stringified to 'null'");
-  aElement.removeAttribute(aAttr);
+  element.removeAttribute(contentAttr);
 
   // Tests various strings.
   var stringsToTest = [
     // [ test value, expected result ]
     [ "", "" ],
     [ "null", "null" ],
     [ "undefined", "undefined" ],
     [ "foo", "foo" ],
-    [ aAttr, aAttr ],
+    [ contentAttr, contentAttr ],
+    [ idlAttr, idlAttr ],
     // TODO: uncomment this when null stringification will follow the specs.
     // [ null, "null" ],
     [ undefined, "undefined" ],
     [ true, "true" ],
     [ false, "false" ],
     [ 42, "42" ],
     // ES5, verse 8.12.8.
     [ { toString: function() { return "foo" } },
@@ -75,233 +87,250 @@ function reflectString(aElement, aAttr, 
     [ { valueOf: function() { return "foo" },
         toString: function() { return "bar" } },
       "bar" ]
   ];
 
   otherValues.forEach(function(v) { stringsToTest.push([v, v]) });
 
   stringsToTest.forEach(function([v, r]) {
-    aElement.setAttribute(aAttr, v);
-    is(aElement[aAttr], r,
+    element.setAttribute(contentAttr, v);
+    is(element[idlAttr], r,
        "IDL attribute should return the value it has been set to.");
-    is(aElement.getAttribute(aAttr), r,
+    is(element.getAttribute(contentAttr), r,
        "Content attribute should return the value it has been set to.");
-    aElement.removeAttribute(aAttr);
+    element.removeAttribute(contentAttr);
 
-    aElement[aAttr] = v;
-    is(aElement[aAttr], r,
+    element[idlAttr] = v;
+    is(element[idlAttr], r,
        "IDL attribute should return the value it has been set to.");
-    is(aElement.getAttribute(aAttr), r,
+    is(element.getAttribute(contentAttr), r,
        "Content attribute should return the value it has been set to.");
-    aElement.removeAttribute(aAttr);
+    element.removeAttribute(contentAttr);
   });
 
   // Tests after removeAttribute() is called. Should be equivalent with not set.
-  is(aElement.getAttribute(aAttr), null,
-     "When not set, the content attribute should be undefined.");
-  is(aElement[aAttr], "",
+  is(element.getAttribute(contentAttr), null,
+     "When not set, the content attribute should be null.");
+  is(element[idlAttr], "",
      "When not set, the IDL attribute should return the empty string");
 }
 
 /**
  * Checks that a given attribute name for a given element is correctly reflected
  * as an unsigned int.
+ *
+ * @param aParameters   Object    object containing the parameters, which are:
+ *  - element           Element   node to test on
+ *  - attribute         String    name of the attribute
+ *  - nonZero           Boolean   whether the attribute should be non-null
+ *  - defaultValue      Integer   [optional] default value, if different from the default one
  */
-function reflectUnsignedInt(aElement, aAttr, aNonNull, aDefault)
+function reflectUnsignedInt(aParameters)
 {
-  function checkGetter(aElement, aAttr, aValue)
-  {
-    is(aElement[aAttr], aValue, "." + aAttr + " should be equals " + aValue);
-    is(aElement.getAttribute(aAttr), aValue,
-       "@" + aAttr + " should be equals " + aValue);
-  }
+  var element = aParameters.element;
+  var attr = aParameters.attribute;
+  var nonZero = aParameters.nonZero;
+  var defaultValue = aParameters.defaultValue;
 
-  if (!aDefault) {
-    if (aNonNull) {
-      aDefault = 1;
+  if (defaultValue === undefined) {
+    if (nonZero) {
+      defaultValue = 1;
     } else {
-      aDefault = 0;
+      defaultValue = 0;
     }
   }
 
-  ok(aAttr in aElement, aAttr + " should be an IDL attribute of this element");
-  is(typeof aElement[aAttr], "number", aAttr + " IDL attribute should be a string");
+  ok(attr in element, attr + " should be an IDL attribute of this element");
+  is(typeof element[attr], "number", attr + " IDL attribute should be a number");
 
   // Check default value.
-  is(aElement[aAttr], aDefault, "default value should be " + aDefault);
-  ok(!aElement.hasAttribute(aAttr), aAttr + " shouldn't be present");
+  is(element[attr], defaultValue, "default value should be " + defaultValue);
+  ok(!element.hasAttribute(attr), attr + " shouldn't be present");
 
   var values = [ 1, 3, 42, 2147483647 ];
 
   for each (var value in values) {
-    aElement[aAttr] = value;
-    checkGetter(aElement, aAttr, value);
-  }
+    element[attr] = value;
+    is(element[attr], value, "." + attr + " should be equals " + value);
+    is(element.getAttribute(attr), value,
+       "@" + attr + " should be equals " + value);
 
-  for each (var value in values) {
-    aElement.setAttribute(aAttr, value);
-    checkGetter(aElement, aAttr, value);
+    element.setAttribute(attr, value);
+    is(element[attr], value, "." + attr + " should be equals " + value);
+    is(element.getAttribute(attr), value,
+       "@" + attr + " should be equals " + value);
   }
 
   // -3000000000 is equivalent to 1294967296 when using the IDL attribute.
-  aElement[aAttr] = -3000000000;
-  checkGetter(aElement, aAttr, 1294967296);
+  element[attr] = -3000000000;
+  is(element[attr], 1294967296, "." + attr + " should be equals to 1294967296");
+  is(element.getAttribute(attr), 1294967296,
+     "@" + attr + " should be equals to 1294967296");
+
   // When setting the content atribute, it's a string so it will be unvalid.
-  aElement.setAttribute(aAttr, -3000000000);
-  is(aElement.getAttribute(aAttr), -3000000000,
-     "@" + aAttr + " should be equals to " + -3000000000);
-  is(aElement[aAttr], aDefault,
-     "." + aAttr + " should be equals to " + aDefault);
+  element.setAttribute(attr, -3000000000);
+  is(element.getAttribute(attr), -3000000000,
+     "@" + attr + " should be equals to " + -3000000000);
+  is(element[attr], defaultValue,
+     "." + attr + " should be equals to " + defaultValue);
 
   var nonValidValues = [
     /* invalid value, value in the unsigned int range */
     [ -2147483648, 2147483648 ],
     [ -1,          4294967295 ],
     [ 3147483647,  3147483647 ],
   ];
 
   for each (var values in nonValidValues) {
-    aElement[aAttr] = values[0];
-    is(aElement.getAttribute(aAttr), values[1],
-       "@" + aAttr + " should be equals to " + values[1]);
-    is(aElement[aAttr], aDefault,
-       "." + aAttr + " should be equals to " + aDefault);
+    element[attr] = values[0];
+    is(element.getAttribute(attr), values[1],
+       "@" + attr + " should be equals to " + values[1]);
+    is(element[attr], defaultValue,
+       "." + attr + " should be equals to " + defaultValue);
   }
 
   for each (var values in nonValidValues) {
-    aElement.setAttribute(aAttr, values[0]);
-    is(aElement.getAttribute(aAttr), values[0],
-       "@" + aAttr + " should be equals to " + values[0]);
-    is(aElement[aAttr], aDefault,
-       "." + aAttr + " should be equals to " + aDefault);
+    element.setAttribute(attr, values[0]);
+    is(element.getAttribute(attr), values[0],
+       "@" + attr + " should be equals to " + values[0]);
+    is(element[attr], defaultValue,
+       "." + attr + " should be equals to " + defaultValue);
   }
 
-  // Setting to 0 should throw an error if aNonNull is true.
+  // Setting to 0 should throw an error if nonZero is true.
   var caught = false;
   try {
-    aElement[aAttr] = 0;
+    element[attr] = 0;
   } catch(e) {
     caught = true;
     is(e.code, DOMException.INDEX_SIZE_ERR, "exception should be INDEX_SIZE_ERR");
   }
 
-  if (aNonNull) {
+  if (nonZero) {
     ok(caught, "an exception should have been caught");
   } else {
     ok(!caught, "no exception should have been caught");
   }
 
-  // If 0 is set in @aAttr, it will be ignored when calling .aAttr.
-  aElement.setAttribute(aAttr, 0);
-  is(aElement.getAttribute(aAttr), 0, "@" + aAttr + " should be equals to 0");
-  if (aNonNull) {
-    is(aElement[aAttr], aDefault,
-       "." + aAttr + " should be equals to " + aDefault);
+  // If 0 is set in @attr, it will be ignored when calling .attr.
+  element.setAttribute(attr, 0);
+  is(element.getAttribute(attr), 0, "@" + attr + " should be equals to 0");
+  if (nonZero) {
+    is(element[attr], defaultValue,
+       "." + attr + " should be equals to " + defaultValue);
   } else {
-    is(aElement[aAttr], 0, "." + aAttr + " should be equals to 0");
+    is(element[attr], 0, "." + attr + " should be equals to 0");
   }
 }
 
 /**
- * @param aElement            Element     node to test on
- * @param aAttr               String      name of the attribute
- * @param aValidValues        Array       valid values we support
- * @param aInvalidValues      Array       invalid values
- * @param aDefaultValue       String      default value when no valid value is set [optional]
- * @param aUnsupportedValues  Array       valid values we do not support [optional]
+ * Checks that a given attribute is correctly reflected as limited to known
+ * values enumerated attribute.
+ *
+ * @param aParameters    Object    object containing the parameters, which are:
+ *  - element            Element   node to test on
+ *  - attribute          String    name of the attribute
+ *  - validValues        Array     valid values we support
+ *  - invalidValues      Array     invalid values
+ *  - defaultValue       String    [optional] default value when no valid value is set
+ *  - unsupportedValues  Array     [optional] valid values we do not support
  */
-function reflectLimitedEnumerated(aElement, aAttr, aValidValues, aInvalidValues,
-                                  aDefaultValue, aUnsupportedValues)
+function reflectLimitedEnumerated(aParameters)
 {
-  var defaultValue = aDefaultValue !== undefined ? aDefaultValue : "";
-  var unsupportedValues = aUnsupportedValues !== undefined ? aUnsupportedValues
-                                                           : [];
+  var element = aParameters.element;
+  var attr = aParameters.attribute;
+  var validValues = aParameters.validValues;
+  var invalidValues = aParameters.invalidValues;
+  var defaultValue = aParameters.defaultValue !== undefined
+    ? aParameters.defaultValue : "";
+  var unsupportedValues = aParameters.unsupportedValues !== undefined
+    ? aParameters.unsupportedValues : [];
 
-  ok(aAttr in aElement, aAttr + " should be an IDL attribute of this element");
-  is(typeof aElement[aAttr], "string", aAttr + " IDL attribute should be a string");
+  ok(attr in element, attr + " should be an IDL attribute of this element");
+  is(typeof element[attr], "string", attr + " IDL attribute should be a string");
 
   // Explicitly check the default value.
-  aElement.removeAttribute(aAttr);
-  is(aElement[aAttr], defaultValue,
+  element.removeAttribute(attr);
+  is(element[attr], defaultValue,
      "When no attribute is set, the value should be the default value.");
 
   // Check valid values.
-  aValidValues.forEach(function (v) {
-    aElement.setAttribute(aAttr, v);
-    is(aElement[aAttr], v,
-       v + " should be accepted as a valid value for " + aAttr);
-    is(aElement.getAttribute(aAttr), v,
+  validValues.forEach(function (v) {
+    element.setAttribute(attr, v);
+    is(element[attr], v,
+       v + " should be accepted as a valid value for " + attr);
+    is(element.getAttribute(attr), v,
        "Content attribute should return the value it has been set to.");
-    aElement.removeAttribute(aAttr);
+    element.removeAttribute(attr);
 
-    aElement.setAttribute(aAttr, v.toUpperCase());
-    is(aElement[aAttr], v,
+    element.setAttribute(attr, v.toUpperCase());
+    is(element[attr], v,
        "Enumerated attributes should be case-insensitive.");
-    is(aElement.getAttribute(aAttr), v.toUpperCase(),
+    is(element.getAttribute(attr), v.toUpperCase(),
        "Content attribute should not be lower-cased.");
-    aElement.removeAttribute(aAttr);
+    element.removeAttribute(attr);
 
-    aElement[aAttr] = v;
-    is(aElement[aAttr], v,
-       v + " should be accepted as a valid value for " + aAttr);
-    is(aElement.getAttribute(aAttr), v,
+    element[attr] = v;
+    is(element[attr], v,
+       v + " should be accepted as a valid value for " + attr);
+    is(element.getAttribute(attr), v,
        "Content attribute should return the value it has been set to.");
-    aElement.removeAttribute(aAttr);
+    element.removeAttribute(attr);
 
-    aElement[aAttr] = v.toUpperCase();
-    is(aElement[aAttr], v,
+    element[attr] = v.toUpperCase();
+    is(element[attr], v,
        "Enumerated attributes should be case-insensitive.");
-    is(aElement.getAttribute(aAttr), v.toUpperCase(),
+    is(element.getAttribute(attr), v.toUpperCase(),
        "Content attribute should not be lower-cased.");
-    aElement.removeAttribute(aAttr);
+    element.removeAttribute(attr);
   });
 
   // Check invalid values.
-  aInvalidValues.forEach(function (v) {
-    aElement.setAttribute(aAttr, v);
-    is(aElement[aAttr], defaultValue,
+  invalidValues.forEach(function (v) {
+    element.setAttribute(attr, v);
+    is(element[attr], defaultValue,
        "When the content attribute is set to an invalid value, the default value should be returned.");
-    is(aElement.getAttribute(aAttr), v,
+    is(element.getAttribute(attr), v,
        "Content attribute should not have been changed.");
-    aElement.removeAttribute(aAttr);
+    element.removeAttribute(attr);
 
-    aElement[aAttr] = v;
-    is(aElement[aAttr], defaultValue,
+    element[attr] = v;
+    is(element[attr], defaultValue,
        "When the value is set to an invalid value, the default value should be returned.");
-    is(aElement.getAttribute(aAttr), v,
+    is(element.getAttribute(attr), v,
        "Content attribute should not have been changed.");
-    aElement.removeAttribute(aAttr);
+    element.removeAttribute(attr);
   });
 
   // Check valid values we currently do not support.
   // Basically, it's like the checks for the valid values but with some todo's.
   unsupportedValues.forEach(function (v) {
-    aElement.setAttribute(aAttr, v);
-    todo_is(aElement[aAttr], v,
-            v + " should be accepted as a valid value for " + aAttr);
-    is(aElement.getAttribute(aAttr), v,
+    element.setAttribute(attr, v);
+    todo_is(element[attr], v,
+            v + " should be accepted as a valid value for " + attr);
+    is(element.getAttribute(attr), v,
        "Content attribute should return the value it has been set to.");
-    aElement.removeAttribute(aAttr);
+    element.removeAttribute(attr);
 
-    aElement.setAttribute(aAttr, v.toUpperCase());
-    todo_is(aElement[aAttr], v,
+    element.setAttribute(attr, v.toUpperCase());
+    todo_is(element[attr], v,
             "Enumerated attributes should be case-insensitive.");
-    is(aElement.getAttribute(aAttr), v.toUpperCase(),
+    is(element.getAttribute(attr), v.toUpperCase(),
        "Content attribute should not be lower-cased.");
-    aElement.removeAttribute(aAttr);
+    element.removeAttribute(attr);
 
-    aElement[aAttr] = v;
-    todo_is(aElement[aAttr], v,
-            v + " should be accepted as a valid value for " + aAttr);
-    is(aElement.getAttribute(aAttr), v,
+    element[attr] = v;
+    todo_is(element[attr], v,
+            v + " should be accepted as a valid value for " + attr);
+    is(element.getAttribute(attr), v,
        "Content attribute should return the value it has been set to.");
-    aElement.removeAttribute(aAttr);
+    element.removeAttribute(attr);
 
-    aElement[aAttr] = v.toUpperCase();
-    todo_is(aElement[aAttr], v,
+    element[attr] = v.toUpperCase();
+    todo_is(element[attr], v,
             "Enumerated attributes should be case-insensitive.");
-    is(aElement.getAttribute(aAttr), v.toUpperCase(),
+    is(element.getAttribute(attr), v.toUpperCase(),
        "Content attribute should not be lower-cased.");
-    aElement.removeAttribute(aAttr);
+    element.removeAttribute(attr);
   });
 }
 
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_bug586786.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=586786
+-->
+<head>
+  <title>Test for Bug 586786</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="reflect.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=586786">Mozilla Bug 586786</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 586786 **/
+
+var elements = ["col", "colgroup", "tbody", "tfoot", "thead", "tr", "td", "th"];
+
+for(var i = 0; i < elements.length; i++)
+{
+  reflectString({
+    element: document.createElement(elements[i]), 
+    attribute: "align",
+    otherValues: [ "left", "right", "center", "justify", "char" ]
+  });
+  
+  reflectString({
+    element: document.createElement(elements[i]), 
+    attribute: "vAlign",
+    otherValues: [ "top", "middle", "bottom", "baseline" ]
+  });
+  
+  reflectString({
+    element: document.createElement(elements[i]), 
+    attribute: {idl: "ch", content: "char"}
+  });
+}
+
+// table.border, table.width
+reflectString({
+  element: document.createElement("table"), 
+  attribute: "border"
+});
+
+reflectString({
+  element: document.createElement("table"), 
+  attribute: "width"
+});
+</script>
+</pre>
+</body>
+</html>
deleted file mode 100644
--- a/content/html/content/test/test_bug601061.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=601061
--->
-<head>
-  <title>Test for Bug 601061</title>
-  <script type="application/javascript" src="/MochiKit/packed.js"></script>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="reflect.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=601061">Mozilla Bug 601061</a>
-<p id="display"></p>
-<pre id="test">
-<script type="application/javascript">
-
-/** Test for Bug 601061 **/
-
-reflectUnsignedInt(document.createElement("input"), "size", true, 20);
-
-</script>
-</pre>
-</body>
-</html>
--- a/content/html/content/test/test_bug610212.html
+++ b/content/html/content/test/test_bug610212.html
@@ -17,15 +17,27 @@ https://bugzilla.mozilla.org/show_bug.cg
   
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 610212 **/
 
 var canvas = document.createElement('canvas');
-reflectUnsignedInt(canvas, "width", false, 300);
-reflectUnsignedInt(canvas, "height", false, 150);
+
+reflectUnsignedInt({
+  element: canvas,
+  attribute: "width",
+  nonZero: false,
+  defaultValue: 300,
+});
+
+reflectUnsignedInt({
+  element: canvas,
+  attribute: "height",
+  nonZero: false,
+  defaultValue: 150,
+});
 
 </script>
 </pre>
 </body>
 </html>
--- a/content/html/content/test/test_bug660663.html
+++ b/content/html/content/test/test_bug660663.html
@@ -14,18 +14,19 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=660663">Mozilla Bug 660663</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script type="application/javascript">
 /** Test for Bug 660663 **/
-reflectLimitedEnumerated(document.createElement("div"),
-                         "dir",
-                         ["ltr", "rtl"],
-                         ["cheesecake", ""],
-                         undefined, // There is no default value.
-                         ["auto"]);
+reflectLimitedEnumerated({
+  element: document.createElement("div"),
+  attribute: "dir",
+  validValues: ["ltr", "rtl"],
+  invalidValues: ["cheesecake", ""],
+  unsupportedValues: ["auto"]
+});
 </script>
 </pre>
 </body>
 </html>
--- a/content/html/document/src/ImageDocument.cpp
+++ b/content/html/document/src/ImageDocument.cpp
@@ -638,23 +638,42 @@ ImageDocument::HandleEvent(nsIDOMEvent* 
 
 nsresult
 ImageDocument::CreateSyntheticDocument()
 {
   // Synthesize an html document that refers to the image
   nsresult rv = MediaDocument::CreateSyntheticDocument();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // We must declare the image as a block element. If we stay as
+  // an inline element, our parent LineBox will be inline too and
+  // ignore the available height during reflow.
+  // This is bad during printing, it means tall image frames won't know
+  // the size of the paper and cannot break into continuations along
+  // multiple pages.
   Element* body = GetBodyElement();
   if (!body) {
     NS_WARNING("no body on image document!");
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
+  nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::style, nsnull,
+                                           kNameSpaceID_XHTML,
+                                           nsIDOMNode::ELEMENT_NODE);
+  NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
+  nsRefPtr<nsGenericHTMLElement> styleContent = NS_NewHTMLStyleElement(nodeInfo.forget());
+  if (!styleContent) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  styleContent->SetTextContent(NS_LITERAL_STRING("img { display: block; }"));
+  body->AppendChildTo(styleContent, PR_FALSE);
+
+  // Add the image element
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::img, nsnull,
                                            kNameSpaceID_XHTML,
                                            nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   mImageContent = NS_NewHTMLImageElement(nodeInfo.forget());
   if (!mImageContent) {
     return NS_ERROR_OUT_OF_MEMORY;
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -2165,45 +2165,28 @@ nsHTMLDocument::GetEmbeds(nsIDOMHTMLColl
 
   *aEmbeds = mEmbeds;
   NS_ADDREF(*aEmbeds);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLDocument::GetSelection(nsAString& aReturn)
+nsHTMLDocument::GetSelection(nsISelection** aReturn)
 {
-  aReturn.Truncate();
-
-  nsCOMPtr<nsIJSContextStack> stack = do_GetService("@mozilla.org/js/xpc/ContextStack;1");
-  JSContext* ccx = nsnull;
-  if (stack && NS_SUCCEEDED(stack->Peek(&ccx)) && ccx) {
-    JS_ReportWarning(ccx, "Deprecated method document.getSelection() called.  Please use window.getSelection() instead.");
-  }
-
   nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(GetScopeObject());
   nsCOMPtr<nsPIDOMWindow> pwin = do_QueryInterface(window);
   NS_ENSURE_TRUE(pwin, NS_OK);
   NS_ASSERTION(pwin->IsInnerWindow(), "Should have inner window here!");
   NS_ENSURE_TRUE(pwin->GetOuterWindow() &&
                  pwin->GetOuterWindow()->GetCurrentInnerWindow() == pwin,
                  NS_OK);
 
-  nsCOMPtr<nsISelection> selection;
-  nsresult rv = window->GetSelection(getter_AddRefs(selection));
-  NS_ENSURE_TRUE(selection && NS_SUCCEEDED(rv), rv);
-
-  nsXPIDLString str;
-
-  rv = selection->ToString(getter_Copies(str));
-
-  aReturn.Assign(str);
-
-  return rv;
+  return window->GetSelection(aReturn);
+  
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::CaptureEvents(PRInt32 aEventFlags)
 {
   ReportUseOfDeprecatedMethod(this, "UseOfCaptureEventsWarning");
   return NS_OK;
 }
--- a/content/media/nsAudioStream.h
+++ b/content/media/nsAudioStream.h
@@ -71,19 +71,21 @@ public:
   // AllocateStream will return either a local stream or a remoted stream
   // depending on where you call it from.  If you call this from a child process,
   // you may receive an implementation which forwards to a compositing process.
   static nsAudioStream* AllocateStream();
 
   // Initialize the audio stream. aNumChannels is the number of audio channels 
   // (1 for mono, 2 for stereo, etc) and aRate is the frequency of the sound 
   // samples (22050, 44100, etc).
+  // Unsafe to call with the decoder monitor held.
   virtual nsresult Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat) = 0;
 
   // Closes the stream. All future use of the stream is an error.
+  // Unsafe to call with the decoder monitor held.
   virtual void Shutdown() = 0;
 
   // Write sound data to the audio hardware.  aBuf is an array of samples in
   // the format specified by mFormat of length aCount.  aCount should be
   // evenly divisible by the number of channels in this audio stream.
   // When aBlocking is PR_TRUE, we'll block until the write has completed,
   // otherwise we'll buffer any data we can't write immediately, and write
   // it in a later call.
@@ -93,16 +95,17 @@ public:
   // without blocking.
   virtual PRUint32 Available() = 0;
 
   // Set the current volume of the audio playback. This is a value from
   // 0 (meaning muted) to 1 (meaning full volume).
   virtual void SetVolume(double aVolume) = 0;
 
   // Block until buffered audio data has been consumed.
+  // Unsafe to call with the decoder monitor held.
   virtual void Drain() = 0;
 
   // Pause audio playback
   virtual void Pause() = 0;
 
   // Resume audio playback
   virtual void Resume() = 0;
 
@@ -114,15 +117,16 @@ public:
   // the audio hardware.
   virtual PRInt64 GetSampleOffset() = 0;
 
   // Returns PR_TRUE when the audio stream is paused.
   virtual PRBool IsPaused() = 0;
 
   // Returns the minimum number of samples which must be written before
   // you can be sure that something will be played.
+  // Unsafe to call with the decoder monitor held.
   virtual PRInt32 GetMinWriteSamples() = 0;