Merge inbound to m-c a=merge
authorWes Kocher <wkocher@mozilla.com>
Wed, 07 Oct 2015 10:29:41 -0700
changeset 266645 49d87bbe0122d894c8e45f0b409c42dfe1c36737
parent 266644 1831ba1be747218569761f3f57e986f78f349b09 (current diff)
parent 266508 d6793bb3e45b2853d33c653b14f5a909ee46a9e4 (diff)
child 266646 1e1fa696e2b626ead6817b7c5bd871fec5d5ab5a
push id66235
push userkwierso@gmail.com
push dateWed, 07 Oct 2015 18:10:17 +0000
treeherdermozilla-inbound@2499a66d5b37 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone44.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to m-c a=merge
accessible/windows/ia2/ia2Accessible.cpp
browser/base/content/social-content.js
devtools/client/animationinspector/animation-controller.js
devtools/client/layoutview/view.js
devtools/client/styleinspector/test/head.js
devtools/client/webide/content/webide.js
devtools/client/webide/test/head.js
devtools/server/tests/browser/head.js
docshell/base/nsDocShell.cpp
dom/animation/Animation.cpp
dom/animation/Animation.h
dom/animation/KeyframeEffect.cpp
dom/animation/KeyframeEffect.h
dom/audiochannel/AudioChannelAgent.cpp
dom/base/Navigator.cpp
dom/base/WebSocket.cpp
dom/base/nsContentUtils.cpp
dom/base/nsDOMWindowUtils.cpp
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsIDocument.h
dom/base/nsObjectLoadingContent.cpp
dom/base/nsPIDOMWindow.h
dom/canvas/CanvasRenderingContext2D.cpp
dom/canvas/nsICanvasRenderingContextInternal.h
dom/crypto/WebCryptoTask.cpp
dom/crypto/WebCryptoTask.h
dom/fetch/FetchDriver.cpp
dom/filesystem/GetDirectoryListingTask.cpp
dom/html/nsHTMLDocument.cpp
dom/html/test/file_fullscreen-ancestor-stacking-context.html
dom/ipc/ContentChild.cpp
dom/media/MP3Decoder.cpp
dom/media/MediaDecoder.cpp
dom/media/MediaDecoder.h
dom/media/MediaDecoderStateMachine.cpp
dom/media/MediaFormatReader.cpp
dom/media/MediaFormatReader.h
dom/media/MediaManager.cpp
dom/media/MediaManager.h
dom/media/fmp4/MP4Decoder.cpp
dom/media/gmp/GMPServiceParent.cpp
dom/media/omx/MediaCodecProxy.h
dom/media/omx/MediaOmxCommonDecoder.cpp
dom/media/omx/MediaOmxReader.cpp
dom/media/platforms/PlatformDecoderModule.cpp
dom/media/platforms/PlatformDecoderModule.h
dom/media/platforms/agnostic/BlankDecoderModule.cpp
dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
dom/media/platforms/agnostic/eme/EMEDecoderModule.h
dom/media/platforms/apple/AppleDecoderModule.cpp
dom/media/platforms/ffmpeg/FFmpegDataDecoder.h
dom/media/platforms/ffmpeg/FFmpegDecoderModule.h
dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
dom/media/platforms/gonk/GonkAudioDecoderManager.cpp
dom/media/platforms/gonk/GonkAudioDecoderManager.h
dom/media/platforms/gonk/GonkMediaDataDecoder.cpp
dom/media/platforms/gonk/GonkMediaDataDecoder.h
dom/media/platforms/gonk/GonkVideoDecoderManager.cpp
dom/media/platforms/gonk/GonkVideoDecoderManager.h
dom/media/systemservices/MediaUtils.h
dom/media/webaudio/AudioContext.cpp
dom/media/webaudio/AudioContext.h
dom/media/webaudio/AudioDestinationNode.cpp
dom/media/webaudio/AudioDestinationNode.h
dom/media/webm/AudioDecoder.cpp
dom/media/webm/IntelWebMVideoDecoder.cpp
dom/media/webm/IntelWebMVideoDecoder.h
dom/media/webm/SoftwareWebMVideoDecoder.cpp
dom/media/webm/SoftwareWebMVideoDecoder.h
dom/media/webm/WebMReader.cpp
dom/media/webm/WebMReader.h
dom/media/webrtc/RTCCertificate.cpp
dom/svg/SVGFEImageElement.cpp
dom/workers/RuntimeService.cpp
dom/workers/ScriptLoader.cpp
dom/workers/ServiceWorkerScriptCache.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerPrivate.h
dom/workers/Workers.h
gfx/2d/PathHelpers.h
gfx/gl/GLTextureImage.cpp
gfx/gl/GLTextureImage.h
gfx/layers/ImageLayers.h
gfx/layers/LayerTreeInvalidation.cpp
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/YCbCrImageDataSerializer.cpp
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/APZCTreeManager.h
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/basic/BasicCanvasLayer.cpp
gfx/layers/basic/BasicImageLayer.cpp
gfx/layers/composite/AsyncCompositionManager.h
gfx/layers/composite/CanvasLayerComposite.cpp
gfx/layers/composite/ImageLayerComposite.cpp
gfx/layers/ipc/CompositorChild.cpp
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/CompositorParent.h
gfx/layers/opengl/CompositorOGL.cpp
gfx/layers/opengl/CompositorOGLVR.cpp
gfx/thebes/GraphicsFilter.h
gfx/thebes/gfxDrawable.cpp
gfx/thebes/gfxDrawable.h
gfx/thebes/gfxPattern.h
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxUtils.cpp
gfx/thebes/gfxUtils.h
gfx/thebes/gfxWindowsNativeDrawing.cpp
image/ClippedImage.cpp
image/ClippedImage.h
image/DynamicImage.cpp
image/FrozenImage.h
image/ImageWrapper.cpp
image/OrientedImage.cpp
image/OrientedImage.h
image/RasterImage.cpp
image/RasterImage.h
image/VectorImage.cpp
image/imgFrame.cpp
image/imgFrame.h
image/imgIContainer.idl
js/src/devtools/rootAnalysis/build.b2g
js/src/devtools/rootAnalysis/build.browser
js/src/devtools/rootAnalysis/build.shell
js/src/jit-test/tests/basic/bug778268.js
js/src/jit/AtomicOperations-inl.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/tests/js1_7/regress/regress-406477.js
js/src/vm/Interpreter.cpp
js/src/vm/Runtime.h
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/src/XPCShellImpl.cpp
layout/base/AccessibleCaretManager.cpp
layout/base/AccessibleCaretManager.h
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSRendering.cpp
layout/base/nsDisplayList.h
layout/base/nsDocumentViewer.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/generic/nsBlockFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
layout/generic/nsImageFrame.cpp
layout/generic/nsPluginFrame.cpp
layout/generic/nsPluginFrame.h
layout/mathml/nsMathMLFrame.cpp
layout/style/AnimationCommon.h
layout/style/full-screen-override.css
layout/style/nsAnimationManager.cpp
layout/style/nsAnimationManager.h
layout/style/nsCSSParser.cpp
layout/style/nsCSSProps.h
layout/style/nsCSSRuleProcessor.cpp
layout/style/nsLayoutStylesheetCache.cpp
layout/style/nsLayoutStylesheetCache.h
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.h
layout/style/nsTransitionManager.cpp
layout/style/nsTransitionManager.h
layout/svg/nsSVGIntegrationUtils.cpp
layout/xul/tree/nsTreeBodyFrame.cpp
media/libstagefright/frameworks/av/media/libstagefright/id3/ID3.cpp
media/libstagefright/frameworks/av/media/libstagefright/include/ID3.h
modules/libjar/nsJARChannel.cpp
modules/libjar/nsJARChannel.h
modules/libpref/init/all.js
netwerk/base/nsIOService.cpp
netwerk/base/nsNetUtil.cpp
netwerk/protocol/app/AppProtocolHandler.cpp
netwerk/protocol/http/Http2Session.cpp
netwerk/protocol/http/Http2Stream.cpp
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpBaseChannel.h
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/nsCORSListenerProxy.cpp
netwerk/protocol/http/nsHttpChannel.cpp
security/manager/ssl/nsNSSCallbacks.cpp
testing/profiles/prefs_general.js
toolkit/components/alerts/resources/content/alert.js
toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
toolkit/components/url-classifier/nsUrlClassifierProxies.h
toolkit/mozapps/extensions/internal/XPIProvider.jsm
toolkit/mozapps/extensions/test/xpcshell/test_system_update.js
widget/PuppetWidget.cpp
widget/cocoa/nsCocoaUtils.mm
widget/nsBaseDragService.cpp
xpcom/base/nsMemoryReporterManager.cpp
xpcom/base/nsMemoryReporterManager.h
--- a/accessible/atk/AccessibleWrap.cpp
+++ b/accessible/atk/AccessibleWrap.cpp
@@ -9,16 +9,18 @@
 #include "Accessible-inl.h"
 #include "ApplicationAccessibleWrap.h"
 #include "InterfaceInitFuncs.h"
 #include "nsAccUtils.h"
 #include "mozilla/a11y/PDocAccessible.h"
 #include "OuterDocAccessible.h"
 #include "ProxyAccessible.h"
 #include "RootAccessible.h"
+#include "TableAccessible.h"
+#include "TableCellAccessible.h"
 #include "nsMai.h"
 #include "nsMaiHyperlink.h"
 #include "nsString.h"
 #include "nsAutoPtr.h"
 #include "prprf.h"
 #include "nsStateMap.h"
 #include "mozilla/a11y/Platform.h"
 #include "Relation.h"
@@ -1565,8 +1567,123 @@ AccessibleWrap::FireAtkShowHideEvent(Acc
     NS_ENSURE_STATE(parentObject);
 
     bool isFromUserInput = aEvent->IsFromUserInput();
     const char *signal_name = kMutationStrings[isFromUserInput][aIsAdded];
     g_signal_emit_by_name(parentObject, signal_name, indexInParent, aObject, nullptr);
 
     return NS_OK;
 }
+
+// static
+void
+AccessibleWrap::GetKeyBinding(Accessible* aAccessible, nsAString& aResult)
+{
+  // Return all key bindings including access key and keyboard shortcut.
+
+  // Get access key.
+  nsAutoString keyBindingsStr;
+  KeyBinding keyBinding = aAccessible->AccessKey();
+  if (!keyBinding.IsEmpty()) {
+    keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
+
+    Accessible* parent = aAccessible->Parent();
+    roles::Role role = parent ? parent->Role() : roles::NOTHING;
+    if (role == roles::PARENT_MENUITEM || role == roles::MENUITEM ||
+        role == roles::RADIO_MENU_ITEM || role == roles::CHECK_MENU_ITEM) {
+      // It is submenu, expose keyboard shortcuts from menu hierarchy like
+      // "s;<Alt>f:s"
+      nsAutoString keysInHierarchyStr = keyBindingsStr;
+      do {
+        KeyBinding parentKeyBinding = parent->AccessKey();
+        if (!parentKeyBinding.IsEmpty()) {
+          nsAutoString str;
+          parentKeyBinding.ToString(str, KeyBinding::eAtkFormat);
+          str.Append(':');
+
+          keysInHierarchyStr.Insert(str, 0);
+        }
+      } while ((parent = parent->Parent()) && parent->Role() != roles::MENUBAR);
+
+      keyBindingsStr.Append(';');
+      keyBindingsStr.Append(keysInHierarchyStr);
+    }
+  } else {
+    // No access key, add ';' to point this.
+    keyBindingsStr.Append(';');
+  }
+
+  // Get keyboard shortcut.
+  keyBindingsStr.Append(';');
+  keyBinding = aAccessible->KeyboardShortcut();
+  if (!keyBinding.IsEmpty()) {
+    keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
+  }
+  aResult = keyBindingsStr;
+}
+
+// static
+Accessible*
+AccessibleWrap::GetColumnHeader(TableAccessible* aAccessible, int32_t aColIdx)
+{
+  if (!aAccessible) {
+    return nullptr;
+  }
+
+  Accessible* cell = aAccessible->CellAt(0, aColIdx);
+  if (!cell) {
+    return nullptr;
+  }
+
+  // If the cell at the first row is column header then assume it is column
+  // header for all rows,
+  if (cell->Role() == roles::COLUMNHEADER) {
+    return cell;
+  }
+
+  // otherwise get column header for the data cell at the first row.
+  TableCellAccessible* tableCell = cell->AsTableCell();
+  if (!tableCell) {
+    return nullptr;
+  }
+
+  nsAutoTArray<Accessible*, 10> headerCells;
+  tableCell->ColHeaderCells(&headerCells);
+  if (headerCells.IsEmpty()) {
+    return nullptr;
+  }
+
+  return headerCells[0];
+}
+
+// static
+Accessible*
+AccessibleWrap::GetRowHeader(TableAccessible* aAccessible, int32_t aRowIdx)
+{
+  if (!aAccessible) {
+    return nullptr;
+  }
+
+  Accessible* cell = aAccessible->CellAt(aRowIdx, 0);
+  if (!cell) {
+    return nullptr;
+  }
+
+  // If the cell at the first column is row header then assume it is row
+  // header for all columns,
+  if (cell->Role() == roles::ROWHEADER) {
+    return cell;
+  }
+
+  // otherwise get row header for the data cell at the first column.
+  TableCellAccessible* tableCell = cell->AsTableCell();
+  if (!tableCell) {
+    return nullptr;
+  }
+
+  nsAutoTArray<Accessible*, 10> headerCells;
+  tableCell->RowHeaderCells(&headerCells);
+  if (headerCells.IsEmpty()) {
+    return nullptr;
+  }
+
+  return headerCells[0];
+}
--- a/accessible/atk/AccessibleWrap.h
+++ b/accessible/atk/AccessibleWrap.h
@@ -64,16 +64,22 @@ public:
   bool IsValidObject();
 
   static const char * ReturnString(nsAString &aString) {
     static nsCString returnedString;
     returnedString = NS_ConvertUTF16toUTF8(aString);
     return returnedString.get();
   }
 
+  static void GetKeyBinding(Accessible* aAccessible, nsAString& aResult);
+
+  static Accessible* GetColumnHeader(TableAccessible* aAccessible,
+                                     int32_t aColIdx);
+  static Accessible* GetRowHeader(TableAccessible* aAccessible,
+                                  int32_t aRowIdx);
 protected:
 
   nsresult FireAtkStateChangeEvent(AccEvent* aEvent, AtkObject *aObject);
   nsresult FireAtkTextChangedEvent(AccEvent* aEvent, AtkObject *aObject);
   nsresult FireAtkShowHideEvent(AccEvent* aEvent, AtkObject *aObject,
                                 bool aIsAdded);
 
   AtkObject *mAtkObject;
--- a/accessible/atk/nsMaiInterfaceAction.cpp
+++ b/accessible/atk/nsMaiInterfaceAction.cpp
@@ -5,107 +5,90 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "InterfaceInitFuncs.h"
 
 #include "Accessible-inl.h"
 #include "nsMai.h"
 #include "Role.h"
 #include "mozilla/Likely.h"
-
+#include "ProxyAccessible.h"
 #include "nsString.h"
 
 using namespace mozilla::a11y;
 
 extern "C" {
 
 static gboolean
 doActionCB(AtkAction *aAction, gint aActionIndex)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
-  return accWrap && accWrap->DoAction(aActionIndex);
+  if (accWrap) {
+    return accWrap->DoAction(aActionIndex);
+  }
+
+  ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aAction));
+  return proxy && proxy->DoAction(aActionIndex);
 }
 
 static gint
 getActionCountCB(AtkAction *aAction)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
-  return accWrap ? accWrap->ActionCount() : 0;
+  if (accWrap) {
+    return accWrap->ActionCount();
+  }
+
+  ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aAction));
+  return proxy ? proxy->ActionCount() : 0;
 }
 
 static const gchar*
 getActionDescriptionCB(AtkAction *aAction, gint aActionIndex)
 {
+  nsAutoString description;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
-  if (!accWrap)
+  if (accWrap) {
+    accWrap->ActionDescriptionAt(aActionIndex, description);
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aAction))) {
+    proxy->ActionDescriptionAt(aActionIndex, description);
+  } else {
     return nullptr;
+  }
 
-  nsAutoString description;
-  accWrap->ActionDescriptionAt(aActionIndex, description);
   return AccessibleWrap::ReturnString(description);
 }
 
 static const gchar*
 getActionNameCB(AtkAction *aAction, gint aActionIndex)
 {
+  nsAutoString autoStr;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
-  if (!accWrap)
+  if (accWrap) {
+    accWrap->ActionNameAt(aActionIndex, autoStr);
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aAction))) {
+    proxy->ActionNameAt(aActionIndex, autoStr);
+  } else {
     return nullptr;
+  }
 
-  nsAutoString autoStr;
-  accWrap->ActionNameAt(aActionIndex, autoStr);
   return AccessibleWrap::ReturnString(autoStr);
 }
 
 static const gchar*
 getKeyBindingCB(AtkAction *aAction, gint aActionIndex)
 {
+  nsAutoString keyBindingsStr;
   AccessibleWrap* acc = GetAccessibleWrap(ATK_OBJECT(aAction));
-  if (!acc)
+  if (acc) {
+    AccessibleWrap::GetKeyBinding(acc, keyBindingsStr);
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aAction))) {
+    proxy->AtkKeyBinding(keyBindingsStr);
+  } else {
     return nullptr;
-
-  // Return all key bindings including access key and keyboard shortcut.
-  nsAutoString keyBindingsStr;
-
-  // Get access key.
-  KeyBinding keyBinding = acc->AccessKey();
-  if (!keyBinding.IsEmpty()) {
-    keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
-
-    Accessible* parent = acc->Parent();
-    roles::Role role = parent ? parent->Role() : roles::NOTHING;
-    if (role == roles::PARENT_MENUITEM || role == roles::MENUITEM ||
-        role == roles::RADIO_MENU_ITEM || role == roles::CHECK_MENU_ITEM) {
-      // It is submenu, expose keyboard shortcuts from menu hierarchy like
-      // "s;<Alt>f:s"
-      nsAutoString keysInHierarchyStr = keyBindingsStr;
-      do {
-        KeyBinding parentKeyBinding = parent->AccessKey();
-        if (!parentKeyBinding.IsEmpty()) {
-          nsAutoString str;
-          parentKeyBinding.ToString(str, KeyBinding::eAtkFormat);
-          str.Append(':');
-
-          keysInHierarchyStr.Insert(str, 0);
-        }
-      } while ((parent = parent->Parent()) && parent->Role() != roles::MENUBAR);
-
-      keyBindingsStr.Append(';');
-      keyBindingsStr.Append(keysInHierarchyStr);
-    }
-  } else {
-    // No access key, add ';' to point this.
-    keyBindingsStr.Append(';');
-  }
-
-  // Get keyboard shortcut.
-  keyBindingsStr.Append(';');
-  keyBinding = acc->KeyboardShortcut();
-  if (!keyBinding.IsEmpty()) {
-    keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
   }
 
   return AccessibleWrap::ReturnString(keyBindingsStr);
 }
 }
 
 void
 actionInterfaceInitCB(AtkActionIface* aIface)
--- a/accessible/atk/nsMaiInterfaceTable.cpp
+++ b/accessible/atk/nsMaiInterfaceTable.cpp
@@ -7,205 +7,260 @@
 #include "InterfaceInitFuncs.h"
 
 #include "Accessible-inl.h"
 #include "AccessibleWrap.h"
 #include "nsAccUtils.h"
 #include "TableAccessible.h"
 #include "TableCellAccessible.h"
 #include "nsMai.h"
-
+#include "ProxyAccessible.h"
 #include "nsArrayUtils.h"
 
 #include "mozilla/Likely.h"
 
 using namespace mozilla::a11y;
 
 extern "C" {
 static AtkObject*
 refAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
 {
+  if (aRowIdx < 0 || aColIdx < 0) {
+    return nullptr;
+  }
+
+  AtkObject* cellAtkObj = nullptr;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap || aRowIdx < 0 || aColIdx < 0)
-    return nullptr;
+  if (accWrap) {
+    Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, aColIdx);
+    if (!cell) {
+      return nullptr;
+    }
 
-  Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, aColIdx);
-  if (!cell)
-    return nullptr;
+    cellAtkObj = AccessibleWrap::GetAtkObject(cell);
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    ProxyAccessible* cell = proxy->TableCellAt(aRowIdx, aColIdx);
+    if (!cell) {
+      return nullptr;
+    }
 
-  AtkObject* cellAtkObj = AccessibleWrap::GetAtkObject(cell);
-  if (cellAtkObj)
+    cellAtkObj = GetWrapperFor(cell);
+  }
+
+  if (cellAtkObj) {
     g_object_ref(cellAtkObj);
+  }
 
   return cellAtkObj;
 }
 
 static gint
 getIndexAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
 {
-  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap || aRowIdx < 0 || aColIdx < 0)
+  if (aRowIdx < 0 || aColIdx < 0) {
     return -1;
+  }
 
-  return static_cast<gint>(accWrap->AsTable()->CellIndexAt(aRowIdx, aColIdx));
+  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
+  if (accWrap) {
+    return static_cast<gint>(accWrap->AsTable()->CellIndexAt(aRowIdx, aColIdx));
+  }
+
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gint>(proxy->TableCellIndexAt(aRowIdx, aColIdx));
+  }
+
+  return -1;
 }
 
 static gint
 getColumnAtIndexCB(AtkTable *aTable, gint aIdx)
 {
-  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap || aIdx < 0)
+  if (aIdx < 0) {
     return -1;
+  }
 
+  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
+  if (accWrap) {
     return static_cast<gint>(accWrap->AsTable()->ColIndexAt(aIdx));
+  }
+
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gint>(proxy->TableColumnIndexAt(aIdx));
+  }
+
+  return -1;
 }
 
 static gint
 getRowAtIndexCB(AtkTable *aTable, gint aIdx)
 {
-  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap || aIdx < 0)
+  if (aIdx < 0) {
     return -1;
+  }
 
+  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
+  if (accWrap) {
     return static_cast<gint>(accWrap->AsTable()->RowIndexAt(aIdx));
+  }
+
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gint>(proxy->TableRowIndexAt(aIdx));
+  }
+
+  return -1;
 }
 
 static gint
 getColumnCountCB(AtkTable *aTable)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return -1;
+  if (accWrap) {
+    return static_cast<gint>(accWrap->AsTable()->ColCount());
+  }
 
-    return static_cast<gint>(accWrap->AsTable()->ColCount());
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gint>(proxy->TableColumnCount());
+  }
+
+  return -1;
 }
 
 static gint
 getRowCountCB(AtkTable *aTable)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return -1;
+  if (accWrap) {
+    return static_cast<gint>(accWrap->AsTable()->RowCount());
+  }
 
-    return static_cast<gint>(accWrap->AsTable()->RowCount());
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gint>(proxy->TableRowCount());
+  }
+
+  return -1;
 }
 
 static gint
 getColumnExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
 {
-  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap || aRowIdx < 0 || aColIdx < 0)
+  if (aRowIdx < 0 || aColIdx < 0) {
     return -1;
+  }
 
+  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
+  if (accWrap) {
     return static_cast<gint>(accWrap->AsTable()->ColExtentAt(aRowIdx, aColIdx));
+  }
+
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gint>(proxy->TableColumnExtentAt(aRowIdx, aColIdx));
+  }
+
+  return -1;
 }
 
 static gint
 getRowExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return -1;
+  if (accWrap) {
+    return static_cast<gint>(accWrap->AsTable()->RowExtentAt(aRowIdx, aColIdx));
+  }
 
-  return static_cast<gint>(accWrap->AsTable()->RowExtentAt(aRowIdx, aColIdx));
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gint>(proxy->TableRowExtentAt(aRowIdx, aColIdx));
+  }
+
+  return -1;
 }
 
 static AtkObject*
 getCaptionCB(AtkTable* aTable)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return nullptr;
+  if (accWrap) {
+    Accessible* caption = accWrap->AsTable()->Caption();
+    return caption ? AccessibleWrap::GetAtkObject(caption) : nullptr;
+  }
 
-  Accessible* caption = accWrap->AsTable()->Caption();
-  return caption ? AccessibleWrap::GetAtkObject(caption) : nullptr;
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    ProxyAccessible* caption = proxy->TableCaption();
+    return caption ? GetWrapperFor(caption) : nullptr;
+  }
+
+  return nullptr;
 }
 
 static const gchar*
 getColumnDescriptionCB(AtkTable *aTable, gint aColumn)
 {
+  nsAutoString autoStr;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
+  if (accWrap) {
+    accWrap->AsTable()->ColDescription(aColumn, autoStr);
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    proxy->TableColumnDescription(aColumn, autoStr);
+  } else {
     return nullptr;
-
-  nsAutoString autoStr;
-  accWrap->AsTable()->ColDescription(aColumn, autoStr);
+  }
 
   return AccessibleWrap::ReturnString(autoStr);
 }
 
 static AtkObject*
 getColumnHeaderCB(AtkTable *aTable, gint aColIdx)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return nullptr;
-
-  Accessible* cell = accWrap->AsTable()->CellAt(0, aColIdx);
-  if (!cell)
-    return nullptr;
-
-  // If the cell at the first row is column header then assume it is column
-  // header for all rows,
-  if (cell->Role() == roles::COLUMNHEADER)
-    return AccessibleWrap::GetAtkObject(cell);
+  if (accWrap) {
+    Accessible* header =
+      AccessibleWrap::GetColumnHeader(accWrap->AsTable(), aColIdx);
+    return header ? AccessibleWrap::GetAtkObject(header) : nullptr;
+  }
 
-  // otherwise get column header for the data cell at the first row.
-  TableCellAccessible* tableCell = cell->AsTableCell();
-  if (!tableCell)
-    return nullptr;
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    ProxyAccessible* header = proxy->AtkTableColumnHeader(aColIdx);
+    return header ? GetWrapperFor(header) : nullptr;
+  }
 
-  nsAutoTArray<Accessible*, 10> headerCells;
-  tableCell->ColHeaderCells(&headerCells);
-  if (headerCells.IsEmpty())
-    return nullptr;
-
-  return AccessibleWrap::GetAtkObject(headerCells[0]);
+  return nullptr;
 }
 
 static const gchar*
 getRowDescriptionCB(AtkTable *aTable, gint aRow)
 {
+  nsAutoString autoStr;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
+  if (accWrap) {
+    accWrap->AsTable()->RowDescription(aRow, autoStr);
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    proxy->TableRowDescription(aRow, autoStr);
+  } else {
     return nullptr;
-
-  nsAutoString autoStr;
-  accWrap->AsTable()->RowDescription(aRow, autoStr);
+  }
 
   return AccessibleWrap::ReturnString(autoStr);
 }
 
 static AtkObject*
 getRowHeaderCB(AtkTable *aTable, gint aRowIdx)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return nullptr;
-
-  Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, 0);
-  if (!cell)
-    return nullptr;
-
-  // If the cell at the first column is row header then assume it is row
-  // header for all columns,
-  if (cell->Role() == roles::ROWHEADER)
-    return AccessibleWrap::GetAtkObject(cell);
+  if (accWrap) {
+    Accessible* header =
+      AccessibleWrap::GetRowHeader(accWrap->AsTable(), aRowIdx);
+    return header ? AccessibleWrap::GetAtkObject(header) : nullptr;
+  }
 
-  // otherwise get row header for the data cell at the first column.
-  TableCellAccessible* tableCell = cell->AsTableCell();
-  if (!tableCell)
-    return nullptr;
+  if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    ProxyAccessible* header = proxy->AtkTableRowHeader(aRowIdx);
+    return header ? GetWrapperFor(header) : nullptr;
+  }
 
-  nsAutoTArray<Accessible*, 10> headerCells;
-  tableCell->RowHeaderCells(&headerCells);
-  if (headerCells.IsEmpty())
-    return nullptr;
-
-  return AccessibleWrap::GetAtkObject(headerCells[0]);
+  return nullptr;
 }
 
 static AtkObject*
 getSummaryCB(AtkTable *aTable)
 {
   // Neither html:table nor xul:tree nor ARIA grid/tree have an ability to
   // link an accessible object to specify a summary. There is closes method
   // in TableAccessible::summary to get a summary as a string which is not
@@ -213,22 +268,26 @@ getSummaryCB(AtkTable *aTable)
   return nullptr;
 }
 
 static gint
 getSelectedColumnsCB(AtkTable *aTable, gint** aSelected)
 {
   *aSelected = nullptr;
 
+  nsAutoTArray<uint32_t, 10> cols;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
+  if (accWrap) {
+    accWrap->AsTable()->SelectedColIndices(&cols);
+   } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    proxy->TableSelectedColumnIndices(&cols);
+  } else {
     return 0;
+  }
 
-  nsAutoTArray<uint32_t, 10> cols;
-  accWrap->AsTable()->SelectedColIndices(&cols);
   if (cols.IsEmpty())
     return 0;
 
   gint* atkColumns = g_new(gint, cols.Length());
   if (!atkColumns) {
     NS_WARNING("OUT OF MEMORY");
     return 0;
   }
@@ -236,63 +295,75 @@ getSelectedColumnsCB(AtkTable *aTable, g
   memcpy(atkColumns, cols.Elements(), cols.Length() * sizeof(uint32_t));
   *aSelected = atkColumns;
   return cols.Length();
 }
 
 static gint
 getSelectedRowsCB(AtkTable *aTable, gint **aSelected)
 {
+  nsAutoTArray<uint32_t, 10> rows;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
+  if (accWrap) {
+    accWrap->AsTable()->SelectedRowIndices(&rows);
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    proxy->TableSelectedRowIndices(&rows);
+  } else {
     return 0;
-
-  nsAutoTArray<uint32_t, 10> rows;
-  accWrap->AsTable()->SelectedRowIndices(&rows);
+  }
 
   gint* atkRows = g_new(gint, rows.Length());
   if (!atkRows) {
     NS_WARNING("OUT OF MEMORY");
     return 0;
   }
 
   memcpy(atkRows, rows.Elements(), rows.Length() * sizeof(uint32_t));
   *aSelected = atkRows;
   return rows.Length();
 }
 
 static gboolean
 isColumnSelectedCB(AtkTable *aTable, gint aColIdx)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return FALSE;
+  if (accWrap) {
+    return static_cast<gboolean>(accWrap->AsTable()->IsColSelected(aColIdx));
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gboolean>(proxy->TableColumnSelected(aColIdx));
+  }
 
-  return static_cast<gboolean>(accWrap->AsTable()->IsColSelected(aColIdx));
+  return FALSE;
 }
 
 static gboolean
 isRowSelectedCB(AtkTable *aTable, gint aRowIdx)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return FALSE;
+  if (accWrap) {
+    return static_cast<gboolean>(accWrap->AsTable()->IsRowSelected(aRowIdx));
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gboolean>(proxy->TableRowSelected(aRowIdx));
+  }
 
-  return static_cast<gboolean>(accWrap->AsTable()->IsRowSelected(aRowIdx));
+  return FALSE;
 }
 
 static gboolean
 isCellSelectedCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
-  if (!accWrap)
-    return FALSE;
-
+  if (accWrap) {
     return static_cast<gboolean>(accWrap->AsTable()->
       IsCellSelected(aRowIdx, aColIdx));
+  } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
+    return static_cast<gboolean>(proxy->TableCellSelected(aRowIdx, aColIdx));
+  }
+
+  return FALSE;
 }
 }
 
 void
 tableInterfaceInitCB(AtkTableIface* aIface)
 {
   NS_ASSERTION(aIface, "no interface!");
   if (MOZ_UNLIKELY(!aIface))
--- a/accessible/ipc/DocAccessibleChild.cpp
+++ b/accessible/ipc/DocAccessibleChild.cpp
@@ -12,16 +12,19 @@
 #include "HyperTextAccessible-inl.h"
 #include "TextLeafAccessible.h"
 #include "ImageAccessible.h"
 #include "TableAccessible.h"
 #include "TableCellAccessible.h"
 #include "nsIPersistentProperties2.h"
 #include "nsISimpleEnumerator.h"
 #include "nsAccUtils.h"
+#ifdef MOZ_ACCESSIBILITY_ATK
+#include "AccessibleWrap.h"
+#endif
 
 namespace mozilla {
 namespace a11y {
 
 static uint32_t
 InterfacesFor(Accessible* aAcc)
 {
   uint32_t interfaces = 0;
@@ -1445,16 +1448,62 @@ DocAccessibleChild::RecvTableIsProbablyF
   if (acc) {
     *aForLayout = acc->IsProbablyLayoutTable();
   }
 
   return true;
 }
 
 bool
+DocAccessibleChild::RecvAtkTableColumnHeader(const uint64_t& aID,
+                                             const int32_t& aCol,
+                                             uint64_t* aHeader,
+                                             bool* aOk)
+{
+  *aHeader = 0;
+  *aOk = false;
+
+#ifdef MOZ_ACCESSIBILITY_ATK
+  TableAccessible* acc = IdToTableAccessible(aID);
+  if (acc) {
+    Accessible* header = AccessibleWrap::GetColumnHeader(acc, aCol);
+    if (header) {
+      *aHeader = reinterpret_cast<uint64_t>(header->UniqueID());
+      *aOk = true;
+    }
+  }
+#endif
+
+  return true;
+}
+
+bool
+DocAccessibleChild::RecvAtkTableRowHeader(const uint64_t& aID,
+                                          const int32_t& aRow,
+                                          uint64_t* aHeader,
+                                          bool* aOk)
+{
+  *aHeader = 0;
+  *aOk = false;
+
+#ifdef MOZ_ACCESSIBILITY_ATK
+  TableAccessible* acc = IdToTableAccessible(aID);
+  if (acc) {
+    Accessible* header = AccessibleWrap::GetRowHeader(acc, aRow);
+    if (header) {
+      *aHeader = reinterpret_cast<uint64_t>(header->UniqueID());
+      *aOk = true;
+    }
+  }
+#endif
+
+  return true;
+}
+
+bool
 DocAccessibleChild::RecvSelectedItems(const uint64_t& aID,
                                       nsTArray<uint64_t>* aSelectedItemIDs)
 {
   Accessible* acc = IdToAccessibleSelect(aID);
   if (acc) {
     nsAutoTArray<Accessible*, 10> selectedItems;
     acc->SelectedItems(&selectedItems);
     aSelectedItemIDs->SetCapacity(selectedItems.Length());
@@ -1651,16 +1700,29 @@ DocAccessibleChild::RecvKeyboardShortcut
     *aKey = kb.Key();
     *aModifierMask = kb.ModifierMask();
   }
 
   return true;
 }
 
 bool
+DocAccessibleChild::RecvAtkKeyBinding(const uint64_t& aID,
+                                      nsString* aResult)
+{
+#ifdef MOZ_ACCESSIBILITY_ATK
+  Accessible* acc = IdToAccessible(aID);
+  if (acc) {
+    AccessibleWrap::GetKeyBinding(acc, *aResult);
+  }
+#endif
+  return true;
+}
+
+bool
 DocAccessibleChild::RecvCurValue(const uint64_t& aID,
                                  double* aValue)
 {
   *aValue = UnspecifiedNaN<double>();
   Accessible* acc = IdToAccessible(aID);
   if (acc) {
     *aValue = acc->CurValue();
   }
--- a/accessible/ipc/DocAccessibleChild.h
+++ b/accessible/ipc/DocAccessibleChild.h
@@ -358,16 +358,24 @@ public:
   virtual bool RecvTableSelectRow(const uint64_t& aID,
                                   const uint32_t& aRow) override;
   virtual bool RecvTableUnselectColumn(const uint64_t& aID,
                                        const uint32_t& aCol) override;
   virtual bool RecvTableUnselectRow(const uint64_t& aID,
                                     const uint32_t& aRow) override;
   virtual bool RecvTableIsProbablyForLayout(const uint64_t& aID,
                                             bool* aForLayout) override;
+  virtual bool RecvAtkTableColumnHeader(const uint64_t& aID,
+                                        const int32_t& aCol,
+                                        uint64_t* aHeader,
+                                        bool* aOk) override;
+  virtual bool RecvAtkTableRowHeader(const uint64_t& aID,
+                                     const int32_t& aRow,
+                                     uint64_t* aHeader,
+                                     bool* aOk) override;
 
   virtual bool RecvSelectedItems(const uint64_t& aID,
                                  nsTArray<uint64_t>* aSelectedItemIDs) override;
 
   virtual bool RecvSelectedItemCount(const uint64_t& aID,
                                      uint32_t* aCount) override;
 
   virtual bool RecvGetSelectedItem(const uint64_t& aID,
@@ -411,16 +419,19 @@ public:
   virtual bool RecvAccessKey(const uint64_t& aID,
                              uint32_t* aKey,
                              uint32_t* aModifierMask) override;
 
   virtual bool RecvKeyboardShortcut(const uint64_t& aID,
                                     uint32_t* aKey,
                                     uint32_t* aModifierMask) override;
 
+  virtual bool RecvAtkKeyBinding(const uint64_t& aID,
+                                 nsString* aResult) override;
+
   virtual bool RecvCurValue(const uint64_t& aID,
                             double* aValue) override;
 
   virtual bool RecvSetCurValue(const uint64_t& aID,
                                const double& aValue,
                                bool* aRetVal) override;
 
   virtual bool RecvMinValue(const uint64_t& aID,
--- a/accessible/ipc/PDocAccessible.ipdl
+++ b/accessible/ipc/PDocAccessible.ipdl
@@ -197,32 +197,37 @@ child:
   prio(high) sync TableSelectedCellIndices(uint64_t aID) returns(uint32_t[] aCellIndeces);
   prio(high) sync TableSelectedColumnIndices(uint64_t aID) returns(uint32_t[] aColumnIndeces);
   prio(high) sync TableSelectedRowIndices(uint64_t aID) returns(uint32_t[] aRowIndeces);
   prio(high) sync TableSelectColumn(uint64_t aID, uint32_t aCol);
   prio(high) sync TableSelectRow(uint64_t aID, uint32_t aRow);
   prio(high) sync TableUnselectColumn(uint64_t aID, uint32_t aCol);
   prio(high) sync TableUnselectRow(uint64_t aID, uint32_t aRow);
   prio(high) sync TableIsProbablyForLayout(uint64_t aID) returns(bool aForLayout);
+  prio(high) sync AtkTableColumnHeader(uint64_t aID, int32_t aCol)
+    returns(uint64_t aHeaderID, bool aOk);
+  prio(high) sync AtkTableRowHeader(uint64_t aID, int32_t aRow)
+    returns(uint64_t aHeaderID, bool aOk);
 
   prio(high) sync SelectedItems(uint64_t aID) returns(uint64_t[] aSelectedItemIDs);
   prio(high) sync SelectedItemCount(uint64_t aID) returns(uint32_t aCount);
   prio(high) sync GetSelectedItem(uint64_t aID, uint32_t aIndex) returns(uint64_t aSelected, bool aOk);
   prio(high) sync IsItemSelected(uint64_t aID, uint32_t aIndex) returns(bool aSelected);
   prio(high) sync AddItemToSelection(uint64_t aID, uint32_t aIndex) returns(bool aSuccess);
   prio(high) sync RemoveItemFromSelection(uint64_t aID, uint32_t aIndex) returns(bool aSuccess);
   prio(high) sync SelectAll(uint64_t aID) returns(bool aSuccess);
   prio(high) sync UnselectAll(uint64_t aID) returns(bool aSuccess);
 
   prio(high) sync DoAction(uint64_t aID, uint8_t aIndex) returns(bool aSuccess);
   prio(high) sync ActionCount(uint64_t aID) returns(uint8_t aCount);
   prio(high) sync ActionDescriptionAt(uint64_t aID, uint8_t aIndex) returns(nsString aDescription);
   prio(high) sync ActionNameAt(uint64_t aID, uint8_t aIndex) returns(nsString aName);
   prio(high) sync AccessKey(uint64_t aID) returns(uint32_t aKey, uint32_t aModifierMask);
   prio(high) sync KeyboardShortcut(uint64_t aID) returns(uint32_t aKey, uint32_t aModifierMask);
+  prio(high) sync AtkKeyBinding(uint64_t aID) returns(nsString aResult);
 
   prio(high) sync CurValue(uint64_t aID) returns(double aValue);
   prio(high) sync SetCurValue(uint64_t aID, double aValue) returns(bool aRetVal);
   prio(high) sync MinValue(uint64_t aID) returns(double aValue);
   prio(high) sync MaxValue(uint64_t aID) returns(double aValue);
   prio(high) sync Step(uint64_t aID) returns(double aStep);
 
   async TakeFocus(uint64_t aID);
--- a/accessible/ipc/ProxyAccessible.cpp
+++ b/accessible/ipc/ProxyAccessible.cpp
@@ -815,16 +815,34 @@ ProxyAccessible::TableUnselectRow(uint32
 bool
 ProxyAccessible::TableIsProbablyForLayout()
 {
   bool forLayout = false;
   unused << mDoc->SendTableIsProbablyForLayout(mID, &forLayout);
   return forLayout;
 }
 
+ProxyAccessible*
+ProxyAccessible::AtkTableColumnHeader(int32_t aCol)
+{
+  uint64_t headerID = 0;
+  bool ok = false;
+  unused << mDoc->SendAtkTableColumnHeader(mID, aCol, &headerID, &ok);
+  return ok ? mDoc->GetAccessible(headerID) : nullptr;
+}
+
+ProxyAccessible*
+ProxyAccessible::AtkTableRowHeader(int32_t aRow)
+{
+  uint64_t headerID = 0;
+  bool ok = false;
+  unused << mDoc->SendAtkTableRowHeader(mID, aRow, &headerID, &ok);
+  return ok ? mDoc->GetAccessible(headerID) : nullptr;
+}
+
 void
 ProxyAccessible::SelectedItems(nsTArray<ProxyAccessible*>* aSelectedItems)
 {
   nsAutoTArray<uint64_t, 10> itemIDs;
   unused << mDoc->SendSelectedItems(mID, &itemIDs);
   aSelectedItems->SetCapacity(itemIDs.Length());
   for (size_t i = 0; i < itemIDs.Length(); ++i) {
     aSelectedItems->AppendElement(mDoc->GetAccessible(itemIDs[i]));
@@ -929,16 +947,22 @@ KeyBinding
 ProxyAccessible::KeyboardShortcut()
 {
   uint32_t key = 0;
   uint32_t modifierMask = 0;
   unused << mDoc->SendKeyboardShortcut(mID, &key, &modifierMask);
   return KeyBinding(key, modifierMask);
 }
 
+void
+ProxyAccessible::AtkKeyBinding(nsString& aBinding)
+{
+  unused << mDoc->SendAtkKeyBinding(mID, &aBinding);
+}
+
 double
 ProxyAccessible::CurValue()
 {
   double val = UnspecifiedNaN<double>();
   unused << mDoc->SendCurValue(mID, &val);
   return val;
 }
 
--- a/accessible/ipc/ProxyAccessible.h
+++ b/accessible/ipc/ProxyAccessible.h
@@ -292,32 +292,35 @@ public:
   void TableSelectedCellIndices(nsTArray<uint32_t>* aCellIndices);
   void TableSelectedColumnIndices(nsTArray<uint32_t>* aColumnIndices);
   void TableSelectedRowIndices(nsTArray<uint32_t>* aRowIndices);
   void TableSelectColumn(uint32_t aCol);
   void TableSelectRow(uint32_t aRow);
   void TableUnselectColumn(uint32_t aCol);
   void TableUnselectRow(uint32_t aRow);
   bool TableIsProbablyForLayout();
+  ProxyAccessible* AtkTableColumnHeader(int32_t aCol);
+  ProxyAccessible* AtkTableRowHeader(int32_t aRow);
 
   void SelectedItems(nsTArray<ProxyAccessible*>* aSelectedItems);
   uint32_t SelectedItemCount();
   ProxyAccessible* GetSelectedItem(uint32_t aIndex);
   bool IsItemSelected(uint32_t aIndex);
   bool AddItemToSelection(uint32_t aIndex);
   bool RemoveItemFromSelection(uint32_t aIndex);
   bool SelectAll();
   bool UnselectAll();
 
   bool DoAction(uint8_t aIndex);
   uint8_t ActionCount();
   void ActionDescriptionAt(uint8_t aIndex, nsString& aDescription);
   void ActionNameAt(uint8_t aIndex, nsString& aName);
   KeyBinding AccessKey();
   KeyBinding KeyboardShortcut();
+  void AtkKeyBinding(nsString& aBinding);
 
   double CurValue();
   bool SetCurValue(double aValue);
   double MinValue();
   double MaxValue();
   double Step();
 
   void TakeFocus();
--- a/accessible/tests/mochitest/jsat/dom_helper.js
+++ b/accessible/tests/mochitest/jsat/dom_helper.js
@@ -1,16 +1,16 @@
 'use strict';
 
 /* global getMainChromeWindow, AccessFuTest, GestureSettings, GestureTracker,
    SimpleTest, getBoundsForDOMElm, Point, Utils */
 /* exported loadJSON, eventMap */
 
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
 Cu.import('resource://gre/modules/accessibility/Utils.jsm');
 Cu.import('resource://gre/modules/Geometry.jsm');
 Cu.import("resource://gre/modules/accessibility/Gestures.jsm");
 
 var win = getMainChromeWindow(window);
 
 /**
--- a/accessible/tests/mochitest/jsat/output.js
+++ b/accessible/tests/mochitest/jsat/output.js
@@ -1,9 +1,9 @@
-const Cu = Components.utils;
+var Cu = Components.utils;
 const PREF_UTTERANCE_ORDER = "accessibility.accessfu.utterance";
 
 Cu.import('resource://gre/modules/accessibility/Utils.jsm');
 Cu.import("resource://gre/modules/accessibility/OutputGenerator.jsm", this);
 
 /**
  * Test context output generation.
  *
--- a/accessible/tests/mochitest/relations.js
+++ b/accessible/tests/mochitest/relations.js
@@ -1,31 +1,31 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Constants
 
-const RELATION_CONTROLLED_BY = nsIAccessibleRelation.RELATION_CONTROLLED_BY;
-const RELATION_CONTROLLER_FOR = nsIAccessibleRelation.RELATION_CONTROLLER_FOR;
-const RELATION_DEFAULT_BUTTON = nsIAccessibleRelation.RELATION_DEFAULT_BUTTON;
-const RELATION_DESCRIBED_BY = nsIAccessibleRelation.RELATION_DESCRIBED_BY;
-const RELATION_DESCRIPTION_FOR = nsIAccessibleRelation.RELATION_DESCRIPTION_FOR;
-const RELATION_EMBEDDED_BY = nsIAccessibleRelation.RELATION_EMBEDDED_BY;
-const RELATION_EMBEDS = nsIAccessibleRelation.RELATION_EMBEDS;
-const RELATION_FLOWS_FROM = nsIAccessibleRelation.RELATION_FLOWS_FROM;
-const RELATION_FLOWS_TO = nsIAccessibleRelation.RELATION_FLOWS_TO;
-const RELATION_LABEL_FOR = nsIAccessibleRelation.RELATION_LABEL_FOR;
-const RELATION_LABELLED_BY = nsIAccessibleRelation.RELATION_LABELLED_BY;
-const RELATION_MEMBER_OF = nsIAccessibleRelation.RELATION_MEMBER_OF;
-const RELATION_NODE_CHILD_OF = nsIAccessibleRelation.RELATION_NODE_CHILD_OF;
-const RELATION_NODE_PARENT_OF = nsIAccessibleRelation.RELATION_NODE_PARENT_OF;
-const RELATION_PARENT_WINDOW_OF = nsIAccessibleRelation.RELATION_PARENT_WINDOW_OF;
-const RELATION_POPUP_FOR = nsIAccessibleRelation.RELATION_POPUP_FOR;
-const RELATION_SUBWINDOW_OF = nsIAccessibleRelation.RELATION_SUBWINDOW_OF;
-const RELATION_CONTAINING_DOCUMENT = nsIAccessibleRelation.RELATION_CONTAINING_DOCUMENT;
-const RELATION_CONTAINING_TAB_PANE = nsIAccessibleRelation.RELATION_CONTAINING_TAB_PANE;
-const RELATION_CONTAINING_APPLICATION = nsIAccessibleRelation.RELATION_CONTAINING_APPLICATION;
+var RELATION_CONTROLLED_BY = nsIAccessibleRelation.RELATION_CONTROLLED_BY;
+var RELATION_CONTROLLER_FOR = nsIAccessibleRelation.RELATION_CONTROLLER_FOR;
+var RELATION_DEFAULT_BUTTON = nsIAccessibleRelation.RELATION_DEFAULT_BUTTON;
+var RELATION_DESCRIBED_BY = nsIAccessibleRelation.RELATION_DESCRIBED_BY;
+var RELATION_DESCRIPTION_FOR = nsIAccessibleRelation.RELATION_DESCRIPTION_FOR;
+var RELATION_EMBEDDED_BY = nsIAccessibleRelation.RELATION_EMBEDDED_BY;
+var RELATION_EMBEDS = nsIAccessibleRelation.RELATION_EMBEDS;
+var RELATION_FLOWS_FROM = nsIAccessibleRelation.RELATION_FLOWS_FROM;
+var RELATION_FLOWS_TO = nsIAccessibleRelation.RELATION_FLOWS_TO;
+var RELATION_LABEL_FOR = nsIAccessibleRelation.RELATION_LABEL_FOR;
+var RELATION_LABELLED_BY = nsIAccessibleRelation.RELATION_LABELLED_BY;
+var RELATION_MEMBER_OF = nsIAccessibleRelation.RELATION_MEMBER_OF;
+var RELATION_NODE_CHILD_OF = nsIAccessibleRelation.RELATION_NODE_CHILD_OF;
+var RELATION_NODE_PARENT_OF = nsIAccessibleRelation.RELATION_NODE_PARENT_OF;
+var RELATION_PARENT_WINDOW_OF = nsIAccessibleRelation.RELATION_PARENT_WINDOW_OF;
+var RELATION_POPUP_FOR = nsIAccessibleRelation.RELATION_POPUP_FOR;
+var RELATION_SUBWINDOW_OF = nsIAccessibleRelation.RELATION_SUBWINDOW_OF;
+var RELATION_CONTAINING_DOCUMENT = nsIAccessibleRelation.RELATION_CONTAINING_DOCUMENT;
+var RELATION_CONTAINING_TAB_PANE = nsIAccessibleRelation.RELATION_CONTAINING_TAB_PANE;
+var RELATION_CONTAINING_APPLICATION = nsIAccessibleRelation.RELATION_CONTAINING_APPLICATION;
 
 ////////////////////////////////////////////////////////////////////////////////
 // General
 
 /**
  * Test the accessible relation.
  *
  * @param aIdentifier          [in] identifier to get an accessible, may be ID
--- a/accessible/windows/ia2/ia2Accessible.cpp
+++ b/accessible/windows/ia2/ia2Accessible.cpp
@@ -13,16 +13,17 @@
 
 #include "Compatibility.h"
 #include "ia2AccessibleRelation.h"
 #include "IUnknownImpl.h"
 #include "nsCoreUtils.h"
 #include "nsIAccessibleTypes.h"
 #include "mozilla/a11y/PDocAccessible.h"
 #include "Relation.h"
+#include "nsAccessibilityService.h"
 
 #include "nsIPersistentProperties2.h"
 #include "nsISimpleEnumerator.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 template<typename String> static void EscapeAttributeChars(String& aStr);
@@ -646,17 +647,37 @@ ia2Accessible::get_accessibleWithCaret(I
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aAccessible || !aCaretOffset)
     return E_INVALIDARG;
 
   *aAccessible = nullptr;
   *aCaretOffset = -1;
-  return E_NOTIMPL;
+
+  AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
+  if (acc->IsDefunct())
+    return CO_E_OBJNOTCONNECTED;
+
+  int32_t caretOffset = -1;
+  Accessible* accWithCaret = SelectionMgr()->AccessibleWithCaret(&caretOffset);
+  if (acc->Document() != accWithCaret->Document())
+    return S_FALSE;
+
+  Accessible* child = accWithCaret;
+  while (child != acc)
+    child = child->Parent();
+
+  if (!child)
+    return S_FALSE;
+
+  *aAccessible =  static_cast<IAccessible2*>(
+    static_cast<AccessibleWrap*>(accWithCaret));
+  *aCaretOffset = caretOffset;
+  return S_OK;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::get_relationTargetsOfType(BSTR aType,
                                          long aMaxTargets,
                                          IUnknown*** aTargets,
--- a/addon-sdk/source/modules/system/Startup.js
+++ b/addon-sdk/source/modules/system/Startup.js
@@ -1,16 +1,16 @@
 /* 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/. */
 "use strict";
 
 var EXPORTED_SYMBOLS = ["Startup"];
 
-const { utils: Cu, interfaces: Ci, classes: Cc } = Components;
+var { utils: Cu, interfaces: Ci, classes: Cc } = Components;
 const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 const { defer } = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
 
 const { XulApp } = Cu.import("resource://gre/modules/commonjs/sdk/system/xul-app.jsm", {});
 
 const appStartupSrv = Cc["@mozilla.org/toolkit/app-startup;1"]
                        .getService(Ci.nsIAppStartup);
 
--- a/addon-sdk/source/python-lib/cuddlefish/mobile-utils/bootstrap.js
+++ b/addon-sdk/source/python-lib/cuddlefish/mobile-utils/bootstrap.js
@@ -1,14 +1,14 @@
 /* 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/. */
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 
 var { log } = console;
 
 function startup(data, reason) {
   // This code allow to make all stdIO work
   try {
--- a/addon-sdk/source/test/fixtures/addon/bootstrap.js
+++ b/addon-sdk/source/test/fixtures/addon/bootstrap.js
@@ -1,9 +1,9 @@
 /* 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/. */
 "use strict";
 
 const { utils: Cu } = Components;
 const {require} = Cu.import(`${ROOT}/toolkit/require.js`, {});
 const {Bootstrap} = require(`${ROOT}/sdk/addon/bootstrap.js`);
-const {startup, shutdown, install, uninstall} = new Bootstrap();
+var {startup, shutdown, install, uninstall} = new Bootstrap();
--- a/addon-sdk/source/test/test-content-script.js
+++ b/addon-sdk/source/test/test-content-script.js
@@ -722,17 +722,17 @@ exports["test requestAnimationFrame"] = 
     }
   );
 
 });
 
 exports["testGlobalScope"] = createProxyTest("", function (helper) {
 
   helper.createWorker(
-    'let toplevelScope = true;' +
+    'var toplevelScope = true;' +
     'assert(window.toplevelScope, "variables in toplevel scope are set to `window` object");' +
     'assert(this.toplevelScope, "variables in toplevel scope are set to `this` object");' +
     'done();'
   );
 
 });
 
 // Bug 715755: proxy code throw an exception on COW
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -3,20 +3,20 @@
 /* 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/. */
 
 "use strict";
 
 window.performance.mark('gecko-settings-loadstart');
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 
 // The load order is important here SettingsRequestManager _must_ be loaded
 // prior to using SettingsListener otherwise there is a race in acquiring the
 // lock and fulfilling it. If we ever move SettingsListener or this file down in
 // the load order of shell.html things will likely break.
 Cu.import('resource://gre/modules/SettingsRequestManager.jsm');
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.import('resource://gre/modules/Services.jsm');
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -1497,17 +1497,17 @@ const saveWindowGeometry = () => {
   window.removeEventListener("unload", saveWindowGeometry);
   Services.prefs.setIntPref("b2g.nativeWindowGeometry.screenX", screenX);
   Services.prefs.setIntPref("b2g.nativeWindowGeometry.screenY", screenY);
   Services.prefs.setIntPref("b2g.nativeWindowGeometry.width", outerWidth);
   Services.prefs.setIntPref("b2g.nativeWindowGeometry.height", outerHeight);
 }
 window.addEventListener("unload", saveWindowGeometry);
 
-let baseWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
+var baseWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
                        .getInterface(Ci.nsIWebNavigation)
                        .QueryInterface(Ci.nsIDocShellTreeItem)
                        .treeOwner
                        .QueryInterface(Ci.nsIInterfaceRequestor)
                        .getInterface(Ci.nsIBaseWindow);
 
 const showNativeWindow = () => baseWindow.visibility = true;
 const hideNativeWindow = () => baseWindow.visibility = false;
--- a/b2g/chrome/content/shell_remote.js
+++ b/b2g/chrome/content/shell_remote.js
@@ -1,25 +1,25 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- /
 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
 /* 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/. */
 
 "use strict";
 
-const {utils: Cu} = Components;
+var {utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 
 function debug(aStr) {
   // dump(" -*- ShellRemote.js: " + aStr + "\n");
 }
 
-let remoteShell = {
+var remoteShell = {
 
   get homeURL() {
     let systemAppManifestURL = Services.io.newURI(this.systemAppManifestURL, null, null);
     let shellRemoteURL = Services.prefs.getCharPref("b2g.multiscreen.system_remote_url");
     shellRemoteURL = Services.io.newURI(shellRemoteURL, null, systemAppManifestURL);
     return shellRemoteURL.spec;
   },
 
--- a/b2g/chrome/content/test/mochitest/RecordingStatusChromeScript.js
+++ b/b2g/chrome/content/test/mochitest/RecordingStatusChromeScript.js
@@ -1,12 +1,12 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
 const { Services } = Cu.import('resource://gre/modules/Services.jsm');
 const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm');
 
 var processId;
 
 function peekChildId(aSubject, aTopic, aData) {
   Services.obs.removeObserver(peekChildId, 'recording-device-events');
   Services.obs.removeObserver(peekChildId, 'recording-device-ipc-events');
--- a/b2g/components/MultiscreenHandler.jsm
+++ b/b2g/components/MultiscreenHandler.jsm
@@ -10,21 +10,21 @@ const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 
 function debug(aStr) {
   // dump("MultiscreenHandler: " + aStr + "\n");
 }
 
-let window = Services.wm.getMostRecentWindow("navigator:browser");
+var window = Services.wm.getMostRecentWindow("navigator:browser");
 
 // Multi-screen support on b2g. The following implementation will open a new
 // top-level window once we receive a display connected event.
-let MultiscreenHandler = {
+var MultiscreenHandler = {
 
   topLevelWindows: new Map(),
 
   init: function init() {
     Services.obs.addObserver(this, "display-changed", false);
     Services.obs.addObserver(this, "xpcom-shutdown", false);
   },
 
--- a/b2g/components/test/mochitest/filepicker_path_handler_chrome.js
+++ b/b2g/components/test/mochitest/filepicker_path_handler_chrome.js
@@ -1,16 +1,16 @@
 /* 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/. */
 
 'use strict';
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
 // use ppmm to handle file-picker message.
 var ppmm = Cc['@mozilla.org/parentprocessmessagemanager;1']
              .getService(Ci.nsIMessageListenerManager);
 
 var pickResult = null;
 
 function processPickMessage(message) {
--- a/b2g/components/test/mochitest/permission_handler_chrome.js
+++ b/b2g/components/test/mochitest/permission_handler_chrome.js
@@ -3,19 +3,19 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 function debug(str) {
   dump("CHROME PERMISSON HANDLER -- " + str + "\n");
 }
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
 const { Services } = Cu.import("resource://gre/modules/Services.jsm");
 const { SystemAppProxy } = Cu.import("resource://gre/modules/SystemAppProxy.jsm");
 
 var eventHandler = function(evt) {
   if (!evt.detail || evt.detail.type !== "permission-prompt") {
     return;
   }
--- a/b2g/components/test/mochitest/presentation_prompt_handler_chrome.js
+++ b/b2g/components/test/mochitest/presentation_prompt_handler_chrome.js
@@ -3,17 +3,17 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 'use strict';
 
  function debug(str) {
    dump('presentation_prompt_handler_chrome: ' + str + '\n');
  }
 
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 const { XPCOMUtils } = Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm');
 
 const manager = Cc["@mozilla.org/presentation-device/manager;1"]
                   .getService(Ci.nsIPresentationDeviceManager);
 
 const prompt = Cc['@mozilla.org/presentation-device/prompt;1']
                  .getService(Ci.nsIPresentationDevicePrompt);
--- a/b2g/components/test/mochitest/presentation_ui_glue_handler_chrome.js
+++ b/b2g/components/test/mochitest/presentation_ui_glue_handler_chrome.js
@@ -1,15 +1,15 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 'use strict';
 
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 const { XPCOMUtils } = Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm');
 
 const glue = Cc["@mozilla.org/presentation/requestuiglue;1"]
              .createInstance(Ci.nsIPresentationRequestUIGlue);
 
 SystemAppProxy.addEventListener('mozPresentationChromeEvent', function(aEvent) {
   if (!aEvent.detail || aEvent.detail.type !== 'presentation-launch-receiver') {
--- a/b2g/components/test/mochitest/screenshot_helper.js
+++ b/b2g/components/test/mochitest/screenshot_helper.js
@@ -1,10 +1,10 @@
-const Cu = Components.utils;
-const Ci = Components.interfaces;
+var Cu = Components.utils;
+var Ci = Components.interfaces;
 
 Cu.importGlobalProperties(['File']);
 
 const { Services } = Cu.import("resource://gre/modules/Services.jsm");
 
 // Load a duplicated copy of the jsm to prevent messing with the currently running one
 var scope = {};
 Services.scriptloader.loadSubScript("resource://gre/modules/Screenshot.jsm", scope);
--- a/b2g/components/test/mochitest/systemapp_helper.js
+++ b/b2g/components/test/mochitest/systemapp_helper.js
@@ -1,9 +1,9 @@
-const Cu = Components.utils;
+var Cu = Components.utils;
 
 const { Services } = Cu.import("resource://gre/modules/Services.jsm");
 
 // Load a duplicated copy of the jsm to prevent messing with the currently running one
 var scope = {};
 Services.scriptloader.loadSubScript("resource://gre/modules/SystemAppProxy.jsm", scope);
 const { SystemAppProxy } = scope;
 
--- a/b2g/components/test/unit/file_killswitch.js
+++ b/b2g/components/test/unit/file_killswitch.js
@@ -1,15 +1,15 @@
 /* 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/. */
 
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/NetUtil.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
 
 var kUserValues;
--- a/b2g/components/test/unit/head_identity.js
+++ b/b2g/components/test/unit/head_identity.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
 // The following boilerplate makes sure that XPCOM calls
 // that use the profile directory work.
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "MinimalIDService",
--- a/b2g/components/test/unit/head_logshake_gonk.js
+++ b/b2g/components/test/unit/head_logshake_gonk.js
@@ -9,19 +9,19 @@
    do_get_profile, OS, volumeService, equal, XPCOMUtils */
 /* exported setup_logshake_mocks */
 
 /* disable use strict warning */
 /* jshint -W097 */
 
 "use strict";
 
-const Cu = Components.utils;
-const Ci = Components.interfaces;
-const Cc = Components.classes;
+var Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cc = Components.classes;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/osfile.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "volumeService",
                                    "@mozilla.org/telephony/volume-service;1",
                                    "nsIVolumeService");
 
--- a/b2g/components/test/unit/test_aboutserviceworkers.js
+++ b/b2g/components/test/unit/test_aboutserviceworkers.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const {utils: Cu} = Components;
+var {utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "AboutServiceWorkers",
   "resource://gre/modules/AboutServiceWorkers.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gServiceWorkerManager",
--- a/b2g/components/test/unit/test_fxaccounts.js
+++ b/b2g/components/test/unit/test_fxaccounts.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const {utils: Cu} = Components;
+var {utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://services-common/utils.js");
 Cu.import("resource://testing-common/httpd.js");
 
 XPCOMUtils.defineLazyModuleGetter(this, "FxAccountsMgmtService",
   "resource://gre/modules/FxAccountsMgmtService.jsm",
--- a/b2g/components/test/unit/test_killswitch.js
+++ b/b2g/components/test/unit/test_killswitch.js
@@ -1,15 +1,15 @@
 /* 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/. */
 
 "use strict";
 
-const {results: Cr} = Components;
+var {results: Cr} = Components;
 
 // Trivial test just to make sure we have no syntax error
 add_test(function test_ksm_ok() {
   ok(KillSwitchMain, "KillSwitchMain object exists");
 
   run_next_test();
 });
 
--- a/b2g/components/test/unit/test_logparser.js
+++ b/b2g/components/test/unit/test_logparser.js
@@ -1,11 +1,11 @@
 /* jshint moz: true */
 
-const {utils: Cu, classes: Cc, interfaces: Ci} = Components;
+var {utils: Cu, classes: Cc, interfaces: Ci} = Components;
 
 function debug(msg) {
   var timestamp = Date.now();
   dump("LogParser: " + timestamp + ": " + msg + "\n");
 }
 
 function run_test() {
   Cu.import("resource:///modules/LogParser.jsm");
--- a/b2g/components/test/unit/test_logshake.js
+++ b/b2g/components/test/unit/test_logshake.js
@@ -5,17 +5,17 @@
 /* jshint moz: true */
 /* global Components, LogCapture, LogShake, ok, add_test, run_next_test, dump */
 /* exported run_test */
 
 /* disable use strict warning */
 /* jshint -W097 */
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 
 Cu.import("resource://gre/modules/LogCapture.jsm");
 Cu.import("resource://gre/modules/LogShake.jsm");
 
 const EVENTS_PER_SECOND = 6.25;
 const GRAVITY = 9.8;
 
 /**
--- a/b2g/simulator/bootstrap.js
+++ b/b2g/simulator/bootstrap.js
@@ -1,10 +1,10 @@
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 
 // Useful piece of code from :bent
 // http://mxr.mozilla.org/mozilla-central/source/dom/workers/test/extensions/bootstrap/bootstrap.js
 function registerAddonResourceHandler(data) {
   let file = data.installPath;
   let fileuri = file.isDirectory() ?
--- a/browser/base/content/aboutaccounts/aboutaccounts.js
+++ b/browser/base/content/aboutaccounts/aboutaccounts.js
@@ -1,15 +1,15 @@
 /* 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/. */
 
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/FxAccounts.jsm");
 
 var fxAccountsCommon = {};
 Cu.import("resource://gre/modules/FxAccountsCommon.js", fxAccountsCommon);
 
 // for master-password utilities
--- a/browser/base/content/abouthealthreport/abouthealth.js
+++ b/browser/base/content/abouthealthreport/abouthealth.js
@@ -1,15 +1,15 @@
 /* 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/. */
 
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 const prefs = new Preferences("datareporting.healthreport.");
 
 const PREF_UNIFIED = "toolkit.telemetry.unified";
 const PREF_UNIFIED_OPTIN = "toolkit.telemetry.unifiedIsOptIn";
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3717,16 +3717,18 @@ const BrowserSearch = {
   },
 
   recordOneoffSearchInTelemetry: function (engine, source, type, where) {
     let id = this._getSearchEngineId(engine) + "." + source;
     BrowserUITelemetry.countOneoffSearchEvent(id, type, where);
   }
 };
 
+XPCOMUtils.defineConstant(this, "BrowserSearch", BrowserSearch);
+
 function FillHistoryMenu(aParent) {
   // Lazily add the hover listeners on first showing and never remove them
   if (!aParent.hasStatusListener) {
     // Show history item's uri in the status bar when hovering, and clear on exit
     aParent.addEventListener("DOMMenuItemActive", function(aEvent) {
       // Only the current page should have the checked attribute, so skip it
       if (!aEvent.target.hasAttribute("checked"))
         XULBrowserWindow.setOverLink(aEvent.target.getAttribute("uri"));
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import("resource://gre/modules/LoadContextInfo.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 //******** define a js object to implement nsITreeView
 function pageInfoTreeView(treeid, copycol)
 {
   // copycol is the index number for the column that we want to add to
   // the copy-n-paste buffer when the user hits accel-c
--- a/browser/base/content/sanitizeDialog.js
+++ b/browser/base/content/sanitizeDialog.js
@@ -1,18 +1,18 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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/. */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
-let {Sanitizer} = Cu.import("resource:///modules/Sanitizer.jsm", {});
+var {Sanitizer} = Cu.import("resource:///modules/Sanitizer.jsm", {});
 
 var gSanitizePromptDialog = {
 
   get bundleBrowser()
   {
     if (!this._bundleBrowser)
       this._bundleBrowser = document.getElementById("bundleBrowser");
     return this._bundleBrowser;
--- a/browser/base/content/social-content.js
+++ b/browser/base/content/social-content.js
@@ -1,17 +1,17 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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/. */
 
 /* This content script should work in any browser or iframe and should not
  * depend on the frame being contained in tabbrowser. */
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 // social frames are always treated as app tabs
 docShell.isAppTab = true;
 
 // Error handling class used to listen for network errors in the social frames
--- a/browser/base/content/sync/aboutSyncTabs.js
+++ b/browser/base/content/sync/aboutSyncTabs.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 
 Cu.import("resource://services-common/utils.js");
 Cu.import("resource://services-sync/main.js");
 Cu.import("resource:///modules/PlacesUIUtils.jsm");
 Cu.import("resource://gre/modules/PlacesUtils.jsm", this);
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
--- a/browser/base/content/sync/addDevice.js
+++ b/browser/base/content/sync/addDevice.js
@@ -1,15 +1,15 @@
 /* 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/. */
 
-const Ci = Components.interfaces;
-const Cc = Components.classes;
-const Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cu = Components.utils;
 
 Cu.import("resource://services-sync/main.js");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const PIN_PART_LENGTH = 4;
 
 const ADD_DEVICE_PAGE       = 0;
 const SYNC_KEY_PAGE         = 1;
--- a/browser/base/content/sync/genericChange.js
+++ b/browser/base/content/sync/genericChange.js
@@ -1,14 +1,14 @@
 /* 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/. */
 
-const Ci = Components.interfaces;
-const Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cc = Components.classes;
 
 Components.utils.import("resource://services-sync/main.js");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 var Change = {
   _dialog: null,
   _dialogType: null,
   _status: null,
--- a/browser/base/content/sync/setup.js
+++ b/browser/base/content/sync/setup.js
@@ -1,17 +1,17 @@
 // -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
 /* 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/. */
 
-const Ci = Components.interfaces;
-const Cc = Components.classes;
-const Cr = Components.results;
-const Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cr = Components.results;
+var Cu = Components.utils;
 
 // page consts
 
 const PAIR_PAGE                     = 0;
 const INTRO_PAGE                    = 1;
 const NEW_ACCOUNT_START_PAGE        = 2;
 const EXISTING_ACCOUNT_CONNECT_PAGE = 3;
 const EXISTING_ACCOUNT_LOGIN_PAGE   = 4;
--- a/browser/base/content/test/general/browser_aboutTabCrashed.js
+++ b/browser/base/content/test/general/browser_aboutTabCrashed.js
@@ -1,11 +1,11 @@
 "use strict";
 
-let { TabCrashReporter } =
+var { TabCrashReporter } =
   Cu.import("resource:///modules/ContentCrashReporters.jsm");
 
 const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs";
 const PAGE = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
 const COMMENTS = "Here's my test comment!";
 const EMAIL = "foo@privacy.com";
 
 /**
--- a/browser/base/content/test/general/browser_alltabslistener.js
+++ b/browser/base/content/test/general/browser_alltabslistener.js
@@ -1,9 +1,9 @@
-const Ci = Components.interfaces;
+var Ci = Components.interfaces;
 
 const gCompleteState = Ci.nsIWebProgressListener.STATE_STOP +
                        Ci.nsIWebProgressListener.STATE_IS_NETWORK;
 
 var gFrontProgressListener = {
   onProgressChange: function (aWebProgress, aRequest,
                               aCurSelfProgress, aMaxSelfProgress,
                               aCurTotalProgress, aMaxTotalProgress) {
--- a/browser/base/content/test/general/browser_bug356571.js
+++ b/browser/base/content/test/general/browser_bug356571.js
@@ -1,12 +1,12 @@
 // Bug 356571 - loadOneOrMoreURIs gives up if one of the URLs has an unknown protocol
 
-const Cr = Components.results;
-const Cm = Components.manager;
+var Cr = Components.results;
+var Cm = Components.manager;
 
 // Set to true when docShell alerts for unknown protocol error
 var didFail = false;
 
 // Override Alert to avoid blocking the test due to unknown protocol error
 const kPromptServiceUUID = "{6cc9c9fe-bc0b-432b-a410-253ef8bcc699}";
 const kPromptServiceContractID = "@mozilla.org/embedcomp/prompt-service;1";
 
--- a/browser/base/content/test/general/browser_bug567306.js
+++ b/browser/base/content/test/general/browser_bug567306.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-const {Ci: interfaces, Cc: classes} = Components;
+var {Ci: interfaces, Cc: classes} = Components;
 
 var Clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
 var HasFindClipboard = Clipboard.supportsFindClipboard();
 
 add_task(function* () {
   let newwindow = yield BrowserTestUtils.openNewBrowserWindow();
 
   let selectedBrowser = newwindow.gBrowser.selectedBrowser;
--- a/browser/base/content/test/general/browser_minimize.js
+++ b/browser/base/content/test/general/browser_minimize.js
@@ -1,37 +1,18 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
-function waitForActive() {
-    if (!gBrowser.docShell.isActive) {
-        executeSoon(waitForActive);
-        return;
-    }
-    is(gBrowser.docShell.isActive, true, "Docshell should be active again");
-    finish();
-}
 
-function waitForInactive() {
-    if (gBrowser.docShell.isActive) {
-        executeSoon(waitForInactive);
-        return;
-    }
-    is(gBrowser.docShell.isActive, false, "Docshell should be inactive");
-    window.restore();
-    waitForActive();
-}
-
-function test() {
+add_task(function *() {
     registerCleanupFunction(function() {
       window.restore();
     });
-
-    waitForExplicitFinish();
-    is(gBrowser.docShell.isActive, true, "Docshell should be active");
+    function waitForActive() { return gBrowser.selectedTab.linkedBrowser.docShellIsActive; }
+    function waitForInactive() { return !gBrowser.selectedTab.linkedBrowser.docShellIsActive; }
+    yield promiseWaitForCondition(waitForActive);
+    is(gBrowser.selectedTab.linkedBrowser.docShellIsActive, true, "Docshell should be active");
     window.minimize();
-    // XXX On Linux minimize/restore seem to be very very async, but
-    // our window.windowState changes sync.... so we can't rely on the
-    // latter correctly reflecting the state of the former.  In
-    // particular, a restore() call before minimizing is done will not
-    // actually restore the window, but change the window state.  As a
-    // result, just poll waiting for our expected isActive values.
-    waitForInactive();
-}
+    yield promiseWaitForCondition(waitForInactive);
+    is(gBrowser.selectedTab.linkedBrowser.docShellIsActive, false, "Docshell should be Inactive");
+    window.restore();
+    yield promiseWaitForCondition(waitForActive);
+    is(gBrowser.selectedTab.linkedBrowser.docShellIsActive, true, "Docshell should be active again");
+});
\ No newline at end of file
--- a/browser/base/content/test/general/browser_mixedContentFramesOnHttp.js
+++ b/browser/base/content/test/general/browser_mixedContentFramesOnHttp.js
@@ -5,49 +5,30 @@
  * Test for Bug 1182551 -
  *
  * This test has a top level HTTP page with an HTTPS iframe.  The HTTPS iframe
  * includes an HTTP image.  We check that the top level security state is
  * STATE_IS_INSECURE.  The mixed content from the iframe shouldn't "upgrade"
  * the HTTP top level page to broken HTTPS.
  */
 
-const gHttpTestRoot = "http://example.com/browser/browser/base/content/test/general/";
+const gHttpTestUrl = "http://example.com/browser/browser/base/content/test/general/file_mixedContentFramesOnHttp.html";
 
 var gTestBrowser = null;
 
-function SecStateTestsCompleted() {
-  gBrowser.removeCurrentTab();
-  window.focus();
-  finish();
-}
-
-function test() {
-  waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [
-    ["security.mixed_content.block_active_content", true],
-    ["security.mixed_content.block_display_content", false]
-  ]}, SecStateTests);
-}
+add_task(function *() {
+  yield new Promise(resolve => {
+    SpecialPowers.pushPrefEnv({
+      "set": [
+        ["security.mixed_content.block_active_content", true],
+        ["security.mixed_content.block_display_content", false]
+      ]
+    }, resolve);
+  });
+  let url = gHttpTestUrl
+  yield BrowserTestUtils.withNewTab({gBrowser, url}, function*(){
+    gTestBrowser = gBrowser.selectedBrowser;
+    // check security state is insecure
+    isSecurityState("insecure");
+    assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: true});
+  });
+});
 
-function SecStateTests() {
-  let url = gHttpTestRoot + "file_mixedContentFramesOnHttp.html";
-  gBrowser.selectedTab = gBrowser.addTab();
-  gTestBrowser = gBrowser.selectedBrowser;
-  whenLoaded(gTestBrowser, SecStateTest1);
-  gTestBrowser.contentWindow.location = url;
-}
-
-// The http page loads an https frame with an http image.
-function SecStateTest1() {
-  // check security state is insecure
-  isSecurityState("insecure");
-  assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: true});
-
-  SecStateTestsCompleted();
-}
-
-function whenLoaded(aElement, aCallback) {
-  aElement.addEventListener("load", function onLoad() {
-    aElement.removeEventListener("load", onLoad, true);
-    executeSoon(aCallback);
-  }, true);
-}
--- a/browser/base/content/test/general/browser_mixedContentFromOnunload.js
+++ b/browser/base/content/test/general/browser_mixedContentFromOnunload.js
@@ -9,72 +9,41 @@
 
 // We use different domains for each test and for navigation within each test
 const gHttpTestRoot1 = "http://example.com/browser/browser/base/content/test/general/";
 const gHttpsTestRoot1 = "https://test1.example.com/browser/browser/base/content/test/general/";
 const gHttpTestRoot2 = "http://example.net/browser/browser/base/content/test/general/";
 const gHttpsTestRoot2 = "https://test2.example.com/browser/browser/base/content/test/general/";
 
 var gTestBrowser = null;
-
-function SecStateTestsCompleted() {
-  gBrowser.removeCurrentTab();
-  window.focus();
-  finish();
-}
-
-function test() {
-  waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [["security.mixed_content.block_active_content", true],
-                            ["security.mixed_content.block_display_content", false]]}, SecStateTests);
-}
-
-function SecStateTests() {
-  gBrowser.selectedTab = gBrowser.addTab();
+add_task(function *() {
+  let url = gHttpTestRoot1 + "file_mixedContentFromOnunload.html";
+  yield BrowserTestUtils.withNewTab({gBrowser, url}, function*(){
+    yield new Promise(resolve => {
+      SpecialPowers.pushPrefEnv({
+        "set": [
+          ["security.mixed_content.block_active_content", true],
+          ["security.mixed_content.block_display_content", false]
+        ]
+      }, resolve);
+    });
   gTestBrowser = gBrowser.selectedBrowser;
-
-  whenLoaded(gTestBrowser, SecStateTest1A);
-  let url = gHttpTestRoot1 + "file_mixedContentFromOnunload.html";
-  gTestBrowser.contentWindow.location = url;
-}
-
-// Navigation from an http page to a https page with no mixed content
-// The http page loads an http image on unload
-function SecStateTest1A() {
-  whenLoaded(gTestBrowser, SecStateTest1B);
-  let url = gHttpsTestRoot1 + "file_mixedContentFromOnunload_test1.html";
-  gTestBrowser.contentWindow.location = url;
-}
-
-function SecStateTest1B() {
+  // Navigation from an http page to a https page with no mixed content
+  // The http page loads an http image on unload
+  url = gHttpsTestRoot1 + "file_mixedContentFromOnunload_test1.html";
+  yield BrowserTestUtils.loadURI(gTestBrowser, url);
+  yield BrowserTestUtils.browserLoaded(gTestBrowser);
   // check security state.  Since current url is https and doesn't have any
   // mixed content resources, we expect it to be secure.
   isSecurityState("secure");
   assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: false});
-
-  whenLoaded(gTestBrowser, SecStateTest2A);
-
-  // change locations and proceed with the second test
-  let url = gHttpTestRoot2 + "file_mixedContentFromOnunload.html";
-  gTestBrowser.contentWindow.location = url;
-}
-
-// Navigation from an http page to a https page that has mixed display content
-// The https page loads an http image on unload
-function SecStateTest2A() {
-  whenLoaded(gTestBrowser, SecStateTest2B);
-  let url = gHttpsTestRoot2 + "file_mixedContentFromOnunload_test2.html";
-  gTestBrowser.contentWindow.location = url;
-}
-
-function SecStateTest2B() {
+  // Navigation from an http page to a https page that has mixed display content
+  // The https page loads an http image on unload
+  url = gHttpTestRoot2 + "file_mixedContentFromOnunload.html";
+  yield BrowserTestUtils.loadURI(gTestBrowser, url);
+  yield BrowserTestUtils.browserLoaded(gTestBrowser);
+  url = gHttpsTestRoot2 + "file_mixedContentFromOnunload_test2.html";
+  yield BrowserTestUtils.loadURI(gTestBrowser, url);
+  yield BrowserTestUtils.browserLoaded(gTestBrowser);
   isSecurityState("broken");
   assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: true});
-
-  SecStateTestsCompleted();
-}
-
-function whenLoaded(aElement, aCallback) {
-  aElement.addEventListener("load", function onLoad() {
-    aElement.removeEventListener("load", onLoad, true);
-    executeSoon(aCallback);
-  }, true);
-}
+  });
+});
--- a/browser/base/content/test/general/browser_overflowScroll.js
+++ b/browser/base/content/test/general/browser_overflowScroll.js
@@ -1,23 +1,23 @@
 var tabstrip = gBrowser.tabContainer.mTabstrip;
 var scrollbox = tabstrip._scrollbox;
 var originalSmoothScroll = tabstrip.smoothScroll;
 var tabs = gBrowser.tabs;
 
-let rect = ele => ele.getBoundingClientRect();
-let width = ele => rect(ele).width;
-let left = ele => rect(ele).left;
-let right = ele => rect(ele).right;
-let isLeft = (ele, msg) => is(left(ele) + tabstrip._tabMarginLeft, left(scrollbox), msg);
-let isRight = (ele, msg) => is(right(ele) - tabstrip._tabMarginRight, right(scrollbox), msg);
-let elementFromPoint = x => tabstrip._elementFromPoint(x);
-let nextLeftElement = () => elementFromPoint(left(scrollbox) - 1);
-let nextRightElement = () => elementFromPoint(right(scrollbox) + 1);
-let firstScrollable = () => tabs[gBrowser._numPinnedTabs];
+var rect = ele => ele.getBoundingClientRect();
+var width = ele => rect(ele).width;
+var left = ele => rect(ele).left;
+var right = ele => rect(ele).right;
+var isLeft = (ele, msg) => is(left(ele) + tabstrip._tabMarginLeft, left(scrollbox), msg);
+var isRight = (ele, msg) => is(right(ele) - tabstrip._tabMarginRight, right(scrollbox), msg);
+var elementFromPoint = x => tabstrip._elementFromPoint(x);
+var nextLeftElement = () => elementFromPoint(left(scrollbox) - 1);
+var nextRightElement = () => elementFromPoint(right(scrollbox) + 1);
+var firstScrollable = () => tabs[gBrowser._numPinnedTabs];
 
 function test() {
   requestLongerTimeout(2);
   waitForExplicitFinish();
 
   // If the previous (or more) test finished with cleaning up the tabs,
   // there may be some pending animations. That can cause a failure of
   // this tests, so, we should test this in another stack.
--- a/browser/base/content/test/general/browser_permissions.js
+++ b/browser/base/content/test/general/browser_permissions.js
@@ -1,13 +1,13 @@
 /*
  * Test the Permissions section in the Control Center.
  */
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const PERMISSIONS_PAGE = "http://example.com/browser/browser/base/content/test/general/permissions.html";
 var {SitePermissions} = Cu.import("resource:///modules/SitePermissions.jsm", {});
 
 registerCleanupFunction(function() {
   SitePermissions.remove(gBrowser.currentURI, "install");
   while (gBrowser.tabs.length > 1) {
     gBrowser.removeCurrentTab();
   }
--- a/browser/base/content/test/general/browser_sanitizeDialog.js
+++ b/browser/base/content/test/general/browser_sanitizeDialog.js
@@ -13,31 +13,31 @@
  * 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/general/browser_sanitize-timespans.js.
  */
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-let {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", {});
+var {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", {});
 
 XPCOMUtils.defineLazyModuleGetter(this, "FormHistory",
                                   "resource://gre/modules/FormHistory.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
                                   "resource://gre/modules/Downloads.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Timer",
                                   "resource://gre/modules/Timer.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
                                   "resource://testing-common/PlacesTestUtils.jsm");
 
-let tempScope = {};
+var tempScope = {};
 Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
                                            .loadSubScript("chrome://browser/content/sanitize.js", tempScope);
-let Sanitizer = tempScope.Sanitizer;
+var Sanitizer = tempScope.Sanitizer;
 
 const kMsecPerMin = 60 * 1000;
 const kUsecPerMin = 60 * 1000000;
 
 add_task(function* init() {
   requestLongerTimeout(2);
   blankSlate();
   registerCleanupFunction(() => {
@@ -670,18 +670,18 @@ add_task(function* test_offline_apps_per
     var pm = Cc["@mozilla.org/permissionmanager;1"]
              .getService(Ci.nsIPermissionManager);
     is(pm.testPermissionFromPrincipal(principal, "offline-app"), 0, "offline-app permissions removed");
   };
   wh.open();
   return wh.promiseClosed;
 });
 
-let now_mSec = Date.now();
-let now_uSec = now_mSec * 1000;
+var now_mSec = Date.now();
+var now_uSec = now_mSec * 1000;
 
 ///////////////////////////////////////////////////////////////////////////////
 
 /**
  * This wraps the dialog and provides some convenience methods for interacting
  * with it.
  *
  * @param aWin
--- a/browser/base/content/test/general/browser_trackingUI_1.js
+++ b/browser/base/content/test/general/browser_trackingUI_1.js
@@ -2,17 +2,17 @@
  * Test that the Tracking Protection section is visible in the Control Center
  * and has the correct state for the cases when:
  *   1) A page with no tracking elements is loaded.
  *   2) A page with tracking elements is loaded and they are blocked.
  *   3) A page with tracking elements is loaded and they are not blocked.
  * See also Bugs 1175327, 1043801, 1178985
  */
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const PREF = "privacy.trackingprotection.enabled";
 const PB_PREF = "privacy.trackingprotection.pbmode.enabled";
 const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
 var TrackingProtection = null;
 var tabbrowser = null;
 
 var {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
--- a/browser/base/content/test/general/browser_trackingUI_2.js
+++ b/browser/base/content/test/general/browser_trackingUI_2.js
@@ -1,15 +1,15 @@
 /*
  * Test that the Tracking Protection section is never visible in the
  * Control Center when the feature is off.
  * See also Bugs 1175327, 1043801, 1178985.
  */
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const PREF = "privacy.trackingprotection.enabled";
 const PB_PREF = "privacy.trackingprotection.pbmode.enabled";
 const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
 var TrackingProtection = null;
 var tabbrowser = null;
 
 var {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
--- a/browser/base/content/test/general/browser_trackingUI_4.js
+++ b/browser/base/content/test/general/browser_trackingUI_4.js
@@ -1,15 +1,15 @@
 /*
  * Test that the Tracking Protection icon is properly animated in the identity
  * block when loading tabs and switching between tabs.
  * See also Bug 1175858.
  */
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const PREF = "privacy.trackingprotection.enabled";
 const PB_PREF = "privacy.trackingprotection.pbmode.enabled";
 const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
 var TrackingProtection = null;
 var tabbrowser = null;
 
 var {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
--- a/browser/base/content/test/general/browser_trackingUI_telemetry.js
+++ b/browser/base/content/test/general/browser_trackingUI_telemetry.js
@@ -1,13 +1,13 @@
 /*
  * Test telemetry for Tracking Protection
  */
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const PREF = "privacy.trackingprotection.enabled";
 const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
 const {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
 
 /**
  * Enable local telemetry recording for the duration of the tests.
  */
--- a/browser/base/content/test/general/content_aboutAccounts.js
+++ b/browser/base/content/test/general/content_aboutAccounts.js
@@ -1,16 +1,16 @@
 /* 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/. */
 
 // This file is loaded as a "content script" for browser_aboutAccounts tests
 "use strict";
 
-const {interfaces: Ci, utils: Cu} = Components;
+var {interfaces: Ci, utils: Cu} = Components;
 
 addEventListener("load", function load(event) {
   if (event.target != content.document) {
     return;
   }
 //  content.document.removeEventListener("load", load, true);
   sendAsyncMessage("test:document:load");
   // Opening Sync prefs in tests is a pain as leaks are reported due to the
--- a/browser/base/content/test/general/healthreport_pingData.js
+++ b/browser/base/content/test/general/healthreport_pingData.js
@@ -1,9 +1,9 @@
-const TEST_PINGS = [
+var TEST_PINGS = [
   {
     type: "test-telemetryArchive-1",
     payload: { foo: "bar" },
     date: new Date(2010, 1, 1, 10, 0, 0),
   },
   {
     type: "test-telemetryArchive-2",
     payload: { x: { y: "z"} },
--- a/browser/base/content/test/plugins/blocklist_proxy.js
+++ b/browser/base/content/test/plugins/blocklist_proxy.js
@@ -1,12 +1,12 @@
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cm = Components.manager;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cm = Components.manager;
 
 const kBlocklistServiceUUID = "{66354bc9-7ed1-4692-ae1d-8da97d6b205e}";
 const kBlocklistServiceContractID = "@mozilla.org/extensions/blocklist;1";
 const kBlocklistServiceFactory = Cm.getClassObject(Cc[kBlocklistServiceContractID], Ci.nsIFactory);
 
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 
 /*
--- a/browser/base/content/test/plugins/browser_bug797677.js
+++ b/browser/base/content/test/plugins/browser_bug797677.js
@@ -1,14 +1,14 @@
 var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
 var gTestBrowser = null;
 var gConsoleErrors = 0;
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
 add_task(function* () {
   registerCleanupFunction(function () {
     clearAllPluginPermissions();
     setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
     setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
     consoleService.unregisterListener(errorListener);
     gBrowser.removeCurrentTab();
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -1589,19 +1589,21 @@ file, You can obtain one at http://mozil
 
       <field name="progressmeter" readonly="true">
         document.getElementById("addon-progress-notification-progressmeter"); 
       </field>
       <field name="progresstext" readonly="true">
         document.getElementById("addon-progress-notification-progresstext");
       </field>
       <field name="DownloadUtils" readonly="true">
-        let utils = {};
-        Components.utils.import("resource://gre/modules/DownloadUtils.jsm", utils);
-        utils.DownloadUtils;
+        {
+          let utils = {};
+          Components.utils.import("resource://gre/modules/DownloadUtils.jsm", utils);
+          utils.DownloadUtils;
+        }
       </field>
 
       <method name="destroy">
         <body><![CDATA[
           if (!this.notification)
             return;
 
           this.notification.options.installs.forEach(function(aInstall) {
@@ -2671,21 +2673,23 @@ file, You can obtain one at http://mozil
         this._panel.addEventListener("popupshowing", this, false);
       ]]></constructor>
 
       <destructor><![CDATA[
         this._panel.removeEventListener("popupshowing", this, false);
       ]]></destructor>
 
       <field name="_panel" readonly="true"><![CDATA[
-        let node = this.parentNode;
-        while(node && node.localName != "panel") {
-          node = node.parentNode;
+        {
+          let node = this.parentNode;
+          while(node && node.localName != "panel") {
+            node = node.parentNode;
+          }
+          node;
         }
-        node;
       ]]></field>
       <field name="_promomessage" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "promo-message");
       </field>
       <field name="_promolink" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "promo-link");
       </field>
       <field name="_brandBundle" readonly="true">
--- a/browser/base/content/webrtcIndicator.js
+++ b/browser/base/content/webrtcIndicator.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource:///modules/webrtcUI.jsm");
 
 const BUNDLE_URL = "chrome://browser/locale/webrtcIndicator.properties";
 var gStringBundle;
 
 function init(event) {
   gStringBundle = Services.strings.createBundle(BUNDLE_URL);
--- a/browser/components/customizableui/content/panelUI.js
+++ b/browser/components/customizableui/content/panelUI.js
@@ -505,16 +505,18 @@ const PanelUI = {
 
   _overlayScrollListenerBoundFn: null,
   _overlayScrollListener: function(aMQL) {
     ScrollbarSampler.resetSystemScrollbarWidth();
     this._scrollWidth = null;
   },
 };
 
+XPCOMUtils.defineConstant(this, "PanelUI", PanelUI);
+
 /**
  * Gets the currently selected locale for display.
  * @return  the selected locale or "en-US" if none is selected
  */
 function getLocale() {
   try {
     let chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"]
                            .getService(Ci.nsIXULChromeRegistry);
--- a/browser/components/customizableui/test/browser_1096763_seen_widgets_post_reset.js
+++ b/browser/components/customizableui/test/browser_1096763_seen_widgets_post_reset.js
@@ -4,27 +4,28 @@ const BUTTONID = "test-seenwidget-post-r
 
 add_task(function*() {
   let widget = CustomizableUI.createWidget({
     id: BUTTONID,
     label: "Test widget seen post reset",
     defaultArea: CustomizableUI.AREA_NAVBAR
   });
 
+  const kPrefCustomizationState = "browser.uiCustomization.state";
   let bsPass = Cu.import("resource:///modules/CustomizableUI.jsm", {});
   ok(bsPass.gSeenWidgets.has(BUTTONID), "Widget should be seen after createWidget is called.");
   CustomizableUI.reset();
   ok(bsPass.gSeenWidgets.has(BUTTONID), "Widget should still be seen after reset.");
-  ok(!Services.prefs.prefHasUserValue(bsPass.kPrefCustomizationState), "Pref shouldn't be set right now, because that'd break undo.");
+  ok(!Services.prefs.prefHasUserValue(kPrefCustomizationState), "Pref shouldn't be set right now, because that'd break undo.");
   CustomizableUI.addWidgetToArea(BUTTONID, CustomizableUI.AREA_NAVBAR);
   gCustomizeMode.removeFromArea(document.getElementById(BUTTONID));
-  let hasUserValue = Services.prefs.prefHasUserValue(bsPass.kPrefCustomizationState);
+  let hasUserValue = Services.prefs.prefHasUserValue(kPrefCustomizationState);
   ok(hasUserValue, "Pref should be set right now.");
   if (hasUserValue) {
-    let seenArray = JSON.parse(Services.prefs.getCharPref(bsPass.kPrefCustomizationState)).seen;
+    let seenArray = JSON.parse(Services.prefs.getCharPref(kPrefCustomizationState)).seen;
     isnot(seenArray.indexOf(BUTTONID), -1, "Widget should be in saved 'seen' list.");
   }
 });
 
 registerCleanupFunction(function() {
   CustomizableUI.destroyWidget(BUTTONID);
   CustomizableUI.reset();
 });
--- a/browser/components/dirprovider/tests/unit/head_dirprovider.js
+++ b/browser/components/dirprovider/tests/unit/head_dirprovider.js
@@ -1,14 +1,14 @@
 /* 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/. */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
 var gProfD = do_get_profile();
 var gDirSvc = Cc["@mozilla.org/file/directory_service;1"].
               getService(Ci.nsIProperties);
 var gPrefSvc = Cc["@mozilla.org/preferences-service;1"].
                getService(Ci.nsIPrefBranch);
 
 function writeTestFile(aParent, aName) {
--- a/browser/components/distribution.js
+++ b/browser/components/distribution.js
@@ -1,18 +1,18 @@
 /* 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/. */
 
 this.EXPORTED_SYMBOLS = [ "DistributionCustomizer" ];
 
-const Ci = Components.interfaces;
-const Cc = Components.classes;
-const Cr = Components.results;
-const Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cr = Components.results;
+var Cu = Components.utils;
 
 const DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC =
   "distribution-customization-complete";
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
--- a/browser/components/downloads/content/downloads.js
+++ b/browser/components/downloads/content/downloads.js
@@ -575,16 +575,18 @@ const DownloadsPanel = {
       }
 
       DownloadsCommon.log("Opening downloads panel popup.");
       this.panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, null);
     });
   },
 };
 
+XPCOMUtils.defineConstant(this, "DownloadsPanel", DownloadsPanel);
+
 ////////////////////////////////////////////////////////////////////////////////
 //// DownloadsOverlayLoader
 
 /**
  * Allows loading the downloads panel and the status indicator interfaces on
  * demand, to improve startup performance.
  */
 const DownloadsOverlayLoader = {
@@ -653,16 +655,18 @@ const DownloadsOverlayLoader = {
       // We must call ensureOverlayLoaded again for each request, to check if
       // the associated callback can be invoked now, or if we must still wait
       // for the associated overlay to load.
       this.ensureOverlayLoaded(request.overlay, request.callback);
     }
   },
 };
 
+XPCOMUtils.defineConstant(this, "DownloadsOverlayLoader", DownloadsOverlayLoader);
+
 ////////////////////////////////////////////////////////////////////////////////
 //// DownloadsView
 
 /**
  * Builds and updates the downloads list widget, responding to changes in the
  * download state and real-time data.  In addition, handles part of the user
  * interaction events raised by the downloads list widget.
  */
@@ -999,16 +1003,18 @@ const DownloadsView = {
     dataTransfer.setData("text/uri-list", spec);
     dataTransfer.setData("text/plain", spec);
     dataTransfer.addElement(element);
 
     aEvent.stopPropagation();
   },
 }
 
+XPCOMUtils.defineConstant(this, "DownloadsView", DownloadsView);
+
 ////////////////////////////////////////////////////////////////////////////////
 //// DownloadsViewItem
 
 /**
  * Builds and updates a single item in the downloads list widget, responding to
  * changes in the download state and real-time data.
  *
  * @param download
@@ -1137,16 +1143,18 @@ const DownloadsViewController = {
    */
   commands: {
     downloadsCmd_clearList() {
       DownloadsCommon.getData(window).removeFinished();
     }
   }
 };
 
+XPCOMUtils.defineConstant(this, "DownloadsViewController", DownloadsViewController);
+
 ////////////////////////////////////////////////////////////////////////////////
 //// DownloadsViewItemController
 
 /**
  * Handles all the user interaction events, in particular the "commands",
  * related to a single item in the downloads list widgets.
  */
 function DownloadsViewItemController(download) {
@@ -1483,17 +1491,19 @@ const DownloadsSummary = {
   get _detailsNode() {
     let node = document.getElementById("downloadsSummaryDetails");
     if (!node) {
       return null;
     }
     delete this._detailsNode;
     return this._detailsNode = node;
   }
-}
+};
+
+XPCOMUtils.defineConstant(this, "DownloadsSummary", DownloadsSummary);
 
 ////////////////////////////////////////////////////////////////////////////////
 //// DownloadsFooter
 
 /**
  * Manages events sent to to the footer vbox, which contains both the
  * DownloadsSummary as well as the "Show All Downloads" button.
  */
@@ -1537,8 +1547,10 @@ const DownloadsFooter = {
     let node = document.getElementById("downloadsFooter");
     if (!node) {
       return null;
     }
     delete this._footerNode;
     return this._footerNode = node;
   }
 };
+
+XPCOMUtils.defineConstant(this, "DownloadsFooter", DownloadsFooter);
--- a/browser/components/downloads/content/indicator.js
+++ b/browser/components/downloads/content/indicator.js
@@ -572,8 +572,13 @@ const DownloadsIndicatorView = {
       this._onCustomizedAway();
       this._operational = false;
       this.ensureTerminated();
       this.ensureInitialized();
     }
   },
 };
 
+Object.defineProperty(this, "DownloadsIndicatorView", {
+  value: DownloadsIndicatorView,
+  enumerable: true,
+  writable: false
+});
--- a/browser/components/downloads/test/unit/head.js
+++ b/browser/components/downloads/test/unit/head.js
@@ -5,14 +5,14 @@
 
 /**
  * Provides infrastructure for automated download components tests.
  */
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Globals
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 
 Cu.import("resource:///modules/DownloadsCommon.jsm");
--- a/browser/components/extensions/ext-browserAction.js
+++ b/browser/components/extensions/ext-browserAction.js
@@ -12,17 +12,17 @@ var {
 } = ExtensionUtils;
 
 // WeakMap[Extension -> BrowserAction]
 var browserActionMap = new WeakMap();
 
 // WeakMap[Extension -> docshell]
 // This map is a cache of the windowless browser that's used to render ImageData
 // for the browser_action icon.
-let imageRendererMap = new WeakMap();
+var imageRendererMap = new WeakMap();
 
 function browserActionOf(extension)
 {
   return browserActionMap.get(extension);
 }
 
 function makeWidgetId(id)
 {
--- a/browser/components/extensions/ext-contextMenus.js
+++ b/browser/components/extensions/ext-contextMenus.js
@@ -1,45 +1,45 @@
 Cu.import("resource://gre/modules/ExtensionUtils.jsm");
 Cu.import("resource://gre/modules/MatchPattern.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-let {
+var {
   EventManager,
   contextMenuItems,
   runSafe
 } = ExtensionUtils;
 
 
 // Map[Extension -> Map[ID -> MenuItem]]
 // Note: we want to enumerate all the menu items so
 // this cannot be a weak map.
-let contextMenuMap = new Map();
+var contextMenuMap = new Map();
 
 // Not really used yet, will be used for event pages.
-let onClickedCallbacksMap = new WeakMap();
+var onClickedCallbacksMap = new WeakMap();
 
 // If id is not specified for an item we use an integer.
-let nextID = 0;
+var nextID = 0;
 
 function contextMenuObserver(subject, topic, data) {
   subject = subject.wrappedJSObject;
   menuBuilder.build(subject);
 }
 
 // When a new contextMenu is opened, this function is called and
 // we populate the |xulMenu| with all the items from extensions
 // to be displayed. We always clear all the items again when
 // popuphidden fires. Since most of the info we need is already
 // calculated in nsContextMenu.jsm we simple reuse its flags here.
 // For remote processes there is a gContextMenuContentData where all
 // the important info is stored from the child process. We get
 // this data in |contentData|.
-let menuBuilder = {
+var menuBuilder = {
   build: function(contextData) {
     // TODO: icons should be set for items
     let xulMenu = contextData.menu;
     xulMenu.addEventListener("popuphidden", this);
     let doc = xulMenu.ownerDocument;
     for (let [ext, menuItemMap] of contextMenuMap) {
       let parentMap = new Map();
       let topLevelItems = new Set();
@@ -333,17 +333,17 @@ MenuItem.prototype = {
       // TODO: double check if mediaURL is always set when we need it
       return false;
     }
 
     return true;
   },
 };
 
-let extCount = 0;
+var extCount = 0;
 extensions.on("startup", (type, extension) => {
   contextMenuMap.set(extension, new Map());
   if (++extCount == 1) {
     Services.obs.addObserver(contextMenuObserver,
                              "on-build-contextmenu",
                              false);
   }
 });
--- a/browser/components/extensions/test/browser/head.js
+++ b/browser/components/extensions/test/browser/head.js
@@ -1,7 +1,7 @@
-let {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm");
+var {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm");
 
 function makeWidgetId(id)
 {
   id = id.toLowerCase();
   return id.replace(/[^a-z0-9_-]/g, "_");
 }
--- a/browser/components/feeds/test/unit/head_feeds.js
+++ b/browser/components/feeds/test/unit/head_feeds.js
@@ -1,5 +1,5 @@
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
 
 var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
--- a/browser/components/feeds/test/unit/test_355473.js
+++ b/browser/components/feeds/test/unit/test_355473.js
@@ -1,9 +1,9 @@
-const Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import("resource://gre/modules/Services.jsm");
 
 function run_test() {
   var feedFeedURI = ios.newURI("feed://example.com/feed.xml", null, null);
   var httpFeedURI = ios.newURI("feed:http://example.com/feed.xml", null, null);
   var httpURI = ios.newURI("http://example.com/feed.xml", null, null);
 
   var httpsFeedURI =
--- a/browser/components/loop/modules/LoopRoomsCache.jsm
+++ b/browser/components/loop/modules/LoopRoomsCache.jsm
@@ -12,16 +12,17 @@ const {MozLoopService, LOOP_SESSION_TYPE
   Cu.import("resource:///modules/loop/MozLoopService.jsm", {});
 XPCOMUtils.defineLazyModuleGetter(this, "CommonUtils",
                                   "resource://services-common/utils.js");
 XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
 
 this.EXPORTED_SYMBOLS = ["LoopRoomsCache"];
 
 const LOOP_ROOMS_CACHE_FILENAME = "loopRoomsCache.json";
+XPCOMUtils.defineConstant(this, "LOOP_ROOMS_CACHE_FILENAME", LOOP_ROOMS_CACHE_FILENAME);
 
 /**
  * RoomsCache is a cache for saving simple rooms data to the disk in case we
  * need it for back-up purposes, e.g. recording room keys for FxA if the user
  * changes their password.
  *
  * The format of the data is:
  *
--- a/browser/components/loop/modules/MozLoopService.jsm
+++ b/browser/components/loop/modules/MozLoopService.jsm
@@ -107,16 +107,24 @@ Cu.import("resource://gre/modules/Timer.
 Cu.import("resource://gre/modules/FxAccountsOAuthClient.jsm");
 
 Cu.importGlobalProperties(["URL"]);
 
 this.EXPORTED_SYMBOLS = ["MozLoopService", "LOOP_SESSION_TYPE",
   "TWO_WAY_MEDIA_CONN_LENGTH", "SHARING_STATE_CHANGE", "SHARING_ROOM_URL",
   "ROOM_CREATE", "ROOM_DELETE", "ROOM_CONTEXT_ADD"];
 
+XPCOMUtils.defineConstant(this, "LOOP_SESSION_TYPE", LOOP_SESSION_TYPE);
+XPCOMUtils.defineConstant(this, "TWO_WAY_MEDIA_CONN_LENGTH", TWO_WAY_MEDIA_CONN_LENGTH);
+XPCOMUtils.defineConstant(this, "SHARING_STATE_CHANGE", SHARING_STATE_CHANGE);
+XPCOMUtils.defineConstant(this, "SHARING_ROOM_URL", SHARING_ROOM_URL);
+XPCOMUtils.defineConstant(this, "ROOM_CREATE", ROOM_CREATE);
+XPCOMUtils.defineConstant(this, "ROOM_DELETE", ROOM_DELETE);
+XPCOMUtils.defineConstant(this, "ROOM_CONTEXT_ADD", ROOM_CONTEXT_ADD);
+
 XPCOMUtils.defineLazyModuleGetter(this, "injectLoopAPI",
   "resource:///modules/loop/MozLoopAPI.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "convertToRTCStatsReport",
   "resource://gre/modules/media/RTCStatsReport.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "loopUtils",
   "resource:///modules/loop/utils.js", "utils");
 XPCOMUtils.defineLazyModuleGetter(this, "loopCrypto",
--- a/browser/components/loop/test/xpcshell/head.js
+++ b/browser/components/loop/test/xpcshell/head.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 // Initialize this before the imports, as some of them need it.
 do_get_profile();
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Http.jsm");
 Cu.import("resource://testing-common/httpd.js");
--- a/browser/components/migration/IEProfileMigrator.js
+++ b/browser/components/migration/IEProfileMigrator.js
@@ -27,17 +27,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://gre/modules/PlacesUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "OSCrypto",
                                   "resource://gre/modules/OSCrypto.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "WindowsRegistry",
                                   "resource://gre/modules/WindowsRegistry.jsm");
 
 Cu.importGlobalProperties(["URL"]);
 
-let CtypesKernelHelpers = MSMigrationUtils.CtypesKernelHelpers;
+var CtypesKernelHelpers = MSMigrationUtils.CtypesKernelHelpers;
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Resources
 
 
 function History() {
 }
 
--- a/browser/components/migration/content/migration.js
+++ b/browser/components/migration/content/migration.js
@@ -1,15 +1,15 @@
 /* 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/. */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
 const kIMig = Ci.nsIBrowserProfileMigrator;
 const kIPStartup = Ci.nsIProfileStartup;
 
 Cu.import("resource:///modules/MigrationUtils.jsm");
 
 var MigrationWizard = {
   _source: "",                  // Source Profile Migrator ContractID suffix
--- a/browser/components/migration/tests/unit/head_migration.js
+++ b/browser/components/migration/tests/unit/head_migration.js
@@ -1,9 +1,9 @@
-const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
 
 Cu.importGlobalProperties([ "URL" ]);
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
                                   "resource://gre/modules/PlacesUtils.jsm");
--- a/browser/components/places/tests/unit/head_bookmarks.js
+++ b/browser/components/places/tests/unit/head_bookmarks.js
@@ -1,17 +1,17 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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/. */
 
-const Ci = Components.interfaces;
-const Cc = Components.classes;
-const Cr = Components.results;
-const Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cr = Components.results;
+var Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/LoadContextInfo.jsm");
 
 // Import common head.
 var commonFile = do_get_file("../../../../../toolkit/components/places/tests/head_common.js", false);
 if (commonFile) {
   let uri = Services.io.newFileURI(commonFile);
--- a/browser/components/preferences/blocklists.js
+++ b/browser/components/preferences/blocklists.js
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 const TEST_LIST = "test-track-simple";
 const TRACK_SUFFIX = "-track-digest256";
 const TRACKING_TABLE_PREF = "urlclassifier.trackingTable";
 const LISTS_PREF_BRANCH = "browser.safebrowsing.provider.mozilla.lists.";
 
-let gBlocklistManager = {
+var gBlocklistManager = {
   _type: "",
   _blockLists: [],
   _brandShortName : null,
   _bundle: null,
   _tree: null,
 
   _view: {
     _rowCount: 0,
--- a/browser/components/preferences/in-content/preferences.js
+++ b/browser/components/preferences/in-content/preferences.js
@@ -1,18 +1,18 @@
 /* - 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/. */
 
 "use strict";
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 var gLastHash = "";
 
 var gCategoryInits = new Map();
 function init_category_if_required(category) {
--- a/browser/components/preferences/translation.js
+++ b/browser/components/preferences/translation.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
 /* 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/. */
 
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "gLangBundle", () =>
   Services.strings.createBundle("chrome://global/locale/languageNames.properties"));
 
 const kPermissionType = "translate";
--- a/browser/components/privatebrowsing/content/aboutPrivateBrowsing.js
+++ b/browser/components/privatebrowsing/content/aboutPrivateBrowsing.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const FAVICON_QUESTION = "chrome://global/skin/icons/question-16.png";
 const FAVICON_PRIVACY = "chrome://browser/skin/Privacy-16.png";
 
--- a/browser/components/sessionstore/content/aboutSessionRestore.js
+++ b/browser/components/sessionstore/content/aboutSessionRestore.js
@@ -1,15 +1,15 @@
 /* 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/. */
 
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
   "resource://gre/modules/AppConstants.jsm");
 
 var gStateObject;
 var gTreeData;
--- a/browser/components/sessionstore/test/browser_privatetabs.js
+++ b/browser/components/sessionstore/test/browser_privatetabs.js
@@ -1,15 +1,11 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-var Imports = {};
-Cu.import("resource:///modules/sessionstore/SessionSaver.jsm", Imports);
-var {SessionSaver} = Imports;
-
 add_task(function cleanup() {
   info("Forgetting closed tabs");
   while (ss.getClosedTabCount(window)) {
     ss.forgetClosedTab(window, 0);
   }
 });
 
 add_task(function() {
--- a/browser/components/shell/test/unit/test_421977.js
+++ b/browser/components/shell/test/unit/test_421977.js
@@ -1,11 +1,11 @@
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
 
 const GCONF_BG_COLOR_KEY = "/desktop/gnome/background/primary_color";
 
 var gShell;
 var gGConf;
 
 /**
  * Converts from a rgb numerical color valule (r << 16 | g << 8 | b)
--- a/browser/components/tabview/tabview.js
+++ b/browser/components/tabview/tabview.js
@@ -1,18 +1,18 @@
 /* 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/. */
 
 "use strict";
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 
 Cu.import("resource:///modules/tabview/utils.jsm");
 Cu.import("resource://gre/modules/AppConstants.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "tabviewBundle", function() {
   return Services.strings.
--- a/browser/components/uitour/test/browser_fxa.js
+++ b/browser/components/uitour/test/browser_fxa.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
                                   "resource://gre/modules/FxAccounts.jsm");
 
 var gTestTab;
 var gContentAPI;
 var gContentWindow;
 
--- a/browser/components/uitour/test/browser_openPreferences.js
+++ b/browser/components/uitour/test/browser_openPreferences.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 var gTestTab;
 var gContentAPI;
 var gContentWindow;
 
 function test() {
   UITourTest();
 }
--- a/browser/components/uitour/test/browser_showMenu_controlCenter.js
+++ b/browser/components/uitour/test/browser_showMenu_controlCenter.js
@@ -1,11 +1,11 @@
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const CONTROL_CENTER_PANEL = gIdentityHandler._identityPopup;
 const CONTROL_CENTER_MENU_NAME = "controlCenter";
 
 var gTestTab;
 var gContentAPI;
 var gContentWindow;
 
 function test() {
--- a/browser/components/uitour/test/browser_trackingProtection.js
+++ b/browser/components/uitour/test/browser_trackingProtection.js
@@ -1,11 +1,11 @@
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const PREF_INTRO_COUNT = "privacy.trackingprotection.introCount";
 const PREF_TP_ENABLED = "privacy.trackingprotection.enabled";
 const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
 const TOOLTIP_PANEL = document.getElementById("UITourTooltip");
 const TOOLTIP_ANCHOR = document.getElementById("tracking-protection-icon");
 
 var {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
--- a/browser/experiments/Experiments.jsm
+++ b/browser/experiments/Experiments.jsm
@@ -89,16 +89,17 @@ const TELEMETRY_LOG = {
     FROM_API: "FROM_API",
     // The experiment expired (e.g. by exceeding the end date).
     EXPIRED: "EXPIRED",
     // Disabled after re-evaluating conditions. If this is specified,
     // details will be provided.
     RECHECK: "RECHECK",
   },
 };
+XPCOMUtils.defineConstant(this, "TELEMETRY_LOG", TELEMETRY_LOG);
 
 const gPrefs = new Preferences(PREF_BRANCH);
 const gPrefsTelemetry = new Preferences(PREF_BRANCH_TELEMETRY);
 var gExperimentsEnabled = false;
 var gAddonProvider = null;
 var gExperiments = null;
 var gLogAppenderDump = null;
 var gPolicyCounter = 0;
--- a/browser/experiments/test/xpcshell/head.js
+++ b/browser/experiments/test/xpcshell/head.js
@@ -1,12 +1,12 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Promise.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/osfile.jsm");
 Cu.import("resource://testing-common/AddonManagerTesting.jsm");
 
--- a/browser/modules/Chat.jsm
+++ b/browser/modules/Chat.jsm
@@ -13,17 +13,17 @@ Cu.import("resource://gre/modules/Servic
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
   "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 const kDefaultButtonSet = new Set(["minimize", "swap", "close"]);
 const kHiddenDefaultButtons = new Set(["minimize", "close"]);
-let gCustomButtons = new Map();
+var gCustomButtons = new Map();
 
 // A couple of internal helper function.
 function isWindowChromeless(win) {
   // XXX - stolen from browser-social.js, but there's no obvious place to
   // put this so it can be shared.
 
   // Is this a popup window that doesn't want chrome shown?
   let docElem = win.document.documentElement;
--- a/browser/modules/Sanitizer.jsm
+++ b/browser/modules/Sanitizer.jsm
@@ -10,13 +10,13 @@
 // sanitize is loaded from its own compartment, rather than from that
 // of the sanitize dialog.
 //
 
 this.EXPORTED_SYMBOLS = ["Sanitizer"];
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
-let scope = {};
+var scope = {};
 Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
  .loadSubScript("chrome://browser/content/sanitize.js", scope);
 
 this.Sanitizer = scope.Sanitizer;
--- a/browser/modules/Windows8WindowFrameColor.jsm
+++ b/browser/modules/Windows8WindowFrameColor.jsm
@@ -6,17 +6,17 @@
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 this.EXPORTED_SYMBOLS = ["Windows8WindowFrameColor"];
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 var Registry = Cu.import("resource://gre/modules/WindowsRegistry.jsm").WindowsRegistry;
 
-const Windows8WindowFrameColor = {
+var Windows8WindowFrameColor = {
   _windowFrameColor: null,
 
   get: function() {
     if (this._windowFrameColor)
       return this._windowFrameColor;
 
     const HKCU = Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER;
     const dwmKey = "Software\\Microsoft\\Windows\\DWM";
--- a/browser/modules/test/unit/social/head.js
+++ b/browser/modules/test/unit/social/head.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 var Social, SocialService;
 
 var manifests = [
   {
     name: "provider 1",
--- a/browser/modules/test/xpcshell/test_DirectoryLinksProvider.js
+++ b/browser/modules/test/xpcshell/test_DirectoryLinksProvider.js
@@ -2,17 +2,17 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 "use strict";
 
 /**
  * This file tests the DirectoryLinksProvider singleton in the DirectoryLinksProvider.jsm module.
  */
 
-const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu, Constructor: CC } = Components;
+var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu, Constructor: CC } = Components;
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource:///modules/DirectoryLinksProvider.jsm");
 Cu.import("resource://gre/modules/Promise.jsm");
 Cu.import("resource://gre/modules/Http.jsm");
 Cu.import("resource://testing-common/httpd.js");
 Cu.import("resource://gre/modules/osfile.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
--- a/caps/tests/unit/test_origin.js
+++ b/caps/tests/unit/test_origin.js
@@ -1,11 +1,11 @@
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 var ssm = Services.scriptSecurityManager;
 function makeURI(uri) { return Services.io.newURI(uri, null, null); }
 
 function checkThrows(f) {
   var threw = false;
   try { f(); } catch (e) { threw = true }
--- a/chrome/test/unit/head_crtestutils.js
+++ b/chrome/test/unit/head_crtestutils.js
@@ -1,14 +1,14 @@
 const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1";
 const XULAPPINFO_CID = Components.ID("{4ba645d3-be6f-40d6-a42a-01b2f40091b8}");
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
 
 
 function registerManifests(manifests)
 {
   var reg = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
   for each (var manifest in manifests)
     reg.autoRegister(manifest);
 }
--- a/configure.in
+++ b/configure.in
@@ -473,16 +473,19 @@ EOF
   fi
   if test -z "$MOZ_RUST"; then
     AC_MSG_ERROR([rustc does not support MacOS X $MACOSX_DEPLOYMENT_TARGET
       Add 'ac_add_options --enable-macos-target=10.7' (or later)
       to mozconfig, disable Rust support, or use an alternate toolchain.])
   fi
 fi
 
+AC_PROG_CPP
+AC_PROG_CXXCPP
+
 dnl ========================================================
 dnl Special win32 checks
 dnl ========================================================
 
 # Target the Windows 8.1 SDK by default
 WINSDK_TARGETVER=603
 WINVER=502
 
@@ -662,18 +665,16 @@ See https://developer.mozilla.org/en/Win
             AC_MSG_ERROR([Gecko exception wrapping doesn't understand your your MSVC/SDK.  Please file a bug describing this error and your build configuration.])
         fi
 
         if test "$WRAP_STL_INCLUDES" = "1"; then
             STL_FLAGS='-I$(DIST)/stl_wrappers'
         fi
         CFLAGS="$CFLAGS -D_HAS_EXCEPTIONS=0"
         CXXFLAGS="$CXXFLAGS -D_HAS_EXCEPTIONS=0"
-
-        MOZ_FIND_WINSDK_VERSION
     else
         # Check w32api version
         _W32API_MAJOR_VERSION=`echo $W32API_VERSION | $AWK -F\. '{ print $1 }'`
         _W32API_MINOR_VERSION=`echo $W32API_VERSION | $AWK -F\. '{ print $2 }'`
         AC_MSG_CHECKING([for w32api version >= $W32API_VERSION])
         AC_TRY_COMPILE([#include <w32api.h>],
             #if (__W32API_MAJOR_VERSION < $_W32API_MAJOR_VERSION) || \
                 (__W32API_MAJOR_VERSION == $_W32API_MAJOR_VERSION && \
@@ -715,20 +716,19 @@ See https://developer.mozilla.org/en/Win
                 MIDL_FLAGS="$MIDL_FLAGS --win64 -m64"
                 ;;
             esac
         fi
 
         # strsafe.h on mingw uses macros for function deprecation that pollutes namespace
         # causing problems with local implementations with the same name.
         AC_DEFINE(STRSAFE_NO_DEPRECATE)
-
-        MOZ_WINSDK_MAXVER=0x06030000
     fi # !GNU_CC
 
+    MOZ_FIND_WINSDK_VERSION
     AC_DEFINE_UNQUOTED(WINVER,0x$WINVER)
     AC_DEFINE_UNQUOTED(_WIN32_WINNT,0x$WINVER)
     # Require OS features provided by IE 6.0 SP2 (XP SP2)
     AC_DEFINE_UNQUOTED(_WIN32_IE,0x0603)
 
     # If the maximum version supported by this SDK is lower than the target
     # version, error out
     AC_MSG_CHECKING([for Windows SDK being recent enough])
@@ -740,19 +740,16 @@ See https://developer.mozilla.org/en/Win
     fi
 
     AC_DEFINE_UNQUOTED(MOZ_WINSDK_TARGETVER,0x$MOZ_WINSDK_TARGETVER)
     AC_DEFINE_UNQUOTED(MOZ_WINSDK_MAXVER,$MOZ_WINSDK_MAXVER)
     AC_SUBST(MOZ_WINSDK_MAXVER)
     ;;
 esac
 
-AC_PROG_CPP
-AC_PROG_CXXCPP
-
 if test -n "$_WIN32_MSVC"; then
     SKIP_PATH_CHECKS=1
     SKIP_COMPILER_CHECKS=1
     SKIP_LIBRARY_CHECKS=1
 
     # Since we're skipping compiler and library checks, hard-code
     # some facts here.
     AC_DEFINE(HAVE_IO_H)
@@ -1857,16 +1854,19 @@ case "$host" in
 esac
 
 dnl ==============================================================
 dnl Get mozilla version from central milestone file
 dnl ==============================================================
 MOZILLA_VERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir`
 MOZILLA_UAVERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir --uaversion`
 MOZILLA_SYMBOLVERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir --symbolversion`
+if test -z "$MOZILLA_VERSION"; then
+  AC_MSG_ERROR([failed to read version info from milestone file])
+fi
 
 dnl Get version of various core apps from the version files.
 FIREFOX_VERSION=`cat $_topsrcdir/browser/config/version.txt`
 FIREFOX_VERSION_DISPLAY=`cat $_topsrcdir/browser/config/version_display.txt`
 
 if test -z "$FIREFOX_VERSION"; then
     AC_MSG_ERROR([FIREFOX_VERSION is unexpectedly blank.])
 fi
--- a/devtools/client/aboutdebugging/aboutdebugging.js
+++ b/devtools/client/aboutdebugging/aboutdebugging.js
@@ -16,17 +16,17 @@ loader.lazyRequireGetter(this, "AddonsCo
 loader.lazyRequireGetter(this, "DebuggerClient",
   "devtools/shared/client/main", true);
 loader.lazyRequireGetter(this, "DebuggerServer",
   "devtools/server/main", true);
 loader.lazyRequireGetter(this, "WorkersComponent",
   "devtools/client/aboutdebugging/components/workers", true);
 loader.lazyRequireGetter(this, "Services");
 
-let AboutDebugging = {
+var AboutDebugging = {
   _categories: null,
   get categories() {
     // If needed, initialize the list of available categories.
     if (!this._categories) {
       let elements = document.querySelectorAll(".category");
       this._categories = Array.map(elements, element => {
         let value = element.getAttribute("value");
         element.addEventListener("click", this.showTab.bind(this, value));
--- a/devtools/client/animationinspector/animation-controller.js
+++ b/devtools/client/animationinspector/animation-controller.js
@@ -2,17 +2,17 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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/. */
 /* globals AnimationsPanel */
 
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/Task.jsm");
 var { loader, require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm");
 Cu.import("resource://gre/modules/devtools/shared/Console.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
 
 loader.lazyRequireGetter(this, "promise");
 loader.lazyRequireGetter(this, "EventEmitter",
--- a/devtools/client/animationinspector/test/head.js
+++ b/devtools/client/animationinspector/test/head.js
@@ -1,15 +1,15 @@
 /* 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/ */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {gDevTools} = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const promise = require("promise");
 const {TargetFactory} = require("devtools/client/framework/target");
 const {console} = Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
 const {ViewHelpers} = Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm", {});
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
 
--- a/devtools/client/animationinspector/test/unit/test_findOptimalTimeInterval.js
+++ b/devtools/client/animationinspector/test/unit/test_findOptimalTimeInterval.js
@@ -1,17 +1,17 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 /* eslint no-eval:0 */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {findOptimalTimeInterval} = require("devtools/client/animationinspector/utils");
 
 // This test array contains objects that are used to test the
 // findOptimalTimeInterval function. Each object should have the following
 // properties:
 // - desc: an optional string that will be printed out
 // - timeScale: a number that represents how many pixels is 1ms
--- a/devtools/client/animationinspector/test/unit/test_timeScale.js
+++ b/devtools/client/animationinspector/test/unit/test_timeScale.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {TimeScale} = require("devtools/client/animationinspector/components");
 
 const TEST_ANIMATIONS = [{
   desc: "Testing a few standard animations",
   animations: [{
     previousStartTime: 500,
     delay: 0,
--- a/devtools/client/app-manager/content/connection-footer.js
+++ b/devtools/client/app-manager/content/connection-footer.js
@@ -1,14 +1,14 @@
 /* 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/. */
 
-const Cu = Components.utils;
-const Ci = Components.interfaces;
+var Cu = Components.utils;
+var Ci = Components.interfaces;
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm");
 
 const {Simulator} = Cu.import("resource://gre/modules/devtools/shared/apps/Simulator.jsm")
 const {Devices} = Cu.import("resource://gre/modules/devtools/shared/apps/Devices.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 const {ConnectionManager, Connection} = require("devtools/shared/client/connection-manager");
--- a/devtools/client/app-manager/content/device.js
+++ b/devtools/client/app-manager/content/device.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import("resource://gre/modules/Services.jsm");
 const {gDevTools} = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {TargetFactory} = require("devtools/client/framework/target");
 
 const {ConnectionManager, Connection}
   = require("devtools/shared/client/connection-manager");
--- a/devtools/client/app-manager/content/index.js
+++ b/devtools/client/app-manager/content/index.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const {utils: Cu, interfaces: Ci} = Components;
+var {utils: Cu, interfaces: Ci} = Components;
 Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {Toolbox} = require("devtools/client/framework/toolbox");
 const {ConnectionManager, Connection} = require("devtools/shared/client/connection-manager");
 const promise = require("devtools/shared/deprecated-sync-thenables");
 const prefs = require("sdk/preferences/service");
 const Services = require("Services");
 const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/app-manager.properties");
--- a/devtools/client/app-manager/content/projects.js
+++ b/devtools/client/app-manager/content/projects.js
@@ -1,16 +1,16 @@
 /* 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/. */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {ConnectionManager, Connection} = require("devtools/shared/client/connection-manager");
 const {AppProjects} = require("devtools/client/app-manager/app-projects");
 const {AppValidator} = require("devtools/client/app-manager/app-validator");
 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
 const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
 const {installHosted, installPackaged, getTargetForApp,
--- a/devtools/client/app-manager/test/head.js
+++ b/devtools/client/app-manager/test/head.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const {utils: Cu, classes: Cc, interfaces: Ci} = Components;
+var {utils: Cu, classes: Cc, interfaces: Ci} = Components;
 
 const {Promise: promise} =
   Cu.import("resource://gre/modules/devtools/shared/deprecated-sync-thenables.js", {});
 const {require} =
   Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 const {AppProjects} = require("devtools/client/app-manager/app-projects");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
--- a/devtools/client/canvasdebugger/canvasdebugger.js
+++ b/devtools/client/canvasdebugger/canvasdebugger.js
@@ -1,14 +1,14 @@
 /* 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/. */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/SideMenuWidget.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
 Cu.import("resource://gre/modules/devtools/shared/Console.jsm");
 
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
@@ -72,16 +72,17 @@ const EVENTS = {
   // After all the thumbnails associated with an animation frame snapshot
   // are displayed in the UI.
   THUMBNAILS_DISPLAYED: "CanvasDebugger:ThumbnailsDisplayed",
 
   // When a source is shown in the JavaScript Debugger at a specific location.
   SOURCE_SHOWN_IN_JS_DEBUGGER: "CanvasDebugger:SourceShownInJsDebugger",
   SOURCE_NOT_FOUND_IN_JS_DEBUGGER: "CanvasDebugger:SourceNotFoundInJsDebugger"
 };
+XPCOMUtils.defineConstant(this, "EVENTS", EVENTS);
 
 const HTML_NS = "http://www.w3.org/1999/xhtml";
 const STRINGS_URI = "chrome://browser/locale/devtools/canvasdebugger.properties";
 const SHARED_STRINGS_URI = "chrome://browser/locale/devtools/shared.properties";
 
 const SNAPSHOT_START_RECORDING_DELAY = 10; // ms
 const SNAPSHOT_DATA_EXPORT_MAX_BLOCK = 1000; // ms
 const SNAPSHOT_DATA_DISPLAY_DELAY = 10; // ms
--- a/devtools/client/canvasdebugger/test/head.js
+++ b/devtools/client/canvasdebugger/test/head.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 
 // Disable logging for all the tests. Both the debugger server and frontend will
 // be affected by this pref.
 var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
 Services.prefs.setBoolPref("devtools.debugger.log", false);
 
--- a/devtools/client/debugger/debugger-controller.js
+++ b/devtools/client/debugger/debugger-controller.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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/. */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 const DBG_STRINGS_URI = "chrome://browser/locale/devtools/debugger.properties";
 const NEW_SOURCE_IGNORED_URLS = ["debugger eval code", "XStringBundle"];
 const NEW_SOURCE_DISPLAY_DELAY = 200; // ms
 const FETCH_SOURCE_RESPONSE_DELAY = 200; // ms
 const FRAME_STEP_CLEAR_DELAY = 100; // ms
 const CALL_STACK_PAGE_SIZE = 25; // frames
 
@@ -99,26 +99,29 @@ Cu.import("resource:///modules/devtools/
 Cu.import("resource:///modules/devtools/client/shared/widgets/BreadcrumbsWidget.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/SideMenuWidget.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/VariablesView.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/VariablesViewController.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
 
 Cu.import("resource:///modules/devtools/client/shared/browser-loader.js");
 const require = BrowserLoader("resource:///modules/devtools/client/debugger/", this).require;
+XPCOMUtils.defineConstant(this, "require", require);
 
 const {TargetFactory} = require("devtools/client/framework/target");
 const {Toolbox} = require("devtools/client/framework/toolbox");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
 const promise = require("devtools/shared/deprecated-sync-thenables");
 const Editor = require("devtools/client/sourceeditor/editor");
 const DebuggerEditor = require("devtools/client/sourceeditor/debugger");
 const {Tooltip} = require("devtools/client/shared/widgets/Tooltip");
 const FastListWidget = require("devtools/client/shared/widgets/FastListWidget");
 
+XPCOMUtils.defineConstant(this, "EVENTS", EVENTS);
+
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
   "resource://gre/modules/Task.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Parser",
   "resource:///modules/devtools/client/shared/Parser.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "ShortcutUtils",
   "resource://gre/modules/ShortcutUtils.jsm");
--- a/devtools/client/debugger/debugger-view.js
+++ b/devtools/client/debugger/debugger-view.js
@@ -44,16 +44,29 @@ const { NAME: WAIT_UNTIL_NAME } = requir
 
 const services = {
   WAIT_UNTIL: WAIT_UNTIL_NAME
 };
 
 const EventListenersView = require('./content/views/event-listeners-view');
 const actions = require('./content/actions/event-listeners');
 
+Object.defineProperties(this, {
+  "store": {
+    value: store,
+    enumerable: true,
+    writable: false
+  },
+  "services": {
+    value: services,
+    enumerable: true,
+    writable: false
+  }
+});
+
 /**
  * Object defining the debugger view components.
  */
 var DebuggerView = {
   /**
    * Initializes the debugger view.
    *
    * @return object
--- a/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/bootstrap.js
+++ b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/bootstrap.js
@@ -1,12 +1,12 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const { interfaces: Ci, classes: Cc, utils: Cu } = Components;
+var { interfaces: Ci, classes: Cc, utils: Cu } = Components;
 
 function notify() {
   // Log objects so makeDebuggeeValue can get the global to use
   console.log({ msg: "Hello again" });
 }
 
 function startup(aParams, aReason) {
   Cu.import("resource://gre/modules/Services.jsm");
--- a/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon5/bootstrap.js
+++ b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon5/bootstrap.js
@@ -1,12 +1,12 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const { interfaces: Ci, classes: Cc } = Components;
+var { interfaces: Ci, classes: Cc } = Components;
 
 function startup(aParams, aReason) {
   Components.utils.import("resource://gre/modules/Services.jsm");
   let res = Services.io.getProtocolHandler("resource")
                        .QueryInterface(Ci.nsIResProtocolHandler);
   res.setSubstitution("browser_dbg_addon5", aParams.resourceURI);
 
   // Load a JS module
--- a/devtools/client/debugger/test/mochitest/browser_dbg_break-on-next-console.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_break-on-next-console.js
@@ -35,21 +35,23 @@ function test() {
     EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
     let jsterm = yield getSplitConsole();
     let executed = jsterm.execute("1+1");
     yield oncePaused;
 
     let updatedFrame = yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
     let variables = gDebugger.DebuggerView.Variables;
 
-    is(variables._store.length, 2, "Correct number of scopes available");
+    is(variables._store.length, 3, "Correct number of scopes available");
     is(variables.getScopeAtIndex(0).name, "With scope [Object]",
         "Paused with correct scope (0)");
-    is(variables.getScopeAtIndex(1).name, "Global scope [Window]",
+    is(variables.getScopeAtIndex(1).name, "Block scope",
         "Paused with correct scope (1)");
+    is(variables.getScopeAtIndex(2).name, "Global scope [Window]",
+        "Paused with correct scope (2)");
 
     let onceResumed = gTarget.once("thread-resumed");
     EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
     yield onceResumed;
 
     yield executed;
   });
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_break-on-next.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_break-on-next.js
@@ -44,23 +44,25 @@ function test() {
 
     let oncePaused = gTarget.once("thread-paused");
     EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
     yield oncePaused;
 
     let updatedFrame = yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
     let variables = gDebugger.DebuggerView.Variables;
 
-    is(variables._store.length, 3, "Correct number of scopes available");
+    is(variables._store.length, 4, "Correct number of scopes available");
     is(variables.getScopeAtIndex(0).name, "Function scope [interval<]",
         "Paused with correct scope (0)");
     is(variables.getScopeAtIndex(1).name, "Block scope",
         "Paused with correct scope (1)");
-    is(variables.getScopeAtIndex(2).name, "Global scope [Window]",
+    is(variables.getScopeAtIndex(2).name, "Block scope",
         "Paused with correct scope (2)");
+    is(variables.getScopeAtIndex(3).name, "Global scope [Window]",
+        "Paused with correct scope (3)");
 
     yield evalInTab(gTab, "clearInterval(interval)");
     let onceResumed = gTarget.once("thread-resumed");
     EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
     yield onceResumed;
   });
 
   let testEvent = Task.async(function*() {
@@ -71,23 +73,29 @@ function test() {
     once(gDebugger.gClient, "willInterrupt").then(() => {
       generateMouseClickInTab(gTab, "content.document.querySelector('button')");
     });
     yield oncePaused;
 
     let updatedFrame = yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
     let variables = gDebugger.DebuggerView.Variables;
 
-    is(variables._store.length, 4, "Correct number of scopes available");
+    is(variables._store.length, 6, "Correct number of scopes available");
     is(variables.getScopeAtIndex(0).name, "Function scope [onclick]",
         "Paused with correct scope (0)");
-    is(variables.getScopeAtIndex(1).name, "With scope [HTMLButtonElement]",
+    // Non-syntactic lexical scope introduced by non-syntactic scope chain.
+    is(variables.getScopeAtIndex(1).name, "Block scope",
         "Paused with correct scope (1)");
-    is(variables.getScopeAtIndex(2).name, "With scope [HTMLDocument]",
+    is(variables.getScopeAtIndex(2).name, "With scope [HTMLButtonElement]",
         "Paused with correct scope (2)");
-    is(variables.getScopeAtIndex(3).name, "Global scope [Window]",
+    is(variables.getScopeAtIndex(3).name, "With scope [HTMLDocument]",
         "Paused with correct scope (3)");
+    // Global lexical scope.
+    is(variables.getScopeAtIndex(4).name, "Block scope",
+        "Paused with correct scope (4)");
+    is(variables.getScopeAtIndex(5).name, "Global scope [Window]",
+        "Paused with correct scope (5)");
 
     let onceResumed = gTarget.once("thread-resumed");
     EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
     yield onceResumed;
   });
 }
--- a/devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-01.js
@@ -48,18 +48,18 @@ function testPauseOnExceptionsDisabled()
     ok(isCaretPos(gPanel, 26),
       "Should be paused on the debugger statement (1).");
 
     let innerScope = gVariables.getScopeAtIndex(0);
     let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes;
 
     is(gFrames.itemCount, 1,
       "Should have one frame.");
-    is(gVariables._store.length, 3,
-      "Should have three scopes.");
+    is(gVariables._store.length, 4,
+      "Should have four scopes.");
 
     is(innerNodes[0].querySelector(".name").getAttribute("value"), "this",
       "Should have the right property name for 'this'.");
     is(innerNodes[0].querySelector(".value").getAttribute("value"), "<button>",
       "Should have the right property value for 'this'.");
 
     let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
       isnot(gDebugger.gThreadClient.state, "paused",
@@ -91,18 +91,18 @@ function testPauseOnExceptionsEnabled() 
     ok(isCaretPos(gPanel, 19),
       "Should be paused on the debugger statement.");
 
     let innerScope = gVariables.getScopeAtIndex(0);
     let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes;
 
     is(gFrames.itemCount, 1,
       "Should have one frame.");
-    is(gVariables._store.length, 3,
-      "Should have three scopes.");
+    is(gVariables._store.length, 4,
+      "Should have four scopes.");
 
     is(innerNodes[0].querySelector(".name").getAttribute("value"), "<exception>",
       "Should have the right property name for <exception>.");
     is(innerNodes[0].querySelector(".value").getAttribute("value"), "Error",
       "Should have the right property value for <exception>.");
 
     let finished = waitForCaretAndScopes(gPanel, 26).then(() => {
       info("Testing enabled pause-on-exceptions and resumed after pause.");
@@ -112,18 +112,18 @@ function testPauseOnExceptionsEnabled() 
       ok(isCaretPos(gPanel, 26),
         "Should be paused on the debugger statement.");
 
       let innerScope = gVariables.getScopeAtIndex(0);
       let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes;
 
       is(gFrames.itemCount, 1,
         "Should have one frame.");
-      is(gVariables._store.length, 3,
-        "Should have three scopes.");
+      is(gVariables._store.length, 4,
+        "Should have four scopes.");
 
       is(innerNodes[0].querySelector(".name").getAttribute("value"), "this",
         "Should have the right property name for 'this'.");
       is(innerNodes[0].querySelector(".value").getAttribute("value"), "<button>",
         "Should have the right property value for 'this'.");
 
       let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
         isnot(gDebugger.gThreadClient.state, "paused",
--- a/devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-02.js
@@ -47,18 +47,18 @@ function testPauseOnExceptionsAfterReloa
     ok(isCaretPos(gPanel, 19),
       "Should be paused on the debugger statement.");
 
     let innerScope = gVariables.getScopeAtIndex(0);
     let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes;
 
     is(gFrames.itemCount, 1,
       "Should have one frame.");
-    is(gVariables._store.length, 3,
-      "Should have three scopes.");
+    is(gVariables._store.length, 4,
+      "Should have four scopes.");
 
     is(innerNodes[0].querySelector(".name").getAttribute("value"), "<exception>",
       "Should have the right property name for <exception>.");
     is(innerNodes[0].querySelector(".value").getAttribute("value"), "Error",
       "Should have the right property value for <exception>.");
 
     let finished = waitForCaretAndScopes(gPanel, 26).then(() => {
       info("Testing enabled pause-on-exceptions and resumed after pause.");
@@ -68,18 +68,18 @@ function testPauseOnExceptionsAfterReloa
       ok(isCaretPos(gPanel, 26),
         "Should be paused on the debugger statement.");
 
       let innerScope = gVariables.getScopeAtIndex(0);
       let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes;
 
       is(gFrames.itemCount, 1,
         "Should have one frame.");
-      is(gVariables._store.length, 3,
-        "Should have three scopes.");
+      is(gVariables._store.length, 4,
+        "Should have four scopes.");
 
       is(innerNodes[0].querySelector(".name").getAttribute("value"), "this",
         "Should have the right property name for 'this'.");
       is(innerNodes[0].querySelector(".value").getAttribute("value"), "<button>",
         "Should have the right property value for 'this'.");
 
       let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
         isnot(gDebugger.gThreadClient.state, "paused",
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-06.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-06.js
@@ -2,17 +2,17 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Test that Promises get their internal state added as psuedo properties.
  */
 
 const TAB_URL = EXAMPLE_URL + "doc_promise.html";
 
-const test = Task.async(function* () {
+var test = Task.async(function* () {
   const [tab,, panel] = yield initDebugger(TAB_URL);
   yield ensureSourceIs(panel, "doc_promise.html", true);
 
   const scopes = waitForCaretAndScopes(panel, 21);
   callInTab(tab, "doPause");
   yield scopes;
 
   const variables = panel.panelWin.DebuggerView.Variables;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-01.js
@@ -39,29 +39,32 @@ function test() {
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testVariablesAndPropertiesFiltering() {
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
   let protoVar = localScope.get("__proto__");
   let constrVar = protoVar.get("constructor");
   let proto2Var = constrVar.get("__proto__");
   let constr2Var = proto2Var.get("constructor");
 
   function testFiltered() {
     is(localScope.expanded, true,
       "The localScope should be expanded.");
     is(withScope.expanded, true,
       "The withScope should be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalLexicalScope should be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should be expanded.");
 
     is(protoVar.expanded, true,
       "The protoVar should be expanded.");
     is(constrVar.expanded, true,
       "The constrVar should be expanded.");
     is(proto2Var.expanded, true,
@@ -70,23 +73,27 @@ function testVariablesAndPropertiesFilte
       "The constr2Var should be expanded.");
 
     is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 1,
       "There should be 1 variable displayed in the local scope.");
     is(withScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be 0 variables displayed in the with scope.");
     is(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be 0 variables displayed in the function scope.");
+    is(globalLexicalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
+      "There should be 0 variables displayed in the global lexical scope.");
     is(globalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be 0 variables displayed in the global scope.");
 
     is(withScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the with scope.");
     is(functionScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the function scope.");
+    is(globalLexicalScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
+      "There should be 0 properties displayed in the global lexical scope.");
     is(globalScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the global scope.");
 
     is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
       "__proto__", "The only inner variable displayed should be '__proto__'");
     is(localScope.target.querySelectorAll(".variables-view-property:not([unmatched]) > .title > .name")[0].getAttribute("value"),
       "constructor", "The first inner property displayed should be 'constructor'");
     is(localScope.target.querySelectorAll(".variables-view-property:not([unmatched]) > .title > .name")[1].getAttribute("value"),
@@ -101,28 +108,31 @@ function testVariablesAndPropertiesFilte
     gSearchBox.doCommand();
     return expanded.then(testFiltered);
   }
 
   function secondFilter() {
     localScope.collapse();
     withScope.collapse();
     functionScope.collapse();
+    globalLexicalScope.collapse();
     globalScope.collapse();
     protoVar.collapse();
     constrVar.collapse();
     proto2Var.collapse();
     constr2Var.collapse();
 
     is(localScope.expanded, false,
       "The localScope should not be expanded.");
     is(withScope.expanded, false,
       "The withScope should not be expanded.");
     is(functionScope.expanded, false,
       "The functionScope should not be expanded.");
+    is(globalLexicalScope.expanded, false,
+      "The globalLexicalScope should not be expanded.");
     is(globalScope.expanded, false,
       "The globalScope should not be expanded.");
 
     is(protoVar.expanded, false,
       "The protoVar should not be expanded.");
     is(constrVar.expanded, false,
       "The constrVar should not be expanded.");
     is(proto2Var.expanded, false,
@@ -140,36 +150,41 @@ function testVariablesAndPropertiesFilte
 }
 
 function prepareVariablesAndProperties() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   is(localScope.expanded, true,
     "The localScope should be expanded.");
   is(withScope.expanded, false,
     "The withScope should not be expanded yet.");
   is(functionScope.expanded, false,
-    "The functionScope should not be expanded yet.");
+     "The functionScope should not be expanded yet.");
+  is(globalLexicalScope.expanded, false,
+     "The globalLexicalScope should not be expanded yet.");
   is(globalScope.expanded, false,
     "The globalScope should not be expanded yet.");
 
   // Wait for only two events to be triggered, because the Function scope is
   // an environment to which scope arguments and variables are already attached.
   waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
     is(localScope.expanded, true,
       "The localScope should now be expanded.");
     is(withScope.expanded, true,
       "The withScope should now be expanded.");
     is(functionScope.expanded, true,
-      "The functionScope should now be expanded.");
+       "The functionScope should now be expanded.");
+    is(globalLexicalScope.expanded, true,
+       "The globalLexicalScope should be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should now be expanded.");
 
     let protoVar = localScope.get("__proto__");
 
     waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
       let constrVar = protoVar.get("constructor");
 
@@ -201,16 +216,17 @@ function prepareVariablesAndProperties()
       constrVar.expand();
     });
 
     protoVar.expand();
   });
 
   withScope.expand();
   functionScope.expand();
+  globalLexicalScope.expand();
   globalScope.expand();
 
   return deferred.promise;
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gPanel = null;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-02.js
@@ -39,29 +39,32 @@ function test() {
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testVariablesAndPropertiesFiltering() {
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
   let protoVar = localScope.get("__proto__");
   let constrVar = protoVar.get("constructor");
   let proto2Var = constrVar.get("__proto__");
   let constr2Var = proto2Var.get("constructor");
 
   function testFiltered() {
     is(localScope.expanded, true,
       "The localScope should be expanded.");
     is(withScope.expanded, true,
       "The withScope should be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalScope should be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should be expanded.");
 
     is(protoVar.expanded, true,
       "The protoVar should be expanded.");
     is(constrVar.expanded, true,
       "The constrVar should be expanded.");
     is(proto2Var.expanded, true,
@@ -70,25 +73,29 @@ function testVariablesAndPropertiesFilte
       "The constr2Var should be expanded.");
 
     is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 1,
       "There should be 1 variable displayed in the local scope.");
     is(withScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be 0 variables displayed in the with scope.");
     is(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be 0 variables displayed in the function scope.");
+    is(globalLexicalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
+      "There should be no variables displayed in the global lexical scope.");
     is(globalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be no variables displayed in the global scope.");
 
     is(localScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 4,
       "There should be 4 properties displayed in the local scope.");
     is(withScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the with scope.");
     is(functionScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the function scope.");
+    is(globalLexicalScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
+      "There should be 0 properties displayed in the global lexical scope.");
     is(globalScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the global scope.");
 
     is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
       "__proto__", "The only inner variable displayed should be '__proto__'");
     is(localScope.target.querySelectorAll(".variables-view-property:not([unmatched]) > .title > .name")[0].getAttribute("value"),
       "constructor", "The first inner property displayed should be 'constructor'");
     is(localScope.target.querySelectorAll(".variables-view-property:not([unmatched]) > .title > .name")[1].getAttribute("value"),
@@ -108,28 +115,31 @@ function testVariablesAndPropertiesFilte
     gSearchBox.doCommand();
     return expanded.then(testFiltered);
   }
 
   function secondFilter() {
     localScope.collapse();
     withScope.collapse();
     functionScope.collapse();
+    globalLexicalScope.collapse();
     globalScope.collapse();
     protoVar.collapse();
     constrVar.collapse();
     proto2Var.collapse();
     constr2Var.collapse();
 
     is(localScope.expanded, false,
       "The localScope should not be expanded.");
     is(withScope.expanded, false,
       "The withScope should not be expanded.");
     is(functionScope.expanded, false,
       "The functionScope should not be expanded.");
+    is(globalLexicalScope.expanded, false,
+      "The globalScope should not be expanded.");
     is(globalScope.expanded, false,
       "The globalScope should not be expanded.");
 
     is(protoVar.expanded, false,
       "The protoVar should not be expanded.");
     is(constrVar.expanded, false,
       "The constrVar should not be expanded.");
     is(proto2Var.expanded, false,
@@ -148,36 +158,41 @@ function testVariablesAndPropertiesFilte
 }
 
 function prepareVariablesAndProperties() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   is(localScope.expanded, true,
     "The localScope should be expanded.");
   is(withScope.expanded, false,
     "The withScope should not be expanded yet.");
   is(functionScope.expanded, false,
     "The functionScope should not be expanded yet.");
+  is(globalLexicalScope.expanded, false,
+    "The globalScope should not be expanded yet.");
   is(globalScope.expanded, false,
     "The globalScope should not be expanded yet.");
 
   // Wait for only two events to be triggered, because the Function scope is
   // an environment to which scope arguments and variables are already attached.
   waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
     is(localScope.expanded, true,
       "The localScope should now be expanded.");
     is(withScope.expanded, true,
       "The withScope should now be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should now be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalScope should now be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should now be expanded.");
 
     let protoVar = localScope.get("__proto__");
 
     waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
       let constrVar = protoVar.get("constructor");
 
@@ -209,16 +224,17 @@ function prepareVariablesAndProperties()
       constrVar.expand();
     });
 
     protoVar.expand();
   });
 
   withScope.expand();
   functionScope.expand();
+  globalLexicalScope.expand();
   globalScope.expand();
 
   return deferred.promise;
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gPanel = null;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-03.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-03.js
@@ -38,67 +38,77 @@ function test() {
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testVariablesAndPropertiesFiltering() {
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   function testFiltered() {
     is(localScope.expanded, true,
       "The localScope should be expanded.");
     is(withScope.expanded, true,
       "The withScope should be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalScope should be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should be expanded.");
 
     is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 1,
       "There should be 1 variable displayed in the local scope.");
     is(withScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be 0 variables displayed in the with scope.");
     is(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be 0 variables displayed in the function scope.");
+    is(globalLexicalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
+      "There should be 0 variables displayed in the global scope.");
     is(globalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length, 0,
       "There should be 0 variables displayed in the global scope.");
 
     is(localScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the local scope.");
     is(withScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the with scope.");
     is(functionScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the function scope.");
+    is(globalLexicalScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
+      "There should be 0 properties displayed in the global scope.");
     is(globalScope.target.querySelectorAll(".variables-view-property:not([unmatched])").length, 0,
       "There should be 0 properties displayed in the global scope.");
   }
 
   function firstFilter() {
     typeText(gSearchBox, "*alpha");
     testFiltered("alpha");
 
     is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
       "alpha", "The only inner variable displayed should be 'alpha'");
   }
 
   function secondFilter() {
     localScope.collapse();
     withScope.collapse();
     functionScope.collapse();
+    globalLexicalScope.collapse();
     globalScope.collapse();
 
     is(localScope.expanded, false,
       "The localScope should not be expanded.");
     is(withScope.expanded, false,
       "The withScope should not be expanded.");
     is(functionScope.expanded, false,
       "The functionScope should not be expanded.");
+    is(globalLexicalScope.expanded, false,
+      "The globalScope should not be expanded.");
     is(globalScope.expanded, false,
       "The globalScope should not be expanded.");
 
     backspaceText(gSearchBox, 6);
     typeText(gSearchBox, "*beta");
     testFiltered("beta");
 
     is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
@@ -110,44 +120,50 @@ function testVariablesAndPropertiesFilte
 }
 
 function prepareVariablesAndProperties() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   is(localScope.expanded, true,
     "The localScope should be expanded.");
   is(withScope.expanded, false,
     "The withScope should not be expanded yet.");
   is(functionScope.expanded, false,
     "The functionScope should not be expanded yet.");
+  is(globalLexicalScope.expanded, false,
+    "The globalScope should not be expanded yet.");
   is(globalScope.expanded, false,
     "The globalScope should not be expanded yet.");
 
   // Wait for only two events to be triggered, because the Function scope is
   // an environment to which scope arguments and variables are already attached.
   waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
     is(localScope.expanded, true,
       "The localScope should now be expanded.");
     is(withScope.expanded, true,
       "The withScope should now be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should now be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalScope should now be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should now be expanded.");
 
     deferred.resolve();
   });
 
   withScope.expand();
   functionScope.expand();
+  globalLexicalScope.expand();
   globalScope.expand();
 
   return deferred.promise;
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gPanel = null;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-04.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-04.js
@@ -39,182 +39,195 @@ function test() {
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testVariablesAndPropertiesFiltering() {
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
   let step = 0;
 
   let tests = [
     function() {
-      assertExpansion([true, false, false, false]);
+      assertExpansion([true, false, false, false, false]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, false, false, false]);
+      assertExpansion([true, false, false, false, false]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, false, false, false]);
+      assertExpansion([true, false, false, false, false]);
       gEditor.focus();
     },
     function() {
-      assertExpansion([true, false, false, false]);
+      assertExpansion([true, false, false, false, false]);
       typeText(gSearchBox, "*");
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       gEditor.focus();
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       backspaceText(gSearchBox, 1);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       gEditor.focus();
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       localScope.collapse();
       withScope.collapse();
       functionScope.collapse();
+      globalLexicalScope.collapse();
       globalScope.collapse();
     },
     function() {
-      assertExpansion([false, false, false, false]);
+      assertExpansion([false, false, false, false, false]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([false, false, false, false]);
+      assertExpansion([false, false, false, false, false]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([false, false, false, false]);
+      assertExpansion([false, false, false, false, false]);
       gEditor.focus();
     },
     function() {
-      assertExpansion([false, false, false, false]);
+      assertExpansion([false, false, false, false, false]);
       clearText(gSearchBox);
       typeText(gSearchBox, "*");
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       gEditor.focus();
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       backspaceText(gSearchBox, 1);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       EventUtils.sendKey("RETURN", gDebugger);
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
       gEditor.focus();
     },
     function() {
-      assertExpansion([true, true, true, true]);
+      assertExpansion([true, true, true, true, true]);
     }
   ];
 
   function assertExpansion(aFlags) {
     is(localScope.expanded, aFlags[0],
       "The localScope should " + (aFlags[0] ? "" : "not ") +
       "be expanded at this point (" + step + ").");
 
     is(withScope.expanded, aFlags[1],
       "The withScope should " + (aFlags[1] ? "" : "not ") +
       "be expanded at this point (" + step + ").");
 
     is(functionScope.expanded, aFlags[2],
       "The functionScope should " + (aFlags[2] ? "" : "not ") +
       "be expanded at this point (" + step + ").");
 
-    is(globalScope.expanded, aFlags[3],
-      "The globalScope should " + (aFlags[3] ? "" : "not ") +
+    is(globalLexicalScope.expanded, aFlags[3],
+      "The globalLexicalScope should " + (aFlags[3] ? "" : "not ") +
+      "be expanded at this point (" + step + ").");
+
+    is(globalScope.expanded, aFlags[4],
+      "The globalScope should " + (aFlags[4] ? "" : "not ") +
       "be expanded at this point (" + step + ").");
 
     step++;
   }
 
   return promise.all(tests.map(f => f()));
 }
 
 function prepareVariablesAndProperties() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   is(localScope.expanded, true,
     "The localScope should be expanded.");
   is(withScope.expanded, false,
     "The withScope should not be expanded yet.");
   is(functionScope.expanded, false,
     "The functionScope should not be expanded yet.");
+  is(globalLexicalScope.expanded, false,
+    "The globalLexicalScope should not be expanded yet.");
   is(globalScope.expanded, false,
     "The globalScope should not be expanded yet.");
 
   // Wait for only two events to be triggered, because the Function scope is
   // an environment to which scope arguments and variables are already attached.
   waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
     is(localScope.expanded, true,
       "The localScope should now be expanded.");
     is(withScope.expanded, true,
       "The withScope should now be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should now be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalLexicalScope should now be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should now be expanded.");
 
     withScope.collapse();
     functionScope.collapse();
+    globalLexicalScope.collapse();
     globalScope.collapse();
 
     deferred.resolve();
   });
 
   withScope.expand();
   functionScope.expand();
+  globalLexicalScope.expand();
   globalScope.expand();
 
   return deferred.promise;
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gPanel = null;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-05.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-05.js
@@ -38,54 +38,55 @@ function test() {
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testVariablesAndPropertiesFiltering() {
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
   let step = 0;
 
   let tests = [
     function() {
-      assertScopeExpansion([true, false, false, false]);
+      assertScopeExpansion([true, false, false, false, false]);
       typeText(gSearchBox, "*arguments");
     },
     function() {
-      assertScopeExpansion([true, true, true, true]);
-      assertVariablesCountAtLeast([0, 0, 1, 0]);
+      assertScopeExpansion([true, true, true, true, true]);
+      assertVariablesCountAtLeast([0, 0, 1, 0, 0]);
 
       is(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
         "arguments", "The arguments pseudoarray should be visible.");
       is(functionScope.get("arguments").expanded, false,
         "The arguments pseudoarray in functionScope should not be expanded.");
 
       backspaceText(gSearchBox, 6);
     },
     function() {
-      assertScopeExpansion([true, true, true, true]);
-      assertVariablesCountAtLeast([0, 0, 1, 1]);
+      assertScopeExpansion([true, true, true, true, true]);
+      assertVariablesCountAtLeast([0, 0, 1, 0, 1]);
 
       is(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
         "arguments", "The arguments pseudoarray should be visible.");
       is(functionScope.get("arguments").expanded, false,
         "The arguments pseudoarray in functionScope should not be expanded.");
 
       is(globalScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
         "EventTarget", "The EventTarget object should be visible.");
       is(globalScope.get("EventTarget").expanded, false,
         "The EventTarget object in globalScope should not be expanded.");
 
       backspaceText(gSearchBox, 2);
     },
     function() {
-      assertScopeExpansion([true, true, true, true]);
-      assertVariablesCountAtLeast([0, 1, 3, 1]);
+      assertScopeExpansion([true, true, true, true, true]);
+      assertVariablesCountAtLeast([0, 1, 3, 0, 1]);
 
       is(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
         "aNumber", "The aNumber param should be visible.");
       is(functionScope.get("aNumber").expanded, false,
         "The aNumber param in functionScope should not be expanded.");
 
       is(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[1].getAttribute("value"),
         "a", "The a variable should be visible.");
@@ -95,18 +96,18 @@ function testVariablesAndPropertiesFilte
       is(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[2].getAttribute("value"),
         "arguments", "The arguments pseudoarray should be visible.");
       is(functionScope.get("arguments").expanded, false,
         "The arguments pseudoarray in functionScope should not be expanded.");
 
       backspaceText(gSearchBox, 1);
     },
     function() {
-      assertScopeExpansion([true, true, true, true]);
-      assertVariablesCountAtLeast([4, 1, 3, 1]);
+      assertScopeExpansion([true, true, true, true, true]);
+      assertVariablesCountAtLeast([4, 1, 3, 0, 1]);
 
       is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[0].getAttribute("value"),
         "this", "The this reference should be visible.");
       is(localScope.get("this").expanded, false,
         "The this reference in localScope should not be expanded.");
 
       is(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched]) > .title > .name")[1].getAttribute("value"),
         "alpha", "The alpha variable should be visible.");
@@ -148,82 +149,97 @@ function testVariablesAndPropertiesFilte
     is(withScope.expanded, aFlags[1],
       "The withScope should " + (aFlags[1] ? "" : "not ") +
        "be expanded at this point (" + step + ").");
 
     is(functionScope.expanded, aFlags[2],
       "The functionScope should " + (aFlags[2] ? "" : "not ") +
        "be expanded at this point (" + step + ").");
 
-    is(globalScope.expanded, aFlags[3],
-      "The globalScope should " + (aFlags[3] ? "" : "not ") +
+    is(globalLexicalScope.expanded, aFlags[3],
+      "The globalLexicalScope should " + (aFlags[3] ? "" : "not ") +
+       "be expanded at this point (" + step + ").");
+
+    is(globalScope.expanded, aFlags[4],
+      "The globalScope should " + (aFlags[4] ? "" : "not ") +
        "be expanded at this point (" + step + ").");
   }
 
   function assertVariablesCountAtLeast(aCounts) {
     ok(localScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length >= aCounts[0],
       "There should be " + aCounts[0] +
       " variable displayed in the local scope (" + step + ").");
 
     ok(withScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length >= aCounts[1],
       "There should be " + aCounts[1] +
       " variable displayed in the with scope (" + step + ").");
 
     ok(functionScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length >= aCounts[2],
       "There should be " + aCounts[2] +
       " variable displayed in the function scope (" + step + ").");
 
-    ok(globalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length >= aCounts[3],
+    ok(globalLexicalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length >= aCounts[3],
       "There should be " + aCounts[3] +
+       " variable displayed in the global scope (" + step + ").");
+
+    ok(globalScope.target.querySelectorAll(".variables-view-variable:not([unmatched])").length >= aCounts[4],
+      "There should be " + aCounts[4] +
       " variable displayed in the global scope (" + step + ").");
 
     step++;
   }
 
   return promise.all(tests.map(f => f()));
 }
 
 function prepareVariablesAndProperties() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   is(localScope.expanded, true,
     "The localScope should be expanded.");
   is(withScope.expanded, false,
     "The withScope should not be expanded yet.");
   is(functionScope.expanded, false,
     "The functionScope should not be expanded yet.");
+  is(globalLexicalScope.expanded, false,
+    "The globalScope should not be expanded yet.");
   is(globalScope.expanded, false,
     "The globalScope should not be expanded yet.");
 
   // Wait for only two events to be triggered, because the Function scope is
   // an environment to which scope arguments and variables are already attached.
   waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
     is(localScope.expanded, true,
       "The localScope should now be expanded.");
     is(withScope.expanded, true,
       "The withScope should now be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should now be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalScope should now be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should now be expanded.");
 
     withScope.collapse();
     functionScope.collapse();
+    globalLexicalScope.collapse();
     globalScope.collapse();
 
     deferred.resolve();
   });
 
   withScope.expand();
   functionScope.expand();
+  globalLexicalScope.expand();
   globalScope.expand();
 
   return deferred.promise;
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gPanel = null;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-01.js
@@ -30,37 +30,45 @@ function test() {
       });
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function initialChecks() {
   let scopeNodes = gDebugger.document.querySelectorAll(".variables-view-scope");
-  is(scopeNodes.length, 2,
-    "There should be 2 scopes available.");
+  is(scopeNodes.length, 3,
+    "There should be 3 scopes available.");
 
   ok(scopeNodes[0].querySelector(".name").getAttribute("value").includes("[test]"),
     "The local scope should be properly identified.");
-  ok(scopeNodes[1].querySelector(".name").getAttribute("value").includes("[Window]"),
+  ok(scopeNodes[1].querySelector(".name").getAttribute("value").includes("Block"),
+    "The global lexical scope should be properly identified.");
+  ok(scopeNodes[2].querySelector(".name").getAttribute("value").includes("[Window]"),
     "The global scope should be properly identified.");
 
   is(gVariables.getScopeAtIndex(0).target, scopeNodes[0],
     "getScopeAtIndex(0) didn't return the expected scope.");
   is(gVariables.getScopeAtIndex(1).target, scopeNodes[1],
     "getScopeAtIndex(1) didn't return the expected scope.");
+  is(gVariables.getScopeAtIndex(2).target, scopeNodes[2],
+    "getScopeAtIndex(2) didn't return the expected scope.");
 
   is(gVariables.getItemForNode(scopeNodes[0]).target, scopeNodes[0],
     "getItemForNode([0]) didn't return the expected scope.");
   is(gVariables.getItemForNode(scopeNodes[1]).target, scopeNodes[1],
     "getItemForNode([1]) didn't return the expected scope.");
+  is(gVariables.getItemForNode(scopeNodes[2]).target, scopeNodes[2],
+    "getItemForNode([2]) didn't return the expected scope.");
 
   is(gVariables.getItemForNode(scopeNodes[0]).expanded, true,
     "The local scope should be expanded by default.");
   is(gVariables.getItemForNode(scopeNodes[1]).expanded, false,
+    "The global lexical scope should not be collapsed by default.");
+  is(gVariables.getItemForNode(scopeNodes[2]).expanded, false,
     "The global scope should not be collapsed by default.");
 }
 
 function testExpandVariables() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let localEnums = localScope.target.querySelector(".variables-view-element-details.enum").childNodes;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-03.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-03.js
@@ -33,31 +33,31 @@ function test() {
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function expandGlobalScope() {
   let deferred = promise.defer();
 
-  let globalScope = gVariables.getScopeAtIndex(1);
+  let globalScope = gVariables.getScopeAtIndex(2);
   is(globalScope.expanded, false,
     "The global scope should not be expanded by default.");
 
   gDebugger.once(gDebugger.EVENTS.FETCHED_VARIABLES, deferred.resolve);
 
   EventUtils.sendMouseEvent({ type: "mousedown" },
     globalScope.target.querySelector(".name"),
     gDebugger);
 
   return deferred.promise;
 }
 
 function testGlobalScope() {
-  let globalScope = gVariables.getScopeAtIndex(1);
+  let globalScope = gVariables.getScopeAtIndex(2);
   is(globalScope.expanded, true,
     "The global scope should now be expanded.");
 
   is(globalScope.get("InstallTrigger").target.querySelector(".name").getAttribute("value"), "InstallTrigger",
     "Should have the right property name for 'InstallTrigger'.");
   is(globalScope.get("InstallTrigger").target.querySelector(".value").getAttribute("value"), "InstallTriggerImpl",
     "Should have the right property value for 'InstallTrigger'.");
 
@@ -87,31 +87,31 @@ function testGlobalScope() {
     "Should have no child enumerable properties for 'undefined'.");
   is(globalScope.get("undefined").target.querySelector(".nonenum").childNodes.length, 0,
     "Should have no child non-enumerable properties for 'undefined'.");
 }
 
 function expandWindowVariable() {
   let deferred = promise.defer();
 
-  let windowVar = gVariables.getScopeAtIndex(1).get("window");
+  let windowVar = gVariables.getScopeAtIndex(2).get("window");
   is(windowVar.expanded, false,
     "The window variable should not be expanded by default.");
 
   gDebugger.once(gDebugger.EVENTS.FETCHED_PROPERTIES, deferred.resolve);
 
   EventUtils.sendMouseEvent({ type: "mousedown" },
     windowVar.target.querySelector(".name"),
     gDebugger);
 
   return deferred.promise;
 }
 
 function testWindowVariable() {
-  let windowVar = gVariables.getScopeAtIndex(1).get("window");
+  let windowVar = gVariables.getScopeAtIndex(2).get("window");
   is(windowVar.expanded, true,
     "The window variable should now be expanded.");
 
   is(windowVar.get("InstallTrigger").target.querySelector(".name").getAttribute("value"), "InstallTrigger",
     "Should have the right property name for 'InstallTrigger'.");
   is(windowVar.get("InstallTrigger").target.querySelector(".value").getAttribute("value"), "InstallTriggerImpl",
     "Should have the right property value for 'InstallTrigger'.");
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-override-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-override-01.js
@@ -16,47 +16,55 @@ function test() {
     let variables = win.DebuggerView.Variables;
 
     callInTab(tab, "test");
     yield waitForSourceAndCaretAndScopes(panel, ".html", 23);
 
     let firstScope = variables.getScopeAtIndex(0);
     let secondScope = variables.getScopeAtIndex(1);
     let thirdScope = variables.getScopeAtIndex(2);
-    let globalScope = variables.getScopeAtIndex(3);
+    let globalLexicalScope = variables.getScopeAtIndex(3);
+    let globalScope = variables.getScopeAtIndex(4);
 
     ok(firstScope, "The first scope is available.");
     ok(secondScope, "The second scope is available.");
     ok(thirdScope, "The third scope is available.");
+    ok(globalLexicalScope, "The global lexical scope is available.");
     ok(globalScope, "The global scope is available.");
 
     is(firstScope.name, "Function scope [secondNest]",
       "The first scope's name is correct.");
     is(secondScope.name, "Function scope [firstNest]",
       "The second scope's name is correct.");
     is(thirdScope.name, "Function scope [test]",
       "The third scope's name is correct.");
+    is(globalLexicalScope.name, "Block scope",
+      "The global lexical scope's name is correct.");
     is(globalScope.name, "Global scope [Window]",
       "The global scope's name is correct.");
 
     is(firstScope.expanded, true,
       "The first scope's expansion state is correct.");
     is(secondScope.expanded, false,
       "The second scope's expansion state is correct.");
     is(thirdScope.expanded, false,
       "The third scope's expansion state is correct.");
+    is(globalLexicalScope.expanded, false,
+      "The global lexical scope's expansion state is correct.");
     is(globalScope.expanded, false,
       "The global scope's expansion state is correct.");
 
     is(firstScope._store.size, 3,
       "The first scope should have all the variables available.");
     is(secondScope._store.size, 0,
       "The second scope should have no variables available yet.");
     is(thirdScope._store.size, 0,
       "The third scope should have no variables available yet.");
+    is(globalLexicalScope._store.size, 0,
+      "The global scope should have no variables available yet.");
     is(globalScope._store.size, 0,
       "The global scope should have no variables available yet.");
 
     // Test getOwnerScopeForVariableOrProperty with simple variables.
 
     let thisVar = firstScope.get("this");
     let thisOwner = variables.getOwnerScopeForVariableOrProperty(thisVar);
     is(thisOwner, firstScope,
@@ -95,16 +103,17 @@ function test() {
     // from non-topmost scopes.
 
     // Only need to wait for a single FETCHED_VARIABLES event, just for the
     // global scope, because the other local scopes already have the
     // arguments and variables available as evironment bindings.
     fetched = waitForDebuggerEvents(panel, events.FETCHED_VARIABLES);
     secondScope.expand();
     thirdScope.expand();
+    globalLexicalScope.expand();
     globalScope.expand();
     yield fetched;
 
     let someVar2 = secondScope.get("a");
     let someOwner2 = variables.getOwnerScopeForVariableOrProperty(someVar2);
     is(someOwner2, secondScope,
       "The getOwnerScopeForVariableOrProperty method works properly (5).");
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-16.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-16.js
@@ -37,17 +37,17 @@ function test() {
         ok(isDebugPos(panel, debugLine), "Editor debug location is correct.");
         deferred.resolve();
       });
 
       return deferred.promise;
     }
 
     function expandGlobalScope() {
-      let globalScope = variables.getScopeAtIndex(1);
+      let globalScope = variables.getScopeAtIndex(2);
       is(globalScope.expanded, false,
         "The globalScope should not be expanded yet.");
 
       let finished = waitForDebuggerEvents(panel, events.FETCHED_VARIABLES);
       globalScope.expand();
       return finished;
     }
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-reexpand-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-reexpand-01.js
@@ -69,87 +69,99 @@ function stepInDebuggee() {
     waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1),
   ]);
 }
 
 function testVariablesExpand() {
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   let thisVar = localScope.get("this");
   let windowVar = thisVar.get("window");
 
   is(localScope.target.querySelector(".arrow").hasAttribute("open"), true,
     "The localScope arrow should still be expanded.");
   is(withScope.target.querySelector(".arrow").hasAttribute("open"), true,
     "The withScope arrow should still be expanded.");
   is(functionScope.target.querySelector(".arrow").hasAttribute("open"), true,
     "The functionScope arrow should still be expanded.");
+  is(globalLexicalScope.target.querySelector(".arrow").hasAttribute("open"), true,
+    "The globalLexicalScope arrow should still be expanded.");
   is(globalScope.target.querySelector(".arrow").hasAttribute("open"), true,
     "The globalScope arrow should still be expanded.");
   is(thisVar.target.querySelector(".arrow").hasAttribute("open"), true,
     "The thisVar arrow should still be expanded.");
   is(windowVar.target.querySelector(".arrow").hasAttribute("open"), false,
     "The windowVar arrow should not be expanded.");
 
   is(localScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The localScope enumerables should still be expanded.");
   is(withScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The withScope enumerables should still be expanded.");
   is(functionScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The functionScope enumerables should still be expanded.");
+  is(globalLexicalScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
+    "The globalLexicalScope enumerables should still be expanded.");
   is(globalScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The globalScope enumerables should still be expanded.");
   is(thisVar.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The thisVar enumerables should still be expanded.");
   is(windowVar.target.querySelector(".variables-view-element-details").hasAttribute("open"), false,
     "The windowVar enumerables should not be expanded.");
 
   is(localScope.expanded, true,
     "The localScope expanded getter should return true.");
   is(withScope.expanded, true,
     "The withScope expanded getter should return true.");
   is(functionScope.expanded, true,
     "The functionScope expanded getter should return true.");
+  is(globalLexicalScope.expanded, true,
+    "The globalScope expanded getter should return true.");
   is(globalScope.expanded, true,
     "The globalScope expanded getter should return true.");
   is(thisVar.expanded, true,
     "The thisVar expanded getter should return true.");
   is(windowVar.expanded, false,
     "The windowVar expanded getter should return true.");
 }
 
 function prepareVariablesAndProperties() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   is(localScope.expanded, true,
     "The localScope should be expanded.");
   is(withScope.expanded, false,
     "The withScope should not be expanded yet.");
   is(functionScope.expanded, false,
     "The functionScope should not be expanded yet.");
+  is(globalLexicalScope.expanded, false,
+    "The globalLexicalScope should not be expanded yet.");
   is(globalScope.expanded, false,
     "The globalScope should not be expanded yet.");
 
   // Wait for only two events to be triggered, because the Function scope is
   // an environment to which scope arguments and variables are already attached.
   waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
     is(localScope.expanded, true,
       "The localScope should now be expanded.");
     is(withScope.expanded, true,
       "The withScope should now be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should now be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalLexicalScope should now be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should now be expanded.");
 
     let thisVar = localScope.get("this");
 
     waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
       let windowVar = thisVar.get("window");
 
@@ -181,16 +193,17 @@ function prepareVariablesAndProperties()
       windowVar.expand();
     });
 
     thisVar.expand();
   });
 
   withScope.expand();
   functionScope.expand();
+  globalLexicalScope.expand();
   globalScope.expand();
 
   return deferred.promise;
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gPanel = null;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-reexpand-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-reexpand-02.js
@@ -70,29 +70,32 @@ function stepInDebuggee() {
     waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 4),
   ]);
 }
 
 function testVariablesExpand() {
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   let thisVar = localScope.get("this");
   let windowVar = thisVar.get("window");
   let documentVar = windowVar.get("document");
   let locationVar = documentVar.get("location");
 
   is(localScope.target.querySelector(".arrow").hasAttribute("open"), true,
     "The localScope arrow should still be expanded.");
   is(withScope.target.querySelector(".arrow").hasAttribute("open"), true,
     "The withScope arrow should still be expanded.");
   is(functionScope.target.querySelector(".arrow").hasAttribute("open"), true,
     "The functionScope arrow should still be expanded.");
+  is(globalLexicalScope.target.querySelector(".arrow").hasAttribute("open"), true,
+    "The globalLexicalScope arrow should still be expanded.");
   is(globalScope.target.querySelector(".arrow").hasAttribute("open"), true,
     "The globalScope arrow should still be expanded.");
   is(thisVar.target.querySelector(".arrow").hasAttribute("open"), true,
     "The thisVar arrow should still be expanded.");
   is(windowVar.target.querySelector(".arrow").hasAttribute("open"), true,
     "The windowVar arrow should still be expanded.");
   is(documentVar.target.querySelector(".arrow").hasAttribute("open"), true,
     "The documentVar arrow should still be expanded.");
@@ -100,16 +103,18 @@ function testVariablesExpand() {
     "The locationVar arrow should still be expanded.");
 
   is(localScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The localScope enumerables should still be expanded.");
   is(withScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The withScope enumerables should still be expanded.");
   is(functionScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The functionScope enumerables should still be expanded.");
+  is(globalLexicalScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
+    "The globalLexicalScope enumerables should still be expanded.");
   is(globalScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The globalScope enumerables should still be expanded.");
   is(thisVar.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The thisVar enumerables should still be expanded.");
   is(windowVar.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The windowVar enumerables should still be expanded.");
   is(documentVar.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
     "The documentVar enumerables should still be expanded.");
@@ -117,16 +122,18 @@ function testVariablesExpand() {
     "The locationVar enumerables should still be expanded.");
 
   is(localScope.expanded, true,
     "The localScope expanded getter should return true.");
   is(withScope.expanded, true,
     "The withScope expanded getter should return true.");
   is(functionScope.expanded, true,
     "The functionScope expanded getter should return true.");
+  is(globalLexicalScope.expanded, true,
+    "The globalLexicalScope expanded getter should return true.");
   is(globalScope.expanded, true,
     "The globalScope expanded getter should return true.");
   is(thisVar.expanded, true,
     "The thisVar expanded getter should return true.");
   is(windowVar.expanded, true,
     "The windowVar expanded getter should return true.");
   is(documentVar.expanded, true,
     "The documentVar expanded getter should return true.");
@@ -135,36 +142,41 @@ function testVariablesExpand() {
 }
 
 function prepareVariablesAndProperties() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
-  let globalScope = gVariables.getScopeAtIndex(3);
+  let globalLexicalScope = gVariables.getScopeAtIndex(3);
+  let globalScope = gVariables.getScopeAtIndex(4);
 
   is(localScope.expanded, true,
     "The localScope should be expanded.");
   is(withScope.expanded, false,
     "The withScope should not be expanded yet.");
   is(functionScope.expanded, false,
     "The functionScope should not be expanded yet.");
+  is(globalLexicalScope.expanded, false,
+    "The globalLexicalScope should not be expanded yet.");
   is(globalScope.expanded, false,
     "The globalScope should not be expanded yet.");
 
   // Wait for only two events to be triggered, because the Function scope is
   // an environment to which scope arguments and variables are already attached.
   waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
     is(localScope.expanded, true,
       "The localScope should now be expanded.");
     is(withScope.expanded, true,
       "The withScope should now be expanded.");
     is(functionScope.expanded, true,
       "The functionScope should now be expanded.");
+    is(globalLexicalScope.expanded, true,
+      "The globalLexicalScope should now be expanded.");
     is(globalScope.expanded, true,
       "The globalScope should now be expanded.");
 
     let thisVar = localScope.get("this");
 
     waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
       let windowVar = thisVar.get("window");
 
@@ -196,16 +208,17 @@ function prepareVariablesAndProperties()
       windowVar.expand();
     });
 
     thisVar.expand();
   });
 
   withScope.expand();
   functionScope.expand();
+  globalLexicalScope.expand();
   globalScope.expand();
 
   return deferred.promise;
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gPanel = null;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-webidl.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-webidl.js
@@ -31,32 +31,32 @@ function test() {
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function expandGlobalScope() {
   let deferred = promise.defer();
 
-  let globalScope = gVariables.getScopeAtIndex(1);
+  let globalScope = gVariables.getScopeAtIndex(2);
   is(globalScope.expanded, false,
     "The global scope should not be expanded by default.");
 
   gDebugger.once(gDebugger.EVENTS.FETCHED_VARIABLES, deferred.resolve);
 
   EventUtils.sendMouseEvent({ type: "mousedown" },
     globalScope.target.querySelector(".name"),
     gDebugger);
 
   return deferred.promise;
 }
 
 function performTest() {
   let deferred = promise.defer();
-  let globalScope = gVariables.getScopeAtIndex(1);
+  let globalScope = gVariables.getScopeAtIndex(2);
 
   let buttonVar = globalScope.get("button");
   let buttonAsProtoVar = globalScope.get("buttonAsProto");
   let documentVar = globalScope.get("document");
 
   is(buttonVar.target.querySelector(".name").getAttribute("value"), "button",
     "Should have the right property name for 'button'.");
   is(buttonVar.target.querySelector(".value").getAttribute("value"), "<button>",
--- a/devtools/client/debugger/test/mochitest/code_frame-script.js
+++ b/devtools/client/debugger/test/mochitest/code_frame-script.js
@@ -1,11 +1,11 @@
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 const { loadSubScript } = Cc['@mozilla.org/moz/jssubscript-loader;1'].
                           getService(Ci.mozIJSSubScriptLoader);
 
 const EventUtils = {};
 loadSubScript("chrome://marionette/content/EventUtils.js", EventUtils);
 
 dump("Frame script loaded.\n");
 
--- a/devtools/client/debugger/test/mochitest/doc_function-search.html
+++ b/devtools/client/debugger/test/mochitest/doc_function-search.html
@@ -12,19 +12,19 @@
     <p>Peanut butter jelly time!</p>
 
     <script type="text/javascript" src="code_function-search-01.js"></script>
     <script type="text/javascript" src="code_function-search-02.js"></script>
     <script type="text/javascript" src="code_function-search-03.js"></script>
 
     <script type="text/javascript;version=1.8">
       function inline() {}
-      let arrow = () => {}
+      var arrow = () => {}
 
-      let foo = bar => {}
-      let foo2 = bar2 = baz2 => 42;
+      var foo = bar => {}
+      var foo2 = bar2 = baz2 => 42;
 
       setTimeout((foo, bar, baz) => {});
       setTimeout((foo, bar, baz) => 42);
     </script>
   </body>
 
 </html>
--- a/devtools/client/debugger/test/mochitest/head.js
+++ b/devtools/client/debugger/test/mochitest/head.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 
 // Disable logging for faster test runs. Set this pref to true if you want to
 // debug a test in your try runs. Both the debugger server and frontend will
 // be affected by this pref.
 var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
 Services.prefs.setBoolPref("devtools.debugger.log", false);
--- a/devtools/client/debugger/utils.js
+++ b/devtools/client/debugger/utils.js
@@ -1,14 +1,14 @@
 /* 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/. */
 "use strict";
 
-const XULUtils = {
+var XULUtils = {
   /**
    * Create <command> elements within `commandset` with event handlers
    * bound to the `command` event
    *
    * @param commandset HTML Element
    *        A <commandset> element
    * @param commands Object
    *        An object where keys specify <command> ids and values
@@ -30,17 +30,17 @@ const XULUtils = {
 // Used to detect minification for automatic pretty printing
 const SAMPLE_SIZE = 50; // no of lines
 const INDENT_COUNT_THRESHOLD = 5; // percentage
 const CHARACTER_LIMIT = 250; // line character limit
 
 /**
  * Utility functions for handling sources.
  */
-const SourceUtils = {
+var SourceUtils = {
   _labelsCache: new Map(), // Can't use WeakMaps because keys are strings.
   _groupsCache: new Map(),
   _minifiedCache: new WeakMap(),
 
   /**
    * Returns true if the specified url and/or content type are specific to
    * javascript files.
    *
--- a/devtools/client/fontinspector/font-inspector.js
+++ b/devtools/client/fontinspector/font-inspector.js
@@ -1,17 +1,17 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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/. */
 
 "use strict";
 
-const { utils: Cu } = Components;
+var { utils: Cu } = Components;
 const DEFAULT_PREVIEW_TEXT = "Abc";
 const PREVIEW_UPDATE_DELAY = 150;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
   "resource://gre/modules/Task.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "console",
   "resource://gre/modules/devtools/shared/Console.jsm");
--- a/devtools/client/framework/connect/connect.js
+++ b/devtools/client/framework/connect/connect.js
@@ -1,17 +1,17 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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/. */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 var {gDevTools} = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var {TargetFactory} = require("devtools/client/framework/target");
 var {Toolbox} = require("devtools/client/framework/toolbox")
 var promise = require("promise");
--- a/devtools/client/framework/test/shared-head.js
+++ b/devtools/client/framework/test/shared-head.js
@@ -1,15 +1,15 @@
 /* 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/. */
 
 // This shared-head.js file is used for multiple directories in devtools.
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 function scopedCuImport(path) {
   const scope = {};
   Cu.import(path, scope);
   return scope;
 }
 
 const {Services} = scopedCuImport("resource://gre/modules/Services.jsm");
--- a/devtools/client/framework/toolbox-process-window.js
+++ b/devtools/client/framework/toolbox-process-window.js
@@ -1,14 +1,14 @@
 /* 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/. */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 var { gDevTools } = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 var { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var { TargetFactory } = require("devtools/client/framework/target");
 var { Toolbox } = require("devtools/client/framework/toolbox");
 var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 var { DebuggerClient } = require("devtools/shared/client/main");
 var { ViewHelpers } =
--- a/devtools/client/inspector/inspector-panel.js
+++ b/devtools/client/inspector/inspector-panel.js
@@ -983,23 +983,23 @@ InspectorPanel.prototype = {
    * temp variable on the content window.  Also opens the split console and
    * autofills it with the temp variable.
    */
   useInConsole: function() {
     this._toolbox.openSplitConsole().then(() => {
       let panel = this._toolbox.getPanel("webconsole");
       let jsterm = panel.hud.jsterm;
 
-      let evalString = `let i = 0;
+      let evalString = `{ let i = 0;
         while (window.hasOwnProperty("temp" + i) && i < 1000) {
           i++;
         }
         window["temp" + i] = $0;
         "temp" + i;
-      `;
+      }`;
 
       let options = {
         selectedNodeActor: this.selection.nodeFront.actorID,
       };
       jsterm.requestEvaluation(evalString, options).then((res) => {
         jsterm.setInputValue(res.result);
         this.emit("console-var-ready");
       });
--- a/devtools/client/inspector/test/head.js
+++ b/devtools/client/inspector/test/head.js
@@ -1,18 +1,18 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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/. */
 "use strict";
 
-const Cu = Components.utils;
-const Ci = Components.interfaces;
-const Cc = Components.classes;
-const CC = Components.Constructor;
+var Cu = Components.utils;
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+var CC = Components.Constructor;
 
 // Services.prefs.setBoolPref("devtools.debugger.log", true);
 // SimpleTest.registerCleanupFunction(() => {
 //   Services.prefs.clearUserPref("devtools.debugger.log");
 // });
 
 // Uncomment this pref to dump all devtools emitted events to the console.
 // Services.prefs.setBoolPref("devtools.dump.emit", true);
--- a/devtools/client/layoutview/test/head.js
+++ b/devtools/client/layoutview/test/head.js
@@ -1,15 +1,15 @@
 /* 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/ */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 var {gDevTools} = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var {console} = Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
 var {TargetFactory} = require("devtools/client/framework/target");
 var promise = require("promise");
 var DevToolsUtils = require("devtools/shared/DevToolsUtils");
 
 // All test are asynchronous
--- a/devtools/client/layoutview/view.js
+++ b/devtools/client/layoutview/view.js
@@ -1,17 +1,17 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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/. */
 
 "use strict";
 
-const {utils: Cu, interfaces: Ci, classes: Cc} = Components;
+var {utils: Cu, interfaces: Ci, classes: Cc} = Components;
 
 Cu.import("resource://gre/modules/Task.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 Cu.import("resource://gre/modules/devtools/shared/Console.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
 
 const {InplaceEditor, editableItem} = require("devtools/client/shared/inplace-editor");
 const {ReflowFront} = require("devtools/server/actors/layout");
--- a/devtools/client/markupview/test/actor_events_form.js
+++ b/devtools/client/markupview/test/actor_events_form.js
@@ -9,17 +9,17 @@
 
 const Events = require("sdk/event/core");
 const {ActorClass, Actor, FrontClass, Front, method} =
   require("devtools/server/protocol");
 
 const {Cu} = require("chrome");
 const {NodeActor} = require("devtools/server/actors/inspector");
 
-const EventsFormActor = ActorClass({
+var EventsFormActor = ActorClass({
   typeName: "eventsFormActor",
 
   initialize: function() {
     Actor.prototype.initialize.apply(this, arguments);
   },
 
   attach: method(function() {
     Events.on(NodeActor, "form", this.onNodeActorForm);
@@ -39,17 +39,17 @@ const EventsFormActor = ActorClass({
     let nodeActor = event.target;
     if (nodeActor.rawNode.id == "container") {
       let form = event.data;
       form.setFormProperty("test-property", "test-value");
     }
   }
 });
 
-const EventsFormFront = FrontClass(EventsFormActor, {
+var EventsFormFront = FrontClass(EventsFormActor, {
   initialize: function(client, form) {
     Front.prototype.initialize.apply(this, arguments);
 
     this.actorID = form[EventsFormActor.prototype.typeName];
     this.manage(this);
   }
 });
 
--- a/devtools/client/markupview/test/frame-script-utils.js
+++ b/devtools/client/markupview/test/frame-script-utils.js
@@ -1,15 +1,15 @@
 /* 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/. */
 
 "use strict";
 
-const {classes: Cc, interfaces: Ci} = Components;
+var {classes: Cc, interfaces: Ci} = Components;
 const subScriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
                           .getService(Ci.mozIJSSubScriptLoader);
 var EventUtils = {};
 subScriptLoader.loadSubScript("chrome://marionette/content/EventUtils.js", EventUtils);
 
 /**
  * Synthesize a mouse event on an element. This handler doesn't send a message
  * back. Consumers should listen to specific events on the inspector/highlighter
--- a/devtools/client/markupview/test/head.js
+++ b/devtools/client/markupview/test/head.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var {TargetFactory} = require("devtools/client/framework/target");
 var {console} = Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
 var promise = require("promise");
 var {getInplaceEditorForSpan: inplaceEditor} = require("devtools/client/shared/inplace-editor");
 var clipboard = require("sdk/clipboard");
 var {setTimeout, clearTimeout} = require("sdk/timers");
 var {promiseInvoke} = require("devtools/shared/async-utils");
--- a/devtools/client/memory/initializer.js
+++ b/devtools/client/memory/initializer.js
@@ -1,22 +1,22 @@
 /* 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/. */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 const { require } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
 const { Task } = require("resource://gre/modules/Task.jsm");
 const { MemoryController } = require("devtools/client/memory/controller");
 
 /**
  * The current target, toolbox and MemoryFront, set by this tool's host.
  */
-let gToolbox, gTarget, gFront;
+var gToolbox, gTarget, gFront;
 
 /**
  * Initializes the profiler controller and views.
  */
 var controller = null;
 function initialize () {
   return Task.spawn(function *() {
     controller = new MemoryController({ toolbox: gToolbox, target: gTarget, front: gFront });
--- a/devtools/client/memory/test/mochitest/head.js
+++ b/devtools/client/memory/test/mochitest/head.js
@@ -1,12 +1,12 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-const CC = Components.Constructor;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
+var CC = Components.Constructor;
 
 const { require } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
--- a/devtools/client/memory/test/unit/test_action-take-snapshot.js
+++ b/devtools/client/memory/test/unit/test_action-take-snapshot.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Tests the async action creator `takeSnapshot(front)`
  */
 
-let actions = require("devtools/client/memory/actions/snapshot");
+var actions = require("devtools/client/memory/actions/snapshot");
 
 function run_test() {
   run_next_test();
 }
 
 add_task(function *() {
   let front = new StubbedMemoryFront();
   yield front.attach();
--- a/devtools/client/netmonitor/netmonitor-controller.js
+++ b/devtools/client/netmonitor/netmonitor-controller.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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/. */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 const NET_STRINGS_URI = "chrome://browser/locale/devtools/netmonitor.properties";
 const PKI_STRINGS_URI = "chrome://pippki/locale/pippki.properties";
 const LISTENERS = [ "NetworkActivity" ];
 const NET_PREFS = { "NetworkMonitor.saveRequestAndResponseBodies": true };
 
 // The panel's window global is an EventEmitter firing the following events:
 const EVENTS = {
@@ -120,16 +120,20 @@ Cu.import("resource:///modules/devtools/
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const promise = require("promise");
 const EventEmitter = require("devtools/shared/event-emitter");
 const Editor = require("devtools/client/sourceeditor/editor");
 const {Tooltip} = require("devtools/client/shared/widgets/Tooltip");
 const {ToolSidebar} = require("devtools/client/framework/sidebar");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
 
+XPCOMUtils.defineConstant(this, "EVENTS", EVENTS);
+XPCOMUtils.defineConstant(this, "ACTIVITY_TYPE", ACTIVITY_TYPE);
+XPCOMUtils.defineConstant(this, "Editor", Editor);
+
 XPCOMUtils.defineLazyModuleGetter(this, "Chart",
   "resource:///modules/devtools/client/shared/widgets/Chart.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Curl",
   "resource:///modules/devtools/client/shared/Curl.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "CurlUtils",
   "resource:///modules/devtools/client/shared/Curl.jsm");
--- a/devtools/client/netmonitor/test/head.js
+++ b/devtools/client/netmonitor/test/head.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 var { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
 var { gDevTools } = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 var { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var { CurlUtils } = Cu.import("resource:///modules/devtools/client/shared/Curl.jsm", {});
 var promise = require("promise");
 var NetworkHelper = require("devtools/shared/webconsole/network-helper");
--- a/devtools/client/performance/performance-controller.js
+++ b/devtools/client/performance/performance-controller.js
@@ -1,21 +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/. */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 const { loader, require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 const { Task } = require("resource://gre/modules/Task.jsm");
 const { Heritage, ViewHelpers, WidgetMethods } = require("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
 
 // Events emitted by various objects in the panel.
 const EVENTS = require("devtools/client/performance/events");
+Object.defineProperty(this, "EVENTS", {
+  value: EVENTS,
+  enumerable: true,
+  writable: false
+});
 
 loader.lazyRequireGetter(this, "Services");
 loader.lazyRequireGetter(this, "promise");
 loader.lazyRequireGetter(this, "EventEmitter",
   "devtools/shared/event-emitter");
 loader.lazyRequireGetter(this, "DevToolsUtils",
   "devtools/shared/DevToolsUtils");
 loader.lazyRequireGetter(this, "system",
--- a/devtools/client/performance/test/browser_perf-private-browsing.js
+++ b/devtools/client/performance/test/browser_perf-private-browsing.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Tests that disables the frontend when in private browsing mode.
  */
 
-let gPanelWinTuples = [];
+var gPanelWinTuples = [];
 
 function* spawnTest() {
   yield testNormalWindow();
   yield testPrivateWindow();
   yield testRecordingFailingInWindow(0);
   yield testRecordingFailingInWindow(1);
   yield teardownPerfInWindow(1);
   yield testRecordingSucceedingInWindow(0);
--- a/devtools/client/performance/test/head.js
+++ b/devtools/client/performance/test/head.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 var { Preferences } = Cu.import("resource://gre/modules/Preferences.jsm", {});
 var { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
 var { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var { gDevTools } = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 var { console } = require("resource://gre/modules/devtools/shared/Console.jsm");
 var { TargetFactory } = require("devtools/client/framework/target");
@@ -42,16 +42,19 @@ const ALLOCATIONS_PREF = "devtools.perfo
 const PLATFORM_DATA_PREF = "devtools.performance.ui.show-platform-data";
 const IDLE_PREF = "devtools.performance.ui.show-idle-blocks";
 const INVERT_PREF = "devtools.performance.ui.invert-call-tree";
 const INVERT_FLAME_PREF = "devtools.performance.ui.invert-flame-graph";
 const FLATTEN_PREF = "devtools.performance.ui.flatten-tree-recursion";
 const JIT_PREF = "devtools.performance.ui.enable-jit-optimizations";
 const EXPERIMENTAL_PREF = "devtools.performance.ui.experimental";
 
+// Keep in sync with FRAMERATE_GRAPH_HIGH_RES_INTERVAL in views/overview.js
+const FRAMERATE_GRAPH_HIGH_RES_INTERVAL = 16; // ms
+
 // All tests are asynchronous.
 waitForExplicitFinish();
 
 DevToolsUtils.testing = true;
 
 var DEFAULT_PREFS = [
   "devtools.debugger.log",
   "devtools.performance.ui.invert-call-tree",
@@ -418,17 +421,17 @@ function* stopRecording(panel, options =
     : Promise.resolve();
 
   yield hasStopped;
 
   // Wait for the final rendering of the overview, not a low res
   // incremental rendering and less likely to be from another rendering that was selected
   while (!overviewRendered && options.waitForOverview) {
     let [_, res] = yield onceSpread(win.OverviewView, win.EVENTS.OVERVIEW_RENDERED);
-    if (res === win.FRAMERATE_GRAPH_HIGH_RES_INTERVAL) {
+    if (res === FRAMERATE_GRAPH_HIGH_RES_INTERVAL) {
       overviewRendered = true;
     }
   }
 
   yield stateChanged;
 
   is(win.PerformanceView.getState(), "recorded",
     "The current state is 'recorded'.");
--- a/devtools/client/performance/test/unit/head.js
+++ b/devtools/client/performance/test/unit/head.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 var { console } = require("resource://gre/modules/devtools/shared/Console.jsm");
 const RecordingUtils = require("devtools/shared/performance/utils");
 
 const PLATFORM_DATA_PREF = "devtools.performance.ui.show-platform-data";
 
--- a/devtools/client/performance/views/overview.js
+++ b/devtools/client/performance/views/overview.js
@@ -14,17 +14,17 @@ const GRAPH_REQUIREMENTS = {
     features: ["withMarkers"]
   },
   framerate: {
     features: ["withTicks"]
   },
   memory: {
     features: ["withMemory"]
   },
-}
+};
 
 /**
  * View handler for the overview panel's time view, displaying
  * framerate, timeline and memory over time.
  */
 var OverviewView = {
 
   /**
--- a/devtools/client/projecteditor/chrome/content/projecteditor-loader.js
+++ b/devtools/client/projecteditor/chrome/content/projecteditor-loader.js
@@ -1,9 +1,9 @@
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {});
 const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {});
 const promise = require("promise");
 const ProjectEditor = require("devtools/client/projecteditor/lib/projecteditor");
 
 const SAMPLE_PATH = buildTempDirectoryStructure();
 const SAMPLE_NAME = "DevTools Content Application Name";
--- a/devtools/client/projecteditor/test/head.js
+++ b/devtools/client/projecteditor/test/head.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {TargetFactory} = require("devtools/client/framework/target");
 const {console} = Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
 const promise = require("promise");
 const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {});
 const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {});
 const ProjectEditor = require("devtools/client/projecteditor/lib/projecteditor");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
--- a/devtools/client/promisedebugger/promise-controller.js
+++ b/devtools/client/promisedebugger/promise-controller.js
@@ -3,17 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* global PromisesPanel */
 
 "use strict";
 
-const { utils: Cu } = Components;
+var { utils: Cu } = Components;
 const { loader, require } =
   Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 const { Task } = require("resource://gre/modules/Task.jsm");
 
 loader.lazyRequireGetter(this, "promise");
 loader.lazyRequireGetter(this, "EventEmitter",
   "devtools/shared/event-emitter");
--- a/devtools/client/responsivedesign/responsivedesign-child.js
+++ b/devtools/client/responsivedesign/responsivedesign-child.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Ci = Components.interfaces;
+var Ci = Components.interfaces;
 const gDeviceSizeWasPageSize = docShell.deviceSizeIsPageSize;
 const gFloatingScrollbarsStylesheet = Services.io.newURI("chrome://devtools/skin/themes/floating-scrollbars.css", null, null);
 var gRequiresFloatingScrollbars;
 
 var active = false;
 
 addMessageListener("ResponsiveMode:Start", startResponsiveMode);
 addMessageListener("ResponsiveMode:Stop", stopResponsiveMode);
--- a/devtools/client/responsivedesign/test/head.js
+++ b/devtools/client/responsivedesign/test/head.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-var {require} = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
+var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var {TargetFactory} = require("devtools/client/framework/target");
 var DevToolsUtils = require("devtools/shared/DevToolsUtils");
 var promise = require("promise");
 
 // Import the GCLI test helper
 var testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
 Services.scriptloader.loadSubScript(testDir + "../../../commandline/test/helpers.js", this);
 
--- a/devtools/client/scratchpad/scratchpad.js
+++ b/devtools/client/scratchpad/scratchpad.js
@@ -9,19 +9,19 @@
  *
  * Copied and relicensed from the Public Domain.
  * See bug 653934 for details.
  * https://bugzilla.mozilla.org/show_bug.cgi?id=653934
  */
 
 "use strict";
 
-const Cu = Components.utils;
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
 const SCRATCHPAD_CONTEXT_CONTENT = 1;
 const SCRATCHPAD_CONTEXT_BROWSER = 2;
 const BUTTON_POSITION_SAVE       = 0;
 const BUTTON_POSITION_CANCEL     = 1;
 const BUTTON_POSITION_DONT_SAVE  = 2;
 const BUTTON_POSITION_REVERT     = 0;
 const EVAL_FUNCTION_TIMEOUT      = 1000; // milliseconds
@@ -58,16 +58,23 @@ Cu.import("resource://gre/modules/Servic
 Cu.import("resource://gre/modules/NetUtil.jsm");
 Cu.import("resource:///modules/devtools/client/scratchpad/scratchpad-manager.jsm");
 Cu.import("resource://gre/modules/jsdebugger.jsm");
 Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm");
 Cu.import("resource://gre/modules/osfile.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
 Cu.import("resource://gre/modules/reflect.jsm");
 
+XPCOMUtils.defineConstant(this, "SCRATCHPAD_CONTEXT_CONTENT", SCRATCHPAD_CONTEXT_CONTENT);
+XPCOMUtils.defineConstant(this, "SCRATCHPAD_CONTEXT_BROWSER", SCRATCHPAD_CONTEXT_BROWSER);
+XPCOMUtils.defineConstant(this, "BUTTON_POSITION_SAVE", BUTTON_POSITION_SAVE);
+XPCOMUtils.defineConstant(this, "BUTTON_POSITION_CANCEL", BUTTON_POSITION_CANCEL);
+XPCOMUtils.defineConstant(this, "BUTTON_POSITION_DONT_SAVE", BUTTON_POSITION_DONT_SAVE);
+XPCOMUtils.defineConstant(this, "BUTTON_POSITION_REVERT", BUTTON_POSITION_REVERT);
+
 XPCOMUtils.defineLazyModuleGetter(this, "VariablesView",
   "resource:///modules/devtools/client/shared/widgets/VariablesView.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "VariablesViewController",
   "resource:///modules/devtools/client/shared/widgets/VariablesViewController.jsm");
 
 loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
 
--- a/devtools/client/scratchpad/test/browser_scratchpad_files.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_files.js
@@ -1,16 +1,12 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-var tempScope = {};
-Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
-var NetUtil = tempScope.NetUtil;
-
 // Reference to the Scratchpad object.
 var gScratchpad;
 
 // Reference to the temporary nsIFile we will work with.
 var gFile;
 
 // The temporary file content.
 var gFileContent = "hello.world('bug636725');";
--- a/devtools/client/scratchpad/test/browser_scratchpad_modeline.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_modeline.js
@@ -1,20 +1,13 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 /* Bug 644413 */
 
-var tempScope = {};
-Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
-Cu.import("resource://gre/modules/FileUtils.jsm", tempScope);
-var NetUtil = tempScope.NetUtil;
-var FileUtils = tempScope.FileUtils;
-
-
 var gScratchpad; // Reference to the Scratchpad object.
 var gFile; // Reference to the temporary nsIFile we will work with.
 var DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
 
 // The temporary file content.
 var gFileContent = "function main() { return 0; }";
 
 function test() {
--- a/devtools/client/scratchpad/test/browser_scratchpad_recent_files.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_recent_files.js
@@ -1,19 +1,13 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 /* Bug 651942 */
 
-var tempScope = {};
-Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
-Cu.import("resource://gre/modules/FileUtils.jsm", tempScope);
-var NetUtil = tempScope.NetUtil;
-var FileUtils = tempScope.FileUtils;
-
 // Reference to the Scratchpad object.
 var gScratchpad;
 
 // References to the temporary nsIFiles.
 var gFile01;
 var gFile02;
 var gFile03;
 var gFile04;
--- a/devtools/client/scratchpad/test/browser_scratchpad_reset_undo.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_reset_undo.js
@@ -1,19 +1,13 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 /* Bug 684546 */
 
-var tempScope = {};
-Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
-Cu.import("resource://gre/modules/FileUtils.jsm", tempScope);
-var NetUtil = tempScope.NetUtil;
-var FileUtils = tempScope.FileUtils;
-
 // Reference to the Scratchpad chrome window object.
 var gScratchpadWindow;
 
 // Reference to the Scratchpad object.
 var gScratchpad;
 
 // Reference to the temporary nsIFile we will work with.
 var gFileA;
--- a/devtools/client/scratchpad/test/browser_scratchpad_revert_to_saved.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_revert_to_saved.js
@@ -1,19 +1,13 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 /* Bug 751744 */
 
-var tempScope = {};
-Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
-Cu.import("resource://gre/modules/FileUtils.jsm", tempScope);
-var NetUtil = tempScope.NetUtil;
-var FileUtils = tempScope.FileUtils;
-
 // Reference to the Scratchpad object.
 var gScratchpad;
 
 // Reference to the temporary nsIFiles.
 var gFile;
 
 // Temporary file name.
 var gFileName = "testFileForBug751744.tmp"
--- a/devtools/client/shadereditor/shadereditor.js
+++ b/devtools/client/shadereditor/shadereditor.js
@@ -1,14 +1,14 @@
 /* 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/. */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/SideMenuWidget.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
 Cu.import("resource://gre/modules/devtools/shared/Console.jsm");
 
@@ -33,16 +33,17 @@ const EVENTS = {
   SHADER_COMPILED: "ShaderEditor:ShaderCompiled",
 
   // When the UI is reset from tab navigation
   UI_RESET: "ShaderEditor:UIReset",
 
   // When the editor's error markers are all removed
   EDITOR_ERROR_MARKERS_REMOVED: "ShaderEditor:EditorCleaned"
 };
+XPCOMUtils.defineConstant(this, "EVENTS", EVENTS);
 
 const STRINGS_URI = "chrome://browser/locale/devtools/shadereditor.properties"
 const HIGHLIGHT_TINT = [1, 0, 0.25, 1]; // rgba
 const TYPING_MAX_DELAY = 500; // ms
 const SHADERS_AUTOGROW_ITEMS = 4;
 const GUTTER_ERROR_PANEL_OFFSET_X = 7; // px
 const GUTTER_ERROR_PANEL_DELAY = 100; // ms
 const DEFAULT_EDITOR_CONFIG = {
--- a/devtools/client/shadereditor/test/head.js
+++ b/devtools/client/shadereditor/test/head.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 
 var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
 // To enable logging for try runs, just set the pref to true.
 Services.prefs.setBoolPref("devtools.debugger.log", false);
 
 var { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
--- a/devtools/client/shared/browser-loader.js
+++ b/devtools/client/shared/browser-loader.js
@@ -1,9 +1,9 @@
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 const loaders = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {});
 const devtools = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {}).devtools;
 const { joinURI } = devtools.require("devtools/shared/path");
 var appConstants;
 
 // Some of the services that the system module requires is not
 // available in xpcshell tests. This is ok, we can easily polyfill the
--- a/devtools/client/shared/frame-script-utils.js
+++ b/devtools/client/shared/frame-script-utils.js
@@ -1,14 +1,14 @@
 /* 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/. */
 
 "use strict";
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const {require, loader} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const promise = require("promise");
 loader.lazyImporter(this, "Task", "resource://gre/modules/Task.jsm", "Task");
 const subScriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
                           .getService(Ci.mozIJSSubScriptLoader);
 var EventUtils = {};
 subScriptLoader.loadSubScript("chrome://marionette/content/EventUtils.js", EventUtils);
 loader.lazyGetter(this, "nsIProfilerModule", () => {
--- a/devtools/client/shared/test/browser_layoutHelpers-getBoxQuads.js
+++ b/devtools/client/shared/test/browser_layoutHelpers-getBoxQuads.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests getAdjustedQuads works properly in a variety of use cases including
 // iframes, scroll and zoom
 
-const {utils: Cu} = Components;
-let {getAdjustedQuads} = require("devtools/shared/layout/utils");
+var {utils: Cu} = Components;
+var {getAdjustedQuads} = require("devtools/shared/layout/utils");
 
 const TEST_URI = TEST_URI_ROOT + "browser_layoutHelpers-getBoxQuads.html";
 
 function test() {
   addTab(TEST_URI, function(browser, tab) {
     let doc = browser.contentDocument;
 
     ok(typeof getAdjustedQuads === "function", "getAdjustedQuads is defined");
--- a/devtools/client/shared/test/browser_layoutHelpers.js
+++ b/devtools/client/shared/test/browser_layoutHelpers.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that scrollIntoViewIfNeeded works properly.
-let {scrollIntoViewIfNeeded} = require("devtools/shared/layout/utils");
+var {scrollIntoViewIfNeeded} = require("devtools/shared/layout/utils");
 
 const TEST_URI = TEST_URI_ROOT + "browser_layoutHelpers.html";
 
 add_task(function*() {
   let [host, win, doc] = yield createHost("bottom", TEST_URI);
   runTest(win);
   host.destroy();
 });
--- a/devtools/client/shared/test/test-actor.js
+++ b/devtools/client/shared/test/test-actor.js
@@ -1,17 +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/ */
 
 "use strict";
 
 // A helper actor for brower/devtools/inspector tests.
 
-let { Cc, Ci, Cu, Cr } = require("chrome");
+var { Cc, Ci, Cu, Cr } = require("chrome");
 const {getRect, getElementFromPoint, getAdjustedQuads} = require("devtools/shared/layout/utils");
 const promise = require("promise");
 const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
 var DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
 var loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
             .getService(Ci.mozIJSSubScriptLoader);
 var EventUtils = {};
 loader.loadSubScript("chrome://marionette/content/EventUtils.js", EventUtils);
@@ -33,17 +33,17 @@ var dumpn = msg => {
  */
 function getHighlighterCanvasFrameHelper(conn, actorID) {
   let actor = conn.getActor(actorID);
   if (actor && actor._highlighter) {
     return actor._highlighter.markup;
   }
 }
 
-const TestActor = exports.TestActor = protocol.ActorClass({
+var TestActor = exports.TestActor = protocol.ActorClass({
   typeName: "testActor",
 
   initialize: function(conn, tabActor, options) {
     this.conn = conn;
     this.tabActor = tabActor;
   },
 
   get content() {
@@ -520,17 +520,17 @@ const TestActor = exports.TestActor = pr
       selector: Arg(0, "string")
     },
     response: {
       value: RetVal("json")
     }
   }),
 });
 
-const TestActorFront = exports.TestActorFront = protocol.FrontClass(TestActor, {
+var TestActorFront = exports.TestActorFront = protocol.FrontClass(TestActor, {
   initialize: function(client, { testActor }, toolbox) {
     protocol.Front.prototype.initialize.call(this, client, { actor: testActor });
     this.manage(this);
     this.toolbox = toolbox;
   },
 
   /**
    * Zoom the current page to a given level.
--- a/devtools/client/shared/test/unit/test_VariablesView_filtering-without-controller.js
+++ b/devtools/client/shared/test/unit/test_VariablesView_filtering-without-controller.js
@@ -1,19 +1,19 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Test that VariablesView._doSearch() works even without an attached
 // VariablesViewController (bug 1196341).
 
-const Cu = Components.utils;
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 const DOMParser = Cc["@mozilla.org/xmlextras/domparser;1"]
                     .createInstance(Ci.nsIDOMParser);
 const { VariablesView } =
   Cu.import("resource:///modules/devtools/client/shared/widgets/VariablesView.jsm", {});
 
 function run_test() {
   let doc = DOMParser.parseFromString("<div>", "text/html");
   let container = doc.body.firstChild;
--- a/devtools/client/shared/test/unit/test_VariablesView_getString_promise.js
+++ b/devtools/client/shared/test/unit/test_VariablesView_getString_promise.js
@@ -1,14 +1,14 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 const { VariablesView } = Cu.import("resource:///modules/devtools/client/shared/widgets/VariablesView.jsm", {});
 
 const PENDING = {
   "type": "object",
   "class": "Promise",
   "actor": "conn0.pausedobj35",
   "extensible": true,
   "frozen": false,
--- a/devtools/client/shared/test/unit/test_advanceValidate.js
+++ b/devtools/client/shared/test/unit/test_advanceValidate.js
@@ -2,18 +2,18 @@
 /* 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";
 
 // Tests the advanceValidate function from rule-view.js.
 
-const Cu = Components.utils;
-const Ci = Components.interfaces;
+var Cu = Components.utils;
+var Ci = Components.interfaces;
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var {advanceValidate} = require("devtools/client/styleinspector/utils");
 
 //                            1         2         3
 //                  0123456789012345678901234567890
 var sampleInput = '\\symbol "string" url(somewhere)';
 
 function testInsertion(where, result, testName) {
--- a/devtools/client/shared/test/unit/test_attribute-parsing-01.js
+++ b/devtools/client/shared/test/unit/test_attribute-parsing-01.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Test splitBy from node-attribute-parser.js
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {splitBy} = require("devtools/client/shared/node-attribute-parser");
 
 const TEST_DATA = [{
   value: "this is a test",
   splitChar: " ",
   expected: [
     {value: "this"},
--- a/devtools/client/shared/test/unit/test_attribute-parsing-02.js
+++ b/devtools/client/shared/test/unit/test_attribute-parsing-02.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Test parseAttribute from node-attribute-parser.js
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {parseAttribute} = require("devtools/client/shared/node-attribute-parser");
 
 const TEST_DATA = [{
   tagName: "body",
   namespaceURI: "http://www.w3.org/1999/xhtml",
   attributeName: "class",
   attributeValue: "some css class names",
--- a/devtools/client/shared/test/unit/test_bezierCanvas.js
+++ b/devtools/client/shared/test/unit/test_bezierCanvas.js
@@ -2,17 +2,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";
 
 // Tests the BezierCanvas API in the CubicBezierWidget module
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var {CubicBezier, BezierCanvas} = require("devtools/client/shared/widgets/CubicBezierWidget");
 
 function run_test() {
   offsetsGetterReturnsData();
   convertsOffsetsToCoordinates();
   plotsCanvas();
 }
--- a/devtools/client/shared/test/unit/test_cubicBezier.js
+++ b/devtools/client/shared/test/unit/test_cubicBezier.js
@@ -2,17 +2,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";
 
 // Tests the CubicBezier API in the CubicBezierWidget module
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var {CubicBezier, _parseTimingFunction} = require("devtools/client/shared/widgets/CubicBezierWidget");
 
 function run_test() {
   throwsWhenMissingCoordinates();
   throwsWhenIncorrectCoordinates();
   convertsStringCoordinates();
   coordinatesToStringOutputsAString();
--- a/devtools/client/shared/test/unit/test_undoStack.js
+++ b/devtools/client/shared/test/unit/test_undoStack.js
@@ -1,14 +1,14 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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 Cu = Components.utils;
+var Cu = Components.utils;
 var {Loader} = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {});
 
 var loader = new Loader.Loader({
   paths: {
     "": "resource://gre/modules/commonjs/",
     "devtools": "resource:///modules/devtools",
   },
   globals: {},
--- a/devtools/client/shared/widgets/TableWidget.js
+++ b/devtools/client/shared/widgets/TableWidget.js
@@ -15,16 +15,21 @@ const EVENTS = {
   TABLE_CLEARED: "table-cleared",
   COLUMN_SORTED: "column-sorted",
   COLUMN_TOGGLED: "column-toggled",
   ROW_SELECTED: "row-selected",
   ROW_UPDATED: "row-updated",
   HEADER_CONTEXT_MENU: "header-context-menu",
   ROW_CONTEXT_MENU: "row-context-menu"
 };
+Object.defineProperty(this, "EVENTS", {
+  value: EVENTS,
+  enumerable: true,
+  writable: false
+});
 
 // Maximum number of character visible in any cell in the table. This is to avoid
 // making the cell take up all the space in a row.
 const MAX_VISIBLE_STRING_SIZE = 100;
 
 /**
  * A table widget with various features like resizble/toggleable columns,
  * sorting, keyboard navigation etc.
--- a/devtools/client/styleeditor/test/browser_styleeditor_filesave.js
+++ b/devtools/client/styleeditor/test/browser_styleeditor_filesave.js
@@ -3,18 +3,18 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
 // Test that 'Save' function works.
 
 const TESTCASE_URI_HTML = TEST_BASE_HTTP + "simple.html";
 const TESTCASE_URI_CSS = TEST_BASE_HTTP + "simple.css";
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
 var tempScope = {};
 Components.utils.import("resource://gre/modules/FileUtils.jsm", tempScope);
 Components.utils.import("resource://gre/modules/NetUtil.jsm", tempScope);
 var FileUtils = tempScope.FileUtils;
 var NetUtil = tempScope.NetUtil;
 
 add_task(function* () {
--- a/devtools/client/styleeditor/test/browser_styleeditor_sourcemap_watching.js
+++ b/devtools/client/styleeditor/test/browser_styleeditor_sourcemap_watching.js
@@ -14,18 +14,18 @@ const TESTCASE_URI_REG_CSS = TEST_BASE_H
 const TESTCASE_URI_SCSS = TEST_BASE_HTTP + "sourcemap-sass/sourcemaps.scss";
 const TESTCASE_URI_MAP = TEST_BASE_HTTP + "sourcemap-css/sourcemaps.css.map";
 const TESTCASE_SCSS_NAME = "sourcemaps.scss";
 
 const TRANSITIONS_PREF = "devtools.styleeditor.transitions";
 
 const CSS_TEXT = "* { color: blue }";
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
 var tempScope = {};
 Components.utils.import("resource://gre/modules/FileUtils.jsm", tempScope);
 Components.utils.import("resource://gre/modules/NetUtil.jsm", tempScope);
 var FileUtils = tempScope.FileUtils;
 var NetUtil = tempScope.NetUtil;
 
 function test() {
--- a/devtools/client/styleinspector/test/head.js
+++ b/devtools/client/styleinspector/test/head.js
@@ -1,15 +1,15 @@
 /* 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/ */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 var {gDevTools} = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 var {TargetFactory} = require("devtools/client/framework/target");
 var {CssComputedView} = require("devtools/client/styleinspector/computed-view");
 var {CssRuleView, _ElementStyle} = require("devtools/client/styleinspector/rule-view");
 var {CssLogic, CssSelector} = require("devtools/shared/styleinspector/css-logic");
 var DevToolsUtils = require("devtools/shared/DevToolsUtils");
 var promise = require("promise");
--- a/devtools/client/styleinspector/test/unit/test_escapeCSSComment.js
+++ b/devtools/client/styleinspector/test/unit/test_escapeCSSComment.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import("resource://gre/modules/devtools/Loader.jsm");
 const {escapeCSSComment, _unescapeCSSComment} =
       devtools.require("devtools/client/styleinspector/css-parsing-utils");
 
 const TEST_DATA = [
   {
     input: "simple",
     expected: "simple"
--- a/devtools/client/styleinspector/test/unit/test_parseDeclarations.js
+++ b/devtools/client/styleinspector/test/unit/test_parseDeclarations.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {parseDeclarations, _parseCommentDeclarations} =
   require("devtools/client/styleinspector/css-parsing-utils");
 
 const TEST_DATA = [
   // Simple test
   {
     input: "p:v;",
--- a/devtools/client/styleinspector/test/unit/test_parsePseudoClassesAndAttributes.js
+++ b/devtools/client/styleinspector/test/unit/test_parsePseudoClassesAndAttributes.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {
   parsePseudoClassesAndAttributes,
   SELECTOR_ATTRIBUTE,
   SELECTOR_ELEMENT,
   SELECTOR_PSEUDO_CLASS
 } = require("devtools/client/styleinspector/css-parsing-utils");
 
--- a/devtools/client/styleinspector/test/unit/test_parseSingleValue.js
+++ b/devtools/client/styleinspector/test/unit/test_parseSingleValue.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {parseSingleValue} = require("devtools/client/styleinspector/css-parsing-utils");
 
 const TEST_DATA = [
   {input: null, throws: true},
   {input: undefined, throws: true},
   {input: "", expected: {value: "", priority: ""}},
   {input: "  \t \t \n\n  ", expected: {value: "", priority: ""}},
--- a/devtools/client/styleinspector/test/unit/test_rewriteDeclarations.js
+++ b/devtools/client/styleinspector/test/unit/test_rewriteDeclarations.js
@@ -1,16 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import("resource://gre/modules/devtools/Loader.jsm");
 const {parseDeclarations, RuleRewriter} =
       devtools.require("devtools/client/styleinspector/css-parsing-utils");
 
 const TEST_DATA = [
   {
     desc: "simple set",
     input: "p:v;",
--- a/devtools/client/webaudioeditor/includes.js
+++ b/devtools/client/webaudioeditor/includes.js
@@ -1,14 +1,14 @@
 /* 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/. */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm");
 Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm");
 
 const { loader, require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
@@ -69,16 +69,17 @@ const EVENTS = {
   // Is called with two arguments, first representing number of nodes
   // rendered, second being the number of edge connections rendering (not counting
   // param edges), followed by the count of the param edges rendered.
   UI_GRAPH_RENDERED: "WebAudioEditor:UIGraphRendered",
 
   // Called when the inspector splitter is moved and resized.
   UI_INSPECTOR_RESIZE: "WebAudioEditor:UIInspectorResize"
 };
+XPCOMUtils.defineConstant(this, "EVENTS", EVENTS);
 
 /**
  * The current target and the Web Audio Editor front, set by this tool's host.
  */
 var gToolbox, gTarget, gFront;
 
 /**
  * Convenient way of emitting events from the panel window.
--- a/devtools/client/webaudioeditor/test/head.js
+++ b/devtools/client/webaudioeditor/test/head.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 
 // Enable logging for all the tests. Both the debugger server and frontend will
 // be affected by this pref.
 var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
 Services.prefs.setBoolPref("devtools.debugger.log", false);
 
--- a/devtools/client/webaudioeditor/views/context.js
+++ b/devtools/client/webaudioeditor/views/context.js
@@ -16,16 +16,21 @@ const GRAPH_DEFAULTS = {
 const ARROW_HEIGHT = 5;
 const ARROW_WIDTH = 8;
 
 // Styles for markers as they cannot be done with CSS.
 const MARKER_STYLING = {
   light: "#AAA",
   dark: "#CED3D9"
 };
+Object.defineProperty(this, "MARKER_STYLING", {
+  value: MARKER_STYLING,
+  enumerable: true,
+  writable: false
+});
 
 const GRAPH_DEBOUNCE_TIMER = 100;
 
 // `gAudioNodes` events that should require the graph
 // to redraw
 const GRAPH_REDRAW_EVENTS = ["add", "connect", "disconnect", "remove"];
 
 /**
--- a/devtools/client/webconsole/test/browser_webconsole_autocomplete-properties-with-non-alphanumeric-names.js
+++ b/devtools/client/webconsole/test/browser_webconsole_autocomplete-properties-with-non-alphanumeric-names.js
@@ -23,17 +23,21 @@ var test = asyncTest(function*() {
     yield deferred.promise;
 
     ok(popup.itemCount > 0, "There's suggestions for '" + term + "'");
   }
 
   let { jsterm } = yield openConsole();
   let popup = jsterm.autocompletePopup;
 
-  yield jsterm.execute("let testObject = {$$aaab: '', $$aaac: ''}");
+  yield jsterm.execute("var testObject = {$$aaab: '', $$aaac: ''}");
+
+  // FIXMEshu: global lexicals can't be autocompleted without extra platform
+  // support. See bug 1207868.
+  //yield jsterm.execute("let testObject = {$$aaab: '', $$aaac: ''}");
 
   // Should work with bug 967468.
   yield autocomplete("Object.__d");
   yield autocomplete("testObject.$$a");
 
   // Here's when things go wrong in bug 967468.
   yield autocomplete("Object.__de");
   yield autocomplete("testObject.$$aa");
--- a/devtools/client/webconsole/test/browser_webconsole_netlogging_reset_filter.js
+++ b/devtools/client/webconsole/test/browser_webconsole_netlogging_reset_filter.js
@@ -7,19 +7,19 @@
 
 "use strict";
 
 const TEST_FILE_URI =
   "http://example.com/browser/devtools/client/webconsole/test/" +
   "test-network.html";
 const TEST_URI = "data:text/html;charset=utf8,<p>test file URI";
 
-let hud;
+var hud;
 
-let test = asyncTest(function* () {
+var test = asyncTest(function* () {
   let requests = [];
   let { browser } = yield loadTab(TEST_URI);
 
   yield pushPrefEnv();
   hud = yield openConsole();
   hud.jsterm.clearOutput();
 
   HUDService.lastFinishedRequest.callback = request => requests.push(request);
--- a/devtools/client/webide/content/addons.js
+++ b/devtools/client/webide/content/addons.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {GetAvailableAddons, ForgetAddonsList} = require("devtools/client/webide/modules/addons");
 const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/webide.properties");
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad);
   document.querySelector("#aboutaddons").onclick = function() {
--- a/devtools/client/webide/content/details.js
+++ b/devtools/client/webide/content/details.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm");
 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {AppProjects} = require("devtools/client/app-manager/app-projects");
 const {AppValidator} = require("devtools/client/app-manager/app-validator");
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 const {ProjectBuilding} = require("devtools/client/webide/modules/build");
 
--- a/devtools/client/webide/content/devicepreferences.js
+++ b/devtools/client/webide/content/devicepreferences.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 const {Connection} = require("devtools/shared/client/connection-manager");
 const ConfigView = require("devtools/client/webide/modules/config-view");
 
 var configView = new ConfigView(window);
 
 window.addEventListener("load", function onLoad() {
--- a/devtools/client/webide/content/devicesettings.js
+++ b/devtools/client/webide/content/devicesettings.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 const {Connection} = require("devtools/shared/client/connection-manager");
 const ConfigView = require("devtools/client/webide/modules/config-view");
 
 var configView = new ConfigView(window);
 
 window.addEventListener("load", function onLoad() {
--- a/devtools/client/webide/content/logs.js
+++ b/devtools/client/webide/content/logs.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad);
 
   Logs.init();
--- a/devtools/client/webide/content/monitor.js
+++ b/devtools/client/webide/content/monitor.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 Cu.import('resource:///modules/devtools/client/framework/gDevTools.jsm');
 const {require} = Cu.import('resource://gre/modules/devtools/shared/Loader.jsm', {});
 const {Services} = Cu.import('resource://gre/modules/Services.jsm');
 const {AppManager} = require('devtools/client/webide/modules/app-manager');
 const {AppActorFront} = require('devtools/shared/apps/app-actor-front');
 const {Connection} = require('devtools/shared/client/connection-manager');
 const EventEmitter = require('devtools/shared/event-emitter');
 
--- a/devtools/client/webide/content/newapp.js
+++ b/devtools/client/webide/content/newapp.js
@@ -1,15 +1,15 @@
 /* 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/. */
 
-const Cc = Components.classes;
-const Cu = Components.utils;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cu = Components.utils;
+var Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "ZipUtils", "resource://gre/modules/ZipUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Downloads", "resource://gre/modules/Downloads.jsm");
 
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
--- a/devtools/client/webide/content/permissionstable.js
+++ b/devtools/client/webide/content/permissionstable.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 const {Connection} = require("devtools/shared/client/connection-manager");
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad);
   document.querySelector("#close").onclick = CloseUI;
--- a/devtools/client/webide/content/prefs.js
+++ b/devtools/client/webide/content/prefs.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad);
 
   // Listen to preference changes
   let inputs = document.querySelectorAll("[data-pref]");
   for (let i of inputs) {
--- a/devtools/client/webide/content/project-listing.js
+++ b/devtools/client/webide/content/project-listing.js
@@ -1,15 +1,15 @@
 /* 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/. */
 
 /* eslint-env browser */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const ProjectList = require("devtools/client/webide/modules/project-list");
 
 var projectList = new ProjectList(window, window.parent);
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad, true);
   document.getElementById("new-app").onclick = CreateNewApp;
--- a/devtools/client/webide/content/runtime-listing.js
+++ b/devtools/client/webide/content/runtime-listing.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const RuntimeList = require("devtools/client/webide/modules/runtime-list");
 
 var runtimeList = new RuntimeList(window, window.parent);
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad, true);
   document.getElementById("runtime-screenshot").onclick = TakeScreenshot;
--- a/devtools/client/webide/content/runtimedetails.js
+++ b/devtools/client/webide/content/runtimedetails.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 const {Connection} = require("devtools/shared/client/connection-manager");
 const {RuntimeTypes} = require("devtools/client/webide/modules/runtimes");
 const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/webide.properties");
 
 const UNRESTRICTED_HELP_URL = "https://developer.mozilla.org/docs/Tools/WebIDE/Running_and_debugging_apps#Unrestricted_app_debugging_%28including_certified_apps_main_process_etc.%29";
--- a/devtools/client/webide/content/simulator.js
+++ b/devtools/client/webide/content/simulator.js
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const { GetDevices, GetDeviceString } = require("devtools/client/shared/devices");
 const { Services } = Cu.import("resource://gre/modules/Services.jsm");
 const { Simulators, Simulator } = require("devtools/client/webide/modules/simulators");
 const EventEmitter = require('devtools/shared/event-emitter');
 const promise = require("promise");
 const utils = require("devtools/client/webide/modules/utils");
--- a/devtools/client/webide/content/webide.js
+++ b/devtools/client/webide/content/webide.js
@@ -1,15 +1,15 @@
 /* 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/. */
 
-const Cc = Components.classes;
-const Cu = Components.utils;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cu = Components.utils;
+var Ci = Components.interfaces;
 
 Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {Toolbox} = require("devtools/client/framework/toolbox");
 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
 const {AppProjects} = require("devtools/client/app-manager/app-projects");
@@ -31,16 +31,26 @@ const Strings = Services.strings.createB
 const HTML = "http://www.w3.org/1999/xhtml";
 const HELP_URL = "https://developer.mozilla.org/docs/Tools/WebIDE/Troubleshooting";
 
 const MAX_ZOOM = 1.4;
 const MIN_ZOOM = 0.6;
 
 const MS_PER_DAY = 86400000;
 
+[["AppManager", AppManager],
+ ["AppProjects", AppProjects],
+ ["Connection", Connection]].forEach(([key, value]) => {
+   Object.defineProperty(this, key, {
+     value: value,
+     enumerable: true,
+     writable: false
+   });
+ });
+
 // Download remote resources early
 getJSON("devtools.webide.addonsURL", true);
 getJSON("devtools.webide.templatesURL", true);
 getJSON("devtools.devices.url", true);
 
 // See bug 989619
 console.log = console.log.bind(console);
 console.warn = console.warn.bind(console);
--- a/devtools/client/webide/content/wifi-auth.js
+++ b/devtools/client/webide/content/wifi-auth.js
@@ -1,15 +1,15 @@
 /* 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/. */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const { Services } = Cu.import("resource://gre/modules/Services.jsm");
 const { require } =
   Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const QR = require("devtools/shared/qrcode/index");
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad);
   document.getElementById("close").onclick = () => window.close();
--- a/devtools/client/webide/test/head.js
+++ b/devtools/client/webide/test/head.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const {utils: Cu, classes: Cc, interfaces: Ci} = Components;
+var {utils: Cu, classes: Cc, interfaces: Ci} = Components;
 
 Cu.import('resource://gre/modules/Services.jsm');
 Cu.import("resource://gre/modules/FileUtils.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {gDevTools} = Cu.import("resource:///modules/devtools/client/framework/gDevTools.jsm", {});
 const promise = require("promise");
--- a/devtools/server/actors/highlighters.js
+++ b/devtools/server/actors/highlighters.js
@@ -74,17 +74,17 @@ exports.register = register;
  *
  * Other types of highlighter actors exist and can be accessed via the
  * InspectorActor's 'getHighlighterByType' method.
  */
 
 /**
  * The HighlighterActor class
  */
-let HighlighterActor = exports.HighlighterActor = protocol.ActorClass({
+var HighlighterActor = exports.HighlighterActor = protocol.ActorClass({
   typeName: "highlighter",
 
   initialize: function(inspector, autohide) {
     protocol.Actor.prototype.initialize.call(this, null);
 
     this._autohide = autohide;
     this._inspector = inspector;
     this._walker = this._inspector.walker;
@@ -403,30 +403,30 @@ let HighlighterActor = exports.Highlight
       this._highlighter.hide();
       this._stopPickerListeners();
       this._isPicking = false;
       this._hoveredNode = null;
     }
   })
 });
 
-let HighlighterFront = protocol.FrontClass(HighlighterActor, {
+var HighlighterFront = protocol.FrontClass(HighlighterActor, {
   // Update the object given a form representation off the wire.
   form: function(json) {
     this.actorID = json.actor;
     // FF42+ HighlighterActors starts exposing custom form, with traits object
     this.traits = json.traits || {};
   }
 });
 
 /**
  * A generic highlighter actor class that instantiate a highlighter given its
  * type name and allows to show/hide it.
  */
-let CustomHighlighterActor = exports.CustomHighlighterActor = protocol.ActorClass({
+var CustomHighlighterActor = exports.CustomHighlighterActor = protocol.ActorClass({
   typeName: "customhighlighter",
 
   /**
    * Create a highlighter instance given its typename
    * The typename must be one of HIGHLIGHTER_CLASSES and the class must
    * implement constructor(tabActor), show(node), hide(), destroy()
    */
   initialize: function(inspector, typeName) {
@@ -522,17 +522,17 @@ let CustomHighlighterActor = exports.Cus
       this._highlighterEnv.destroy();
       this._highlighterEnv = null;
     }
   }, {
     oneway: true
   })
 });
 
-let CustomHighlighterFront = protocol.FrontClass(CustomHighlighterActor, {});
+var CustomHighlighterFront = protocol.FrontClass(CustomHighlighterActor, {});
 
 /**
  * The HighlighterEnvironment is an object that holds all the required data for
  * highlighters to work: the window, docShell, event listener target, ...
  * It also emits "will-navigate" and "navigate" events, similarly to the
  * TabActor.
  *
  * It can be initialized either from a TabActor (which is the most frequent way
--- a/devtools/server/actors/highlighters/css-transform.js
+++ b/devtools/server/actors/highlighters/css-transform.js
@@ -10,17 +10,17 @@ const {
   CanvasFrameAnonymousContentHelper, getComputedStyle,
   createSVGNode, createNode } = require("./utils/markup");
 const { setIgnoreLayoutChanges,
   getNodeBounds } = require("devtools/shared/layout/utils");
 
 // The minimum distance a line should be before it has an arrow marker-end
 const ARROW_LINE_MIN_DISTANCE = 10;
 
-let MARKER_COUNTER = 1;
+var MARKER_COUNTER = 1;
 
 /**
  * The CssTransformHighlighter is the class that draws an outline around a
  * transformed element and an outline around where it would be if untransformed
  * as well as arrows connecting the 2 outlines' corners.
  */
 function CssTransformHighlighter(highlighterEnv) {
   AutoRefreshHighlighter.call(this, highlighterEnv);
--- a/devtools/server/actors/highlighters/geometry-editor.js
+++ b/devtools/server/actors/highlighters/geometry-editor.js
@@ -14,17 +14,17 @@ const { setIgnoreLayoutChanges,
   getAdjustedQuads } = require("devtools/shared/layout/utils");
 
 const GEOMETRY_LABEL_SIZE = 6;
 
 /**
  * Element geometry properties helper that gives names of position and size
  * properties.
  */
-let GeoProp = {
+var GeoProp = {
   SIDES: ["top", "right", "bottom", "left"],
   SIZES: ["width", "height"],
 
   allProps: function() {
     return [...this.SIDES, ...this.SIZES];
   },
 
   isSide: function(name) {
--- a/devtools/server/actors/highlighters/utils/markup.js
+++ b/devtools/server/actors/highlighters/utils/markup.js
@@ -45,17 +45,17 @@ const STYLESHEET_URI = "resource://gre/m
 function isXUL(window) {
   return window.document.documentElement.namespaceURI === XUL_NS;
 }
 exports.isXUL = isXUL;
 
 /**
  * Inject a helper stylesheet in the window.
  */
-let installedHelperSheets = new WeakMap();
+var installedHelperSheets = new WeakMap();
 
 function installHelperSheet(win, source, type = "agent") {
   if (installedHelperSheets.has(win.document)) {
     return;
   }
   let {Style} = require("sdk/stylesheet/style");
   let {attach} = require("sdk/content/mod");
   let style = Style({source, type});
--- a/devtools/server/actors/memprof.js
+++ b/devtools/server/actors/memprof.js
@@ -1,21 +1,21 @@
 /* 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/. */
 
 "use strict";
 
 const { Cc, Ci, Cu } = require("chrome");
-let protocol = require("devtools/server/protocol");
-let { method, RetVal, Arg, types } = protocol;
+var protocol = require("devtools/server/protocol");
+var { method, RetVal, Arg, types } = protocol;
 const { reportException } = require("devtools/shared/DevToolsUtils");
 loader.lazyRequireGetter(this, "events", "sdk/event/core");
 
-let MemprofActor = protocol.ActorClass({
+var MemprofActor = protocol.ActorClass({
   typeName: "memprof",
 
   initialize: function(conn) {
     protocol.Actor.prototype.initialize.call(this, conn);
     this._profiler = Cc["@mozilla.org/tools/memory-profiler;1"]
       .getService(Ci.nsIMemoryProfiler);
   },
 
--- a/devtools/server/tests/browser/head.js
+++ b/devtools/server/tests/browser/head.js
@@ -1,15 +1,15 @@
 /* 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/. */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 const {console} = Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {DebuggerClient} = require("devtools/shared/client/main");
 const {DebuggerServer} = require("devtools/server/main");
 const {defer} = require("promise");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
--- a/devtools/server/tests/mochitest/hello-actor.js
+++ b/devtools/server/tests/mochitest/hello-actor.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const protocol = require("devtools/server/protocol");
 
-const HelloActor = protocol.ActorClass({
+var HelloActor = protocol.ActorClass({
   typeName: "helloActor",
 
   initialize: function() {
     protocol.Actor.prototype.initialize.apply(this, arguments);
     this.counter = 0;
   },
 
   count: protocol.method(function () {
--- a/devtools/server/tests/mochitest/memprof-helpers.js
+++ b/devtools/server/tests/mochitest/memprof-helpers.js
@@ -1,27 +1,27 @@
-let Cu = Components.utils;
-let Cc = Components.classes;
-let Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
-let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
+var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 
 // Always log packets when running tests.
 Services.prefs.setBoolPref("devtools.debugger.log", true);
 SimpleTest.registerCleanupFunction(function() {
   Services.prefs.clearUserPref("devtools.debugger.log");
 });
 
-let { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
-let { require } =
+var { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
+var { require } =
   Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
-let { DebuggerClient } = require("devtools/shared/client/main");
-let { DebuggerServer } = require("devtools/server/main");
-let { MemprofFront } = require("devtools/server/actors/memprof");
+var { DebuggerClient } = require("devtools/shared/client/main");
+var { DebuggerServer } = require("devtools/server/main");
+var { MemprofFront } = require("devtools/server/actors/memprof");
 
 function startServerAndGetSelectedTabMemprof() {
   DebuggerServer.init();
   DebuggerServer.addBrowserActors();
   var client = new DebuggerClient(DebuggerServer.connectPipe());
 
   return new Promise((resolve, reject) => {
     client.connect(response => {
--- a/devtools/server/tests/mochitest/test_registerActor.html
+++ b/devtools/server/tests/mochitest/test_registerActor.html
@@ -62,17 +62,17 @@ window.onload = function() {
           });
         });
       });
     });
   });
 }
 
 function checkActorState(helloActor, callback) {
-  getCount(helloActor, response => {
+getCount(helloActor, response => {
     ok(!response.error, "No error");
     is(response.count, 1, "The counter must be valid");
 
     getCount(helloActor, response => {
       ok(!response.error, "No error");
       is(response.count, 2, "The counter must be valid");
 
       gClient.listTabs(response => {
--- a/devtools/server/tests/unit/head_dbg.js
+++ b/devtools/server/tests/unit/head_dbg.js
@@ -1,17 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-const CC = Components.Constructor;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
+var CC = Components.Constructor;
 
 const { require, loader } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const { worker } = Cu.import("resource://gre/modules/devtools/shared/worker-loader.js", {})
 const promise = require("promise");
 const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
 const { promiseInvoke } = require("devtools/shared/async-utils");
 
 const Services = require("Services");
--- a/devtools/server/tests/unit/hello-actor.js
+++ b/devtools/server/tests/unit/hello-actor.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const protocol = require("devtools/server/protocol");
 
-const HelloActor = protocol.ActorClass({
+var HelloActor = protocol.ActorClass({
   typeName: "helloActor",
 
   hello: protocol.method(function () {
     return;
   }, {
     request: {},
     response: {}
   })
--- a/devtools/server/tests/unit/test_framebindings-02.js
+++ b/devtools/server/tests/unit/test_framebindings-02.js
@@ -31,17 +31,18 @@ function test_pause_frame()
     let args = bindings.arguments;
     let vars = bindings.variables;
     do_check_neq(parentEnv, undefined);
     do_check_eq(args.length, 0);
     do_check_eq(vars.stopMe.value.type, "object");
     do_check_eq(vars.stopMe.value.class, "Function");
     do_check_true(!!vars.stopMe.value.actor);
 
-    parentEnv = parentEnv.parent.parent;
+    // Skip both the eval lexical scope and the global lexical scope.
+    parentEnv = parentEnv.parent.parent.parent;
     do_check_neq(parentEnv, undefined);
     let objClient = gThreadClient.pauseGrip(parentEnv.object);
     objClient.getPrototypeAndProperties(function(aResponse) {
       do_check_eq(aResponse.ownProperties.Object.value.type, "object");
       do_check_eq(aResponse.ownProperties.Object.value.class, "Function");
       do_check_true(!!aResponse.ownProperties.Object.value.actor);
 
       gThreadClient.resume(function() {
--- a/devtools/server/tests/unit/test_framebindings-05.js
+++ b/devtools/server/tests/unit/test_framebindings-05.js
@@ -31,17 +31,18 @@ function test_pause_frame()
 
     let objClient = gThreadClient.pauseGrip(env.object);
     objClient.getPrototypeAndProperties(function(aResponse) {
       do_check_eq(aResponse.ownProperties.PI.value, Math.PI);
       do_check_eq(aResponse.ownProperties.cos.value.type, "object");
       do_check_eq(aResponse.ownProperties.cos.value.class, "Function");
       do_check_true(!!aResponse.ownProperties.cos.value.actor);
 
-      let parentEnv = env.parent.parent;
+      // Skip both the eval lexical scope and the global lexical scope.
+      let parentEnv = env.parent.parent.parent;
       do_check_neq(parentEnv, undefined);
 
       let parentClient = gThreadClient.pauseGrip(parentEnv.object);
       parentClient.getPrototypeAndProperties(function(aResponse) {
         do_check_eq(aResponse.ownProperties.a.value, Math.PI * 100);
         do_check_eq(aResponse.ownProperties.r.value, 10);
         do_check_eq(aResponse.ownProperties.Object.value.type, "object");
         do_check_eq(aResponse.ownProperties.Object.value.class, "Function");
--- a/devtools/shared/acorn/tests/unit/head_acorn.js
+++ b/devtools/shared/acorn/tests/unit/head_acorn.js
@@ -1,10 +1,10 @@
 "use strict";
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 
 function isObject(value) {
   return typeof value === "object" && value !== null;
 }
 
 function intersect(a, b) {
--- a/devtools/shared/apps/Devices.jsm
+++ b/devtools/shared/apps/Devices.jsm
@@ -39,10 +39,15 @@ const Devices = {
   available: function () {
     return Object.keys(this._devices).sort();
   },
 
   getByName: function (name) {
     return this._devices[name];
   }
 };
+Object.defineProperty(this, "Devices", {
+  value: Devices,
+  enumerable: true,
+  writable: false
+});
 
 EventEmitter.decorate(Devices);
--- a/devtools/shared/apps/tests/debugger-protocol-helper.js
+++ b/devtools/shared/apps/tests/debugger-protocol-helper.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
 
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const { DebuggerClient } = require("devtools/shared/client/main");
 const { DebuggerServer } = require("devtools/server/main");
 const { FileUtils } = Cu.import("resource://gre/modules/FileUtils.jsm");
 const { Services } = Cu.import("resource://gre/modules/Services.jsm");
 
 var gClient, gActor;
--- a/devtools/shared/apps/tests/unit/head_apps.js
+++ b/devtools/shared/apps/tests/unit/head_apps.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-const CC = Components.Constructor;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
+var CC = Components.Constructor;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/FileUtils.jsm");
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const {DebuggerClient} = require("devtools/shared/client/main");
 const {DebuggerServer} = require("devtools/server/main");
 const {AppActorFront} = require("devtools/shared/apps/app-actor-front");
--- a/devtools/shared/discovery/tests/unit/test_discovery.js
+++ b/devtools/shared/discovery/tests/unit/test_discovery.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 
 const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 Services.prefs.setBoolPref("devtools.discovery.log", true);
 
 do_register_cleanup(() => {
   Services.prefs.clearUserPref("devtools.discovery.log");
 });
 
--- a/devtools/shared/heapsnapshot/tests/unit/head_heapsnapshot.js
+++ b/devtools/shared/heapsnapshot/tests/unit/head_heapsnapshot.js
@@ -1,18 +1,18 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-const CC = Components.Constructor;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
+var CC = Components.Constructor;
 
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const { Match } = Cu.import("resource://test/Match.jsm", {});
 const { Census } = Cu.import("resource://test/Census.jsm", {});
 const { addDebuggerToGlobal } =
   Cu.import("resource://gre/modules/jsdebugger.jsm", {});
 const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
 
--- a/devtools/shared/jsbeautify/tests/unit/head_jsbeautify.js
+++ b/devtools/shared/jsbeautify/tests/unit/head_jsbeautify.js
@@ -1,17 +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/ */
 
 "use strict";
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 var beautify = require("devtools/shared/jsbeautify/beautify");
 var SanityTest = require('devtools/shared/jsbeautify/lib/sanitytest');
 var Urlencoded = require('devtools/shared/jsbeautify/lib/urlencode_unpacker');
 var {run_beautifier_tests} = require('devtools/shared/jsbeautify/src/beautify-tests');
--- a/devtools/shared/performance/test/head.js
+++ b/devtools/shared/performance/test/head.js
@@ -1,7 +1,7 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
--- a/devtools/shared/pretty-fast/tests/unit/head_pretty-fast.js
+++ b/devtools/shared/pretty-fast/tests/unit/head_pretty-fast.js
@@ -1,13 +1,13 @@
 "use strict";
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 this.sourceMap = require("source-map");
 this.acorn = require("acorn/acorn");
 this.prettyFast = require("devtools/shared/pretty-fast/pretty-fast");
 const { console } = Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
 
--- a/devtools/shared/qrcode/tests/unit/test_encode.js
+++ b/devtools/shared/qrcode/tests/unit/test_encode.js
@@ -1,17 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
 /**
  * Test encoding a simple message.
  */
 
-const { utils: Cu } = Components;
+var { utils: Cu } = Components;
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 const QR = require("devtools/shared/qrcode/index");
 
 function run_test() {
   let imgData = QR.encodeToDataURI("HELLO", "L");
   do_check_eq(imgData.src,
               "data:image/gif;base64,R0lGODdhOgA6AIAAAAAAAP///ywAAAAAOgA6AAAC" +
--- a/devtools/shared/security/tests/unit/head_dbg.js
+++ b/devtools/shared/security/tests/unit/head_dbg.js
@@ -1,17 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-const CC = Components.Constructor;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
+var CC = Components.Constructor;
 
 const { require } =
   Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const promise = require("promise");
 const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
 
 const Services = require("Services");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
--- a/devtools/shared/shared/tests/unit/test_indentation.js
+++ b/devtools/shared/shared/tests/unit/test_indentation.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const Cu = Components.utils;
+var Cu = Components.utils;
 const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm");
 const Services = require("Services");
 const {
   EXPAND_TAB,
   TAB_SIZE,
   DETECT_INDENT,
   getIndentationFromPrefs,
   getIndentationFromIteration,
--- a/devtools/shared/shims/dbg-client.jsm
+++ b/devtools/shared/shims/dbg-client.jsm
@@ -26,17 +26,17 @@ const { require } =
 
 this.EXPORTED_SYMBOLS = ["DebuggerTransport",
                          "DebuggerClient",
                          "RootClient",
                          "LongStringClient",
                          "EnvironmentClient",
                          "ObjectClient"];
 
-let client = require("devtools/shared/client/main");
+var client = require("devtools/shared/client/main");
 
 this.DebuggerClient = client.DebuggerClient;
 this.RootClient = client.RootClient;
 this.LongStringClient = client.LongStringClient;
 this.EnvironmentClient = client.EnvironmentClient;
 this.ObjectClient = client.ObjectClient;
 
 this.DebuggerTransport =
--- a/devtools/shared/sourcemap/tests/unit/head_sourcemap.js
+++ b/devtools/shared/sourcemap/tests/unit/head_sourcemap.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 
 function doesNotThrow(f) {
   try {
     f();
   } catch(e) {
     ok(false, e + e.stack);
   }
 }
--- a/devtools/shared/tern/tests/unit/head_tern.js
+++ b/devtools/shared/tern/tests/unit/head_tern.js
@@ -1,3 +1,3 @@
 "use strict";
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
--- a/devtools/shared/tests/unit/head_devtools.js
+++ b/devtools/shared/tests/unit/head_devtools.js
@@ -1,13 +1,13 @@
 "use strict";
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
 
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
 
 // Register a console listener, so console messages don't just disappear
 // into the ether.
 var errorCount = 0;
 var listener = {
--- a/devtools/shared/transport/tests/unit/head_dbg.js
+++ b/devtools/shared/transport/tests/unit/head_dbg.js
@@ -1,17 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-const CC = Components.Constructor;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
+var CC = Components.Constructor;
 
 const { require } =
   Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 const promise = require("promise");
 const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
 
 const Services = require("Services");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
--- a/devtools/shared/webconsole/test/common.js
+++ b/devtools/shared/webconsole/test/common.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 const XHTML_NS = "http://www.w3.org/1999/xhtml";
 
 Cu.import("resource://gre/modules/Services.jsm");
 const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
 
 // This gives logging to stdout for tests
 var {console} = Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
--- a/devtools/shared/webconsole/test/test_commands_registration.html
+++ b/devtools/shared/webconsole/test/test_commands_registration.html
@@ -13,17 +13,16 @@
 <p id="quack"></p>
 
 <script class="testbody" type="text/javascript;version=1.8">
 SimpleTest.waitForExplicitFinish();
 
 let gState;
 let tests;
 
-let {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 let {WebConsoleCommands} = require("devtools/shared/webconsole/utils");
 
 function evaluateJS(input) {
   return new Promise((resolve) => gState.client.evaluateJS(input, resolve));
 }
 
 function* evaluateJSAndCheckResult(input, result) {
   let response = yield evaluateJS(input);
--- a/devtools/shared/webconsole/test/test_jsterm.html
+++ b/devtools/shared/webconsole/test/test_jsterm.html
@@ -11,17 +11,16 @@
 <body>
 <p>Test for JavaScript terminal functionality</p>
 
 <script class="testbody" type="text/javascript;version=1.8">
 SimpleTest.waitForExplicitFinish();
 
 let gState;
 
-let {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 let {MAX_AUTOCOMPLETE_ATTEMPTS,MAX_AUTOCOMPLETIONS} = require("devtools/shared/webconsole/utils");
 
 // This test runs all of its assertions twice - once with
 // evaluateJS and once with evaluateJSAsync.
 let evaluatingSync = true;
 function evaluateJS(input, callback) {
   if (evaluatingSync) {
     gState.client.evaluateJS(input, callback);
--- a/devtools/shared/webconsole/test/unit/test_network_helper.js
+++ b/devtools/shared/webconsole/test/unit/test_network_helper.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
-const Cu = Components.utils;
+var Cu = Components.utils;
 const { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
 
 Object.defineProperty(this, "NetworkHelper", {
   get: function() {
     return require("devtools/shared/webconsole/network-helper");
   },
   configurable: true,
   writeable: false,
--- a/devtools/shared/webconsole/test/unit/test_security-info-certificate.js
+++ b/devtools/shared/webconsole/test/unit/test_security-info-certificate.js
@@ -12,17 +12,17 @@ Object.defineProperty(this, "NetworkHelp
   get: function() {
     return require("devtools/shared/webconsole/network-helper");
   },
   configurable: true,
   writeable: false,
   enumerable: true
 });
 
-const Ci = Components.interfaces;
+var Ci = Components.interfaces;
 const DUMMY_CERT = {
   commonName: "cn",
   organization: "o",
   organizationalUnit: "ou",
   issuerCommonName: "issuerCN",
   issuerOrganization: "issuerO",
   issuerOrganizationUnit: "issuerOU",
   sha256Fingerprint: "qwertyuiopoiuytrewq",
--- a/devtools/shared/webconsole/test/unit/test_security-info-parser.js
+++ b/devtools/shared/webconsole/test/unit/test_security-info-parser.js
@@ -12,17 +12,17 @@ Object.defineProperty(this, "NetworkHelp
   get: function() {
     return require("devtools/shared/webconsole/network-helper");
   },
   configurable: true,
   writeable: false,
   enumerable: true
 });
 
-const Ci = Components.interfaces;
+var Ci = Components.interfaces;
 const wpl = Ci.nsIWebProgressListener;
 const MockCertificate = {
   commonName: "cn",
   organization: "o",
   organizationalUnit: "ou",
   issuerCommonName: "issuerCN",
   issuerOrganization: "issuerO",
   issuerOrganizationUnit: "issuerOU",
--- a/devtools/shared/webconsole/test/unit/test_security-info-protocol-version.js
+++ b/devtools/shared/webconsole/test/unit/test_security-info-protocol-version.js
@@ -12,17 +12,17 @@ Object.defineProperty(this, "NetworkHelp
   get: function() {
     return require("devtools/shared/webconsole/network-helper");
   },
   configurable: true,
   writeable: false,
   enumerable: true
 });
 
-const Ci = Components.interfaces;
+var Ci = Components.interfaces;
 const TEST_CASES = [
   {
     description: "TLS_VERSION_1",
     input: 1,
     expected: "TLSv1"
   }, {
     description: "TLS_VERSION_1.1",
     input: 2,
--- a/devtools/shared/webconsole/test/unit/test_security-info-state.js
+++ b/devtools/shared/webconsole/test/unit/test_security-info-state.js
@@ -13,17 +13,17 @@ Object.defineProperty(this, "NetworkHelp
   get: function() {
     return require("devtools/shared/webconsole/network-helper");
   },
   configurable: true,
   writeable: false,
   enumerable: true
 });
 
-const Ci = Components.interfaces;
+var Ci = Components.interfaces;
 const wpl = Ci.nsIWebProgressListener;
 const MockSecurityInfo = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsITransportSecurityInfo,
                                          Ci.nsISSLStatusProvider]),
   securityState: wpl.STATE_IS_BROKEN,
   errorCode: 0,
   SSLStatus: {
     protocolVersion: 3, // nsISSLStatus.TLS_VERSION_1_2
--- a/devtools/shared/webconsole/test/unit/test_security-info-static-hpkp.js
+++ b/devtools/shared/webconsole/test/unit/test_security-info-static-hpkp.js
@@ -13,17 +13,17 @@ Object.defineProperty(this, "NetworkHelp
   get: function() {
     return require("devtools/shared/webconsole/network-helper");
   },
   configurable: true,
   writeable: false,
   enumerable: true
 });
 
-const Ci = Components.interfaces;
+var Ci = Components.interfaces;
 const wpl = Ci.nsIWebProgressListener;
 
 const MockSecurityInfo = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsITransportSecurityInfo,
                                          Ci.nsISSLStatusProvider]),
   securityState: wpl.STATE_IS_SECURE,
   errorCode: 0,
   SSLStatus: {
--- a/devtools/shared/webconsole/test/unit/test_security-info-weakness-reasons.js
+++ b/devtools/shared/webconsole/test/unit/test_security-info-weakness-reasons.js
@@ -12,17 +12,17 @@ Object.defineProperty(this, "NetworkHelp
   get: function() {
     return require("devtools/shared/webconsole/network-helper");
   },
   configurable: true,
   writeable: false,
   enumerable: true
 });
 
-const Ci = Components.interfaces;
+var Ci = Components.interfaces;
 const wpl = Ci.nsIWebProgressListener;
 const TEST_CASES = [
   {
     description: "weak cipher",
     input: wpl.STATE_IS_BROKEN | wpl.STATE_USES_WEAK_CRYPTO,
     expected: ["cipher"]
   }, {
     description: "only STATE_IS_BROKEN flag",
--- a/devtools/shared/worker-loader.js
+++ b/devtools/shared/worker-loader.js
@@ -424,17 +424,17 @@ var {
     }
 
     let xpcInspector = Cc["@mozilla.org/jsinspector;1"].
                        getService(Ci.nsIJSInspector);
 
     return {
       Debugger,
       createSandbox,
-      dump,
+      dump: this.dump,
       rpc,
       loadSubScript,
       reportError,
       setImmediate,
       xpcInspector
     };
   } else { // Worker thread
     let requestors = [];
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -10892,26 +10892,23 @@ nsDocShell::DoChannelLoad(nsIChannel* aC
       }
       break;
   }
 
   if (!aBypassClassifier) {
     loadFlags |= nsIChannel::LOAD_CLASSIFY_URI;
   }
 
-  (void)aChannel->SetLoadFlags(loadFlags);
-
   // If the user pressed shift-reload, then do not allow ServiceWorker
   // interception to occur. See step 12.1 of the SW HandleFetch algorithm.
   if (IsForceReloadType(mLoadType)) {
-    nsCOMPtr<nsIHttpChannelInternal> internal = do_QueryInterface(aChannel);
-    if (internal) {
-      internal->ForceNoIntercept();
-    }
-  }
+    loadFlags |= nsIChannel::LOAD_BYPASS_SERVICE_WORKER;
+  }
+
+  (void)aChannel->SetLoadFlags(loadFlags);
 
   uint32_t openFlags = 0;
   if (mLoadType == LOAD_LINK) {
     openFlags |= nsIURILoader::IS_CONTENT_PREFERRED;
   }
   if (!mAllowContentRetargeting) {
     openFlags |= nsIURILoader::DONT_RETARGET;
   }
@@ -13445,17 +13442,17 @@ nsDocShell::OnLinkClickSync(nsIContent* 
 
   // If this is an anchor element, grab its type property to use as a hint
   nsAutoString typeHint;
   nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(aContent));
   if (anchor) {
     anchor->GetType(typeHint);
     NS_ConvertUTF16toUTF8 utf8Hint(typeHint);
     nsAutoCString type, dummy;
-    NS_ParseContentType(utf8Hint, type, dummy);
+    NS_ParseRequestContentType(utf8Hint, type, dummy);
     CopyUTF8toUTF16(type, typeHint);
   }
 
   // Clone the URI now, in case a content policy or something messes
   // with it under InternalLoad; we do _not_ want to change the URI
   // our caller passed in.
   nsCOMPtr<nsIURI> clonedURI;
   aURI->Clone(getter_AddRefs(clonedURI));
--- a/docshell/test/browser/browser_loadURI.js
+++ b/docshell/test/browser/browser_loadURI.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
 const gPostData = "postdata=true";
 
 function test() {
   waitForExplicitFinish();
 
   let tab = gBrowser.selectedTab = gBrowser.addTab();
   registerCleanupFunction(function () {
--- a/docshell/test/browser/frame-head.js
+++ b/docshell/test/browser/frame-head.js
@@ -1,15 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Functions that are automatically loaded as frame scripts for
 // timeline tests.
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 var { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
 var { Promise } = Cu.import('resource://gre/modules/Promise.jsm', {});
 
 Cu.import("resource://gre/modules/Timer.jsm");
 
 // Functions that look like mochitest functions but forward to the
 // browser process.
 
--- a/docshell/test/chrome/chrome.ini
+++ b/docshell/test/chrome/chrome.ini
@@ -75,17 +75,17 @@ skip-if = toolkit == "gtk2"
 [test_bug565388.xul]
 skip-if = os == 'linux' || os == 'mac' # Bug 1026815
 [test_bug582176.xul]
 [test_bug608669.xul]
 [test_bug662200.xul]
 [test_bug690056.xul]
 [test_bug789773.xul]
 [test_bug846906.xul]
-skip-if = os == 'linux' && asan # Bug 1207161
+skip-if = (os == 'linux' && asan) || debug # Bug 1207161
 [test_bug89419.xul]
 [test_bug909218.html]
 [test_bug92598.xul]
 [test_mozFrameType.xul]
 [test_principalInherit.xul]
 [test_private_hidden_window.html]
 [test_viewsource_forbidden_in_iframe.xul]
 skip-if = true # bug 1019315
--- a/docshell/test/unit/head_docshell.js
+++ b/docshell/test/unit/head_docshell.js
@@ -1,11 +1,11 @@
 /* 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/. */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
 
 var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
              getService(Ci.nsIProperties);
 var profileDir = do_get_profile();
--- a/docshell/test/unit/test_nsDefaultURIFixup_search.js
+++ b/docshell/test/unit/test_nsDefaultURIFixup_search.js
@@ -1,40 +1,40 @@
-let urifixup = Cc["@mozilla.org/docshell/urifixup;1"].
+var urifixup = Cc["@mozilla.org/docshell/urifixup;1"].
                getService(Ci.nsIURIFixup);
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/AppConstants.jsm");
 
 Services.prefs.setBoolPref("keyword.enabled", true);
 
 const kSearchEngineID = "test_urifixup_search_engine";
 const kSearchEngineURL = "http://www.example.org/?search={searchTerms}";
 Services.search.addEngineWithDetails(kSearchEngineID, "", "", "", "get",
                                      kSearchEngineURL);
 
-let oldDefaultEngine = Services.search.defaultEngine;
+var oldDefaultEngine = Services.search.defaultEngine;
 Services.search.defaultEngine = Services.search.getEngineByName(kSearchEngineID);
 
-let selectedName = Services.search.defaultEngine.name;
+var selectedName = Services.search.defaultEngine.name;
 do_check_eq(selectedName, kSearchEngineID);
 
 do_register_cleanup(function() {
   if (oldDefaultEngine) {
     Services.search.defaultEngine = oldDefaultEngine;
   }
   let engine = Services.search.getEngineByName(kSearchEngineID);
   if (engine) {
     Services.search.removeEngine(engine);
   }
   Services.prefs.clearUserPref("keyword.enabled");
 });
 
-let isWin = AppConstants.platform == "win";
+var isWin = AppConstants.platform == "win";
 
-let data = [
+var data = [
   {
     // Valid should not be changed.
     wrong: 'https://example.com/this/is/a/test.html',
     fixed: 'https://example.com/this/is/a/test.html',
   },
   {
     // Unrecognized protocols should be changed.
     wrong: 'whatever://this/is/a/test.html',
@@ -85,31 +85,31 @@ let data = [
     fixed: 'http://user:pass@example.com:8080/this/is/a/test.html',
   },
   {
     wrong: 'whatever://this/is/a@b/test.html',
     fixed: kSearchEngineURL.replace("{searchTerms}", encodeURIComponent('whatever://this/is/a@b/test.html')),
   },
 ];
 
-let extProtocolSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"]
+var extProtocolSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"]
                      .getService(Ci.nsIExternalProtocolService);
 
 if (extProtocolSvc && extProtocolSvc.externalProtocolHandlerExists("mailto")) {
   data.push({
     wrong: "mailto:foo@bar.com",
     fixed: "mailto:foo@bar.com"
   });
 }
 
 function run_test() {
   run_next_test();
 }
 
-let len = data.length;
+var len = data.length;
 // Make sure we fix what needs fixing
 add_task(function test_fix_unknown_schemes() {
   for (let i = 0; i < len; ++i) {
     let item = data[i];
     let result =
       urifixup.createFixupURI(item.wrong,
                               urifixup.FIXUP_FLAG_FIX_SCHEME_TYPOS).spec;
     do_check_eq(result, item.fixed);
--- a/docshell/test/unit_ipc/test_pb_notification_ipc.js
+++ b/docshell/test/unit_ipc/test_pb_notification_ipc.js
@@ -1,10 +1,10 @@
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
 
 function run_test() {
   var notifications = 0;
   var obs = {
     observe: function(aSubject, aTopic, aData) {
       do_check_eq(aTopic, "last-pb-context-exited");
       notifications++;
     }
--- a/dom/activities/tests/mochi/common.js
+++ b/dom/activities/tests/mochi/common.js
@@ -1,9 +1,9 @@
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 const ACTIVITY_GLUE_CID = Components.ID("{f4cfbe10-a106-4cd1-b04e-0d2a6aac138b}");
 const SYS_MSG_GLUE_CID = Components.ID("{b0b6b9af-bc4e-4200-bffe-fb7691065ec9}");
 
 const gRootUrl = "http://test/chrome/dom/activities/tests/mochi/";
 
 function registerComponent(aObject, aDescription, aContract, aCid) {
   info("Registering " + aCid);
--- a/dom/alarm/test/system_message_chrome_script.js
+++ b/dom/alarm/test/system_message_chrome_script.js
@@ -1,14 +1,14 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 'use strict';
 
-const { classes: Cc, interfaces: Ci } = Components;
+var { classes: Cc, interfaces: Ci } = Components;
 
 const systemMessenger = Cc["@mozilla.org/system-message-internal;1"]
                           .getService(Ci.nsISystemMessagesInternal);
 const ioService = Cc["@mozilla.org/network/io-service;1"]
                     .getService(Ci.nsIIOService);
 
 addMessageListener("trigger-register-page", function(aData) {
   systemMessenger.registerPage(aData.type,
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/Animation.cpp
@@ -46,25 +46,27 @@ Animation::WrapObject(JSContext* aCx, JS
 //
 // Animation interface:
 //
 // ---------------------------------------------------------------------------
 
 void
 Animation::SetEffect(KeyframeEffectReadOnly* aEffect)
 {
+  nsRefPtr<Animation> kungFuDeathGrip(this);
+
   if (mEffect == aEffect) {
     return;
   }
   if (mEffect) {
-    mEffect->SetParentTime(Nullable<TimeDuration>());
+    mEffect->SetAnimation(nullptr);
   }
   mEffect = aEffect;
   if (mEffect) {
-    mEffect->SetParentTime(GetCurrentTime());
+    mEffect->SetAnimation(this);
   }
 
   UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async);
 }
 
 void
 Animation::SetTimeline(AnimationTimeline* aTimeline)
 {
@@ -81,16 +83,17 @@ Animation::SetTimeline(AnimationTimeline
   // FIXME(spec): Once we implement the seeking defined in the spec
   // surely this should be SeekFlag::DidSeek but the spec says otherwise.
   UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async);
 
   // FIXME: When we expose this method to script we'll need to call PostUpdate
   // (but *not* when this method gets called from style).
 }
 
+// https://w3c.github.io/web-animations/#set-the-animation-start-time
 void
 Animation::SetStartTime(const Nullable<TimeDuration>& aNewStartTime)
 {
   Nullable<TimeDuration> timelineTime;
   if (mTimeline) {
     // The spec says to check if the timeline is active (has a resolved time)
     // before using it here, but we don't need to since it's harmless to set
     // the already null time to null.
@@ -116,17 +119,17 @@ Animation::SetStartTime(const Nullable<T
     // MaybeResolve is a no-op, so that's okay.
     mReady->MaybeResolve(this);
   }
 
   UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async);
   PostUpdate();
 }
 
-// http://w3c.github.io/web-animations/#current-time
+// https://w3c.github.io/web-animations/#current-time
 Nullable<TimeDuration>
 Animation::GetCurrentTime() const
 {
   Nullable<TimeDuration> result;
   if (!mHoldTime.IsNull()) {
     result = mHoldTime;
     return result;
   }
@@ -136,17 +139,17 @@ Animation::GetCurrentTime() const
     if (!timelineTime.IsNull()) {
       result.SetValue((timelineTime.Value() - mStartTime.Value())
                         .MultDouble(mPlaybackRate));
     }
   }
   return result;
 }
 
-// Implements http://w3c.github.io/web-animations/#set-the-current-time
+// https://w3c.github.io/web-animations/#set-the-current-time
 void
 Animation::SetCurrentTime(const TimeDuration& aSeekTime)
 {
   SilentlySetCurrentTime(aSeekTime);
 
   if (mPendingState == PendingState::PausePending) {
     // Finish the pause operation
     mHoldTime.SetValue(aSeekTime);
@@ -157,26 +160,28 @@ Animation::SetCurrentTime(const TimeDura
     }
     CancelPendingTasks();
   }
 
   UpdateTiming(SeekFlag::DidSeek, SyncNotifyFlag::Async);
   PostUpdate();
 }
 
+// https://w3c.github.io/web-animations/#set-the-animation-playback-rate
 void
 Animation::SetPlaybackRate(double aPlaybackRate)
 {
   Nullable<TimeDuration> previousTime = GetCurrentTime();
   mPlaybackRate = aPlaybackRate;
   if (!previousTime.IsNull()) {
     SetCurrentTime(previousTime.Value());
   }
 }
 
+// https://w3c.github.io/web-animations/#play-state
 AnimationPlayState
 Animation::PlayState() const
 {
   if (mPendingState != PendingState::NotPending) {
     return AnimationPlayState::Pending;
   }
 
   Nullable<TimeDuration> currentTime = GetCurrentTime();
@@ -290,16 +295,17 @@ Animation::Play(ErrorResult& aRv, LimitB
 
 void
 Animation::Pause(ErrorResult& aRv)
 {
   DoPause(aRv);
   PostUpdate();
 }
 
+// https://w3c.github.io/web-animations/#reverse-an-animation
 void
 Animation::Reverse(ErrorResult& aRv)
 {
   if (!mTimeline || mTimeline->GetCurrentTime().IsNull()) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
   }
 
@@ -349,25 +355,28 @@ Animation::SetCurrentTimeAsDouble(const 
   return SetCurrentTime(TimeDuration::FromMilliseconds(aCurrentTime.Value()));
 }
 
 // ---------------------------------------------------------------------------
 
 void
 Animation::Tick()
 {
-  // Since we are not guaranteed to get only one call per refresh driver tick,
-  // it's possible that mPendingReadyTime is set to a time in the future.
-  // In that case, we should wait until the next refresh driver tick before
-  // resuming.
+  // Finish pending if we have a pending ready time, but only if we also
+  // have an active timeline.
   if (mPendingState != PendingState::NotPending &&
       !mPendingReadyTime.IsNull() &&
       mTimeline &&
-      !mTimeline->GetCurrentTime().IsNull() &&
-      mPendingReadyTime.Value() <= mTimeline->GetCurrentTime().Value()) {
+      !mTimeline->GetCurrentTime().IsNull()) {
+    // Even though mPendingReadyTime is initialized using TimeStamp::Now()
+    // during the *previous* tick of the refresh driver, it can still be
+    // ahead of the *current* timeline time when we are using the
+    // vsync timer so we need to clamp it to the timeline time.
+    mPendingReadyTime.SetValue(std::min(mTimeline->GetCurrentTime().Value(),
+                                        mPendingReadyTime.Value()));
     FinishPendingAt(mPendingReadyTime.Value());
     mPendingReadyTime.SetNull();
   }
 
   if (IsPossiblyOrphanedPendingAnimation()) {
     MOZ_ASSERT(mTimeline && !mTimeline->GetCurrentTime().IsNull(),
                "Orphaned pending animtaions should have an active timeline");
     FinishPendingAt(mTimeline->GetCurrentTime().Value());
@@ -441,17 +450,17 @@ Animation::GetCurrentOrPendingStartTime(
 
   // Calculate the equivalent start time from the pending ready time.
   // This is the same as the calculation performed in ResumeAt and will
   // need to incorporate the playbackRate when implemented (bug 1127380).
   result.SetValue(mPendingReadyTime.Value() - mHoldTime.Value());
   return result;
 }
 
-// http://w3c.github.io/web-animations/#silently-set-the-current-time
+// https://w3c.github.io/web-animations/#silently-set-the-current-time
 void
 Animation::SilentlySetCurrentTime(const TimeDuration& aSeekTime)
 {
   if (!mHoldTime.IsNull() ||
       mStartTime.IsNull() ||
       !mTimeline ||
       mTimeline->GetCurrentTime().IsNull() ||
       mPlaybackRate == 0.0) {
@@ -472,16 +481,17 @@ Animation::SilentlySetPlaybackRate(doubl
 {
   Nullable<TimeDuration> previousTime = GetCurrentTime();
   mPlaybackRate = aPlaybackRate;
   if (!previousTime.IsNull()) {
     SilentlySetCurrentTime(previousTime.Value());
   }
 }
 
+// https://w3c.github.io/web-animations/#cancel-an-animation
 void
 Animation::DoCancel()
 {
   if (mPendingState != PendingState::NotPending) {
     CancelPendingTasks();
     if (mReady) {
       mReady->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
     }
@@ -561,27 +571,26 @@ Animation::CanThrottle() const
   }
 
   return IsRunningOnCompositor();
 }
 
 void
 Animation::ComposeStyle(nsRefPtr<AnimValuesStyleRule>& aStyleRule,
                         nsCSSPropertySet& aSetProperties,
-                        bool& aNeedsRefreshes)
+                        bool& aStyleChanging)
 {
   if (!mEffect) {
     return;
   }
 
   AnimationPlayState playState = PlayState();
   if (playState == AnimationPlayState::Running ||
-      playState == AnimationPlayState::Pending ||
-      HasEndEventToQueue()) {
-    aNeedsRefreshes = true;
+      playState == AnimationPlayState::Pending) {
+    aStyleChanging = true;
   }
 
   if (!IsInEffect()) {
     return;
   }
 
   // In order to prevent flicker, there are a few cases where we want to use
   // a different time for rendering that would otherwise be returned by
@@ -657,17 +666,17 @@ Animation::NotifyEffectTimingUpdated()
 {
   MOZ_ASSERT(mEffect,
              "We should only update timing effect when we have a target "
              "effect");
   UpdateTiming(Animation::SeekFlag::NoSeek,
                Animation::SyncNotifyFlag::Async);
 }
 
-// http://w3c.github.io/web-animations/#play-an-animation
+// https://w3c.github.io/web-animations/#play-an-animation
 void
 Animation::DoPlay(ErrorResult& aRv, LimitBehavior aLimitBehavior)
 {
   bool abortedPause = mPendingState == PendingState::PausePending;
 
   Nullable<TimeDuration> currentTime = GetCurrentTime();
   if (mPlaybackRate > 0.0 &&
       (currentTime.IsNull() ||
@@ -732,17 +741,17 @@ Animation::DoPlay(ErrorResult& aRv, Limi
     tracker->AddPlayPending(*this);
   } else {
     TriggerOnNextTick(Nullable<TimeDuration>());
   }
 
   UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async);
 }
 
-// http://w3c.github.io/web-animations/#pause-an-animation
+// https://w3c.github.io/web-animations/#pause-an-animation
 void
 Animation::DoPause(ErrorResult& aRv)
 {
   if (IsPausedOrPausing()) {
     return;
   }
 
   // If we are transitioning from idle, fill in the current time
@@ -843,16 +852,17 @@ Animation::UpdateTiming(SeekFlag aSeekFl
   UpdateFinishedState(aSeekFlag, aSyncNotifyFlag);
   UpdateEffect();
 
   if (mTimeline) {
     mTimeline->NotifyAnimationUpdated(*this);
   }
 }
 
+// https://w3c.github.io/web-animations/#update-an-animations-finished-state
 void
 Animation::UpdateFinishedState(SeekFlag aSeekFlag,
                                SyncNotifyFlag aSyncNotifyFlag)
 {
   Nullable<TimeDuration> currentTime = GetCurrentTime();
   TimeDuration effectEnd = TimeDuration(EffectEnd());
 
   if (!mStartTime.IsNull() &&
@@ -897,17 +907,16 @@ Animation::UpdateFinishedState(SeekFlag 
   // changes the code above made.