Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Wed, 25 Jan 2012 15:27:24 -0800
changeset 86172 18f53c3f6fac1ab4e7aa1f9509dfd8521dc7981a
parent 85939 aec2f378af30cd816035b89478aa96d0ba730594 (current diff)
parent 86171 edf8075b0333a0ed7be2d77b1fd06bc87ca7bdec (diff)
child 86173 b2a4c499d052ad6d4da96dedca8667144bb6ab1a
push idunknown
push userunknown
push dateunknown
milestone12.0a1
Merge from mozilla-central.
.hgtags
accessible/src/base/nsAccessible.cpp
accessible/src/html/nsHTMLTableAccessible.cpp
accessible/src/mac/mozTextAccessible.mm
accessible/src/mac/nsAccessibleWrap.mm
b2g/installer/package-manifest.in
browser/base/content/browser.js
browser/base/content/tabbrowser.xml
browser/base/content/test/browser_sanitizeDialog.js
browser/components/nsBrowserGlue.js
browser/components/sessionstore/src/nsSessionStore.js
browser/devtools/highlighter/test/Makefile.in
browser/devtools/styleeditor/test/browser_styleeditor_sv_filter.js
browser/devtools/webconsole/test/browser_gcli_integrate.js
browser/devtools/webconsole/test/browser_webconsole_bug_642108_pruneTest.js
browser/themes/gnomestripe/newtab/strip.png
browser/themes/gnomestripe/newtab/toolbar.png
browser/themes/pinstripe/newtab/strip.png
browser/themes/pinstripe/newtab/toolbar.png
browser/themes/winstripe/newtab/strip.png
browser/themes/winstripe/newtab/toolbar.png
build/autoconf/mozconfig2client-mk
build/mobile/devicemanagerADB.py
build/mobile/robocop/robotium-solo-3.0.jar
config/autoconf.mk.in
configure.in
content/base/public/nsContentUtils.h
content/base/public/nsIDocument.h
content/base/public/nsINode.h
content/base/src/mozSanitizingSerializer.cpp
content/base/src/mozSanitizingSerializer.h
content/base/src/nsContentUtils.cpp
content/base/src/nsDocument.cpp
content/base/src/nsObjectLoadingContent.cpp
content/base/src/nsPlainTextSerializer.h
content/base/src/nsXMLHttpRequest.cpp
content/canvas/src/WebGLContext.cpp
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/WebGLContextUtils.cpp
content/canvas/src/nsCanvasRenderingContext2D.cpp
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
content/events/src/nsEventListenerManager.cpp
content/events/src/nsEventStateManager.cpp
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsHTMLAnchorElement.cpp
content/html/content/src/nsHTMLDNSPrefetch.cpp
content/html/content/src/nsHTMLDNSPrefetch.h
content/html/content/src/nsTextEditorState.cpp
content/html/document/src/MediaDocument.cpp
content/html/document/src/PluginDocument.cpp
content/html/document/src/nsHTMLContentSink.cpp
content/html/document/src/nsHTMLDocument.cpp
content/html/document/src/nsHTMLDocument.h
content/media/nsMediaDecoder.h
content/xbl/src/nsXBLBinding.cpp
content/xbl/src/nsXBLDocumentInfo.cpp
content/xbl/src/nsXBLPrototypeBinding.cpp
content/xul/content/src/nsXULElement.cpp
db/sqlite3/src/Makefile.in
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/base/nsFocusManager.cpp
dom/base/nsGlobalWindow.cpp
dom/indexedDB/AsyncConnectionHelper.cpp
dom/indexedDB/IDBCursor.cpp
dom/indexedDB/IDBDatabase.cpp
dom/indexedDB/IDBFactory.cpp
dom/indexedDB/IDBIndex.cpp
dom/indexedDB/IDBObjectStore.cpp
dom/indexedDB/IDBObjectStore.h
dom/indexedDB/IDBTransaction.cpp
dom/indexedDB/IndexedDatabaseManager.cpp
dom/interfaces/core/nsIDOMDOMError.idl
dom/interfaces/core/nsIDOMDOMErrorHandler.idl
dom/plugins/base/nsPluginStreamListenerPeer.cpp
dom/plugins/ipc/PluginModuleParent.cpp
editor/libeditor/html/nsHTMLEditRules.cpp
editor/libeditor/html/nsHTMLEditUtils.cpp
editor/libeditor/html/nsHTMLEditUtils.h
editor/libeditor/html/nsHTMLEditor.cpp
editor/libeditor/html/nsHTMLEditor.h
editor/libeditor/html/nsTableEditor.cpp
embedding/android/GeckoApp.java
embedding/android/GeckoAppShell.java
gfx/layers/basic/BasicLayers.cpp
image/decoders/nsBMPDecoder.cpp
intl/chardet/public/nsDocumentCharsetInfoCID.h
intl/chardet/public/nsIDocCharset.idl
intl/chardet/public/nsIDocumentCharsetInfo.idl
intl/chardet/src/nsDocumentCharsetInfo.cpp
intl/chardet/src/nsDocumentCharsetInfo.h
js/src/Makefile.in
js/src/MemoryMetrics.cpp
js/src/configure.in
js/src/frontend/BytecodeCompiler.cpp
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/BytecodeEmitter.h
js/src/frontend/FoldConstants.cpp
js/src/frontend/ParseNode.cpp
js/src/frontend/ParseNode.h
js/src/frontend/Parser.cpp
js/src/ion/Bailouts.cpp
js/src/ion/CodeGenerator.cpp
js/src/ion/Ion.cpp
js/src/ion/IonBuilder.cpp
js/src/ion/IonFrameIterator.h
js/src/ion/IonFrames.cpp
js/src/ion/IonFrames.h
js/src/ion/arm/MacroAssembler-arm.cpp
js/src/ion/arm/Trampoline-arm.cpp
js/src/ion/x64/MacroAssembler-x64.h
js/src/ion/x64/Trampoline-x64.cpp
js/src/ion/x86/MacroAssembler-x86.h
js/src/ion/x86/Trampoline-x86.cpp
js/src/jit-test/tests/basic/bug684796.js
js/src/jit-test/tests/basic/testBug650618.js
js/src/jit-test/tests/basic/testInitSharp.js
js/src/jit-test/tests/jaeger/bug580883.js
js/src/jit-test/tests/jaeger/bug606662-1.js
js/src/jsanalyze.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsatom.cpp
js/src/jsatom.h
js/src/jsatominlines.h
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscntxtinlines.h
js/src/jscompartment.cpp
js/src/jscompartment.h
js/src/jsdbgapi.cpp
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsfun.cpp
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsgcinlines.h
js/src/jsgcmark.cpp
js/src/jsgcmark.h
js/src/jsinfer.cpp
js/src/jsinfer.h
js/src/jsinferinlines.h
js/src/jsinterp.cpp
js/src/jsinterp.h
js/src/jsinterpinlines.h
js/src/jslock.cpp
js/src/jslocko.asm
js/src/jsnum.cpp
js/src/jsnum.h
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsopcode.cpp
js/src/jsopcode.h
js/src/jsopcode.tbl
js/src/jsprobes.cpp
js/src/jsproxy.cpp
js/src/jsprvtd.h
js/src/jsreflect.cpp
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jsstr.cpp
js/src/jsstr.h
js/src/jsxdrapi.h
js/src/jsxml.cpp
js/src/lock_sparcv8plus.il
js/src/lock_sparcv9.il
js/src/methodjit/Compiler.cpp
js/src/methodjit/FastOps.cpp
js/src/methodjit/InvokeHelpers.cpp
js/src/methodjit/LoopState.cpp
js/src/methodjit/MethodJIT.h
js/src/methodjit/StubCalls.cpp
js/src/shell/js.cpp
js/src/shell/jsworkers.cpp
js/src/tests/e4x/extensions/regress-335051.js
js/src/tests/js1_5/extensions/regress-367630.js
js/src/tests/js1_5/extensions/regress-368859.js
js/src/tests/js1_5/extensions/regress-379523.js
js/src/tests/js1_8_1/extensions/regress-452498-224.js
js/src/tests/js1_8_5/extensions/jstests.list
js/src/tests/js1_8_5/extensions/regress-613452.js
js/src/tests/js1_8_5/extensions/regress-630377.js
js/src/vm/RegExpObject-inl.h
js/src/vm/RegExpObject.h
js/src/vm/Stack.cpp
js/src/vm/Stack.h
js/src/vm/StackSpace.h
js/src/vm/String.cpp
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCThreadContext.cpp
js/xpconnect/src/XPCVariant.cpp
js/xpconnect/src/XPCWrappedJS.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/dom_quickstubs.qsconf
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/tests/chrome/test_ccbeginfail.xul
js/xpconnect/tests/chrome/test_ccdump.xul
layout/base/nsCaret.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/base/nsPresContext.h
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
layout/base/tests/Makefile.in
layout/build/Makefile.in
layout/forms/nsFieldSetFrame.cpp
layout/forms/nsListControlFrame.cpp
layout/forms/nsListControlFrame.h
layout/forms/nsProgressFrame.cpp
layout/forms/nsSelectsAreaFrame.cpp
layout/forms/nsTextControlFrame.cpp
layout/generic/TextOverflow.cpp
layout/generic/nsBRFrame.cpp
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockReflowState.cpp
layout/generic/nsBulletFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsHTMLReflowState.cpp
layout/generic/nsHTMLReflowState.h
layout/generic/nsIFrame.h
layout/generic/nsImageFrame.cpp
layout/generic/nsInlineFrame.cpp
layout/generic/nsLineLayout.cpp
layout/generic/nsTextFrame.h
layout/generic/nsTextFrameThebes.cpp
layout/mathml/nsMathMLChar.cpp
layout/printing/nsPrintEngine.cpp
layout/reftests/canvas/reftest.list
layout/reftests/svg/reftest.list
layout/style/nsCSSParser.cpp
layout/style/nsRuleNode.cpp
layout/style/nsRuleNode.h
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/svg/base/src/nsSVGContainerFrame.cpp
layout/svg/base/src/nsSVGGlyphFrame.cpp
layout/svg/base/src/nsSVGMarkerFrame.cpp
layout/svg/base/src/nsSVGTextFrame.cpp
layout/tables/BasicTableLayoutStrategy.cpp
layout/tables/nsTableFrame.cpp
layout/tables/nsTableOuterFrame.cpp
layout/xul/base/src/nsBox.cpp
layout/xul/base/src/nsXULPopupManager.cpp
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/Makefile.in
mobile/android/base/resources/drawable/checkerboard.png
mobile/xul/chrome/content/content.js
mozglue/android/APKOpen.cpp
netwerk/dns/nsDNSService2.cpp
netwerk/dns/nsHostResolver.cpp
netwerk/dns/nsHostResolver.h
netwerk/protocol/http/SpdySession.cpp
netwerk/protocol/http/SpdyStream.cpp
netwerk/protocol/http/nsHttpChannel.cpp
parser/html/nsHtml5TreeOperation.cpp
parser/htmlparser/public/nsIHTMLContentSink.h
parser/htmlparser/public/nsILoggingSink.h
parser/htmlparser/src/CNavDTD.cpp
parser/htmlparser/src/nsLoggingSink.cpp
parser/htmlparser/src/nsLoggingSink.h
parser/htmlparser/src/nsParserModule.cpp
testing/mochitest/runtestsremote.py
testing/xpcshell/xpcshell.ini
toolkit/components/autocomplete/nsAutoCompleteController.cpp
toolkit/components/places/History.cpp
toolkit/components/places/nsPlacesImportExportService.cpp
toolkit/components/telemetry/Telemetry.cpp
toolkit/components/telemetry/TelemetryPing.js
toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
toolkit/crashreporter/nsExceptionHandler.cpp
uriloader/exthandler/mac/nsOSHelperAppService.mm
uriloader/prefetch/nsPrefetchService.cpp
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/AndroidJNI.cpp
widget/android/nsWindow.cpp
widget/android/nsWindow.h
widget/windows/nsFilePicker.cpp
widget/windows/nsNativeThemeWin.cpp
xpcom/base/nsCycleCollector.cpp
xpcom/base/nsStackWalk.cpp
xpcom/ds/nsVariant.cpp
xpcom/glue/nsCOMPtr.h
xpcom/glue/nsCycleCollectionParticipant.h
xpcom/glue/nsStringAPI.h
--- a/.hgtags
+++ b/.hgtags
@@ -67,8 +67,9 @@ 9eae975b3d6fb7748fe5a3c0113d449b1c7cc0b2
 138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R14
 462c726144bc1fb45b61e774f64ac5d61b4e047c UPDATE_PACKAGING_R14
 5eb553dd2ceae5f88d80f27afc5ef3935c5d43b0 AURORA_BASE_20110705
 41b84b87c816403e1b74963d8094cff0406c989e AURORA_BASE_20110816
 c0983049bcaa9551e5f276d5a77ce154c151e0b0 AURORA_BASE_20110927
 462c726144bc1fb45b61e774f64ac5d61b4e047c UPDATE_PACKAGING_R15
 54bfd8bf682e295ffd7f22fa921ca343957b6c1c AURORA_BASE_20111108
 a8506ab2c65480cf2f85f54e203ea746522c62bb AURORA_BASE_20111220
+462c726144bc1fb45b61e774f64ac5d61b4e047c UPDATE_PACKAGING_R16
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -611,16 +611,19 @@ nsAccessible::VisibilityState()
 
     const nsIView* view = frame->GetView();
     if (view && view->GetVisibility() == nsViewVisibility_kHide)
       return vstates;
     
   } while (accessible = accessible->Parent());
 
   nsIFrame* frame = GetFrame();
+  if (!frame)
+    return vstates;
+
   const nsCOMPtr<nsIPresShell> shell(GetPresShell());
 
   // We need to know if at least a kMinPixels around the object is visible,
   // otherwise it will be marked states::OFFSCREEN.
   const PRUint16 kMinPixels  = 12;
   const nsSize frameSize = frame->GetSize();
   const nsRectVisibility rectVisibility =
     shell->GetRectVisibility(frame, nsRect(nsPoint(0,0), frameSize),
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -1340,17 +1340,17 @@ nsHTMLTableAccessible::HasDescendant(con
     return true;
 
   // Make sure that the item we found has contents and either has multiple
   // children or the found item is not a whitespace-only text node.
   nsCOMPtr<nsIContent> foundItemContent = do_QueryInterface(foundItem);
   if (foundItemContent->GetChildCount() > 1)
     return true; // Treat multiple child nodes as non-empty
 
-  nsIContent *innerItemContent = foundItemContent->GetChildAt(0);
+  nsIContent *innerItemContent = foundItemContent->GetFirstChild();
   if (innerItemContent && !innerItemContent->TextIsOnlyWhitespace())
     return true;
 
   // If we found more than one node then return true not depending on
   // aAllowEmpty flag.
   // XXX it might be dummy but bug 501375 where we changed this addresses
   // performance problems only. Note, currently 'aAllowEmpty' flag is used for
   // caption element only. On another hand we create accessible object for
--- a/accessible/src/mac/Makefile.in
+++ b/accessible/src/mac/Makefile.in
@@ -51,16 +51,17 @@ LIBXUL_LIBRARY = 1
 CMMSRCS = nsAccessNodeWrap.mm \
           nsDocAccessibleWrap.mm \
           nsRootAccessibleWrap.mm \
           nsAccessibleWrap.mm \
           mozAccessible.mm \
           mozDocAccessible.mm \
           mozActionElements.mm \
           mozTextAccessible.mm \
+          mozHTMLAccessible.mm \
           $(NULL)
           
 
 EXPORTS = \
   nsAccessNodeWrap.h \
   nsTextAccessibleWrap.h \
   nsAccessibleWrap.h \
   nsARIAGridAccessibleWrap.h \
new file mode 100644
--- /dev/null
+++ b/accessible/src/mac/mozHTMLAccessible.h
@@ -0,0 +1,45 @@
+/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=2:tabstop=2:
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2012
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Original Author: Hub Figuière <hub@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * 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 ***** */
+
+#import "mozAccessible.h"
+
+@interface mozHeadingAccessible : mozAccessible
+
+@end
new file mode 100644
--- /dev/null
+++ b/accessible/src/mac/mozHTMLAccessible.mm
@@ -0,0 +1,56 @@
+/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=2:tabstop=2:
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2012
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Original Author: Hub Figuière <hub@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * 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 ***** */
+
+#import "mozHTMLAccessible.h"
+
+#import "nsHyperTextAccessible.h"
+
+@implementation mozHeadingAccessible
+
+- (id)value
+{
+  if (!mGeckoAccessible || !mGeckoAccessible->IsHyperText())
+    return nil;
+
+  PRUint32 level = mGeckoAccessible->AsHyperText()->GetLevelInternal();
+  return [NSNumber numberWithInt:level];
+}
+
+@end
--- a/accessible/src/mac/mozTextAccessible.mm
+++ b/accessible/src/mac/mozTextAccessible.mm
@@ -1,22 +1,25 @@
 #include "nsAccessibleWrap.h"
+
+#include "nsCocoaUtils.h"
 #include "nsObjCExceptions.h"
 
 #import "mozTextAccessible.h"
 
 using namespace mozilla::a11y;
 
 @interface mozTextAccessible (Private)
 - (NSString*)subrole;
 - (NSString*)selectedText;
 - (NSValue*)selectedTextRange;
 - (long)textLength;
 - (BOOL)isReadOnly;
 - (void)setText:(NSString*)newText;
+- (NSString*)text;
 @end
 
 @implementation mozTextAccessible
 
 - (id)initWithAccessible:(nsAccessibleWrap*)accessible
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
@@ -74,18 +77,19 @@ using namespace mozilla::a11y;
   if ([attribute isEqualToString:NSAccessibilityNumberOfCharactersAttribute])
     return [NSNumber numberWithInt:[self textLength]];
   if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute])
     return [self selectedTextRange];
   if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute])
     return [self selectedText];
   // Apple's SpeechSynthesisServer expects AXValue to return an AXStaticText
   // object's AXSelectedText attribute.  See bug 674612.
+  // Also if there is no selected text, we return the full text.See bug 369710
   if ([attribute isEqualToString:NSAccessibilityValueAttribute])
-    return [self selectedText];
+    return [self selectedText] ? : [self text];
 
   // let mozAccessible handle all other attributes
   return [super accessibilityAttributeValue:attribute];
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute
@@ -153,16 +157,30 @@ using namespace mozilla::a11y;
 
   if (mGeckoEditableTextAccessible) {
     mGeckoEditableTextAccessible->SetTextContents(NS_ConvertUTF8toUTF16([newString UTF8String]));
   }
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
+- (NSString*)text
+{
+  if (!mGeckoTextAccessible)
+    return nil;
+    
+  nsAutoString text;
+  nsresult rv = 
+    mGeckoTextAccessible->GetText(0, nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT,
+				  text);
+  NS_ENSURE_SUCCESS(rv, nil);
+
+  return text.IsEmpty() ? nil : nsCocoaUtils::ToNSString(text);
+}
+
 - (long)textLength
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
 
   return mGeckoTextAccessible ? mGeckoTextAccessible->CharacterCount() : 0;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
 }
--- a/accessible/src/mac/nsAccessibleWrap.mm
+++ b/accessible/src/mac/nsAccessibleWrap.mm
@@ -40,16 +40,17 @@
 #include "nsObjCExceptions.h"
 
 #import "nsRoleMap.h"
 
 #include "Role.h"
 
 #import "mozAccessible.h"
 #import "mozActionElements.h"
+#import "mozHTMLAccessible.h"
 #import "mozTextAccessible.h"
 
 using namespace mozilla::a11y;
 
 nsAccessibleWrap::
   nsAccessibleWrap(nsIContent *aContent, nsIWeakReference *aShell) :
   nsAccessible(aContent, aShell), mNativeObject(nil),
   mNativeInited(false)
@@ -103,20 +104,22 @@ nsAccessibleWrap::GetNativeType ()
              [mozButtonAccessible class];
     }
     
     case roles::CHECKBUTTON:
       return [mozCheckboxAccessible class];
       
     case roles::AUTOCOMPLETE:
       return [mozComboboxAccessible class];
-      
+
+    case roles::HEADING:
+      return [mozHeadingAccessible class];
+
     case roles::ENTRY:
     case roles::STATICTEXT:
-    case roles::HEADING:
     case roles::LABEL:
     case roles::CAPTION:
     case roles::ACCEL_LABEL:
     case roles::TEXT_LEAF:
       // normal textfield (static or editable)
       return [mozTextAccessible class]; 
       
     case roles::COMBOBOX:
--- a/accessible/src/mac/nsRoleMap.h
+++ b/accessible/src/mac/nsRoleMap.h
@@ -142,17 +142,17 @@ static const NSString* AXRoles [] = {
   NSAccessibilityGroupRole,                     // ROLE_FOOTER
   NSAccessibilityGroupRole,                     // ROLE_PARAGRAPH
   @"AXRuler",                                   // ROLE_RULER. 10.4+ only, so we re-define the constant.
   NSAccessibilityComboBoxRole,                  // ROLE_AUTOCOMPLETE
   NSAccessibilityTextFieldRole,                 // ROLE_EDITBAR
   NSAccessibilityTextFieldRole,                 // ROLE_ENTRY
   NSAccessibilityStaticTextRole,                // ROLE_CAPTION
   @"AXWebArea",                                 // ROLE_DOCUMENT_FRAME
-  NSAccessibilityStaticTextRole,                // ROLE_HEADING
+  @"AXHeading",                                 // ROLE_HEADING
   NSAccessibilityGroupRole,                     // ROLE_PAGE
   NSAccessibilityGroupRole,                     // ROLE_SECTION
   NSAccessibilityUnknownRole,                   // ROLE_REDUNDANT_OBJECT
   NSAccessibilityGroupRole,                     // ROLE_FORM
   NSAccessibilityUnknownRole,                   // ROLE_IME
   NSAccessibilityUnknownRole,                   // ROLE_APP_ROOT. unused on OS X
   NSAccessibilityMenuItemRole,                  // ROLE_PARENT_MENUITEM
   NSAccessibilityGroupRole,                     // ROLE_CALENDAR
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -390,20 +390,18 @@
 @BINPATH@/components/contentSecurityPolicy.js
 @BINPATH@/components/contentAreaDropListener.manifest
 @BINPATH@/components/contentAreaDropListener.js
 @BINPATH@/components/messageWakeupService.js
 @BINPATH@/components/messageWakeupService.manifest
 @BINPATH@/components/nsFilePicker.js
 @BINPATH@/components/nsFilePicker.manifest
 #ifdef MOZ_B2G_RIL
-@BINPATH@/components/nsTelephonyWorker.manifest
-@BINPATH@/components/nsTelephonyWorker.js
-@BINPATH@/components/Telephony.manifest
-@BINPATH@/components/Telephony.js
+@BINPATH@/components/RadioInterfaceLayer.manifest
+@BINPATH@/components/RadioInterfaceLayer.js
 @BINPATH@/components/nsWifiWorker.js
 @BINPATH@/components/nsWifiWorker.manifest
 #endif
 #ifdef XP_MACOSX
 @BINPATH@/components/libalerts.dylib
 #endif
 #ifdef MOZ_ENABLE_DBUS
 @BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1496,16 +1496,18 @@ function prepareForStartup() {
   gBrowser.addEventListener("MozApplicationManifest",
                             OfflineApps, false);
 
   // setup simple gestures support
   gGestureSupport.init(true);
 }
 
 function delayedStartup(isLoadingBlank, mustLoadSidebar) {
+  Cu.import("resource:///modules/TelemetryTimestamps.jsm");
+  TelemetryTimestamps.add("delayedStartupStarted");
   gDelayedStartupTimeoutId = null;
 
   Services.obs.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
   Services.obs.addObserver(gXPInstallObserver, "addon-install-disabled", false);
   Services.obs.addObserver(gXPInstallObserver, "addon-install-started", false);
   Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked", false);
   Services.obs.addObserver(gXPInstallObserver, "addon-install-failed", false);
   Services.obs.addObserver(gXPInstallObserver, "addon-install-complete", false);
@@ -1760,16 +1762,17 @@ function delayedStartup(isLoadingBlank, 
                                              Ci.nsIPrefLocalizedString).data)
     document.getElementById("appmenu_charsetMenu").hidden = true;
 #endif
 
   window.addEventListener("mousemove", MousePosTracker, false);
   window.addEventListener("dragover", MousePosTracker, false);
 
   Services.obs.notifyObservers(window, "browser-delayed-startup-finished", "");
+  TelemetryTimestamps.add("delayedStartupFinished");
 }
 
 function BrowserShutdown() {
   // In certain scenarios it's possible for unload to be fired before onload,
   // (e.g. if the window is being closed after browser.js loads but before the
   // load completes). In that case, there's nothing to do here.
   if (!gStartupRan)
     return;
@@ -3104,30 +3107,23 @@ function FillInHTMLTooltip(tipElement)
     tipElement = tipElement.parentNode;
   }
 
   var tipNode = document.getElementById("aHTMLTooltip");
   tipNode.style.direction = direction;
 
   [titleText, XLinkTitleText, SVGTitleText].forEach(function (t) {
     if (t && /\S/.test(t)) {
-
-      // Per HTML 4.01 6.2 (CDATA section), literal CRs and tabs should be
-      // replaced with spaces, and LFs should be removed entirely.
-      // XXX Bug 322270: We don't preserve the result of entities like &#13;,
-      // which should result in a line break in the tooltip, because we can't
-      // distinguish that from a literal character in the source by this point.
-      t = t.replace(/[\r\t]/g, ' ');
-      t = t.replace(/\n/g, '');
+      // Make CRLF and CR render one line break each.  
+      t = t.replace(/\r\n?/g, '\n');
 
       tipNode.setAttribute("label", t);
       retVal = true;
     }
   });
-
   return retVal;
 }
 
 var browserDragAndDrop = {
   canDropLink: function (aEvent) Services.droppedLinkHandler.canDropLink(aEvent, true),
 
   dragOver: function (aEvent)
   {
@@ -5196,17 +5192,17 @@ nsBrowserAccess.prototype = {
         // Pass all params to openDialog to ensure that "url" isn't passed through
         // loadOneOrMoreURIs, which splits based on "|"
         newWindow = openDialog(getBrowserURL(), "_blank", "all,dialog=no", url, null, null, null);
         break;
       case Ci.nsIBrowserDOMWindow.OPEN_NEWTAB :
         let win, needToFocusWin;
 
         // try the current window.  if we're in a popup, fall back on the most recent browser window
-        if (!window.document.documentElement.getAttribute("chromehidden"))
+        if (window.toolbar.visible)
           win = window;
         else {
           win = Cc["@mozilla.org/browser/browserglue;1"]
                   .getService(Ci.nsIBrowserGlue)
                   .getMostRecentBrowserWindow();
           needToFocusWin = true;
         }
 
@@ -5968,22 +5964,22 @@ function handleDroppedLink(event, url, n
 };
 
 function MultiplexHandler(event)
 { try {
     var node = event.target;
     var name = node.getAttribute('name');
 
     if (name == 'detectorGroup') {
-        SetForcedDetector(true);
+        BrowserCharsetReload();
         SelectDetector(event, false);
     } else if (name == 'charsetGroup') {
         var charset = node.getAttribute('id');
         charset = charset.substring('charset.'.length, charset.length)
-        SetForcedCharset(charset);
+        BrowserSetForcedCharacterSet(charset);
     } else if (name == 'charsetCustomize') {
         //do nothing - please remove this else statement, once the charset prefs moves to the pref window
     } else {
         SetForcedCharset(node.getAttribute('id'));
     }
     } catch(ex) { alert(ex); }
 }
 
@@ -6004,42 +6000,29 @@ function SelectDetector(event, doReload)
         if (doReload)
           window.content.location.reload();
     }
     catch (ex) {
         dump("Failed to set the intl.charset.detector preference.\n");
     }
 }
 
-function SetForcedDetector(doReload)
-{
-    BrowserSetForcedDetector(doReload);
-}
-
-function SetForcedCharset(charset)
-{
-    BrowserSetForcedCharacterSet(charset);
-}
-
 function BrowserSetForcedCharacterSet(aCharset)
 {
-  var docCharset = gBrowser.docShell.QueryInterface(Ci.nsIDocCharset);
-  docCharset.charset = aCharset;
+  gBrowser.docShell.charset = aCharset;
   // Save the forced character-set
   PlacesUtils.history.setCharsetForURI(getWebNavigation().currentURI, aCharset);
+  BrowserCharsetReload();
+}
+
+function BrowserCharsetReload()
+{
   BrowserReloadWithFlags(nsIWebNavigation.LOAD_FLAGS_CHARSET_CHANGE);
 }
 
-function BrowserSetForcedDetector(doReload)
-{
-  gBrowser.documentCharsetInfo.forcedDetector = true;
-  if (doReload)
-    BrowserReloadWithFlags(nsIWebNavigation.LOAD_FLAGS_CHARSET_CHANGE);
-}
-
 function charsetMenuGetElement(parent, id) {
   return parent.getElementsByAttribute("id", id)[0];
 }
 
 function UpdateCurrentCharset(target) {
     // extract the charset from DOM
     var wnd = document.commandDispatcher.focusedWindow;
     if ((window == wnd) || (wnd == null)) wnd = window.content;
@@ -8917,19 +8900,20 @@ var TabContextMenu = {
 
     // Hide "Move to Group" if it's a pinned tab.
     document.getElementById("context_tabViewMenu").hidden =
       (this.contextTab.pinned || !TabView.firstUseExperienced);
   }
 };
 
 XPCOMUtils.defineLazyGetter(this, "HUDConsoleUI", function () {
-  Cu.import("resource:///modules/HUDService.jsm");
+  let tempScope = {};
+  Cu.import("resource:///modules/HUDService.jsm", tempScope);
   try {
-    return HUDService.consoleUI;
+    return tempScope.HUDService.consoleUI;
   }
   catch (ex) {
     Components.utils.reportError(ex);
   }
 });
 
 // Prompt user to restart the browser in safe mode 
 function safeModeRestart()
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2370,20 +2370,16 @@
       <property name="contentViewerEdit"
                 onget="return this.mCurrentBrowser.contentViewerEdit;"
                 readonly="true"/>
 
       <property name="contentViewerFile"
                 onget="return this.mCurrentBrowser.contentViewerFile;"
                 readonly="true"/>
 
-      <property name="documentCharsetInfo"
-                onget="return this.mCurrentBrowser.documentCharsetInfo;"
-                readonly="true"/>
-
       <property name="contentDocument"
                 onget="return this.mCurrentBrowser.contentDocument;"
                 readonly="true"/>
 
       <property name="contentTitle"
                 onget="return this.mCurrentBrowser.contentTitle;"
                 readonly="true"/>
 
@@ -3806,59 +3802,44 @@
         this.style.MozUserFocus = '';
       </handler>
     </handlers>
   </binding>
 
   <binding id="tabbrowser-alltabs-popup"
            extends="chrome://global/content/bindings/popup.xml#popup">
     <implementation implements="nsIDOMEventListener">
-      <method name="_menuItemOnCommand">
-        <parameter name="aEvent"/>
-        <body><![CDATA[
-          gBrowser.selectedTab = aEvent.target.tab;
-        ]]></body>
-      </method>
-
       <method name="_tabOnAttrModified">
         <parameter name="aEvent"/>
         <body><![CDATA[
           var tab = aEvent.target;
-          this._setMenuitemAttributes(tab.mCorrespondingMenuitem, tab);
+          if (tab.mCorrespondingMenuitem)
+            this._setMenuitemAttributes(tab.mCorrespondingMenuitem, tab);
         ]]></body>
       </method>
 
       <method name="_tabOnTabClose">
         <parameter name="aEvent"/>
         <body><![CDATA[
-          var menuItem = aEvent.target.mCorrespondingMenuitem;
-          if (menuItem)
-            this.removeChild(menuItem);
+          var tab = aEvent.target;
+          if (tab.mCorrespondingMenuitem)
+            this.removeChild(tab.mCorrespondingMenuitem);
         ]]></body>
       </method>
 
       <method name="handleEvent">
         <parameter name="aEvent"/>
         <body><![CDATA[
-          if (!aEvent.isTrusted)
-            return;
-
           switch (aEvent.type) {
-            case "command":
-              this._menuItemOnCommand(aEvent);
-              break;
             case "TabAttrModified":
               this._tabOnAttrModified(aEvent);
               break;
             case "TabClose":
               this._tabOnTabClose(aEvent);
               break;
-            case "TabOpen":
-              this._createTabMenuItem(aEvent.originalTarget);
-              break;
             case "scroll":
               this._updateTabsVisibilityStatus();
               break;
           }
         ]]></body>
       </method>
 
       <method name="_updateTabsVisibilityStatus">
@@ -3869,18 +3850,16 @@
             return;
 
           var tabstripBO = tabContainer.mTabstrip.scrollBoxObject;
           for (var i = 0; i < this.childNodes.length; i++) {
             let curTab = this.childNodes[i].tab;
             if (!curTab) // "Tab Groups" menuitem and its menuseparator
               continue;
             let curTabBO = curTab.boxObject;
-            if (!curTabBO) // "Tabs From Other Computers" menuitem
-              continue;
             if (curTabBO.screenX >= tabstripBO.screenX &&
                 curTabBO.screenX + curTabBO.width <= tabstripBO.screenX + tabstripBO.width)
               this.childNodes[i].setAttribute("tabIsVisible", "true");
             else
               this.childNodes[i].removeAttribute("tabIsVisible");
           }
         ]]></body>
       </method>
@@ -3891,24 +3870,20 @@
           var menuItem = document.createElementNS(
             "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
             "menuitem");
 
           menuItem.setAttribute("class", "menuitem-iconic alltabs-item menuitem-with-favicon");
 
           this._setMenuitemAttributes(menuItem, aTab);
 
-          // Keep some attributes of the menuitem in sync with its
-          // corresponding tab (e.g. the tab label)
           aTab.mCorrespondingMenuitem = menuItem;
           menuItem.tab = aTab;
-          menuItem.addEventListener("command", this, false);
 
           this.appendChild(menuItem);
-          return menuItem;
         ]]></body>
       </method>
 
       <method name="_setMenuitemAttributes">
         <parameter name="aMenuitem"/>
         <parameter name="aTab"/>
         <body><![CDATA[
           aMenuitem.setAttribute("label", aTab.label);
@@ -3933,46 +3908,43 @@
             aMenuitem.removeAttribute("selected");
         ]]></body>
       </method>
     </implementation>
 
     <handlers>
       <handler event="popupshowing">
       <![CDATA[
-        // set up the menu popup
         var tabcontainer = gBrowser.tabContainer;
-        let tabs = gBrowser.visibleTabs;
 
         // Listen for changes in the tab bar.
-        tabcontainer.addEventListener("TabOpen", this, false);
         tabcontainer.addEventListener("TabAttrModified", this, false);
         tabcontainer.addEventListener("TabClose", this, false);
         tabcontainer.mTabstrip.addEventListener("scroll", this, false);
 
+        let tabs = gBrowser.visibleTabs;
         for (var i = 0; i < tabs.length; i++) {
-          this._createTabMenuItem(tabs[i]);
+          if (!tabs[i].pinned)
+            this._createTabMenuItem(tabs[i]);
         }
         this._updateTabsVisibilityStatus();
       ]]></handler>
 
       <handler event="popuphidden">
       <![CDATA[
         // clear out the menu popup and remove the listeners
         for (let i = this.childNodes.length - 1; i > 0; i--) {
           let menuItem = this.childNodes[i];
           if (menuItem.tab) {
-            menuItem.removeEventListener("command", this, false);
             menuItem.tab.mCorrespondingMenuitem = null;
             this.removeChild(menuItem);
           }
         }
         var tabcontainer = gBrowser.tabContainer;
         tabcontainer.mTabstrip.removeEventListener("scroll", this, false);
-        tabcontainer.removeEventListener("TabOpen", this, false);
         tabcontainer.removeEventListener("TabAttrModified", this, false);
         tabcontainer.removeEventListener("TabClose", this, false);
       ]]></handler>
 
       <handler event="DOMMenuItemActive">
       <![CDATA[
         var tab = event.target.tab;
         if (tab) {
@@ -3983,16 +3955,21 @@
         }
       ]]></handler>
 
       <handler event="DOMMenuItemInactive">
       <![CDATA[
         XULBrowserWindow.setOverLink("", null);
       ]]></handler>
 
+      <handler event="command"><![CDATA[
+        if (event.target.tab)
+          gBrowser.selectedTab = event.target.tab;
+      ]]></handler>
+
     </handlers>
   </binding>
 
   <binding id="statuspanel" display="xul:hbox">
     <content>
       <xul:hbox class="statuspanel-inner">
         <xul:label class="statuspanel-label"
                    role="status"
--- a/browser/base/content/test/browser_bug329212.js
+++ b/browser/base/content/test/browser_bug329212.js
@@ -6,26 +6,26 @@ function test () {
 
     let doc = gBrowser.contentDocument;
     let tooltip = document.getElementById("aHTMLTooltip");
 
     ok(FillInHTMLTooltip(doc.getElementById("svg1"), "should get title"));
     is(tooltip.getAttribute("label"), "This is a non-root SVG element title");
 
     ok(FillInHTMLTooltip(doc.getElementById("text1"), "should get title"));
-    is(tooltip.getAttribute("label"), "    This            is a title    ");
+    is(tooltip.getAttribute("label"), "\n\n\n    This            is a title\n\n    ");
 
     ok(!FillInHTMLTooltip(doc.getElementById("text2"), "should not get title"));
 
     ok(!FillInHTMLTooltip(doc.getElementById("text3"), "should not get title"));
 
     ok(FillInHTMLTooltip(doc.getElementById("link1"), "should get title"));
-    is(tooltip.getAttribute("label"), "      This is a title    ");
+    is(tooltip.getAttribute("label"), "\n      This is a title\n    ");
     ok(FillInHTMLTooltip(doc.getElementById("text4"), "should get title"));
-    is(tooltip.getAttribute("label"), "      This is a title    ");
+    is(tooltip.getAttribute("label"), "\n      This is a title\n    ");
 
     ok(!FillInHTMLTooltip(doc.getElementById("link2"), "should not get title"));
 
     ok(FillInHTMLTooltip(doc.getElementById("link3"), "should get title"));
     ok(tooltip.getAttribute("label") != "");
 
     ok(FillInHTMLTooltip(doc.getElementById("link4"), "should get title"));
     is(tooltip.getAttribute("label"), "This is an xlink:title attribute");
--- a/browser/base/content/test/browser_clearplugindata.js
+++ b/browser/base/content/test/browser_clearplugindata.js
@@ -2,18 +2,20 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 // Test clearing plugin data using sanitize.js.
 const testURL1 = "http://mochi.test:8888/browser/browser/base/content/test/browser_clearplugindata.html";
 const testURL2 = "http://mochi.test:8888/browser/browser/base/content/test/browser_clearplugindata_noage.html";
 
+let tempScope = {};
 Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
-                                           .loadSubScript("chrome://browser/content/sanitize.js");
+                                           .loadSubScript("chrome://browser/content/sanitize.js", tempScope);
+let Sanitizer = tempScope.Sanitizer;
 
 const pluginHostIface = Ci.nsIPluginHost;
 var pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
 pluginHost.QueryInterface(pluginHostIface);
 
 var pluginTag;
 var s;
 
--- a/browser/base/content/test/browser_sanitize-passwordDisabledHosts.js
+++ b/browser/base/content/test/browser_sanitize-passwordDisabledHosts.js
@@ -1,13 +1,15 @@
 // Bug 474792 - Clear "Never remember passwords for this site" when
 // clearing site-specific settings in Clear Recent History dialog
 
+let tempScope = {};
 Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
-                                           .loadSubScript("chrome://browser/content/sanitize.js");
+                                           .loadSubScript("chrome://browser/content/sanitize.js", tempScope);
+let Sanitizer = tempScope.Sanitizer;
 
 function test() {
 
   var pwmgr = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
 
   // Add a disabled host
   pwmgr.setLoginSavingEnabled("http://example.com", false);
   
--- a/browser/base/content/test/browser_sanitize-sitepermissions.js
+++ b/browser/base/content/test/browser_sanitize-sitepermissions.js
@@ -1,12 +1,14 @@
 // Bug 380852 - Delete permission manager entries in Clear Recent History
 
+let tempScope = {};
 Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
-                                           .loadSubScript("chrome://browser/content/sanitize.js");
+                                           .loadSubScript("chrome://browser/content/sanitize.js", tempScope);
+let Sanitizer = tempScope.Sanitizer;
 
 function test() {
   
   // Add a permission entry
   var pm = Services.perms;
   pm.add(makeURI("http://example.com"), "testing", pm.ALLOW_ACTION);
   
   // Sanity check
--- a/browser/base/content/test/browser_sanitize-timespans.js
+++ b/browser/base/content/test/browser_sanitize-timespans.js
@@ -1,17 +1,19 @@
 // Bug 453440 - Test the timespan-based logic of the sanitizer code
 var now_uSec = Date.now() * 1000;
 
 const dm = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager);
 const bhist = Cc["@mozilla.org/browser/global-history;2"].getService(Ci.nsIBrowserHistory);
 const formhist = Cc["@mozilla.org/satchel/form-history;1"].getService(Ci.nsIFormHistory2);
 
+let tempScope = {};
 Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
-                                           .loadSubScript("chrome://browser/content/sanitize.js");
+                                           .loadSubScript("chrome://browser/content/sanitize.js", tempScope);
+let Sanitizer = tempScope.Sanitizer;
 
 function test() {
   
   var hoursSinceMidnight = new Date().getHours();
   var minutesSinceMidnight = hoursSinceMidnight * 60 + new Date().getMinutes();
 
   setupHistory();
   setupFormHistory();
--- a/browser/base/content/test/browser_sanitizeDialog.js
+++ b/browser/base/content/test/browser_sanitizeDialog.js
@@ -45,19 +45,20 @@
  * browser/base/content/test/browser_sanitize-timespans.js does that.  This
  * test checks the UI of the dialog and makes sure it's correctly connected to
  * the sanitize timespan code.
  *
  * Some of this code, especially the history creation parts, was taken from
  * browser/base/content/test/browser_sanitize-timespans.js.
  */
 
-Cc["@mozilla.org/moz/jssubscript-loader;1"].
-  getService(Ci.mozIJSSubScriptLoader).
-  loadSubScript("chrome://browser/content/sanitize.js");
+let tempScope = {};
+Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
+                                           .loadSubScript("chrome://browser/content/sanitize.js", tempScope);
+let Sanitizer = tempScope.Sanitizer;
 
 const dm = Cc["@mozilla.org/download-manager;1"].
            getService(Ci.nsIDownloadManager);
 const formhist = Cc["@mozilla.org/satchel/form-history;1"].
                  getService(Ci.nsIFormHistory2);
 
 // Add tests here.  Each is a function that's called by doNextTest().
 var gAllTests = [
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -51,17 +51,17 @@ function getBrowserURL()
   return "chrome://browser/content/browser.xul";
 }
 
 function getTopWin(skipPopups) {
   // If this is called in a browser window, use that window regardless of
   // whether it's the frontmost window, since commands can be executed in
   // background windows (bug 626148).
   if (top.document.documentElement.getAttribute("windowtype") == "navigator:browser" &&
-      (!skipPopups || !top.document.documentElement.getAttribute("chromehidden")))
+      (!skipPopups || top.toolbar.visible))
     return top;
 
   if (skipPopups) {
     return Components.classes["@mozilla.org/browser/browserglue;1"]
                      .getService(Components.interfaces.nsIBrowserGlue)
                      .getMostRecentBrowserWindow();
   }
   return Services.wm.getMostRecentWindow("navigator:browser");
@@ -201,17 +201,17 @@ function openLinkIn(url, where, params) 
     saveURL(url, null, null, true, null, aReferrerURI);
     return;
   }
   const Cc = Components.classes;
   const Ci = Components.interfaces;
 
   var w = getTopWin();
   if ((where == "tab" || where == "tabshifted") &&
-      w && w.document.documentElement.getAttribute("chromehidden")) {
+      w && !w.toolbar.visible) {
     w = getTopWin(true);
     aRelatedToCurrent = false;
   }
 
   if (!w || where == "window") {
     var sa = Cc["@mozilla.org/supports-array;1"].
              createInstance(Ci.nsISupportsArray);
 
index 85eb545601f66f0aada8d7d02144ae7627ef53aa..c09d6c1344f7b281220ca2e9c3a55b15e97c8472
GIT binary patch
literal 15364
zc%1E-&2Jk;6u{p&ZfqxRviWLBQ_4b=CWzD@P0}C>DUK6pB3dQFX_}}B>Du1d+t|C-
z?mB4+0i#Mt91sVPP?5M4i4#Z&^}+!aR1VFFONHox@)r<=0}=-$^JaIP*p5kPL8J=v
zlV;!S%$v9K-h6n+3jidNO9TN#0C0mX1us;^&C(7WOg3O5*dDYPHG?<d>XtYh4u`|x
z>^sC3?)v@h28Y9W459mj$Yhwwye$c<cQENJX(KQxG8twvZ%e}T985ZybTcV1DKZ&m
zGH*+^X%Tk#AneJ6oluCtq{w9Wp<L#0{#V#%cX2$e#bfER^ZSRG+=W6cY-#u+FP|M{
z8s5pc8Ns!G3!re@t{oqlo``8$n%K9o6(h@(zldeiieUx<KM+Ta^H8nJjd<rSDr!Po
ziD)@BVO)x)w3VomkYkcQZ{<zN%o!0$w`wLOGZka`DSQUz=a}|IC1Iu(g!a|dzB8wL
z#b96{u+}TC_6G-g#lGO++8TYB@U6S;8Q%+IQ_|WSZ|2{!{Vwh!aJV8M*KH3LSCqh3
zKo-aq@^+0!iL1*@%hFg*87WQ2n{K;Ai6=GIhVDjAmaLlPVvUITe#onuD#tW4V_7R|
z0wjQJwO|o+zFUmo&q8A{hMu~5@8O0<p{cp0we85!C)$s79B)6dAhg7!_)=1*VI9%Z
znjT5#<QXNdsZr%Mc|I-0<n)9Z(M(gz%$V|3lNK)s%@wU)krS_O7foHuqE2gt&RJcS
z)k{fTNlYv*8nQW4lAoQ!z^sg$a%Nmz)X@I2BCkwjO+{0UX<0W=&Puv2sYy9<t<3az
zMoP-VX+<&?ghtB<_I*;9sR8Q&(X13#)MV$-racgy;mdZ$(;4nzMa4S7v8`4d-mQ#V
zfGIi%6HSiq=sjNXC#7~cr)#=Yb*ZfX@}MyG92^30bvJBx*_Tz5RrPnrb$Wf{tNG$x
z0l~TGs8Fi+Z9j)jM4VRZ8%Kw*rpeC#`Z2KIP**qh|7pAXp^|2y%APjB2~07NAP!5A
z1RXTUfr?Yl2U(O!XvF$j7{*dsr=w;wbofhb`YUa=K%;+JOXo7O;V(w8m87T(ctx+g
z=jpJSnvoL6Mk}1Wd;iKB#ubO;+y`}bYhNPsC^1Do`Teu?jXOV;$JHZN27gpGmP{?n
zVtV)f&9Ap(`p1)2Oue)}nBD<+zYBdhRq8_Mf`RimWSDX`C95H3E>zn41~>wBWl{8D
zj5AhzkD>MR)(9vVaTDteNZ}jL7>r`9Ma#IK8TT{e{u1LYK>Pr0*sBKWA5HGg@GSGr
z4bQ?5+M0$1w0#{uf=}T~xDEH<0sKZ>q=g(OUF0P3ljli@jF5BW0+}W=WZv23JZYP7
z6t~Bx$^+;0LvedD?adFoc1c!=oA!o9e;2Ilp6lt>_y6vCdhb;ExF4|fG(%m$D|+RM
znpl{WtHyP+BWkTD$35{MuP4Wk`Spz(pO?pVul2OPxpoJ3t|#mdrh0(abLc}4b7AkL
zwA)G&zy(oj1<~>($d9^y=<GndRmSnZf0+pe27|rgz`z;$GBY?B=oS0>@MXq>2;V&H
z%S>hDB%GDm^7lQU@+Kw^i$oK=ggcXt(OkrKSO12EIJHnH*z<$K;cz&QH8r*n>Hq&P
z{`L2N4u^AqA<oh0Xau%C2=0I$qeM)Xiw$7+4*?GQ53n9q7J%(`VJ7po+^3HL{QS?)
b|NQ*V;cz${4u`|xa5x+ehr{7;4k&*D(Qxb<
index ea1c05db0dc9a467a75998c7673ce327a8b01971..360fd08066b0a0f695363cabafc776db28210f48
GIT binary patch
literal 15364
zc%1E7-%le&9RF@vY_UC9ehD0xbA{k>9%+lfku(}=4?T$9ffhN)amQ`jrQKt@+w5-X
zAyy&A2NU1U_~wK72dIhhMU5I?z{L1sjQ8M=H=oX&F}`W)cXwuKDHsmCh~CX7nSN$>
zX1+V$&&+prrV9XEET8HJ5COmkgoOa?3Li~7;Gx`riNp4wCu}o#F|xZQ1_lNO1_p*h
z2S>=~KiqCGFfjZFVXqG&<tXJ<!W=F4Q06Pz2$V(2QOc`?Ia<#{nWyZdEKn9HM=7ro
zri&Iw4<8(TGDlA+oIqKm9Nm}83=H=a$k|;SSM_8<-FAL|6O*r0N<^I+!PwJhM`?|~
zWYUUZ?0*bU`jnK8pP8OW=(@_0%S6G<(aP^7a;jol;qbSdr-rY+&+9`3<}N5&N-xCp
zyp}RA#xr^$uB7CIWL$FcmSpA4m}EF5laiH5(EJoW1M_pV_5~$nW#)yBm6d_hkM@cE
z;h}J`Ph1)7AL<ha`iF}}`(eW8zSgebV`EcN@uinn*NETlIs!+k1bKycuuxFKTY}7U
zSGiYf>Xf9mL~A)U%z~<GX}o&Ny|a`tGrEBn50g7eGObf9_WH!r<diJAB_ierVO7&L
zIiXuw$G%$=AO+l33#uu9-PQC*p}|$P?tXvZNPUCQ*woz8`aoNI$I;GX9mnT|=7f}7
zOdGb)XLMCJVrpKVQIfhAS6-0kg_d&hcvecwPpFDy&RFs_i<CE2HGfV{T`u36TFz~^
z;nX>6$g*}ZZ78XUg#}Z#W-9WtbEr^Z+>*27+JcVumlU}$k+T$CGpA+4M4pulL(<Z6
zZ26KZC1iC%i|Ll7XXk|mr!Dq<(va<Tj@@`pN-A2qd*l`wn(pWol9_1qd}%ZO;>*H&
zUP)&xb$PcS*u42eY3vl#VyzSPWoLppXLR=qZ|~;KpWb(`N(h`~o~lazVEH-r6vOGU
z`AeG}ca0?9{wvV8qxS^%zl(N1Qqe9_)zx}9jwt~WBw-QKV1N#J&~OR`A%~pCXcxc>
z=Rv`I1}sov8JeIoRADq!?SC@}p=n*sXJs?wYS_Z5P86uNvVn8<09d-25ywWW+}yZv
zwTQ~%^nd0JKW!aMWe*}N!1}_oI8uM6<Rv4OG8c)mbz-&rqq4bZ={c(E#*Ot)%Br?K
z?x-5D`-AB<fa^WzL$K0?$nz#n#E5Chxs0qusJTdG@9Uu*{8c&zQRl3q@lmvY&KU&-
zRkv^yOspls7>uIY4>{&T)O?7V4{Z~t8MqKYEB373_R&t=(O%-;)<hRP<vH&<zm@R`
zFlDbOb-wQCta}em!U*<a9(z-S*Wn#_7e0aw_#S?S-#IVW%pK!;YJRKvgRkYiyuf$x
zU3@p+!#~2G;`@jRkGpI>xLtI92;4==B1<3y$eo;$w8*k$zb~BMJ)`l1ukUO$ez@jd
z-KEiZ*>(bdZDr$@Zs0<`tFpH`<4!bsz7hX%G<v>U!;$)Gf6=&ktM~=%j7IDaCO^Q7
zdGz5Vb>TJwagRu}^^H3bXy7=cK|Xl=*|P*K?=qhM{${5?Jlx+W4h@~QH#@__;XZM2
z05>~z2;sB+Zg!gBDOAruZ5Gg@Ydf@*aJJ^Q?+@V$rngHaGUkplx6?|(v~JIdQYjfd
z(41pnU|?Xl6R061+W-GQ`S;)d85kJuVsQLud^84I9|U*6J}!wswtWD5e+cl9zq@+r
zy)cy9MJcZmKBSKU?EKHp|CP80&;JLIl7WGNfq{X6fq{X6fq{X6fq{YHe}caNn2h^T
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -169,17 +169,17 @@ BrowserGlue.prototype = {
       case "final-ui-startup":
         this._onProfileStartup();
         break;
       case "browser-delayed-startup-finished":
         this._onFirstWindowLoaded();
         Services.obs.removeObserver(this, "browser-delayed-startup-finished");
         break;
       case "sessionstore-windows-restored":
-        this._onBrowserStartup();
+        this._onWindowsRestored();
         break;
       case "browser:purge-session-history":
         // reset the console service's error buffer
         Services.console.logStringMessage(null); // clear the console (in case it's open)
         Services.console.reset();
         break;
       case "quit-application-requested":
         this._onQuitRequest(subject, data);
@@ -368,18 +368,18 @@ BrowserGlue.prototype = {
   },
 
   // profile shutdown handler (contains profile cleanup routines)
   _onProfileShutdown: function BG__onProfileShutdown() {
     this._shutdownPlaces();
     this._sanitizer.onShutdown();
   },
 
-  // Browser startup complete. All initial windows have opened.
-  _onBrowserStartup: function BG__onBrowserStartup() {
+  // All initial windows have opened.
+  _onWindowsRestored: function BG__onWindowsRestored() {
     // Show about:rights notification, if needed.
     if (this._shouldShowRights()) {
       this._showRightsNotification();
 #ifdef MOZ_TELEMETRY_REPORTING
     } else {
       // Only show telemetry notification when about:rights notification is not shown.
       this._showTelemetryNotification();
 #endif
@@ -1437,17 +1437,17 @@ BrowserGlue.prototype = {
 #ifndef XP_WIN
 #define BROKEN_WM_Z_ORDER
 #endif
 
   // this returns the most recent non-popup browser window
   getMostRecentBrowserWindow: function BG_getMostRecentBrowserWindow() {
     function isFullBrowserWindow(win) {
       return !win.closed &&
-             !win.document.documentElement.getAttribute("chromehidden");
+             win.toolbar.visible;
     }
 
 #ifdef BROKEN_WM_Z_ORDER
     var win = Services.wm.getMostRecentWindow("navigator:browser");
 
     // if we're lucky, this isn't a popup, and we can just return this
     if (win && !isFullBrowserWindow(win)) {
       win = null;
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -125,16 +125,18 @@ const TAB_EVENTS = ["TabOpen", "TabClose
 #define BROKEN_WM_Z_ORDER
 #endif
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 // debug.js adds NS_ASSERT. cf. bug 669196
 Cu.import("resource://gre/modules/debug.js");
 
+Cu.import("resource:///modules/TelemetryTimestamps.jsm");
+
 XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
   Cu.import("resource://gre/modules/NetUtil.jsm");
   return NetUtil;
 });
 
 XPCOMUtils.defineLazyGetter(this, "ScratchpadManager", function() {
   Cu.import("resource:///modules/devtools/scratchpad-manager.jsm");
   return ScratchpadManager;
@@ -289,16 +291,17 @@ SessionStoreService.prototype = {
   },
 
 /* ........ Global Event Handlers .............. */
 
   /**
    * Initialize the component
    */
   initService: function() {
+    TelemetryTimestamps.add("sessionRestoreInitialized");
     OBSERVING.forEach(function(aTopic) {
       Services.obs.addObserver(this, aTopic, true);
     }, this);
 
     var pbs = Cc["@mozilla.org/privatebrowsing;1"].
               getService(Ci.nsIPrivateBrowsingService);
     this._inPrivateBrowsing = pbs.privateBrowsingEnabled;
 
@@ -828,24 +831,25 @@ SessionStoreService.prototype = {
 
     // and create its internal data object
     this._internalWindows[aWindow.__SSi] = { hosts: {} }
 
     if (!this._isWindowLoaded(aWindow))
       this._windows[aWindow.__SSi]._restoring = true;
     if (!aWindow.toolbar.visible)
       this._windows[aWindow.__SSi].isPopup = true;
-    
+
     // perform additional initialization when the first window is loading
     if (this._loadState == STATE_STOPPED) {
       this._loadState = STATE_RUNNING;
       this._lastSaveTime = Date.now();
       
       // restore a crashed session resp. resume the last session if requested
       if (this._initialState) {
+        TelemetryTimestamps.add("sessionRestoreRestoring");
         // make sure that the restored tabs are first in the window
         this._initialState._firstTabs = true;
         this._restoreCount = this._initialState.windows ? this._initialState.windows.length : 0;
         this.restoreWindow(aWindow, this._initialState,
                            this._isCmdLineEmpty(aWindow, this._initialState));
         delete this._initialState;
         
         // _loadState changed from "stopped" to "running"
--- a/browser/components/sessionstore/test/browser_248970_b.js
+++ b/browser/components/sessionstore/test/browser_248970_b.js
@@ -43,17 +43,17 @@ function test() {
       return aLambda() || true;
     } catch(ex) { }
     return false;
   }
 
   var file = Components.classes["@mozilla.org/file/directory_service;1"]
              .getService(Components.interfaces.nsIProperties)
              .get("TmpD", Components.interfaces.nsIFile);
-  filePath = file.path;
+  var filePath = file.path;
 
   let fieldList = {
     "//input[@name='input']":     Date.now().toString(),
     "//input[@name='spaced 1']":  Math.random().toString(),
     "//input[3]":                 "three",
     "//input[@type='checkbox']":  true,
     "//input[@name='uncheck']":   false,
     "//input[@type='radio'][1]":  false,
--- a/browser/components/sessionstore/test/browser_346337.js
+++ b/browser/components/sessionstore/test/browser_346337.js
@@ -37,23 +37,23 @@
 function test() {
   /** Test for Bug 346337 **/
 
   var file = Components.classes["@mozilla.org/file/directory_service;1"]
                .getService(Components.interfaces.nsIProperties)
                .get("TmpD", Components.interfaces.nsILocalFile);
   file.append("346337_test1.file");
   file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
-  filePath1 = file.path;
+  var filePath1 = file.path;
   file = Components.classes["@mozilla.org/file/directory_service;1"]
              .getService(Components.interfaces.nsIProperties)
              .get("TmpD", Components.interfaces.nsILocalFile);
   file.append("346337_test2.file");
   file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
-  filePath2 = file.path;
+  var filePath2 = file.path;
   
   let fieldList = {
     "//input[@name='input']":     Date.now().toString(),
     "//input[@name='spaced 1']":  Math.random().toString(),
     "//input[3]":                 "three",
     "//input[@type='checkbox']":  true,
     "//input[@name='uncheck']":   false,
     "//input[@type='radio'][1]":  false,
--- a/browser/devtools/highlighter/TreePanel.jsm
+++ b/browser/devtools/highlighter/TreePanel.jsm
@@ -136,17 +136,17 @@ TreePanel.prototype = {
     this.treePanelDiv = this.treeBrowserDocument.createElement("div");
     this.treeBrowserDocument.body.appendChild(this.treePanelDiv);
     this.treePanelDiv.ownerPanel = this;
     this.ioBox = new InsideOutBox(this, this.treePanelDiv);
     this.ioBox.createObjectBox(this.IUI.win.document.documentElement);
     this.treeLoaded = true;
     this.treeIFrame.addEventListener("click", this.onTreeClick.bind(this), false);
     this.treeIFrame.addEventListener("dblclick", this.onTreeDblClick.bind(this), false);
-    this.treeIFrame.addEventListener("keypress", this.IUI, false);
+    this.treeIFrame.focus();
     delete this.initializingTreePanel;
     Services.obs.notifyObservers(null,
       this.IUI.INSPECTOR_NOTIFICATIONS.TREEPANELREADY, null);
     if (this.IUI.selection)
       this.select(this.IUI.selection, true);
   },
 
   /**
@@ -228,17 +228,17 @@ TreePanel.prototype = {
     treeBox.id = "inspector-tree-box";
     treeBox.state = "open"; // for the registerTools API.
     try {
       treeBox.height =
         Services.prefs.getIntPref("devtools.inspector.htmlHeight");
     } catch(e) {
       treeBox.height = 112;
     }
-                      
+
     treeBox.minHeight = 64;
     treeBox.flex = 1;
     toolbarParent.insertBefore(treeBox, toolbar);
 
     this.IUI.toolbar.setAttribute("treepanel-open", "true");
 
     treeBox.appendChild(this.treeIFrame);
 
@@ -461,19 +461,16 @@ TreePanel.prototype = {
     // position the editor
     editor.style.left = editorLeft + "px";
     editor.style.top = editorTop + "px";
 
     // set and select the text
     editorInput.value = aAttrVal;
     editorInput.select();
 
-    // remove tree key navigation events
-    this.treeIFrame.removeEventListener("keypress", this.IUI, false);
-
     // listen for editor specific events
     this.bindEditorEvent(editor, "click", function(aEvent) {
       aEvent.stopPropagation();
     });
     this.bindEditorEvent(editor, "dblclick", function(aEvent) {
       aEvent.stopPropagation();
     });
     this.bindEditorEvent(editor, "keypress",
@@ -556,19 +553,16 @@ TreePanel.prototype = {
     this.unbindEditorEvent(editor, "keypress");
 
     // clean up after the editor
     editorInput.value = "";
     editorInput.blur();
     this.editingContext = null;
     this.editingEvents = {};
 
-    // re-add navigation listener
-    this.treeIFrame.addEventListener("keypress", this.IUI, false);
-
     // event notification
     Services.obs.notifyObservers(null, this.IUI.INSPECTOR_NOTIFICATIONS.EDITOR_CLOSED,
                                   null);
   },
 
   /**
    * Commit the edits made in the editor, then close it.
    */
@@ -695,17 +689,16 @@ TreePanel.prototype = {
       this.treePanelDiv.ownerPanel = null;
       let parent = this.treePanelDiv.parentNode;
       parent.removeChild(this.treePanelDiv);
       delete this.treePanelDiv;
       delete this.treeBrowserDocument;
     }
 
     if (this.treeIFrame) {
-      this.treeIFrame.removeEventListener("keypress", this.IUI, false);
       this.treeIFrame.removeEventListener("dblclick", this.onTreeDblClick, false);
       this.treeIFrame.removeEventListener("click", this.onTreeClick, false);
       let parent = this.treeIFrame.parentNode;
       parent.removeChild(this.treeIFrame);
       delete this.treeIFrame;
     }
 
     if (this.ioBox) {
--- a/browser/devtools/highlighter/highlighter.jsm
+++ b/browser/devtools/highlighter/highlighter.jsm
@@ -693,22 +693,24 @@ Highlighter.prototype = {
     this.browser.removeEventListener("mousedown", this, true);
     this.browser.removeEventListener("mouseup", this, true);
   },
 
   attachPageListeners: function Highlighter_attachPageListeners()
   {
     this.browser.addEventListener("resize", this, true);
     this.browser.addEventListener("scroll", this, true);
+    this.browser.addEventListener("MozAfterPaint", this, true);
   },
 
   detachPageListeners: function Highlighter_detachPageListeners()
   {
     this.browser.removeEventListener("resize", this, true);
     this.browser.removeEventListener("scroll", this, true);
+    this.browser.removeEventListener("MozAfterPaint", this, true);
   },
 
   attachKeysListeners: function Highlighter_attachKeysListeners()
   {
     this.browser.addEventListener("keypress", this, true);
     this.highlighterContainer.addEventListener("keypress", this, true);
   },
 
@@ -729,98 +731,36 @@ Highlighter.prototype = {
     switch (aEvent.type) {
       case "click":
         this.handleClick(aEvent);
         break;
       case "mousemove":
         this.handleMouseMove(aEvent);
         break;
       case "resize":
+        this.computeZoomFactor();
+        break;
+      case "MozAfterPaint":
       case "scroll":
-        this.computeZoomFactor();
         this.brieflyDisableTransitions();
         this.invalidateSize();
         break;
       case "dblclick":
       case "mousedown":
       case "mouseup":
         aEvent.stopPropagation();
         aEvent.preventDefault();
         break;
-        break;
       case "keypress":
         switch (aEvent.keyCode) {
           case this.chromeWin.KeyEvent.DOM_VK_RETURN:
             this.locked ? this.unlock() : this.lock();
             aEvent.preventDefault();
             aEvent.stopPropagation();
             break;
-          case this.chromeWin.KeyEvent.DOM_VK_LEFT:
-            let node;
-            if (this.node) {
-              node = this.node.parentNode;
-            } else {
-              node = this.defaultSelection;
-            }
-            if (node && this.isNodeHighlightable(node)) {
-              this.highlight(node);
-            }
-            aEvent.preventDefault();
-            aEvent.stopPropagation();
-            break;
-          case this.chromeWin.KeyEvent.DOM_VK_RIGHT:
-            if (this.node) {
-              // Find the first child that is highlightable.
-              for (let i = 0; i < this.node.childNodes.length; i++) {
-                node = this.node.childNodes[i];
-                if (node && this.isNodeHighlightable(node)) {
-                  break;
-                }
-              }
-            } else {
-              node = this.defaultSelection;
-            }
-            if (node && this.isNodeHighlightable(node)) {
-              this.highlight(node, true);
-            }
-            aEvent.preventDefault();
-            aEvent.stopPropagation();
-            break;
-          case this.chromeWin.KeyEvent.DOM_VK_UP:
-            if (this.node) {
-              // Find a previous sibling that is highlightable.
-              node = this.node.previousSibling;
-              while (node && !this.isNodeHighlightable(node)) {
-                node = node.previousSibling;
-              }
-            } else {
-              node = this.defaultSelection;
-            }
-            if (node && this.isNodeHighlightable(node)) {
-              this.highlight(node, true);
-            }
-            aEvent.preventDefault();
-            aEvent.stopPropagation();
-            break;
-          case this.chromeWin.KeyEvent.DOM_VK_DOWN:
-            if (this.node) {
-              // Find a next sibling that is highlightable.
-              node = this.node.nextSibling;
-              while (node && !this.isNodeHighlightable(node)) {
-                node = node.nextSibling;
-              }
-            } else {
-              node = this.defaultSelection;
-            }
-            if (node && this.isNodeHighlightable(node)) {
-              this.highlight(node, true);
-            }
-            aEvent.preventDefault();
-            aEvent.stopPropagation();
-            break;
         }
     }
   },
 
   /**
    * Disable the CSS transitions for a short time to avoid laggy animations
    * during scrolling or resizing.
    */
--- a/browser/devtools/highlighter/inspector.jsm
+++ b/browser/devtools/highlighter/inspector.jsm
@@ -281,16 +281,18 @@ InspectorUI.prototype = {
     this.isDirty = false;
 
     this.progressListener = new InspectorProgressListener(this);
 
     this.chromeWin.addEventListener("keypress", this, false);
 
     // initialize the highlighter
     this.highlighter = new Highlighter(this.chromeWin);
+
+    this.setupNavigationKeys();
     this.highlighterReady();
   },
 
   /**
    * Register the Rule View in the Sidebar.
    */
   registerRuleView: function IUI_registerRuleView()
   {
@@ -345,16 +347,46 @@ InspectorUI.prototype = {
       this.store.setValue(this.winID, "selectedNode", null);
       this.store.setValue(this.winID, "inspecting", true);
       this.store.setValue(this.winID, "isDirty", this.isDirty);
       this.win.addEventListener("pagehide", this, true);
     }
   },
 
   /**
+   * Browse nodes according to the breadcrumbs layout, only for some specific
+   * elements of the UI.
+   */
+   setupNavigationKeys: function IUI_setupNavigationKeys()
+   {
+     // UI elements that are arrow keys sensitive:
+     // - highlighter veil;
+     // - content window (when the highlighter `veil is pointer-events:none`;
+     // - the Inspector toolbar.
+
+     this.onKeypress = this.onKeypress.bind(this);
+
+     this.highlighter.highlighterContainer.addEventListener("keypress",
+       this.onKeypress, true);
+     this.win.addEventListener("keypress", this.onKeypress, true);
+     this.toolbar.addEventListener("keypress", this.onKeypress, true);
+   },
+
+  /**
+   * Remove the event listeners for the arrowkeys.
+   */
+   removeNavigationKeys: function IUI_removeNavigationKeys()
+   {
+      this.highlighter.highlighterContainer.removeEventListener("keypress",
+        this.onKeypress, true);
+      this.win.removeEventListener("keypress", this.onKeypress, true);
+      this.toolbar.removeEventListener("keypress", this.onKeypress, true);
+   },
+
+  /**
    * Close inspector UI and associated panels. Unhighlight and stop inspecting.
    * Remove event listeners for document scrolling, resize,
    * tabContainer.TabSelect and others.
    *
    * @param boolean aKeepStore
    *        Tells if you want the store associated to the current tab/window to
    *        be cleared or not. Set this to true to not clear the store, or false
    *        otherwise.
@@ -370,16 +402,18 @@ InspectorUI.prototype = {
       return;
     }
 
     let winId = new String(this.winID); // retain this to notify observers.
 
     this.closing = true;
     this.toolbar.hidden = true;
 
+    this.removeNavigationKeys();
+
     this.progressListener.destroy();
     delete this.progressListener;
 
     if (!aKeepStore) {
       this.store.deleteStore(this.winID);
       this.win.removeEventListener("pagehide", this, true);
     } else {
       // Update the store before closing.
@@ -587,16 +621,24 @@ InspectorUI.prototype = {
           }
         }
 
         if (this.store.isEmpty()) {
           this.tabbrowser.tabContainer.removeEventListener("TabSelect", this,
                                                          false);
         }
         break;
+      case "keypress":
+        switch (event.keyCode) {
+          case this.chromeWin.KeyEvent.DOM_VK_ESCAPE:
+            this.closeInspectorUI(false);
+            event.preventDefault();
+            event.stopPropagation();
+            break;
+      }
       case "pagehide":
         win = event.originalTarget.defaultView;
         // Skip iframes/frames.
         if (!win || win.frameElement || win.top != win) {
           break;
         }
 
         win.removeEventListener(event.type, this, true);
@@ -606,28 +648,76 @@ InspectorUI.prototype = {
           this.store.deleteStore(winID);
         }
 
         if (this.store.isEmpty()) {
           this.tabbrowser.tabContainer.removeEventListener("TabSelect", this,
                                                          false);
         }
         break;
-      case "keypress":
-        switch (event.keyCode) {
-          case this.chromeWin.KeyEvent.DOM_VK_ESCAPE:
-            this.closeInspectorUI(false);
-            event.preventDefault();
-            event.stopPropagation();
-            break;
+    }
+  },
+
+  /*
+   * handles "keypress" events.
+  */
+  onKeypress: function IUI_onKeypress(event)
+  {
+    let node = null;
+    let bc = this.breadcrumbs;
+    switch (event.keyCode) {
+      case this.chromeWin.KeyEvent.DOM_VK_LEFT:
+        if (bc.currentIndex != 0)
+          node = bc.nodeHierarchy[bc.currentIndex - 1].node;
+        if (node && this.highlighter.isNodeHighlightable(node))
+          this.highlighter.highlight(node);
+        event.preventDefault();
+        event.stopPropagation();
+        break;
+      case this.chromeWin.KeyEvent.DOM_VK_RIGHT:
+        if (bc.currentIndex < bc.nodeHierarchy.length - 1)
+          node = bc.nodeHierarchy[bc.currentIndex + 1].node;
+        if (node && this.highlighter.isNodeHighlightable(node)) {
+          this.highlighter.highlight(node);
         }
+        event.preventDefault();
+        event.stopPropagation();
+        break;
+      case this.chromeWin.KeyEvent.DOM_VK_UP:
+        if (this.selection) {
+          // Find a previous sibling that is highlightable.
+          node = this.selection.previousSibling;
+          while (node && !this.highlighter.isNodeHighlightable(node)) {
+            node = node.previousSibling;
+          }
+        }
+        if (node && this.highlighter.isNodeHighlightable(node)) {
+          this.highlighter.highlight(node, true);
+        }
+        event.preventDefault();
+        event.stopPropagation();
+        break;
+      case this.chromeWin.KeyEvent.DOM_VK_DOWN:
+        if (this.selection) {
+          // Find a next sibling that is highlightable.
+          node = this.selection.nextSibling;
+          while (node && !this.highlighter.isNodeHighlightable(node)) {
+            node = node.nextSibling;
+          }
+        }
+        if (node && this.highlighter.isNodeHighlightable(node)) {
+          this.highlighter.highlight(node, true);
+        }
+        event.preventDefault();
+        event.stopPropagation();
         break;
     }
   },
 
+
   /////////////////////////////////////////////////////////////////////////
   //// CssRuleView methods
 
   /**
    * Is the cssRuleView open?
    */
   isRuleViewOpen: function IUI_isRuleViewOpen()
   {
@@ -1715,16 +1805,18 @@ HTMLBreadcrumbs.prototype = {
   setCursor: function BC_setCursor(aIdx)
   {
     // Unselect the previously selected button
     if (this.currentIndex > -1 && this.currentIndex < this.nodeHierarchy.length) {
       this.nodeHierarchy[this.currentIndex].button.removeAttribute("checked");
     }
     if (aIdx > -1) {
       this.nodeHierarchy[aIdx].button.setAttribute("checked", "true");
+      if (this.hadFocus)
+        this.nodeHierarchy[aIdx].button.focus();
     }
     this.currentIndex = aIdx;
   },
 
   /**
    * Get the index of the node in the cache.
    *
    * @param aNode
@@ -1890,16 +1982,20 @@ HTMLBreadcrumbs.prototype = {
 
   /**
    * Update the breadcrumbs display when a new node is selected.
    */
   update: function BC_update()
   {
     this.menu.hidePopup();
 
+    let cmdDispatcher = this.IUI.chromeDoc.commandDispatcher;
+    this.hadFocus = (cmdDispatcher.focusedElement &&
+                     cmdDispatcher.focusedElement.parentNode == this.container);
+
     let selection = this.IUI.selection;
     let idx = this.indexOf(selection);
 
     // Is the node already displayed in the breadcrumbs?
     if (idx > -1) {
       // Yes. We select it.
       this.setCursor(idx);
     } else {
@@ -1919,17 +2015,18 @@ HTMLBreadcrumbs.prototype = {
       idx = this.indexOf(selection);
       this.setCursor(idx);
     }
     // Add the first child of the very last node of the breadcrumbs if possible.
     this.ensureFirstChild();
 
     // Make sure the selected node and its neighbours are visible.
     this.scroll();
-  }
+  },
+
 }
 
 /////////////////////////////////////////////////////////////////////////
 //// Initializers
 
 XPCOMUtils.defineLazyGetter(InspectorUI.prototype, "strings",
   function () {
     return Services.strings.createBundle(
--- a/browser/devtools/highlighter/test/Makefile.in
+++ b/browser/devtools/highlighter/test/Makefile.in
@@ -64,16 +64,17 @@ include $(topsrcdir)/config/rules.mk
 		browser_inspector_bug_672902_keyboard_shortcuts.js \
 		browser_inspector_keybindings.js \
 		browser_inspector_breadcrumbs.html \
 		browser_inspector_breadcrumbs.js \
 		browser_inspector_bug_699308_iframe_navigation.js \
 		browser_inspector_changes.js \
 		browser_inspector_ruleviewstore.js \
 		browser_inspector_duplicate_ruleview.js \
+		browser_inspector_invalidate.js \
 		head.js \
 		$(NULL)
 
 # Disabled due to constant failures
 # 		browser_inspector_treePanel_click.js \
 
 libs::	$(_BROWSER_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/highlighter/test/browser_inspector_invalidate.js
@@ -0,0 +1,52 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+let doc;
+let div;
+
+function createDocument()
+{
+  div = doc.createElement("div");
+  div.setAttribute("style", "width: 100px; height: 100px;");
+  doc.body.appendChild(div);
+
+  Services.obs.addObserver(runTest,
+    InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
+  InspectorUI.toggleInspectorUI();
+}
+
+function runTest(subject)
+{
+  Services.obs.removeObserver(runTest,
+    InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
+
+  InspectorUI.highlighter.highlight(div);
+
+  executeSoon(function() {
+    let veilBoxDims = InspectorUI.highlighter.veilTransparentBox;
+    is(veilBoxDims.style.width, "100px", "selection has the right width");
+
+    div.style.width = "200px";
+    setTimeout(function () {
+      let veilBoxDims = InspectorUI.highlighter.veilTransparentBox;
+      is(veilBoxDims.style.width, "200px", "selection updated");
+      InspectorUI.closeInspectorUI();
+      gBrowser.removeCurrentTab();
+      finish();
+    }, 1000);
+  });
+}
+
+function test()
+{
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function() {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+    doc = content.document;
+    waitForFocus(createDocument, content);
+  }, true);
+
+  content.location = "data:text/html,basic tests for inspector";
+}
+
--- a/browser/devtools/highlighter/test/browser_inspector_ruleviewstore.js
+++ b/browser/devtools/highlighter/test/browser_inspector_ruleviewstore.js
@@ -87,18 +87,17 @@ function inspectorUIOpen1()
 
 function ruleViewOpened1()
 {
   let prop = InspectorUI.ruleView._elementStyle.rules[0].textProps[0];
   is(prop.name, "background-color", "First prop is the background color prop.");
   prop.setEnabled(false);
 
   // Open second tab and switch to it
-  tab2 = gBrowser.addTab();
-  gBrowser.selectedTab = tab2;
+  gBrowser.selectedTab = gBrowser.addTab();
 
   gBrowser.selectedBrowser.addEventListener("load", function(evt) {
     gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
                                                  true);
     waitForFocus(inspectorTabOpen2, content);
   }, true);
   content.location = "data:text/html,<p>tab 2: the inspector should close now";
 }
--- a/browser/devtools/highlighter/test/head.js
+++ b/browser/devtools/highlighter/test/head.js
@@ -32,17 +32,19 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 const Cu = Components.utils;
-Cu.import("resource:///modules/devtools/LayoutHelpers.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/devtools/LayoutHelpers.jsm", tempScope);
+let LayoutHelpers = tempScope.LayoutHelpers;
 
 function isHighlighting()
 {
   let veil = InspectorUI.highlighter.veilTransparentBox;
   return !(veil.style.visibility == "hidden");
 }
 
 function getHighlitNode()
--- a/browser/devtools/scratchpad/test/browser_scratchpad_bug684546_reset_undo.js
+++ b/browser/devtools/scratchpad/test/browser_scratchpad_bug684546_reset_undo.js
@@ -1,14 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-Cu.import("resource://gre/modules/NetUtil.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
+let tempScope = {};
+Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
+Cu.import("resource://gre/modules/FileUtils.jsm", tempScope);
+let NetUtil = tempScope.NetUtil;
+let FileUtils = tempScope.FileUtils;
 
 // Reference to the Scratchpad chrome window object.
 let gScratchpadWindow;
 
 // Reference to the Scratchpad object.
 let gScratchpad;
 
 // Reference to the temporary nsIFile we will work with.
--- a/browser/devtools/scratchpad/test/browser_scratchpad_bug_653427_confirm_close.js
+++ b/browser/devtools/scratchpad/test/browser_scratchpad_bug_653427_confirm_close.js
@@ -1,15 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-
-Cu.import("resource://gre/modules/NetUtil.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
+let tempScope = {};
+Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
+Cu.import("resource://gre/modules/FileUtils.jsm", tempScope);
+let NetUtil = tempScope.NetUtil;
+let FileUtils = tempScope.FileUtils;
 
 // only finish() when correct number of tests are done
 const expected = 5;
 var count = 0;
 function done()
 {
   if (++count == expected) {
     cleanup();
--- a/browser/devtools/scratchpad/test/browser_scratchpad_bug_699130_edit_ui_updates.js
+++ b/browser/devtools/scratchpad/test/browser_scratchpad_bug_699130_edit_ui_updates.js
@@ -1,15 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-Cu.import("resource:///modules/source-editor.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/source-editor.jsm", tempScope);
+let SourceEditor = tempScope.SourceEditor;
 
 function test()
 {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
     gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
--- a/browser/devtools/scratchpad/test/browser_scratchpad_contexts.js
+++ b/browser/devtools/scratchpad/test/browser_scratchpad_contexts.js
@@ -70,16 +70,17 @@ function runTests()
   ok(sp.getText(), "window.foobarBug636725 = 'aloha2';",
      "setText() worked");
 
   ok(!window.foobarBug636725, "no window.foobarBug636725");
 
   sp.run();
 
   is(window.foobarBug636725, "aloha2", "window.foobarBug636725 has been set");
+  delete window.foobarBug636725;
 
   sp.setText("gBrowser", 7);
 
   ok(sp.getText(), "window.gBrowser",
      "setText() worked with no end for the replace range");
 
   is(typeof sp.run()[2].addTab, "function",
      "chrome context has access to chrome objects");
--- a/browser/devtools/scratchpad/test/browser_scratchpad_files.js
+++ b/browser/devtools/scratchpad/test/browser_scratchpad_files.js
@@ -1,14 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-Cu.import("resource://gre/modules/NetUtil.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
+let tempScope = {};
+Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
+Cu.import("resource://gre/modules/FileUtils.jsm", tempScope);
+let NetUtil = tempScope.NetUtil;
+let FileUtils = tempScope.FileUtils;
 
 // Reference to the Scratchpad object.
 let gScratchpad;
 
 // Reference to the temporary nsIFile we will work with.
 let gFile;
 
 // The temporary file content.
--- a/browser/devtools/shared/SplitView.jsm
+++ b/browser/devtools/shared/SplitView.jsm
@@ -64,21 +64,16 @@ function SplitView(aRoot)
   this._root = aRoot;
   this._controller = aRoot.querySelector(".splitview-controller");
   this._nav = aRoot.querySelector(".splitview-nav");
   this._side = aRoot.querySelector(".splitview-side-details");
   this._activeSummary = null
 
   this._mql = aRoot.ownerDocument.defaultView.matchMedia(LANDSCAPE_MEDIA_QUERY);
 
-  this._filter = aRoot.querySelector(".splitview-filter");
-  if (this._filter) {
-    this._setupFilterBox();
-  }
-
   // items list focus and search-on-type handling
   this._nav.addEventListener("keydown", function onKeyCatchAll(aEvent) {
     function getFocusedItemWithin(nav) {
       let node = nav.ownerDocument.activeElement;
       while (node && node.parentNode != nav) {
         node = node.parentNode;
       }
       return node;
@@ -111,23 +106,16 @@ function SplitView(aRoot)
     if (newFocusOrdinal !== undefined) {
       aEvent.stopPropagation();
       let el = this.getSummaryElementByOrdinal(newFocusOrdinal);
       if (el) {
         el.focus();
       }
       return false;
     }
-
-    // search-on-type when any non-whitespace character is pressed while list
-    // has the focus
-    if (this._filter &&
-        !/\s/.test(String.fromCharCode(aEvent.which))) {
-      this._filter.focus();
-    }
   }.bind(this), false);
 }
 
 SplitView.prototype = {
   /**
     * Retrieve whether the UI currently has a landscape orientation.
     *
     * @return boolean
@@ -222,20 +210,16 @@ SplitView.prototype = {
    *     - function(DOMElement summary, DOMElement details, object data) onCreate
    *         Called when the item has been added.
    *     - function(summary, details, data) onShow
    *         Called when the item is shown/active.
    *     - function(summary, details, data) onHide
    *         Called when the item is hidden/inactive.
    *     - function(summary, details, data) onDestroy
    *         Called when the item has been removed.
-   *     - function(summary, details, data, query) onFilterBy
-   *         Called when the user performs a filtering search.
-   *         If the function returns false, the item does not match query
-   *         string and will be hidden.
    *     - object data
    *         Object to pass to the callbacks above.
    *     - number ordinal
    *         Items with a lower ordinal are displayed before those with a
    *         higher ordinal.
    */
   appendItem: function ASV_appendItem(aSummary, aDetails, aOptions)
   {
@@ -323,81 +307,16 @@ SplitView.prototype = {
   removeAll: function ASV_removeAll()
   {
     while (this._nav.hasChildNodes()) {
       this.removeItem(this._nav.firstChild);
     }
   },
 
   /**
-    * Filter items by given string.
-    * Matching is performed on every item by calling onFilterBy when defined
-    * and then by searching aQuery in the summary element's text item.
-    * Non-matching item is hidden.
-    *
-    * If no item matches, 'splitview-all-filtered' class is set on the filter
-    * input element and the splitview-nav element.
-    *
-    * @param string aQuery
-    *        The query string. Use null to reset (no filter).
-    * @return number
-    *         The number of filtered (non-matching) item.
-    */
-  filterItemsBy: function ASV_filterItemsBy(aQuery)
-  {
-    if (!this._nav.hasChildNodes()) {
-      return 0;
-    }
-    if (aQuery) {
-      aQuery = aQuery.trim();
-    }
-    if (!aQuery) {
-      for (let i = 0; i < this._nav.childNodes.length; ++i) {
-        this._nav.childNodes[i].classList.remove("splitview-filtered");
-      }
-      this._filter.classList.remove("splitview-all-filtered");
-      this._nav.classList.remove("splitview-all-filtered");
-      return 0;
-    }
-
-    let count = 0;
-    let filteredCount = 0;
-    for (let i = 0; i < this._nav.childNodes.length; ++i) {
-      let summary = this._nav.childNodes[i];
-
-      let matches = false;
-      let binding = summary.getUserData(BINDING_USERDATA);
-      if (binding.onFilterBy) {
-        matches = binding.onFilterBy(summary, binding._details, binding.data, aQuery);
-      }
-      if (!matches) { // try text content
-        let content = summary.textContent.toUpperCase();
-        matches = (content.indexOf(aQuery.toUpperCase()) > -1);
-      }
-
-      count++;
-      if (!matches) {
-        summary.classList.add("splitview-filtered");
-        filteredCount++;
-      } else {
-        summary.classList.remove("splitview-filtered");
-      }
-    }
-
-    if (count > 0 && filteredCount == count) {
-      this._filter.classList.add("splitview-all-filtered");
-      this._nav.classList.add("splitview-all-filtered");
-    } else {
-      this._filter.classList.remove("splitview-all-filtered");
-      this._nav.classList.remove("splitview-all-filtered");
-    }
-    return filteredCount;
-  },
-
-  /**
    * Set the item's CSS class name.
    * This sets the class on both the summary and details elements, retaining
    * any SplitView-specific classes.
    *
    * @param DOMElement aSummary
    *        Summary element of the item to set.
    * @param string aClassName
    *        One or more space-separated CSS classes.
@@ -410,44 +329,9 @@ SplitView.prototype = {
     viewSpecific = aSummary.className.match(/(splitview\-[\w-]+)/g);
     viewSpecific = viewSpecific ? viewSpecific.join(" ") : "";
     aSummary.className = viewSpecific + " " + aClassName;
 
     viewSpecific = binding._details.className.match(/(splitview\-[\w-]+)/g);
     viewSpecific = viewSpecific ? viewSpecific.join(" ") : "";
     binding._details.className = viewSpecific + " " + aClassName;
   },
-
-  /**
-   * Set up filter search box.
-   */
-  _setupFilterBox: function ASV__setupFilterBox()
-  {
-    let clearFilter = function clearFilter(aEvent) {
-      this._filter.value = "";
-      this.filterItemsBy("");
-      return false;
-    }.bind(this);
-
-    this._filter.addEventListener("command", function onFilterInput(aEvent) {
-      this.filterItemsBy(this._filter.value);
-    }.bind(this), false);
-
-    this._filter.addEventListener("keyup", function onFilterKeyUp(aEvent) {
-      if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) {
-        clearFilter();
-      }
-      if (aEvent.keyCode == aEvent.DOM_VK_ENTER ||
-          aEvent.keyCode == aEvent.DOM_VK_RETURN) {
-        // autofocus matching item if there is only one
-        let matches = this._nav.querySelectorAll("* > li:not(.splitview-filtered)");
-        if (matches.length == 1) {
-          this.activeSummary = matches[0];
-        }
-      }
-    }.bind(this), false);
-
-    let clearButtons = this._root.querySelectorAll(".splitview-filter-clearButton");
-    for (let i = 0; i < clearButtons.length; ++i) {
-      clearButtons[i].addEventListener("click", clearFilter, false);
-    }
-  }
 };
--- a/browser/devtools/shared/splitview.css
+++ b/browser/devtools/shared/splitview.css
@@ -53,16 +53,17 @@ box,
 .splitview-controller,
 .splitview-main {
   -moz-box-flex: 0;
 }
 
 .splitview-controller {
   min-height: 3em;
   max-height: 14em;
+  max-width: 400px;
 }
 
 .splitview-nav {
   display: -moz-box;
   overflow-x: hidden;
   overflow-y: auto;
 }
 
@@ -118,9 +119,13 @@ ol.splitview-nav > li.splitview-filtered
 @media (max-aspect-ratio: 5/3) {
   #splitview-details-toolbar {
     display: none;
   }
 
   .splitview-portrait-resizer {
     display: -moz-box;
   }
+
+  .splitview-controller {
+    max-width: none;
+  }
 }
--- a/browser/devtools/shared/test/browser_promise_basic.js
+++ b/browser/devtools/shared/test/browser_promise_basic.js
@@ -1,14 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that our Promise implementation works properly
 
-Cu.import("resource:///modules/devtools/Promise.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/devtools/Promise.jsm", tempScope);
+let Promise = tempScope.Promise;
 
 function test() {
   addTab("about:blank", function() {
     info("Starting Promise Tests");
     testBasic();
   });
 }
 
--- a/browser/devtools/shared/test/browser_templater_basic.js
+++ b/browser/devtools/shared/test/browser_templater_basic.js
@@ -1,15 +1,18 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that the DOM Template engine works properly
 
-Cu.import("resource:///modules/devtools/Templater.jsm");
-Cu.import("resource:///modules/devtools/Promise.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/devtools/Templater.jsm", tempScope);
+Cu.import("resource:///modules/devtools/Promise.jsm", tempScope);
+let template = tempScope.template;
+let Promise = tempScope.Promise;
 
 function test() {
   addTab("http://example.com/browser/browser/devtools/shared/test/browser_templater_basic.html", function() {
     info("Starting DOM Templater Tests");
     runTest(0);
   });
 }
 
--- a/browser/devtools/sourceeditor/orion/README
+++ b/browser/devtools/sourceeditor/orion/README
@@ -10,16 +10,18 @@ To upgrade Orion to a newer version see 
 
 Orion version: git clone from 2011-12-09
                commit hash d8a6dc01d9c561d6eb99f03b64c8c78ce785c59d
   + patch for Eclipse Bug 366312 - right-clicking outside of the selection causes the caret to move
     https://github.com/mihaisucan/orion.client/tree/bug-366312
       see https://bugs.eclipse.org/bugs/show_bug.cgi?id=366312
   + patch for Mozilla Bug 711737 - Orion should support all the CSS properties from CSS1, CSS2, CSS2.1 and CSS3
     https://bugzilla.mozilla.org/show_bug.cgi?id=711737
+  + patch for Mozilla Bug 719028 - Style Editor does not highlight a few CSS2.0 and CSS3 properties
+    https://bugzilla.mozilla.org/show_bug.cgi?id=719028
 
 # License
 
 The following files are licensed according to the contents in the LICENSE
 file:
   orion.js
   orion.css
 
--- a/browser/devtools/sourceeditor/orion/orion.js
+++ b/browser/devtools/sourceeditor/orion/orion.js
@@ -5,16 +5,17 @@
  * available under the terms of the Eclipse Public License v1.0 
  * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution 
  * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html). 
  * 
  * Contributors: 
  *		Felipe Heidrich (IBM Corporation) - initial API and implementation
  *		Silenio Quarti (IBM Corporation) - initial API and implementation
  *		Mihai Sucan (Mozilla Foundation) - fix for Bug#364214
+ *		Alex Lakatos (Mozilla Contributor) - fix for Mozilla Bug#719028
  */
 
 /*global window */
 
 /**
  * Evaluates the definition function and mixes in the returned module with
  * the module specified by <code>moduleName</code>.
  * <p>
@@ -10483,23 +10484,24 @@ define(['orion/textview/annotations'], f
 		 "border-radius", "border-right", "border-right-color", "border-right-style", "border-right-width", "border-spacing", "border-style",
 		 "border-top", "border-top-color", "border-top-left-radius", "border-top-right-radius", "border-top-style", "border-top-width",
 		 "border-width", "bottom", "box-align", "box-decoration-break", "box-direction", "box-flex", "box-flex-group", "box-lines",
 		 "box-ordinal-group", "box-orient", "box-pack", "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
 		 "caption-side", "clear", "clip", "color", "color-profile", "column-count", "column-fill", "column-gap", "column-rule",
 		 "column-rule-color", "column-rule-style", "column-rule-width", "column-span", "column-width", "columns", "content", "counter-increment",
 		 "counter-reset", "crop", "cue", "cue-after", "cue-before", "cursor", "direction", "display", "dominant-baseline",
 		 "drop-initial-after-adjust", "drop-initial-after-align", "drop-initial-before-adjust", "drop-initial-before-align", "drop-initial-size",
-		 "drop-initial-value", "elevation", "empty-cells", "fit", "fit-position", "float", "float-offset", "font", "font-family", "font-size",
-		 "font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "grid-columns", "grid-rows", "hanging-punctuation",
-		 "height", "hyphenate-after", "hyphenate-before", "hyphenate-character", "hyphenate-lines", "hyphenate-resource", "hyphens", "icon",
-		 "image-orientation", "image-rendering", "image-resolution", "inline-box-align", "left", "letter-spacing", "line-height",
-		 "line-stacking", "line-stacking-ruby", "line-stacking-shift", "line-stacking-strategy", "list-style", "list-style-image",
-		 "list-style-position", "list-style-type", "margin", "margin-bottom", "margin-left", "margin-right", "margin-top", "mark", "mark-after",
-		 "mark-before", "marks", "marquee-direction", "marquee-loop", "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
+		 "drop-initial-value", "elevation", "empty-cells", "fit", "fit-position", "flex-align", "flex-flow", "flex-inline-pack", "flex-order",
+		 "flex-pack", "float", "float-offset", "font", "font-family", "font-size", "font-size-adjust", "font-stretch", "font-style",
+		 "font-variant", "font-weight", "grid-columns", "grid-rows", "hanging-punctuation", "height", "hyphenate-after",
+		 "hyphenate-before", "hyphenate-character", "hyphenate-lines", "hyphenate-resource", "hyphens", "icon", "image-orientation",
+		 "image-rendering", "image-resolution", "inline-box-align", "left", "letter-spacing", "line-height", "line-stacking",
+		 "line-stacking-ruby", "line-stacking-shift", "line-stacking-strategy", "list-style", "list-style-image", "list-style-position",
+		 "list-style-type", "margin", "margin-bottom", "margin-left", "margin-right", "margin-top", "mark", "mark-after", "mark-before",
+		 "marker-offset", "marks", "marquee-direction", "marquee-loop", "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
 		 "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index", "nav-left", "nav-right", "nav-up", "opacity", "orphans",
 		 "outline", "outline-color", "outline-offset", "outline-style", "outline-width", "overflow", "overflow-style", "overflow-x",
 		 "overflow-y", "padding", "padding-bottom", "padding-left", "padding-right", "padding-top", "page", "page-break-after", "page-break-before",
 		 "page-break-inside", "page-policy", "pause", "pause-after", "pause-before", "perspective", "perspective-origin", "phonemes", "pitch",
 		 "pitch-range", "play-during", "position", "presentation-level", "punctuation-trim", "quotes", "rendering-intent", "resize",
 		 "rest", "rest-after", "rest-before", "richness", "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang", "ruby-position",
 		 "ruby-span", "size", "speak", "speak-header", "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set", "table-layout",
 		 "target", "target-name", "target-new", "target-position", "text-align", "text-align-last", "text-decoration", "text-emphasis",
--- a/browser/devtools/sourceeditor/test/browser_bug650345_find.js
+++ b/browser/devtools/sourceeditor/test/browser_bug650345_find.js
@@ -1,15 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-Cu.import("resource:///modules/source-editor.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/source-editor.jsm", tempScope);
+let SourceEditor = tempScope.SourceEditor;
 
 let testWin;
 let editor;
 
 function test()
 {
   waitForExplicitFinish();
 
--- a/browser/devtools/sourceeditor/test/browser_bug684546_reset_undo.js
+++ b/browser/devtools/sourceeditor/test/browser_bug684546_reset_undo.js
@@ -1,15 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-Cu.import("resource:///modules/source-editor.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/source-editor.jsm", tempScope);
+let SourceEditor = tempScope.SourceEditor;
 
 let testWin;
 let editor;
 
 function test()
 {
   waitForExplicitFinish();
 
--- a/browser/devtools/sourceeditor/test/browser_bug684862_paste_html.js
+++ b/browser/devtools/sourceeditor/test/browser_bug684862_paste_html.js
@@ -1,15 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-Cu.import("resource:///modules/source-editor.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/source-editor.jsm", tempScope);
+let SourceEditor = tempScope.SourceEditor;
 
 let testWin;
 let editor;
 
 function test()
 {
   waitForExplicitFinish();
 
--- a/browser/devtools/sourceeditor/test/browser_bug687160_line_api.js
+++ b/browser/devtools/sourceeditor/test/browser_bug687160_line_api.js
@@ -1,15 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-Cu.import("resource:///modules/source-editor.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/source-editor.jsm", tempScope);
+let SourceEditor = tempScope.SourceEditor;
 
 let testWin;
 let editor;
 
 function test()
 {
   waitForExplicitFinish();
 
--- a/browser/devtools/sourceeditor/test/browser_bug687568_pagescroll.js
+++ b/browser/devtools/sourceeditor/test/browser_bug687568_pagescroll.js
@@ -1,15 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-Cu.import("resource:///modules/source-editor.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/source-editor.jsm", tempScope);
+let SourceEditor = tempScope.SourceEditor;
 
 let testWin;
 let editor;
 
 function test()
 {
   let component = Services.prefs.getCharPref(SourceEditor.PREFS.COMPONENT);
   if (component != "orion") {
--- a/browser/devtools/sourceeditor/test/browser_bug687573_vscroll.js
+++ b/browser/devtools/sourceeditor/test/browser_bug687573_vscroll.js
@@ -1,15 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-Cu.import("resource:///modules/source-editor.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/source-editor.jsm", tempScope);
+let SourceEditor = tempScope.SourceEditor;
 
 let testWin;
 let editor;
 
 function test()
 {
   let component = Services.prefs.getCharPref(SourceEditor.PREFS.COMPONENT);
   if (component == "textarea") {
--- a/browser/devtools/sourceeditor/test/browser_bug687580_drag_and_drop.js
+++ b/browser/devtools/sourceeditor/test/browser_bug687580_drag_and_drop.js
@@ -1,15 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-Cu.import("resource:///modules/source-editor.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/source-editor.jsm", tempScope);
+let SourceEditor = tempScope.SourceEditor;
 
 let testWin;
 let editor;
 
 function test()
 {
   let component = Services.prefs.getCharPref(SourceEditor.PREFS.COMPONENT);
   if (component != "orion") {
--- a/browser/devtools/sourceeditor/test/browser_bug695035_middle_click_paste.js
+++ b/browser/devtools/sourceeditor/test/browser_bug695035_middle_click_paste.js
@@ -1,15 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-Cu.import("resource:///modules/source-editor.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/source-editor.jsm", tempScope);
+let SourceEditor = tempScope.SourceEditor;
 
 let testWin;
 let editor;
 
 function test()
 {
   if (Services.appinfo.OS != "Linux") {
     ok(true, "this test only applies to Linux, skipping.")
--- a/browser/devtools/sourceeditor/test/browser_sourceeditor_initialization.js
+++ b/browser/devtools/sourceeditor/test/browser_sourceeditor_initialization.js
@@ -1,15 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-Cu.import("resource:///modules/source-editor.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/source-editor.jsm", tempScope);
+let SourceEditor = tempScope.SourceEditor;
 
 let testWin;
 let testDoc;
 let editor;
 
 function test()
 {
   waitForExplicitFinish();
--- a/browser/devtools/styleeditor/StyleEditor.jsm
+++ b/browser/devtools/styleeditor/StyleEditor.jsm
@@ -224,16 +224,18 @@ StyleEditor.prototype = {
       placeholderText: this._state.text, //! this is initialText (bug 680371)
       showLineNumbers: true,
       mode: SourceEditor.MODES.CSS,
       readOnly: this._state.readOnly,
       keys: this._getKeyBindings()
     };
 
     sourceEditor.init(aElement, config, function onSourceEditorReady() {
+      setupBracketCompletion(sourceEditor);
+
       sourceEditor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED,
                                     function onTextChanged(aEvent) {
         this.updateStyleSheet();
       }.bind(this));
 
       this._sourceEditor = sourceEditor;
 
       if (this._focusOnSourceEditorReady) {
@@ -1127,8 +1129,53 @@ function prettifyCSS(aText)
   * @param string aText
   * @param number aCount
   * @return string
   */
 function repeat(aText, aCount)
 {
   return (new Array(aCount + 1)).join(aText);
 }
+
+/**
+ * Set up bracket completion on a given SourceEditor.
+ * This automatically closes the following CSS brackets: "{", "(", "["
+ *
+ * @param SourceEditor aSourceEditor
+ */
+function setupBracketCompletion(aSourceEditor)
+{
+  let editorElement = aSourceEditor.editorElement;
+  let pairs = {
+    123: { // {
+      closeString: "}",
+      closeKeyCode: Ci.nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET
+    },
+    40: { // (
+      closeString: ")",
+      closeKeyCode: Ci.nsIDOMKeyEvent.DOM_VK_0
+    },
+    91: { // [
+      closeString: "]",
+      closeKeyCode: Ci.nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET
+    },
+  };
+
+  editorElement.addEventListener("keypress", function onKeyPress(aEvent) {
+    let pair = pairs[aEvent.charCode];
+    if (!pair) {
+      return true;
+    }
+
+    // We detected an open bracket, sending closing character
+    let keyCode = pair.closeKeyCode;
+    let charCode = pair.closeString.charCodeAt(0);
+    let modifiers = 0;
+    let utils = editorElement.ownerDocument.defaultView.
+                  QueryInterface(Ci.nsIInterfaceRequestor).
+                  getInterface(Ci.nsIDOMWindowUtils);
+    let handled = utils.sendKeyEvent("keydown", keyCode, 0, modifiers);
+    utils.sendKeyEvent("keypress", 0, charCode, modifiers, !handled);
+    utils.sendKeyEvent("keyup", keyCode, 0, modifiers);
+    // and rewind caret
+    aSourceEditor.setCaretOffset(aSourceEditor.getCaretOffset() - 1);
+  }, false);
+}
--- a/browser/devtools/styleeditor/StyleEditorChrome.jsm
+++ b/browser/devtools/styleeditor/StyleEditorChrome.jsm
@@ -397,17 +397,19 @@ StyleEditorChrome.prototype = {
    */
   _updateSummaryForEditor: function SEC__updateSummaryForEditor(aEditor, aSummary)
   {
     let summary = aSummary || this.getSummaryElementForEditor(aEditor);
     let ruleCount = aEditor.styleSheet.cssRules.length;
 
     this._view.setItemClassName(summary, aEditor.flags);
 
-    text(summary, ".stylesheet-name", aEditor.getFriendlyName());
+    let label = summary.querySelector(".stylesheet-name > label");
+    label.setAttribute("value", aEditor.getFriendlyName());
+
     text(summary, ".stylesheet-title", aEditor.styleSheet.title || "");
     text(summary, ".stylesheet-rule-count",
       PluralForm.get(ruleCount, _("ruleCount.label")).replace("#1", ruleCount));
     text(summary, ".stylesheet-error-message", aEditor.errorMessage);
   },
 
   /**
    * IStyleEditorActionListener implementation
--- a/browser/devtools/styleeditor/styleeditor.css
+++ b/browser/devtools/styleeditor/styleeditor.css
@@ -15,16 +15,17 @@
  * The Original Code is Style Editor code.
  *
  * The Initial Developer of the Original Code is Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2011
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Cedric Vivier <cedricv@neonux.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
@@ -59,32 +60,27 @@ li.error > .stylesheet-info > .styleshee
   -moz-box-flex: 1;
 }
 
 .stylesheet-info > h1 {
   -moz-box-flex: 1;
 }
 
 .stylesheet-name {
-  /* clip the text at the beginning */
-  display: -moz-box;
-  direction: rtl;
-  text-align: left;
-  overflow: hidden;
+  outline: none;
+}
+
+.stylesheet-name > label {
+  cursor: pointer;
 }
 
 .splitview-nav > li > hgroup.stylesheet-info {
   -moz-box-pack: center;
 }
 
-.splitview-nav:-moz-locale-dir(ltr) > li.unsaved > hgroup .stylesheet-name:before,
-.splitview-nav:-moz-locale-dir(rtl) > li.unsaved > hgroup .stylesheet-name:after {
-  content: "* ";
-}
-
 .stylesheet-enabled {
   display: -moz-box;
 }
 
 .stylesheet-saveButton {
   display: none;
 }
 
@@ -102,17 +98,17 @@ li:hover > hgroup > .stylesheet-more > h
 @media (max-aspect-ratio: 5/3) {
   li.splitview-active > hgroup > .stylesheet-more > .stylesheet-rule-count,
   li:hover > hgroup > .stylesheet-more > .stylesheet-rule-count {
     display: none;
   }
 
   .stylesheet-more {
     -moz-box-flex: 1;
-    -moz-box-direction: reverse;
+    -moz-box-pack: end;
   }
 
   .splitview-nav > li > hgroup.stylesheet-info {
     -moz-box-orient: horizontal;
     -moz-box-flex: 1;
   }
 
   .stylesheet-more > spacer {
--- a/browser/devtools/styleeditor/styleeditor.xul
+++ b/browser/devtools/styleeditor/styleeditor.xul
@@ -49,84 +49,84 @@
         xmlns="http://www.w3.org/1999/xhtml"
         id="style-editor-chrome-window"
         title="&window.title;"
         windowtype="Tools:StyleEditor"
         width="800" height="280"
         persist="screenX screenY width height sizemode">
 <xul:script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
 
+<xul:commandset id="style-editor-commandset">
+  <xul:command id="style-editor-cmd-close" oncommand="window.close();"/>
+</xul:commandset>
+
+<xul:keyset id="style-editor-keyset">
+  <xul:key id="style-editor-key-close"
+           key="&closeCmd.key;"
+           command="style-editor-cmd-close"
+           modifiers="accel"/>
+</xul:keyset>
+
 <xul:box id="style-editor-chrome" class="splitview-root loading">
-  <xul:box class="splitview-controller" id="stylesheets-controller" persist="width height">
+  <xul:box class="splitview-controller">
     <xul:box class="splitview-main">
       <xul:toolbar class="devtools-toolbar">
         <xul:toolbarbutton class="style-editor-newButton devtools-toolbarbutton"
                     accesskey="&newButton.accesskey;"
                     tooltiptext="&newButton.tooltip;"
                     label="&newButton.label;"
                     disabled="true"/>
         <xul:toolbarbutton class="style-editor-importButton devtools-toolbarbutton"
                     accesskey="&importButton.accesskey;"
                     tooltiptext="&importButton.tooltip;"
                     label="&importButton.label;"
                     disabled="true"/>
-        <xul:spacer flex="1"/>
-        <xul:textbox class="splitview-filter devtools-searchinput"
-                     type="search" flex="1"
-                     tooltiptext="&searchInput.tooltip;"
-                     placeholder="&searchInput.placeholder;"/>
       </xul:toolbar>
     </xul:box>
-    <xul:box class="splitview-nav-container">
+    <xul:box id="splitview-resizer-target" class="splitview-nav-container"
+             persist="width height">
       <ol class="splitview-nav" tabindex="0"></ol>
       <div class="splitview-nav placeholder empty">
         <p><strong>&noStyleSheet.label;</strong></p>
         <p>&noStyleSheet-tip-start.label;
           <a href="#"
              class="style-editor-newButton">&noStyleSheet-tip-action.label;</a>
           &noStyleSheet-tip-end.label;</p>
       </div>
-      <div class="splitview-nav placeholder all-filtered">
-        <p><strong>&searchNoResults.label;</strong></p>
-        <p>
-          <a href="#"
-             class="splitview-filter-clearButton">&searchClearButton.label;</a>
-        </p>
-      </div>
     </xul:box> <!-- .splitview-nav-container -->
   </xul:box>   <!-- .splitview-controller -->
   <xul:box class="splitview-side-details"/>
 
   <div id="splitview-templates" hidden="true">
     <li id="splitview-tpl-summary-stylesheet" tabindex="0">
       <a class="stylesheet-enabled" tabindex="0" href="#"
          title="&visibilityToggle.tooltip;"
          accesskey="&saveButton.accesskey;"></a>
       <hgroup class="stylesheet-info">
-        <h1><a class="stylesheet-name" href="#"></a></h1>
+        <h1><a class="stylesheet-name" href="#"><xul:label crop="start"/></a></h1>
         <div class="stylesheet-more">
           <h3 class="stylesheet-title"></h3>
           <h3 class="stylesheet-rule-count"></h3>
           <h3 class="stylesheet-error-message"></h3>
           <xul:spacer/>
           <h3><a class="stylesheet-saveButton" href="#"
                  title="&saveButton.tooltip;"
                  accesskey="&saveButton.accesskey;">&saveButton.label;</a></h3>
         </div>
       </hgroup>
     </li>
 
     <xul:box id="splitview-tpl-details-stylesheet" class="splitview-details">
       <xul:resizer class="splitview-portrait-resizer"
-               dir="bottom"
-               element="stylesheets-controller"/>
+                   dir="bottom"
+                   element="splitview-resizer-target"/>
       <xul:toolbar id="splitview-details-toolbar" class="devtools-toolbar">
         <xul:resizer class="splitview-landscape-resizer"
                      dir="bottomend"
-                     element="stylesheets-controller"/>
+                     element="splitview-resizer-target"/>
       </xul:toolbar>
       <xul:box class="stylesheet-editor-input textbox"
                data-placeholder="&editorTextbox.placeholder;"/>
     </xul:box>
   </div> <!-- #splitview-templates -->
 </xul:box>   <!-- .splitview-root -->
 
 <xul:script type="application/javascript"><![CDATA[
--- a/browser/devtools/styleeditor/test/Makefile.in
+++ b/browser/devtools/styleeditor/test/Makefile.in
@@ -48,17 +48,16 @@ include $(topsrcdir)/config/rules.mk
                  browser_styleeditor_enabled.js \
                  browser_styleeditor_import.js \
                  browser_styleeditor_init.js \
                  browser_styleeditor_loading.js \
                  browser_styleeditor_new.js \
                  browser_styleeditor_pretty.js \
                  browser_styleeditor_readonly.js \
                  browser_styleeditor_reopen.js \
-                 browser_styleeditor_sv_filter.js \
                  browser_styleeditor_sv_keynav.js \
                  browser_styleeditor_sv_resize.js \
                  four.html \
                  head.js \
                  media.html \
                  media-small.css \
                  minified.html \
                  simple.css \
--- a/browser/devtools/styleeditor/test/browser_styleeditor_import.js
+++ b/browser/devtools/styleeditor/test/browser_styleeditor_import.js
@@ -1,16 +1,19 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // http rather than chrome to improve coverage
 const TESTCASE_URI = TEST_BASE_HTTP + "simple.html";
 
-Components.utils.import("resource://gre/modules/FileUtils.jsm");
+let tempScope = {};
+Components.utils.import("resource://gre/modules/FileUtils.jsm", tempScope);
+let FileUtils = tempScope.FileUtils;
+
 const FILENAME = "styleeditor-import-test.css";
 const SOURCE = "body{background:red;}";
 
 
 function test()
 {
   waitForExplicitFinish();
 
--- a/browser/devtools/styleeditor/test/browser_styleeditor_init.js
+++ b/browser/devtools/styleeditor/test/browser_styleeditor_init.js
@@ -80,17 +80,17 @@ function testFirstStyleSheetEditor(aChro
 
   ok(!aEditor.hasFlag("inline"),
      "first stylesheet does not have INLINE flag");
 
   let summary = aChrome.getSummaryElementForEditor(aEditor);
   ok(!summary.classList.contains("inline"),
      "first stylesheet UI does not have INLINE class");
 
-  let name = summary.querySelector(".stylesheet-name").textContent;
+  let name = summary.querySelector(".stylesheet-name > label").getAttribute("value");
   is(name, "simple.css",
      "first stylesheet's name is `simple.css`");
 
   let ruleCount = summary.querySelector(".stylesheet-rule-count").textContent;
   is(parseInt(ruleCount), 1,
      "first stylesheet UI shows rule count as 1");
 
   ok(summary.classList.contains("splitview-active"),
@@ -108,17 +108,17 @@ function testSecondStyleSheetEditor(aChr
 
   ok(aEditor.hasFlag("inline"),
      "second stylesheet has INLINE flag");
 
   let summary = aChrome.getSummaryElementForEditor(aEditor);
   ok(summary.classList.contains("inline"),
      "second stylesheet UI has INLINE class");
 
-  let name = summary.querySelector(".stylesheet-name").textContent;
+  let name = summary.querySelector(".stylesheet-name > label").getAttribute("value");
   ok(/^<.*>$/.test(name),
      "second stylesheet's name is surrounded by `<>`");
 
   let ruleCount = summary.querySelector(".stylesheet-rule-count").textContent;
   is(parseInt(ruleCount), 3,
      "second stylesheet UI shows rule count as 3");
 
   ok(!summary.classList.contains("splitview-active"),
--- a/browser/devtools/styleeditor/test/browser_styleeditor_new.js
+++ b/browser/devtools/styleeditor/test/browser_styleeditor_new.js
@@ -1,16 +1,16 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const TESTCASE_URI = TEST_BASE + "simple.html";
 
 const TRANSITION_CLASS = "moz-styleeditor-transitioning";
-
+const TESTCASE_CSS_SOURCE = "body{background-color:red;";
 
 function test()
 {
   waitForExplicitFinish();
 
   addTabAndLaunchStyleEditorChromeWhenLoaded(function (aChrome) {
     aChrome.addChromeListener({
       onContentAttach: run,
@@ -74,19 +74,23 @@ function testEditorAdded(aChrome, aEdito
         let ruleCount = summary.querySelector(".stylesheet-rule-count").textContent;
         is(parseInt(ruleCount), 0,
            "new editor initially shows 0 rules");
 
         let computedStyle = content.getComputedStyle(content.document.body, null);
         is(computedStyle.backgroundColor, "rgb(255, 255, 255)",
            "content's background color is initially white");
 
-        for each (let c in "body{background-color:red;}") {
+        for each (let c in TESTCASE_CSS_SOURCE) {
           EventUtils.synthesizeKey(c, {}, gChromeWindow);
         }
+
+        is(aEditor.sourceEditor.getText(), TESTCASE_CSS_SOURCE + "}",
+           "rule bracket has been auto-closed");
+
       }, gChromeWindow) ;
     },
 
     onUpdate: function (aEditor) {
       gUpdateCount++;
 
       ok(content.document.documentElement.classList.contains(TRANSITION_CLASS),
          "StyleEditor's transition class has been added to content");
--- a/browser/devtools/styleeditor/test/browser_styleeditor_reopen.js
+++ b/browser/devtools/styleeditor/test/browser_styleeditor_reopen.js
@@ -2,17 +2,20 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // http rather than chrome to improve coverage
 const TESTCASE_URI = TEST_BASE_HTTP + "simple.gz.html";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
-Components.utils.import("resource://gre/modules/FileUtils.jsm");
+
+let tempScope = {};
+Components.utils.import("resource://gre/modules/FileUtils.jsm", tempScope);
+let FileUtils = tempScope.FileUtils;
 
 
 function test()
 {
   waitForExplicitFinish();
 
   addTabAndLaunchStyleEditorChromeWhenLoaded(function (aChrome) {
     aChrome.addChromeListener({
deleted file mode 100644
--- a/browser/devtools/styleeditor/test/browser_styleeditor_sv_filter.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const TESTCASE_URI = TEST_BASE + "simple.html";
-
-
-function test()
-{
-  waitForExplicitFinish();
-
-  addTabAndLaunchStyleEditorChromeWhenLoaded(function (aChrome) {
-    aChrome.addChromeListener({
-      onContentAttach: run
-    });
-    if (aChrome.isContentAttached) {
-      run(aChrome);
-    }
-  });
-
-  content.location = TESTCASE_URI;
-}
-
-function getFilteredItemsCount(nav)
-{
-  let matches = nav.querySelectorAll("*.splitview-filtered");
-  return matches ? matches.length : 0;
-}
-
-function run(aChrome)
-{
-  aChrome.editors[0].addActionListener({onAttach: onFirstEditorAttach});
-  aChrome.editors[1].addActionListener({onAttach: onSecondEditorAttach});
-}
-
-function onFirstEditorAttach(aEditor)
-{
-  let filter = gChromeWindow.document.querySelector(".splitview-filter");
-  // force the command event on input since it is not possible to disable
-  // the search textbox's timeout.
-  let forceCommandEvent = function forceCommandEvent() {
-    let evt = gChromeWindow.document.createEvent("XULCommandEvent");
-    evt.initCommandEvent("command", true, true, gChromeWindow, 0, false, false,
-                         false, false, null);
-    filter.dispatchEvent(evt);
-  }
-  filter.addEventListener("input", forceCommandEvent, false);
-
-  let nav = gChromeWindow.document.querySelector(".splitview-nav");
-  nav.focus();
-
-  is(getFilteredItemsCount(nav), 0,
-     "there is 0 filtered item initially");
-
-  waitForFocus(function () {
-    // Search [s] (type-on-search since we focused nav above - not filter directly)
-    EventUtils.synthesizeKey("s", {}, gChromeWindow);
-
-    // the search space is "simple.css" and "inline stylesheet #1" (2 sheets)
-    is(getFilteredItemsCount(nav), 0,
-       "there is 0 filtered item if searching for 's'");
-
-    EventUtils.synthesizeKey("i", {}, gChromeWindow); // Search [si]
-
-    is(getFilteredItemsCount(nav), 1, // inline stylesheet is filtered
-       "there is 1 filtered item if searching for 's'");
-
-    // use uppercase to check that filtering is case-insensitive
-    EventUtils.synthesizeKey("X", {}, gChromeWindow); // Search [siX]
-    is(getFilteredItemsCount(nav), 2,
-       "there is 2 filtered items if searching for 's'"); // no match
-
-    // clear the search
-    EventUtils.synthesizeKey("VK_ESCAPE", {}, gChromeWindow);
-
-    is(filter.value, "",
-       "filter is back to empty");
-    is(getFilteredItemsCount(nav), 0,
-       "there is 0 filtered item when filter is empty again");
-
-    for each (let c in "inline") {
-      EventUtils.synthesizeKey(c, {}, gChromeWindow);
-    }
-
-    is(getFilteredItemsCount(nav), 1, // simple.css is filtered
-       "there is 1 filtered item if searching for 'inline'");
-
-    // auto-select the only result (enter the editor)
-    EventUtils.synthesizeKey("VK_ENTER", {}, gChromeWindow);
-
-    filter.removeEventListener("input", forceCommandEvent, false);
-  }, gChromeWindow);
-}
-
-function onSecondEditorAttach(aEditor)
-{
-  ok(aEditor.sourceEditor.hasFocus(),
-     "second editor has been selected and focused automatically.");
-
-  finish();
-}
--- a/browser/devtools/styleinspector/CssRuleView.jsm
+++ b/browser/devtools/styleinspector/CssRuleView.jsm
@@ -1305,16 +1305,17 @@ InplaceEditor.prototype = {
       prevent = true;
       moveFocus(this.input.ownerDocument.defaultView, FOCUS_FORWARD);
     } else if (aEvent.keyCode === Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE) {
       // Cancel and blur ourselves.  |_onBlur| will call the user's
       // done handler for us.
       prevent = true;
       this.cancelled = true;
       this.input.blur();
+      aEvent.stopPropagation();
     } else if (aEvent.keyCode === Ci.nsIDOMKeyEvent.DOM_VK_SPACE) {
       // No need for leading spaces here.  This is particularly
       // noticable when adding a property: it's very natural to type
       // <name>: (which advances to the next property) then spacebar.
       prevent = !this.input.value;
     }
 
     if (prevent) {
--- a/browser/devtools/styleinspector/test/browser_bug589375_keybindings.js
+++ b/browser/devtools/styleinspector/test/browser_bug589375_keybindings.js
@@ -9,17 +9,16 @@ let stylePanel;
 
 function createDocument()
 {
   doc.body.innerHTML = '<style type="text/css"> ' +
     '.matches {color: #F00;}</style>' +
     '<span class="matches">Some styled text</span>' +
     '</div>';
   doc.title = "Style Inspector key binding test";
-  ok(window.StyleInspector, "StyleInspector exists");
   stylePanel = new StyleInspector(window);
   Services.obs.addObserver(runStyleInspectorTests, "StyleInspector-opened", false);
   stylePanel.createPanel(false, function() {
     stylePanel.open(doc.body);
   });
 }
 
 function runStyleInspectorTests()
--- a/browser/devtools/styleinspector/test/browser_bug683672.js
+++ b/browser/devtools/styleinspector/test/browser_bug683672.js
@@ -4,30 +4,32 @@
 
 // Tests that the style inspector works properly
 
 let doc;
 let stylePanel;
 
 const TEST_URI = "http://example.com/browser/browser/devtools/styleinspector/test/browser_bug683672.html";
 
-Cu.import("resource:///modules/devtools/CssHtmlTree.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/devtools/CssHtmlTree.jsm", tempScope);
+let CssHtmlTree = tempScope.CssHtmlTree;
+let PropertyView = tempScope.PropertyView;
 
 function test()
 {
   waitForExplicitFinish();
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoaded, true);
 }
 
 function tabLoaded()
 {
   browser.removeEventListener("load", tabLoaded, true);
   doc = content.document;
-  ok(window.StyleInspector, "StyleInspector exists");
   // ok(StyleInspector.isEnabled, "style inspector preference is enabled");
   stylePanel = new StyleInspector(window);
   Services.obs.addObserver(runTests, "StyleInspector-opened", false);
   stylePanel.createPanel(false, function() {
     stylePanel.open(doc.body);
   });
 }
 
--- a/browser/devtools/styleinspector/test/browser_bug_692400_element_style.js
+++ b/browser/devtools/styleinspector/test/browser_bug_692400_element_style.js
@@ -7,17 +7,16 @@
 let doc;
 let stylePanel;
 
 function createDocument()
 {
   doc.body.innerHTML = "<div style='color:blue;'></div>";
 
   doc.title = "Style Inspector Selector Text Test";
-  ok(window.StyleInspector, "StyleInspector exists");
   stylePanel = new StyleInspector(window);
 
 
   stylePanel.createPanel(false, function() {
     Services.obs.addObserver(SI_checkText, "StyleInspector-populated", false);
 
     let span = doc.querySelector("div");
     ok(span, "captain, we have the test div");
--- a/browser/devtools/styleinspector/test/browser_csslogic_inherited.js
+++ b/browser/devtools/styleinspector/test/browser_csslogic_inherited.js
@@ -1,15 +1,17 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Test that inherited properties are treated correctly.
 
-Cu.import("resource:///modules/devtools/CssLogic.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/devtools/CssLogic.jsm", tempScope);
+let CssLogic = tempScope.CssLogic;
 
 let doc;
 
 function createDocument()
 {
   doc.body.innerHTML = '<div style="margin-left:10px; font-size: 5px"><div id="innerdiv">Inner div</div></div>';
   doc.title = "Style Inspector Inheritance Test";
 
--- a/browser/devtools/styleinspector/test/browser_ruleview_editor.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_editor.js
@@ -1,13 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-Cu.import("resource:///modules/devtools/CssRuleView.jsm");
+let tempScope = {}
+Cu.import("resource:///modules/devtools/CssRuleView.jsm", tempScope);
+let CssRuleView = tempScope.CssRuleView;
+let _ElementStyle = tempScope._ElementStyle;
+let _editableField = tempScope._editableField;
 
 let doc = content.document;
 
 function expectDone(aValue, aCommit, aNext)
 {
   return function(aDoneValue, aDoneCommit) {
     dump("aDoneValue: " + aDoneValue + " commit: " + aDoneCommit + "\n");
 
@@ -113,9 +117,9 @@ function test()
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", function(evt) {
     gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
     doc = content.document;
     waitForFocus(testReturnCommit, content);
   }, true);
 
   content.location = "data:text/html,inline editor tests";
-}
\ No newline at end of file
+}
--- a/browser/devtools/styleinspector/test/browser_ruleview_inherit.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_inherit.js
@@ -1,13 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-Cu.import("resource:///modules/devtools/CssRuleView.jsm");
+let tempScope = {}
+Cu.import("resource:///modules/devtools/CssRuleView.jsm", tempScope);
+let CssRuleView = tempScope.CssRuleView;
+let _ElementStyle = tempScope._ElementStyle;
+let _editableField = tempScope._editableField;
 
 let doc;
 
 function simpleInherit()
 {
   let style = '' +
     '#test2 {' +
     '  background-color: green;' +
--- a/browser/devtools/styleinspector/test/browser_ruleview_manipulation.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_manipulation.js
@@ -1,13 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-Cu.import("resource:///modules/devtools/CssRuleView.jsm");
+let tempScope = {}
+Cu.import("resource:///modules/devtools/CssRuleView.jsm", tempScope);
+let CssRuleView = tempScope.CssRuleView;
+let _ElementStyle = tempScope._ElementStyle;
+let _editableField = tempScope._editableField;
 
 let doc;
 
 function simpleOverride()
 {
   doc.body.innerHTML = '<div id="testid">Styled Node</div>';
   let element = doc.getElementById("testid");
   let elementStyle = new _ElementStyle(element);
--- a/browser/devtools/styleinspector/test/browser_ruleview_override.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_override.js
@@ -1,13 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-Cu.import("resource:///modules/devtools/CssRuleView.jsm");
+let tempScope = {}
+Cu.import("resource:///modules/devtools/CssRuleView.jsm", tempScope);
+let CssRuleView = tempScope.CssRuleView;
+let _ElementStyle = tempScope._ElementStyle;
+let _editableField = tempScope._editableField;
 
 let doc;
 
 function simpleOverride()
 {
   let style = '' +
     '#testid {' +
     '  background-color: blue;' +
--- a/browser/devtools/styleinspector/test/browser_ruleview_ui.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_ui.js
@@ -1,13 +1,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-Cu.import("resource:///modules/devtools/CssRuleView.jsm");
+let tempScope = {}
+Cu.import("resource:///modules/devtools/CssRuleView.jsm", tempScope);
+let CssRuleView = tempScope.CssRuleView;
+let _ElementStyle = tempScope._ElementStyle;
+let _editableField = tempScope._editableField;
 
 let doc;
 let ruleDialog;
 let ruleView;
 
 function waitForEditorFocus(aParent, aCallback)
 {
   aParent.addEventListener("focus", function onFocus(evt) {
--- a/browser/devtools/styleinspector/test/browser_styleinspector.js
+++ b/browser/devtools/styleinspector/test/browser_styleinspector.js
@@ -21,17 +21,16 @@ function createDocument()
     'style list-items in the box at right. If you are reading this, ' +
     'you should go do something else instead. Maybe read a book. Or better ' +
     'yet, write some test-cases for another bit of code. ' +
     '<span style="font-style: italic">Maybe more inspector test-cases!</span></p>\n' +
     '<p id="closing">end transmission</p>\n' +
     '<p>Inspect using inspectstyle(document.querySelectorAll("span")[0])</p>' +
     '</div>';
   doc.title = "Style Inspector Test";
-  ok(window.StyleInspector, "StyleInspector exists");
   stylePanel = new StyleInspector(window);
   Services.obs.addObserver(runStyleInspectorTests, "StyleInspector-opened", false);
   stylePanel.createPanel(false, function() {
     stylePanel.open(doc.body);
   });
 }
 
 function runStyleInspectorTests()
--- a/browser/devtools/styleinspector/test/browser_styleinspector_bug_672744_search_filter.js
+++ b/browser/devtools/styleinspector/test/browser_styleinspector_bug_672744_search_filter.js
@@ -9,17 +9,16 @@ let stylePanel;
 
 function createDocument()
 {
   doc.body.innerHTML = '<style type="text/css"> ' +
     '.matches {color: #F00;}</style>' +
     '<span id="matches" class="matches">Some styled text</span>' +
     '</div>';
   doc.title = "Style Inspector Search Filter Test";
-  ok(window.StyleInspector, "StyleInspector exists");
   // ok(StyleInspector.isEnabled, "style inspector preference is enabled");
   stylePanel = new StyleInspector(window);
   Services.obs.addObserver(runStyleInspectorTests, "StyleInspector-opened", false);
   stylePanel.createPanel(false, function() {
     stylePanel.open(doc.body);
   });
 }
 
--- a/browser/devtools/styleinspector/test/browser_styleinspector_bug_672746_default_styles.js
+++ b/browser/devtools/styleinspector/test/browser_styleinspector_bug_672746_default_styles.js
@@ -9,17 +9,16 @@ let stylePanel;
 
 function createDocument()
 {
   doc.body.innerHTML = '<style type="text/css"> ' +
     '.matches {color: #F00;}</style>' +
     '<span id="matches" class="matches">Some styled text</span>' +
     '</div>';
   doc.title = "Style Inspector Default Styles Test";
-  ok(window.StyleInspector, "StyleInspector exists");
   // ok(StyleInspector.isEnabled, "style inspector preference is enabled");
   stylePanel = new StyleInspector(window);
   Services.obs.addObserver(runStyleInspectorTests, "StyleInspector-opened", false);
   stylePanel.createPanel(false, function() {
     stylePanel.open(doc.body);
   });
 }
 
--- a/browser/devtools/styleinspector/test/browser_styleinspector_bug_689759_no_results_placeholder.js
+++ b/browser/devtools/styleinspector/test/browser_styleinspector_bug_689759_no_results_placeholder.js
@@ -8,17 +8,16 @@ let doc;
 let stylePanel;
 
 function createDocument()
 {
   doc.body.innerHTML = '<style type="text/css"> ' +
     '.matches {color: #F00;}</style>' +
     '<span id="matches" class="matches">Some styled text</span>';
   doc.title = "Tests that the no results placeholder works properly";
-  ok(window.StyleInspector, "StyleInspector exists");
   stylePanel = new StyleInspector(window);
   Services.obs.addObserver(runStyleInspectorTests, "StyleInspector-opened", false);
   stylePanel.createPanel(false, function() {
     stylePanel.open(doc.body);
   });
 }
 
 function runStyleInspectorTests()
--- a/browser/devtools/styleinspector/test/head.js
+++ b/browser/devtools/styleinspector/test/head.js
@@ -30,18 +30,22 @@
  * 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 ***** */
 
-Cu.import("resource:///modules/devtools/StyleInspector.jsm");
-Cu.import("resource://gre/modules/HUDService.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/devtools/StyleInspector.jsm", tempScope);
+Cu.import("resource://gre/modules/HUDService.jsm", tempScope);
+let StyleInspector = tempScope.StyleInspector;
+let HUDService = tempScope.HUDService;
+let ConsoleUtils = tempScope.ConsoleUtils;
 
 function log(aMsg)
 {
   dump("*** WebConsoleTest: " + aMsg + "\n");
 }
 
 function pprint(aObj)
 {
--- a/browser/devtools/tilt/test/head.js
+++ b/browser/devtools/tilt/test/head.js
@@ -1,19 +1,29 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /*global Services, Components, gBrowser, executeSoon, info */
 /*global InspectorUI, Tilt, TiltGL, EPSILON */
 "use strict";
 
-Components.utils.import("resource:///modules/devtools/TiltGL.jsm");
-Components.utils.import("resource:///modules/devtools/TiltMath.jsm");
-Components.utils.import("resource:///modules/devtools/TiltUtils.jsm");
-Components.utils.import("resource:///modules/devtools/TiltVisualizer.jsm");
+let tempScope = {};
+Components.utils.import("resource:///modules/devtools/TiltGL.jsm", tempScope);
+Components.utils.import("resource:///modules/devtools/TiltMath.jsm", tempScope);
+Components.utils.import("resource:///modules/devtools/TiltUtils.jsm", tempScope);
+Components.utils.import("resource:///modules/devtools/TiltVisualizer.jsm", tempScope);
+let TiltGL = tempScope.TiltGL;
+let EPSILON = tempScope.EPSILON;
+let TiltMath = tempScope.TiltMath;
+let vec3 = tempScope.vec3;
+let mat3 = tempScope.mat3;
+let mat4 = tempScope.mat4;
+let quat4 = tempScope.quat4;
+let TiltUtils = tempScope.TiltUtils;
+let TiltVisualizer = tempScope.TiltVisualizer;
 
 
 const DEFAULT_HTML = "data:text/html," +
   "<DOCTYPE html>" +
   "<html>" +
     "<head>" +
       "<title>Three Laws</title>" +
     "</head>" +
--- a/browser/devtools/webconsole/test/browser_gcli_inspect.js
+++ b/browser/devtools/webconsole/test/browser_gcli_inspect.js
@@ -2,17 +2,19 @@
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // For more information on GCLI see:
 // - https://github.com/mozilla/gcli/blob/master/docs/index.md
 // - https://wiki.mozilla.org/DevTools/Features/GCLI
 
 // Tests that the inspect command works as it should
 
-Components.utils.import("resource:///modules/gcli.jsm");
+let tempScope = {};
+Components.utils.import("resource:///modules/gcli.jsm", tempScope);
+let gcli = tempScope.gcli;
 
 registerCleanupFunction(function() {
   gcliterm = undefined;
   requisition = undefined;
 
   Services.prefs.clearUserPref("devtools.gcli.enable");
 });
 
--- a/browser/devtools/webconsole/test/browser_gcli_integrate.js
+++ b/browser/devtools/webconsole/test/browser_gcli_integrate.js
@@ -3,17 +3,19 @@
 
 // For more information on GCLI see:
 // - https://github.com/mozilla/gcli/blob/master/docs/index.md
 // - https://wiki.mozilla.org/DevTools/Features/GCLI
 
 // Tests that source URLs in the Web Console can be clicked to display the
 // standard View Source window.
 
-Components.utils.import("resource:///modules/gcli.jsm");
+let tempScope = {};
+Components.utils.import("resource:///modules/gcli.jsm", tempScope);
+let gcli = tempScope.gcli;
 let require = gcli._internal.require;
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console.html";
 
 registerCleanupFunction(function() {
   require = undefined;
   Services.prefs.clearUserPref("devtools.gcli.enable");
 });
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_580454_timestamp_l10n.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_580454_timestamp_l10n.js
@@ -5,18 +5,16 @@
  *
  * Contributor(s):
  *  Patrick Walton <pcwalton@mozilla.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that appropriately-localized timestamps are printed.
 
-Cu.import("resource:///modules/HUDService.jsm");
-
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testTimestamp, false);
 
   function testTimestamp()
   {
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
@@ -32,16 +32,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TEST_URI = "data:text/html,<p>bug 585991 - autocomplete popup keyboard usage test";
+let HUD;
 
 registerCleanupFunction(function() {
   Services.prefs.clearUserPref("devtools.gcli.enable");
 });
 
 function test() {
   Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_586388_select_all.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_586388_select_all.js
@@ -67,13 +67,11 @@ function testSelectionWhenMovingBetweenB
   selectAllItem.dispatchEvent(commandEvent);
 
   is(outputNode.selectedCount, outputNode.childNodes.length, "all console " +
      "messages are selected after performing a select-all operation from " +
      "the context menu");
 
   outputNode.selectedIndex = -1;
 
-  commandEvent = contextMenu = groupNode = range = null;
-
   finishTest();
 }
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_594497_history_arrow_keys.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_594497_history_arrow_keys.js
@@ -12,17 +12,17 @@ let inputNode, values;
 
 function tabLoad(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
 
   waitForFocus(function() {
     openConsole();
 
     let hudId = HUDService.getHudIdByWindow(content);
-    HUD = HUDService.hudReferences[hudId];
+    let HUD = HUDService.hudReferences[hudId];
 
     inputNode = HUD.jsterm.inputNode;
 
     inputNode.focus();
 
     ok(!inputNode.value, "inputNode.value is empty");
 
     values = ["document", "window", "document.body"];
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_598357_jsterm_output.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_598357_jsterm_output.js
@@ -86,16 +86,17 @@ let inputValues = [
   // 17
   [true, "({a:'b', c:'d', e:1, f:'2'})", '({a:"b", c:"d", e:1, f:"2"})',
     "[object Object",
     '({a:"b", c:"d", e:1, f:"2"})'],
 ];
 
 let eventHandlers = [];
 let popupShown = [];
+let HUD;
 
 function tabLoad(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
 
   waitForFocus(function () {
     openConsole();
 
     let hudId = HUDService.getHudIdByWindow(content);
@@ -216,17 +217,16 @@ function testEnd() {
   }
 
   for (let i = 0; i < inputValues.length; i++) {
     if (inputValues[i][0] && !popupShown[i]) {
       ok(false, "the property panel failed to show for inputValues[" + i + "]");
     }
   }
 
-  eventHandlers = popupshown = null;
   executeSoon(finishTest);
 }
 
 registerCleanupFunction(function() {
   Services.prefs.clearUserPref("devtools.gcli.enable");
 });
 
 function test() {
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_642108_pruneTest.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_642108_pruneTest.js
@@ -16,31 +16,31 @@ const SEVERITY_WARNING = 1;
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testCSSPruning, false);
 }
 
 function populateConsoleRepeats(aHudRef) {
   let hud = aHudRef.HUDBox;
 
-  for (i = 0; i < 5; i++) {
+  for (let i = 0; i < 5; i++) {
     let node = ConsoleUtils.createMessageNode(hud.ownerDocument,
                                               CATEGORY_CSS,
                                               SEVERITY_WARNING,
                                               "css log x",
                                               aHudRef.hudId);
     ConsoleUtils.outputMessageNode(node, aHudRef.hudId);
   }
 }
 
 
 function populateConsole(aHudRef) {
   let hud = aHudRef.HUDBox;
 
-  for (i = 0; i < LOG_LIMIT + 5; i++) {
+  for (let i = 0; i < LOG_LIMIT + 5; i++) {
     let node = ConsoleUtils.createMessageNode(hud.ownerDocument,
                                               CATEGORY_CSS,
                                               SEVERITY_WARNING,
                                               "css log " + i,
                                               aHudRef.hudId);
     ConsoleUtils.outputMessageNode(node, aHudRef.hudId);
   }
 }
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js
@@ -1,17 +1,22 @@
 /* vim:set ts=2 sw=2 sts=2 et: */
 /*
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 // Tests that document.body autocompletes in the web console.
 
-Cu.import("resource:///modules/PropertyPanel.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/PropertyPanel.jsm", tempScope);
+let PropertyPanel = tempScope.PropertyPanel;
+let PropertyTreeView = tempScope.PropertyTreeView;
+let namesAndValuesOf = tempScope.namesAndValuesOf;
+let isNonNativeGetter = tempScope.isNonNativeGetter;
 
 registerCleanupFunction(function() {
   Services.prefs.clearUserPref("devtools.gcli.enable");
 });
 
 function test() {
   Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab("data:text/html,Web Console autocompletion bug in document.body");
--- a/browser/devtools/webconsole/test/head.js
+++ b/browser/devtools/webconsole/test/head.js
@@ -31,17 +31,20 @@
  * 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 ***** */
 
-Cu.import("resource:///modules/HUDService.jsm");
+let tempScope = {};
+Cu.import("resource:///modules/HUDService.jsm", tempScope);
+let HUDService = tempScope.HUDService;
+let ConsoleUtils = tempScope.ConsoleUtils;
 
 function log(aMsg)
 {
   dump("*** WebConsoleTest: " + aMsg + "\n");
 }
 
 function pprint(aObj)
 {
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -364,20 +364,18 @@
 @BINPATH@/components/nsFormAutoComplete.js
 @BINPATH@/components/nsFormHistory.js
 @BINPATH@/components/nsInputListAutoComplete.js
 @BINPATH@/components/contentSecurityPolicy.manifest
 @BINPATH@/components/contentSecurityPolicy.js
 @BINPATH@/components/contentAreaDropListener.manifest
 @BINPATH@/components/contentAreaDropListener.js
 #ifdef MOZ_B2G_RIL
-@BINPATH@/components/nsTelephonyWorker.manifest
-@BINPATH@/components/nsTelephonyWorker.js
-@BINPATH@/components/Telephony.manifest
-@BINPATH@/components/Telephony.js
+@BINPATH@/components/RadioInterfaceLayer.manifest
+@BINPATH@/components/RadioInterfaceLayer.js
 @BINPATH@/components/nsWifiWorker.js
 @BINPATH@/components/nsWifiWorker.manifest
 #endif
 @BINPATH@/components/BrowserProfileMigrators.manifest
 @BINPATH@/components/ChromeProfileMigrator.js
 @BINPATH@/components/FirefoxProfileMigrator.js
 #ifdef XP_MACOSX
 @BINPATH@/components/libalerts.dylib
--- a/browser/locales/en-US/chrome/browser/devtools/styleeditor.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/styleeditor.dtd
@@ -17,27 +17,16 @@
 <!ENTITY newButton.accesskey        "N">
 <!ENTITY newButton.commandkey       "n">
 
 <!ENTITY importButton.label         "Import…">
 <!ENTITY importButton.tooltip       "Import and append an existing style sheet to the document">
 <!ENTITY importButton.accesskey     "I">
 <!ENTITY importButton.commandkey    "i">
 
-<!ENTITY searchInput.tooltip        "Filter style sheets by name">
-<!ENTITY searchInput.placeholder    "Find style sheet">
-
-<!-- LOCALIZATION NOTE  (searchNoResults): This is shown when searching a term
-     that is not found in any stylesheet or stylesheet name. -->
-<!ENTITY searchNoResults.label      "No matching style sheet has been found.">
-
-<!-- LOCALIZATION NOTE  (searchClearButton): This button clears the search input
-     box and is visible only when a search term has been typed. -->
-<!ENTITY searchClearButton.label    "Clear">
-
 <!ENTITY visibilityToggle.tooltip   "Toggle style sheet visibility">
 <!ENTITY visibilityToggle.accesskey "V">
 
 <!ENTITY saveButton.label           "Save">
 <!ENTITY saveButton.tooltip         "Save this style sheet to a file">
 <!ENTITY saveButton.accesskey       "S">
 <!ENTITY saveButton.commandkey      "s">
 
@@ -55,8 +44,11 @@
      tip sentence shown when there is no stylesheet. It suggests to create a new
      stylesheet and provides an action link to do so. -->
 <!ENTITY noStyleSheet-tip-start.label  "Perhaps you'd like to ">
 <!-- LOCALICATION NOTE  (noStyleSheet-tip-action.label): This is text for the
      link that triggers creation of a new stylesheet. -->
 <!ENTITY noStyleSheet-tip-action.label "append a new style sheet">
 <!-- LOCALICATION NOTE  (noStyleSheet-tip-end.label): End of the tip sentence -->
 <!ENTITY noStyleSheet-tip-end.label    "?">
+
+<!-- LOCALIZATION NOTE  (closeCmd.key): Accel + this key closes the window. -->
+<!ENTITY closeCmd.key                  "W">
--- a/browser/modules/Makefile.in
+++ b/browser/modules/Makefile.in
@@ -47,16 +47,17 @@ include $(topsrcdir)/config/config.mk
 ifdef ENABLE_TESTS
 DIRS += test
 endif
 
 EXTRA_JS_MODULES = \
 	openLocationLastURL.jsm \
 	NetworkPrioritizer.jsm \
 	offlineAppCache.jsm \
+	TelemetryTimestamps.jsm \
 	$(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows) 
 EXTRA_JS_MODULES += \
 	WindowsPreviewPerTab.jsm \
 	WindowsJumpLists.jsm \
 	$(NULL)
 endif
new file mode 100644
--- /dev/null
+++ b/browser/modules/TelemetryTimestamps.jsm
@@ -0,0 +1,26 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+let EXPORTED_SYMBOLS = ["TelemetryTimestamps"];
+
+let TelemetryTimestamps = {
+  timeStamps: {},
+  add: function TT_add(name, value) {
+    // Default to "now" if not specified
+    if (value == null)
+      value = Date.now();
+
+    if (isNaN(value))
+      throw new Error("Value must be a timestamp");
+
+    // If there's an existing value, just ignore the new value.
+    if (this.timeStamps.hasOwnProperty(name))
+      return;
+
+    this.timeStamps[name] = value;
+  },
+  get: function TT_get() {
+    return JSON.parse(JSON.stringify(this.timeStamps));
+  }
+};
--- a/browser/modules/test/Makefile.in
+++ b/browser/modules/test/Makefile.in
@@ -40,16 +40,17 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = browser/modules/test
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_FILES = \
                  browser_NetworkPrioritizer.js \
+                 browser_TelemetryTimestamps.js \
                  $(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows) 
 _BROWSER_FILES += \
                  browser_taskbar_preview.js \
                  $(NULL)
 endif
 
new file mode 100644
--- /dev/null
+++ b/browser/modules/test/browser_TelemetryTimestamps.js
@@ -0,0 +1,62 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function getSimpleMeasurementsFromTelemetryPing() {
+  const TelemetryPing = Cc["@mozilla.org/base/telemetry-ping;1"].getService(Ci.nsIObserver);
+  let str = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString);
+  TelemetryPing.observe(str, "get-payload", "");
+
+  return JSON.parse(str.data).simpleMeasurements;
+}
+
+function test() {
+  // Test the module logic
+  Cu.import("resource:///modules/TelemetryTimestamps.jsm");
+  let now = Date.now();
+  TelemetryTimestamps.add("foo");
+  let fooValue = TelemetryTimestamps.get().foo;
+  ok(fooValue, "foo was added");
+  ok(fooValue >= now, "foo has a reasonable value");
+
+  // Add timestamp with value
+  TelemetryTimestamps.add("bar", 1);
+  ok(TelemetryTimestamps.get().bar, "bar was added");
+  is(TelemetryTimestamps.get().bar, 1, "bar has the right value");
+
+  // Can't add the same timestamp twice
+  TelemetryTimestamps.add("bar", 2);
+  is(TelemetryTimestamps.get().bar, 1, "bar wasn't overwritten");
+
+  let threw = false;
+  try {
+    TelemetryTimestamps.add("baz", "this isn't a number");
+  } catch (ex) {
+    threw = true;
+  }
+  ok(threw, "adding baz threw");
+  ok(!TelemetryTimestamps.get().baz, "no baz was added");
+
+  // Test that the data gets added to the telemetry ping properly
+  let simpleMeasurements = getSimpleMeasurementsFromTelemetryPing();
+  ok(simpleMeasurements, "got simple measurements from ping data");
+  is(simpleMeasurements.foo, fooValue, "foo was included");
+  is(simpleMeasurements.bar, 1, "bar was included");
+  ok(!simpleMeasurements.baz, "baz wasn't included since it wasn't added");
+
+  // Check browser timestamps that we add
+  let props = [
+    // These can't be reliably tested when the test is run alone
+    //"delayedStartupStarted",
+    //"delayedStartupFinished",
+    "sessionRestoreInitialized",
+    // This doesn't get hit in the testing profile
+    //"sessionRestoreRestoring"
+  ];
+
+  props.forEach(function (p) {
+    let value = simpleMeasurements[p];
+    ok(value, p + " exists");
+    ok(!isNaN(value), p + " is a number");
+    ok(value > 0 && value < Date.now(), p + " value is reasonable");
+  });
+}
deleted file mode 100644
index 2527df6e72b5c80b91e180af9644ba96a5c148d6..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 389f689aa2a7611f53977594c048f79c4991affd..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 2527df6e72b5c80b91e180af9644ba96a5c148d6..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 75d6f13d8c6e6a1cfc0d5766cfec91378e0b60c0..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 2527df6e72b5c80b91e180af9644ba96a5c148d6..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 33bb4a320e76cc7a346ca4beb60e89a85a48aa2c..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/build/autoconf/mozconfig2client-mk
+++ b/build/autoconf/mozconfig2client-mk
@@ -44,18 +44,16 @@
 # See mozconfig2configure for more details
 
 print_header() {
   _mozconfig=${MOZCONFIG:-$HOME/.mozconfig}
   cat >> $tmp_file <<EOF
 # gmake
 # This file is automatically generated for client.mk.
 # Do not edit. Edit $_mozconfig instead.
-# To create a new .mozconfig file, you can visit,
-#   http://webtools.mozilla.org/build/config.cgi
 
 EOF
 }
 
 ac_add_options() {
   echo "# $* is used by configure (not client.mk)" >> $tmp_file
 }
 
--- a/build/mobile/devicemanager.py
+++ b/build/mobile/devicemanager.py
@@ -57,252 +57,292 @@ class DMError(Exception):
 
   def __init__(self, msg= ''):
     self.msg = msg
 
   def __str__(self):
     return self.msg
 
 
+def abstractmethod(method):
+  line = method.func_code.co_firstlineno
+  filename = method.func_code.co_filename
+  def not_implemented(*args, **kwargs):
+    raise NotImplementedError('Abstract method %s at File "%s", line %s \
+                              should be implemented by a concrete class' %
+                              (repr(method), filename,line))
+    return not_implemented
+  
 class DeviceManager:
-  # external function
-  # returns:
-  #  success: True
-  #  failure: False
+  
+  @abstractmethod
   def pushFile(self, localname, destname):
-    assert 0 == 1
-    return False
-
-  # external function
-  # returns:
-  #  success: directory name
-  #  failure: None
+    """
+    external function
+    returns:
+    success: True
+    failure: False
+    """
+    
+  @abstractmethod
   def mkDir(self, name):
-      assert 0 == 1
-      return None
-
-  # make directory structure on the device
-  # external function
-  # returns:
-  #  success: directory structure that we created
-  #  failure: None
+    """
+    external function
+    returns:
+    success: directory name
+    failure: None
+    """
+    
+  @abstractmethod
   def mkDirs(self, filename):
-      assert 0 == 1
-      return None
-
-  # push localDir from host to remoteDir on the device
-  # external function
-  # returns:
-  #  success: remoteDir
-  #  failure: None
+    """
+    make directory structure on the device
+    external function
+    returns:
+    success: directory structure that we created
+    failure: None
+    """
+    
+  @abstractmethod
   def pushDir(self, localDir, remoteDir):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: True
-  #  failure: False
-  def dirExists(self, dirname):
-    assert 0 == 1
-    return False
-
-  # Because we always have / style paths we make this a lot easier with some
-  # assumptions
-  # external function
-  # returns:
-  #  success: True
-  #  failure: False
-  def fileExists(self, filepath):
-    assert 0 == 1
-    return False
+    """
+    push localDir from host to remoteDir on the device
+    external function
+    returns:
+    success: remoteDir
+    failure: None
+    """
 
-  # list files on the device, requires cd to directory first
-  # external function
-  # returns:
-  #  success: array of filenames, ['file1', 'file2', ...]
-  #  failure: []
+  @abstractmethod
+  def dirExists(self, dirname):
+    """
+    external function
+    returns:
+    success: True
+    failure: False
+    """
+    
+  @abstractmethod
+  def fileExists(self, filepath):
+    """
+    Because we always have / style paths we make this a lot easier with some
+    assumptions
+    external function
+    returns:
+    success: True
+    failure: False
+    """
+    
+  @abstractmethod
   def listFiles(self, rootdir):
-    assert 0 == 1
-    return []
-
-  # external function
-  # returns:
-  #  success: output of telnet, i.e. "removing file: /mnt/sdcard/tests/test.txt"
-  #  failure: None
+    """
+    list files on the device, requires cd to directory first
+    external function
+    returns:
+    success: array of filenames, ['file1', 'file2', ...]
+    failure: None
+    """
+  
+  @abstractmethod
   def removeFile(self, filename):
-    assert 0 == 1
-    return False
-
-  # does a recursive delete of directory on the device: rm -Rf remoteDir
-  # external function
-  # returns:
-  #  success: output of telnet, i.e. "removing file: /mnt/sdcard/tests/test.txt"
-  #  failure: None
+    """
+    external function
+    returns:
+    success: output of telnet, i.e. "removing file: /mnt/sdcard/tests/test.txt"
+    failure: None
+    """
+    
+  @abstractmethod
   def removeDir(self, remoteDir):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: array of process tuples
-  #  failure: []
+    """
+    does a recursive delete of directory on the device: rm -Rf remoteDir
+    external function
+    returns:
+    success: output of telnet, i.e. "removing file: /mnt/sdcard/tests/test.txt"
+    failure: None
+    """
+    
+  @abstractmethod
   def getProcessList(self):
-    assert 0 == 1
-    return []
-
-  # external function
-  # returns:
-  #  success: pid
-  #  failure: None
+    """
+    external function
+    returns:
+    success: array of process tuples
+    failure: None
+    """
+    
+  @abstractmethod
   def fireProcess(self, appname, failIfRunning=False):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: output filename
-  #  failure: None
+    """
+    external function
+    returns:
+    success: pid
+    failure: None
+    """
+    
+  @abstractmethod
   def launchProcess(self, cmd, outputFile = "process.txt", cwd = '', env = '', failIfRunning=False):
-    assert 0 == 1
-    return None
-
-  # loops until 'process' has exited or 'timeout' seconds is reached
-  # loop sleeps for 'interval' seconds between iterations
-  # external function
-  # returns:
-  #  success: [file contents, None]
-  #  failure: [None, None]
+    """
+    external function
+    returns:
+    success: output filename
+    failure: None
+    """
+    
   def communicate(self, process, timeout = 600, interval = 5):
+    """
+    loops until 'process' has exited or 'timeout' seconds is reached
+    loop sleeps for 'interval' seconds between iterations
+    external function
+    returns:
+    success: [file contents, None]
+    failure: [None, None]
+    """
+    
     timed_out = True
     if (timeout > 0):
       total_time = 0
       while total_time < timeout:
         time.sleep(interval)
         if self.processExist(process) == None:
           timed_out = False
           break
         total_time += interval
 
     if (timed_out == True):
       return [None, None]
 
     return [self.getFile(process, "temp.txt"), None]
 
-  # iterates process list and returns pid if exists, otherwise None
-  # external function
-  # returns:
-  #  success: pid
-  #  failure: None
   def processExist(self, appname):
+    """
+    iterates process list and returns pid if exists, otherwise None
+    external function
+    returns:
+    success: pid
+    failure: None
+    """
+    
     pid = None
 
     #filter out extra spaces
     parts = filter(lambda x: x != '', appname.split(' '))
     appname = ' '.join(parts)
 
     #filter out the quoted env string if it exists
     #ex: '"name=value;name2=value2;etc=..." process args' -> 'process args'
     parts = appname.split('"')
     if (len(parts) > 2):
       appname = ' '.join(parts[2:]).strip()
   
     pieces = appname.split(' ')
     parts = pieces[0].split('/')
     app = parts[-1]
+    procre = re.compile('.*' + app + '.*')
 
     procList = self.getProcessList()
     if (procList == []):
       return None
       
     for proc in procList:
-      procName = proc[1].split('/')[-1]
-      if (procName == app):
+      if (procre.match(proc[1])):
         pid = proc[0]
         break
     return pid
 
-  # external function
-  # returns:
-  #  success: output from testagent
-  #  failure: None
+
+  @abstractmethod
   def killProcess(self, appname):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: filecontents
-  #  failure: None
+    """
+    external function
+    returns:
+    success: output from testagent
+    failure: None
+    """
+    
+  @abstractmethod
   def catFile(self, remoteFile):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: output of pullfile, string
-  #  failure: None
+    """
+    external function
+    returns:
+    success: filecontents
+    failure: None
+    """
+    
+  @abstractmethod
   def pullFile(self, remoteFile):
-    assert 0 == 1
-    return None
-
-  # copy file from device (remoteFile) to host (localFile)
-  # external function
-  # returns:
-  #  success: output of pullfile, string
-  #  failure: None
+    """
+    external function
+    returns:
+    success: output of pullfile, string
+    failure: None
+    """
+    
+  @abstractmethod
   def getFile(self, remoteFile, localFile = ''):
-    assert 0 == 1
-    return None
-
-  # copy directory structure from device (remoteDir) to host (localDir)
-  # external function
-  # checkDir exists so that we don't create local directories if the
-  # remote directory doesn't exist but also so that we don't call isDir
-  # twice when recursing.
-  # returns:
-  #  success: list of files, string
-  #  failure: None
+    """
+    copy file from device (remoteFile) to host (localFile)
+    external function
+    returns:
+    success: output of pullfile, string
+    failure: None
+    """
+    
+  @abstractmethod
   def getDirectory(self, remoteDir, localDir, checkDir=True):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: True
-  #  failure: False
-  #  Throws a FileError exception when null (invalid dir/filename)
+    """
+    copy directory structure from device (remoteDir) to host (localDir)
+    external function
+    checkDir exists so that we don't create local directories if the
+    remote directory doesn't exist but also so that we don't call isDir
+    twice when recursing.
+    returns:
+    success: list of files, string
+    failure: None
+    """
+    
+  @abstractmethod
   def isDir(self, remotePath):
-    assert 0 == 1
-    return False
-
-  # true/false check if the two files have the same md5 sum
-  # external function
-  # returns:
-  #  success: True
-  #  failure: False
+    """
+    external function
+    returns:
+    success: True
+    failure: False
+    Throws a FileError exception when null (invalid dir/filename)
+    """
+    
+  @abstractmethod
   def validateFile(self, remoteFile, localFile):
-    assert 0 == 1
-    return False
-
-  # return the md5 sum of a remote file
-  # internal function
-  # returns:
-  #  success: MD5 hash for given filename
-  #  failure: None
+    """
+    true/false check if the two files have the same md5 sum
+    external function
+    returns:
+    success: True
+    failure: False
+    """
+    
+  @abstractmethod
   def getRemoteHash(self, filename):
-    assert 0 == 1
-    return None
-
-  # return the md5 sum of a file on the host
-  # internal function
-  # returns:
-  #  success: MD5 hash for given filename
-  #  failure: None
+    """
+    return the md5 sum of a remote file
+    internal function
+    returns:
+    success: MD5 hash for given filename
+    failure: None
+    """
+    
   def getLocalHash(self, filename):
+    """
+    return the md5 sum of a file on the host
+    internal function
+    returns:
+    success: MD5 hash for given filename
+    failure: None
+    """
+    
     file = open(filename, 'rb')
     if (file == None):
       return None
 
     try:
       mdsum = hashlib.md5()
     except:
       return None
@@ -312,162 +352,201 @@ class DeviceManager:
       if not data:
         break
       mdsum.update(data)
 
     file.close()
     hexval = mdsum.hexdigest()
     if (self.debug >= 3): print "local hash returned: '" + hexval + "'"
     return hexval
-  # Gets the device root for the testing area on the device
-  # For all devices we will use / type slashes and depend on the device-agent
-  # to sort those out.  The agent will return us the device location where we
-  # should store things, we will then create our /tests structure relative to
-  # that returned path.
-  # Structure on the device is as follows:
-  # /tests
-  #       /<fennec>|<firefox>  --> approot
-  #       /profile
-  #       /xpcshell
-  #       /reftest
-  #       /mochitest
-  #
-  # external function
-  # returns:
-  #  success: path for device root
-  #  failure: None
+  
+  @abstractmethod
   def getDeviceRoot(self):
-    assert 0 == 1
+    """
+    Gets the device root for the testing area on the device
+    For all devices we will use / type slashes and depend on the device-agent
+    to sort those out.  The agent will return us the device location where we
+    should store things, we will then create our /tests structure relative to
+    that returned path.
+    Structure on the device is as follows:
+    /tests
+          /<fennec>|<firefox>  --> approot
+          /profile
+          /xpcshell
+          /reftest
+          /mochitest
+    external 
+    returns:
+    success: path for device root
+    failure: None
+    """
+  
+  def getAppRoot(self):
+    """
+    Either we will have /tests/fennec or /tests/firefox but we will never have
+    both.  Return the one that exists
+    TODO: ensure we can support org.mozilla.firefox
+    external function
+    returns:
+    success: path for app root
+    failure: None
+    """
+    
+    devroot = self.getDeviceRoot()
+    if (devroot == None):
+      return None
+
+    if (self.dirExists(devroot + '/fennec')):
+      return devroot + '/fennec'
+    elif (self.dirExists(devroot + '/firefox')):
+      return devroot + '/firefox'
+    elif (self.dirExsts('/data/data/org.mozilla.fennec')):
+      return 'org.mozilla.fennec'
+    elif (self.dirExists('/data/data/org.mozilla.firefox')):
+      return 'org.mozilla.firefox'
+    elif (self.dirExists('/data/data/org.mozilla.fennec_aurora')):
+      return 'org.mozilla.fennec_aurora'
+    elif (self.dirExists('/data/data/org.mozilla.firefox_beta')):
+      return 'org.mozilla.firefox_beta'
+
+    # Failure (either not installed or not a recognized platform)
     return None
 
-  # Either we will have /tests/fennec or /tests/firefox but we will never have
-  # both.  Return the one that exists
-  # TODO: ensure we can support org.mozilla.firefox
-  # external function
-  # returns:
-  #  success: path for app root
-  #  failure: None
-  def getAppRoot(self):
-    assert 0 == 1
-    return None
-
-  # Gets the directory location on the device for a specific test type
-  # Type is one of: xpcshell|reftest|mochitest
-  # external function
-  # returns:
-  #  success: path for test root
-  #  failure: None
   def getTestRoot(self, type):
+    """
+    Gets the directory location on the device for a specific test type
+    Type is one of: xpcshell|reftest|mochitest
+    external function
+    returns:
+    success: path for test root
+    failure: None
+    """
+    
     devroot = self.getDeviceRoot()
     if (devroot == None):
       return None
 
     if (re.search('xpcshell', type, re.I)):
       self.testRoot = devroot + '/xpcshell'
     elif (re.search('?(i)reftest', type)):
       self.testRoot = devroot + '/reftest'
     elif (re.search('?(i)mochitest', type)):
       self.testRoot = devroot + '/mochitest'
     return self.testRoot
 
-  # Sends a specific process ID a signal code and action.
-  # For Example: SIGINT and SIGDFL to process x
   def signal(self, processID, signalType, signalAction):
-    # currently not implemented in device agent - todo
+    """
+    Sends a specific process ID a signal code and action.
+    For Example: SIGINT and SIGDFL to process x
+    """
+    #currently not implemented in device agent - todo
+    
     pass
 
-  # Get a return code from process ending -- needs support on device-agent
   def getReturnCode(self, processID):
+    """Get a return code from process ending -- needs support on device-agent"""
     # TODO: make this real
+    
     return 0
 
-  # external function
-  # returns:
-  #  success: output of unzip command
-  #  failure: None
+  @abstractmethod
   def unpackFile(self, filename):
-    return None
-
-  # external function
-  # returns:
-  #  success: status from test agent
-  #  failure: None
+    """
+    external function
+    returns:
+    success: output of unzip command
+    failure: None
+    """
+    
+  @abstractmethod
   def reboot(self, ipAddr=None, port=30000):
-    assert 0 == 1
-    return None
-
-  # validate localDir from host to remoteDir on the device
-  # external function
-  # returns:
-  #  success: True
-  #  failure: False
+    """
+    external function
+    returns:
+    success: status from test agent
+    failure: None
+    """
+    
   def validateDir(self, localDir, remoteDir):
+    """
+    validate localDir from host to remoteDir on the device
+    external function
+    returns:
+    success: True
+    failure: False
+    """
+    
     if (self.debug >= 2): print "validating directory: " + localDir + " to " + remoteDir
     for root, dirs, files in os.walk(localDir):
       parts = root.split(localDir)
       for file in files:
         remoteRoot = remoteDir + '/' + parts[1]
         remoteRoot = remoteRoot.replace('/', '/')
         if (parts[1] == ""): remoteRoot = remoteDir
         remoteName = remoteRoot + '/' + file
         if (self.validateFile(remoteName, os.path.join(root, file)) <> True):
             return False
     return True
-
-  # Returns information about the device:
-  # Directive indicates the information you want to get, your choices are:
-  # os - name of the os
-  # id - unique id of the device
-  # uptime - uptime of the device
-  # systime - system time of the device
-  # screen - screen resolution
-  # memory - memory stats
-  # process - list of running processes (same as ps)
-  # disk - total, free, available bytes on disk
-  # power - power status (charge, battery temp)
-  # all - all of them - or call it with no parameters to get all the information
-  # returns:
-  #   success: dict of info strings by directive name
-  #   failure: {}
+    
+  @abstractmethod
   def getInfo(self, directive=None):
-    assert 0 == 1
-    return {}
-
-  # external function
-  # returns:
-  #  success: output from agent for inst command
-  #  failure: None
+    """
+    Returns information about the device:
+    Directive indicates the information you want to get, your choices are:
+    os - name of the os
+    id - unique id of the device
+    uptime - uptime of the device
+    systime - system time of the device
+    screen - screen resolution
+    memory - memory stats
+    process - list of running processes (same as ps)
+    disk - total, free, available bytes on disk
+    power - power status (charge, battery temp)
+    all - all of them - or call it with no parameters to get all the information
+    returns:
+    success: dict of info strings by directive name
+    failure: None
+    """
+    
+  @abstractmethod
   def installApp(self, appBundlePath, destPath=None):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: True
-  #  failure: None
+    """
+    external function
+    returns:
+    success: output from agent for inst command
+    failure: None
+    """
+    
+  @abstractmethod
   def uninstallAppAndReboot(self, appName, installPath=None):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: text status from command or callback server
-  #  failure: None
-  def updateApp(self, appBundlePath, processName=None, destPath=None, ipAddr=None, port=30000):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: time in ms
-  #  failure: None
+    """
+    external function
+    returns:
+    success: True
+    failure: None
+    """
+    
+  @abstractmethod
+  def updateApp(self, appBundlePath, processName=None,
+                destPath=None, ipAddr=None, port=30000):
+    """
+    external function
+    returns:
+    success: text status from command or callback server
+    failure: None
+    """
+  
+  @abstractmethod
   def getCurrentTime(self):
-    assert 0 == 1
-    return None
-
+    """
+    external function
+    returns:
+    success: time in ms
+    failure: None
+    """
 
 class NetworkTools:
   def __init__(self):
     pass
 
   # Utilities to get the local ip address
   def getInterfaceIp(self, ifname):
     if os.name != "nt":
@@ -478,20 +557,17 @@ class NetworkTools:
                               s.fileno(),
                               0x8915,  # SIOCGIFADDR
                               struct.pack('256s', ifname[:15])
                               )[20:24])
     else:
       return None
 
   def getLanIp(self):
-    try:
-      ip = socket.gethostbyname(socket.gethostname())
-    except socket.gaierror:
-      ip = socket.gethostbyname(socket.gethostname() + ".local") # for Mac OS X
+    ip = socket.gethostbyname(socket.gethostname())
     if ip.startswith("127.") and os.name != "nt":
       interfaces = ["eth0","eth1","eth2","wlan0","wlan1","wifi0","ath0","ath1","ppp0"]
       for ifname in interfaces:
         try:
           ip = self.getInterfaceIp(ifname)
           break;
         except IOError:
           pass
@@ -516,9 +592,8 @@ class NetworkTools:
           if seed > maxportnum:
             print "Could not find open port after checking 5000 ports"
           raise
         seed += 1
     except:
       print "Socket error trying to find open port"
         
     return seed
-
--- a/build/mobile/devicemanagerADB.py
+++ b/build/mobile/devicemanagerADB.py
@@ -110,24 +110,27 @@ class DeviceManagerADB(DeviceManager):
     # adb "push" accepts a directory as an argument, but if the directory
     # contains symbolic links, the links are pushed, rather than the linked
     # files; we either zip/unzip or push file-by-file to get around this 
     # limitation
     try:
       if (not self.dirExists(remoteDir)):
         self.mkDirs(remoteDir+"/x")
       if (self.useZip):
-        localZip = tempfile.mktemp()+".zip"
-        remoteZip = remoteDir + "/adbdmtmp.zip"
-        subprocess.check_output(["zip", "-r", localZip, '.'], cwd=localDir)
-        self.pushFile(localZip, remoteZip)
-        os.remove(localZip)
-        data = self.runCmdAs(["shell", "unzip", "-o", remoteZip, "-d", remoteDir]).stdout.read()
-        self.checkCmdAs(["shell", "rm", remoteZip])
-        if (re.search("unzip: exiting", data) or re.search("Operation not permitted", data)):
+        try:
+          localZip = tempfile.mktemp()+".zip"
+          remoteZip = remoteDir + "/adbdmtmp.zip"
+          subprocess.check_output(["zip", "-r", localZip, '.'], cwd=localDir)
+          self.pushFile(localZip, remoteZip)
+          os.remove(localZip)
+          data = self.runCmdAs(["shell", "unzip", "-o", remoteZip, "-d", remoteDir]).stdout.read()
+          self.checkCmdAs(["shell", "rm", remoteZip])
+          if (re.search("unzip: exiting", data) or re.search("Operation not permitted", data)):
+            raise Exception("unzip failed, or permissions error")
+        except:
           print "zip/unzip failure: falling back to normal push"
           self.useZip = False
           self.pushDir(localDir, remoteDir)
       else:
         for root, dirs, files in os.walk(localDir, followlinks='true'):
           relRoot = os.path.relpath(root, localDir)
           for file in files:
             localFile = os.path.join(root, file)
--- a/build/mobile/robocop/Makefile.in
+++ b/build/mobile/robocop/Makefile.in
@@ -40,17 +40,17 @@ topsrcdir   = @top_srcdir@
 srcdir      = @srcdir@
 VPATH       = @srcdir@
 TESTPATH    = $(topsrcdir)/mobile/android/base/tests
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = robocop
 
-ROBOTIUM_PATH = $(srcdir)/robotium-solo-3.0.jar
+ROBOTIUM_PATH = $(srcdir)/robotium-solo-3.1.jar
 
 JAVAFILES = \
   R.java \
 
 _JAVA_HARNESS = \
   Actions.java \
   Assert.java \
   Driver.java \
--- a/build/mobile/robocop/README
+++ b/build/mobile/robocop/README
@@ -1,9 +1,9 @@
 Robocop is a Mozilla project which uses Robotium to test Firefox on Android devices.
 
 Robotium is an open source tool licensed under the Apache 2.0 license and the original 
 source can be found here:
 http://code.google.com/p/robotium/
 
-We are including robotium-solo-3.0.jar as a binary and are not modifying it in anyway 
+We are including robotium-solo-3.1.jar as a binary and are not modifying it in anyway 
 from the original download found at: 
 http://code.google.com/p/robotium/
deleted file mode 100644
index 3305251f61d61702e0f3dd61f67eb11e984ac587..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0ba05859b90a8c29ca519e228674db9aebe69d90
GIT binary patch
literal 49691
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
KV6(Nqwf+y-lXzPI
--- a/build/unix/build-toolchain/build-gcc.py
+++ b/build/unix/build-toolchain/build-gcc.py
@@ -66,16 +66,24 @@ def build_one_stage(env, stage_dir):
                    "--with-mpfr=%s" % lib_inst_dir])
 
     tool_inst_dir = stage_dir + '/inst'
 
     binutils_build_dir = stage_dir + '/binutils'
     build_package(binutils_source_dir, binutils_build_dir,
                   ["--prefix=%s" % tool_inst_dir])
 
+    glibc_build_dir = stage_dir + '/glibc'
+    build_package(glibc_source_dir, glibc_build_dir,
+                  ["--disable-profile",
+                   "--enable-add-ons=nptl",
+                   "--without-selinux",
+                   "--enable-kernel=2.6.25",
+                   "--prefix=%s" % tool_inst_dir])
+
     gcc_build_dir = stage_dir + '/gcc'
     build_package(gcc_source_dir, gcc_build_dir,
                   ["--prefix=%s" % tool_inst_dir,
                    "--enable-__cxa_atexit",
                    "--with-gmp=%s" % lib_inst_dir,
                    "--with-mpfr=%s" % lib_inst_dir,
                    "--with-mpc=%s" % lib_inst_dir,
                    "--enable-languages=c,c++",
@@ -91,54 +99,61 @@ def build_tar_package(tar, name, base, d
 ##############################################
 
 source_dir = os.path.realpath('src')
 
 def build_source_dir(prefix, version):
     return source_dir + '/' + prefix + version
 
 binutils_version = "2.21.1"
+glibc_version = "2.13" #FIXME: should probably use 2.5.1
 tar_version = "1.26"
 gcc_version = "4.5.2"
 mpfr_version = "2.4.2"
 gmp_version = "5.0.1"
 mpc_version = "0.8.1"
 
 binutils_source_uri = "http://ftp.gnu.org/gnu/binutils/binutils-%sa.tar.bz2" % \
     binutils_version
+glibc_source_uri = "http://ftp.gnu.org/gnu/glibc/glibc-%s.tar.bz2" % \
+    glibc_version
 tar_source_uri = "http://ftp.gnu.org/gnu/tar/tar-%s.tar.bz2" % \
     tar_version
 gcc_source_uri = "http://ftp.gnu.org/gnu/gcc/gcc-%s/gcc-%s.tar.bz2" % \
     (gcc_version, gcc_version)
 mpfr_source_uri = "http://www.mpfr.org/mpfr-%s/mpfr-%s.tar.bz2" % \
     (mpfr_version, mpfr_version)
 gmp_source_uri = "http://ftp.gnu.org/gnu/gmp/gmp-%s.tar.bz2" % gmp_version
 mpc_source_uri = "http://www.multiprecision.org/mpc/download/mpc-%s.tar.gz" % \
     mpc_version
 
 binutils_source_tar = download_uri(binutils_source_uri)
+glibc_source_tar = download_uri(glibc_source_uri)
 tar_source_tar = download_uri(tar_source_uri)
 mpc_source_tar = download_uri(mpc_source_uri)
 mpfr_source_tar = download_uri(mpfr_source_uri)
 gmp_source_tar = download_uri(gmp_source_uri)
 gcc_source_tar = download_uri(gcc_source_uri)
 
 build_dir = os.path.realpath('build')
 
 binutils_source_dir  = build_source_dir('binutils-', binutils_version)
+glibc_source_dir  = build_source_dir('glibc-', glibc_version)
 tar_source_dir  = build_source_dir('tar-', tar_version)
 mpc_source_dir  = build_source_dir('mpc-', mpc_version)
 mpfr_source_dir = build_source_dir('mpfr-', mpfr_version)
 gmp_source_dir  = build_source_dir('gmp-', gmp_version)
 gcc_source_dir  = build_source_dir('gcc-', gcc_version)
 
 if not os.path.exists(source_dir):
     os.mkdir(source_dir)
     extract(binutils_source_tar, source_dir)
     patch('binutils-deterministic.patch', 1, binutils_source_dir)
+    extract(glibc_source_tar, source_dir)
+    patch('glibc-deterministic.patch', 1, glibc_source_dir)
     extract(tar_source_tar, source_dir)
     extract(mpc_source_tar, source_dir)
     extract(mpfr_source_tar, source_dir)
     extract(gmp_source_tar, source_dir)
     extract(gcc_source_tar, source_dir)
     patch('plugin_finish_decl.diff', 0, gcc_source_dir)
     patch('pr49911.diff', 1, gcc_source_dir)
     patch('r159628-r163231-r171807.patch', 1, gcc_source_dir)
@@ -153,12 +168,13 @@ build_tar(build_dir, tar_inst_dir)
 stage1_dir = build_dir + '/stage1'
 build_one_stage({"CC": "gcc", "CXX" : "g++"}, stage1_dir)
 
 stage1_tool_inst_dir = stage1_dir + '/inst'
 stage2_dir = build_dir + '/stage2'
 build_one_stage({"CC"     : stage1_tool_inst_dir + "/bin/gcc",
                  "CXX"    : stage1_tool_inst_dir + "/bin/g++",
                  "AR"     : stage1_tool_inst_dir + "/bin/ar",
-                 "RANLIB" : "true" })
+                 "RANLIB" : "true" },
+                stage2_dir)
 
 build_tar_package(tar_inst_dir + "/bin/tar",
                   "toolchain.tar", stage2_dir, "inst")
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -143,16 +143,17 @@ MOZ_UPDATER	= @MOZ_UPDATER@
 MOZ_UPDATE_CHANNEL	= @MOZ_UPDATE_CHANNEL@
 MOZ_UPDATE_PACKAGING	= @MOZ_UPDATE_PACKAGING@
 MOZ_DISABLE_PARENTAL_CONTROLS = @MOZ_DISABLE_PARENTAL_CONTROLS@
 NS_ENABLE_TSF = @NS_ENABLE_TSF@
 MOZ_SPELLCHECK = @MOZ_SPELLCHECK@
 MOZ_ANDROID_HISTORY = @MOZ_ANDROID_HISTORY@
 MOZ_WEBSMS_BACKEND = @MOZ_WEBSMS_BACKEND@
 MOZ_JAVA_COMPOSITOR = @MOZ_JAVA_COMPOSITOR@
+MOZ_ONLY_TOUCH_EVENTS = @MOZ_ONLY_TOUCH_EVENTS@
 MOZ_TOUCH = @MOZ_TOUCH@
 MOZ_PROFILELOCKING = @MOZ_PROFILELOCKING@
 MOZ_FEEDS = @MOZ_FEEDS@
 MOZ_TOOLKIT_SEARCH = @MOZ_TOOLKIT_SEARCH@
 MOZ_PLACES = @MOZ_PLACES@
 MOZ_SAFE_BROWSING = @MOZ_SAFE_BROWSING@
 MOZ_URL_CLASSIFIER = @MOZ_URL_CLASSIFIER@
 MOZ_ZIPWRITER = @MOZ_ZIPWRITER@
--- a/config/expandlibs.py
+++ b/config/expandlibs.py
@@ -81,16 +81,21 @@ def relativize(path):
         del abspath[0]
     if not curdir and not abspath:
         return '.'
     relpath = os.path.join(*[os.pardir for i in curdir] + abspath)
     if len(path) > len(relpath):
         return relpath
     return path
 
+def isObject(path):
+    '''Returns whether the given path points to an object file, that is,
+    ends with OBJ_SUFFIX or .i_o'''
+    return os.path.splitext(path)[1] in [conf.OBJ_SUFFIX, '.i_o']
+
 class LibDescriptor(dict):
     KEYS = ['OBJS', 'LIBS']
 
     def __init__(self, content=None):
         '''Creates an instance of a lib descriptor, initialized with contents
         from a list of strings when given. This is intended for use with
         file.readlines()'''
         if isinstance(content, list) and all([isinstance(item, str) for item in content]):
--- a/config/expandlibs_exec.py
+++ b/config/expandlibs_exec.py
@@ -51,17 +51,17 @@ See https://bugzilla.mozilla.org/show_bu
 
 With the --reorder argument, followed by a file name, it will reorder the
 object files from the command line according to the order given in the file.
 Implies --extract.
 '''
 from __future__ import with_statement
 import sys
 import os
-from expandlibs import ExpandArgs, relativize
+from expandlibs import ExpandArgs, relativize, isObject
 import expandlibs_config as conf
 from optparse import OptionParser
 import subprocess
 import tempfile
 import shutil
 
 class ExpandArgsMore(ExpandArgs):
     ''' Meant to be used as 'with ExpandArgsMore(args) as ...: '''
@@ -92,29 +92,29 @@ class ExpandArgsMore(ExpandArgs):
                 if os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
                     newlist += self._extract(self._expand_desc(arg))
                 elif os.path.exists(arg) and len(ar_extract):
                     tmp = tempfile.mkdtemp(dir=os.curdir)
                     self.tmp.append(tmp)
                     subprocess.call(ar_extract + [os.path.abspath(arg)], cwd=tmp)
                     objs = []
                     for root, dirs, files in os.walk(tmp):
-                        objs += [relativize(os.path.join(root, f)) for f in files if os.path.splitext(f)[1] in [conf.OBJ_SUFFIX, '.i_o']]
+                        objs += [relativize(os.path.join(root, f)) for f in files if isObject(f)]
                     newlist += objs
                 else:
                     newlist += [arg]
             else:
                 newlist += [arg]
         return newlist
 
     def makelist(self):
         '''Replaces object file names with a temporary list file, using a
         list format depending on the EXPAND_LIBS_LIST_STYLE variable
         '''
-        objs = [o for o in self if os.path.splitext(o)[1] == conf.OBJ_SUFFIX]
+        objs = [o for o in self if isObject(o)]
         if not len(objs): return
         fd, tmp = tempfile.mkstemp(suffix=".list",dir=os.curdir)
         if conf.EXPAND_LIBS_LIST_STYLE == "linkerscript":
             content = ["INPUT(%s)\n" % obj for obj in objs]
             ref = tmp
         elif conf.EXPAND_LIBS_LIST_STYLE == "list":
             content = ["%s\n" % obj for obj in objs]
             ref = "@" + tmp
@@ -129,25 +129,25 @@ class ExpandArgsMore(ExpandArgs):
         newlist = self[0:idx] + [ref] + [item for item in self[idx:] if item not in objs]
         self[0:] = newlist
 
     def reorder(self, order_list):
         '''Given a list of file names without OBJ_SUFFIX, rearrange self
         so that the object file names it contains are ordered according to
         that list.
         '''
-        objs = [o for o in self if o.endswith(conf.OBJ_SUFFIX)]
+        objs = [o for o in self if isObject(o)]
         if not objs: return
         idx = self.index(objs[0])
         # Keep everything before the first object, then the ordered objects,
         # then any other objects, then any non-objects after the first object
         objnames = dict([(os.path.splitext(os.path.basename(o))[0], o) for o in objs])
         self[0:] = self[0:idx] + [objnames[o] for o in order_list if o in objnames] + \
                    [o for o in objs if os.path.splitext(os.path.basename(o))[0] not in order_list] + \
-                   [x for x in self[idx:] if not x.endswith(conf.OBJ_SUFFIX)]
+                   [x for x in self[idx:] if not isObject(x)]
 
 
 def main():
     parser = OptionParser()
     parser.add_option("--extract", action="store_true", dest="extract",
         help="when a library has no descriptor file, extract it first, when possible")
     parser.add_option("--uselist", action="store_true", dest="uselist",
         help="use a list file for objects when executing a command")
--- a/config/expandlibs_gen.py
+++ b/config/expandlibs_gen.py
@@ -36,22 +36,22 @@
 # ***** END LICENSE BLOCK *****
 
 '''Given a list of object files and library names, prints a library
 descriptor to standard output'''
 
 import sys
 import os
 import expandlibs_config as conf
-from expandlibs import LibDescriptor
+from expandlibs import LibDescriptor, isObject
 
 def generate(args):
     desc = LibDescriptor()
     for arg in args:
-        if os.path.splitext(arg)[1] in [conf.OBJ_SUFFIX, '.i_o']:
+        if isObject(arg):
             desc['OBJS'].append(os.path.abspath(arg))
         elif os.path.splitext(arg)[1] == conf.LIB_SUFFIX and \
              (os.path.exists(arg) or os.path.exists(arg + conf.LIBS_DESC_SUFFIX)):
             desc['LIBS'].append(os.path.abspath(arg))
     return desc
 
 if __name__ == '__main__':
     print generate(sys.argv[1:])
--- a/configure.in
+++ b/configure.in
@@ -124,17 +124,17 @@ GTK2_VERSION=2.10.0
 WINDRES_VERSION=2.14.90
 W32API_VERSION=3.14
 GNOMEVFS_VERSION=2.0
 GNOMEUI_VERSION=2.2.0
 GCONF_VERSION=1.2.1
 GIO_VERSION=2.18
 STARTUP_NOTIFICATION_VERSION=0.8
 DBUS_VERSION=0.60
-SQLITE_VERSION=3.7.7.1
+SQLITE_VERSION=3.7.10
 LIBNOTIFY_VERSION=0.4
 
 MSMANIFEST_TOOL=
 
 dnl Set various checks
 dnl ========================================================
 MISSING_X=
 AC_PROG_AWK
@@ -1819,19 +1819,33 @@ if test "$OS_TARGET" = "Android"; then
        AC_MSG_ERROR([Couldn't find path to stlport in the android ndk])
     fi
     CPPFLAGS="$CPPFLAGS $STLPORT_CPPFLAGS"
     LDFLAGS="$LDFLAGS $STLPORT_LDFLAGS"
     LIBS="$LIBS $STLPORT_LIBS"
 fi
 
 dnl ========================================================
+dnl Suppress Clang Argument Warnings
+dnl ========================================================
+if test -n "$CLANG_CC"; then
+    _WARNINGS_CFLAGS="-Qunused-arguments ${_WARNINGS_CFLAGS}"
+    CPPFLAGS="-Qunused-arguments ${CPPFLAGS}"
+fi
+if test -n "$CLANG_CXX"; then
+    _WARNINGS_CXXFLAGS="-Qunused-arguments ${_WARNINGS_CXXFLAGS}"
+fi
+
+dnl ========================================================
 dnl GNU specific defaults
 dnl ========================================================
 if test "$GNU_CC"; then
+    # Per bug 719659 comment 2, some of the headers on ancient build machines
+    # require gnu89 inline semantics.  But otherwise, we use C99.
+    CFLAGS="$CFLAGS -std=gnu99 -fgnu89-inline"
     # FIXME: Let us build with strict aliasing. bug 414641.
     CFLAGS="$CFLAGS -fno-strict-aliasing"
     MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$@ -o $@'
     MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$@ -o $@'
     DSO_LDOPTS='-shared'
     if test "$GCC_USE_GNU_LD"; then
         # Don't allow undefined symbols in libraries
         DSO_LDOPTS="$DSO_LDOPTS -Wl,-z,defs"
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1447,23 +1447,16 @@ public:
   /**
    * Increases the count of blockers preventing scripts from running.
    * NOTE: You might want to use nsAutoScriptBlocker rather than calling
    * this directly
    */
   static void AddScriptBlocker();
 
   /**
-   * Increases the count of blockers preventing scripts from running.
-   * Also, while this script blocker is active, script runners must not be
-   * added --- we'll assert if one is, and ignore it.
-   */
-  static void AddScriptBlockerAndPreventAddingRunners();
-
-  /**
    * Decreases the count of blockers preventing scripts from running.
    * NOTE: You might want to use nsAutoScriptBlocker rather than calling
    * this directly
    *
    * WARNING! Calling this function could synchronously execute scripts.
    */
   static void RemoveScriptBlocker();
 
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -1595,16 +1595,18 @@ public:
   enum DeprecatedOperations {
 #include "nsDeprecatedOperationList.h"
     eDeprecatedOperationCount
   };
 #undef DEPRECATED_OPERATION
   void WarnOnceAbout(DeprecatedOperations aOperation);
 
   virtual void PostVisibilityUpdateEvent() = 0;
+  
+  bool IsSyntheticDocument() { return mIsSyntheticDocument; }
 
   void SetNeedLayoutFlush() {
     mNeedLayoutFlush = true;
     if (mDisplayDocument) {
       mDisplayDocument->SetNeedLayoutFlush();
     }
   }
 
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -374,16 +374,21 @@ public:
 
   /**
    * Return this node as an Element.  Should only be used for nodes
    * for which IsElement() is true.
    */
   mozilla::dom::Element* AsElement();
 
   /**
+   * Return if this node has any children.
+   */
+  bool HasChildren() const { return !!mFirstChild; }
+
+  /**
    * Get the number of children
    * @return the number of children
    */
   virtual PRUint32 GetChildCount() const = 0;
 
   /**
    * Get a child by index
    * @param aIndex the index of the child to get
--- a/content/base/public/nsISelectionController.idl
+++ b/content/base/public/nsISelectionController.idl
@@ -1,11 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** 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,
@@ -42,21 +41,22 @@
 #include "nsISelection.idl"
 #include "nsISelectionDisplay.idl"
 
 %{C++
 typedef short SelectionType;
 typedef short SelectionRegion;
 %}
 
+interface nsIContent;
 interface nsIDOMNode;
 interface nsISelection;
 interface nsISelectionDisplay;
 
-[scriptable, uuid(cf30315f-b65d-44c3-8c57-557e36d18fd2)]
+[scriptable, uuid(b1ff7faa-8097-431d-b7f1-b0615e3cd596)]
 interface nsISelectionController : nsISelectionDisplay
 {
    const short SELECTION_NONE=0;
    const short SELECTION_NORMAL=1;
    const short SELECTION_SPELLCHECK=2;
    const short SELECTION_IME_RAWINPUT=4;
    const short SELECTION_IME_SELECTEDRAWTEXT=8;
    const short SELECTION_IME_CONVERTEDTEXT=16;
@@ -271,15 +271,16 @@ interface nsISelectionController : nsISe
   /** CheckVisibility will return true if textnode and offsets are actually rendered 
    *  in the current precontext.
    *  @param aNode textNode to test
    *  @param aStartOffset  offset in dom to first char of textnode to test
    *  @param aEndOffset    offset in dom to last char of textnode to test
    *  @param aReturnBool   boolean returned TRUE if visible FALSE if not
    */
     boolean checkVisibility(in nsIDOMNode node, in short startOffset, in short endOffset);
+    [noscript,nostdcall] boolean checkVisibilityContent(in nsIContent node, in short startOffset, in short endOffset);
 
 };
 %{ C++
    #define NS_ISELECTIONCONTROLLER_CID \
    { 0x513b9460, 0xd56a, 0x4c4e, \
    { 0xb6, 0xf9, 0x0b, 0x8a, 0xe4, 0x37, 0x2a, 0x3b }}
 %}
--- a/content/base/src/Link.h
+++ b/content/base/src/Link.h
@@ -46,18 +46,18 @@
 
 #include "mozilla/dom/Element.h"
 #include "mozilla/IHistory.h"
 
 namespace mozilla {
 namespace dom {
 
 #define MOZILLA_DOM_LINK_IMPLEMENTATION_IID \
-  { 0xa687a99c, 0x3893, 0x45c0, \
-    {0x8e, 0xab, 0xb8, 0xf7, 0xd7, 0x9e, 0x9e, 0x7b } }
+  { 0x7EA57721, 0xE373, 0x458E, \
+    {0x8F, 0x44, 0xF8, 0x96, 0x56, 0xB4, 0x14, 0xF5 } }
 
 class Link : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOM_LINK_IMPLEMENTATION_IID)
 
   static const nsLinkState defaultState = eLinkState_Unknown;
 
@@ -108,16 +108,34 @@ public:
    *        true if ResetLinkState should notify the owning document about style
    *        changes or false if it should not.
    */
   void ResetLinkState(bool aNotify);
   
   // This method nevers returns a null element.
   Element* GetElement() const { return mElement; }
 
+  /**
+   * DNS prefetch has been deferred until later, e.g. page load complete.
+   */
+  virtual void OnDNSPrefetchDeferred() { /*do nothing*/ }
+  
+  /**
+   * DNS prefetch has been submitted to Host Resolver.
+   */
+  virtual void OnDNSPrefetchRequested() { /*do nothing*/ }
+
+  /**
+   * Checks if DNS Prefetching is ok
+   * 
+   * @returns boolean
+   *          Defaults to true; should be overridden for specialised cases
+   */
+  virtual bool HasDeferredDNSPrefetchRequest() { return true; }
+
 protected:
   virtual ~Link();
 
   bool HasCachedURI() const { return !!mCachedURI; }
 
 private:
   /**
    * Unregisters from History so this node no longer gets notifications about
--- a/content/base/src/mozSanitizingSerializer.cpp
+++ b/content/base/src/mozSanitizingSerializer.cpp
@@ -312,22 +312,16 @@ mozSanitizingHTMLSerializer::AddLeaf(con
   eHTMLTags type = (eHTMLTags)aNode.GetNodeType();
   const nsAString& text = aNode.GetText();
 
   mParserNode = const_cast<nsIParserNode*>(&aNode);
   return DoAddLeaf(type, text);
 }
 
 NS_IMETHODIMP 
-mozSanitizingHTMLSerializer::AddDocTypeDecl(const nsIParserNode& aNode)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP 
 mozSanitizingHTMLSerializer::SetDocumentCharset(nsACString& aCharset)
 {
   // No idea, if this works - it isn't invoked by |TestOutput|.
   Write(NS_LITERAL_STRING("\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=")
         /* Danger: breaking the line within the string literal, like
            "foo"\n"bar", breaks win32! */
         + nsAdoptingString(escape(NS_ConvertASCIItoUTF16(aCharset)))
         + NS_LITERAL_STRING("\">\n"));
--- a/content/base/src/mozSanitizingSerializer.h
+++ b/content/base/src/mozSanitizingSerializer.h
@@ -102,29 +102,24 @@ public:
   // nsIContentSink
   NS_IMETHOD WillParse(void) { return NS_OK; }
   NS_IMETHOD WillInterrupt(void) { return NS_OK; }
   NS_IMETHOD WillResume(void) { return NS_OK; }
   NS_IMETHOD SetParser(nsParserBase* aParser) { return NS_OK; }
   NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
   NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
   NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
-  NS_IMETHOD AddComment(const nsIParserNode& aNode) { return NS_OK; }
-  NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode)
-                                                    { return NS_OK; }
-  NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode);
   virtual void FlushPendingNotifications(mozFlushType aType) { }
   NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
   virtual nsISupports *GetTarget() { return nsnull; }
 
   // nsIHTMLContentSink
   NS_IMETHOD OpenHead();
   NS_IMETHOD IsEnabled(PRInt32 aTag, bool* aReturn);
   NS_IMETHOD NotifyTagObservers(nsIParserNode* aNode) { return NS_OK; }
-  NS_IMETHOD_(bool) IsFormOnStack() { return false; }
   NS_IMETHOD BeginContext(PRInt32 aPosition) { return NS_OK; }
   NS_IMETHOD EndContext(PRInt32 aPosition) { return NS_OK; }
   NS_IMETHOD DidProcessTokens(void) { return NS_OK; }
   NS_IMETHOD WillProcessAToken(void) { return NS_OK; }
   NS_IMETHOD DidProcessAToken(void) { return NS_OK; }
 
   // nsISanitizingHTMLSerializer
   NS_IMETHOD Initialize(nsAString* aOutString,
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -255,17 +255,16 @@ PRUint32 nsContentUtils::sJSGCThingRootC
 nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nsnull;
 #endif
 PRUint32 nsContentUtils::sScriptBlockerCount = 0;
 #ifdef DEBUG
 PRUint32 nsContentUtils::sDOMNodeRemovedSuppressCount = 0;
 #endif
 nsTArray< nsCOMPtr<nsIRunnable> >* nsContentUtils::sBlockedScriptRunners = nsnull;
 PRUint32 nsContentUtils::sRunnersCountAtFirstBlocker = 0;
-PRUint32 nsContentUtils::sScriptBlockerCountWhereRunnersPrevented = 0;
 nsIInterfaceRequestor* nsContentUtils::sSameOriginChecker = nsnull;
 
 bool nsContentUtils::sIsHandlingKeyBoardEvent = false;
 bool nsContentUtils::sAllowXULXBL_for_file = false;
 
 nsString* nsContentUtils::sShiftText = nsnull;
 nsString* nsContentUtils::sControlText = nsnull;
 nsString* nsContentUtils::sMetaText = nsnull;
@@ -4414,33 +4413,20 @@ nsContentUtils::AddScriptBlocker()
                  "Should not already have a count");
     sRunnersCountAtFirstBlocker = sBlockedScriptRunners->Length();
   }
   ++sScriptBlockerCount;
 }
 
 /* static */
 void
-nsContentUtils::AddScriptBlockerAndPreventAddingRunners()
-{
-  AddScriptBlocker();
-  if (sScriptBlockerCountWhereRunnersPrevented == 0) {
-    sScriptBlockerCountWhereRunnersPrevented = sScriptBlockerCount;
-  }
-}
-
-/* static */
-void
 nsContentUtils::RemoveScriptBlocker()
 {
   NS_ASSERTION(sScriptBlockerCount != 0, "Negative script blockers");
   --sScriptBlockerCount;
-  if (sScriptBlockerCount < sScriptBlockerCountWhereRunnersPrevented) {
-    sScriptBlockerCountWhereRunnersPrevented = 0;
-  }
   if (sScriptBlockerCount) {
     return;
   }
 
   PRUint32 firstBlocker = sRunnersCountAtFirstBlocker;
   PRUint32 lastBlocker = sBlockedScriptRunners->Length();
   PRUint32 originalFirstBlocker = firstBlocker;
   PRUint32 blockersCount = lastBlocker - firstBlocker;
@@ -4464,20 +4450,16 @@ nsContentUtils::RemoveScriptBlocker()
 bool
 nsContentUtils::AddScriptRunner(nsIRunnable* aRunnable)
 {
   if (!aRunnable) {
     return false;
   }
 
   if (sScriptBlockerCount) {
-    if (sScriptBlockerCountWhereRunnersPrevented > 0) {
-      NS_ERROR("Adding a script runner when that is prevented!");
-      return false;
-    }
     return sBlockedScriptRunners->AppendElement(aRunnable) != nsnull;
   }
   
   nsCOMPtr<nsIRunnable> run = aRunnable;
   run->Run();
 
   return true;
 }
@@ -5449,18 +5431,19 @@ public:
   {
   }
   NS_IMETHOD_(void) NoteRoot(PRUint32 langID, void* root,
                              nsCycleCollectionParticipant* helper)
   {
   }
   NS_IMETHOD_(void) NoteScriptChild(PRUint32 langID, void* child)
   {
-    if (langID == nsIProgrammingLanguage::JAVASCRIPT) {
-      mFound = child == mWrapper;
+    if (langID == nsIProgrammingLanguage::JAVASCRIPT &&
+        child == mWrapper) {
+      mFound = true;
     }
   }
   NS_IMETHOD_(void) NoteXPCOMChild(nsISupports *child)
   {
   }
   NS_IMETHOD_(void) NoteNativeChild(void* child,
                                     nsCycleCollectionParticipant* helper)
   {
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -7092,18 +7092,26 @@ nsDocument::BlockOnload()
   // If mScriptGlobalObject is null, we shouldn't be messing with the loadgroup
   // -- it's not ours.
   if (mOnloadBlockCount == 0 && mScriptGlobalObject) {
     if (!nsContentUtils::IsSafeToRunScript()) {
       // Because AddRequest may lead to OnStateChange calls in chrome,
       // block onload only when there are no script blockers.
       ++mAsyncOnloadBlockCount;
       if (mAsyncOnloadBlockCount == 1) {
-        nsContentUtils::AddScriptRunner(
+        bool success = nsContentUtils::AddScriptRunner(
           NS_NewRunnableMethod(this, &nsDocument::AsyncBlockOnload));
+
+        // The script runner shouldn't fail to add. But if somebody broke
+        // something and it does, we'll thrash at 100% cpu forever. The best
+        // response is just to ignore the onload blocking request. See bug 579535.
+        if (!success) {
+          NS_WARNING("Disaster! Onload blocking script runner failed to add - expect bad things!");
+          mAsyncOnloadBlockCount = 0;
+        }
       }
       return;
     }
     nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
     if (loadGroup) {
       loadGroup->AddRequest(mOnloadBlocker, nsnull);
     }
   }
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -92,16 +92,17 @@
 #include "nsFrameLoader.h"
 
 #include "nsObjectLoadingContent.h"
 #include "mozAutoDocUpdate.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIChannelPolicy.h"
 #include "nsChannelPolicy.h"
 #include "mozilla/dom/Element.h"
+#include "sampler.h"
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc");
 #endif
 
 #define LOG(args) PR_LOG(gObjectLog, PR_LOG_DEBUG, args)
 #define LOG_ENABLED() PR_LOG_TEST(gObjectLog, PR_LOG_DEBUG)
 
@@ -504,16 +505,17 @@ nsObjectLoadingContent::~nsObjectLoading
   }
 }
 
 // nsIRequestObserver
 NS_IMETHODIMP
 nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
                                        nsISupports *aContext)
 {
+  SAMPLE_LABEL("nsObjectLoadingContent", "OnStartRequest");
   if (aRequest != mChannel || !aRequest) {
     // This is a bit of an edge case - happens when a new load starts before the
     // previous one got here
     return NS_BINDING_ABORTED;
   }
 
   AutoNotifier notifier(this, true);
 
--- a/content/base/src/nsPlainTextSerializer.h
+++ b/content/base/src/nsPlainTextSerializer.h
@@ -103,28 +103,24 @@ public:
   // nsIContentSink
   NS_IMETHOD WillParse(void) { return NS_OK; }
   NS_IMETHOD WillInterrupt(void) { return NS_OK; }
   NS_IMETHOD WillResume(void) { return NS_OK; }
   NS_IMETHOD SetParser(nsParserBase* aParser) { return NS_OK; }
   NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
   NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
   NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
-  NS_IMETHOD AddComment(const nsIParserNode& aNode) { return NS_OK; }
-  NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode) { return NS_OK; }
-  NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode) { return NS_OK; }
   virtual void FlushPendingNotifications(mozFlushType aType) { }
   NS_IMETHOD SetDocumentCharset(nsACString& aCharset) { return NS_OK; }
   virtual nsISupports *GetTarget() { return nsnull; }
 
   // nsIHTMLContentSink
   NS_IMETHOD OpenHead();
   NS_IMETHOD IsEnabled(PRInt32 aTag, bool* aReturn);
   NS_IMETHOD NotifyTagObservers(nsIParserNode* aNode) { return NS_OK; }
-  NS_IMETHOD_(bool) IsFormOnStack() { return false; }
 
   NS_IMETHOD BeginContext(PRInt32 aPosition) { return NS_OK; }
   NS_IMETHOD EndContext(PRInt32 aPosition) { return NS_OK; }
   NS_IMETHOD DidProcessTokens(void) { return NS_OK; }
   NS_IMETHOD WillProcessAToken(void) { return NS_OK; }
   NS_IMETHOD DidProcessAToken(void) { return NS_OK; }
 
   // nsIHTMLToTextSink
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -1815,16 +1815,17 @@ IsSameOrBaseChannel(nsIRequest* aPossibl
 
   return aPossibleBase == aChannel;
 }
 
 /* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
 NS_IMETHODIMP
 nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
 {
+  SAMPLE_LABEL("nsXMLHttpRequest", "OnStartRequest");
   nsresult rv = NS_OK;
   if (!mFirstStartRequestSeen && mRequestObserver) {
     mFirstStartRequestSeen = true;
     mRequestObserver->OnStartRequest(request, ctxt);
   }
 
   if (!IsSameOrBaseChannel(request, mChannel)) {
     return NS_OK;
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -216,17 +216,16 @@ NS_NewCanvasRenderingContextWebGL(nsIDOM
     NS_ADDREF(*aResult = ctx);
     return NS_OK;
 }
 
 WebGLContext::WebGLContext()
     : mCanvasElement(nsnull),
       gl(nsnull)
 {
-    mWidth = mHeight = 0;
     mGeneration = 0;
     mInvalidated = false;
     mResetLayer = true;
     mVerbose = false;
     mOptionsFrozen = false;
 
     mActiveTexture = 0;
     mWebGLError = LOCAL_GL_NO_ERROR;
@@ -1100,16 +1099,27 @@ WebGLContext::EnsureBackbufferClearedAsN
     ForceClearFramebufferWithDefaultValues(LOCAL_GL_COLOR_BUFFER_BIT |
                                            LOCAL_GL_DEPTH_BUFFER_BIT |
                                            LOCAL_GL_STENCIL_BUFFER_BIT,
                                            nsIntRect(0, 0, mWidth, mHeight));
 
     Invalidate();
 }
 
+nsresult
+WebGLContext::DummyFramebufferOperation(const char *info)
+{
+    WebGLenum status;
+    CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER, &status);
+    if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE)
+        return NS_OK;
+    else
+        return ErrorInvalidFramebufferOperation("%s: incomplete framebuffer", info);
+}
+
 // We use this timer for many things. Here are the things that it is activated for:
 // 1) If a script is using the MOZ_WEBGL_lose_context extension.
 // 2) If we are using EGL and _NOT ANGLE_, we query periodically to see if the
 //    CONTEXT_LOST_WEBGL error has been triggered.
 // 3) If we are using ANGLE, or anything that supports ARB_robustness, query the
 //    GPU periodically to see if the reset status bit has been set.
 // In all of these situations, we use this timer to send the script context lost
 // and restored events asynchronously. For example, if it triggers a context loss,
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -92,16 +92,17 @@ class WebGLBuffer;
 class WebGLProgram;
 class WebGLShader;
 class WebGLFramebuffer;
 class WebGLRenderbuffer;
 class WebGLUniformLocation;
 class WebGLExtension;
 struct WebGLVertexAttribData;
 
+class WebGLRectangleObject;
 class WebGLContextBoundObject;
 
 enum FakeBlackStatus { DoNotNeedFakeBlack, DoNeedFakeBlack, DontKnowIfNeedFakeBlack };
 
 struct VertexAttrib0Status {
     enum { Default, EmulatedUninitializedArray, EmulatedInitializedArray };
 };
 
@@ -430,16 +431,57 @@ private:
             NS_RUNTIMEABORT("ran out of monotonic ids!");
         return mCurrentMonotonicHandle.value();
     }
 
     nsTArray<Entry> mArray;
     CheckedInt<WebGLMonotonicHandle> mCurrentMonotonicHandle;
 };
 
+// this class is a mixin for GL objects that have dimensions
+// that we need to track.
+class WebGLRectangleObject
+{
+public:
+    WebGLRectangleObject()
+        : mWidth(0), mHeight(0) { }
+
+    WebGLRectangleObject(WebGLsizei width, WebGLsizei height)
+        : mWidth(width), mHeight(height) { }
+
+    WebGLsizei Width() const { return mWidth; }
+    void width(WebGLsizei value) { mWidth = value; }
+
+    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) {
+        if (rect) {
+            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;
+};
+
 struct WebGLContextOptions {
     // these are defaults
     WebGLContextOptions()
         : alpha(true), depth(true), stencil(false),
           premultipliedAlpha(true), antialias(true),
           preserveDrawingBuffer(false)
     { }
 
@@ -464,17 +506,18 @@ struct WebGLContextOptions {
     bool antialias;
     bool preserveDrawingBuffer;
 };
 
 class WebGLContext :
     public nsIDOMWebGLRenderingContext,
     public nsICanvasRenderingContextInternal,
     public nsSupportsWeakReference,
-    public nsITimerCallback
+    public nsITimerCallback,
+    public WebGLRectangleObject
 {
     friend class WebGLMemoryReporter;
     friend class WebGLExtensionLoseContext;
     friend class WebGLContextUserData;
 
 public:
     WebGLContext();
     virtual ~WebGLContext();
@@ -518,37 +561,42 @@ public:
     bool RestoreContext();
 
     nsresult SynthesizeGLError(WebGLenum err);
     nsresult SynthesizeGLError(WebGLenum err, const char *fmt, ...);
 
     nsresult ErrorInvalidEnum(const char *fmt = 0, ...);
     nsresult ErrorInvalidOperation(const char *fmt = 0, ...);
     nsresult ErrorInvalidValue(const char *fmt = 0, ...);
+    nsresult ErrorInvalidFramebufferOperation(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);
 
+    nsresult DummyFramebufferOperation(const char *info);
+
     WebGLTexture *activeBoundTextureForTarget(WebGLenum target) {
         return target == LOCAL_GL_TEXTURE_2D ? mBound2DTextures[mActiveTexture]
                                              : mBoundCubeMapTextures[mActiveTexture];
     }
 
     already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                                  CanvasLayer *aOldLayer,
                                                  LayerManager *aManager);
     void MarkContextClean() { mInvalidated = false; }
 
     // a number that increments every time we have an event that causes
     // all context resources to be lost.
     PRUint32 Generation() { return mGeneration.value(); }
 
+    const WebGLRectangleObject *FramebufferRectangleObject() const;
+
     // this is similar to GLContext::ClearSafely, but is more comprehensive
     // (takes care of scissor, stencil write mask, dithering, viewport...)
     // 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.
@@ -637,17 +685,16 @@ protected:
 
     nsCOMPtr<nsIDOMHTMLCanvasElement> mCanvasElement;
     nsHTMLCanvasElement *HTMLCanvasElement() {
         return static_cast<nsHTMLCanvasElement*>(mCanvasElement.get());
     }
 
     nsRefPtr<gl::GLContext> gl;
 
-    PRInt32 mWidth, mHeight;
     CheckedUint32 mGeneration;
 
     WebGLContextOptions mOptions;
 
     bool mInvalidated;
     bool mResetLayer;
     bool mVerbose;
     bool mOptionsFrozen;
@@ -906,55 +953,16 @@ public:
     friend class WebGLFramebuffer;
     friend class WebGLRenderbuffer;
     friend class WebGLProgram;
     friend class WebGLBuffer;
     friend class WebGLShader;
     friend class WebGLUniformLocation;
 };
 
-// this class is a mixin for GL objects that have dimensions
-// that we need to track.
-class WebGLRectangleObject
-{
-protected:
-    WebGLRectangleObject()
-        : mWidth(0), mHeight(0) { }
-
-public:
-    WebGLsizei width() const { return mWidth; }
-    void width(WebGLsizei value) { mWidth = value; }
-
-    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) {
-        if (rect) {
-            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.
 class WebGLContextBoundObject
 {
 public:
     WebGLContextBoundObject(WebGLContext *context) {
         mContext = context;
@@ -1201,21 +1209,22 @@ protected:
     bool mHasEverBeenBound;
     WebGLuint mGLName;
 
     // 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(false) {}
+    class ImageInfo : public WebGLRectangleObject {
+    public:
+        ImageInfo() : mFormat(0), mType(0), mIsDefined(false) {}
         ImageInfo(WebGLsizei width, WebGLsizei height,
                   WebGLenum format, WebGLenum type)
-            : mWidth(width), mHeight(height), mFormat(format), mType(type), mIsDefined(true) {}
+            : WebGLRectangleObject(width, height), mFormat(format), mType(type), mIsDefined(true) {}
 
         bool operator==(const ImageInfo& a) const {
             return mWidth == a.mWidth && mHeight == a.mHeight &&
                    mFormat == a.mFormat && mType == a.mType;
         }
         bool operator!=(const ImageInfo& a) const {
             return !(*this == a);
         }
@@ -1230,19 +1239,23 @@ public:
                    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 Format() const { return mFormat; }
+        WebGLenum Type() const { return mType; }
+    protected:
         WebGLenum mFormat, mType;
         bool mIsDefined;
+
+        friend class WebGLTexture;
     };
 
     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().
@@ -1821,17 +1834,17 @@ public:
 
     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());
+        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;
@@ -1859,17 +1872,16 @@ protected:
     WebGLMonotonicHandle mMonotonicHandle;
     bool mHasEverBeenBound;
     bool mInitialized;
 
     friend class WebGLFramebuffer;
 };
 
 class WebGLFramebufferAttachment
-    : public WebGLRectangleObject
 {
     // deleting a texture or renderbuffer immediately detaches it
     WebGLRefPtr<WebGLTexture> mTexturePtr;
     WebGLRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
     WebGLenum mAttachmentPoint;
     WebGLint mTextureLevel;
     WebGLenum mTextureCubeMapFace;
 
@@ -1885,90 +1897,113 @@ public:
     bool IsDeleteRequested() const {
         return Texture() ? Texture()->IsDeleteRequested()
              : Renderbuffer() ? Renderbuffer()->IsDeleteRequested()
              : false;
     }
 
     bool HasAlpha() const {
         WebGLenum format = 0;
-        if (Texture() && Texture()->HasImageInfoAt(0,0))
-            format = mTexturePtr->ImageInfoAt(0,0).mFormat;
+        if (Texture() && Texture()->HasImageInfoAt(mTextureLevel, mTextureCubeMapFace))
+            format = Texture()->ImageInfoAt(mTextureLevel, mTextureCubeMapFace).Format();
         else if (Renderbuffer())
-            format = mRenderbufferPtr->InternalFormat();
+            format = Renderbuffer()->InternalFormat();
         return format == LOCAL_GL_RGBA ||
                format == LOCAL_GL_LUMINANCE_ALPHA ||
                format == LOCAL_GL_ALPHA ||
                format == LOCAL_GL_RGBA4 ||
                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);
+    }
+    const WebGLTexture *Texture() const {
+        return mTexturePtr;
     }
-    WebGLTexture *Texture() const {
-        return mTexturePtr.get();
+    WebGLTexture *Texture() {
+        return mTexturePtr;
     }
-    WebGLRenderbuffer *Renderbuffer() const {
-        return mRenderbufferPtr.get();
+    const WebGLRenderbuffer *Renderbuffer() const {
+        return mRenderbufferPtr;
+    }
+    WebGLRenderbuffer *Renderbuffer() {
+        return mRenderbufferPtr;
     }
     WebGLint TextureLevel() const {
         return mTextureLevel;
     }
     WebGLenum TextureCubeMapFace() const {
         return mTextureCubeMapFace;
     }
 
-    bool IsIncompatibleWithAttachmentPoint() const
-    {
-        // textures can only be color textures in WebGL
-        if (mTexturePtr)
-            return mAttachmentPoint != LOCAL_GL_COLOR_ATTACHMENT0;
-
-        if (mRenderbufferPtr) {
-            WebGLenum format = mRenderbufferPtr->InternalFormat();
-            switch (mAttachmentPoint) {
-                case LOCAL_GL_COLOR_ATTACHMENT0:
-                    return format != LOCAL_GL_RGB565 &&
-                           format != LOCAL_GL_RGB5_A1 &&
-                           format != LOCAL_GL_RGBA4;
-                case LOCAL_GL_DEPTH_ATTACHMENT:
-                    return format != LOCAL_GL_DEPTH_COMPONENT16;
-                case LOCAL_GL_STENCIL_ATTACHMENT:
-                    return format != LOCAL_GL_STENCIL_INDEX8;
-                case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
-                    return format != LOCAL_GL_DEPTH_STENCIL;
-            }
-        }
-
-        return false; // no attachment at all, so no incompatibility
-    }
-
     bool HasUninitializedRenderbuffer() const {
         return mRenderbufferPtr && !mRenderbufferPtr->Initialized();
     }
 
     void Reset() {
         mTexturePtr = nsnull;
         mRenderbufferPtr = nsnull;
     }
+
+    const WebGLRectangleObject* RectangleObject() const {
+        if (Texture() && Texture()->HasImageInfoAt(mTextureLevel, mTextureCubeMapFace))
+            return &Texture()->ImageInfoAt(mTextureLevel, mTextureCubeMapFace);
+        else if (Renderbuffer())
+            return Renderbuffer();
+        else
+            return nsnull;
+    }
+    bool HasSameDimensionsAs(const WebGLFramebufferAttachment& other) const {
+        const WebGLRectangleObject *thisRect = RectangleObject();
+        const WebGLRectangleObject *otherRect = other.RectangleObject();
+        return thisRect &&
+               otherRect &&
+               thisRect->HasSameDimensionsAs(*otherRect);
+    }
+
+    bool IsComplete() const {
+        const WebGLRectangleObject *thisRect = RectangleObject();
+
+        if (!thisRect ||
+            !thisRect->Width() ||
+            !thisRect->Height())
+            return false;
+
+        if (mTexturePtr)
+            return mAttachmentPoint == LOCAL_GL_COLOR_ATTACHMENT0;
+
+        if (mRenderbufferPtr) {
+            WebGLenum format = mRenderbufferPtr->InternalFormat();
+            switch (mAttachmentPoint) {
+                case LOCAL_GL_COLOR_ATTACHMENT0:
+                    return format == LOCAL_GL_RGB565 ||
+                           format == LOCAL_GL_RGB5_A1 ||
+                           format == LOCAL_GL_RGBA4;
+                case LOCAL_GL_DEPTH_ATTACHMENT:
+                    return format == LOCAL_GL_DEPTH_COMPONENT16;
+                case LOCAL_GL_STENCIL_ATTACHMENT:
+                    return format == LOCAL_GL_STENCIL_INDEX8;
+                case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
+                    return format == LOCAL_GL_DEPTH_STENCIL;
+                default:
+                    NS_ABORT(); // should have been validated earlier
+            }
+        }
+
+        NS_ABORT(); // should never get there
+        return false;
+    }
 };
 
 class WebGLFramebuffer
     : public nsIWebGLFramebuffer
     , public WebGLRefCountedObject<WebGLFramebuffer>
     , public WebGLContextBoundObject
 {
 public:
@@ -1998,19 +2033,16 @@ public:
         mContext->gl->fDeleteFramebuffers(1, &mGLName);
         mContext->mFramebuffers.RemoveElement(mMonotonicHandle);
     }
 
     bool HasEverBeenBound() { return mHasEverBeenBound; }
     void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
     WebGLuint GLName() { return mGLName; }
 
-    WebGLsizei width() { return mColorAttachment.width(); }
-    WebGLsizei height() { return mColorAttachment.height(); }
-
     nsresult FramebufferRenderbuffer(WebGLenum target,
                                      WebGLenum attachment,
                                      WebGLenum rbtarget,
                                      nsIWebGLRenderbuffer *rbobj)
     {
         WebGLuint renderbuffername;
         bool isNull;
         WebGLRenderbuffer *wrb;
@@ -2109,60 +2141,33 @@ public:
             mContext->gl->fFramebufferTexture2D(target, LOCAL_GL_STENCIL_ATTACHMENT, textarget, texturename, level);
         } else {
             mContext->gl->fFramebufferTexture2D(target, attachment, textarget, texturename, level);
         }
 
         return NS_OK;
     }
 
-    bool CheckAndInitializeRenderbuffers()
-    {
-        if (HasBadAttachments()) {
-            mContext->SynthesizeGLError(LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION);
-            return false;
-        }
-
-        if (mColorAttachment.HasUninitializedRenderbuffer() ||
-            mDepthAttachment.HasUninitializedRenderbuffer() ||
-            mStencilAttachment.HasUninitializedRenderbuffer() ||
-            mDepthStencilAttachment.HasUninitializedRenderbuffer())
-        {
-            InitializeRenderbuffers();
-        }
-
-        return true;
+    bool HasIncompleteAttachment() const {
+        return (mColorAttachment.IsDefined() && !mColorAttachment.IsComplete()) ||
+               (mDepthAttachment.IsDefined() && !mDepthAttachment.IsComplete()) ||
+               (mStencilAttachment.IsDefined() && !mStencilAttachment.IsComplete()) ||
+               (mDepthStencilAttachment.IsDefined() && !mDepthStencilAttachment.IsComplete());
     }
 
-    bool HasBadAttachments() const {
-        if (mColorAttachment.IsIncompatibleWithAttachmentPoint() ||
-            mDepthAttachment.IsIncompatibleWithAttachmentPoint() ||
-            mStencilAttachment.IsIncompatibleWithAttachmentPoint() ||
-            mDepthStencilAttachment.IsIncompatibleWithAttachmentPoint())
-        {
-            // some attachment is incompatible with its attachment point
-            return true;
-        }
-
-        if (int(mDepthAttachment.IsDefined()) +
-            int(mStencilAttachment.IsDefined()) +
-            int(mDepthStencilAttachment.IsDefined()) >= 2)
-        {
-            // has at least two among Depth, Stencil, DepthStencil
-            return true;
-        }
-
-        if (mDepthAttachment.IsDefined() && !mDepthAttachment.HasSameDimensionsAs(mColorAttachment))
-            return true;
-        if (mStencilAttachment.IsDefined() && !mStencilAttachment.HasSameDimensionsAs(mColorAttachment))
-            return true;
-        if (mDepthStencilAttachment.IsDefined() && !mDepthStencilAttachment.HasSameDimensionsAs(mColorAttachment))
-            return true;
-
-        return false;
+    bool HasDepthStencilConflict() const {
+        return int(mDepthAttachment.IsDefined()) +
+               int(mStencilAttachment.IsDefined()) +
+               int(mDepthStencilAttachment.IsDefined()) >= 2;
+    }
+
+    bool HasAttachmentsOfMismatchedDimensions() const {
+        return (mDepthAttachment.IsDefined() && !mDepthAttachment.HasSameDimensionsAs(mColorAttachment)) ||
+               (mStencilAttachment.IsDefined() && !mStencilAttachment.HasSameDimensionsAs(mColorAttachment)) ||
+               (mDepthStencilAttachment.IsDefined() && !mDepthStencilAttachment.HasSameDimensionsAs(mColorAttachment));
     }
 
     const WebGLFramebufferAttachment& ColorAttachment() const {
         return mColorAttachment;
     }
 
     const WebGLFramebufferAttachment& DepthAttachment() const {
         return mDepthAttachment;
@@ -2205,28 +2210,49 @@ public:
         if (mDepthAttachment.Renderbuffer() == rb)
             FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nsnull);
         if (mStencilAttachment.Renderbuffer() == rb)
             FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nsnull);
         if (mDepthStencilAttachment.Renderbuffer() == rb)
             FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nsnull);
     }
 
+    const WebGLRectangleObject *RectangleObject() {
+        return mColorAttachment.RectangleObject();
+    }
+
     NS_DECL_ISUPPORTS
     NS_DECL_NSIWEBGLFRAMEBUFFER
 
-protected:
-
-    // protected because WebGLContext should only call InitializeRenderbuffers
-    void InitializeRenderbuffers()
+    bool CheckAndInitializeRenderbuffers()
     {
+        // enforce WebGL section 6.5 which is WebGL-specific, hence OpenGL itself would not
+        // generate the INVALID_FRAMEBUFFER_OPERATION that we need here
+        if (HasDepthStencilConflict())
+            return false;
+
+        if (!mColorAttachment.HasUninitializedRenderbuffer() &&
+            !mDepthAttachment.HasUninitializedRenderbuffer() &&
+            !mStencilAttachment.HasUninitializedRenderbuffer() &&
+            !mDepthStencilAttachment.HasUninitializedRenderbuffer())
+            return true;
+
+        // ensure INVALID_FRAMEBUFFER_OPERATION in zero-size case
+        const WebGLRectangleObject *rect = mColorAttachment.RectangleObject();
+        if (!rect ||
+            !rect->Width() ||
+            !rect->Height())
+            return false;
+
         mContext->MakeContextCurrent();
 
-        if (mContext->gl->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER) != LOCAL_GL_FRAMEBUFFER_COMPLETE)
-            return;
+        WebGLenum status;
+        mContext->CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER, &status);
+        if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE)
+            return false;
 
         PRUint32 mask = 0;
 
         if (mColorAttachment.HasUninitializedRenderbuffer())
             mask |= LOCAL_GL_COLOR_BUFFER_BIT;
 
         if (mDepthAttachment.HasUninitializedRenderbuffer() ||
             mDepthStencilAttachment.HasUninitializedRenderbuffer())
@@ -2235,30 +2261,31 @@ protected:
         }
 
         if (mStencilAttachment.HasUninitializedRenderbuffer() ||
             mDepthStencilAttachment.HasUninitializedRenderbuffer())
         {
             mask |= LOCAL_GL_STENCIL_BUFFER_BIT;
         }
 
-        // the one useful line of code
-        mContext->ForceClearFramebufferWithDefaultValues(mask, nsIntRect(0,0,width(),height()));
+        mContext->ForceClearFramebufferWithDefaultValues(mask, nsIntRect(0, 0, rect->Width(), rect->Height()));
 
         if (mColorAttachment.HasUninitializedRenderbuffer())
             mColorAttachment.Renderbuffer()->SetInitialized(true);
 
         if (mDepthAttachment.HasUninitializedRenderbuffer())
             mDepthAttachment.Renderbuffer()->SetInitialized(true);
 
         if (mStencilAttachment.HasUninitializedRenderbuffer())
             mStencilAttachment.Renderbuffer()->SetInitialized(true);
 
         if (mDepthStencilAttachment.HasUninitializedRenderbuffer())
             mDepthStencilAttachment.Renderbuffer()->SetInitialized(true);
+
+        return true;
     }
 
     WebGLuint mGLName;
     bool mHasEverBeenBound;
 
     // we only store pointers to attached renderbuffers, not to attached textures, because
     // we will only need to initialize renderbuffers. Textures are already initialized.
     WebGLFramebufferAttachment mColorAttachment,
@@ -2358,16 +2385,21 @@ public:
     WebGLExtension(WebGLContext *baseContext)
         : WebGLContextBoundObject(baseContext)
     {}
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIWEBGLEXTENSION
 };
 
+inline const WebGLRectangleObject *WebGLContext::FramebufferRectangleObject() const {
+    return mBoundFramebuffer ? mBoundFramebuffer->RectangleObject()
+                             : static_cast<const WebGLRectangleObject*>(this);
+}
+
 /**
  ** Template implementations
  **/
 
 /* Helper function taking a BaseInterfaceType pointer, casting it to
  * ConcreteObjectType and performing some checks along the way.
  *
  * By default, null (respectively: deleted) aInterface pointers are
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -681,18 +681,26 @@ WebGLContext::CheckFramebufferStatus(Web
     }
 
     *retval = 0;
 
     MakeContextCurrent();
     if (target != LOCAL_GL_FRAMEBUFFER)
         return ErrorInvalidEnum("checkFramebufferStatus: target must be FRAMEBUFFER");
 
-    if (mBoundFramebuffer && mBoundFramebuffer->HasBadAttachments())
+    if (!mBoundFramebuffer)
+        *retval = LOCAL_GL_FRAMEBUFFER_COMPLETE;
+    else if(mBoundFramebuffer->HasDepthStencilConflict())
         *retval = LOCAL_GL_FRAMEBUFFER_UNSUPPORTED;
+    else if(!mBoundFramebuffer->ColorAttachment().IsDefined())
+        *retval = LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
+    else if(mBoundFramebuffer->HasIncompleteAttachment())
+        *retval = LOCAL_GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+    else if(mBoundFramebuffer->HasAttachmentsOfMismatchedDimensions())
+        *retval = LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
     else
         *retval = gl->fCheckFramebufferStatus(target);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::Clear(PRUint32 mask)
@@ -705,17 +713,17 @@ WebGLContext::Clear(PRUint32 mask)
     PRUint32 m = mask & (LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT);
     if (mask != m)
         return ErrorInvalidValue("clear: invalid mask bits");
 
     bool needClearCallHere = true;
 
     if (mBoundFramebuffer) {
         if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
-            return NS_OK;
+            return ErrorInvalidFramebufferOperation("clear: incomplete framebuffer");
     } else {
         // no FBO is bound, so we are clearing the backbuffer here
         EnsureBackbufferClearedAsNeeded();
         bool valuesAreDefault = mColorClearValue[0] == 0.0f &&
                                   mColorClearValue[1] == 0.0f &&
                                   mColorClearValue[2] == 0.0f &&
                                   mColorClearValue[3] == 0.0f &&
                                   mDepthClearValue    == 1.0f &&
@@ -797,19 +805,19 @@ WebGLContext::CopyTexSubImage2D_base(Web
                                      WebGLint xoffset,
                                      WebGLint yoffset,
                                      WebGLint x,
                                      WebGLint y,
                                      WebGLsizei width,
                                      WebGLsizei height,
                                      bool sub)
 {
-
-    WebGLsizei framebufferWidth =  mBoundFramebuffer ? mBoundFramebuffer->width() : mWidth;
-    WebGLsizei framebufferHeight = mBoundFramebuffer ? mBoundFramebuffer->height() : mHeight;
+    const WebGLRectangleObject *framebufferRect = FramebufferRectangleObject();
+    WebGLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
+    WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
 
     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);
@@ -856,17 +864,17 @@ WebGLContext::CopyTexSubImage2D_base(Web
 
         // 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)
         {
             // we are completely outside of range, can exit now with buffer filled with zeros
-            return NS_OK;
+            return DummyFramebufferOperation(info);
         }
 
         GLint   actual_x             = clamped(x, 0, framebufferWidth);
         GLint   actual_x_plus_width  = clamped(x + width, 0, framebufferWidth);
         GLsizei actual_width   = actual_x_plus_width  - actual_x;
         GLint   actual_xoffset = xoffset + actual_x - x;
 
         GLint   actual_y             = clamped(y, 0, framebufferHeight);
@@ -941,36 +949,37 @@ WebGLContext::CopyTexImage2D(WebGLenum t
                                     internalformat == LOCAL_GL_ALPHA ||
                                     internalformat == LOCAL_GL_LUMINANCE_ALPHA;
     bool fboFormatHasAlpha = mBoundFramebuffer ? mBoundFramebuffer->ColorAttachment().HasAlpha()
                                                  : bool(gl->ActualFormat().alpha > 0);
     if (texFormatRequiresAlpha && !fboFormatHasAlpha)
         return ErrorInvalidOperation("copyTexImage2D: texture format requires an alpha channel "
                                      "but the framebuffer doesn't have one");
 
-    if (mBoundFramebuffer && !mBoundFramebuffer->CheckAndInitializeRenderbuffers())
-        return NS_OK;
+    if (mBoundFramebuffer)
+        if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
+            return ErrorInvalidFramebufferOperation("copyTexImage2D: incomplete framebuffer");
 
     WebGLTexture *tex = activeBoundTextureForTarget(target);
     if (!tex)
         return ErrorInvalidOperation("copyTexImage2D: no texture bound to this target");
 
     // copyTexImage2D only generates textures with type = UNSIGNED_BYTE
     GLenum type = LOCAL_GL_UNSIGNED_BYTE;
 
     // check if the memory size of this texture may change with this call
     bool sizeMayChange = true;
     size_t face = WebGLTexture::FaceForTarget(target);
     if (tex->HasImageInfoAt(level, face)) {
         const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(level, face);
 
-        sizeMayChange = width != imageInfo.mWidth ||
-                        height != imageInfo.mHeight ||
-                        internalformat != imageInfo.mFormat ||
-                        type != imageInfo.mType;
+        sizeMayChange = width != imageInfo.Width() ||
+                        height != imageInfo.Height() ||
+                        internalformat != imageInfo.Format() ||
+                        type != imageInfo.Type();
     }
 
     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) {
@@ -1027,38 +1036,40 @@ WebGLContext::CopyTexSubImage2D(WebGLenu
     WebGLTexture *tex = activeBoundTextureForTarget(target);
     if (!tex)
         return ErrorInvalidOperation("copyTexSubImage2D: no texture bound to this target");
 
     WebGLint face = WebGLTexture::FaceForTarget(target);
     if (!tex->HasImageInfoAt(level, face))
         return ErrorInvalidOperation("copyTexSubImage2D: no texture image previously defined for this level and face");
 
-    WebGLsizei texWidth = tex->ImageInfoAt(level, face).mWidth;
-    WebGLsizei texHeight = tex->ImageInfoAt(level, face).mHeight;
+    const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(level, face);
+    WebGLsizei texWidth = imageInfo.Width();
+    WebGLsizei texHeight = imageInfo.Height();
 
     if (xoffset + width > texWidth || xoffset + width < 0)
       return ErrorInvalidValue("copyTexSubImage2D: xoffset+width is too large");
 
     if (yoffset + height > texHeight || yoffset + height < 0)
       return ErrorInvalidValue("copyTexSubImage2D: yoffset+height is too large");
 
-    WebGLenum format = tex->ImageInfoAt(level, face).mFormat;
+    WebGLenum format = imageInfo.Format();
     bool texFormatRequiresAlpha = format == LOCAL_GL_RGBA ||
-                                    format == LOCAL_GL_ALPHA ||
-                                    format == LOCAL_GL_LUMINANCE_ALPHA;
+                                  format == LOCAL_GL_ALPHA ||
+                                  format == LOCAL_GL_LUMINANCE_ALPHA;
     bool fboFormatHasAlpha = mBoundFramebuffer ? mBoundFramebuffer->ColorAttachment().HasAlpha()
                                                  : bool(gl->ActualFormat().alpha > 0);
 
     if (texFormatRequiresAlpha && !fboFormatHasAlpha)
         return ErrorInvalidOperation("copyTexSubImage2D: texture format requires an alpha channel "
                                      "but the framebuffer doesn't have one");
 
-    if (mBoundFramebuffer && !mBoundFramebuffer->CheckAndInitializeRenderbuffers())
-        return NS_OK;
+    if (mBoundFramebuffer)
+        if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
+            return ErrorInvalidFramebufferOperation("copyTexSubImage2D: incomplete framebuffer");
 
     return CopyTexSubImage2D_base(target, level, format, xoffset, yoffset, x, y, width, height, true);
 }
 
 
 NS_IMETHODIMP
 WebGLContext::CreateProgram(nsIWebGLProgram **retval)
 {
@@ -1582,17 +1593,17 @@ WebGLContext::DrawArrays(GLenum mode, We
 
     if (checked_firstPlusCount.value() > maxAllowedCount)
         return ErrorInvalidOperation("drawArrays: bound vertex attribute buffers do not have sufficient size for given first and count");
 
     MakeContextCurrent();
 
     if (mBoundFramebuffer) {
         if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
-            return NS_OK;
+            return ErrorInvalidFramebufferOperation("drawArrays: incomplete framebuffer");
     } else {
         EnsureBackbufferClearedAsNeeded();
     }
 
     BindFakeBlackTextures();
     if (!DoFakeVertexAttrib0(checked_firstPlusCount.value()))
         return NS_OK;
 
@@ -1693,17 +1704,17 @@ WebGLContext::DrawElements(WebGLenum mod
                 "size for given indices from the bound element array");
         }
     }
 
     MakeContextCurrent();
 
     if (mBoundFramebuffer) {
         if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
-            return NS_OK;
+            return ErrorInvalidFramebufferOperation("drawElements: incomplete framebuffer");
     } else {
         EnsureBackbufferClearedAsNeeded();
     }
 
     BindFakeBlackTextures();
     if (!DoFakeVertexAttrib0(checked_maxIndexPlusOne.value()))
         return NS_OK;
 
@@ -2401,30 +2412,30 @@ WebGLContext::GetFramebufferAttachmentPa
 
     if (fba.Renderbuffer()) {
         switch (pname) {
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
                 wrval->SetAsInt32(LOCAL_GL_RENDERBUFFER);
                 break;
 
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
-                wrval->SetAsISupports(fba.Renderbuffer());
+                wrval->SetAsISupports(const_cast<WebGLRenderbuffer*>(fba.Renderbuffer()));
                 break;
 
             default:
                 return ErrorInvalidEnumInfo("GetFramebufferAttachmentParameter: pname", pname);
         }
     } else if (fba.Texture()) {
         switch (pname) {
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
                 wrval->SetAsInt32(LOCAL_GL_TEXTURE);
                 break;
 
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
-                wrval->SetAsISupports(fba.Texture());
+                wrval->SetAsISupports(const_cast<WebGLTexture*>(fba.Texture()));
                 break;
 
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
                 wrval->SetAsInt32(fba.TextureLevel());
                 break;
 
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
                 wrval->SetAsInt32(fba.TextureCubeMapFace());
@@ -3283,18 +3294,19 @@ WebGLContext::ReadPixels_base(WebGLint x
     }
 
     if (width < 0 || height < 0)
         return ErrorInvalidValue("ReadPixels: negative size passed");
 
     if (!pixels)
         return ErrorInvalidValue("ReadPixels: null array passed");
 
-    WebGLsizei boundWidth = mBoundFramebuffer ? mBoundFramebuffer->width() : mWidth;
-    WebGLsizei boundHeight = mBoundFramebuffer ? mBoundFramebuffer->height() : mHeight;
+    const WebGLRectangleObject *framebufferRect = FramebufferRectangleObject();
+    WebGLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
+    WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
 
     void* data = JS_GetTypedArrayData(pixels);
     PRUint32 dataByteLen = JS_GetTypedArrayByteLength(pixels);
     int dataType = JS_GetTypedArrayType(pixels);
 
     PRUint32 channels = 0;
 
     // Check the format param
@@ -3365,57 +3377,57 @@ WebGLContext::ReadPixels_base(WebGLint x
             return ErrorInvalidOperation("readPixels: Invalid format/type pair");
     }
 
     MakeContextCurrent();
 
     if (mBoundFramebuffer) {
         // prevent readback of arbitrary video memory through uninitialized renderbuffers!
         if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
-            return NS_OK;
+            return ErrorInvalidFramebufferOperation("readPixels: incomplete framebuffer");
     } else {
         EnsureBackbufferClearedAsNeeded();
     }
     // Now that the errors are out of the way, on to actually reading
 
     // If we won't be reading any pixels anyways, just skip the actual reading
     if (width == 0 || height == 0)
-        return NS_OK;
-
-    if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, boundWidth, boundHeight)) {
+        return DummyFramebufferOperation("readPixels");
+
+    if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, framebufferWidth, framebufferHeight)) {
         // the easy case: we're not reading out-of-range pixels
         gl->fReadPixels(x, y, width, height, format, type, data);
     } else {
         // the rectangle doesn't fit entirely in the bound buffer. We then have to set to zero the part
         // of the buffer that correspond to out-of-range pixels. We don't want to rely on system OpenGL
         // to do that for us, because passing out of range parameters to a buggy OpenGL implementation
         // could conceivably allow to read memory we shouldn't be allowed to read. So we manually initialize
         // the buffer to zero and compute the parameters to pass to OpenGL. We have to use an intermediate buffer
         // to accomodate the potentially different strides (widths).
 
         // zero the whole destination buffer. Too bad for the part that's going to be overwritten, we're not
         // 100% efficient here, but in practice this is a quite rare case anyway.
         memset(data, 0, dataByteLen);
 
-        if (   x >= boundWidth
+        if (   x >= framebufferWidth
             || x+width <= 0
-            || y >= boundHeight
+            || y >= framebufferHeight
             || y+height <= 0)
         {
             // we are completely outside of range, can exit now with buffer filled with zeros
-            return NS_OK;
+            return DummyFramebufferOperation("readPixels");
         }
 
         // compute the parameters of the subrect we're actually going to call glReadPixels on
         GLint   subrect_x      = NS_MAX(x, 0);
-        GLint   subrect_end_x  = NS_MIN(x+width, boundWidth);
+        GLint   subrect_end_x  = NS_MIN(x+width, framebufferWidth);
         GLsizei subrect_width  = subrect_end_x - subrect_x;
 
         GLint   subrect_y      = NS_MAX(y, 0);
-        GLint   subrect_end_y  = NS_MIN(y+height, boundHeight);
+        GLint   subrect_end_y  = NS_MIN(y+height, framebufferHeight);
         GLsizei subrect_height = subrect_end_y - subrect_y;
 
         if (subrect_width < 0 || subrect_height < 0 ||
             subrect_width > width || subrect_height > height)
             return ErrorInvalidOperation("ReadPixels: integer overflow computing clipped rect size");
 
         // now we know that subrect_width is in the [0..width] interval, and same for heights.
 
@@ -3552,26 +3564,26 @@ WebGLContext::RenderbufferStorage(WebGLe
         internalformatForGL = LOCAL_GL_DEPTH24_STENCIL8;
         break;
     default:
         return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", internalformat);
     }
 
     MakeContextCurrent();
 
-    bool sizeChanges = width != mBoundRenderbuffer->width() ||
-                       height != mBoundRenderbuffer->height() ||
+    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));
+            LogMessageIfVerbose("renderbufferStorage generated error %s", ErrorName(error));
             return NS_OK;
         }
     } else {
         gl->fRenderbufferStorage(target, internalformatForGL, width, height);
     }
 
     mBoundRenderbuffer->SetInternalFormat(internalformat);
     mBoundRenderbuffer->SetInternalFormatForGL(internalformatForGL);
@@ -4727,20 +4739,20 @@ GLenum WebGLContext::CheckedTexImage2D(G
     WebGLTexture *tex = activeBoundTextureForTarget(target);
     NS_ABORT_IF_FALSE(tex != nsnull, "no texture bound");
 
     bool sizeMayChange = true;
     size_t face = WebGLTexture::FaceForTarget(target);
     
     if (tex->HasImageInfoAt(level, face)) {
         const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(level, face);
-        sizeMayChange = width != imageInfo.mWidth ||
-                        height != imageInfo.mHeight ||
-                        format != imageInfo.mFormat ||
-                        type != imageInfo.mType;
+        sizeMayChange = width != imageInfo.Width() ||
+                        height != imageInfo.Height() ||
+                        format != imageInfo.Format() ||
+                        type != imageInfo.Type();
     }
     
     if (sizeMayChange) {
         UpdateWebGLErrorAndClearGLError();
         gl->fTexImage2D(target, level, internalFormat, width, height, border, format, type, data);
         GLenum error = LOCAL_GL_NO_ERROR;
         UpdateWebGLErrorAndClearGLError(&error);
         return error;
@@ -5034,21 +5046,21 @@ WebGLContext::TexSubImage2D_base(WebGLen
         return ErrorInvalidOperation("texSubImage2D: no texture is bound to this target");
 
     size_t face = WebGLTexture::FaceForTarget(target);
     
     if (!tex->HasImageInfoAt(level, face))
         return ErrorInvalidOperation("texSubImage2D: no texture image previously defined for this level and face");
     
     const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(level, face);
-    if (!CanvasUtils::CheckSaneSubrectSize(xoffset, yoffset, width, height, imageInfo.mWidth, imageInfo.mHeight))
+    if (!CanvasUtils::CheckSaneSubrectSize(xoffset, yoffset, width, height, imageInfo.Width(), imageInfo.Height()))
         return ErrorInvalidValue("texSubImage2D: subtexture rectangle out of bounds");
     
     // Require the format and type in texSubImage2D to match that of the existing texture as created by texImage2D
-    if (imageInfo.mFormat != format || imageInfo.mType != type)
+    if (imageInfo.Format() != format || imageInfo.Type() != type)
         return ErrorInvalidOperation("texSubImage2D: format or type doesn't match the existing texture");
 
     MakeContextCurrent();
 
     int dstFormat = GetWebGLTexelFormat(format, type);
     int actualSrcFormat = srcFormat == WebGLTexelFormat::Auto ? dstFormat : srcFormat;
     size_t srcStride = srcStrideOrZero ? srcStrideOrZero : checked_alignedRowSize.value();
 
--- a/content/canvas/src/WebGLContextUtils.cpp
+++ b/content/canvas/src/WebGLContextUtils.cpp
@@ -193,16 +193,27 @@ WebGLContext::ErrorInvalidValue(const ch
     va_start(va, fmt);
     LogMessageIfVerbose(fmt, va);
     va_end(va);
 
     return SynthesizeGLError(LOCAL_GL_INVALID_VALUE);
 }
 
 nsresult
+WebGLContext::ErrorInvalidFramebufferOperation(const char *fmt, ...)
+{
+    va_list va;
+    va_start(va, fmt);
+    LogMessageIfVerbose(fmt, va);
+    va_end(va);
+
+    return SynthesizeGLError(LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION);
+}
+
+nsresult
 WebGLContext::ErrorOutOfMemory(const char *fmt, ...)
 {
     va_list va;
     va_start(va, fmt);
     LogMessageIfVerbose(fmt, va);
     va_end(va);
 
     return SynthesizeGLError(LOCAL_GL_OUT_OF_MEMORY);
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -2535,17 +2535,17 @@ nsCanvasRenderingContext2D::SetFont(cons
     nsRefPtr<nsStyleContext> sc =
         styleSet->ResolveStyleForRules(parentContext, rules);
     if (!sc)
         return NS_ERROR_FAILURE;
     const nsStyleFont* fontStyle = sc->GetStyleFont();
 
     NS_ASSERTION(fontStyle, "Could not obtain font style");
 
-    nsIAtom* language = sc->GetStyleVisibility()->mLanguage;
+    nsIAtom* language = sc->GetStyleFont()->mLanguage;
     if (!language) {
         language = presShell->GetPresContext()->GetLanguageFromCharset();
     }
 
     // use CSS pixels instead of dev pixels to avoid being affected by page zoom
     const PRUint32 aupcp = nsPresContext::AppUnitsPerCSSPixel();
     // un-zoom the font size to avoid being affected by text-only zoom
     const nscoord fontSize = nsStyleFont::UnZoomText(parentContext->PresContext(), fontStyle->mFont.size);
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
@@ -2746,17 +2746,17 @@ nsCanvasRenderingContext2DAzure::SetFont
   if (!sc) {
     return NS_ERROR_FAILURE;
   }
 
   const nsStyleFont* fontStyle = sc->GetStyleFont();
 
   NS_ASSERTION(fontStyle, "Could not obtain font style");
 
-  nsIAtom* language = sc->GetStyleVisibility()->mLanguage;
+  nsIAtom* language = sc->GetStyleFont()->mLanguage;
   if (!language) {
     language = presShell->GetPresContext()->GetLanguageFromCharset();
   }
 
   // use CSS pixels instead of dev pixels to avoid being affected by page zoom
   const PRUint32 aupcp = nsPresContext::AppUnitsPerCSSPixel();
   // un-zoom the font size to avoid being affected by text-only zoom
   const nscoord fontSize = nsStyleFont::UnZoomText(parentContext->PresContext(), fontStyle->mFont.size);
--- a/content/canvas/test/webgl/failing_tests_linux.txt
+++ b/content/canvas/test/webgl/failing_tests_linux.txt
@@ -6,9 +6,8 @@ conformance/misc/uninitialized-test.html
 conformance/programs/gl-get-active-attribute.html
 conformance/textures/texture-mips.html
 conformance/uniforms/gl-uniform-bool.html
 conformance/more/conformance/quickCheckAPI-S_V.html
 conformance/more/functions/uniformfArrayLen1.html
 conformance/glsl/misc/attrib-location-length-limits.html
 conformance/glsl/misc/uniform-location-length-limits.html
 conformance/renderbuffers/framebuffer-object-attachment.html
-conformance/misc/object-deletion-behaviour.html
--- a/content/canvas/test/webgl/failing_tests_mac.txt
+++ b/content/canvas/test/webgl/failing_tests_mac.txt
@@ -2,11 +2,9 @@ conformance/context/premultiplyalpha-tes
 conformance/glsl/misc/glsl-function-nodes.html
 conformance/glsl/misc/glsl-long-variable-names.html
 conformance/glsl/misc/shader-with-256-character-identifier.frag.html
 conformance/glsl/misc/shader-with-long-line.html
 conformance/more/conformance/quickCheckAPI-S_V.html
 conformance/more/functions/uniformfBadArgs.html
 conformance/more/functions/uniformiBadArgs.html
 conformance/glsl/misc/attrib-location-length-limits.html
-conformance/glsl/misc/uniform-location-length-limits.html
-conformance/renderbuffers/framebuffer-object-attachment.html
-conformance/misc/object-deletion-behaviour.html
+conformance/glsl/misc/uniform-location-length-limits.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
@@ -3,11 +3,9 @@ conformance/glsl/functions/glsl-function
 conformance/glsl/functions/glsl-function-atan-xy.html
 conformance/glsl/misc/glsl-long-variable-names.html
 conformance/glsl/misc/shader-with-256-character-identifier.frag.html
 conformance/glsl/misc/shader-with-long-line.html
 conformance/more/conformance/quickCheckAPI-S_V.html
 conformance/more/functions/uniformfArrayLen1.html
 conformance/glsl/misc/attrib-location-length-limits.html
 conformance/glsl/misc/struct-nesting-under-maximum.html
-conformance/glsl/misc/uniform-location-length-limits.html
-conformance/renderbuffers/framebuffer-object-attachment.html
-conformance/misc/object-deletion-behaviour.html
+conformance/glsl/misc/uniform-location-length-limits.html
\ No newline at end of file
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -77,16 +77,17 @@
 #include "nsDOMJSUtils.h"
 #include "nsDOMScriptObjectHolder.h"
 #include "nsDataHashtable.h"
 #include "nsCOMArray.h"
 #include "nsEventListenerService.h"
 #include "nsDOMEvent.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsJSEnvironment.h"
+#include "sampler.h"
 
 using namespace mozilla::dom;
 
 #define EVENT_TYPE_EQUALS( ls, type, userType ) \
   (ls->mEventType == type && \
   (ls->mEventType != NS_USER_DEFINED_EVENT || ls->mTypeAtom == userType))
 
 static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
@@ -746,16 +747,17 @@ void
 nsEventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
                                             nsEvent* aEvent,
                                             nsIDOMEvent** aDOMEvent,
                                             nsIDOMEventTarget* aCurrentTarget,
                                             PRUint32 aFlags,
                                             nsEventStatus* aEventStatus,
                                             nsCxPusher* aPusher)
 {
+  SAMPLE_LABEL("nsEventListenerManager", "HandleEventInternal");
   //Set the value of the internal PreventDefault flag properly based on aEventStatus
   if (*aEventStatus == nsEventStatus_eConsumeNoDefault) {
     aEvent->flags |= NS_EVENT_FLAG_NO_DEFAULT;
   }
 
   nsAutoTObserverArray<nsListenerStruct, 2>::EndLimitedIterator iter(mListeners);
   nsAutoPopupStatePusher popupStatePusher(nsDOMEvent::GetEventPopupControlState(aEvent));
   bool hasListener = false;
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -2511,17 +2511,17 @@ nsEventStateManager::DoScrollZoom(nsIFra
   nsIContent *content = aTargetFrame->GetContent();
   if (content &&
       !content->IsNodeOfType(nsINode::eHTML_FORM_CONTROL) &&
       !content->IsXUL())
     {
       // positive adjustment to decrease zoom, negative to increase
       PRInt32 change = (adjustment > 0) ? -1 : 1;
 
-      if (Preferences::GetBool("browser.zoom.full")) {
+      if (Preferences::GetBool("browser.zoom.full") || content->GetCurrentDoc()->IsSyntheticDocument()) {
         ChangeFullZoom(change);
       } else {
         ChangeTextSize(change);
       }
     }
 }
 
 static nsIFrame*
@@ -2544,17 +2544,18 @@ GetScrollableLineHeight(nsIFrame* aTarge
     nsIScrollableFrame* sf = f->GetScrollTargetFrame();
     if (sf)
       return sf->GetLineScrollAmount().height;
   }
 
   // Fall back to the font height of the target frame.
   nsRefPtr<nsFontMetrics> fm;
   nsLayoutUtils::GetFontMetricsForFrame(aTargetFrame, getter_AddRefs(fm),
-    nsLayoutUtils::FontSizeInflationFor(aTargetFrame));
+    nsLayoutUtils::FontSizeInflationFor(aTargetFrame,
+                                        nsLayoutUtils::eNotInReflow));
   NS_ASSERTION(fm, "FontMetrics is null!");
   if (fm)
     return fm->MaxHeight();
   return 0;
 }
 
 void
 nsEventStateManager::SendLineScrollEvent(nsIFrame* aTargetFrame,
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -1821,17 +1821,17 @@ nsGenericHTMLElement::MapCommonAttribute
         else if (value->Equals(nsGkAtoms::_false, eIgnoreCase)) {
             userModify->SetIntValue(NS_STYLE_USER_MODIFY_READ_ONLY,
                                     eCSSUnit_Enumerated);
         }
       }
     }
   }
 
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Visibility)) {
+  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Font)) {
     const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::lang);
     if (value && value->Type() == nsAttrValue::eString) {
       aData->ValueForLang()->SetStringValue(value->GetStringValue(),
                                             eCSSUnit_Ident);
     }
   }
 }
 
--- a/content/html/content/src/nsHTMLAnchorElement.cpp
+++ b/content/html/content/src/nsHTMLAnchorElement.cpp
@@ -135,24 +135,37 @@ public:
                                 const nsAString& aValue,
                                 nsAttrValue& aResult);
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsEventStates IntrinsicState() const;
 
   virtual nsXPCClassInfo* GetClassInfo();
+  
+  virtual void OnDNSPrefetchDeferred();
+  virtual void OnDNSPrefetchRequested();
+  virtual bool HasDeferredDNSPrefetchRequest();
 };
 
+// Indicates that a DNS Prefetch has been requested from this Anchor elem
+#define HTML_ANCHOR_DNS_PREFETCH_REQUESTED \
+  (1 << ELEMENT_TYPE_SPECIFIC_BITS_OFFSET)
+// Indicates that a DNS Prefetch was added to the deferral queue
+#define HTML_ANCHOR_DNS_PREFETCH_DEFERRED \
+  (1 << (ELEMENT_TYPE_SPECIFIC_BITS_OFFSET+1))
+
+// Make sure we have enough space for those bits
+PR_STATIC_ASSERT(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET+1 < 32);
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Anchor)
 
 nsHTMLAnchorElement::nsHTMLAnchorElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo),
-    Link(this)
+  : nsGenericHTMLElement(aNodeInfo)
+  , Link(this)
 {
 }
 
 nsHTMLAnchorElement::~nsHTMLAnchorElement()
 {
 }
 
 
@@ -197,16 +210,36 @@ nsHTMLAnchorElement::GetDraggable(bool* 
                                nsGkAtoms::_false, eIgnoreCase);
     return NS_OK;
   }
 
   // no href, so just use the same behavior as other elements
   return nsGenericHTMLElement::GetDraggable(aDraggable);
 }
 
+void
+nsHTMLAnchorElement::OnDNSPrefetchRequested()
+{
+  UnsetFlags(HTML_ANCHOR_DNS_PREFETCH_DEFERRED);
+  SetFlags(HTML_ANCHOR_DNS_PREFETCH_REQUESTED);
+}
+
+void
+nsHTMLAnchorElement::OnDNSPrefetchDeferred()
+{
+  UnsetFlags(HTML_ANCHOR_DNS_PREFETCH_REQUESTED);
+  SetFlags(HTML_ANCHOR_DNS_PREFETCH_DEFERRED);
+}
+
+bool
+nsHTMLAnchorElement::HasDeferredDNSPrefetchRequest()
+{
+  return HasFlag(HTML_ANCHOR_DNS_PREFETCH_DEFERRED);
+}
+
 nsresult
 nsHTMLAnchorElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                                 nsIContent* aBindingParent,
                                 bool aCompileEventHandlers)
 {
   Link::ResetLinkState(false);
 
   nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
@@ -223,16 +256,31 @@ nsHTMLAnchorElement::BindToTree(nsIDocum
   }
 
   return rv;
 }
 
 void
 nsHTMLAnchorElement::UnbindFromTree(bool aDeep, bool aNullParent)
 {
+  // Cancel any DNS prefetches
+  // Note: Must come before ResetLinkState.  If called after, it will recreate
+  // mCachedURI based on data that is invalid - due to a call to GetHostname.
+
+  // If prefetch was deferred, clear flag and move on
+  if (HasFlag(HTML_ANCHOR_DNS_PREFETCH_DEFERRED))
+    UnsetFlags(HTML_ANCHOR_DNS_PREFETCH_DEFERRED);
+  // Else if prefetch was requested, clear flag and send cancellation
+  else if (HasFlag(HTML_ANCHOR_DNS_PREFETCH_REQUESTED)) {
+    UnsetFlags(HTML_ANCHOR_DNS_PREFETCH_REQUESTED);
+    // Possible that hostname could have changed since binding, but since this
+    // covers common cases, most DNS prefetch requests will be canceled
+    nsHTMLDNSPrefetch::CancelPrefetchLow(this, NS_ERROR_ABORT);
+  }
+  
   // If this link is ever reinserted into a document, it might
   // be under a different xml:base, so forget the cached state now.
   Link::ResetLinkState(false);
   
   nsIDocument* doc = GetCurrentDoc();
   if (doc) {
     doc->UnregisterPendingLinkUpdate(this);
   }
--- a/content/html/content/src/nsHTMLDNSPrefetch.cpp
+++ b/content/html/content/src/nsHTMLDNSPrefetch.cpp
@@ -160,54 +160,112 @@ nsHTMLDNSPrefetch::PrefetchMedium(Link *
 
 nsresult
 nsHTMLDNSPrefetch::PrefetchHigh(Link *aElement)
 {
   return Prefetch(aElement, 0);
 }
 
 nsresult
-nsHTMLDNSPrefetch::Prefetch(nsAString &hostname, PRUint16 flags)
+nsHTMLDNSPrefetch::Prefetch(const nsAString &hostname, PRUint16 flags)
 {
   if (IsNeckoChild()) {
     // We need to check IsEmpty() because net_IsValidHostName()
     // considers empty strings to be valid hostnames
     if (!hostname.IsEmpty() &&
         net_IsValidHostName(NS_ConvertUTF16toUTF8(hostname))) {
       gNeckoChild->SendHTMLDNSPrefetch(nsAutoString(hostname), flags);
     }
     return NS_OK;
   }
 
   if (!(sInitialized && sDNSService && sPrefetches && sDNSListener))
     return NS_ERROR_NOT_AVAILABLE;
 
   nsCOMPtr<nsICancelable> tmpOutstanding;
-  return sDNSService->AsyncResolve(NS_ConvertUTF16toUTF8(hostname), flags | nsIDNSService::RESOLVE_SPECULATE,
-                                   sDNSListener, nsnull, getter_AddRefs(tmpOutstanding));
+  return sDNSService->AsyncResolve(NS_ConvertUTF16toUTF8(hostname),
+                                   flags | nsIDNSService::RESOLVE_SPECULATE,
+                                   sDNSListener, nsnull, 
+                                   getter_AddRefs(tmpOutstanding));
 }
 
 nsresult
-nsHTMLDNSPrefetch::PrefetchLow(nsAString &hostname)
+nsHTMLDNSPrefetch::PrefetchLow(const nsAString &hostname)
 {
   return Prefetch(hostname, nsIDNSService::RESOLVE_PRIORITY_LOW);
 }
 
 nsresult
-nsHTMLDNSPrefetch::PrefetchMedium(nsAString &hostname)
+nsHTMLDNSPrefetch::PrefetchMedium(const nsAString &hostname)
 {
   return Prefetch(hostname, nsIDNSService::RESOLVE_PRIORITY_MEDIUM);
 }
 
 nsresult
-nsHTMLDNSPrefetch::PrefetchHigh(nsAString &hostname)
+nsHTMLDNSPrefetch::PrefetchHigh(const nsAString &hostname)
 {
   return Prefetch(hostname, 0);
 }
 
+nsresult
+nsHTMLDNSPrefetch::CancelPrefetch(Link *aElement,
+                                  PRUint16 flags,
+                                  nsresult aReason)
+{
+  if (!(sInitialized && sPrefetches && sDNSService && sDNSListener))
+    return NS_ERROR_NOT_AVAILABLE;
+
+  nsAutoString hostname;
+  nsresult rv = aElement->GetHostname(hostname);
+  NS_ENSURE_SUCCESS(rv, rv);
+  return CancelPrefetch(hostname, flags, aReason);
+}
+
+nsresult
+nsHTMLDNSPrefetch::CancelPrefetch(const nsAString &hostname,
+                                  PRUint16 flags,
+                                  nsresult aReason)
+{
+  // Forward this request to Necko Parent if we're a child process
+  if (IsNeckoChild()) {
+    // We need to check IsEmpty() because net_IsValidHostName()
+    // considers empty strings to be valid hostnames
+    if (!hostname.IsEmpty() &&
+        net_IsValidHostName(NS_ConvertUTF16toUTF8(hostname))) {
+      gNeckoChild->SendCancelHTMLDNSPrefetch(nsString(hostname), flags,
+                                             aReason);
+    }
+    return NS_OK;
+  }
+
+  if (!(sInitialized && sDNSService && sPrefetches && sDNSListener))
+    return NS_ERROR_NOT_AVAILABLE;
+
+  // Forward cancellation to DNS service
+  return sDNSService->CancelAsyncResolve(NS_ConvertUTF16toUTF8(hostname),
+                                         flags
+                                         | nsIDNSService::RESOLVE_SPECULATE,
+                                         sDNSListener, aReason);
+}
+
+nsresult
+nsHTMLDNSPrefetch::CancelPrefetchLow(Link *aElement, nsresult aReason)
+{
+  return CancelPrefetch(aElement, nsIDNSService::RESOLVE_PRIORITY_LOW,
+                        aReason);
+}
+
+nsresult
+nsHTMLDNSPrefetch::CancelPrefetchLow(const nsAString &hostname, nsresult aReason)
+{
+  return CancelPrefetch(hostname, nsIDNSService::RESOLVE_PRIORITY_LOW,
+                        aReason);
+}
+
+
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsHTMLDNSPrefetch::nsListener,
                               nsIDNSListener)
 
 NS_IMETHODIMP
 nsHTMLDNSPrefetch::nsListener::OnLookupComplete(nsICancelable *request,
                                               nsIDNSRecord  *rec,
@@ -252,16 +310,18 @@ nsHTMLDNSPrefetch::nsDeferrals::Flush()
 }
 
 nsresult
 nsHTMLDNSPrefetch::nsDeferrals::Add(PRUint16 flags, Link *aElement)
 {
   // The FIFO has no lock, so it can only be accessed on main thread
   NS_ASSERTION(NS_IsMainThread(), "nsDeferrals::Add must be on main thread");
 
+  aElement->OnDNSPrefetchDeferred();
+
   if (((mHead + 1) & sMaxDeferredMask) == mTail)
     return NS_ERROR_DNS_LOOKUP_QUEUE_FULL;
     
   mEntries[mHead].mFlags = flags;
   mEntries[mHead].mElement = do_GetWeakReference(aElement);
   mHead = (mHead + 1) & sMaxDeferredMask;
 
   if (!mActiveLoaderCount && !mTimerArmed && mTimer) {
@@ -278,30 +338,38 @@ nsHTMLDNSPrefetch::nsDeferrals::SubmitQu
   NS_ASSERTION(NS_IsMainThread(), "nsDeferrals::SubmitQueue must be on main thread");
   nsCString hostName;
   if (!sDNSService) return;
 
   while (mHead != mTail) {
     nsCOMPtr<nsIContent> content = do_QueryReferent(mEntries[mTail].mElement);
     if (content) {
       nsCOMPtr<Link> link = do_QueryInterface(content);
-      nsCOMPtr<nsIURI> hrefURI(link ? link->GetURI() : nsnull);
-      if (hrefURI)
-        hrefURI->GetAsciiHost(hostName);
+      // Only prefetch here if request was deferred and deferral not cancelled
+      if (link && link->HasDeferredDNSPrefetchRequest()) {
+        nsCOMPtr<nsIURI> hrefURI(link ? link->GetURI() : nsnull);
+        if (hrefURI)
+          hrefURI->GetAsciiHost(hostName);
 
-      if (!hostName.IsEmpty()) {
-        if (IsNeckoChild()) {
-          gNeckoChild->SendHTMLDNSPrefetch(NS_ConvertUTF8toUTF16(hostName),
+        if (!hostName.IsEmpty()) {
+          if (IsNeckoChild()) {
+            gNeckoChild->SendHTMLDNSPrefetch(NS_ConvertUTF8toUTF16(hostName),
                                            mEntries[mTail].mFlags);
-        } else {
-          nsCOMPtr<nsICancelable> tmpOutstanding;
+          } else {
+            nsCOMPtr<nsICancelable> tmpOutstanding;
 
-          sDNSService->AsyncResolve(hostName, 
-                                  mEntries[mTail].mFlags | nsIDNSService::RESOLVE_SPECULATE,
-                                  sDNSListener, nsnull, getter_AddRefs(tmpOutstanding));
+            nsresult rv = sDNSService->AsyncResolve(hostName, 
+                                    mEntries[mTail].mFlags
+                                    | nsIDNSService::RESOLVE_SPECULATE,
+                                    sDNSListener, nsnull,
+                                    getter_AddRefs(tmpOutstanding));
+            // Tell link that deferred prefetch was requested
+            if (NS_SUCCEEDED(rv))
+              link->OnDNSPrefetchRequested();
+          }
         }
       }
     }
     
     mEntries[mTail].mElement = nsnull;
     mTail = (mTail + 1) & sMaxDeferredMask;
   }
   
--- a/content/html/content/src/nsHTMLDNSPrefetch.h
+++ b/content/html/content/src/nsHTMLDNSPrefetch.h
@@ -79,23 +79,32 @@ public:
   // complete, while the string versions submit the lookup to 
   // the DNS system immediately. The URI version is somewhat lighter
   // weight, but its request is also more likely to be dropped due to a 
   // full queue and it may only be used from the main thread.
 
   static nsresult PrefetchHigh(mozilla::dom::Link *aElement);
   static nsresult PrefetchMedium(mozilla::dom::Link *aElement);
   static nsresult PrefetchLow(mozilla::dom::Link *aElement);
-  static nsresult PrefetchHigh(nsAString &host);
-  static nsresult PrefetchMedium(nsAString &host);
-  static nsresult PrefetchLow(nsAString &host);
+  static nsresult PrefetchHigh(const nsAString &host);
+  static nsresult PrefetchMedium(const nsAString &host);
+  static nsresult PrefetchLow(const nsAString &host);
+  static nsresult CancelPrefetchLow(const nsAString &host, nsresult aReason);
+  static nsresult CancelPrefetchLow(mozilla::dom::Link *aElement,
+                                    nsresult aReason);
 
 private:
-  static nsresult Prefetch(nsAString &host, PRUint16 flags);
+  static nsresult Prefetch(const nsAString &host, PRUint16 flags);
   static nsresult Prefetch(mozilla::dom::Link *aElement, PRUint16 flags);
+  static nsresult CancelPrefetch(const nsAString &hostname,
+                                 PRUint16 flags,
+                                 nsresult aReason);
+  static nsresult CancelPrefetch(mozilla::dom::Link *aElement,
+                                 PRUint16 flags,
+                                 nsresult aReason);
   
 public:
   class nsListener : public nsIDNSListener
   {
     // This class exists to give a safe callback no-op DNSListener
   public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIDNSLISTENER
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -212,16 +212,17 @@ public:
   NS_IMETHOD PageMove(bool aForward, bool aExtend);
   NS_IMETHOD CompleteScroll(bool aForward);
   NS_IMETHOD CompleteMove(bool aForward, bool aExtend);
   NS_IMETHOD ScrollPage(bool aForward);
   NS_IMETHOD ScrollLine(bool aForward);
   NS_IMETHOD ScrollCharacter(bool aRight);
   NS_IMETHOD SelectAll(void);
   NS_IMETHOD CheckVisibility(nsIDOMNode *node, PRInt16 startOffset, PRInt16 EndOffset, bool *_retval);
+  virtual nsresult CheckVisibilityContent(nsIContent* aNode, PRInt16 aStartOffset, PRInt16 aEndOffset, bool* aRetval);
 
 private:
   nsRefPtr<nsFrameSelection> mFrameSelection;
   nsCOMPtr<nsIContent>       mLimiter;
   nsIScrollableFrame        *mScrollFrame;
   nsWeakPtr mPresShellWeak;
 };
 
@@ -601,16 +602,32 @@ nsTextInputSelectionImpl::CheckVisibilit
   if (shell)
   {
     return shell->CheckVisibility(node,startOffset,EndOffset, _retval);
   }
   return NS_ERROR_FAILURE;
 
 }
 
+nsresult
+nsTextInputSelectionImpl::CheckVisibilityContent(nsIContent* aNode,
+                                                 PRInt16 aStartOffset,
+                                                 PRInt16 aEndOffset,
+                                                 bool* aRetval)
+{
+  if (!mPresShellWeak) {
+    return NS_ERROR_NOT_INITIALIZED;
+  }
+
+  nsCOMPtr<nsISelectionController> shell = do_QueryReferent(mPresShellWeak);
+  NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
+
+  return shell->CheckVisibilityContent(aNode, aStartOffset, aEndOffset, aRetval);
+}
+
 class nsTextInputListener : public nsISelectionListener,
                             public nsIDOMEventListener,
                             public nsIEditorObserver,
                             public nsSupportsWeakReference
 {
 public:
   /** the default constructor
    */ 
--- a/content/html/document/src/MediaDocument.cpp
+++ b/content/html/document/src/MediaDocument.cpp
@@ -44,17 +44,16 @@
 #include "nsIScrollable.h"
 #include "nsIViewManager.h"
 #include "nsITextToSubURI.h"
 #include "nsIURL.h"
 #include "nsIContentViewer.h"
 #include "nsIMarkupDocumentViewer.h"
 #include "nsIDocShell.h"
 #include "nsIParser.h" // kCharsetFrom* macro definition
-#include "nsIDocumentCharsetInfo.h" 
 #include "nsNodeInfoManager.h"
 #include "nsContentUtils.h"
 
 namespace mozilla {
 namespace dom {
 
 MediaDocumentStreamListener::MediaDocumentStreamListener(MediaDocument *aDocument)
 {
@@ -180,38 +179,34 @@ MediaDocument::StartDocumentLoad(const c
   // |UpdateTitleAndCharset| and the worst thing possible is a mangled 
   // filename in the titlebar and the file picker.
 
   // When this document is opened in the window/tab of the referring 
   // document (by a simple link-clicking), |prevDocCharacterSet| contains 
   // the charset of the referring document. On the other hand, if the
   // document is opened in a new window, it is |defaultCharacterSet| of |muCV| 
   // where the charset of our interest is stored. In case of openining 
-  // in a new tab, we get the charset from |documentCharsetInfo|. Note that we 
+  // in a new tab, we get the charset from the docShell. Note that we 
   // exclude UTF-8 as 'invalid' because UTF-8 is likely to be the charset 
   // of a chrome document that has nothing to do with the actual content 
   // whose charset we want to know. Even if "the actual content" is indeed 
   // in UTF-8, we don't lose anything because the default empty value is 
   // considered synonymous with UTF-8. 
     
   nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aContainer));
 
   // not being able to set the charset is not critical.
   NS_ENSURE_TRUE(docShell, NS_OK); 
 
-  nsCOMPtr<nsIDocumentCharsetInfo> dcInfo;
   nsCAutoString charset;
 
-  docShell->GetDocumentCharsetInfo(getter_AddRefs(dcInfo));
-  if (dcInfo) {
-    nsCOMPtr<nsIAtom> csAtom;
-    dcInfo->GetParentCharset(getter_AddRefs(csAtom));
-    if (csAtom) {   // opening in a new tab
-      csAtom->ToUTF8String(charset);
-    }
+  nsCOMPtr<nsIAtom> csAtom;
+  docShell->GetParentCharset(getter_AddRefs(csAtom));
+  if (csAtom) {   // opening in a new tab
+    csAtom->ToUTF8String(charset);
   }
 
   if (charset.IsEmpty() || charset.Equals("UTF-8")) {
     nsCOMPtr<nsIContentViewer> cv;
     docShell->GetContentViewer(getter_AddRefs(cv));
 
     // not being able to set the charset is not critical.
     NS_ENSURE_TRUE(cv, NS_OK); 
--- a/content/html/document/src/PluginDocument.cpp
+++ b/content/html/document/src/PluginDocument.cpp
@@ -42,16 +42,17 @@
 #include "nsIObjectFrame.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsNodeInfoManager.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentPolicyUtils.h"
 #include "nsIPropertyBag2.h"
 #include "mozilla/dom/Element.h"
+#include "sampler.h"
 
 namespace mozilla {
 namespace dom {
 
 class PluginDocument : public MediaDocument
                      , public nsIPluginDocument
 {
 public:
@@ -108,16 +109,17 @@ private:
 
   nsRefPtr<PluginDocument> mPluginDoc;
 };
 
 
 NS_IMETHODIMP
 PluginStreamListener::OnStartRequest(nsIRequest* request, nsISupports *ctxt)
 {
+  SAMPLE_LABEL("PluginStreamListener", "OnStartRequest");
   // Have to set up our plugin stuff before we call OnStartRequest, so
   // that the plugin listener can get that call.
   nsresult rv = SetupPlugin();
 
   NS_ASSERTION(NS_FAILED(rv) || mNextStream,
                "We should have a listener by now");
   nsresult rv2 = MediaDocumentStreamListener::OnStartRequest(request, ctxt);
   return NS_SUCCEEDED(rv) ? rv2 : rv;
--- a/content/html/document/src/nsHTMLContentSink.cpp
+++ b/content/html/document/src/nsHTMLContentSink.cpp
@@ -68,20 +68,16 @@
 #include "mozilla/Preferences.h"
 
 #include "nsGenericHTMLElement.h"
 
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentType.h"
 #include "nsIScriptElement.h"
 
-#include "nsIDOMHTMLFormElement.h"
-#include "nsIFormControl.h"
-#include "nsIForm.h"
-
 #include "nsIComponentManager.h"
 #include "nsIServiceManager.h"
 
 #include "nsGkAtoms.h"
 #include "nsContentUtils.h"
 #include "nsIChannel.h"
 #include "nsIHttpChannel.h"
 #include "nsIDocShell.h"
@@ -156,27 +152,24 @@ static const contentCreatorCallback sCon
 #undef HTML_HTMLELEMENT_TAG
 #undef HTML_OTHER
   NS_NewHTMLUnknownElement
 };
 
 class SinkContext;
 class HTMLContentSink;
 
-static void MaybeSetForm(nsGenericHTMLElement*, nsHTMLTag, HTMLContentSink*);
-
 class HTMLContentSink : public nsContentSink,
 #ifdef DEBUG
                         public nsIDebugDumpContent,
 #endif
                         public nsIHTMLContentSink
 {
 public:
   friend class SinkContext;
-  friend void MaybeSetForm(nsGenericHTMLElement*, nsHTMLTag, HTMLContentSink*);
 
   HTMLContentSink();
   virtual ~HTMLContentSink();
 
   NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
 
   nsresult Init(nsIDocument* aDoc, nsIURI* aURI, nsISupports* aContainer,
                 nsIChannel* aChannel);
@@ -197,27 +190,23 @@ public:
   virtual nsISupports *GetTarget();
   virtual bool IsScriptExecuting();
 
   // nsIHTMLContentSink
   NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
   NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
   NS_IMETHOD CloseMalformedContainer(const nsHTMLTag aTag);
   NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
-  NS_IMETHOD AddComment(const nsIParserNode& aNode);
-  NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode);
-  NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode);
   NS_IMETHOD DidProcessTokens(void);
   NS_IMETHOD WillProcessAToken(void);
   NS_IMETHOD DidProcessAToken(void);
   NS_IMETHOD BeginContext(PRInt32 aID);
   NS_IMETHOD EndContext(PRInt32 aID);
   NS_IMETHOD OpenHead();
   NS_IMETHOD IsEnabled(PRInt32 aTag, bool* aReturn);
-  NS_IMETHOD_(bool) IsFormOnStack();
 
 #ifdef DEBUG
   // nsIDebugDumpContent
   NS_IMETHOD DumpContentModel();
 #endif
 
 protected:
   // If aCheckIfPresent is true, will only set an attribute in cases
@@ -238,63 +227,42 @@ protected:
 
   nsCOMPtr<nsIHTMLDocument> mHTMLDocument;
 
   // The maximum length of a text run
   PRInt32 mMaxTextRun;
 
   nsRefPtr<nsGenericHTMLElement> mRoot;
   nsRefPtr<nsGenericHTMLElement> mBody;
-  nsRefPtr<nsGenericHTMLElement> mFrameset;
   nsRefPtr<nsGenericHTMLElement> mHead;
 
-  nsRefPtr<nsGenericHTMLElement> mCurrentForm;
-
   nsAutoTArray<SinkContext*, 8> mContextStack;
   SinkContext* mCurrentContext;
   SinkContext* mHeadContext;
-  PRInt32 mNumOpenIFRAMES;
-
-  // depth of containment within <noembed>, <noframes> etc
-  PRInt32 mInsideNoXXXTag;
 
   // Boolean indicating whether we've seen a <head> tag that might have had
   // attributes once already.