Merge inbound to mozilla-central. a=merge
authorNoemi Erli <nerli@mozilla.com>
Wed, 22 Aug 2018 19:28:33 +0300
changeset 490582 d6e4d3e69d4c8331cfa35c318b616ed390d3538d
parent 490530 61396b1eaa14477e196564ea0c4c0ba79439a64d (current diff)
parent 490581 5c44264ed1fec9b4fad27c0c18de7d383597d847 (diff)
child 490608 ed054a84c6a3ad17821235ff1053930d87583d9e
child 490640 ab8276b5924e4ade5daec800cefc702f72cef34c
push id1815
push userffxbld-merge
push dateMon, 15 Oct 2018 10:40:45 +0000
treeherdermozilla-release@18d4c09e9378 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone63.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 mozilla-central. a=merge
browser/base/content/browser-contentblocking.js
js/rust/src/ac.rs
testing/web-platform/meta/css/css-shapes/shape-outside/values/shape-outside-ellipse-000.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/values/shape-outside-ellipse-009.html.ini
testing/web-platform/meta/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html.ini
testing/web-platform/meta/webdriver/tests/new_session/merge.py.ini
third_party/rust/rustc-serialize/.cargo-checksum.json
third_party/rust/rustc-serialize/.travis.yml
third_party/rust/rustc-serialize/Cargo.toml
third_party/rust/rustc-serialize/LICENSE-APACHE
third_party/rust/rustc-serialize/LICENSE-MIT
third_party/rust/rustc-serialize/README.md
third_party/rust/rustc-serialize/appveyor.yml
third_party/rust/rustc-serialize/benches/base64.rs
third_party/rust/rustc-serialize/benches/hex.rs
third_party/rust/rustc-serialize/benches/json.rs
third_party/rust/rustc-serialize/src/base64.rs
third_party/rust/rustc-serialize/src/collection_impls.rs
third_party/rust/rustc-serialize/src/hex.rs
third_party/rust/rustc-serialize/src/json.rs
third_party/rust/rustc-serialize/src/lib.rs
third_party/rust/rustc-serialize/src/serialize.rs
toolkit/components/privatebrowsing/PrivateBrowsing.manifest
toolkit/components/privatebrowsing/PrivateBrowsingTrackingProtectionWhitelist.js
toolkit/components/privatebrowsing/moz.build
toolkit/components/privatebrowsing/nsIPrivateBrowsingTrackingProtectionWhitelist.idl
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -801,42 +801,46 @@ dependencies = [
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "geckodriver"
 version = "0.21.0"
 dependencies = [
+ "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "mozprofile 0.3.0",
  "mozrunner 0.7.0",
  "mozversion 0.1.3",
  "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.66 (git+https://github.com/servo/serde?branch=deserialize_from_enums8)",
+ "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "webdriver 0.36.0",
  "zip 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "geckoservo"
 version = "0.0.1"
 dependencies = [
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of 0.0.1",
  "nsstring 0.1.0",
+ "num-traits 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "servo_arc 0.1.1",
  "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
  "style_traits 0.0.1",
 ]
 
@@ -1832,29 +1836,29 @@ version = "0.10.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "rustc-demangle"
 version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
-name = "rustc-serialize"
-version = "0.3.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
 name = "rustc_version"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "ryu"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "safemem"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "same-file"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1924,16 +1928,26 @@ version = "1.0.66"
 source = "git+https://github.com/servo/serde?branch=deserialize_from_enums8#c4457d804b38b14e699b45c01d1909f93f25ab5e"
 dependencies = [
  "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "serde_json"
+version = "1.0.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ryu 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "servo_arc"
 version = "0.1.1"
 dependencies = [
  "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2095,16 +2109,17 @@ dependencies = [
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "geckoservo 0.0.1",
  "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of 0.0.1",
+ "num-traits 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "size_of_test 0.0.1",
  "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
  "style_traits 0.0.1",
 ]
 
@@ -2407,21 +2422,25 @@ dependencies = [
  "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "webdriver"
 version = "0.36.0"
 dependencies = [
+ "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.66 (git+https://github.com/servo/serde?branch=deserialize_from_enums8)",
+ "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "webidl"
 version = "0.6.0"
@@ -2790,27 +2809,28 @@ dependencies = [
 "checksum regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75ecf88252dce580404a22444fc7d626c01815debba56a7f4f536772a5ff19d3"
 "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
 "checksum regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1ac0f60d675cc6cf13a20ec076568254472551051ad5dd050364d70671bf6b"
 "checksum rkv 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "21983ae9330b1e1cb1d01868229618a3c7cc5134955f0dc1a86a0a1886f3acb7"
 "checksum ron 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "da06feaa07f69125ab9ddc769b11de29090122170b402547f64b86fe16ebc399"
 "checksum runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d79b4b604167921892e84afbbaad9d5ad74e091bf6c511d9dbfb0593f09fabd"
 "checksum rust-ini 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8a654c5bda722c699be6b0fe4c0d90de218928da5b724c3e467fc48865c37263"
 "checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649"
-"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
 "checksum rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69"
+"checksum ryu 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0568787116e13c652377b6846f5931454a363a8fdf8ae50463ee40935b278b"
 "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
 "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
 "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
 "checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
 "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 "checksum serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "e9a2d9a9ac5120e0f768801ca2b58ad6eec929dc9d1d616c162f208869c2ce95"
 "checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3"
 "checksum serde_derive 1.0.66 (git+https://github.com/servo/serde?branch=deserialize_from_enums8)" = "<none>"
+"checksum serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "44dd2cfde475037451fa99b7e5df77aa3cfd1536575fa8e7a538ab36dcde49ae"
 "checksum simd 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ed3686dd9418ebcc3a26a0c0ae56deab0681e53fe899af91f5bbcee667ebffb1"
 "checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84"
 "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
 "checksum smallbitvec 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c63726029f0069f88467873e47f392575f28f9f16b72ac65465263db4b3a13c"
 "checksum smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "26df3bb03ca5eac2e64192b723d51f56c1b1e0860e7c766281f4598f181acdc8"
 "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
 "checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
 "checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7"
--- a/browser/base/content/browser-context.inc
+++ b/browser/base/content/browser-context.inc
@@ -351,35 +351,32 @@
           <menuitem id="context-printframe"
                     label="&printFrameCmd.label;"
                     accesskey="&printFrameCmd.accesskey;"
                     oncommand="gContextMenu.printFrame();"/>
           <menuseparator/>
           <menuitem id="context-viewframesource"
                     label="&viewFrameSourceCmd.label;"
                     accesskey="&viewFrameSourceCmd.accesskey;"
-                    oncommand="gContextMenu.viewFrameSource();"
-                    observes="isFrameImage"/>
+                    oncommand="gContextMenu.viewFrameSource();"/>
           <menuitem id="context-viewframeinfo"
                     label="&viewFrameInfoCmd.label;"
                     accesskey="&viewFrameInfoCmd.accesskey;"
                     oncommand="gContextMenu.viewFrameInfo();"/>
         </menupopup>
       </menu>
       <menuitem id="context-viewpartialsource-selection"
                 label="&viewPartialSourceForSelectionCmd.label;"
                 accesskey="&viewPartialSourceCmd.accesskey;"
-                oncommand="gContextMenu.viewPartialSource();"
-                observes="isImage"/>
+                oncommand="gContextMenu.viewPartialSource();"/>
       <menuseparator id="context-sep-viewsource"/>
       <menuitem id="context-viewsource"
                 label="&viewPageSourceCmd.label;"
                 accesskey="&viewPageSourceCmd.accesskey;"
-                oncommand="BrowserViewSource(gContextMenu.browser);"
-                observes="canViewSource"/>
+                oncommand="BrowserViewSource(gContextMenu.browser);"/>
       <menuitem id="context-viewinfo"
                 label="&viewPageInfoCmd.label;"
                 accesskey="&viewPageInfoCmd.accesskey;"
                 oncommand="gContextMenu.viewInfo();"/>
       <menuseparator id="spell-separator"/>
       <menuitem id="spell-check-enabled"
                 label="&spellCheckToggle.label;"
                 type="checkbox"
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -84,18 +84,17 @@
                           accesskey="&printCmd.accesskey;"
                           key="printKb"
                           command="cmd_print"/>
                 <menuseparator/>
                 <menuitem id="goOfflineMenuitem"
                           label="&goOfflineCmd.label;"
                           accesskey="&goOfflineCmd.accesskey;"
                           type="checkbox"
-                          observes="workOfflineMenuitemState"
-                          oncommand="BrowserOffline.toggleOfflineStatus();"/>
+                          command="cmd_toggleOfflineStatus"/>
                 <menuitem id="menu_FileQuitItem"
 #ifdef XP_WIN
                           label="&quitApplicationCmdWin2.label;"
                           accesskey="&quitApplicationCmdWin2.accesskey;"
 #elifdef XP_MACOSX
                           label="&quitApplicationCmdMac2.label;"
 #else
                           label="&quitApplicationCmd.label;"
@@ -241,17 +240,17 @@
                               label="&fullZoomToggleCmd.label;"
                               accesskey="&fullZoomToggleCmd.accesskey;"
                               type="checkbox"
                               command="cmd_fullZoomToggle"
                               checked="false"/>
                   </menupopup>
                 </menu>
                 <menu id="pageStyleMenu" label="&pageStyleMenu.label;"
-                      accesskey="&pageStyleMenu.accesskey;" observes="isImage">
+                      accesskey="&pageStyleMenu.accesskey;">
                   <menupopup onpopupshowing="gPageStyleMenu.fillPopup(this);">
                     <menuitem id="menu_pageStyleNoStyle"
                               label="&pageStyleNoStyle.label;"
                               accesskey="&pageStyleNoStyle.accesskey;"
                               oncommand="gPageStyleMenu.disableStyle();"
                               type="radio"/>
                     <menuitem id="menu_pageStylePersistentOnly"
                               label="&pageStylePersistentOnly.label;"
@@ -513,27 +512,28 @@
               <menu id="webDeveloperMenu"
                     label="&webDeveloperMenu.label;"
                     accesskey="&webDeveloperMenu.accesskey;">
                 <menupopup id="menuWebDeveloperPopup">
                   <menuitem id="menu_pageSource"
                             label="&pageSourceCmd.label;"
                             key="key_viewSource"
                             command="View:PageSource"
-                            accesskey="&pageSourceCmd.accesskey;">
-                    <observes element="canViewSource" attribute="disabled"/>
-                  </menuitem>
+                            accesskey="&pageSourceCmd.accesskey;"/>
                   <menuitem id="menu_devtools_recordExecution"
-                            observes="devtoolsMenuBroadcaster_RecordExecution"
+                            label="&devtoolsRecordExecution.label;"
+                            command="Tools:RecordExecution"
                             hidden="true"/>
                   <menuitem id="menu_devtools_saveRecording"
-                            observes="devtoolsMenuBroadcaster_SaveRecording"
+                            label="&devtoolsSaveRecording.label;"
+                            command="Tools:SaveRecording"
                             hidden="true"/>
                   <menuitem id="menu_devtools_replayExecution"
-                            observes="devtoolsMenuBroadcaster_ReplayExecution"
+                            label="&devtoolsReplayExecution.label;"
+                            command="Tools:ReplayExecution"
                             hidden="true"/>
                 </menupopup>
               </menu>
               <menuitem id="menu_pageInfo"
                         accesskey="&pageInfoCmd.accesskey;"
                         label="&pageInfoCmd.label;"
 #ifndef XP_WIN
                         key="key_viewInfo"
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -32,33 +32,28 @@
 
     <command id="cmd_pageSetup" oncommand="PrintUtils.showPageSetup();"/>
     <command id="cmd_print" oncommand="PrintUtils.printWindow(window.gBrowser.selectedBrowser.outerWindowID, window.gBrowser.selectedBrowser);"/>
     <command id="cmd_printPreview" oncommand="PrintUtils.printPreview(PrintPreviewListener);"/>
     <command id="cmd_close" oncommand="BrowserCloseTabOrWindow(event);"/>
     <command id="cmd_closeWindow" oncommand="BrowserTryToCloseWindow()"/>
     <command id="cmd_toggleMute" oncommand="gBrowser.selectedTab.toggleMuteAudio()"/>
     <command id="cmd_CustomizeToolbars" oncommand="gCustomizeMode.enter()"/>
+    <command id="cmd_toggleOfflineStatus" oncommand="BrowserOffline.toggleOfflineStatus();"/>
     <command id="cmd_quitApplication" oncommand="goQuitApplication()"/>
 
 #include ../../../toolkit/content/editMenuCommands.inc.xul
 
-    <command id="View:PageSource" oncommand="BrowserViewSource(window.gBrowser.selectedBrowser);" observes="canViewSource"/>
+    <command id="View:PageSource" oncommand="BrowserViewSource(window.gBrowser.selectedBrowser);"/>
     <command id="View:PageInfo" oncommand="BrowserPageInfo();"/>
     <command id="View:FullScreen" oncommand="BrowserFullScreen();"/>
     <command id="View:ReaderView" oncommand="ReaderParent.toggleReaderMode(event);"/>
-    <command id="cmd_find"
-             oncommand="gLazyFindCommand('onFindCommand')"
-             observes="isImage"/>
-    <command id="cmd_findAgain"
-             oncommand="gLazyFindCommand('onFindAgainCommand', false)"
-             observes="isImage"/>
-    <command id="cmd_findPrevious"
-             oncommand="gLazyFindCommand('onFindAgainCommand', true)"
-             observes="isImage"/>
+    <command id="cmd_find" oncommand="gLazyFindCommand('onFindCommand')"/>
+    <command id="cmd_findAgain" oncommand="gLazyFindCommand('onFindAgainCommand', false)"/>
+    <command id="cmd_findPrevious" oncommand="gLazyFindCommand('onFindAgainCommand', true)"/>
 #ifdef XP_MACOSX
     <command id="cmd_findSelection" oncommand="gLazyFindCommand('onFindSelectionCommand')"/>
 #endif
     <!-- work-around bug 392512 -->
     <command id="Browser:AddBookmarkAs"
              oncommand="PlacesCommandHook.bookmarkPage();"/>
     <!-- The command disabled state must be manually updated through
          PlacesCommandHook.updateBookmarkAllTabsCommand() -->
@@ -116,33 +111,16 @@
     <command id="zoomWindow"
              label="&zoomWindow.label;"
              oncommand="zoomWindow();" />
 #endif
   </commandset>
 
 #include ../../components/places/content/placesCommands.inc.xul
 
-  <broadcasterset id="mainBroadcasterSet">
-    <broadcaster id="isImage"/>
-    <broadcaster id="canViewSource"/>
-    <broadcaster id="isFrameImage"/>
-
-    <broadcaster id="workOfflineMenuitemState"/>
-    <broadcaster id="devtoolsMenuBroadcaster_RecordExecution"
-                 label="&devtoolsRecordExecution.label;"
-                 command="Tools:RecordExecution"/>
-    <broadcaster id="devtoolsMenuBroadcaster_SaveRecording"
-                 label="&devtoolsSaveRecording.label;"
-                 command="Tools:SaveRecording"/>
-    <broadcaster id="devtoolsMenuBroadcaster_ReplayExecution"
-                 label="&devtoolsReplayExecution.label;"
-                 command="Tools:ReplayExecution"/>
-  </broadcasterset>
-
   <keyset id="mainKeyset">
     <key id="key_newNavigator"
          key="&newNavigatorCmd.key;"
          command="cmd_newNavigator"
          modifiers="accel" reserved="true"/>
     <key id="key_newNavigatorTab" key="&tabCmd.commandkey;" modifiers="accel"
          command="cmd_newNavigatorTabNoEvent" reserved="true"/>
     <key id="focusURLBar" key="&openCmd.commandkey;" command="Browser:OpenLocation"
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -23,16 +23,24 @@
   background-image: var(--lwt-header-image) !important;
   background-position: right top !important;
 }
 
 :root:-moz-lwtheme:-moz-window-inactive {
   background-color: var(--lwt-accent-color-inactive, var(--lwt-accent-color)) !important;
 }
 
+/* Set additional backgrounds alignment relative to toolbox */
+
+#navigator-toolbox:-moz-lwtheme {
+  background-image: var(--lwt-additional-images);
+  background-position: var(--lwt-background-alignment);
+  background-repeat: var(--lwt-background-tiling);
+}
+
 #main-window:not([chromehidden~="toolbar"]) {
 %ifdef XP_MACOSX
   min-width: 335px;
 %else
   min-width: 300px;
 %endif
 }
 
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -338,38 +338,38 @@ function isInitialPage(url) {
 
 function* browserWindows() {
   let windows = Services.wm.getEnumerator("navigator:browser");
   while (windows.hasMoreElements())
     yield windows.getNext();
 }
 
 function UpdateBackForwardCommands(aWebNavigation) {
-  var backBroadcaster = document.getElementById("Browser:Back");
-  var forwardBroadcaster = document.getElementById("Browser:Forward");
-
-  // Avoid setting attributes on broadcasters if the value hasn't changed!
+  var backCommand = document.getElementById("Browser:Back");
+  var forwardCommand = document.getElementById("Browser:Forward");
+
+  // Avoid setting attributes on commands if the value hasn't changed!
   // Remember, guys, setting attributes on elements is expensive!  They
   // get inherited into anonymous content, broadcast to other widgets, etc.!
   // Don't do it if the value hasn't changed! - dwh
 
-  var backDisabled = backBroadcaster.hasAttribute("disabled");
-  var forwardDisabled = forwardBroadcaster.hasAttribute("disabled");
+  var backDisabled = backCommand.hasAttribute("disabled");
+  var forwardDisabled = forwardCommand.hasAttribute("disabled");
   if (backDisabled == aWebNavigation.canGoBack) {
     if (backDisabled)
-      backBroadcaster.removeAttribute("disabled");
+      backCommand.removeAttribute("disabled");
     else
-      backBroadcaster.setAttribute("disabled", true);
+      backCommand.setAttribute("disabled", true);
   }
 
   if (forwardDisabled == aWebNavigation.canGoForward) {
     if (forwardDisabled)
-      forwardBroadcaster.removeAttribute("disabled");
+      forwardCommand.removeAttribute("disabled");
     else
-      forwardBroadcaster.setAttribute("disabled", true);
+      forwardCommand.setAttribute("disabled", true);
   }
 }
 
 /**
  * Click-and-Hold implementation for the Back and Forward buttons
  * XXXmano: should this live in toolbarbutton.xml?
  */
 function SetClickAndHoldHandlers() {
@@ -4519,23 +4519,32 @@ var XULBrowserWindow = {
   get stopCommand() {
     delete this.stopCommand;
     return this.stopCommand = document.getElementById("Browser:Stop");
   },
   get reloadCommand() {
     delete this.reloadCommand;
     return this.reloadCommand = document.getElementById("Browser:Reload");
   },
-  get isImage() {
-    delete this.isImage;
-    return this.isImage = document.getElementById("isImage");
-  },
-  get canViewSource() {
-    delete this.canViewSource;
-    return this.canViewSource = document.getElementById("canViewSource");
+  get elementsForTextBasedTypes() {
+    delete this.elementsForTextBasedTypes;
+    return this.elementsForTextBasedTypes = [
+      document.getElementById("pageStyleMenu"),
+      document.getElementById("context-viewpartialsource-selection"),
+      document.getElementById("cmd_find"),
+      document.getElementById("cmd_findAgain"),
+      document.getElementById("cmd_findPrevious"),
+    ];
+  },
+  get elementsForViewSource() {
+    delete this.elementsForViewSource;
+    return this.elementsForViewSource = [
+      document.getElementById("context-viewsource"),
+      document.getElementById("View:PageSource"),
+    ];
   },
 
   forceInitialBrowserNonRemote(aOpener) {
     gBrowser.updateBrowserRemoteness(gBrowser.initialBrowser, false, { opener: aOpener });
   },
 
   setDefaultStatus(status) {
     this.defaultStatus = status;
@@ -4679,27 +4688,32 @@ var XULBrowserWindow = {
             }
           }
         }
 
         this.status = "";
         this.setDefaultStatus(msg);
 
         // Disable menu entries for images, enable otherwise
-        if (browser.documentContentType && BrowserUtils.mimeTypeIsTextBased(browser.documentContentType)) {
-          this.isImage.removeAttribute("disabled");
-        } else {
-          canViewSource = false;
-          this.isImage.setAttribute("disabled", "true");
+        let isText = browser.documentContentType &&
+                     BrowserUtils.mimeTypeIsTextBased(browser.documentContentType);
+        for (let element of this.elementsForTextBasedTypes) {
+          if (isText) {
+            element.removeAttribute("disabled");
+          } else {
+            element.setAttribute("disabled", "true");
+          }
         }
 
-        if (canViewSource) {
-          this.canViewSource.removeAttribute("disabled");
-        } else {
-          this.canViewSource.setAttribute("disabled", "true");
+        for (let element of this.elementsForViewSource) {
+          if (canViewSource && isText) {
+            element.removeAttribute("disabled");
+          } else {
+            element.setAttribute("disabled", "true");
+          }
         }
       }
 
       this.isBusy = false;
 
       if (this.busyUI) {
         this.busyUI = false;
 
@@ -4728,20 +4742,25 @@ var XULBrowserWindow = {
           }
         }
       }
     }
 
     let browser = gBrowser.selectedBrowser;
 
     // Disable menu entries for images, enable otherwise
-    if (browser.documentContentType && BrowserUtils.mimeTypeIsTextBased(browser.documentContentType))
-      this.isImage.removeAttribute("disabled");
-    else
-      this.isImage.setAttribute("disabled", "true");
+    let isText = browser.documentContentType &&
+                 BrowserUtils.mimeTypeIsTextBased(browser.documentContentType);
+    for (let element of this.elementsForTextBasedTypes) {
+      if (isText) {
+        element.removeAttribute("disabled");
+      } else {
+        element.setAttribute("disabled", "true");
+      }
+    }
 
     this.hideOverLinkImmediately = true;
     this.setOverLink("", null);
     this.hideOverLinkImmediately = false;
 
     // We should probably not do this if the value has changed since the user
     // searched
     // Update urlbar only if a new page was loaded on the primary content area
@@ -6426,17 +6445,17 @@ var LanguageDetectionListener = {
 // Note that this is also called from non-browser windows on OSX, which do
 // share menu items but not much else. See nonbrowser-mac.js.
 var BrowserOffline = {
   _inited: false,
 
   // BrowserOffline Public Methods
   init() {
     if (!this._uiElement)
-      this._uiElement = document.getElementById("workOfflineMenuitemState");
+      this._uiElement = document.getElementById("cmd_toggleOfflineStatus");
 
     Services.obs.addObserver(this, "network:offline-status-changed");
 
     this._updateOfflineUI(Services.io.offline);
 
     this._inited = true;
   },
 
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -76,17 +76,17 @@
 #ifdef BROWSER_XHTML
 xmlns="http://www.w3.org/1999/xhtml"
 #endif
 >
   Services.scriptloader.loadSubScript("chrome://global/content/contentAreaUtils.js", this);
   Services.scriptloader.loadSubScript("chrome://browser/content/tabbrowser.js", this);
 </script>
 
-# All sets except for popupsets (commands, keys, stringbundles and broadcasters)
+# All sets except for popupsets (commands, keys, and stringbundles)
 # *must* go into the browser-sets.inc file so that they can be shared with other
 # top level windows in macWindow.inc.xul.
 #include browser-sets.inc
 
   <popupset id="mainPopupSet">
     <menupopup id="tabContextMenu"
                onpopupshowing="if (event.target == this) TabContextMenu.updateContextMenu(this);"
                onpopuphidden="if (event.target == this) TabContextMenu.contextTab = null;">
@@ -1116,16 +1116,17 @@ xmlns="http://www.w3.org/1999/xhtml"
                      ondragleave="PlacesMenuDNDHandler.onDragLeave(event);"
                      ondrop="PlacesMenuDNDHandler.onDrop(event);"
                      oncommand="BookmarkingUI.onCommand(event);">
         <menupopup id="BMB_bookmarksPopup"
                    class="cui-widget-panel cui-widget-panelview cui-widget-panelWithFooter PanelUI-subView"
                    placespopup="true"
                    context="placesContext"
                    openInTabs="children"
+                   side="top"
                    onmouseup="BookmarksEventHandler.onMouseUp(event);"
                    oncommand="BookmarksEventHandler.onCommand(event);"
                    onclick="BookmarksEventHandler.onClick(event, this.parentNode._placesView);"
                    onpopupshowing="BookmarkingUI.onPopupShowing(event);
                                    BookmarkingUI.attachPlacesView(event, this);"
                    tooltip="bhTooltip" popupsinherittooltip="true">
           <menuitem id="BMB_viewBookmarksSidebar"
                     class="menuitem-iconic subviewbutton"
--- a/browser/base/content/macWindow.inc.xul
+++ b/browser/base/content/macWindow.inc.xul
@@ -12,16 +12,16 @@
 
 # All JS files which are needed by browser.xul and other top level windows to
 # support MacOS specific features *must* go into the global-scripts.inc file so
 # that they can be shared with browser.xul.
 #include global-scripts.inc
 
 <script type="application/javascript" src="chrome://browser/content/nonbrowser-mac.js"></script>
 
-# All sets except for popupsets (commands, keys, stringbundles and broadcasters)
+# All sets except for popupsets (commands, keys, and stringbundles)
 # *must* go into the browser-sets.inc file so that they can be shared with
 # browser.xul
 #include browser-sets.inc
 
 # The entire main menubar is placed into browser-menubar.inc, so that it can be
 # shared with browser.xul.
 #include browser-menubar.inc
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -128,17 +128,18 @@ nsContextMenu.prototype = {
         linkUrl: this.linkURL,
         selectionText: this.isTextSelected ? this.selectionInfo.fullText : undefined,
         frameId: this.frameOuterWindowID,
       };
       subject.wrappedJSObject = subject;
       Services.obs.notifyObservers(subject, "on-build-contextmenu");
     }
 
-    this.isFrameImage = document.getElementById("isFrameImage");
+    this.viewFrameSourceElement =
+         document.getElementById("context-viewframesource");
     this.ellipsis = "\u2026";
     try {
       this.ellipsis = Services.prefs.getComplexValue("intl.ellipsis",
                                                      Ci.nsIPrefLocalizedString).data;
     } catch (e) { }
 
     // Reset after "on-build-contextmenu" notification in case selection was
     // changed during the notification.
@@ -369,19 +370,16 @@ nsContextMenu.prototype = {
 
     let stopReloadItem = "";
     if (shouldShow || !this.inTabBrowser) {
       stopReloadItem = (stopped || !this.inTabBrowser) ? "reload" : "stop";
     }
 
     this.showItem("context-reload", stopReloadItem == "reload");
     this.showItem("context-stop", stopReloadItem == "stop");
-
-    // XXX: Stop is determined in browser.js; the canStop broadcaster is broken
-    // this.setItemAttrFromNode( "context-stop", "disabled", "canStop" );
   },
 
   initLeaveDOMFullScreenItems: function CM_initLeaveFullScreenItem() {
     // only show the option if the user is in DOM fullscreen
     var shouldShow = this.target.ownerDocument.fullscreen;
     this.showItem("context-leave-dom-fullscreen", shouldShow);
 
     // Explicitly show if in DOM fullscreen, but do not hide it has already been shown
@@ -529,19 +527,19 @@ nsContextMenu.prototype = {
     this.showItem("context-bookmarkframe", !this.inSrcdocFrame);
     this.showItem("open-frame-sep", !this.inSrcdocFrame);
 
     this.showItem("frame-sep", this.inFrame && this.isTextSelected);
 
     // Hide menu entries for images, show otherwise
     if (this.inFrame) {
       if (BrowserUtils.mimeTypeIsTextBased(this.target.ownerDocument.contentType))
-        this.isFrameImage.removeAttribute("hidden");
+        this.viewFrameSourceElement.removeAttribute("hidden");
       else
-        this.isFrameImage.setAttribute("hidden", "true");
+        this.viewFrameSourceElement.setAttribute("hidden", "true");
     }
 
     // BiDi UI
     this.showItem("context-sep-bidi", !this.onNumeric && top.gBidiUI);
     this.showItem("context-bidi-text-direction-toggle",
                   this.onTextInput && !this.onNumeric && top.gBidiUI);
     this.showItem("context-bidi-page-direction-toggle",
                   !this.onTextInput && top.gBidiUI);
@@ -1337,26 +1335,16 @@ nsContextMenu.prototype = {
         elem.removeAttribute(aAttr);
       } else {
         // Set attr=val.
         elem.setAttribute(aAttr, aVal);
       }
     }
   },
 
-  // Set context menu attribute according to like attribute of another node
-  // (such as a broadcaster).
-  setItemAttrFromNode(aItem_id, aAttr, aOther_id) {
-    var elem = document.getElementById(aOther_id);
-    if (elem && elem.getAttribute(aAttr) == "true")
-      this.setItemAttr(aItem_id, aAttr, "true");
-    else
-      this.setItemAttr(aItem_id, aAttr, null);
-  },
-
   // Temporary workaround for DOM api not yet implemented by XUL nodes.
   cloneNode(aItem) {
     // Create another element like the one we're cloning.
     var node = document.createElement(aItem.tagName);
 
     // Copy attributes from argument item to the new one.
     var attrs = aItem.attributes;
     for (var i = 0; i < attrs.length; i++) {
--- a/browser/base/content/test/general/browser_viewSourceInTabOnViewSource.js
+++ b/browser/base/content/test/general/browser_viewSourceInTabOnViewSource.js
@@ -8,40 +8,44 @@ function wait_while_tab_is_busy() {
         }
       }
     };
     gBrowser.addProgressListener(progressListener);
   });
 }
 
 // This function waits for the tab to stop being busy instead of waiting for it
-// to load, since the canViewSource change happens at that time.
+// to load, since the elementsForViewSource change happens at that time.
 var with_new_tab_opened = async function(options, taskFn) {
   let busyPromise = wait_while_tab_is_busy();
   let tab = await BrowserTestUtils.openNewForegroundTab(options.gBrowser, options.url, false);
   await busyPromise;
   await taskFn(tab.linkedBrowser);
   gBrowser.removeTab(tab);
 };
 
 add_task(async function test_regular_page() {
   function test_expect_view_source_enabled(browser) {
-    ok(!XULBrowserWindow.canViewSource.hasAttribute("disabled"),
-       "View Source should be enabled");
+    for (let element of [...XULBrowserWindow.elementsForViewSource]) {
+      ok(!element.hasAttribute("disabled"),
+         "View Source should be enabled");
+    }
   }
 
   await with_new_tab_opened({
     gBrowser,
     url: "http://example.com",
   }, test_expect_view_source_enabled);
 });
 
 add_task(async function test_view_source_page() {
   function test_expect_view_source_disabled(browser) {
-    ok(XULBrowserWindow.canViewSource.hasAttribute("disabled"),
-       "View Source should be disabled");
+    for (let element of [...XULBrowserWindow.elementsForViewSource]) {
+      ok(element.hasAttribute("disabled"),
+         "View Source should be disabled");
+    }
   }
 
   await with_new_tab_opened({
     gBrowser,
     url: "view-source:http://example.com",
   }, test_expect_view_source_disabled);
 });
--- a/browser/base/content/webext-panels.xul
+++ b/browser/base/content/webext-panels.xul
@@ -21,20 +21,16 @@
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   <script type="application/javascript" src="chrome://global/content/contentAreaUtils.js"/>
   <script type="application/javascript" src="chrome://browser/content/browser.js"/>
   <script type="application/javascript" src="chrome://browser/content/browser-places.js"/>
   <script type="application/javascript" src="chrome://browser/content/webext-panels.js"/>
   <script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
   <script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
 
-  <broadcasterset id="mainBroadcasterSet">
-    <broadcaster id="isFrameImage"/>
-  </broadcasterset>
-
   <commandset id="mainCommandset">
     <command id="Browser:Back"
              oncommand="getPanelBrowser().webNavigation.goBack();"
              disabled="true"/>
     <command id="Browser:Forward"
              oncommand="getPanelBrowser().webNavigation.goForward();"
              disabled="true"/>
     <command id="Browser:Stop" oncommand="PanelBrowserStop();"/>
--- a/browser/components/customizableui/content/panelUI.inc.xul
+++ b/browser/components/customizableui/content/panelUI.inc.xul
@@ -622,18 +622,17 @@
                        class="subviewbutton subviewbutton-nav"
                        label="&charsetMenu2.label;"
                        closemenu="none"
                        oncommand="PanelUI.showSubView('PanelUI-characterEncodingView', this)"/>
         <toolbarbutton id="appMenu-workoffline-button"
                        class="subviewbutton"
                        label="&goOfflineCmd.label;"
                        type="checkbox"
-                       observes="workOfflineMenuitemState"
-                       oncommand="BrowserOffline.toggleOfflineStatus();"/>
+                       command="cmd_toggleOfflineStatus"/>
       </vbox>
     </panelview>
     <panelview id="appMenu-libraryView" class="PanelUI-subView">
       <vbox class="panel-subview-body">
         <toolbarbutton id="appMenu-library-bookmarks-button"
                        class="subviewbutton subviewbutton-iconic subviewbutton-nav"
                        label="&bookmarksSubview.label;"
                        closemenu="none"
--- a/browser/components/preferences/in-content/tests/browser.ini
+++ b/browser/components/preferences/in-content/tests/browser.ini
@@ -11,16 +11,17 @@ support-files =
 [browser_applications_selection.js]
 [browser_advanced_update.js]
 skip-if = !updater
 [browser_basic_rebuild_fonts_test.js]
 [browser_bug410900.js]
 [browser_bug731866.js]
 [browser_search_no_results_change_category.js]
 [browser_search_within_preferences_1.js]
+skip-if = (os == 'win') # Bug 1480314
 [browser_search_within_preferences_2.js]
 [browser_search_within_preferences_command.js]
 [browser_search_subdialogs_within_preferences_1.js]
 [browser_search_subdialogs_within_preferences_2.js]
 [browser_search_subdialogs_within_preferences_3.js]
 [browser_search_subdialogs_within_preferences_4.js]
 [browser_search_subdialogs_within_preferences_5.js]
 [browser_search_subdialogs_within_preferences_6.js]
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -188,22 +188,22 @@ menuitem.bookmark-item {
   background-color: hsla(0,0%,100%,.22);
 }
 
 #close-button {
   list-style-image: url(chrome://browser/skin/window-controls/close.svg);
 }
 
 #close-button:hover {
-  background-color: hsl(355, 86%, 49%);
+  background-color: #d70022;
   stroke: white;
 }
 
 #close-button:hover:active {
-  background-color: hsl(355, 82%, 69%);
+  background-color: #ff0039;
 }
 
 /* Location bar */
 
 %include ../shared/urlbar-searchbar.inc.css
 
 #urlbar:not(:-moz-lwtheme):not([focused="true"]),
 .searchbar-textbox:not(:-moz-lwtheme):not([focused="true"]) {
--- a/browser/themes/shared/browser.inc.css
+++ b/browser/themes/shared/browser.inc.css
@@ -24,24 +24,16 @@
 }
 
 /* Increase contrast of UI links on dark themes */
 
 :root[lwt-popup-brighttext] panel .text-link {
   color: @lwtPopupBrighttextLinkColor@;
 }
 
-/* Set additional backgrounds alignment relative to toolbox*/
-
-#navigator-toolbox:-moz-lwtheme {
-  background-image: var(--lwt-additional-images);
-  background-position: var(--lwt-background-alignment);
-  background-repeat: var(--lwt-background-tiling);
-}
-
 /* Toolbar / content area border */
 
 #navigator-toolbox::after {
   content: "";
   display: -moz-box;
   border-bottom: 1px solid var(--toolbox-border-bottom-color);
 }
 
--- a/devtools/client/accessibility/accessibility-startup.js
+++ b/devtools/client/accessibility/accessibility-startup.js
@@ -1,16 +1,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";
 
+const Services = require("Services");
 const { AccessibilityFront } = require("devtools/shared/fronts/accessibility");
 
+// @remove after release 63 (See Bug 1482461)
+const PROMOTE_COUNT_PREF = "devtools.promote.accessibility";
+
 /**
  * Component responsible for all accessibility panel startup steps before the panel is
  * actually opened.
  */
 class AccessibilityStartup {
   constructor(toolbox) {
     this.toolbox = toolbox;
 
@@ -124,15 +128,20 @@ class AccessibilityStartup {
   _updateAccessibilityToolHighlight() {
     if (this._accessibility.enabled) {
       this.toolbox.highlightTool("accessibility");
     } else {
       this.toolbox.unhighlightTool("accessibility");
     }
   }
 
+  // @remove after release 63 (See Bug 1482461)
+  updatePanelPromoteCount() {
+    Services.prefs.setIntPref(PROMOTE_COUNT_PREF, 0);
+  }
+
   async destroy() {
     await this.destroyAccessibility();
     this.toolbox = null;
   }
 }
 
 exports.AccessibilityStartup = AccessibilityStartup;
--- a/devtools/client/accessibility/accessibility.css
+++ b/devtools/client/accessibility/accessibility.css
@@ -7,16 +7,27 @@
   --accessibility-toolbar-height: 24px;
   --accessibility-toolbar-height-tall: 35px;
   --accessibility-toolbar-focus: var(--blue-50);
   --accessibility-toolbar-focus-alpha30: rgba(10, 132, 255, 0.3);
   --accessibility-full-length-minus-splitter: calc(100% - 1px);
   --accessibility-horizontal-padding: 5px;
   --accessibility-arrow-horizontal-padding: 4px;
   --accessibility-tree-row-height: 21px;
+  --accessibility-unfocused-tree-focused-node-background: var(--grey-20);
+  --accessibility-tree-focused-node-twisty-brightness: brightness(20%);
+  --accessibility-link-color: var(--blue-60);
+  --accessibility-link-color-active: var(--blue-70);
+}
+
+:root.theme-dark {
+  --accessibility-unfocused-tree-focused-node-background: var(--grey-70);
+  --accessibility-tree-focused-node-twisty-brightness: unset;
+  --accessibility-link-color: var(--theme-highlight-blue);
+  --accessibility-link-color-active: var(--blue-40);
 }
 
 /* General */
 html,
 body {
   height: 100%;
   margin: 0;
   padding: 0;
@@ -80,46 +91,109 @@ body {
 .devtools-button:focus > .btn-content:not(.devtools-throbber) {
   outline: 2px solid var(--accessibility-toolbar-focus);
   outline-offset: -2px;
   box-shadow: 0 0 0 2px var(--accessibility-toolbar-focus-alpha30);
   border-radius: 2px;
   -moz-outline-radius: 2px;
 }
 
+.devtools-toolbar {
+  display: flex;
+  align-items: center;
+}
+
+.devtools-toolbar .help {
+  cursor: pointer;
+  width: 18px;
+  margin-inline-start: auto;
+  margin-inline-end: 3px;
+  background: transparent;
+}
+
+.devtools-toolbar .help .btn-content {
+  display: block;
+  padding: 0;
+  background-color: var(--theme-body-color);
+  width: 16px;
+  height: 16px;
+  mask: url("chrome://devtools/skin/images/help.svg") no-repeat;
+}
+
+.devtools-toolbar .help:focus {
+  outline: 2px solid var(--accessibility-toolbar-focus);
+  box-shadow: 0 0 0 3px var(--accessibility-toolbar-focus-alpha30);
+  border-radius: 2px;
+  outline-offset: -1px;
+  -moz-outline-radius: 2px;
+}
+
+.devtools-toolbar .help:focus > .btn-content {
+  outline: none;
+  box-shadow: none;
+}
+
 /* Description */
 .description {
   color: var(--theme-toolbar-color);
   font: message-box;
   font-size: calc(var(--accessibility-font-size) + 1px);
   margin: auto;
   padding-top: 15vh;
   width: 50vw;
 }
 
+/* To ensure that the message does not look squished in vertical mode, increase its width
+   when the toolbox is narrow */
+@media (max-width: 700px) {
+  .description {
+    width: 80vw;
+  }
+}
+
 .description .general {
   display: flex;
   align-items: center;
-  margin-bottom: 1.7em;
+  margin-bottom: 1em;
 }
 
 .description img {
   margin-right: 12px;
   flex-basis: 42px;
   flex-shrink: 0;
   -moz-context-properties: fill;
   fill: var(--grey-40);
 }
 
 .description .devtools-button {
   display: flex;
   align-items: center;
   margin: auto;
 }
 
+.description .link {
+  color: var(--accessibility-link-color);
+  cursor: pointer;
+  outline: 0;
+}
+
+.description .link:hover:not(:focus) {
+  text-decoration: underline;
+}
+
+.description .link:focus:not(:active) {
+  box-shadow: 0 0 0 2px var(--accessibility-toolbar-focus), 0 0 0 4px var(--accessibility-toolbar-focus-alpha30);
+  border-radius: 2px;
+}
+
+.description .link:active {
+  color: var(--accessibility-link-color-active);
+  text-decoration: underline;
+}
+
 /* TreeView Customization */
 .split-box:not(.horz) .main-panel {
   height: calc(100vh - var(--accessibility-toolbar-height));
 }
 
 .treeTable > thead {
   position: sticky;
   top: 0;
@@ -150,19 +224,31 @@ body {
   outline: 0;
 }
 
 .treeTable::-moz-focus-inner,
 .treeTable > tbody::-moz-focus-inner {
   border: 0;
 }
 
-.treeTable:focus > tbody {
-  outline: var(--theme-focus-outline);
-  outline-offset: -1px;
+.treeTable:not(:focus) tbody:not(:focus) .treeRow.selected {
+  background-color: var(--accessibility-unfocused-tree-focused-node-background);
+}
+
+.treeTable:not(:focus) tbody:not(:focus) .treeRow.selected .theme-twisty {
+  filter: var(--accessibility-tree-focused-node-twisty-brightness);
+}
+
+.treeTable:not(:focus) tbody:not(:focus) .treeRow.selected *,
+.treeTable:not(:focus) tbody:not(:focus) .treeRow.selected .treeLabelCell:after {
+  color: inherit;
+}
+
+.treeTable:not(:focus) tbody:not(:focus) .treeRow.selected .objectBox-string {
+  color: var(--string-color);
 }
 
 .treeTable > thead {
   pointer-events: none;
 }
 
 .treeTable > tbody tr {
   height: var(--accessibility-tree-row-height);
@@ -255,33 +341,54 @@ body {
   position: relative;
   display: flex;
   height: var(--accessibility-tree-row-height);
   width: calc(100% - var(--accessibility-horizontal-padding));
   cursor: default;
   align-items: center;
 }
 
-.accessible .tree .node.focused {
-  background-color: var(--theme-selection-background);
+.accessible .tree:focus {
+  outline: 0;
+}
+
+.accessible .tree::-moz-focus-inner {
+  border: 0;
 }
 
-.accessible .tree .tree-node:hover:not(.focused) {
+/* Unset tree styles leaking from reps.css */
+.accessible .tree .tree-node:not(.focused):hover {
+  background-color: transparent;
+}
+
+.accessible .tree:not(:focus) .node.focused {
+  background-color: var(--accessibility-unfocused-tree-focused-node-background);
+}
+
+.accessible .tree:not(:focus) .node.focused .theme-twisty {
+  filter: var(--accessibility-tree-focused-node-twisty-brightness);
+}
+
+.accessible .tree .node:not(.focused):hover {
   background-color: var(--theme-selection-background-hover);
 }
 
-.accessible .tree .node.focused * {
+.accessible .tree:focus .node.focused {
+  background-color: var(--theme-selection-background);
+}
+
+.accessible .tree:focus .node.focused * {
   color: var(--theme-selection-color);
 }
 
-.accessible .tree .node.focused .open-inspector {
+.accessible .tree:focus .node.focused .open-inspector {
   background-color: var(--grey-30);
 }
 
-.accessible .tree .node.focused:hover .open-inspector {
+.accessible .tree:focus .node.focused:hover .open-inspector {
   background-color: var(--theme-selection-color);
 }
 
 .accessible .tree .arrow {
   flex-shrink: 0;
 }
 
 .accessible .tree .object-value {
--- a/devtools/client/accessibility/components/Description.js
+++ b/devtools/client/accessibility/components/Description.js
@@ -7,22 +7,23 @@
 
 // React & Redux
 const { createFactory, Component } = require("devtools/client/shared/vendor/react");
 const { div, p, img } = require("devtools/client/shared/vendor/react-dom-factories");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 const { connect } = require("devtools/client/shared/vendor/react-redux");
 
 const Button = createFactory(require("./Button"));
+const LearnMoreLink = createFactory(require("./LearnMoreLink"));
 const { enable, updateCanBeEnabled } = require("../actions/ui");
 
 // Localization
 const { L10N } = require("../utils/l10n");
 
-const { A11Y_SERVICE_ENABLED_COUNT } = require("../constants");
+const { A11Y_LEARN_MORE_LINK, A11Y_SERVICE_ENABLED_COUNT } = require("../constants");
 
 class OldVersionDescription extends Component {
   render() {
     return (
       div({ className: "description" },
         p({ className: "general" },
           img({
             src: "chrome://devtools/skin/images/accessibility.svg",
@@ -94,23 +95,33 @@ class Description extends Component {
     if (canBeEnabled) {
       title = L10N.getStr("accessibility.enable.enabledTitle");
     } else {
       disableButton = true;
       title = L10N.getStr("accessibility.enable.disabledTitle");
     }
 
     return (
-      div({ className: "description" },
-        p({ className: "general" },
+      div({ className: "description", role: "presentation" },
+        div({ className: "general", role: "presentation" },
           img({
             src: "chrome://devtools/skin/images/accessibility.svg",
             alt: L10N.getStr("accessibility.logo")
           }),
-          L10N.getStr("accessibility.description.general")),
+          div({ role: "presentation" },
+            LearnMoreLink({
+              href: A11Y_LEARN_MORE_LINK +
+                    "?utm_source=devtools&utm_medium=a11y-panel-description",
+              learnMoreStringKey: "accessibility.learnMore",
+              l10n: L10N,
+              messageStringKey: "accessibility.description.general.p1"
+            }),
+            p({}, L10N.getStr("accessibility.description.general.p2"))
+          )
+        ),
         Button({
           id: "accessibility-enable-button",
           onClick: this.onEnable,
           disabled: enabling || disableButton,
           busy: enabling,
           "data-standalone": true,
           title
         }, L10N.getStr(enableButtonStr))
new file mode 100644
--- /dev/null
+++ b/devtools/client/accessibility/components/LearnMoreLink.js
@@ -0,0 +1,60 @@
+/* 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 { Component } = require("devtools/client/shared/vendor/react");
+const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
+const { p, a } = require("devtools/client/shared/vendor/react-dom-factories");
+
+const { openDocLink } = require("devtools/client/shared/link");
+
+/**
+ * Localization friendly component for rendering a block of text with a "Learn more" link
+ * as a part of it.
+ */
+class LearnMoreLink extends Component {
+  static get propTypes() {
+    return {
+      href: PropTypes.string,
+      learnMoreStringKey: PropTypes.string.isRequired,
+      l10n: PropTypes.object.isRequired,
+      messageStringKey: PropTypes.string.isRequired,
+      onClick: PropTypes.func
+    };
+  }
+
+  static get defaultProps() {
+    return {
+      href: "#",
+      learnMoreStringKey: null,
+      l10n: null,
+      messageStringKey: null,
+      onClick: LearnMoreLink.openDocOnClick
+    };
+  }
+
+  static openDocOnClick(event) {
+    event.preventDefault();
+    openDocLink(event.target.href);
+  }
+
+  render() {
+    const { href, learnMoreStringKey, l10n, messageStringKey, onClick } = this.props;
+    const learnMoreString = l10n.getStr(learnMoreStringKey);
+    const messageString = l10n.getFormatStr(messageStringKey, learnMoreString);
+
+    // Split the paragraph string with the link as a separator, and include the link into
+    // results.
+    const re = new RegExp(`(\\b${learnMoreString}\\b)`);
+    const contents = messageString.split(re);
+    contents[1] = a({ className: "link", href, onClick }, contents[1]);
+
+    return (
+      p({}, ...contents)
+    );
+  }
+}
+
+module.exports = LearnMoreLink;
--- a/devtools/client/accessibility/components/Toolbar.js
+++ b/devtools/client/accessibility/components/Toolbar.js
@@ -8,16 +8,19 @@ const { createFactory, Component } = req
 const { div } = require("devtools/client/shared/vendor/react-dom-factories");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 const { L10N } = require("../utils/l10n");
 const Button = createFactory(require("./Button"));
 
 const { connect } = require("devtools/client/shared/vendor/react-redux");
 const { disable, updateCanBeDisabled } = require("../actions/ui");
 
+const { A11Y_LEARN_MORE_LINK } = require("../constants");
+const { openDocLink } = require("devtools/client/shared/link");
+
 class Toolbar extends Component {
   static get propTypes() {
     return {
       dispatch: PropTypes.func.isRequired,
       accessibility: PropTypes.object.isRequired,
       canBeDisabled: PropTypes.bool.isRequired
     };
   }
@@ -51,16 +54,21 @@ class Toolbar extends Component {
     const { accessibility, dispatch } = this.props;
     this.setState({ disabling: true });
 
     dispatch(disable(accessibility))
       .then(() => this.setState({ disabling: false }))
       .catch(() => this.setState({ disabling: false }));
   }
 
+  onLearnMoreClick() {
+    openDocLink(A11Y_LEARN_MORE_LINK +
+      "?utm_source=devtools&utm_medium=a11y-panel-toolbar");
+  }
+
   render() {
     const { canBeDisabled } = this.props;
     const { disabling } = this.state;
     const disableButtonStr = disabling ?
       "accessibility.disabling" : "accessibility.disable";
     let title;
     let isDisabled = false;
 
@@ -77,17 +85,22 @@ class Toolbar extends Component {
         role: "toolbar"
       }, Button({
         className: "disable",
         id: "accessibility-disable-button",
         onClick: this.onDisable,
         disabled: disabling || isDisabled,
         busy: disabling,
         title
-      }, L10N.getStr(disableButtonStr)))
+      }, L10N.getStr(disableButtonStr)),
+      Button({
+        className: "help",
+        title: L10N.getStr("accessibility.learnMore"),
+        onClick: this.onLearnMoreClick
+      }))
     );
   }
 }
 
 const mapStateToProps = ({ ui }) => ({
   canBeDisabled: ui.canBeDisabled
 });
 
--- a/devtools/client/accessibility/components/moz.build
+++ b/devtools/client/accessibility/components/moz.build
@@ -3,12 +3,13 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DevToolsModules(
     'AccessibilityRow.js',
     'AccessibilityTree.js',
     'Accessible.js',
     'Button.js',
     'Description.js',
+    'LearnMoreLink.js',
     'MainFrame.js',
     'RightSidebar.js',
     'Toolbar.js'
 )
--- a/devtools/client/accessibility/constants.js
+++ b/devtools/client/accessibility/constants.js
@@ -58,8 +58,12 @@ exports.ACCESSIBLE_EVENTS = [
   "text-change",
   "value-change",
   "index-in-parent-change"
 ];
 
 // Telemetry name constants.
 exports.A11Y_SERVICE_DURATION = "DEVTOOLS_ACCESSIBILITY_SERVICE_TIME_ACTIVE_SECONDS";
 exports.A11Y_SERVICE_ENABLED_COUNT = "devtools.accessibility.service_enabled_count";
+
+// URL constants
+exports.A11Y_LEARN_MORE_LINK =
+  "https://developer.mozilla.org/docs/Tools/Accessibility_inspector";
--- a/devtools/client/accessibility/panel.js
+++ b/devtools/client/accessibility/panel.js
@@ -81,16 +81,18 @@ AccessibilityPanel.prototype = {
     this.panelWin.gToolbox = this._toolbox;
 
     await this._toolbox.initInspector();
     await this.startup.initAccessibility();
     if (this.supportsLatestAccessibility) {
       this.picker = new Picker(this);
     }
 
+    this.startup.updatePanelPromoteCount();
+
     this.updateA11YServiceDurationTimer();
     this.front.on("init", this.updateA11YServiceDurationTimer);
     this.front.on("shutdown", this.updateA11YServiceDurationTimer);
 
     this.isReady = true;
     this.emit("ready");
     resolver(this);
     return this._opening;
--- a/devtools/client/accessibility/test/mochitest/chrome.ini
+++ b/devtools/client/accessibility/test/mochitest/chrome.ini
@@ -1,5 +1,6 @@
 [DEFAULT]
 support-files =
   head.js
 
+[test_accessible_learnMoreLink.html]
 [test_accessible_openLink.html]
new file mode 100644
--- /dev/null
+++ b/devtools/client/accessibility/test/mochitest/test_accessible_learnMoreLink.html
@@ -0,0 +1,95 @@
+<!-- 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/. -->
+<!DOCTYPE HTML>
+<html>
+<!--
+Test that LearnMoreLink parses and renders correctly text with learn more links.
+-->
+<head>
+  <meta charset="utf-8">
+  <title>LearnMoreLink component test</title>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
+  <link rel="stylesheet" href="chrome://devtools/skin/light-theme.css" type="text/css">
+</head>
+<body>
+<pre id="test">
+<script src="head.js" type="application/javascript"></script>
+<script type="application/javascript">
+
+"use strict";
+
+window.onload = async function() {
+  try {
+    const { gDevTools } = require("devtools/client/framework/devtools");
+    const Services = browserRequire("Services");
+    const ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
+    const { createFactory } = browserRequire("devtools/client/shared/vendor/react");
+    const { Simulate } =
+      browserRequire("devtools/client/shared/vendor/react-dom-test-utils");
+    const LearnMoreLink = createFactory(
+      browserRequire("devtools/client/accessibility/components/LearnMoreLink"));
+
+    class MockL10N {
+      constructor(bundle) {
+        this.bundle = bundle;
+      }
+
+      getStr(name) {
+        return this.bundle[name];
+      }
+
+      getFormatStr(name, ...args) {
+        let index = 0;
+        return this.bundle[name].replace("%S", () => args[index++]);
+      }
+    }
+
+    function testLinkClicked(link, expectedUrl) {
+      const browserWindow = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
+      const defaultOpenWebLinkIn = browserWindow.openWebLinkIn;
+
+      const checker = Symbol();
+      let onClickUrl = checker;
+      browserWindow.openWebLinkIn = url => {
+        onClickUrl = url;
+      };
+
+      Simulate.click(link);
+
+      ok(onClickUrl !== checker, "Link was clicked");
+      is(onClickUrl, expectedUrl, "Correct URL is opened");
+
+      browserWindow.openWebLinkIn = defaultOpenWebLinkIn;
+    }
+
+    const href = "http://example.com/";
+    const l10n = new MockL10N({
+      message: "This is a message that contains a link. %S",
+      link: "Learn more"
+    });
+    const learnMoreLink = LearnMoreLink(
+      { href, l10n, learnMoreStringKey: "link", messageStringKey: "message" });
+    ok(LearnMoreLink, "Should be able to create LearnMoreLink instances");
+
+    ReactDOM.render(learnMoreLink, document.body);
+    const p = document.querySelector("p");
+    is(p.textContent, "This is a message that contains a link. Learn more",
+      "Text content for the whole paragraph is correct");
+
+    const link = p.querySelector(".link");
+    ok(link, "Link was rendered");
+    is(link.textContent, "Learn more", "Text content for link is correct");
+
+    testLinkClicked(link, href);
+  } catch (e) {
+    ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
+  } finally {
+    SimpleTest.finish();
+  }
+};
+</script>
+</pre>
+</body>
+</html>
--- a/devtools/client/debugger/new/README.mozilla
+++ b/devtools/client/debugger/new/README.mozilla
@@ -1,13 +1,13 @@
 This is the debugger.html project output.
 See https://github.com/devtools-html/debugger.html
 
-Version 83
+Version 84
 
-Comparison: https://github.com/devtools-html/debugger.html/compare/release-82...release-83
+Comparison: https://github.com/devtools-html/debugger.html/compare/release-83...release-84
 
 Packages:
 - babel-plugin-transform-es2015-modules-commonjs @6.26.2
 - babel-preset-react @6.24.1
 - react @16.4.1
 - react-dom @16.4.1
 - webpack @3.12.0
--- a/devtools/client/debugger/new/dist/debugger.css
+++ b/devtools/client/debugger/new/dist/debugger.css
@@ -811,18 +811,19 @@ html[dir="rtl"] .managed-tree .tree .nod
 
 .managed-tree .tree-node button {
   position: fixed;
 }
 /* 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/. */
 
-.tree {
-  overflow: auto;
+ /* We can remove the outline since we do add our own focus style on nodes */
+.tree:focus {
+  outline: none;
 }
 
 .tree.inline {
   display: inline-block;
 }
 
 .tree.nowrap {
   white-space: nowrap;
@@ -3144,17 +3145,19 @@ html[dir="rtl"] .breakpoints-list .break
 
 .breakpoints-list .pause-indicator {
   flex: 0 1 content;
   order: 3;
 }
 
 .breakpoint .close-btn {
   offset-inline-end: 15px;
+  inset-inline-end: 15px;
   offset-inline-start: auto;
+  inset-inline-start: auto;
   position: absolute;
   top: 8px;
   display: none;
 }
 
 .breakpoint:hover .close-btn {
   display: flex;
 }
@@ -3293,16 +3296,17 @@ html[dir="rtl"] .breakpoints-list .break
 
 .tree .tree-node:not(.focused):hover {
   background-color: transparent;
 }
 
 .expression-container__close-btn {
   position: absolute;
   offset-inline-end: 0px;
+  inset-inline-end: 0px;
   top: 1px;
 }
 
 .expression-content {
   position: relative;
 }
 
 .expression-content .tree {
@@ -3966,17 +3970,19 @@ html[dir="rtl"] .object-node {
 .theme-dark .welcomebox {
   background-color: var(--theme-body-background);
 }
 
 .welcomebox .command-bar-button {
   position: absolute;
   top: auto;
   offset-inline-end: 0;
+  inset-inline-end: 0;
   offset-inline-start: auto;
+  inset-inline-start: auto;
   bottom: 0;
 }
 
 .alignlabel {
   display: flex;
   white-space: nowrap;
 }
 
--- a/devtools/client/debugger/new/dist/vendors.css
+++ b/devtools/client/debugger/new/dist/vendors.css
@@ -287,18 +287,19 @@ html[dir="rtl"] .arrow svg,
 
 .source-icon svg {
   fill: var(--theme-comment);
 }
 /* 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/. */
 
-.tree {
-  overflow: auto;
+ /* We can remove the outline since we do add our own focus style on nodes */
+.tree:focus {
+  outline: none;
 }
 
 .tree.inline {
   display: inline-block;
 }
 
 .tree.nowrap {
   white-space: nowrap;
--- a/devtools/client/debugger/new/dist/vendors.js
+++ b/devtools/client/debugger/new/dist/vendors.js
@@ -6520,25 +6520,17 @@ class Tree extends Component {
       tabIndex: "0",
       onKeyDown: this._onKeyDown,
       onKeyPress: this._preventArrowKeyScrolling,
       onKeyUp: this._preventArrowKeyScrolling,
       onFocus: ({ nativeEvent }) => {
         if (focused || !nativeEvent || !this.treeRef) {
           return;
         }
-
-        const { explicitOriginalTarget } = nativeEvent;
-
-        // Only set default focus to the first tree node if the focus came
-        // from outside the tree (e.g. by tabbing to the tree from other
-        // external elements).
-        if (explicitOriginalTarget !== this.treeRef && !this.treeRef.contains(explicitOriginalTarget)) {
-          this._focus(traversal[0].item);
-        }
+        this._focus(traversal[0].item);
       },
       onBlur: this._onBlur,
       "aria-label": this.props.label,
       "aria-labelledby": this.props.labelledby,
       "aria-activedescendant": focused && this.props.getKey(focused),
       style
     }, nodes);
   }
@@ -7143,16 +7135,18 @@ function move(array, moveIndex, toIndex)
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
 var _propTypes = __webpack_require__(3642);
 
 var _propTypes2 = _interopRequireDefault(_propTypes);
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
@@ -7161,112 +7155,145 @@ var _tab = __webpack_require__(3759);
 var _tab2 = _interopRequireDefault(_tab);
 
 var _tabList = __webpack_require__(3764);
 
 var _tabList2 = _interopRequireDefault(_tabList);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-class TabList extends _react2.default.Component {
-  constructor(props) {
-    super(props);
-    this.handleKeyPress = this.handleKeyPress.bind(this);
-    this.tabRefs = new Array(_react2.default.Children.count(props.children)).fill(0).map(_ => _react2.default.createRef());
-    this.handlers = this.getHandlers(props.vertical);
-  }
-
-  getHandlers(vertical) {
-    if (vertical) {
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var TabList = function (_React$Component) {
+  _inherits(TabList, _React$Component);
+
+  function TabList(props) {
+    _classCallCheck(this, TabList);
+
+    var _this = _possibleConstructorReturn(this, (TabList.__proto__ || Object.getPrototypeOf(TabList)).call(this, props));
+
+    var childrenCount = _react2.default.Children.count(props.children);
+
+    _this.handleKeyPress = _this.handleKeyPress.bind(_this);
+    _this.tabRefs = new Array(childrenCount).fill(0).map(function () {
+      return _react2.default.createRef();
+    });
+    _this.handlers = _this.getHandlers(props.vertical);
+    return _this;
+  }
+
+  _createClass(TabList, [{
+    key: 'componentDidUpdate',
+    value: function componentDidUpdate(prevProps) {
+      if (prevProps.activeIndex !== this.props.activeIndex) {
+        this.tabRefs[this.props.activeIndex].current.focus();
+      }
+    }
+  }, {
+    key: 'getHandlers',
+    value: function getHandlers(vertical) {
+      if (vertical) {
+        return {
+          ArrowDown: this.next.bind(this),
+          ArrowUp: this.previous.bind(this)
+        };
+      }
       return {
-        ArrowDown: this.next.bind(this),
-        ArrowUp: this.previous.bind(this)
+        ArrowLeft: this.previous.bind(this),
+        ArrowRight: this.next.bind(this)
       };
     }
-    return {
-      ArrowLeft: this.previous.bind(this),
-      ArrowRight: this.next.bind(this)
-    };
-  }
-
-  wrapIndex(index) {
-    const count = _react2.default.Children.count(this.props.children);
-    return (index + count) % count;
-  }
-
-  handleKeyPress(event) {
-    const handler = this.handlers[event.key];
-    if (handler) {
-      handler();
-    }
-  }
-
-  previous() {
-    const newIndex = this.wrapIndex(this.props.activeIndex - 1);
-    this.props.onActivateTab(newIndex);
-  }
-
-  next() {
-    const newIndex = this.wrapIndex(this.props.activeIndex + 1);
-    this.props.onActivateTab(newIndex);
-  }
-
-  componentDidUpdate(prevProps) {
-    if (prevProps.activeIndex !== this.props.activeIndex) {
-      this.tabRefs[this.props.activeIndex].current.focus();
-    }
-  }
-
-  render() {
-    var _props = this.props;
-    const accessibleId = _props.accessibleId,
+  }, {
+    key: 'wrapIndex',
+    value: function wrapIndex(index) {
+      var count = _react2.default.Children.count(this.props.children);
+      return (index + count) % count;
+    }
+  }, {
+    key: 'handleKeyPress',
+    value: function handleKeyPress(event) {
+      var handler = this.handlers[event.key];
+      if (handler) {
+        handler();
+      }
+    }
+  }, {
+    key: 'previous',
+    value: function previous() {
+      var newIndex = this.wrapIndex(this.props.activeIndex - 1);
+      this.props.onActivateTab(newIndex);
+    }
+  }, {
+    key: 'next',
+    value: function next() {
+      var newIndex = this.wrapIndex(this.props.activeIndex + 1);
+      this.props.onActivateTab(newIndex);
+    }
+  }, {
+    key: 'render',
+    value: function render() {
+      var _this2 = this;
+
+      var _props = this.props,
+          accessibleId = _props.accessibleId,
           activeIndex = _props.activeIndex,
           children = _props.children,
           className = _props.className,
           onActivateTab = _props.onActivateTab;
 
 
-    return _react2.default.createElement(
-      'ul',
-      { className: className, onKeyUp: this.handleKeyPress, role: 'tablist' },
-      _react2.default.Children.map(children, (child, index) => {
-        if (child.type !== _tab2.default) {
-          throw new Error('Direct children of a <TabList> must be a <Tab>');
-        }
-
-        const active = index === activeIndex;
-        const tabRef = this.tabRefs[index];
-
-        return _react2.default.cloneElement(child, {
-          accessibleId: active ? accessibleId : undefined,
-          active,
-          tabRef,
-          onActivate: () => this.props.onActivateTab(index)
-        });
-      })
-    );
-  }
-}
+      return _react2.default.createElement(
+        'ul',
+        { className: className, onKeyUp: this.handleKeyPress, role: 'tablist' },
+        _react2.default.Children.map(children, function (child, index) {
+          if (child.type !== _tab2.default) {
+            throw new Error('Direct children of a <TabList> must be a <Tab>');
+          }
+
+          var active = index === activeIndex;
+          var tabRef = _this2.tabRefs[index];
+
+          return _react2.default.cloneElement(child, {
+            accessibleId: active ? accessibleId : undefined,
+            active: active,
+            tabRef: tabRef,
+            onActivate: function onActivate() {
+              return onActivateTab(index);
+            }
+          });
+        })
+      );
+    }
+  }]);
+
+  return TabList;
+}(_react2.default.Component);
 
 exports.default = TabList;
+
+
 TabList.propTypes = {
   accessibleId: _propTypes2.default.string,
   activeIndex: _propTypes2.default.number,
   children: _propTypes2.default.node,
   className: _propTypes2.default.string,
   onActivateTab: _propTypes2.default.func,
   vertical: _propTypes2.default.bool
 };
 
 TabList.defaultProps = {
   accessibleId: undefined,
   activeIndex: 0,
   children: null,
   className: _tabList2.default.container,
-  onActivateTab: () => {},
+  onActivateTab: function onActivateTab() {},
   vertical: false
 };
 
 /***/ }),
 
 /***/ 3759:
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -7281,52 +7308,57 @@ exports.default = Tab;
 var _propTypes = __webpack_require__(3642);
 
 var _propTypes2 = _interopRequireDefault(_propTypes);
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
+var _ref2 = __webpack_require__(3784);
+
+var _ref3 = _interopRequireDefault(_ref2);
+
 var _tab = __webpack_require__(3763);
 
 var _tab2 = _interopRequireDefault(_tab);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-function Tab({
-  accessibleId,
-  active,
-  children,
-  className,
-  onActivate,
-  tabRef
-}) {
+function Tab(_ref) {
+  var accessibleId = _ref.accessibleId,
+      active = _ref.active,
+      children = _ref.children,
+      className = _ref.className,
+      onActivate = _ref.onActivate,
+      tabRef = _ref.tabRef;
+
   return _react2.default.createElement(
     'li',
     {
       'aria-selected': active,
       className: className,
       id: accessibleId,
       onClick: onActivate,
+      onKeyDown: function onKeyDown() {},
       ref: tabRef,
       role: 'tab',
       tabIndex: active ? 0 : undefined
     },
     children
   );
 }
 
 Tab.propTypes = {
   accessibleId: _propTypes2.default.string,
   active: _propTypes2.default.bool,
-  children: _propTypes2.default.node,
+  children: _propTypes2.default.node.isRequired,
   className: _propTypes2.default.string,
   onActivate: _propTypes2.default.func,
-  tabRef: _propTypes2.default.object
+  tabRef: _ref3.default
 };
 
 Tab.defaultProps = {
   accessibleId: undefined,
   active: false,
   className: _tab2.default.container,
   onActivate: undefined,
   tabRef: undefined
@@ -7350,39 +7382,39 @@ var _propTypes = __webpack_require__(364
 var _propTypes2 = _interopRequireDefault(_propTypes);
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-function TabPanels({
-  accessibleId,
-  activeIndex,
-  children,
-  className,
-  hasFocusableContent
-}) {
+function TabPanels(_ref) {
+  var accessibleId = _ref.accessibleId,
+      activeIndex = _ref.activeIndex,
+      children = _ref.children,
+      className = _ref.className,
+      hasFocusableContent = _ref.hasFocusableContent;
+
   return _react2.default.createElement(
     'div',
     {
       'aria-labelledby': accessibleId,
       role: 'tabpanel',
       className: className,
       tabIndex: hasFocusableContent ? undefined : 0
     },
     _react2.default.Children.toArray(children)[activeIndex]
   );
 }
 
 TabPanels.propTypes = {
   accessibleId: _propTypes2.default.string,
   activeIndex: _propTypes2.default.number,
-  children: _propTypes2.default.node,
+  children: _propTypes2.default.node.isRequired,
   className: _propTypes2.default.string,
   hasFocusableContent: _propTypes2.default.bool.isRequired
 };
 
 TabPanels.defaultProps = {
   accessibleId: undefined,
   activeIndex: 0,
   className: null
@@ -7459,16 +7491,18 @@ function _interopRequireDefault(obj) { r
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
 var _propTypes = __webpack_require__(3642);
 
 var _propTypes2 = _interopRequireDefault(_propTypes);
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
@@ -7481,83 +7515,102 @@ var _tabList = __webpack_require__(3758)
 var _tabList2 = _interopRequireDefault(_tabList);
 
 var _tabPanels = __webpack_require__(3760);
 
 var _tabPanels2 = _interopRequireDefault(_tabPanels);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-class Tabs extends _react2.default.Component {
-  constructor() {
-    super();
-    this.accessibleId = (0, _uniqueId2.default)();
-  }
-
-  render() {
-    var _props = this.props;
-    const activeIndex = _props.activeIndex,
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var Tabs = function (_React$Component) {
+  _inherits(Tabs, _React$Component);
+
+  function Tabs() {
+    _classCallCheck(this, Tabs);
+
+    var _this = _possibleConstructorReturn(this, (Tabs.__proto__ || Object.getPrototypeOf(Tabs)).call(this));
+
+    _this.accessibleId = (0, _uniqueId2.default)();
+    return _this;
+  }
+
+  _createClass(Tabs, [{
+    key: 'render',
+    value: function render() {
+      var _props = this.props,
+          activeIndex = _props.activeIndex,
           children = _props.children,
           className = _props.className,
           onActivateTab = _props.onActivateTab;
 
-    const accessibleId = this.accessibleId;
-
-    return _react2.default.createElement(
-      'div',
-      { className: className },
-      _react2.default.Children.map(children, child => {
-        if (!child) {
-          return child;
-        }
-
-        switch (child.type) {
-          case _tabList2.default:
-            return _react2.default.cloneElement(child, { accessibleId, activeIndex, onActivateTab });
-          case _tabPanels2.default:
-            return _react2.default.cloneElement(child, { accessibleId, activeIndex });
-          default:
+      var accessibleId = this.accessibleId;
+
+      return _react2.default.createElement(
+        'div',
+        { className: className },
+        _react2.default.Children.map(children, function (child) {
+          if (!child) {
             return child;
-        }
-      })
-    );
-  }
-}
+          }
+
+          switch (child.type) {
+            case _tabList2.default:
+              return _react2.default.cloneElement(child, { accessibleId: accessibleId, activeIndex: activeIndex, onActivateTab: onActivateTab });
+            case _tabPanels2.default:
+              return _react2.default.cloneElement(child, { accessibleId: accessibleId, activeIndex: activeIndex });
+            default:
+              return child;
+          }
+        })
+      );
+    }
+  }]);
+
+  return Tabs;
+}(_react2.default.Component);
 
 exports.default = Tabs;
+
+
 Tabs.propTypes = {
   activeIndex: _propTypes2.default.number.isRequired,
   children: _propTypes2.default.node,
   className: _propTypes2.default.string,
   onActivateTab: _propTypes2.default.func
 };
 
 Tabs.defaultProps = {
   children: null,
   className: undefined,
-  onActivateTab: () => {}
+  onActivateTab: function onActivateTab() {}
 };
 
 /***/ }),
 
 /***/ 3766:
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.default = uniqueId;
-let counter = 0;
+var counter = 0;
 
 function uniqueId() {
-  counter++;
-  return `$rac$${counter}`;
+  counter += 1;
+  return "$rac$" + counter;
 }
 
 /***/ }),
 
 /***/ 3769:
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -7913,16 +7966,36 @@ function polyfill(Component) {
   return Component;
 }
 
 
 
 
 /***/ }),
 
+/***/ 3784:
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _propTypes = __webpack_require__(3642);
+
+var _propTypes2 = _interopRequireDefault(_propTypes);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = _propTypes2.default.object;
+
+/***/ }),
+
 /***/ 4:
 /***/ (function(module, exports) {
 
 module.exports = __WEBPACK_EXTERNAL_MODULE_4__;
 
 /***/ }),
 
 /***/ 52:
--- a/devtools/client/debugger/new/src/actions/ast.js
+++ b/devtools/client/debugger/new/src/actions/ast.js
@@ -7,16 +7,18 @@ exports.setSourceMetaData = setSourceMet
 exports.setSymbols = setSymbols;
 exports.setOutOfScopeLocations = setOutOfScopeLocations;
 exports.setPausePoints = setPausePoints;
 
 var _selectors = require("../selectors/index");
 
 var _pause = require("./pause/index");
 
+var _tabs = require("./tabs");
+
 var _setInScopeLines = require("./ast/setInScopeLines");
 
 var _parser = require("../workers/parser/index");
 
 var _promise = require("./utils/middleware/promise");
 
 var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
 
@@ -34,16 +36,17 @@ function setSourceMetaData(sourceId) {
   }) => {
     const source = (0, _selectors.getSource)(getState(), sourceId);
 
     if (!source || !(0, _source.isLoaded)(source) || source.isWasm) {
       return;
     }
 
     const framework = await (0, _parser.getFramework)(source.id);
+    dispatch((0, _tabs.updateTab)(source.url, framework));
     dispatch({
       type: "SET_SOURCE_METADATA",
       sourceId: source.id,
       sourceMetaData: {
         framework
       }
     });
   };
--- a/devtools/client/debugger/new/src/actions/pause/index.js
+++ b/devtools/client/debugger/new/src/actions/pause/index.js
@@ -137,25 +137,16 @@ var _pauseOnExceptions = require("./paus
 
 Object.defineProperty(exports, "pauseOnExceptions", {
   enumerable: true,
   get: function () {
     return _pauseOnExceptions.pauseOnExceptions;
   }
 });
 
-var _selectComponent = require("./selectComponent");
-
-Object.defineProperty(exports, "selectComponent", {
-  enumerable: true,
-  get: function () {
-    return _selectComponent.selectComponent;
-  }
-});
-
 var _selectFrame = require("./selectFrame");
 
 Object.defineProperty(exports, "selectFrame", {
   enumerable: true,
   get: function () {
     return _selectFrame.selectFrame;
   }
 });
--- a/devtools/client/debugger/new/src/actions/pause/moz.build
+++ b/devtools/client/debugger/new/src/actions/pause/moz.build
@@ -14,13 +14,12 @@ DevToolsModules(
     'extra.js',
     'fetchScopes.js',
     'index.js',
     'mapFrames.js',
     'mapScopes.js',
     'paused.js',
     'pauseOnExceptions.js',
     'resumed.js',
-    'selectComponent.js',
     'selectFrame.js',
     'setPopupObjectProperties.js',
     'skipPausing.js',
 )
--- a/devtools/client/debugger/new/src/actions/sources/select.js
+++ b/devtools/client/debugger/new/src/actions/sources/select.js
@@ -149,17 +149,17 @@ function selectLocation(location, {
 
     const selectedSource = (0, _selectors.getSelectedSource)(getState());
 
     if (keepContext && selectedSource && (0, _devtoolsSourceMap.isOriginalId)(selectedSource.id) != (0, _devtoolsSourceMap.isOriginalId)(location.sourceId)) {
       location = await (0, _sourceMaps.getMappedLocation)(getState(), sourceMaps, location);
       source = (0, _sources.getSourceFromId)(getState(), location.sourceId);
     }
 
-    dispatch((0, _tabs.addTab)(source.url, 0));
+    dispatch((0, _tabs.addTab)(source.url));
     dispatch(setSelectedLocation(source, location));
     await dispatch((0, _loadSourceText.loadSourceText)(source));
     const loadedSource = (0, _selectors.getSource)(getState(), source.id);
 
     if (!loadedSource) {
       // If there was a navigation while we were loading the loadedSource
       return;
     }
--- a/devtools/client/debugger/new/src/actions/tabs.js
+++ b/devtools/client/debugger/new/src/actions/tabs.js
@@ -1,13 +1,14 @@
 "use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
+exports.updateTab = updateTab;
 exports.addTab = addTab;
 exports.moveTab = moveTab;
 exports.closeTab = closeTab;
 exports.closeTabs = closeTabs;
 
 var _editor = require("../utils/editor/index");
 
 var _sources = require("./sources/index");
@@ -17,21 +18,29 @@ var _selectors = require("../selectors/i
 /* 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/>. */
 
 /**
  * Redux actions for the editor tabs
  * @module actions/tabs
  */
-function addTab(url, tabIndex) {
+function updateTab(url, framework) {
+  return {
+    type: "UPDATE_TAB",
+    url,
+    framework
+  };
+}
+
+function addTab(url, framework) {
   return {
     type: "ADD_TAB",
     url,
-    tabIndex
+    framework
   };
 }
 
 function moveTab(url, tabIndex) {
   return {
     type: "MOVE_TAB",
     url,
     tabIndex
--- a/devtools/client/debugger/new/src/components/shared/SourceIcon.js
+++ b/devtools/client/debugger/new/src/components/shared/SourceIcon.js
@@ -7,40 +7,44 @@ Object.defineProperty(exports, "__esModu
 var _react = require("devtools/client/shared/vendor/react");
 
 var _react2 = _interopRequireDefault(_react);
 
 var _reactRedux = require("devtools/client/shared/vendor/react-redux");
 
 var _source = require("../../utils/source");
 
+var _tabs = require("../../utils/tabs");
+
 var _selectors = require("../../selectors/index");
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 /* 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/>. */
 class SourceIcon extends _react.PureComponent {
   render() {
     const {
       shouldHide,
       source,
-      sourceMetaData
+      sourceMetaData,
+      framework
     } = this.props;
-    const iconClass = (0, _source.getSourceClassnames)(source, sourceMetaData);
+    const iconClass = framework ? framework.toLowerCase() : (0, _source.getSourceClassnames)(source, sourceMetaData);
 
     if (shouldHide && shouldHide(iconClass)) {
       return null;
     }
 
     return _react2.default.createElement("img", {
       className: `source-icon ${iconClass}`
     });
   }
 
 }
 
 exports.default = (0, _reactRedux.connect)((state, props) => {
   return {
-    sourceMetaData: (0, _selectors.getSourceMetaData)(state, props.source.id)
+    sourceMetaData: (0, _selectors.getSourceMetaData)(state, props.source.id),
+    framework: (0, _tabs.getFramework)((0, _selectors.getTabs)(state), props.source.url)
   };
 })(SourceIcon);
\ No newline at end of file
--- a/devtools/client/debugger/new/src/reducers/pause.js
+++ b/devtools/client/debugger/new/src/reducers/pause.js
@@ -21,17 +21,16 @@ exports.getFrames = getFrames;
 exports.getGeneratedFrameScope = getGeneratedFrameScope;
 exports.getOriginalFrameScope = getOriginalFrameScope;
 exports.getFrameScopes = getFrameScopes;
 exports.getSelectedFrameBindings = getSelectedFrameBindings;
 exports.getFrameScope = getFrameScope;
 exports.getSelectedScope = getSelectedScope;
 exports.getSelectedScopeMappings = getSelectedScopeMappings;
 exports.getSelectedFrameId = getSelectedFrameId;
-exports.getSelectedComponentIndex = getSelectedComponentIndex;
 exports.getTopFrame = getTopFrame;
 exports.getDebuggeeUrl = getDebuggeeUrl;
 exports.getSkipPausing = getSkipPausing;
 exports.getChromeScopes = getChromeScopes;
 
 var _reselect = require("devtools/client/debugger/new/dist/vendors").vendored["reselect"];
 
 var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
@@ -45,29 +44,19 @@ var _sources = require("./sources");
  * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 /* eslint complexity: ["error", 30]*/
 
 /**
  * Pause reducer
  * @module reducers/pause
  */
-const createPauseState = exports.createPauseState = () => ({
+const createPauseState = exports.createPauseState = () => ({ ...emptyPauseState,
   extra: {},
-  why: null,
   isWaitingOnBreak: false,
-  frames: undefined,
-  selectedFrameId: undefined,
-  selectedComponentIndex: undefined,
-  frameScopes: {
-    generated: {},
-    original: {},
-    mappings: {}
-  },
-  loadedObjects: {},
   shouldPauseOnExceptions: _prefs.prefs.pauseOnExceptions,
   shouldPauseOnCaughtExceptions: _prefs.prefs.pauseOnCaughtExceptions,
   canRewind: false,
   debuggeeUrl: "",
   command: null,
   previousLocation: null,
   skipPausing: _prefs.prefs.skipPausing
 });
@@ -180,21 +169,16 @@ function update(state = createPauseState
         isWaitingOnBreak: true
       };
 
     case "SELECT_FRAME":
       return { ...state,
         selectedFrameId: action.frame.id
       };
 
-    case "SELECT_COMPONENT":
-      return { ...state,
-        selectedComponentIndex: action.componentIndex
-      };
-
     case "SET_POPUP_OBJECT_PROPERTIES":
       if (!action.properties) {
         return { ...state
         };
       }
 
       return { ...state,
         loadedObjects: { ...state.loadedObjects,
@@ -443,20 +427,16 @@ function getSelectedScopeMappings(state)
 
   return getFrameScopes(state).mappings[frameId];
 }
 
 function getSelectedFrameId(state) {
   return state.pause.selectedFrameId;
 }
 
-function getSelectedComponentIndex(state) {
-  return state.pause.selectedComponentIndex;
-}
-
 function getTopFrame(state) {
   const frames = getFrames(state);
   return frames && frames[0];
 }
 
 const getSelectedFrame = exports.getSelectedFrame = (0, _reselect.createSelector)(getSelectedFrameId, getFrames, (selectedFrameId, frames) => {
   if (!frames) {
     return null;
--- a/devtools/client/debugger/new/src/reducers/sources.js
+++ b/devtools/client/debugger/new/src/reducers/sources.js
@@ -68,28 +68,28 @@ function createSource(source) {
 
 function update(state = initialSourcesState(), action) {
   let location = null;
 
   switch (action.type) {
     case "UPDATE_SOURCE":
       {
         const source = action.source;
-        return updateSource(state, source);
+        return updateSources(state, [source]);
       }
 
     case "ADD_SOURCE":
       {
         const source = action.source;
-        return updateSource(state, source);
+        return updateSources(state, [source]);
       }
 
     case "ADD_SOURCES":
       {
-        return action.sources.reduce((newState, source) => updateSource(newState, source), state);
+        return updateSources(state, action.sources);
       }
 
     case "SET_SELECTED_LOCATION":
       location = { ...action.location,
         url: action.source.url
       };
       _prefs.prefs.pendingSelectedLocation = location;
       return { ...state,
@@ -128,20 +128,20 @@ function update(state = initialSourcesSt
         const {
           id,
           url
         } = action.source;
         const {
           isBlackBoxed
         } = action.value;
         updateBlackBoxList(url, isBlackBoxed);
-        return updateSource(state, {
+        return updateSources(state, [{
           id,
           isBlackBoxed
-        });
+        }]);
       }
 
       break;
 
     case "SET_PROJECT_DIRECTORY_ROOT":
       return recalculateRelativeSources(state, action.url);
 
     case "NAVIGATE":
@@ -174,53 +174,58 @@ function getTextPropsFromAction(action) 
     return {
       id: sourceId,
       error: action.error,
       loadedState: "loaded"
     };
   }
 
   return {
+    id: sourceId,
     text: action.value.text,
-    id: sourceId,
     contentType: action.value.contentType,
     loadedState: "loaded"
   };
 } // TODO: Action is coerced to `any` unfortunately because how we type
 // asynchronous actions is wrong. The `value` may be null for the
 // "start" and "error" states but we don't type it like that. We need
 // to rethink how we type async actions.
 
 
 function setSourceTextProps(state, action) {
-  const text = getTextPropsFromAction(action);
-  return updateSource(state, text);
+  const source = getTextPropsFromAction(action);
+  return updateSources(state, [source]);
+}
+
+function updateSources(state, sources) {
+  state = { ...state,
+    sources: { ...state.sources
+    },
+    relativeSources: { ...state.relativeSources
+    },
+    urls: { ...state.urls
+    }
+  };
+  return sources.reduce((newState, source) => updateSource(newState, source), state);
 }
 
 function updateSource(state, source) {
   if (!source.id) {
     return state;
   }
 
   const existingSource = state.sources[source.id];
   const updatedSource = existingSource ? { ...existingSource,
     ...source
   } : createSource(source);
+  state.sources[source.id] = updatedSource;
   const existingUrls = state.urls[source.url];
-  const urls = existingUrls ? [...existingUrls, source.id] : [source.id];
-  return { ...state,
-    relativeSources: updateRelativeSource({ ...state.relativeSources
-    }, updatedSource, state.projectDirectoryRoot),
-    sources: { ...state.sources,
-      [source.id]: updatedSource
-    },
-    urls: { ...state.urls,
-      [source.url]: urls
-    }
-  };
+  state.urls[source.url] = existingUrls ? [...existingUrls, source.id] : [source.id];
+  updateRelativeSource(state.relativeSources, updatedSource, state.projectDirectoryRoot);
+  return state;
 }
 
 function updateRelativeSource(relativeSources, source, root) {
   if (!(0, _source.underRoot)(source, root)) {
     return relativeSources;
   }
 
   const relativeSource = { ...source,
--- a/devtools/client/debugger/new/src/reducers/tabs.js
+++ b/devtools/client/debugger/new/src/reducers/tabs.js
@@ -26,57 +26,74 @@ function _interopRequireDefault(obj) { r
 
 /**
  * Tabs reducer
  * @module reducers/tabs
  */
 function update(state = _prefs.prefs.tabs || [], action) {
   switch (action.type) {
     case "ADD_TAB":
-      return updateTabList(state, action.url);
+    case "UPDATE_TAB":
+      return updateTabList(state, action);
 
     case "MOVE_TAB":
-      return updateTabList(state, action.url, action.tabIndex);
+      return moveTabInList(state, action);
 
     case "CLOSE_TAB":
     case "CLOSE_TABS":
       _prefs.prefs.tabs = action.tabs;
       return action.tabs;
 
     default:
       return state;
   }
 }
 
 function removeSourceFromTabList(tabs, url) {
-  return tabs.filter(tab => tab !== url);
+  return tabs.filter(tab => tab.url !== url);
 }
 
 function removeSourcesFromTabList(tabs, urls) {
   return urls.reduce((t, url) => removeSourceFromTabList(t, url), tabs);
 }
 /**
  * Adds the new source to the tab list if it is not already there
  * @memberof reducers/tabs
  * @static
  */
 
 
-function updateTabList(tabs, url, newIndex) {
-  const currentIndex = tabs.indexOf(url);
+function updateTabList(tabs, {
+  url,
+  framework = null
+}) {
+  const currentIndex = tabs.findIndex(tab => tab.url == url);
 
   if (currentIndex === -1) {
-    tabs = [url, ...tabs];
-  } else if (newIndex !== undefined) {
-    tabs = (0, _lodashMove2.default)(tabs, currentIndex, newIndex);
+    tabs = [{
+      url,
+      framework
+    }, ...tabs];
+  } else if (framework) {
+    tabs[currentIndex].framework = framework;
   }
 
   _prefs.prefs.tabs = tabs;
   return tabs;
 }
+
+function moveTabInList(tabs, {
+  url,
+  tabIndex: newIndex
+}) {
+  const currentIndex = tabs.findIndex(tab => tab.url == url);
+  tabs = (0, _lodashMove2.default)(tabs, currentIndex, newIndex);
+  _prefs.prefs.tabs = tabs;
+  return tabs;
+}
 /**
  * Gets the next tab to select when a tab closes. Heuristics:
  * 1. if the selected tab is available, it remains selected
  * 2. if it is gone, the next available tab to the left should be active
  * 3. if the first tab is active and closed, select the second tab
  *
  * @memberof reducers/tabs
  * @static
@@ -91,53 +108,58 @@ function getNewSelectedSourceId(state, a
   }
 
   const selectedTab = (0, _sources.getSource)(state, selectedLocation.sourceId);
 
   if (!selectedTab) {
     return "";
   }
 
-  if (availableTabs.includes(selectedTab.url)) {
+  const matchingTab = availableTabs.find(tab => tab.url == selectedTab.url);
+
+  if (matchingTab) {
     const sources = state.sources.sources;
 
     if (!sources) {
       return "";
     }
 
     const selectedSource = (0, _sources.getSourceByURL)(state, selectedTab.url);
 
     if (selectedSource) {
       return selectedSource.id;
     }
 
     return "";
   }
 
-  const tabUrls = state.tabs;
+  const tabUrls = state.tabs.map(t => t.url);
   const leftNeighborIndex = Math.max(tabUrls.indexOf(selectedTab.url) - 1, 0);
   const lastAvailbleTabIndex = availableTabs.length - 1;
   const newSelectedTabIndex = Math.min(leftNeighborIndex, lastAvailbleTabIndex);
   const availableTab = availableTabs[newSelectedTabIndex];
-  const tabSource = (0, _sources.getSourceByUrlInSources)((0, _sources.getSources)(state), (0, _sources.getUrls)(state), availableTab);
+
+  if (availableTab) {
+    const tabSource = (0, _sources.getSourceByUrlInSources)((0, _sources.getSources)(state), (0, _sources.getUrls)(state), availableTab.url);
 
-  if (tabSource) {
-    return tabSource.id;
+    if (tabSource) {
+      return tabSource.id;
+    }
   }
 
   return "";
 } // Selectors
 // Unfortunately, it's really hard to make these functions accept just
 // the state that we care about and still type it with Flow. The
 // problem is that we want to re-export all selectors from a single
 // module for the UI, and all of those selectors should take the
 // top-level app state, so we'd have to "wrap" them to automatically
 // pick off the piece of state we're interested in. It's impossible
 // (right now) to type those wrapped functions.
 
 
 const getTabs = exports.getTabs = state => state.tabs;
 
-const getSourceTabs = exports.getSourceTabs = (0, _reselect.createSelector)(getTabs, _sources.getSources, _sources.getUrls, (tabs, sources, urls) => tabs.filter(tab => (0, _sources.getSourceByUrlInSources)(sources, urls, tab)));
+const getSourceTabs = exports.getSourceTabs = (0, _reselect.createSelector)(getTabs, _sources.getSources, _sources.getUrls, (tabs, sources, urls) => tabs.filter(tab => (0, _sources.getSourceByUrlInSources)(sources, urls, tab.url)));
 const getSourcesForTabs = exports.getSourcesForTabs = (0, _reselect.createSelector)(getSourceTabs, _sources.getSources, _sources.getUrls, (tabs, sources, urls) => {
-  return tabs.map(tab => (0, _sources.getSourceByUrlInSources)(sources, urls, tab)).filter(source => source);
+  return tabs.map(tab => (0, _sources.getSourceByUrlInSources)(sources, urls, tab.url)).filter(source => source);
 });
 exports.default = update;
\ No newline at end of file
--- a/devtools/client/debugger/new/src/selectors/visibleBreakpoints.js
+++ b/devtools/client/debugger/new/src/selectors/visibleBreakpoints.js
@@ -1,58 +1,71 @@
 "use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.getVisibleBreakpoints = getVisibleBreakpoints;
+exports.getVisibleBreakpoints = undefined;
 
 var _breakpoints = require("../reducers/breakpoints");
 
 var _sources = require("../reducers/sources");
 
 var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
 
+var _reselect = require("devtools/client/debugger/new/dist/vendors").vendored["reselect"];
+
 /* 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/>. */
 function getLocation(breakpoint, isGeneratedSource) {
   return isGeneratedSource ? breakpoint.generatedLocation || breakpoint.location : breakpoint.location;
 }
 
-function formatBreakpoint(breakpoint, selectedSource) {
+function memoize(func) {
+  const store = new WeakMap();
+  return function (key, ...rest) {
+    if (store.has(key)) {
+      return store.get(key);
+    }
+
+    const value = func.apply(null, arguments);
+    store.set(key, value);
+    return value;
+  };
+}
+
+const formatBreakpoint = memoize(function (breakpoint, selectedSource) {
   const {
     condition,
     loading,
     disabled,
     hidden
   } = breakpoint;
   const sourceId = selectedSource.id;
   const isGeneratedSource = (0, _devtoolsSourceMap.isGeneratedId)(sourceId);
   return {
     location: getLocation(breakpoint, isGeneratedSource),
     condition,
     loading,
     disabled,
     hidden
   };
-}
+});
 
 function isVisible(breakpoint, selectedSource) {
   const sourceId = selectedSource.id;
   const isGeneratedSource = (0, _devtoolsSourceMap.isGeneratedId)(sourceId);
   const location = getLocation(breakpoint, isGeneratedSource);
   return location.sourceId === sourceId;
 }
 /*
  * Finds the breakpoints, which appear in the selected source.
   */
 
 
-function getVisibleBreakpoints(state) {
-  const selectedSource = (0, _sources.getSelectedSource)(state);
-
+const getVisibleBreakpoints = exports.getVisibleBreakpoints = (0, _reselect.createSelector)(_sources.getSelectedSource, _breakpoints.getBreakpoints, (selectedSource, breakpoints) => {
   if (!selectedSource) {
     return null;
   }
 
-  return (0, _breakpoints.getBreakpoints)(state).filter(bp => isVisible(bp, selectedSource)).map(bp => formatBreakpoint(bp, selectedSource));
-}
\ No newline at end of file
+  return breakpoints.filter(bp => isVisible(bp, selectedSource)).map(bp => formatBreakpoint(bp, selectedSource));
+});
\ No newline at end of file
--- a/devtools/client/debugger/new/src/utils/pause/mapScopes/index.js
+++ b/devtools/client/debugger/new/src/utils/pause/mapScopes/index.js
@@ -336,17 +336,17 @@ async function findGeneratedBinding(sour
           unscoped: true,
           // HACK: Until support for "unscoped" lands in devtools-reps,
           // this will make these show as (unavailable).
           missingArguments: true
         }
       },
       expression: null
     };
-  } else if (!hadApplicableBindings) {
+  } else if (!hadApplicableBindings && name !== "this") {
     // If there were no applicable bindings to consider while searching for
     // matching bindings, then the source map for this file didn't make any
     // attempt to map the binding, and that most likely means that the
     // code was entirely emitted from the output code.
     return {
       grip: {
         configurable: false,
         enumerable: true,
--- a/devtools/client/debugger/new/src/utils/tabs.js
+++ b/devtools/client/debugger/new/src/utils/tabs.js
@@ -1,14 +1,15 @@
 "use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.getHiddenTabs = getHiddenTabs;
+exports.getFramework = getFramework;
 exports.getTabMenuItems = getTabMenuItems;
 
 /* 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/>. */
 
 /*
  * Finds the hidden tabs by comparing the tabs' top offset.
@@ -35,16 +36,26 @@ function getHiddenTabs(sourceTabs, sourc
   }
 
   return sourceTabs.filter((tab, index) => {
     const element = sourceTabEls[index];
     return element && hasTopOffset(element);
   });
 }
 
+function getFramework(tabs, url) {
+  const tab = tabs.find(t => t.url === url);
+
+  if (tab) {
+    return tab.framework;
+  }
+
+  return "";
+}
+
 function getTabMenuItems() {
   return {
     closeTab: {
       id: "node-menu-close-tab",
       label: L10N.getStr("sourceTabs.closeTab"),
       accesskey: L10N.getStr("sourceTabs.closeTab.accesskey"),
       disabled: false
     },
--- a/devtools/client/debugger/new/test/mochitest/browser.ini
+++ b/devtools/client/debugger/new/test/mochitest/browser.ini
@@ -6,16 +6,18 @@ support-files =
   head.js
   helpers.js
   !/devtools/client/shared/test/shared-head.js
   !/devtools/client/shared/test/telemetry-test-helpers.js
   ## START-SOURCEMAPPED-FIXTURES - Generated by examples/sourcemapped/build.js
   examples/sourcemapped/polyfill-bundle.js
   examples/sourcemapped/output/parcel/babel-bindings-with-flow.js
   examples/sourcemapped/output/parcel/babel-bindings-with-flow.map
+  examples/sourcemapped/output/parcel/babel-classes.js
+  examples/sourcemapped/output/parcel/babel-classes.map
   examples/sourcemapped/output/parcel/babel-flowtype-bindings.js
   examples/sourcemapped/output/parcel/babel-flowtype-bindings.map
   examples/sourcemapped/output/parcel/classes.js
   examples/sourcemapped/output/parcel/classes.map
   examples/sourcemapped/output/parcel/esmodules.js
   examples/sourcemapped/output/parcel/esmodules.map
   examples/sourcemapped/output/parcel/esmodules-cjs.js
   examples/sourcemapped/output/parcel/esmodules-cjs.map
@@ -118,16 +120,18 @@ support-files =
   examples/sourcemapped/output/webpack3/typescript-classes.js
   examples/sourcemapped/output/webpack3/typescript-classes.js.map
   examples/sourcemapped/output/webpack3/webpack-functions.js
   examples/sourcemapped/output/webpack3/webpack-functions.js.map
   examples/sourcemapped/output/webpack3/webpack-line-mappings.js
   examples/sourcemapped/output/webpack3/webpack-line-mappings.js.map
   examples/sourcemapped/output/webpack3-babel6/babel-bindings-with-flow.js
   examples/sourcemapped/output/webpack3-babel6/babel-bindings-with-flow.js.map
+  examples/sourcemapped/output/webpack3-babel6/babel-classes.js
+  examples/sourcemapped/output/webpack3-babel6/babel-classes.js.map
   examples/sourcemapped/output/webpack3-babel6/babel-flowtype-bindings.js
   examples/sourcemapped/output/webpack3-babel6/babel-flowtype-bindings.js.map
   examples/sourcemapped/output/webpack3-babel6/classes.js
   examples/sourcemapped/output/webpack3-babel6/classes.js.map
   examples/sourcemapped/output/webpack3-babel6/esmodules.js
   examples/sourcemapped/output/webpack3-babel6/esmodules.js.map
   examples/sourcemapped/output/webpack3-babel6/esmodules-cjs.js
   examples/sourcemapped/output/webpack3-babel6/esmodules-cjs.js.map
@@ -174,16 +178,18 @@ support-files =
   examples/sourcemapped/output/webpack3-babel6/type-script-cjs.js
   examples/sourcemapped/output/webpack3-babel6/type-script-cjs.js.map
   examples/sourcemapped/output/webpack3-babel6/webpack-functions.js
   examples/sourcemapped/output/webpack3-babel6/webpack-functions.js.map
   examples/sourcemapped/output/webpack3-babel6/webpack-line-mappings.js
   examples/sourcemapped/output/webpack3-babel6/webpack-line-mappings.js.map
   examples/sourcemapped/output/webpack3-babel7/babel-bindings-with-flow.js
   examples/sourcemapped/output/webpack3-babel7/babel-bindings-with-flow.js.map
+  examples/sourcemapped/output/webpack3-babel7/babel-classes.js
+  examples/sourcemapped/output/webpack3-babel7/babel-classes.js.map
   examples/sourcemapped/output/webpack3-babel7/babel-flowtype-bindings.js
   examples/sourcemapped/output/webpack3-babel7/babel-flowtype-bindings.js.map
   examples/sourcemapped/output/webpack3-babel7/classes.js
   examples/sourcemapped/output/webpack3-babel7/classes.js.map
   examples/sourcemapped/output/webpack3-babel7/esmodules.js
   examples/sourcemapped/output/webpack3-babel7/esmodules.js.map
   examples/sourcemapped/output/webpack3-babel7/esmodules-cjs.js
   examples/sourcemapped/output/webpack3-babel7/esmodules-cjs.js.map
@@ -284,16 +290,18 @@ support-files =
   examples/sourcemapped/output/webpack4/typescript-classes.js
   examples/sourcemapped/output/webpack4/typescript-classes.js.map
   examples/sourcemapped/output/webpack4/webpack-functions.js
   examples/sourcemapped/output/webpack4/webpack-functions.js.map
   examples/sourcemapped/output/webpack4/webpack-line-mappings.js
   examples/sourcemapped/output/webpack4/webpack-line-mappings.js.map
   examples/sourcemapped/output/webpack4-babel6/babel-bindings-with-flow.js
   examples/sourcemapped/output/webpack4-babel6/babel-bindings-with-flow.js.map
+  examples/sourcemapped/output/webpack4-babel6/babel-classes.js
+  examples/sourcemapped/output/webpack4-babel6/babel-classes.js.map
   examples/sourcemapped/output/webpack4-babel6/babel-flowtype-bindings.js
   examples/sourcemapped/output/webpack4-babel6/babel-flowtype-bindings.js.map
   examples/sourcemapped/output/webpack4-babel6/classes.js
   examples/sourcemapped/output/webpack4-babel6/classes.js.map
   examples/sourcemapped/output/webpack4-babel6/esmodules.js
   examples/sourcemapped/output/webpack4-babel6/esmodules.js.map
   examples/sourcemapped/output/webpack4-babel6/esmodules-cjs.js
   examples/sourcemapped/output/webpack4-babel6/esmodules-cjs.js.map
@@ -340,16 +348,18 @@ support-files =
   examples/sourcemapped/output/webpack4-babel6/type-script-cjs.js
   examples/sourcemapped/output/webpack4-babel6/type-script-cjs.js.map
   examples/sourcemapped/output/webpack4-babel6/webpack-functions.js
   examples/sourcemapped/output/webpack4-babel6/webpack-functions.js.map
   examples/sourcemapped/output/webpack4-babel6/webpack-line-mappings.js
   examples/sourcemapped/output/webpack4-babel6/webpack-line-mappings.js.map
   examples/sourcemapped/output/webpack4-babel7/babel-bindings-with-flow.js
   examples/sourcemapped/output/webpack4-babel7/babel-bindings-with-flow.js.map
+  examples/sourcemapped/output/webpack4-babel7/babel-classes.js
+  examples/sourcemapped/output/webpack4-babel7/babel-classes.js.map
   examples/sourcemapped/output/webpack4-babel7/babel-flowtype-bindings.js
   examples/sourcemapped/output/webpack4-babel7/babel-flowtype-bindings.js.map
   examples/sourcemapped/output/webpack4-babel7/classes.js
   examples/sourcemapped/output/webpack4-babel7/classes.js.map
   examples/sourcemapped/output/webpack4-babel7/esmodules.js
   examples/sourcemapped/output/webpack4-babel7/esmodules.js.map
   examples/sourcemapped/output/webpack4-babel7/esmodules-cjs.js
   examples/sourcemapped/output/webpack4-babel7/esmodules-cjs.js.map
@@ -442,16 +452,18 @@ support-files =
   examples/sourcemapped/output/rollup/typescript-classes.js
   examples/sourcemapped/output/rollup/typescript-classes.js.map
   examples/sourcemapped/output/rollup/webpack-functions.js
   examples/sourcemapped/output/rollup/webpack-functions.js.map
   examples/sourcemapped/output/rollup/webpack-line-mappings.js
   examples/sourcemapped/output/rollup/webpack-line-mappings.js.map
   examples/sourcemapped/output/rollup-babel6/babel-bindings-with-flow.js
   examples/sourcemapped/output/rollup-babel6/babel-bindings-with-flow.js.map
+  examples/sourcemapped/output/rollup-babel6/babel-classes.js
+  examples/sourcemapped/output/rollup-babel6/babel-classes.js.map
   examples/sourcemapped/output/rollup-babel6/babel-flowtype-bindings.js
   examples/sourcemapped/output/rollup-babel6/babel-flowtype-bindings.js.map
   examples/sourcemapped/output/rollup-babel6/classes.js
   examples/sourcemapped/output/rollup-babel6/classes.js.map
   examples/sourcemapped/output/rollup-babel6/esmodules.js
   examples/sourcemapped/output/rollup-babel6/esmodules.js.map
   examples/sourcemapped/output/rollup-babel6/esmodules-es6.js
   examples/sourcemapped/output/rollup-babel6/esmodules-es6.js.map
@@ -490,16 +502,18 @@ support-files =
   examples/sourcemapped/output/rollup-babel6/type-module.js
   examples/sourcemapped/output/rollup-babel6/type-module.js.map
   examples/sourcemapped/output/rollup-babel6/webpack-functions.js
   examples/sourcemapped/output/rollup-babel6/webpack-functions.js.map
   examples/sourcemapped/output/rollup-babel6/webpack-line-mappings.js
   examples/sourcemapped/output/rollup-babel6/webpack-line-mappings.js.map
   examples/sourcemapped/output/rollup-babel7/babel-bindings-with-flow.js
   examples/sourcemapped/output/rollup-babel7/babel-bindings-with-flow.js.map
+  examples/sourcemapped/output/rollup-babel7/babel-classes.js
+  examples/sourcemapped/output/rollup-babel7/babel-classes.js.map
   examples/sourcemapped/output/rollup-babel7/babel-flowtype-bindings.js
   examples/sourcemapped/output/rollup-babel7/babel-flowtype-bindings.js.map
   examples/sourcemapped/output/rollup-babel7/classes.js
   examples/sourcemapped/output/rollup-babel7/classes.js.map
   examples/sourcemapped/output/rollup-babel7/esmodules.js
   examples/sourcemapped/output/rollup-babel7/esmodules.js.map
   examples/sourcemapped/output/rollup-babel7/esmodules-es6.js
   examples/sourcemapped/output/rollup-babel7/esmodules-es6.js.map
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-console-async.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-console-async.js
@@ -33,17 +33,17 @@ async function hasMessage(dbg, msg) {
   return waitFor(async () => findMessages(
     webConsole._frameWindow,
     msg
   ).length > 0)
 }
 
 add_task(async function() {
   Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true);
-  Services.prefs.setBoolPref("devtools.map-await-expression", true);
+  Services.prefs.setBoolPref("devtools.debugger.features.map-await-expression", true);
 
   const dbg = await initDebugger("doc-script-switching.html");
 
   await selectSource(dbg, "switching-01");
 
   // open the console
   await getSplitConsole(dbg);
   ok(dbg.toolbox.splitConsole, "Split console is shown.");
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemapped-breakpoint-console.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemapped-breakpoint-console.js
@@ -73,9 +73,14 @@ add_task(async function() {
 
   await evalInConsoleAtPoint(
     dbg,
     "webpack3-babel6",
     "shadowed-vars",
     { line: 18, column: 6 },
     [`aVar === "var3"`, `aLet === "let3"`, `aConst === "const3"`]
   );
+
+  await evalInConsoleAtPoint(dbg, "webpack3-babel6", "babel-classes", { line: 8, column: 6 }, [
+    `this.hasOwnProperty("bound")`,
+  ]);
+
 });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-tabs.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-tabs.js
@@ -25,15 +25,15 @@ add_task(async function() {
   await waitForSelectedSource(dbg);
 });
 
 add_task(async function() {
   const dbg = await initDebugger("doc-scripts.html", "simple1", "simple2");
 
   await selectSource(dbg, "simple1");
   await selectSource(dbg, "simple2");
-  closeTab(dbg, "simple1");
-  closeTab(dbg, "simple2");
+  await closeTab(dbg, "simple1");
+  await closeTab(dbg, "simple2");
 
   // Test reloading the debugger
   await reload(dbg, "simple1", "simple2");
   is(countTabs(dbg), 0);
 });
--- a/devtools/client/debugger/new/test/mochitest/examples/doc-sourcemapped.html
+++ b/devtools/client/debugger/new/test/mochitest/examples/doc-sourcemapped.html
@@ -11,16 +11,18 @@
     <!-- INJECTED-START -->
     <!--
       Content generated by examples/sourcemapped/build.js.
       Run "yarn build" to update.
     -->
     <h2>parcel</h2>
     <script src="sourcemapped/output/parcel/babel-bindings-with-flow.js"></script>
     <button onclick="parcelBabelBindingsWithFlow()">Run babel-bindings-with-flow</button>
+    <script src="sourcemapped/output/parcel/babel-classes.js"></script>
+    <button onclick="parcelBabelClasses()">Run babel-classes</button>
     <script src="sourcemapped/output/parcel/babel-flowtype-bindings.js"></script>
     <button onclick="parcelBabelFlowtypeBindings()">Run babel-flowtype-bindings</button>
     <script src="sourcemapped/output/parcel/classes.js"></script>
     <button onclick="parcelClasses()">Run classes</button>
     <script src="sourcemapped/output/parcel/esmodules.js"></script>
     <button onclick="parcelEsmodules()">Run esmodules</button>
     <script src="sourcemapped/output/parcel/esmodules-cjs.js"></script>
     <button onclick="parcelEsmodulesCjs()">Run esmodules-cjs</button>
@@ -125,16 +127,18 @@
     <button onclick="webpack3TypescriptClasses()">Run typescript-classes</button>
     <script src="sourcemapped/output/webpack3/webpack-functions.js"></script>
     <button onclick="webpack3WebpackFunctions()">Run webpack-functions</button>
     <script src="sourcemapped/output/webpack3/webpack-line-mappings.js"></script>
     <button onclick="webpack3WebpackLineMappings()">Run webpack-line-mappings</button>
     <h2>webpack3-babel6</h2>
     <script src="sourcemapped/output/webpack3-babel6/babel-bindings-with-flow.js"></script>
     <button onclick="webpack3Babel6BabelBindingsWithFlow()">Run babel-bindings-with-flow</button>
+    <script src="sourcemapped/output/webpack3-babel6/babel-classes.js"></script>
+    <button onclick="webpack3Babel6BabelClasses()">Run babel-classes</button>
     <script src="sourcemapped/output/webpack3-babel6/babel-flowtype-bindings.js"></script>
     <button onclick="webpack3Babel6BabelFlowtypeBindings()">Run babel-flowtype-bindings</button>
     <script src="sourcemapped/output/webpack3-babel6/classes.js"></script>
     <button onclick="webpack3Babel6Classes()">Run classes</button>
     <script src="sourcemapped/output/webpack3-babel6/esmodules.js"></script>
     <button onclick="webpack3Babel6Esmodules()">Run esmodules</button>
     <script src="sourcemapped/output/webpack3-babel6/esmodules-cjs.js"></script>
     <button onclick="webpack3Babel6EsmodulesCjs()">Run esmodules-cjs</button>
@@ -182,16 +186,18 @@
     <button onclick="webpack3Babel6TypeScriptCjs()">Run type-script-cjs</button>
     <script src="sourcemapped/output/webpack3-babel6/webpack-functions.js"></script>
     <button onclick="webpack3Babel6WebpackFunctions()">Run webpack-functions</button>
     <script src="sourcemapped/output/webpack3-babel6/webpack-line-mappings.js"></script>
     <button onclick="webpack3Babel6WebpackLineMappings()">Run webpack-line-mappings</button>
     <h2>webpack3-babel7</h2>
     <script src="sourcemapped/output/webpack3-babel7/babel-bindings-with-flow.js"></script>
     <button onclick="webpack3Babel7BabelBindingsWithFlow()">Run babel-bindings-with-flow</button>
+    <script src="sourcemapped/output/webpack3-babel7/babel-classes.js"></script>
+    <button onclick="webpack3Babel7BabelClasses()">Run babel-classes</button>
     <script src="sourcemapped/output/webpack3-babel7/babel-flowtype-bindings.js"></script>
     <button onclick="webpack3Babel7BabelFlowtypeBindings()">Run babel-flowtype-bindings</button>
     <script src="sourcemapped/output/webpack3-babel7/classes.js"></script>
     <button onclick="webpack3Babel7Classes()">Run classes</button>
     <script src="sourcemapped/output/webpack3-babel7/esmodules.js"></script>
     <button onclick="webpack3Babel7Esmodules()">Run esmodules</button>
     <script src="sourcemapped/output/webpack3-babel7/esmodules-cjs.js"></script>
     <button onclick="webpack3Babel7EsmodulesCjs()">Run esmodules-cjs</button>
@@ -294,16 +300,18 @@
     <button onclick="webpack4TypescriptClasses()">Run typescript-classes</button>
     <script src="sourcemapped/output/webpack4/webpack-functions.js"></script>
     <button onclick="webpack4WebpackFunctions()">Run webpack-functions</button>
     <script src="sourcemapped/output/webpack4/webpack-line-mappings.js"></script>
     <button onclick="webpack4WebpackLineMappings()">Run webpack-line-mappings</button>
     <h2>webpack4-babel6</h2>
     <script src="sourcemapped/output/webpack4-babel6/babel-bindings-with-flow.js"></script>
     <button onclick="webpack4Babel6BabelBindingsWithFlow()">Run babel-bindings-with-flow</button>
+    <script src="sourcemapped/output/webpack4-babel6/babel-classes.js"></script>
+    <button onclick="webpack4Babel6BabelClasses()">Run babel-classes</button>
     <script src="sourcemapped/output/webpack4-babel6/babel-flowtype-bindings.js"></script>
     <button onclick="webpack4Babel6BabelFlowtypeBindings()">Run babel-flowtype-bindings</button>
     <script src="sourcemapped/output/webpack4-babel6/classes.js"></script>
     <button onclick="webpack4Babel6Classes()">Run classes</button>
     <script src="sourcemapped/output/webpack4-babel6/esmodules.js"></script>
     <button onclick="webpack4Babel6Esmodules()">Run esmodules</button>
     <script src="sourcemapped/output/webpack4-babel6/esmodules-cjs.js"></script>
     <button onclick="webpack4Babel6EsmodulesCjs()">Run esmodules-cjs</button>
@@ -351,16 +359,18 @@
     <button onclick="webpack4Babel6TypeScriptCjs()">Run type-script-cjs</button>
     <script src="sourcemapped/output/webpack4-babel6/webpack-functions.js"></script>
     <button onclick="webpack4Babel6WebpackFunctions()">Run webpack-functions</button>
     <script src="sourcemapped/output/webpack4-babel6/webpack-line-mappings.js"></script>
     <button onclick="webpack4Babel6WebpackLineMappings()">Run webpack-line-mappings</button>
     <h2>webpack4-babel7</h2>
     <script src="sourcemapped/output/webpack4-babel7/babel-bindings-with-flow.js"></script>
     <button onclick="webpack4Babel7BabelBindingsWithFlow()">Run babel-bindings-with-flow</button>
+    <script src="sourcemapped/output/webpack4-babel7/babel-classes.js"></script>
+    <button onclick="webpack4Babel7BabelClasses()">Run babel-classes</button>
     <script src="sourcemapped/output/webpack4-babel7/babel-flowtype-bindings.js"></script>
     <button onclick="webpack4Babel7BabelFlowtypeBindings()">Run babel-flowtype-bindings</button>
     <script src="sourcemapped/output/webpack4-babel7/classes.js"></script>
     <button onclick="webpack4Babel7Classes()">Run classes</button>
     <script src="sourcemapped/output/webpack4-babel7/esmodules.js"></script>
     <button onclick="webpack4Babel7Esmodules()">Run esmodules</button>
     <script src="sourcemapped/output/webpack4-babel7/esmodules-cjs.js"></script>
     <button onclick="webpack4Babel7EsmodulesCjs()">Run esmodules-cjs</button>
@@ -455,16 +465,18 @@
     <button onclick="rollupTypescriptClasses()">Run typescript-classes</button>
     <script src="sourcemapped/output/rollup/webpack-functions.js"></script>
     <button onclick="rollupWebpackFunctions()">Run webpack-functions</button>
     <script src="sourcemapped/output/rollup/webpack-line-mappings.js"></script>
     <button onclick="rollupWebpackLineMappings()">Run webpack-line-mappings</button>
     <h2>rollup-babel6</h2>
     <script src="sourcemapped/output/rollup-babel6/babel-bindings-with-flow.js"></script>
     <button onclick="rollupBabel6BabelBindingsWithFlow()">Run babel-bindings-with-flow</button>
+    <script src="sourcemapped/output/rollup-babel6/babel-classes.js"></script>
+    <button onclick="rollupBabel6BabelClasses()">Run babel-classes</button>
     <script src="sourcemapped/output/rollup-babel6/babel-flowtype-bindings.js"></script>
     <button onclick="rollupBabel6BabelFlowtypeBindings()">Run babel-flowtype-bindings</button>
     <script src="sourcemapped/output/rollup-babel6/classes.js"></script>
     <button onclick="rollupBabel6Classes()">Run classes</button>
     <script src="sourcemapped/output/rollup-babel6/esmodules.js"></script>
     <button onclick="rollupBabel6Esmodules()">Run esmodules</button>
     <script src="sourcemapped/output/rollup-babel6/esmodules-es6.js"></script>
     <button onclick="rollupBabel6EsmodulesEs6()">Run esmodules-es6</button>
@@ -504,16 +516,18 @@
     <button onclick="rollupBabel6TypeModule()">Run type-module</button>
     <script src="sourcemapped/output/rollup-babel6/webpack-functions.js"></script>
     <button onclick="rollupBabel6WebpackFunctions()">Run webpack-functions</button>
     <script src="sourcemapped/output/rollup-babel6/webpack-line-mappings.js"></script>
     <button onclick="rollupBabel6WebpackLineMappings()">Run webpack-line-mappings</button>
     <h2>rollup-babel7</h2>
     <script src="sourcemapped/output/rollup-babel7/babel-bindings-with-flow.js"></script>
     <button onclick="rollupBabel7BabelBindingsWithFlow()">Run babel-bindings-with-flow</button>
+    <script src="sourcemapped/output/rollup-babel7/babel-classes.js"></script>
+    <button onclick="rollupBabel7BabelClasses()">Run babel-classes</button>
     <script src="sourcemapped/output/rollup-babel7/babel-flowtype-bindings.js"></script>
     <button onclick="rollupBabel7BabelFlowtypeBindings()">Run babel-flowtype-bindings</button>
     <script src="sourcemapped/output/rollup-babel7/classes.js"></script>
     <button onclick="rollupBabel7Classes()">Run classes</button>
     <script src="sourcemapped/output/rollup-babel7/esmodules.js"></script>
     <button onclick="rollupBabel7Esmodules()">Run esmodules</button>
     <script src="sourcemapped/output/rollup-babel7/esmodules-es6.js"></script>
     <button onclick="rollupBabel7EsmodulesEs6()">Run esmodules-es6</button>
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/rollup-babel6/index.js
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/rollup-babel6/index.js
@@ -38,17 +38,20 @@ module.exports = exports = async functio
         },
         rollupBabel({
           babelrc: false,
           presets: [
             babelEnv
               ? [require.resolve("babel-preset-env"), { modules: false }]
               : null
           ].filter(Boolean),
-          plugins: [require.resolve("babel-plugin-transform-flow-strip-types")]
+          plugins: [
+            require.resolve("babel-plugin-transform-flow-strip-types"),
+            require.resolve("babel-plugin-transform-class-properties")
+          ]
         }),
         {
           ongenerate(out, data) {
             data.map.sources = data.map.sources.map(source =>
               source.replace(/^fixtures[\\/]/, `${TARGET_NAME}://./`)
             );
           }
         }
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/rollup-babel7/index.js
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/rollup-babel7/index.js
@@ -33,16 +33,19 @@ module.exports = exports = async functio
           resolveId: id => (id === "fake-bundle-root" ? id : undefined),
           load: id =>
             id === "fake-bundle-root"
               ? `import test from "${input}"; export default test;`
               : undefined
         },
         rollupBabel({
           babelrc: false,
+          plugins: [
+            require.resolve("@babel/plugin-proposal-class-properties")
+          ],
           presets: [
             require.resolve("@babel/preset-flow"),
             babelEnv
               ? [require.resolve("@babel/preset-env"), { modules: false }]
               : null
           ].filter(Boolean)
         }),
         {
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/rollup-babel7/package.json
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/rollup-babel7/package.json
@@ -1,12 +1,13 @@
 {
   "name": "sourcemapped-rollup",
   "private": true,
   "dependencies": {
     "@babel/core": "^7.0.0-beta.54",
     "@babel/preset-env": "^7.0.0-beta.54",
     "@babel/preset-flow": "^7.0.0-beta.54",
+    "@babel/plugin-proposal-class-properties": "^7.0.0-beta.54",
     "lodash": "^4.17.5",
     "rollup": "^0.63.0",
     "rollup-plugin-babel": "^4.0.0-beta.7"
   }
 }
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/rollup-babel7/yarn.lock
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/rollup-babel7/yarn.lock
@@ -3,16 +3,22 @@
 
 
 "@babel/code-frame@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.54.tgz#0024f96fdf7028a21d68e273afd4e953214a1ead"
   dependencies:
     "@babel/highlight" "7.0.0-beta.54"
 
+"@babel/code-frame@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-rc.1.tgz#5c2154415d6c09959a71845ef519d11157e95d10"
+  dependencies:
+    "@babel/highlight" "7.0.0-rc.1"
+
 "@babel/core@^7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0-beta.54.tgz#253c54d0095403a5cfa764e7d9b458194692d02b"
   dependencies:
     "@babel/code-frame" "7.0.0-beta.54"
     "@babel/generator" "7.0.0-beta.54"
     "@babel/helpers" "7.0.0-beta.54"
     "@babel/parser" "7.0.0-beta.54"
@@ -32,16 +38,26 @@
   resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.54.tgz#c043c7eebeebfd7e665d95c281a4aafc83d4e1c9"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
     jsesc "^2.5.1"
     lodash "^4.17.5"
     source-map "^0.5.0"
     trim-right "^1.0.1"
 
+"@babel/generator@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-rc.1.tgz#739c87d70b31aeed802bd6bc9fd51480065c45e8"
+  dependencies:
+    "@babel/types" "7.0.0-rc.1"
+    jsesc "^2.5.1"
+    lodash "^4.17.10"
+    source-map "^0.5.0"
+    trim-right "^1.0.1"
+
 "@babel/helper-annotate-as-pure@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-beta.54.tgz#1626126a3f9fc4ed280ac942372c7d39653d7121"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
 "@babel/helper-builder-binary-assignment-operator-visitor@7.0.0-beta.54":
   version "7.0.0-beta.54"
@@ -76,34 +92,54 @@
 "@babel/helper-function-name@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.54.tgz#307875507a1eda2482a09a9a4df6a25632ffb34b"
   dependencies:
     "@babel/helper-get-function-arity" "7.0.0-beta.54"
     "@babel/template" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-function-name@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-rc.1.tgz#20b2cc836a53c669f297c8d309fc553385c5cdde"
+  dependencies:
+    "@babel/helper-get-function-arity" "7.0.0-rc.1"
+    "@babel/template" "7.0.0-rc.1"
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-get-function-arity@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.54.tgz#757bd189b077074a004028cfde5f083c306cc6c4"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-get-function-arity@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-rc.1.tgz#60185957f72ed73766ce74c836ac574921743c46"
+  dependencies:
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-hoist-variables@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0-beta.54.tgz#8635be8095135ff73f753ed189e449f68b4f43cb"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
 "@babel/helper-member-expression-to-functions@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0-beta.54.tgz#bce9ddc484317b13d2615bafe2b524d0d56d99df"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-member-expression-to-functions@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0-rc.1.tgz#03a3b200fc00f8100dbcef9a351b69cfc0234b4f"
+  dependencies:
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-module-imports@7.0.0-beta.51":
   version "7.0.0-beta.51"
   resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.51.tgz#ce00428045fbb7d5ebc0ea7bf835789f15366ab2"
   dependencies:
     "@babel/types" "7.0.0-beta.51"
     lodash "^4.17.5"
 
 "@babel/helper-module-imports@7.0.0-beta.54":
@@ -125,20 +161,30 @@
     lodash "^4.17.5"
 
 "@babel/helper-optimise-call-expression@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-beta.54.tgz#4af8dd4ff90dbd29b3bcf85fff43952e2ae1016e"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-optimise-call-expression@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-rc.1.tgz#482d8251870f61d88c9800fd3e58128e14ff8c98"
+  dependencies:
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-plugin-utils@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0-beta.54.tgz#61d2a9a0f9a3e31838a458debb9eebd7bdd249b4"
 
+"@babel/helper-plugin-utils@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0-rc.1.tgz#3e277eae59818e7d4caf4174f58a7a00d441336e"
+
 "@babel/helper-regex@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0-beta.54.tgz#8ac562f855f132fc68dfd10b132552555ac870d9"
   dependencies:
     lodash "^4.17.5"
 
 "@babel/helper-remap-async-to-generator@7.0.0-beta.54":
   version "7.0.0-beta.54"
@@ -154,30 +200,45 @@
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-beta.54.tgz#901f5a1493a410799fd3ab3e0c0d29d18071c89f"
   dependencies:
     "@babel/helper-member-expression-to-functions" "7.0.0-beta.54"
     "@babel/helper-optimise-call-expression" "7.0.0-beta.54"
     "@babel/traverse" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-replace-supers@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-rc.1.tgz#cab8d7a6c758e4561fb285f4725c850d68c1c3db"
+  dependencies:
+    "@babel/helper-member-expression-to-functions" "7.0.0-rc.1"
+    "@babel/helper-optimise-call-expression" "7.0.0-rc.1"
+    "@babel/traverse" "7.0.0-rc.1"
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-simple-access@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.0.0-beta.54.tgz#5f760a19589a9b6f07e80a65ef4bcbd4fba8c253"
   dependencies:
     "@babel/template" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
     lodash "^4.17.5"
 
 "@babel/helper-split-export-declaration@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.54.tgz#89cd8833c95481a0827ac6a1bfccddb92b75a109"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-split-export-declaration@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-rc.1.tgz#b00323834343fd0210f1f46c7a53521ad53efa5e"
+  dependencies:
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-wrap-function@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-beta.54.tgz#dc1b7a483a3074a3531b36523e03156d910a3a2a"
   dependencies:
     "@babel/helper-function-name" "7.0.0-beta.54"
     "@babel/template" "7.0.0-beta.54"
     "@babel/traverse" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
@@ -193,28 +254,51 @@
 "@babel/highlight@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.54.tgz#155d507358329b8e7068970017c3fd74a9b08584"
   dependencies:
     chalk "^2.0.0"
     esutils "^2.0.2"
     js-tokens "^3.0.0"
 
+"@babel/highlight@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-rc.1.tgz#e0ca4731fa4786f7b9500421d6ff5e5a7753e81e"
+  dependencies:
+    chalk "^2.0.0"
+    esutils "^2.0.2"
+    js-tokens "^3.0.0"
+
 "@babel/parser@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.0.0-beta.54.tgz#c01aa63b57c9c8dce8744796c81d9df121f20db4"
 
+"@babel/parser@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.0.0-rc.1.tgz#d009a9bba8175d7b971e30cd03535b278c44082d"
+
 "@babel/plugin-proposal-async-generator-functions@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.0.0-beta.54.tgz#19871bd655b5d748b0ae3e9ecebe247be8b7f83b"
   dependencies:
     "@babel/helper-plugin-utils" "7.0.0-beta.54"
     "@babel/helper-remap-async-to-generator" "7.0.0-beta.54"
     "@babel/plugin-syntax-async-generators" "7.0.0-beta.54"
 
+"@babel/plugin-proposal-class-properties@^7.0.0-beta.54":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0-rc.1.tgz#88b3d3b257b9ed53fae50b13103e4c3c725e704e"
+  dependencies:
+    "@babel/helper-function-name" "7.0.0-rc.1"
+    "@babel/helper-member-expression-to-functions" "7.0.0-rc.1"
+    "@babel/helper-optimise-call-expression" "7.0.0-rc.1"
+    "@babel/helper-plugin-utils" "7.0.0-rc.1"
+    "@babel/helper-replace-supers" "7.0.0-rc.1"
+    "@babel/plugin-syntax-class-properties" "7.0.0-rc.1"
+
 "@babel/plugin-proposal-object-rest-spread@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.54.tgz#5481269a020dd0d38715a8094fed015d30ef4c2a"
   dependencies:
     "@babel/helper-plugin-utils" "7.0.0-beta.54"
     "@babel/plugin-syntax-object-rest-spread" "7.0.0-beta.54"
 
 "@babel/plugin-proposal-optional-catch-binding@7.0.0-beta.54":
@@ -233,16 +317,22 @@
     regexpu-core "^4.2.0"
 
 "@babel/plugin-syntax-async-generators@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0-beta.54.tgz#ffac8f64927614762897cc9643495fd38097dd41"
   dependencies:
     "@babel/helper-plugin-utils" "7.0.0-beta.54"
 
+"@babel/plugin-syntax-class-properties@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0-rc.1.tgz#155343e256c84d127496e46675a3049636d311ff"
+  dependencies:
+    "@babel/helper-plugin-utils" "7.0.0-rc.1"
+
 "@babel/plugin-syntax-flow@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.0.0-beta.54.tgz#8d38fffa6da16e2d327f5fee4f90913b14d43d14"
   dependencies:
     "@babel/helper-plugin-utils" "7.0.0-beta.54"
 
 "@babel/plugin-syntax-object-rest-spread@7.0.0-beta.54":
   version "7.0.0-beta.54"
@@ -507,46 +597,77 @@
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.54.tgz#d5b0d2d2d55c0e78b048c61a058f36cfd7d91af3"
   dependencies:
     "@babel/code-frame" "7.0.0-beta.54"
     "@babel/parser" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
     lodash "^4.17.5"
 
+"@babel/template@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-rc.1.tgz#5f9c0a481c9f22ecdb84697b3c3a34eadeeca23c"
+  dependencies:
+    "@babel/code-frame" "7.0.0-rc.1"
+    "@babel/parser" "7.0.0-rc.1"
+    "@babel/types" "7.0.0-rc.1"
+    lodash "^4.17.10"
+
 "@babel/traverse@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.54.tgz#2c17f98dcdbf19aa918fde128f0e1a0bc089e05a"
   dependencies:
     "@babel/code-frame" "7.0.0-beta.54"
     "@babel/generator" "7.0.0-beta.54"
     "@babel/helper-function-name" "7.0.0-beta.54"
     "@babel/helper-split-export-declaration" "7.0.0-beta.54"
     "@babel/parser" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
     debug "^3.1.0"
     globals "^11.1.0"
     lodash "^4.17.5"
 
+"@babel/traverse@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-rc.1.tgz#867b4b45ada2d51ae2d0076f1c1d5880f8557158"
+  dependencies:
+    "@babel/code-frame" "7.0.0-rc.1"
+    "@babel/generator" "7.0.0-rc.1"
+    "@babel/helper-function-name" "7.0.0-rc.1"
+    "@babel/helper-split-export-declaration" "7.0.0-rc.1"
+    "@babel/parser" "7.0.0-rc.1"
+    "@babel/types" "7.0.0-rc.1"
+    debug "^3.1.0"
+    globals "^11.1.0"
+    lodash "^4.17.10"
+
 "@babel/types@7.0.0-beta.51":
   version "7.0.0-beta.51"
   resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.51.tgz#d802b7b543b5836c778aa691797abf00f3d97ea9"
   dependencies:
     esutils "^2.0.2"
     lodash "^4.17.5"
     to-fast-properties "^2.0.0"
 
 "@babel/types@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.54.tgz#025ad68492fed542c13f14c579a44c848e531063"
   dependencies:
     esutils "^2.0.2"
     lodash "^4.17.5"
     to-fast-properties "^2.0.0"
 
+"@babel/types@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-rc.1.tgz#6abf6d14ddd9fc022617e5b62e6b32f4fa6526ad"
+  dependencies:
+    esutils "^2.0.2"
+    lodash "^4.17.10"
+    to-fast-properties "^2.0.0"
+
 "@types/estree@0.0.39":
   version "0.0.39"
   resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
 
 "@types/node@*":
   version "10.5.3"
   resolved "https://registry.yarnpkg.com/@types/node/-/node-10.5.3.tgz#5bcfaf088ad17894232012877669634c06b20cc5"
 
@@ -787,17 +908,17 @@ kind-of@^3.0.2:
   resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
   dependencies:
     is-buffer "^1.1.5"
 
 kind-of@^6.0.0:
   version "6.0.2"
   resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051"
 
-lodash@^4.17.5:
+lodash@^4.17.10, lodash@^4.17.5:
   version "4.17.10"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
 
 loose-envify@^1.0.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
   dependencies:
     js-tokens "^3.0.0 || ^4.0.0"
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/webpack3-babel6/index.js
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/webpack3-babel6/index.js
@@ -50,17 +50,18 @@ module.exports = exports = async functio
                 babelEnv
                   ? [
                       require.resolve("babel-preset-env"),
                       { modules: babelModules ? "commonjs" : false }
                     ]
                   : null
               ].filter(Boolean),
               plugins: [
-                require.resolve("babel-plugin-transform-flow-strip-types")
+                require.resolve("babel-plugin-transform-flow-strip-types"),
+                require.resolve("babel-plugin-transform-class-properties")
               ]
             }
           }
         ].filter(Boolean)
       }
     });
 
     fixtures.push({
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/webpack3-babel7/index.js
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/webpack3-babel7/index.js
@@ -41,16 +41,19 @@ module.exports = exports = async functio
       module: {
         loaders: [
           {
             test: /\.js$/,
             exclude: /node_modules/,
             loader: require.resolve("babel-loader"),
             options: {
               babelrc: false,
+              plugins: [
+                require.resolve("@babel/plugin-proposal-class-properties")
+              ],
               presets: [
                 require.resolve("@babel/preset-flow"),
                 babelEnv
                   ? [
                       require.resolve("@babel/preset-env"),
                       { modules: babelModules ? "commonjs" : false }
                     ]
                   : null
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/webpack3-babel7/package.json
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/webpack3-babel7/package.json
@@ -1,12 +1,13 @@
 {
   "name": "sourcemapped-webpack3-babel7",
   "private": true,
   "dependencies": {
     "@babel/core": "^7.0.0-beta.54",
     "@babel/preset-env": "^7.0.0-beta.54",
     "@babel/preset-flow": "^7.0.0-beta.54",
+    "@babel/plugin-proposal-class-properties": "^7.0.0-beta.54",
     "babel-loader": "^8.0.0-beta.4",
     "lodash": "^4.17.10",
     "webpack": "3"
   }
 }
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/webpack3-babel7/yarn.lock
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/webpack3-babel7/yarn.lock
@@ -3,16 +3,22 @@
 
 
 "@babel/code-frame@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.54.tgz#0024f96fdf7028a21d68e273afd4e953214a1ead"
   dependencies:
     "@babel/highlight" "7.0.0-beta.54"
 
+"@babel/code-frame@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-rc.1.tgz#5c2154415d6c09959a71845ef519d11157e95d10"
+  dependencies:
+    "@babel/highlight" "7.0.0-rc.1"
+
 "@babel/core@^7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0-beta.54.tgz#253c54d0095403a5cfa764e7d9b458194692d02b"
   dependencies:
     "@babel/code-frame" "7.0.0-beta.54"
     "@babel/generator" "7.0.0-beta.54"
     "@babel/helpers" "7.0.0-beta.54"
     "@babel/parser" "7.0.0-beta.54"
@@ -32,16 +38,26 @@
   resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.54.tgz#c043c7eebeebfd7e665d95c281a4aafc83d4e1c9"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
     jsesc "^2.5.1"
     lodash "^4.17.5"
     source-map "^0.5.0"
     trim-right "^1.0.1"
 
+"@babel/generator@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-rc.1.tgz#739c87d70b31aeed802bd6bc9fd51480065c45e8"
+  dependencies:
+    "@babel/types" "7.0.0-rc.1"
+    jsesc "^2.5.1"
+    lodash "^4.17.10"
+    source-map "^0.5.0"
+    trim-right "^1.0.1"
+
 "@babel/helper-annotate-as-pure@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-beta.54.tgz#1626126a3f9fc4ed280ac942372c7d39653d7121"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
 "@babel/helper-builder-binary-assignment-operator-visitor@7.0.0-beta.54":
   version "7.0.0-beta.54"
@@ -76,34 +92,54 @@
 "@babel/helper-function-name@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.54.tgz#307875507a1eda2482a09a9a4df6a25632ffb34b"
   dependencies:
     "@babel/helper-get-function-arity" "7.0.0-beta.54"
     "@babel/template" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-function-name@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-rc.1.tgz#20b2cc836a53c669f297c8d309fc553385c5cdde"
+  dependencies:
+    "@babel/helper-get-function-arity" "7.0.0-rc.1"
+    "@babel/template" "7.0.0-rc.1"
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-get-function-arity@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.54.tgz#757bd189b077074a004028cfde5f083c306cc6c4"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-get-function-arity@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-rc.1.tgz#60185957f72ed73766ce74c836ac574921743c46"
+  dependencies:
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-hoist-variables@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0-beta.54.tgz#8635be8095135ff73f753ed189e449f68b4f43cb"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
 "@babel/helper-member-expression-to-functions@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0-beta.54.tgz#bce9ddc484317b13d2615bafe2b524d0d56d99df"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-member-expression-to-functions@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0-rc.1.tgz#03a3b200fc00f8100dbcef9a351b69cfc0234b4f"
+  dependencies:
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-module-imports@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.54.tgz#c2d8e14ff034225bf431356db77ef467b8d35aac"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
     lodash "^4.17.5"
 
 "@babel/helper-module-transforms@7.0.0-beta.54":
@@ -118,20 +154,30 @@
     lodash "^4.17.5"
 
 "@babel/helper-optimise-call-expression@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-beta.54.tgz#4af8dd4ff90dbd29b3bcf85fff43952e2ae1016e"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-optimise-call-expression@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-rc.1.tgz#482d8251870f61d88c9800fd3e58128e14ff8c98"
+  dependencies:
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-plugin-utils@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0-beta.54.tgz#61d2a9a0f9a3e31838a458debb9eebd7bdd249b4"
 
+"@babel/helper-plugin-utils@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0-rc.1.tgz#3e277eae59818e7d4caf4174f58a7a00d441336e"
+
 "@babel/helper-regex@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0-beta.54.tgz#8ac562f855f132fc68dfd10b132552555ac870d9"
   dependencies:
     lodash "^4.17.5"
 
 "@babel/helper-remap-async-to-generator@7.0.0-beta.54":
   version "7.0.0-beta.54"
@@ -147,30 +193,45 @@
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-beta.54.tgz#901f5a1493a410799fd3ab3e0c0d29d18071c89f"
   dependencies:
     "@babel/helper-member-expression-to-functions" "7.0.0-beta.54"
     "@babel/helper-optimise-call-expression" "7.0.0-beta.54"
     "@babel/traverse" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-replace-supers@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-rc.1.tgz#cab8d7a6c758e4561fb285f4725c850d68c1c3db"
+  dependencies:
+    "@babel/helper-member-expression-to-functions" "7.0.0-rc.1"
+    "@babel/helper-optimise-call-expression" "7.0.0-rc.1"
+    "@babel/traverse" "7.0.0-rc.1"
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-simple-access@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.0.0-beta.54.tgz#5f760a19589a9b6f07e80a65ef4bcbd4fba8c253"
   dependencies:
     "@babel/template" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
     lodash "^4.17.5"
 
 "@babel/helper-split-export-declaration@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.54.tgz#89cd8833c95481a0827ac6a1bfccddb92b75a109"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-split-export-declaration@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-rc.1.tgz#b00323834343fd0210f1f46c7a53521ad53efa5e"
+  dependencies:
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-wrap-function@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-beta.54.tgz#dc1b7a483a3074a3531b36523e03156d910a3a2a"
   dependencies:
     "@babel/helper-function-name" "7.0.0-beta.54"
     "@babel/template" "7.0.0-beta.54"
     "@babel/traverse" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
@@ -186,28 +247,51 @@
 "@babel/highlight@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.54.tgz#155d507358329b8e7068970017c3fd74a9b08584"
   dependencies:
     chalk "^2.0.0"
     esutils "^2.0.2"
     js-tokens "^3.0.0"
 
+"@babel/highlight@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-rc.1.tgz#e0ca4731fa4786f7b9500421d6ff5e5a7753e81e"
+  dependencies:
+    chalk "^2.0.0"
+    esutils "^2.0.2"
+    js-tokens "^3.0.0"
+
 "@babel/parser@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.0.0-beta.54.tgz#c01aa63b57c9c8dce8744796c81d9df121f20db4"
 
+"@babel/parser@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.0.0-rc.1.tgz#d009a9bba8175d7b971e30cd03535b278c44082d"
+
 "@babel/plugin-proposal-async-generator-functions@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.0.0-beta.54.tgz#19871bd655b5d748b0ae3e9ecebe247be8b7f83b"
   dependencies:
     "@babel/helper-plugin-utils" "7.0.0-beta.54"
     "@babel/helper-remap-async-to-generator" "7.0.0-beta.54"
     "@babel/plugin-syntax-async-generators" "7.0.0-beta.54"
 
+"@babel/plugin-proposal-class-properties@^7.0.0-beta.54":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0-rc.1.tgz#88b3d3b257b9ed53fae50b13103e4c3c725e704e"
+  dependencies:
+    "@babel/helper-function-name" "7.0.0-rc.1"
+    "@babel/helper-member-expression-to-functions" "7.0.0-rc.1"
+    "@babel/helper-optimise-call-expression" "7.0.0-rc.1"
+    "@babel/helper-plugin-utils" "7.0.0-rc.1"
+    "@babel/helper-replace-supers" "7.0.0-rc.1"
+    "@babel/plugin-syntax-class-properties" "7.0.0-rc.1"
+
 "@babel/plugin-proposal-object-rest-spread@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.54.tgz#5481269a020dd0d38715a8094fed015d30ef4c2a"
   dependencies:
     "@babel/helper-plugin-utils" "7.0.0-beta.54"
     "@babel/plugin-syntax-object-rest-spread" "7.0.0-beta.54"
 
 "@babel/plugin-proposal-optional-catch-binding@7.0.0-beta.54":
@@ -226,16 +310,22 @@
     regexpu-core "^4.2.0"
 
 "@babel/plugin-syntax-async-generators@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0-beta.54.tgz#ffac8f64927614762897cc9643495fd38097dd41"
   dependencies:
     "@babel/helper-plugin-utils" "7.0.0-beta.54"
 
+"@babel/plugin-syntax-class-properties@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0-rc.1.tgz#155343e256c84d127496e46675a3049636d311ff"
+  dependencies:
+    "@babel/helper-plugin-utils" "7.0.0-rc.1"
+
 "@babel/plugin-syntax-flow@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.0.0-beta.54.tgz#8d38fffa6da16e2d327f5fee4f90913b14d43d14"
   dependencies:
     "@babel/helper-plugin-utils" "7.0.0-beta.54"
 
 "@babel/plugin-syntax-object-rest-spread@7.0.0-beta.54":
   version "7.0.0-beta.54"
@@ -500,38 +590,69 @@
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.54.tgz#d5b0d2d2d55c0e78b048c61a058f36cfd7d91af3"
   dependencies:
     "@babel/code-frame" "7.0.0-beta.54"
     "@babel/parser" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
     lodash "^4.17.5"
 
+"@babel/template@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-rc.1.tgz#5f9c0a481c9f22ecdb84697b3c3a34eadeeca23c"
+  dependencies:
+    "@babel/code-frame" "7.0.0-rc.1"
+    "@babel/parser" "7.0.0-rc.1"
+    "@babel/types" "7.0.0-rc.1"
+    lodash "^4.17.10"
+
 "@babel/traverse@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.54.tgz#2c17f98dcdbf19aa918fde128f0e1a0bc089e05a"
   dependencies:
     "@babel/code-frame" "7.0.0-beta.54"
     "@babel/generator" "7.0.0-beta.54"
     "@babel/helper-function-name" "7.0.0-beta.54"
     "@babel/helper-split-export-declaration" "7.0.0-beta.54"
     "@babel/parser" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
     debug "^3.1.0"
     globals "^11.1.0"
     lodash "^4.17.5"
 
+"@babel/traverse@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-rc.1.tgz#867b4b45ada2d51ae2d0076f1c1d5880f8557158"
+  dependencies:
+    "@babel/code-frame" "7.0.0-rc.1"
+    "@babel/generator" "7.0.0-rc.1"
+    "@babel/helper-function-name" "7.0.0-rc.1"
+    "@babel/helper-split-export-declaration" "7.0.0-rc.1"
+    "@babel/parser" "7.0.0-rc.1"
+    "@babel/types" "7.0.0-rc.1"
+    debug "^3.1.0"
+    globals "^11.1.0"
+    lodash "^4.17.10"
+
 "@babel/types@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.54.tgz#025ad68492fed542c13f14c579a44c848e531063"
   dependencies:
     esutils "^2.0.2"
     lodash "^4.17.5"
     to-fast-properties "^2.0.0"
 
+"@babel/types@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-rc.1.tgz#6abf6d14ddd9fc022617e5b62e6b32f4fa6526ad"
+  dependencies:
+    esutils "^2.0.2"
+    lodash "^4.17.10"
+    to-fast-properties "^2.0.0"
+
 abbrev@1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
 
 acorn-dynamic-import@^2.0.0:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4"
   dependencies:
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/webpack4-babel6/index.js
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/webpack4-babel6/index.js
@@ -51,17 +51,18 @@ module.exports = exports = async functio
                 babelEnv
                   ? [
                       require.resolve("babel-preset-env"),
                       { modules: babelModules ? "commonjs" : false }
                     ]
                   : null
               ].filter(Boolean),
               plugins: [
-                require.resolve("babel-plugin-transform-flow-strip-types")
+                require.resolve("babel-plugin-transform-flow-strip-types"),
+                require.resolve("babel-plugin-transform-class-properties")
               ]
             }
           }
         ].filter(Boolean)
       }
     });
 
     fixtures.push({
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/webpack4-babel7/index.js
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/webpack4-babel7/index.js
@@ -42,16 +42,19 @@ module.exports = exports = async functio
       module: {
         rules: [
           {
             test: /\.js$/,
             exclude: /node_modules/,
             loader: require.resolve("babel-loader"),
             options: {
               babelrc: false,
+              plugins: [
+                require.resolve("@babel/plugin-proposal-class-properties")
+              ],
               presets: [
                 require.resolve("@babel/preset-flow"),
                 babelEnv
                   ? [
                       require.resolve("@babel/preset-env"),
                       { modules: babelModules ? "commonjs" : false }
                     ]
                   : null
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/webpack4-babel7/package.json
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/webpack4-babel7/package.json
@@ -1,12 +1,13 @@
 {
   "name": "sourcemapped-webpack3-babel7",
   "private": true,
   "dependencies": {
     "@babel/core": "^7.0.0-beta.54",
     "@babel/preset-env": "^7.0.0-beta.54",
     "@babel/preset-flow": "^7.0.0-beta.54",
     "babel-loader": "^8.0.0-beta.4",
+    "@babel/plugin-proposal-class-properties": "^7.0.0-beta.54",
     "lodash": "^4.17.10",
     "webpack": "^4"
   }
 }
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/webpack4-babel7/yarn.lock
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/builds/webpack4-babel7/yarn.lock
@@ -3,16 +3,22 @@
 
 
 "@babel/code-frame@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.54.tgz#0024f96fdf7028a21d68e273afd4e953214a1ead"
   dependencies:
     "@babel/highlight" "7.0.0-beta.54"
 
+"@babel/code-frame@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-rc.1.tgz#5c2154415d6c09959a71845ef519d11157e95d10"
+  dependencies:
+    "@babel/highlight" "7.0.0-rc.1"
+
 "@babel/core@^7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0-beta.54.tgz#253c54d0095403a5cfa764e7d9b458194692d02b"
   dependencies:
     "@babel/code-frame" "7.0.0-beta.54"
     "@babel/generator" "7.0.0-beta.54"
     "@babel/helpers" "7.0.0-beta.54"
     "@babel/parser" "7.0.0-beta.54"
@@ -32,16 +38,26 @@
   resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.54.tgz#c043c7eebeebfd7e665d95c281a4aafc83d4e1c9"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
     jsesc "^2.5.1"
     lodash "^4.17.5"
     source-map "^0.5.0"
     trim-right "^1.0.1"
 
+"@babel/generator@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-rc.1.tgz#739c87d70b31aeed802bd6bc9fd51480065c45e8"
+  dependencies:
+    "@babel/types" "7.0.0-rc.1"
+    jsesc "^2.5.1"
+    lodash "^4.17.10"
+    source-map "^0.5.0"
+    trim-right "^1.0.1"
+
 "@babel/helper-annotate-as-pure@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-beta.54.tgz#1626126a3f9fc4ed280ac942372c7d39653d7121"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
 "@babel/helper-builder-binary-assignment-operator-visitor@7.0.0-beta.54":
   version "7.0.0-beta.54"
@@ -76,34 +92,54 @@
 "@babel/helper-function-name@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.54.tgz#307875507a1eda2482a09a9a4df6a25632ffb34b"
   dependencies:
     "@babel/helper-get-function-arity" "7.0.0-beta.54"
     "@babel/template" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-function-name@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-rc.1.tgz#20b2cc836a53c669f297c8d309fc553385c5cdde"
+  dependencies:
+    "@babel/helper-get-function-arity" "7.0.0-rc.1"
+    "@babel/template" "7.0.0-rc.1"
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-get-function-arity@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.54.tgz#757bd189b077074a004028cfde5f083c306cc6c4"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-get-function-arity@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-rc.1.tgz#60185957f72ed73766ce74c836ac574921743c46"
+  dependencies:
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-hoist-variables@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0-beta.54.tgz#8635be8095135ff73f753ed189e449f68b4f43cb"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
 "@babel/helper-member-expression-to-functions@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0-beta.54.tgz#bce9ddc484317b13d2615bafe2b524d0d56d99df"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-member-expression-to-functions@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0-rc.1.tgz#03a3b200fc00f8100dbcef9a351b69cfc0234b4f"
+  dependencies:
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-module-imports@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.54.tgz#c2d8e14ff034225bf431356db77ef467b8d35aac"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
     lodash "^4.17.5"
 
 "@babel/helper-module-transforms@7.0.0-beta.54":
@@ -118,20 +154,30 @@
     lodash "^4.17.5"
 
 "@babel/helper-optimise-call-expression@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-beta.54.tgz#4af8dd4ff90dbd29b3bcf85fff43952e2ae1016e"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-optimise-call-expression@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-rc.1.tgz#482d8251870f61d88c9800fd3e58128e14ff8c98"
+  dependencies:
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-plugin-utils@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0-beta.54.tgz#61d2a9a0f9a3e31838a458debb9eebd7bdd249b4"
 
+"@babel/helper-plugin-utils@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0-rc.1.tgz#3e277eae59818e7d4caf4174f58a7a00d441336e"
+
 "@babel/helper-regex@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0-beta.54.tgz#8ac562f855f132fc68dfd10b132552555ac870d9"
   dependencies:
     lodash "^4.17.5"
 
 "@babel/helper-remap-async-to-generator@7.0.0-beta.54":
   version "7.0.0-beta.54"
@@ -147,30 +193,45 @@
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-beta.54.tgz#901f5a1493a410799fd3ab3e0c0d29d18071c89f"
   dependencies:
     "@babel/helper-member-expression-to-functions" "7.0.0-beta.54"
     "@babel/helper-optimise-call-expression" "7.0.0-beta.54"
     "@babel/traverse" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-replace-supers@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-rc.1.tgz#cab8d7a6c758e4561fb285f4725c850d68c1c3db"
+  dependencies:
+    "@babel/helper-member-expression-to-functions" "7.0.0-rc.1"
+    "@babel/helper-optimise-call-expression" "7.0.0-rc.1"
+    "@babel/traverse" "7.0.0-rc.1"
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-simple-access@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.0.0-beta.54.tgz#5f760a19589a9b6f07e80a65ef4bcbd4fba8c253"
   dependencies:
     "@babel/template" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
     lodash "^4.17.5"
 
 "@babel/helper-split-export-declaration@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.54.tgz#89cd8833c95481a0827ac6a1bfccddb92b75a109"
   dependencies:
     "@babel/types" "7.0.0-beta.54"
 
+"@babel/helper-split-export-declaration@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-rc.1.tgz#b00323834343fd0210f1f46c7a53521ad53efa5e"
+  dependencies:
+    "@babel/types" "7.0.0-rc.1"
+
 "@babel/helper-wrap-function@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-beta.54.tgz#dc1b7a483a3074a3531b36523e03156d910a3a2a"
   dependencies:
     "@babel/helper-function-name" "7.0.0-beta.54"
     "@babel/template" "7.0.0-beta.54"
     "@babel/traverse" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
@@ -186,28 +247,51 @@
 "@babel/highlight@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.54.tgz#155d507358329b8e7068970017c3fd74a9b08584"
   dependencies:
     chalk "^2.0.0"
     esutils "^2.0.2"
     js-tokens "^3.0.0"
 
+"@babel/highlight@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-rc.1.tgz#e0ca4731fa4786f7b9500421d6ff5e5a7753e81e"
+  dependencies:
+    chalk "^2.0.0"
+    esutils "^2.0.2"
+    js-tokens "^3.0.0"
+
 "@babel/parser@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.0.0-beta.54.tgz#c01aa63b57c9c8dce8744796c81d9df121f20db4"
 
+"@babel/parser@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.0.0-rc.1.tgz#d009a9bba8175d7b971e30cd03535b278c44082d"
+
 "@babel/plugin-proposal-async-generator-functions@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.0.0-beta.54.tgz#19871bd655b5d748b0ae3e9ecebe247be8b7f83b"
   dependencies:
     "@babel/helper-plugin-utils" "7.0.0-beta.54"
     "@babel/helper-remap-async-to-generator" "7.0.0-beta.54"
     "@babel/plugin-syntax-async-generators" "7.0.0-beta.54"
 
+"@babel/plugin-proposal-class-properties@^7.0.0-beta.54":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0-rc.1.tgz#88b3d3b257b9ed53fae50b13103e4c3c725e704e"
+  dependencies:
+    "@babel/helper-function-name" "7.0.0-rc.1"
+    "@babel/helper-member-expression-to-functions" "7.0.0-rc.1"
+    "@babel/helper-optimise-call-expression" "7.0.0-rc.1"
+    "@babel/helper-plugin-utils" "7.0.0-rc.1"
+    "@babel/helper-replace-supers" "7.0.0-rc.1"
+    "@babel/plugin-syntax-class-properties" "7.0.0-rc.1"
+
 "@babel/plugin-proposal-object-rest-spread@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.54.tgz#5481269a020dd0d38715a8094fed015d30ef4c2a"
   dependencies:
     "@babel/helper-plugin-utils" "7.0.0-beta.54"
     "@babel/plugin-syntax-object-rest-spread" "7.0.0-beta.54"
 
 "@babel/plugin-proposal-optional-catch-binding@7.0.0-beta.54":
@@ -226,16 +310,22 @@
     regexpu-core "^4.2.0"
 
 "@babel/plugin-syntax-async-generators@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0-beta.54.tgz#ffac8f64927614762897cc9643495fd38097dd41"
   dependencies:
     "@babel/helper-plugin-utils" "7.0.0-beta.54"
 
+"@babel/plugin-syntax-class-properties@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0-rc.1.tgz#155343e256c84d127496e46675a3049636d311ff"
+  dependencies:
+    "@babel/helper-plugin-utils" "7.0.0-rc.1"
+
 "@babel/plugin-syntax-flow@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.0.0-beta.54.tgz#8d38fffa6da16e2d327f5fee4f90913b14d43d14"
   dependencies:
     "@babel/helper-plugin-utils" "7.0.0-beta.54"
 
 "@babel/plugin-syntax-object-rest-spread@7.0.0-beta.54":
   version "7.0.0-beta.54"
@@ -500,38 +590,69 @@
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.54.tgz#d5b0d2d2d55c0e78b048c61a058f36cfd7d91af3"
   dependencies:
     "@babel/code-frame" "7.0.0-beta.54"
     "@babel/parser" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
     lodash "^4.17.5"
 
+"@babel/template@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-rc.1.tgz#5f9c0a481c9f22ecdb84697b3c3a34eadeeca23c"
+  dependencies:
+    "@babel/code-frame" "7.0.0-rc.1"
+    "@babel/parser" "7.0.0-rc.1"
+    "@babel/types" "7.0.0-rc.1"
+    lodash "^4.17.10"
+
 "@babel/traverse@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.54.tgz#2c17f98dcdbf19aa918fde128f0e1a0bc089e05a"
   dependencies:
     "@babel/code-frame" "7.0.0-beta.54"
     "@babel/generator" "7.0.0-beta.54"
     "@babel/helper-function-name" "7.0.0-beta.54"
     "@babel/helper-split-export-declaration" "7.0.0-beta.54"
     "@babel/parser" "7.0.0-beta.54"
     "@babel/types" "7.0.0-beta.54"
     debug "^3.1.0"
     globals "^11.1.0"
     lodash "^4.17.5"
 
+"@babel/traverse@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-rc.1.tgz#867b4b45ada2d51ae2d0076f1c1d5880f8557158"
+  dependencies:
+    "@babel/code-frame" "7.0.0-rc.1"
+    "@babel/generator" "7.0.0-rc.1"
+    "@babel/helper-function-name" "7.0.0-rc.1"
+    "@babel/helper-split-export-declaration" "7.0.0-rc.1"
+    "@babel/parser" "7.0.0-rc.1"
+    "@babel/types" "7.0.0-rc.1"
+    debug "^3.1.0"
+    globals "^11.1.0"
+    lodash "^4.17.10"
+
 "@babel/types@7.0.0-beta.54":
   version "7.0.0-beta.54"
   resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.54.tgz#025ad68492fed542c13f14c579a44c848e531063"
   dependencies:
     esutils "^2.0.2"
     lodash "^4.17.5"
     to-fast-properties "^2.0.0"
 
+"@babel/types@7.0.0-rc.1":
+  version "7.0.0-rc.1"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-rc.1.tgz#6abf6d14ddd9fc022617e5b62e6b32f4fa6526ad"
+  dependencies:
+    esutils "^2.0.2"
+    lodash "^4.17.10"
+    to-fast-properties "^2.0.0"
+
 "@webassemblyjs/ast@1.5.13":
   version "1.5.13"
   resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.13.tgz#81155a570bd5803a30ec31436bc2c9c0ede38f25"
   dependencies:
     "@webassemblyjs/helper-module-context" "1.5.13"
     "@webassemblyjs/helper-wasm-bytecode" "1.5.13"
     "@webassemblyjs/wast-parser" "1.5.13"
     debug "^3.1.0"
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/fixtures/babel-classes/input.js
@@ -0,0 +1,15 @@
+export default function root() {
+  class Another {
+    bound = () => {
+      return this;
+    }
+
+    method() {
+      let two = 2;
+
+      console.log("pause here", Another, root);
+    }
+  }
+
+  new Another().method();
+}
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/parcel/babel-classes.js
@@ -0,0 +1,132 @@
+// modules are defined as an array
+// [ module function, map of requires ]
+//
+// map of requires is short require name -> numeric require
+//
+// anything defined in a previous bundle is accessed via the
+// orig method which is the require for previous bundles
+
+// eslint-disable-next-line no-global-assign
+parcelRequire = (function (modules, cache, entry, globalName) {
+  // Save the require from previous bundle to this closure if any
+  var previousRequire = typeof parcelRequire === 'function' && parcelRequire;
+  var nodeRequire = typeof require === 'function' && require;
+
+  function newRequire(name, jumped) {
+    if (!cache[name]) {
+      if (!modules[name]) {
+        // if we cannot find the module within our internal map or
+        // cache jump to the current global require ie. the last bundle
+        // that was added to the page.
+        var currentRequire = typeof parcelRequire === 'function' && parcelRequire;
+        if (!jumped && currentRequire) {
+          return currentRequire(name, true);
+        }
+
+        // If there are other bundles on this page the require from the
+        // previous one is saved to 'previousRequire'. Repeat this as
+        // many times as there are bundles until the module is found or
+        // we exhaust the require chain.
+        if (previousRequire) {
+          return previousRequire(name, true);
+        }
+
+        // Try the node require function if it exists.
+        if (nodeRequire && typeof name === 'string') {
+          return nodeRequire(name);
+        }
+
+        var err = new Error('Cannot find module \'' + name + '\'');
+        err.code = 'MODULE_NOT_FOUND';
+        throw err;
+      }
+
+      localRequire.resolve = resolve;
+
+      var module = cache[name] = new newRequire.Module(name);
+
+      modules[name][0].call(module.exports, localRequire, module, module.exports, this);
+    }
+
+    return cache[name].exports;
+
+    function localRequire(x){
+      return newRequire(localRequire.resolve(x));
+    }
+
+    function resolve(x){
+      return modules[name][1][x] || x;
+    }
+  }
+
+  function Module(moduleName) {
+    this.id = moduleName;
+    this.bundle = newRequire;
+    this.exports = {};
+  }
+
+  newRequire.isParcelRequire = true;
+  newRequire.Module = Module;
+  newRequire.modules = modules;
+  newRequire.cache = cache;
+  newRequire.parent = previousRequire;
+  newRequire.register = function (id, exports) {
+    modules[id] = [function (require, module) {
+      module.exports = exports;
+    }, {}];
+  };
+
+  for (var i = 0; i < entry.length; i++) {
+    newRequire(entry[i]);
+  }
+
+  if (entry.length) {
+    // Expose entry point to Node, AMD or browser globals
+    // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
+    var mainExports = newRequire(entry[entry.length - 1]);
+
+    // CommonJS
+    if (typeof exports === "object" && typeof module !== "undefined") {
+      module.exports = mainExports;
+
+    // RequireJS
+    } else if (typeof define === "function" && define.amd) {
+     define(function () {
+       return mainExports;
+     });
+
+    // <script>
+    } else if (globalName) {
+      this[globalName] = mainExports;
+    }
+  }
+
+  // Override the current require with this new one
+  return newRequire;
+})({"input.js":[function(require,module,exports) {
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = root;
+function root() {
+  class Another {
+    constructor() {
+      this.bound = () => {
+        return this;
+      };
+    }
+
+    method() {
+      let two = 2;
+
+      console.log("pause here", Another, root);
+    }
+  }
+
+  new Another().method();
+}
+},{}]},{},["input.js"], "parcelBabelClasses")
+//# sourceMappingURL=babel-classes.map
+;parcelBabelClasses = parcelBabelClasses.default;
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/parcel/babel-classes.map
@@ -0,0 +1,1 @@
+{"version":3,"sources":["parcel://./babel-classes/input.js"],"names":["root","Another","bound","method","two","console","log"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAwBA;AAAT,SAASA,IAAT,GAAgB;AAC7B,QAAMC,OAAN,CAAc;AAAA;AAAA,WACZC,KADY,GACJ,MAAM;AACZ,eAAO,IAAP;AACD,OAHW;AAAA;;AAKZC,aAAS;AACP,UAAIC,MAAM,CAAV;;AAEAC,cAAQC,GAAR,CAAY,YAAZ,EAA0BL,OAA1B,EAAmCD,IAAnC;AACD;AATW;;AAYd,MAAIC,OAAJ,GAAcE,MAAd;AACD","file":"babel-classes.map","sourcesContent":["export default function root() {\n  class Another {\n    bound = () => {\n      return this;\n    }\n\n    method() {\n      let two = 2;\n\n      console.log(\"pause here\", Another, root);\n    }\n  }\n\n  new Another().method();\n}\n"]}
\ No newline at end of file
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/parcel/typescript-classes.js
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/parcel/typescript-classes.js
@@ -116,20 +116,23 @@ exports.decoratorFactory = decoratorFact
 function def() {}
 exports["default"] = def;
 },{}],"input.ts":[function(require,module,exports) {
 "use strict";
 // This file essentially reproduces an example Angular component to map testing,
 // among other typescript edge cases.
 
 var __extends = this && this.__extends || function () {
-    var extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) {
-        d.__proto__ = b;
-    } || function (d, b) {
-        for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) {
+            d.__proto__ = b;
+        } || function (d, b) {
+            for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+        };
+        return extendStatics(d, b);
     };
     return function (d, b) {
         extendStatics(d, b);
         function __() {
             this.constructor = d;
         }
         d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
     };
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/parcel/typescript-classes.map
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/parcel/typescript-classes.map
@@ -1,1 +1,1 @@
-{"version":3,"sources":["parcel://./typescript-classes/src/mod.ts","parcel://./typescript-classes/input.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,SAAA,gBAAA,CAAiC,IAAjC,EAA2D;AACzD,WAAO,SAAA,SAAA,CAAmB,MAAnB,EAAyB;AAC9B,eAAY,MAAZ;AACD,KAFD;AAGD;AAJD,QAAA,gBAAA,GAAA,gBAAA;AAMA,SAAA,GAAA,GAAA,CAAgC;AAAhC,QAAA,SAAA,IAAA,GAAA;;;ACPA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,IAAA,WAAA,QAAA,cAAA,CAAA;AAEA,IAAA,KAAA,aAAA,QAAA,cAAA,CAAA,CAAA;AAKA,IAAA,eAAA,aAAA,YAAA;AAHA,aAAA,YAAA,GAAA;AAIE,aAAA,KAAA,GAAQ,KAAR;AACD;AAFY,mBAAY,WAAA,CAHxB,SAAA,gBAAA,CAAiB;AAChB,kBAAU;AADM,KAAjB,CAGwB,CAAA,EAAZ,YAAY,CAAZ;AAEb,WAAA,YAAA;AAFA,CAAA,EAAA;AAAa,QAAA,YAAA,GAAA,YAAA;AAIb,IAAM,KAAK,UAAA,GAAA,EAAG;AACZ,YAAQ,GAAR,CAAY,MAAZ;AACD,CAFD;AAGA,GAAG,KAAH;AAEA;AACA;AACA,IAAA,gBAAA,aAAA,YAAA;AAAA,aAAA,aAAA,GAAA;AACE,aAAA,KAAA,GAAQ,KAAR;AACD;AAAD,WAAA,aAAA;AAFA,CAAA,EAAA;AAAa,QAAA,aAAA,GAAA,aAAA;AAIb,IAAA,eAAA,aAAA,YAAA;AAAA,aAAA,YAAA,GAAA;AACE,aAAA,IAAA,GAAO,CAAP;AACD;AAAD,WAAA,YAAA;AAFA,CAAA,EAAA;AAIA,IAAM,kBAAe,aAAA,YAAA;AAAG,aAAA,GAAA,GAAA;AACtB,aAAA,IAAA,GAAO,CAAP;AACD;AAAD,WAAA,GAAA;AAFwB,CAAH,EAArB;AAIA,IAAA,UAAA,aAAA,UAAA,MAAA,EAAA;AAAsB,cAAA,OAAA,EAAA,MAAA;AAAtB,aAAA,OAAA,GAAA;AAAA,YAAA,QAAA,WAAA,IAAA,IAAA,OAAA,KAAA,CAAA,IAAA,EAAA,SAAA,CAAA,IAAA,IAAA;AACE,cAAA,IAAA,GAAO,CAAP;;AACD;AAAD,WAAA,OAAA;AAFA,CAAA,CAAsB,YAAtB,CAAA;AAIA,IAAI,SAAM,aAAA,UAAA,MAAA,EAAA;AAAyB,cAAA,OAAA,EAAA,MAAA;AAAtB,aAAA,OAAA,GAAA;AAAA,YAAA,QAAA,WAAA,IAAA,IAAA,OAAA,KAAA,CAAA,IAAA,EAAA,SAAA,CAAA,IAAA,IAAA;AACX,cAAA,IAAA,GAAO,CAAP;;AACD;AAAD,WAAA,OAAA;AAFa,CAAH,CAAyB,YAAzB,CAAV;AAIA;AAEA,SAAA,SAAA,GAAA;AACE;AACA;AACA;AACA,SAAK,EAAL;AAEA,YAAQ,GAAR,CAAY,YAAZ;AACD;AAPD,QAAA,SAAA,IAAA,SAAA","file":"typescript-classes.map","sourcesContent":["\nexport function decoratorFactory(opts: { selector: string }) {\n  return function decorator(target) {\n    return <any>target;\n  };\n}\n\nexport default function def() {}\n","// This file essentially reproduces an example Angular component to map testing,\n// among other typescript edge cases.\n\nimport def, { decoratorFactory } from './src/mod.ts';\n\nimport * as ns from './src/mod.ts';\n\n@decoratorFactory({\n  selector: 'app-root',\n})\nexport class AppComponent {\n  title = 'app';\n}\n\nconst fn = arg => {\n  console.log(\"here\");\n};\nfn(\"arg\");\n\n// Un-decorated exported classes present a mapping challege because\n// the class name is mapped to an unhelpful export assignment.\nexport class ExportedOther {\n  title = 'app';\n}\n\nclass AnotherThing {\n  prop = 4;\n}\n\nconst ExpressionClass = class Foo {\n  prop = 4;\n};\n\nclass SubDecl extends AnotherThing {\n  prop = 4;\n}\n\nlet SubVar = class SubExpr extends AnotherThing {\n  prop = 4;\n};\n\nns;\n\nexport default function(){\n  // This file is specifically for testing the mappings of classes and things\n  // above, which means we don't want to include _other_ references to then.\n  // To avoid having them be optimized out, we include a no-op eval.\n  eval(\"\");\n\n  console.log(\"pause here\");\n}\n"]}
\ No newline at end of file
+{"version":3,"sources":["parcel://./typescript-classes/src/mod.ts","parcel://./typescript-classes/input.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,SAAgB,gBAAhB,CAAiC,IAAjC,EAA2D;AACzD,WAAO,SAAS,SAAT,CAAmB,MAAnB,EAAyB;AAC9B,eAAY,MAAZ;AACD,KAFD;AAGD;AAJD,QAAA,gBAAA,GAAA,gBAAA;AAMA,SAAwB,GAAxB,GAA2B,CAAK;AAAhC,QAAA,SAAA,IAAA,GAAA;;;ACPA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,IAAA,WAAA,QAAA,cAAA,CAAA;AAEA,IAAA,KAAA,aAAA,QAAA,cAAA,CAAA,CAAA;AAKA,IAAA,eAAA,aAAA,YAAA;AAHA,aAAA,YAAA,GAAA;AAIE,aAAA,KAAA,GAAQ,KAAR;AACD;AAFY,mBAAY,WAAA,CAHxB,SAAA,gBAAA,CAAiB;AAChB,kBAAU;AADM,KAAjB,CAGwB,CAAA,EAAZ,YAAY,CAAZ;AAEb,WAAA,YAAA;AAFA,CAAA,EAAA;AAAa,QAAA,YAAA,GAAA,YAAA;AAIb,IAAM,KAAK,UAAA,GAAA,EAAG;AACZ,YAAQ,GAAR,CAAY,MAAZ;AACD,CAFD;AAGA,GAAG,KAAH;AAEA;AACA;AACA,IAAA,gBAAA,aAAA,YAAA;AAAA,aAAA,aAAA,GAAA;AACE,aAAA,KAAA,GAAQ,KAAR;AACD;AAAD,WAAA,aAAA;AAFA,CAAA,EAAA;AAAa,QAAA,aAAA,GAAA,aAAA;AAIb,IAAA,eAAA,aAAA,YAAA;AAAA,aAAA,YAAA,GAAA;AACE,aAAA,IAAA,GAAO,CAAP;AACD;AAAD,WAAA,YAAA;AAFA,CAAA,EAAA;AAIA,IAAM,kBAAe,aAAA,YAAA;AAAG,aAAA,GAAA,GAAA;AACtB,aAAA,IAAA,GAAO,CAAP;AACD;AAAD,WAAA,GAAA;AAFwB,CAAH,EAArB;AAIA,IAAA,UAAA,aAAA,UAAA,MAAA,EAAA;AAAsB,cAAA,OAAA,EAAA,MAAA;AAAtB,aAAA,OAAA,GAAA;AAAA,YAAA,QAAA,WAAA,IAAA,IAAA,OAAA,KAAA,CAAA,IAAA,EAAA,SAAA,CAAA,IAAA,IAAA;AACE,cAAA,IAAA,GAAO,CAAP;;AACD;AAAD,WAAA,OAAA;AAFA,CAAA,CAAsB,YAAtB,CAAA;AAIA,IAAI,SAAM,aAAA,UAAA,MAAA,EAAA;AAAyB,cAAA,OAAA,EAAA,MAAA;AAAtB,aAAA,OAAA,GAAA;AAAA,YAAA,QAAA,WAAA,IAAA,IAAA,OAAA,KAAA,CAAA,IAAA,EAAA,SAAA,CAAA,IAAA,IAAA;AACX,cAAA,IAAA,GAAO,CAAP;;AACD;AAAD,WAAA,OAAA;AAFa,CAAH,CAAyB,YAAzB,CAAV;AAIA;AAEA,SAAA,SAAA,GAAA;AACE;AACA;AACA;AACA,SAAK,EAAL;AAEA,YAAQ,GAAR,CAAY,YAAZ;AACD;AAPD,QAAA,SAAA,IAAA,SAAA","file":"typescript-classes.map","sourcesContent":["\nexport function decoratorFactory(opts: { selector: string }) {\n  return function decorator(target) {\n    return <any>target;\n  };\n}\n\nexport default function def() {}\n","// This file essentially reproduces an example Angular component to map testing,\n// among other typescript edge cases.\n\nimport def, { decoratorFactory } from './src/mod.ts';\n\nimport * as ns from './src/mod.ts';\n\n@decoratorFactory({\n  selector: 'app-root',\n})\nexport class AppComponent {\n  title = 'app';\n}\n\nconst fn = arg => {\n  console.log(\"here\");\n};\nfn(\"arg\");\n\n// Un-decorated exported classes present a mapping challege because\n// the class name is mapped to an unhelpful export assignment.\nexport class ExportedOther {\n  title = 'app';\n}\n\nclass AnotherThing {\n  prop = 4;\n}\n\nconst ExpressionClass = class Foo {\n  prop = 4;\n};\n\nclass SubDecl extends AnotherThing {\n  prop = 4;\n}\n\nlet SubVar = class SubExpr extends AnotherThing {\n  prop = 4;\n};\n\nns;\n\nexport default function(){\n  // This file is specifically for testing the mappings of classes and things\n  // above, which means we don't want to include _other_ references to then.\n  // To avoid having them be optimized out, we include a no-op eval.\n  eval(\"\");\n\n  console.log(\"pause here\");\n}\n"]}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/rollup-babel6/babel-classes.js
@@ -0,0 +1,37 @@
+var rollupBabel6BabelClasses = (function () {
+  'use strict';
+
+  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+  function root() {
+    var Another = function () {
+      function Another() {
+        var _this = this;
+
+        _classCallCheck(this, Another);
+
+        this.bound = function () {
+          return _this;
+        };
+      }
+
+      _createClass(Another, [{
+        key: "method",
+        value: function method() {
+
+          console.log("pause here", Another, root);
+        }
+      }]);
+
+      return Another;
+    }();
+
+    new Another().method();
+  }
+
+  return root;
+
+}());
+//# sourceMappingURL=babel-classes.js.map
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/rollup-babel6/babel-classes.js.map
@@ -0,0 +1,1 @@
+{"version":3,"file":"babel-classes.js","sources":["rollup-babel6://./babel-classes/input.js"],"sourcesContent":["export default function root() {\n  class Another {\n    bound = () => {\n      return this;\n    }\n\n    method() {\n      let two = 2;\n\n      console.log(\"pause here\", Another, root);\n    }\n  }\n\n  new Another().method();\n}\n"],"names":["root","Another","bound","console","log","method"],"mappings":";;;;;;;AAAA,EAAe,SAASA,IAAT,GAAgB;EAAA,MACvBC,OADuB;EAAA;EAAA;;EAAA;;EAAA,WAE3BC,KAF2B,GAEnB,YAAM;EACZ,eAAO,KAAP;EACD,OAJ0B;EAAA;;EAAA;EAAA;EAAA,+BAMlB;AACP;EAEAC,gBAAQC,GAAR,CAAY,YAAZ,EAA0BH,OAA1B,EAAmCD,IAAnC;EACD;EAV0B;;EAAA;EAAA;;EAa7B,MAAIC,OAAJ,GAAcI,MAAd;EACD;;;;;;;;"}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/rollup-babel7/babel-classes.js
@@ -0,0 +1,71 @@
+var rollupBabel7BabelClasses = (function () {
+  'use strict';
+
+  function _classCallCheck(instance, Constructor) {
+    if (!(instance instanceof Constructor)) {
+      throw new TypeError("Cannot call a class as a function");
+    }
+  }
+
+  function _defineProperties(target, props) {
+    for (var i = 0; i < props.length; i++) {
+      var descriptor = props[i];
+      descriptor.enumerable = descriptor.enumerable || false;
+      descriptor.configurable = true;
+      if ("value" in descriptor) descriptor.writable = true;
+      Object.defineProperty(target, descriptor.key, descriptor);
+    }
+  }
+
+  function _createClass(Constructor, protoProps, staticProps) {
+    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
+    if (staticProps) _defineProperties(Constructor, staticProps);
+    return Constructor;
+  }
+
+  function _defineProperty(obj, key, value) {
+    if (key in obj) {
+      Object.defineProperty(obj, key, {
+        value: value,
+        enumerable: true,
+        configurable: true,
+        writable: true
+      });
+    } else {
+      obj[key] = value;
+    }
+
+    return obj;
+  }
+
+  function root() {
+    var Another =
+    /*#__PURE__*/
+    function () {
+      function Another() {
+        var _this = this;
+
+        _classCallCheck(this, Another);
+
+        _defineProperty(this, "bound", function () {
+          return _this;
+        });
+      }
+
+      _createClass(Another, [{
+        key: "method",
+        value: function method() {
+          console.log("pause here", Another, root);
+        }
+      }]);
+
+      return Another;
+    }();
+
+    new Another().method();
+  }
+
+  return root;
+
+}());
+//# sourceMappingURL=babel-classes.js.map
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/rollup-babel7/babel-classes.js.map
@@ -0,0 +1,1 @@
+{"version":3,"file":"babel-classes.js","sources":["rollup-babel7://./babel-classes/input.js"],"sourcesContent":["export default function root() {\n  class Another {\n    bound = () => {\n      return this;\n    }\n\n    method() {\n      let two = 2;\n\n      console.log(\"pause here\", Another, root);\n    }\n  }\n\n  new Another().method();\n}\n"],"names":["root","Another","console","log","method"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAe,SAASA,IAAT,GAAgB;EAAA,MACvBC,OADuB;EAAA;EAAA;EAAA;EAAA;;EAAA;;EAAA,qCAEnB,YAAM;EACZ,eAAO,KAAP;EACD,OAJ0B;EAAA;;EAAA;EAAA;EAAA,+BAMlB;AACP,EAEAC,gBAAQC,GAAR,CAAY,YAAZ,EAA0BF,OAA1B,EAAmCD,IAAnC;EACD;EAV0B;;EAAA;EAAA;;EAa7B,MAAIC,OAAJ,GAAcG,MAAd;EACD;;;;;;;;"}
\ No newline at end of file
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/rollup/typescript-classes.js
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/rollup/typescript-classes.js
@@ -1,97 +1,97 @@
 var rollupTypescriptClasses = (function () {
     'use strict';
 
-    /*! *****************************************************************************
-    Copyright (c) Microsoft Corporation. All rights reserved.
-    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
-    this file except in compliance with the License. You may obtain a copy of the
-    License at http://www.apache.org/licenses/LICENSE-2.0
-
-    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
-    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
-    MERCHANTABLITY OR NON-INFRINGEMENT.
-
-    See the Apache Version 2.0 License for specific language governing permissions
-    and limitations under the License.
-    ***************************************************************************** */
-    /* global Reflect, Promise */
-
-    var extendStatics = function(d, b) {
-        extendStatics = Object.setPrototypeOf ||
-            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
-        return extendStatics(d, b);
-    };
-
-    function __extends(d, b) {
-        extendStatics(d, b);
-        function __() { this.constructor = d; }
-        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    /*! *****************************************************************************
+    Copyright (c) Microsoft Corporation. All rights reserved.
+    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+    this file except in compliance with the License. You may obtain a copy of the
+    License at http://www.apache.org/licenses/LICENSE-2.0
+
+    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+    MERCHANTABLITY OR NON-INFRINGEMENT.
+
+    See the Apache Version 2.0 License for specific language governing permissions
+    and limitations under the License.
+    ***************************************************************************** */
+    /* global Reflect, Promise */
+
+    var extendStatics = function(d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+
+    function __extends(d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    }
+
+    function __decorate(decorators, target, key, desc) {
+        var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+        if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+        else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+        return c > 3 && r && Object.defineProperty(target, key, r), r;
     }
 
-    function __decorate(decorators, target, key, desc) {
-        var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
-        if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
-        else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
-        return c > 3 && r && Object.defineProperty(target, key, r), r;
-    }
-
-    function decoratorFactory(opts) {
-        return function decorator(target) {
-            return target;
-        };
+    function decoratorFactory(opts) {
+        return function decorator(target) {
+            return target;
+        };
     }
 
-    // This file essentially reproduces an example Angular component to map testing,
-    var AppComponent = /** @class */ (function () {
-        function AppComponent() {
-            this.title = 'app';
-        }
-        AppComponent = __decorate([
-            decoratorFactory({
-                selector: 'app-root'
-            })
-        ], AppComponent);
-        return AppComponent;
-    }());
-    var fn = function (arg) {
-        console.log("here");
-    };
-    fn("arg");
-    var AnotherThing = /** @class */ (function () {
-        function AnotherThing() {
-            this.prop = 4;
-        }
-        return AnotherThing;
-    }());
-    var SubDecl = /** @class */ (function (_super) {
-        __extends(SubDecl, _super);
-        function SubDecl() {
-            var _this = _super !== null && _super.apply(this, arguments) || this;
-            _this.prop = 4;
-            return _this;
-        }
-        return SubDecl;
-    }(AnotherThing));
-    var SubVar = /** @class */ (function (_super) {
-        __extends(SubExpr, _super);
-        function SubExpr() {
-            var _this = _super !== null && _super.apply(this, arguments) || this;
-            _this.prop = 4;
-            return _this;
-        }
-        return SubExpr;
-    }(AnotherThing));
-    function test () {
-        // This file is specifically for testing the mappings of classes and things
-        // above, which means we don't want to include _other_ references to then.
-        // To avoid having them be optimized out, we include a no-op eval.
-        eval("");
-        console.log("pause here");
+    // This file essentially reproduces an example Angular component to map testing,
+    var AppComponent = /** @class */ (function () {
+        function AppComponent() {
+            this.title = 'app';
+        }
+        AppComponent = __decorate([
+            decoratorFactory({
+                selector: 'app-root'
+            })
+        ], AppComponent);
+        return AppComponent;
+    }());
+    var fn = function (arg) {
+        console.log("here");
+    };
+    fn("arg");
+    var AnotherThing = /** @class */ (function () {
+        function AnotherThing() {
+            this.prop = 4;
+        }
+        return AnotherThing;
+    }());
+    var SubDecl = /** @class */ (function (_super) {
+        __extends(SubDecl, _super);
+        function SubDecl() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.prop = 4;
+            return _this;
+        }
+        return SubDecl;
+    }(AnotherThing));
+    var SubVar = /** @class */ (function (_super) {
+        __extends(SubExpr, _super);
+        function SubExpr() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.prop = 4;
+            return _this;
+        }
+        return SubExpr;
+    }(AnotherThing));
+    function test () {
+        // This file is specifically for testing the mappings of classes and things
+        // above, which means we don't want to include _other_ references to then.
+        // To avoid having them be optimized out, we include a no-op eval.
+        eval("");
+        console.log("pause here");
     }
 
     return test;
 
 }());
 //# sourceMappingURL=typescript-classes.js.map
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/webpack3-babel6/babel-classes.js
@@ -0,0 +1,107 @@
+var webpack3Babel6BabelClasses =
+/******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId]) {
+/******/ 			return installedModules[moduleId].exports;
+/******/ 		}
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			i: moduleId,
+/******/ 			l: false,
+/******/ 			exports: {}
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.l = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+/******/
+/******/ 	// define getter function for harmony exports
+/******/ 	__webpack_require__.d = function(exports, name, getter) {
+/******/ 		if(!__webpack_require__.o(exports, name)) {
+/******/ 			Object.defineProperty(exports, name, {
+/******/ 				configurable: false,
+/******/ 				enumerable: true,
+/******/ 				get: getter
+/******/ 			});
+/******/ 		}
+/******/ 	};
+/******/
+/******/ 	// getDefaultExport function for compatibility with non-harmony modules
+/******/ 	__webpack_require__.n = function(module) {
+/******/ 		var getter = module && module.__esModule ?
+/******/ 			function getDefault() { return module['default']; } :
+/******/ 			function getModuleExports() { return module; };
+/******/ 		__webpack_require__.d(getter, 'a', getter);
+/******/ 		return getter;
+/******/ 	};
+/******/
+/******/ 	// Object.prototype.hasOwnProperty.call
+/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(__webpack_require__.s = 0);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
+/* harmony export (immutable) */ __webpack_exports__["default"] = root;
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function root() {
+  var Another = function () {
+    function Another() {
+      var _this = this;
+
+      _classCallCheck(this, Another);
+
+      this.bound = function () {
+        return _this;
+      };
+    }
+
+    _createClass(Another, [{
+      key: "method",
+      value: function method() {
+        var two = 2;
+
+        console.log("pause here", Another, root);
+      }
+    }]);
+
+    return Another;
+  }();
+
+  new Another().method();
+}
+
+/***/ })
+/******/ ])["default"];
+//# sourceMappingURL=babel-classes.js.map
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/webpack3-babel6/babel-classes.js.map
@@ -0,0 +1,1 @@
+{"version":3,"sources":["webpack3-babel6://./babel-classes/webpack/bootstrap 5a57728ea4dd6e4f4f6a","webpack3-babel6://./babel-classes/./input.js"],"names":["root","Another","bound","two","console","log","method"],"mappings":";;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;;;;;;;;AC7De,SAASA,IAAT,GAAgB;AAAA,MACvBC,OADuB;AAAA;AAAA;;AAAA;;AAAA,WAE3BC,KAF2B,GAEnB,YAAM;AACZ,eAAO,KAAP;AACD,OAJ0B;AAAA;;AAAA;AAAA;AAAA,+BAMlB;AACP,YAAIC,MAAM,CAAV;;AAEAC,gBAAQC,GAAR,CAAY,YAAZ,EAA0BJ,OAA1B,EAAmCD,IAAnC;AACD;AAV0B;;AAAA;AAAA;;AAa7B,MAAIC,OAAJ,GAAcK,MAAd;AACD,C","file":"babel-classes.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 5a57728ea4dd6e4f4f6a","export default function root() {\n  class Another {\n    bound = () => {\n      return this;\n    }\n\n    method() {\n      let two = 2;\n\n      console.log(\"pause here\", Another, root);\n    }\n  }\n\n  new Another().method();\n}\n\n\n\n// WEBPACK FOOTER //\n// ./input.js"],"sourceRoot":""}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/webpack3-babel7/babel-classes.js
@@ -0,0 +1,112 @@
+var webpack3Babel7BabelClasses =
+/******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId]) {
+/******/ 			return installedModules[moduleId].exports;
+/******/ 		}
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			i: moduleId,
+/******/ 			l: false,
+/******/ 			exports: {}
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.l = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+/******/
+/******/ 	// define getter function for harmony exports
+/******/ 	__webpack_require__.d = function(exports, name, getter) {
+/******/ 		if(!__webpack_require__.o(exports, name)) {
+/******/ 			Object.defineProperty(exports, name, {
+/******/ 				configurable: false,
+/******/ 				enumerable: true,
+/******/ 				get: getter
+/******/ 			});
+/******/ 		}
+/******/ 	};
+/******/
+/******/ 	// getDefaultExport function for compatibility with non-harmony modules
+/******/ 	__webpack_require__.n = function(module) {
+/******/ 		var getter = module && module.__esModule ?
+/******/ 			function getDefault() { return module['default']; } :
+/******/ 			function getModuleExports() { return module; };
+/******/ 		__webpack_require__.d(getter, 'a', getter);
+/******/ 		return getter;
+/******/ 	};
+/******/
+/******/ 	// Object.prototype.hasOwnProperty.call
+/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(__webpack_require__.s = 0);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
+/* harmony export (immutable) */ __webpack_exports__["default"] = root;
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+
+function root() {
+  var Another =
+  /*#__PURE__*/
+  function () {
+    function Another() {
+      var _this = this;
+
+      _classCallCheck(this, Another);
+
+      _defineProperty(this, "bound", function () {
+        return _this;
+      });
+    }
+
+    _createClass(Another, [{
+      key: "method",
+      value: function method() {
+        var two = 2;
+        console.log("pause here", Another, root);
+      }
+    }]);
+
+    return Another;
+  }();
+
+  new Another().method();
+}
+
+/***/ })
+/******/ ])["default"];
+//# sourceMappingURL=babel-classes.js.map
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/webpack3-babel7/babel-classes.js.map
@@ -0,0 +1,1 @@
+{"version":3,"sources":["webpack3-babel7://./babel-classes/webpack/bootstrap 21c3483666431a1bbc91","webpack3-babel7://./babel-classes/./input.js"],"names":["root","Another","two","console","log","method"],"mappings":";;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;AC7De,SAASA,IAAT,GAAgB;AAAA,MACvBC,OADuB;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA,qCAEnB,YAAM;AACZ,eAAO,KAAP;AACD,OAJ0B;AAAA;;AAAA;AAAA;AAAA,+BAMlB;AACP,YAAIC,MAAM,CAAV;AAEAC,gBAAQC,GAAR,CAAY,YAAZ,EAA0BH,OAA1B,EAAmCD,IAAnC;AACD;AAV0B;;AAAA;AAAA;;AAa7B,MAAIC,OAAJ,GAAcI,MAAd;AACD,C","file":"babel-classes.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 21c3483666431a1bbc91","export default function root() {\n  class Another {\n    bound = () => {\n      return this;\n    }\n\n    method() {\n      let two = 2;\n\n      console.log(\"pause here\", Another, root);\n    }\n  }\n\n  new Another().method();\n}\n\n\n\n// WEBPACK FOOTER //\n// ./input.js"],"sourceRoot":""}
\ No newline at end of file
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/webpack3/typescript-classes.js.map
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/webpack3/typescript-classes.js.map
@@ -1,1 +1,1 @@
-{"version":3,"sources":["webpack3://./typescript-classes/webpack/bootstrap 56fd7aa89ed0d74421bc","webpack3://./typescript-classes/./src/mod.ts","webpack3://./typescript-classes/./input.ts"],"names":[],"mappings":";;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;;;;AC5DA,0BAAiC,IAA0B;IACzD,OAAO,mBAAmB,MAAM;QAC9B,OAAY,MAAM,CAAC;IACrB,CAAC,CAAC;AACJ,CAAC;AAJD,4CAIC;AAED,iBAA+B,CAAC;AAAhC,yBAAgC;;;;;;;;;ACPhC,gFAAgF;AAChF,qCAAqC;;;;;;;;;;;;;;;;;;AAErC,sCAAqD;AAErD,gCAAmC;AAKnC;IAHA;QAIE,UAAK,GAAG,KAAK,CAAC;IAChB,CAAC;IAFY,YAAY;QAHxB,yBAAgB,CAAC;YAChB,QAAQ,EAAE,UAAU;SACrB,CAAC;OACW,YAAY,CAExB;IAAD,mBAAC;CAAA;AAFY,oCAAY;AAIzB,IAAM,EAAE,GAAG,aAAG;IACZ,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC,CAAC;AACF,EAAE,CAAC,KAAK,CAAC,CAAC;AAEV,mEAAmE;AACnE,8DAA8D;AAC9D;IAAA;QACE,UAAK,GAAG,KAAK,CAAC;IAChB,CAAC;IAAD,oBAAC;AAAD,CAAC;AAFY,sCAAa;AAI1B;IAAA;QACE,SAAI,GAAG,CAAC,CAAC;IACX,CAAC;IAAD,mBAAC;AAAD,CAAC;AAED,IAAM,eAAe;IAAG;QACtB,SAAI,GAAG,CAAC,CAAC;IACX,CAAC;IAAD,UAAC;AAAD,CAAC,IAAC;AAEF;IAAsB,2BAAY;IAAlC;QAAA,qEAEC;QADC,UAAI,GAAG,CAAC,CAAC;;IACX,CAAC;IAAD,cAAC;AAAD,CAAC,CAFqB,YAAY,GAEjC;AAED,IAAI,MAAM;IAAyB,2BAAY;IAAlC;QAAA,qEAEZ;QADC,UAAI,GAAG,CAAC,CAAC;;IACX,CAAC;IAAD,cAAC;AAAD,CAAC,CAFkC,YAAY,EAE9C,CAAC;AAEF,EAAE,CAAC;AAEH;IACE,2EAA2E;IAC3E,0EAA0E;IAC1E,kEAAkE;IAClE,IAAI,CAAC,EAAE,CAAC,CAAC;IAET,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AAC5B,CAAC;AAPD,+BAOC","file":"typescript-classes.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 1);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 56fd7aa89ed0d74421bc","\nexport function decoratorFactory(opts: { selector: string }) {\n  return function decorator(target) {\n    return <any>target;\n  };\n}\n\nexport default function def() {}\n\n\n\n// WEBPACK FOOTER //\n// ./src/mod.ts","// This file essentially reproduces an example Angular component to map testing,\n// among other typescript edge cases.\n\nimport def, { decoratorFactory } from './src/mod.ts';\n\nimport * as ns from './src/mod.ts';\n\n@decoratorFactory({\n  selector: 'app-root',\n})\nexport class AppComponent {\n  title = 'app';\n}\n\nconst fn = arg => {\n  console.log(\"here\");\n};\nfn(\"arg\");\n\n// Un-decorated exported classes present a mapping challege because\n// the class name is mapped to an unhelpful export assignment.\nexport class ExportedOther {\n  title = 'app';\n}\n\nclass AnotherThing {\n  prop = 4;\n}\n\nconst ExpressionClass = class Foo {\n  prop = 4;\n};\n\nclass SubDecl extends AnotherThing {\n  prop = 4;\n}\n\nlet SubVar = class SubExpr extends AnotherThing {\n  prop = 4;\n};\n\nns;\n\nexport default function(){\n  // This file is specifically for testing the mappings of classes and things\n  // above, which means we don't want to include _other_ references to then.\n  // To avoid having them be optimized out, we include a no-op eval.\n  eval(\"\");\n\n  console.log(\"pause here\");\n}\n\n\n\n// WEBPACK FOOTER //\n// ./input.ts"],"sourceRoot":""}
\ No newline at end of file
+{"version":3,"sources":["webpack3://./typescript-classes/webpack/bootstrap 72affb70e005e17a24e0","webpack3://./typescript-classes/./src/mod.ts","webpack3://./typescript-classes/./input.ts"],"names":[],"mappings":";;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;;;;AC5DA,0BAAiC,IAA0B;IACzD,OAAO,mBAAmB,MAAM;QAC9B,OAAY,MAAM,CAAC;IACrB,CAAC,CAAC;AACJ,CAAC;AAJD,4CAIC;AAED,iBAA+B,CAAC;AAAhC,yBAAgC;;;;;;;;;ACPhC,gFAAgF;AAChF,qCAAqC;;;;;;;;;;;;;;;;;;AAErC,sCAAqD;AAErD,gCAAmC;AAKnC;IAHA;QAIE,UAAK,GAAG,KAAK,CAAC;IAChB,CAAC;IAFY,YAAY;QAHxB,yBAAgB,CAAC;YAChB,QAAQ,EAAE,UAAU;SACrB,CAAC;OACW,YAAY,CAExB;IAAD,mBAAC;CAAA;AAFY,oCAAY;AAIzB,IAAM,EAAE,GAAG,aAAG;IACZ,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC,CAAC;AACF,EAAE,CAAC,KAAK,CAAC,CAAC;AAEV,mEAAmE;AACnE,8DAA8D;AAC9D;IAAA;QACE,UAAK,GAAG,KAAK,CAAC;IAChB,CAAC;IAAD,oBAAC;AAAD,CAAC;AAFY,sCAAa;AAI1B;IAAA;QACE,SAAI,GAAG,CAAC,CAAC;IACX,CAAC;IAAD,mBAAC;AAAD,CAAC;AAED,IAAM,eAAe;IAAG;QACtB,SAAI,GAAG,CAAC,CAAC;IACX,CAAC;IAAD,UAAC;AAAD,CAAC,IAAC;AAEF;IAAsB,2BAAY;IAAlC;QAAA,qEAEC;QADC,UAAI,GAAG,CAAC,CAAC;;IACX,CAAC;IAAD,cAAC;AAAD,CAAC,CAFqB,YAAY,GAEjC;AAED,IAAI,MAAM;IAAyB,2BAAY;IAAlC;QAAA,qEAEZ;QADC,UAAI,GAAG,CAAC,CAAC;;IACX,CAAC;IAAD,cAAC;AAAD,CAAC,CAFkC,YAAY,EAE9C,CAAC;AAEF,EAAE,CAAC;AAEH;IACE,2EAA2E;IAC3E,0EAA0E;IAC1E,kEAAkE;IAClE,IAAI,CAAC,EAAE,CAAC,CAAC;IAET,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AAC5B,CAAC;AAPD,+BAOC","file":"typescript-classes.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 1);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 72affb70e005e17a24e0","\nexport function decoratorFactory(opts: { selector: string }) {\n  return function decorator(target) {\n    return <any>target;\n  };\n}\n\nexport default function def() {}\n\n\n\n// WEBPACK FOOTER //\n// ./src/mod.ts","// This file essentially reproduces an example Angular component to map testing,\n// among other typescript edge cases.\n\nimport def, { decoratorFactory } from './src/mod.ts';\n\nimport * as ns from './src/mod.ts';\n\n@decoratorFactory({\n  selector: 'app-root',\n})\nexport class AppComponent {\n  title = 'app';\n}\n\nconst fn = arg => {\n  console.log(\"here\");\n};\nfn(\"arg\");\n\n// Un-decorated exported classes present a mapping challege because\n// the class name is mapped to an unhelpful export assignment.\nexport class ExportedOther {\n  title = 'app';\n}\n\nclass AnotherThing {\n  prop = 4;\n}\n\nconst ExpressionClass = class Foo {\n  prop = 4;\n};\n\nclass SubDecl extends AnotherThing {\n  prop = 4;\n}\n\nlet SubVar = class SubExpr extends AnotherThing {\n  prop = 4;\n};\n\nns;\n\nexport default function(){\n  // This file is specifically for testing the mappings of classes and things\n  // above, which means we don't want to include _other_ references to then.\n  // To avoid having them be optimized out, we include a no-op eval.\n  eval(\"\");\n\n  console.log(\"pause here\");\n}\n\n\n\n// WEBPACK FOOTER //\n// ./input.ts"],"sourceRoot":""}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/webpack4-babel6/babel-classes.js
@@ -0,0 +1,134 @@
+var webpack4Babel6BabelClasses =
+/******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId]) {
+/******/ 			return installedModules[moduleId].exports;
+/******/ 		}
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			i: moduleId,
+/******/ 			l: false,
+/******/ 			exports: {}
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.l = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+/******/
+/******/ 	// define getter function for harmony exports
+/******/ 	__webpack_require__.d = function(exports, name, getter) {
+/******/ 		if(!__webpack_require__.o(exports, name)) {
+/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
+/******/ 		}
+/******/ 	};
+/******/
+/******/ 	// define __esModule on exports
+/******/ 	__webpack_require__.r = function(exports) {
+/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
+/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+/******/ 		}
+/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
+/******/ 	};
+/******/
+/******/ 	// create a fake namespace object
+/******/ 	// mode & 1: value is a module id, require it
+/******/ 	// mode & 2: merge all properties of value into the ns
+/******/ 	// mode & 4: return value when already ns object
+/******/ 	// mode & 8|1: behave like require
+/******/ 	__webpack_require__.t = function(value, mode) {
+/******/ 		if(mode & 1) value = __webpack_require__(value);
+/******/ 		if(mode & 8) return value;
+/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
+/******/ 		var ns = Object.create(null);
+/******/ 		__webpack_require__.r(ns);
+/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
+/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
+/******/ 		return ns;
+/******/ 	};
+/******/
+/******/ 	// getDefaultExport function for compatibility with non-harmony modules
+/******/ 	__webpack_require__.n = function(module) {
+/******/ 		var getter = module && module.__esModule ?
+/******/ 			function getDefault() { return module['default']; } :
+/******/ 			function getModuleExports() { return module; };
+/******/ 		__webpack_require__.d(getter, 'a', getter);
+/******/ 		return getter;
+/******/ 	};
+/******/
+/******/ 	// Object.prototype.hasOwnProperty.call
+/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+/******/
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(__webpack_require__.s = "./input.js");
+/******/ })
+/************************************************************************/
+/******/ ({
+
+/***/ "./input.js":
+/*!******************!*\
+  !*** ./input.js ***!
+  \******************/
+/*! exports provided: default */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return root; });
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function root() {
+  var Another = function () {
+    function Another() {
+      var _this = this;
+
+      _classCallCheck(this, Another);
+
+      this.bound = function () {
+        return _this;
+      };
+    }
+
+    _createClass(Another, [{
+      key: "method",
+      value: function method() {
+        var two = 2;
+
+        console.log("pause here", Another, root);
+      }
+    }]);
+
+    return Another;
+  }();
+
+  new Another().method();
+}
+
+/***/ })
+
+/******/ })["default"];
+//# sourceMappingURL=babel-classes.js.map
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/webpack4-babel6/babel-classes.js.map
@@ -0,0 +1,1 @@
+{"version":3,"sources":["webpack4-babel6://./babel-classes/webpack/bootstrap","webpack4-babel6://./babel-classes/./input.js"],"names":["root","Another","bound","two","console","log","method"],"mappings":";;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kDAA0C,gCAAgC;AAC1E;AACA;;AAEA;AACA;AACA;AACA,gEAAwD,kBAAkB;AAC1E;AACA,yDAAiD,cAAc;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAyC,iCAAiC;AAC1E,wHAAgH,mBAAmB,EAAE;AACrI;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;;AAGA;AACA;;;;;;;;;;;;;;;;;;;AClFe,SAASA,IAAT,GAAgB;AAAA,MACvBC,OADuB;AAAA;AAAA;;AAAA;;AAAA,WAE3BC,KAF2B,GAEnB,YAAM;AACZ,eAAO,KAAP;AACD,OAJ0B;AAAA;;AAAA;AAAA;AAAA,+BAMlB;AACP,YAAIC,MAAM,CAAV;;AAEAC,gBAAQC,GAAR,CAAY,YAAZ,EAA0BJ,OAA1B,EAAmCD,IAAnC;AACD;AAV0B;;AAAA;AAAA;;AAa7B,MAAIC,OAAJ,GAAcK,MAAd;AACD,C","file":"babel-classes.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./input.js\");\n","export default function root() {\n  class Another {\n    bound = () => {\n      return this;\n    }\n\n    method() {\n      let two = 2;\n\n      console.log(\"pause here\", Another, root);\n    }\n  }\n\n  new Another().method();\n}\n"],"sourceRoot":""}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/webpack4-babel7/babel-classes.js
@@ -0,0 +1,139 @@
+var webpack4Babel7BabelClasses =
+/******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId]) {
+/******/ 			return installedModules[moduleId].exports;
+/******/ 		}
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			i: moduleId,
+/******/ 			l: false,
+/******/ 			exports: {}
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.l = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+/******/
+/******/ 	// define getter function for harmony exports
+/******/ 	__webpack_require__.d = function(exports, name, getter) {
+/******/ 		if(!__webpack_require__.o(exports, name)) {
+/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
+/******/ 		}
+/******/ 	};
+/******/
+/******/ 	// define __esModule on exports
+/******/ 	__webpack_require__.r = function(exports) {
+/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
+/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+/******/ 		}
+/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
+/******/ 	};
+/******/
+/******/ 	// create a fake namespace object
+/******/ 	// mode & 1: value is a module id, require it
+/******/ 	// mode & 2: merge all properties of value into the ns
+/******/ 	// mode & 4: return value when already ns object
+/******/ 	// mode & 8|1: behave like require
+/******/ 	__webpack_require__.t = function(value, mode) {
+/******/ 		if(mode & 1) value = __webpack_require__(value);
+/******/ 		if(mode & 8) return value;
+/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
+/******/ 		var ns = Object.create(null);
+/******/ 		__webpack_require__.r(ns);
+/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
+/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
+/******/ 		return ns;
+/******/ 	};
+/******/
+/******/ 	// getDefaultExport function for compatibility with non-harmony modules
+/******/ 	__webpack_require__.n = function(module) {
+/******/ 		var getter = module && module.__esModule ?
+/******/ 			function getDefault() { return module['default']; } :
+/******/ 			function getModuleExports() { return module; };
+/******/ 		__webpack_require__.d(getter, 'a', getter);
+/******/ 		return getter;
+/******/ 	};
+/******/
+/******/ 	// Object.prototype.hasOwnProperty.call
+/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+/******/
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(__webpack_require__.s = "./input.js");
+/******/ })
+/************************************************************************/
+/******/ ({
+
+/***/ "./input.js":
+/*!******************!*\
+  !*** ./input.js ***!
+  \******************/
+/*! exports provided: default */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return root; });
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+
+function root() {
+  var Another =
+  /*#__PURE__*/
+  function () {
+    function Another() {
+      var _this = this;
+
+      _classCallCheck(this, Another);
+
+      _defineProperty(this, "bound", function () {
+        return _this;
+      });
+    }
+
+    _createClass(Another, [{
+      key: "method",
+      value: function method() {
+        var two = 2;
+        console.log("pause here", Another, root);
+      }
+    }]);
+
+    return Another;
+  }();
+
+  new Another().method();
+}
+
+/***/ })
+
+/******/ })["default"];
+//# sourceMappingURL=babel-classes.js.map
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/output/webpack4-babel7/babel-classes.js.map
@@ -0,0 +1,1 @@
+{"version":3,"sources":["webpack4-babel7://./babel-classes/webpack/bootstrap","webpack4-babel7://./babel-classes/./input.js"],"names":["root","Another","two","console","log","method"],"mappings":";;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kDAA0C,gCAAgC;AAC1E;AACA;;AAEA;AACA;AACA;AACA,gEAAwD,kBAAkB;AAC1E;AACA,yDAAiD,cAAc;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAyC,iCAAiC;AAC1E,wHAAgH,mBAAmB,EAAE;AACrI;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;;AAGA;AACA;;;;;;;;;;;;;;;;;;;;;;;AClFe,SAASA,IAAT,GAAgB;AAAA,MACvBC,OADuB;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA,qCAEnB,YAAM;AACZ,eAAO,KAAP;AACD,OAJ0B;AAAA;;AAAA;AAAA;AAAA,+BAMlB;AACP,YAAIC,MAAM,CAAV;AAEAC,gBAAQC,GAAR,CAAY,YAAZ,EAA0BH,OAA1B,EAAmCD,IAAnC;AACD;AAV0B;;AAAA;AAAA;;AAa7B,MAAIC,OAAJ,GAAcI,MAAd;AACD,C","file":"babel-classes.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./input.js\");\n","export default function root() {\n  class Another {\n    bound = () => {\n      return this;\n    }\n\n    method() {\n      let two = 2;\n\n      console.log(\"pause here\", Another, root);\n    }\n  }\n\n  new Another().method();\n}\n"],"sourceRoot":""}
\ No newline at end of file
--- a/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/polyfill-bundle.js
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemapped/polyfill-bundle.js
@@ -2749,37 +2749,37 @@ hide($DataView[PROTOTYPE], $typed.VIEW, 
 exports[ARRAY_BUFFER] = $ArrayBuffer;
 exports[DATA_VIEW] = $DataView;
 
 
 /***/ }),
 /* 90 */
 /***/ (function(module, exports) {
 
-var g;
-
-// This works in non-strict mode
-g = (function() {
-	return this;
-})();
-
-try {
-	// This works if eval is allowed (see CSP)
-	g = g || Function("return this")() || (1,eval)("this");
-} catch(e) {
-	// This works if the window reference is available
-	if(typeof window === "object")
-		g = window;
-}
-
-// g can still be undefined, but nothing to do about it...
-// We return undefined, instead of nothing here, so it's
-// easier to handle this case. if(!global) { ...}
-
-module.exports = g;
+var g;
+
+// This works in non-strict mode
+g = (function() {
+	return this;
+})();
+
+try {
+	// This works if eval is allowed (see CSP)
+	g = g || Function("return this")() || (1,eval)("this");
+} catch(e) {
+	// This works if the window reference is available
+	if(typeof window === "object")
+		g = window;
+}
+
+// g can still be undefined, but nothing to do about it...
+// We return undefined, instead of nothing here, so it's
+// easier to handle this case. if(!global) { ...}
+
+module.exports = g;
 
 
 /***/ }),
 /* 91 */
 /***/ (function(module, exports, __webpack_require__) {
 
 module.exports = !__webpack_require__(6) && !__webpack_require__(3)(function () {
   return Object.defineProperty(__webpack_require__(64)('div'), 'a', { get: function () { return 7; } }).a != 7;
--- a/devtools/client/debugger/new/test/mochitest/helpers.js
+++ b/devtools/client/debugger/new/test/mochitest/helpers.js
@@ -368,20 +368,21 @@ function assertHighlightLocation(dbg, so
 
   is(
     findAllElements(dbg, "highlightLine").length,
     1,
     "Only 1 line is highlighted"
   );
 
   ok(isVisibleInEditor(dbg, lineEl), "Highlighted line is visible");
+
+  const cm = getCM(dbg);
+  const lineInfo = cm.lineInfo(line - 1);
   ok(
-    getCM(dbg)
-      .lineInfo(line - 1)
-      .wrapClass.includes("highlight-line"),
+    lineInfo.wrapClass.includes("highlight-line"),
     "Line is highlighted"
   );
 }
 
 /**
  * Returns boolean for whether the debugger is paused.
  *
  * @memberof mochitest/asserts
@@ -604,19 +605,19 @@ async function selectSource(dbg, url, li
 
 async function selectSpecificSource(dbg, url, line) {
   const source = findSource(dbg, url);
   await dbg.actions.selectLocation({ sourceId: source.id, line }, {keepContext: false});
   return waitForSelectedSource(dbg, url);
 }
 
 
-function closeTab(dbg, url) {
+async function closeTab(dbg, url) {
   const source = findSource(dbg, url);
-  return dbg.actions.closeTab(source.url);
+  await dbg.actions.closeTab(source.url);
 }
 
 /**
  * Steps over.
  *
  * @memberof mochitest/actions
  * @param {Object} dbg
  * @return {Promise}
--- a/devtools/client/definitions.js
+++ b/devtools/client/definitions.js
@@ -460,16 +460,25 @@ Tools.accessibility = {
 
   build(iframeWindow, toolbox) {
     const startup = toolbox.getToolStartup("accessibility");
     return new AccessibilityPanel(iframeWindow, toolbox, startup);
   },
 
   buildToolStartup(toolbox) {
     return new AccessibilityStartup(toolbox);
+  },
+
+  // @remove after release 63 (See Bug 1482461)
+  get badge() {
+    if (Services.prefs.getIntPref("devtools.promote.accessibility") > 0) {
+      return l10n("toolbox.tab.newBadge");
+    }
+
+    return null;
   }
 };
 
 Tools.application = {
   id: "application",
   ordinal: 15,
   visibilityswitch: "devtools.application.enabled",
   icon: "chrome://devtools/skin/images/tool-application.svg",
--- a/devtools/client/framework/components/ToolboxTab.js
+++ b/devtools/client/framework/components/ToolboxTab.js
@@ -36,17 +36,17 @@ class ToolboxTab extends Component {
         src: icon
       }),
     ];
   }
 
   render() {
     const {panelDefinition, currentToolId, highlightedTools, selectTool,
            focusedButton, focusButton} = this.props;
-    const {id, extensionId, tooltip, label, iconOnly} = panelDefinition;
+    const {id, extensionId, tooltip, label, iconOnly, badge} = panelDefinition;
     const isHighlighted = id === currentToolId;
 
     const className = [
       "devtools-tab",
       currentToolId === id ? "selected" : "",
       highlightedTools.has(id) ? "highlighted" : "",
       iconOnly ? "devtools-tab-icon-only" : ""
     ].join(" ");
@@ -76,15 +76,23 @@ class ToolboxTab extends Component {
       ),
       ...this.renderIcon(panelDefinition, isHighlighted),
       iconOnly ?
         null :
         span(
           {
             className: "devtools-tab-label"
           },
-          label
+          label,
+          badge && !isHighlighted ?
+            span(
+              {
+                className: "devtools-tab-badge"
+              },
+              badge
+            ) :
+            null
         )
     );
   }
 }
 
 module.exports = ToolboxTab;
--- a/devtools/client/locales/en-US/accessibility.properties
+++ b/devtools/client/locales/en-US/accessibility.properties
@@ -72,17 +72,32 @@ accessibility.disable.enabledTitle=Acces
 # be enabled.
 accessibility.enable.disabledTitle=Accessibility service can not be turned on. It is turned off via accessibility services privacy preference.
 
 # LOCALIZATION NOTE (accessibility.enable.enabledTitle): A title text used for
 # a tooltip for Enabled accessibility button when accessibility service can be
 # enabled.
 accessibility.enable.enabledTitle=Accessibility service will be turned on for all tabs and windows.
 
+# LOCALIZATION NOTE (accessibility.learnMore): A text that is used as is or as textual
+# description in places that link to accessibility inspector documentation.
+accessibility.learnMore=Learn more
+
 # LOCALIZATION NOTE (accessibility.description.general): A title text used when
 # accessibility service description is provided before accessibility inspector
 # is enabled.
 accessibility.description.general=Accessibility features are deactivated by default because they negatively impact performance. Consider turning off accessibility features before using other Developer Tools panels.
 
+# LOCALIZATION NOTE (accessibility.description.general.p1): A title text for the first
+# paragraph, used when accessibility service description is provided before accessibility
+# inspector is enabled. %S in the content will be replaced by a link at run time
+# with the accessibility.learnMore string.
+accessibility.description.general.p1=Accessibility Inspector lets you examine the current page’s accessibility tree, which is used by screen readers and other assistive technologies. %S
+
+# LOCALIZATION NOTE (accessibility.description.general.p2): A title text for the second
+# paragraph, used when accessibility service description is provided before accessibility
+# inspector is enabled.
+accessibility.description.general.p2=Accessibility features may affect the performance of other developer tools panels and should be turned off when not in use.
+
 # LOCALIZATION NOTE (accessibility.description.oldVersion): A title text used
 # when accessibility service description is provided when a client is connected
 # to an older version of accessibility actor.
 accessibility.description.oldVersion=You are connected to a debugger server that is too old. To use Accessibility panel, please connect to the latest debugger server version.
--- a/devtools/client/locales/en-US/startup.properties
+++ b/devtools/client/locales/en-US/startup.properties
@@ -307,8 +307,13 @@ toolbox.buttons.screenshot = Take a scre
 # This is the tooltip of the button in the toolbox toolbar that toggles the
 # rulers in the page
 toolbox.buttons.rulers = Toggle rulers for the page
 
 # LOCALIZATION NOTE (toolbox.buttons.measure):
 # This is the tooltip of the button in the toolbox toolbar that toggles the
 # measuring tools
 toolbox.buttons.measure = Measure a portion of the page
+
+# LOCALIZATION NOTE (toolbox.tab.newBadge):
+# This is the text of a promotion badge showed in the toobox tab bar, next to a tab panel
+# name. Used to promote new/recent panels such as the accessibility panel.
+toolbox.tab.newBadge=New
--- a/devtools/client/netmonitor/src/components/MonitorPanel.js
+++ b/devtools/client/netmonitor/src/components/MonitorPanel.js
@@ -144,17 +144,17 @@ class MonitorPanel extends Component {
           singleRow: this.state.isSingleRow,
         }),
         SplitBox({
           className: "devtools-responsive-container",
           initialWidth: initialWidth,
           initialHeight: initialHeight,
           minSize: "50px",
           maxSize: "80%",
-          splitterSize: 1,
+          splitterSize: networkDetailsOpen ? 1 : 0,
           startPanel: RequestList({ isEmpty, connector }),
           endPanel: networkDetailsOpen && NetworkDetailsPanel({
             ref: "endPanel",
             connector,
             openLink,
             sourceMapService,
           }),
           endPanelCollapsed: !networkDetailsOpen,
--- a/devtools/client/preferences/devtools-client.js
+++ b/devtools/client/preferences/devtools-client.js
@@ -224,16 +224,19 @@ pref("devtools.webaudioeditor.enabled", 
 // Enable Scratchpad
 pref("devtools.scratchpad.enabled", false);
 
 // Make sure the DOM panel is hidden by default
 pref("devtools.dom.enabled", false);
 
 // Make sure the Accessibility panel is hidden by default
 pref("devtools.accessibility.enabled", false);
+// Counter to promote the Accessibility panel.
+// @remove after release 63 (See Bug 1482461)
+pref("devtools.promote.accessibility", 1);
 
 // Web Audio Editor Inspector Width should be a preference
 pref("devtools.webaudioeditor.inspectorWidth", 300);
 
 // Web console filters
 pref("devtools.webconsole.filter.error", true);
 pref("devtools.webconsole.filter.warn", true);
 pref("devtools.webconsole.filter.info", true);
--- a/devtools/client/shared/components/reps/reps.css
+++ b/devtools/client/shared/components/reps/reps.css
@@ -1,14 +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/. */
 
-.tree {
-  overflow: auto;
+ /* We can remove the outline since we do add our own focus style on nodes */
+.tree:focus {
+  outline: none;
 }
 
 .tree.inline {
   display: inline-block;
 }
 
 .tree.nowrap {
   white-space: nowrap;
--- a/devtools/client/shared/components/reps/reps.js
+++ b/devtools/client/shared/components/reps/reps.js
@@ -4460,25 +4460,17 @@ class Tree extends Component {
       tabIndex: "0",
       onKeyDown: this._onKeyDown,
       onKeyPress: this._preventArrowKeyScrolling,
       onKeyUp: this._preventArrowKeyScrolling,
       onFocus: ({ nativeEvent }) => {
         if (focused || !nativeEvent || !this.treeRef) {
           return;
         }
-
-        const { explicitOriginalTarget } = nativeEvent;
-
-        // Only set default focus to the first tree node if the focus came
-        // from outside the tree (e.g. by tabbing to the tree from other
-        // external elements).
-        if (explicitOriginalTarget !== this.treeRef && !this.treeRef.contains(explicitOriginalTarget)) {
-          this._focus(traversal[0].item);
-        }
+        this._focus(traversal[0].item);
       },
       onBlur: this._onBlur,
       "aria-label": this.props.label,
       "aria-labelledby": this.props.labelledby,
       "aria-activedescendant": focused && this.props.getKey(focused),
       style
     }, nodes);
   }
--- a/devtools/client/shared/components/splitter/SplitBox.css
+++ b/devtools/client/shared/components/splitter/SplitBox.css
@@ -1,88 +1,94 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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/. */
-
-.split-box {
-  display: flex;
-  flex: 1;
-  min-width: 0;
-  height: 100%;
-  width: 100%;
-}
-
-.split-box.vert {
-  flex-direction: row;
-}
-
-.split-box.horz {
-  flex-direction: column;
-}
-
-.split-box > .uncontrolled {
-  display: flex;
-  flex: 1;
-  min-width: 0;
-  overflow: auto;
-}
-
-.split-box > .controlled {
-  display: flex;
-  overflow: auto;
-}
-
-.split-box > .splitter {
-  background-image: none;
-  border: 0;
-  border-style: solid;
-  border-color: transparent;
-  background-color: var(--theme-splitter-color);
-  background-clip: content-box;
-  position: relative;
-
-  box-sizing: border-box;
-
-  /* Positive z-index positions the splitter on top of its siblings and makes
-     it clickable on both sides. */
-  z-index: 1;
-}
-
-.split-box.vert > .splitter {
-  min-width: calc(var(--devtools-splitter-inline-start-width) +
-    var(--devtools-splitter-inline-end-width) + 1px);
-
-  border-inline-start-width: var(--devtools-splitter-inline-start-width);
-  border-inline-end-width: var(--devtools-splitter-inline-end-width);
-
-  margin-inline-start: calc(-1 * var(--devtools-splitter-inline-start-width) - 1px);
-  margin-inline-end: calc(-1 * var(--devtools-splitter-inline-end-width));
-
-  cursor: ew-resize;
-}
-
-.split-box.horz > .splitter {
-  min-height: calc(var(--devtools-splitter-top-width) +
-    var(--devtools-splitter-bottom-width) + 1px);
-
-  border-top-width: var(--devtools-splitter-top-width);
-  border-bottom-width: var(--devtools-splitter-bottom-width);
-
-  margin-top: calc(-1 * var(--devtools-splitter-top-width) - 1px);
-  margin-bottom: calc(-1 * var(--devtools-splitter-bottom-width));
-
-  cursor: ns-resize;
-}
-
-.split-box.disabled {
-  pointer-events: none;
-}
-
-/**
- * Make sure splitter panels are not processing any mouse
- * events. This is good for performance during splitter
- * bar dragging.
- */
-.split-box.dragging > .controlled,
-.split-box.dragging > .uncontrolled {
-  pointer-events: none;
-}
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* 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/. */
+
+.split-box {
+  display: flex;
+  flex: 1;
+  min-width: 0;
+  height: 100%;
+  width: 100%;
+}
+
+.split-box.vert {
+  flex-direction: row;
+}
+
+.split-box.horz {
+  flex-direction: column;
+}
+
+.split-box > .uncontrolled {
+  display: flex;
+  flex: 1;
+  min-width: 0;
+  overflow: auto;
+}
+
+.split-box > .controlled {
+  display: flex;
+  overflow: auto;
+}
+
+.split-box > .splitter {
+  background-image: none;
+  border: 0;
+  border-style: solid;
+  border-color: transparent;
+  background-color: var(--theme-splitter-color);
+  background-clip: content-box;
+  position: relative;
+
+  box-sizing: border-box;
+
+  /* Positive z-index positions the splitter on top of its siblings and makes
+     it clickable on both sides. */
+  z-index: 1;
+}
+
+.split-box.vert > .splitter {
+  min-width: var(--devtools-vertical-splitter-min-width);
+
+  border-inline-start-width: var(--devtools-splitter-inline-start-width);
+  border-inline-end-width: var(--devtools-splitter-inline-end-width);
+
+  margin-inline-start: calc(-1 * var(--devtools-splitter-inline-start-width) - 1px);
+  margin-inline-end: calc(-1 * var(--devtools-splitter-inline-end-width));
+
+  cursor: ew-resize;
+}
+
+.split-box.horz > .splitter {
+  /* Emphasize the horizontal splitter width and color */
+  min-height: var(--devtools-emphasized-horizontal-splitter-min-height);
+
+  background-color: var(--theme-emphasized-splitter-color);
+
+  border-top-width: var(--devtools-splitter-top-width);
+  border-bottom-width: var(--devtools-splitter-bottom-width);
+
+  margin-top: calc(-1 * var(--devtools-splitter-top-width) - 1px);
+  margin-bottom: calc(-1 * var(--devtools-splitter-bottom-width));
+
+  cursor: ns-resize;
+}
+
+/* Emphasized splitter has the hover style. */
+.split-box.horz > .splitter:hover {
+  background-color: var(--theme-emphasized-splitter-color-hover);
+}
+
+.split-box.disabled {
+  pointer-events: none;
+}
+
+/**
+ * Make sure splitter panels are not processing any mouse
+ * events. This is good for performance during splitter
+ * bar dragging.
+ */
+.split-box.dragging > .controlled,
+.split-box.dragging > .uncontrolled {
+  pointer-events: none;
+}
--- a/devtools/client/themes/splitters.css
+++ b/devtools/client/themes/splitters.css
@@ -3,26 +3,40 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* This file is loaded by both browser.xul and toolbox.xul. Therefore, rules
    defined here can not rely on toolbox.xul variables. */
 
 /* Splitters */
 
 :root {
+  /* Draggable splitter element size */
+  --devtools-splitter-element-size: 1px;
+  --devtools-emphasized-splitter-element-size: 2px;
+
   /* Define the widths of the draggable areas on each side of a splitter. top
      and bottom widths are used for horizontal splitters, inline-start and
      inline-end for side splitters.*/
 
   --devtools-splitter-top-width: 2px;
   --devtools-splitter-bottom-width: 2px;
+  --devtools-horizontal-splitter-min-height: calc(var(--devtools-splitter-top-width) +
+                                                  var(--devtools-splitter-bottom-width) +
+                                                  var(--devtools-splitter-element-size));
+  --devtools-emphasized-horizontal-splitter-min-height: calc(var(--devtools-splitter-top-width) +
+                                                             var(--devtools-splitter-bottom-width) +
+                                                             var(--devtools-emphasized-splitter-element-size));
 
   /* Small draggable area on inline-start to avoid overlaps on scrollbars.*/
   --devtools-splitter-inline-start-width: 1px;
   --devtools-splitter-inline-end-width: 4px;
+
+  --devtools-vertical-splitter-min-width: calc(var(--devtools-splitter-inline-start-width) +
+                                               var(--devtools-splitter-inline-end-width) +
+                                               var(--devtools-splitter-element-size));
 }
 
 #appcontent[devtoolstheme="light"] {
   /* These variables are used in browser.xul but inside the toolbox they are overridden by --theme-splitter-color */
   --devtools-splitter-color: #dde1e4;
 }
 
 #appcontent[devtoolstheme="dark"] {
@@ -43,31 +57,41 @@ splitter.devtools-horizontal-splitter,
   box-sizing: border-box;
 
   /* Positive z-index positions the splitter on top of its siblings and makes
      it clickable on both sides. */
   z-index: 1;
 }
 
 splitter.devtools-horizontal-splitter {
-  min-height: calc(var(--devtools-splitter-top-width) +
-    var(--devtools-splitter-bottom-width) + 1px);
+  min-height: var(--devtools-horizontal-splitter-min-height);
 
   border-top-width: var(--devtools-splitter-top-width);
   border-bottom-width: var(--devtools-splitter-bottom-width);
 
   margin-top: calc(-1 * var(--devtools-splitter-top-width) - 1px);
   margin-bottom: calc(-1 * var(--devtools-splitter-bottom-width));
 
   cursor: ns-resize;
 }
 
+#toolbox-deck ~ splitter.devtools-horizontal-splitter {
+  min-height: var(--devtools-emphasized-horizontal-splitter-min-height);
+}
+
+/**
+ * Emphasized splitter has the hover style.
+ * This emphasized splitter affect splitter console only.
+ */
+#toolbox-deck ~ splitter.devtools-horizontal-splitter:hover {
+  background-color: var(--theme-emphasized-splitter-color-hover);
+}
+
 .devtools-side-splitter {
-  min-width: calc(var(--devtools-splitter-inline-start-width) +
-    var(--devtools-splitter-inline-end-width) + 1px);
+  min-width: var(--devtools-vertical-splitter-min-width);
 
   border-inline-start-width: var(--devtools-splitter-inline-start-width);
   border-inline-end-width: var(--devtools-splitter-inline-end-width);
 
   margin-inline-start: calc(-1 * var(--devtools-splitter-inline-start-width) - 1px);
   margin-inline-end: calc(-1 * var(--devtools-splitter-inline-end-width));
 
   cursor: ew-resize;
--- a/devtools/client/themes/toolbox.css
+++ b/devtools/client/themes/toolbox.css
@@ -114,16 +114,23 @@
   padding-inline-end: 10px;
   min-width: 1px;
 }
 
 .devtools-tab-label:-moz-locale-dir(rtl) {
   mask-image: linear-gradient(to right, transparent 0, black 6px);
 }
 
+.devtools-tab .devtools-tab-badge {
+  color: var(--theme-highlight-blue);
+  font-size: 80%;
+  font-weight: 500;
+  margin-inline-start: 5px;
+}
+
 .devtools-tab-icon-only {
   min-width: 24px;
 }
 
 .devtools-tab {
   color: var(--theme-toolbar-color);
 }
 
--- a/devtools/client/themes/variables.css
+++ b/devtools/client/themes/variables.css
@@ -36,16 +36,18 @@
   --theme-selection-background: var(--blue-55);
   --theme-selection-background-hover: #F0F9FE;
   --theme-selection-focus-background: var(--toolbarbutton-hover-background);
   --theme-selection-focus-color: var(--grey-70);
   --theme-selection-color: #ffffff;
 
   /* Border color that splits the toolbars/panels/headers. */
   --theme-splitter-color: #e0e0e1;
+  --theme-emphasized-splitter-color: var(--grey-30);
+  --theme-emphasized-splitter-color-hover: var(--grey-40);
 
   --theme-comment: var(--grey-50);
   --theme-comment-alt: #ccd1d5;
 
   --theme-body-color: var(--grey-60);
   --theme-body-color-alt: var(--grey-40);
   --theme-body-color-inactive: #999797;
   --theme-content-color1: #292e33;
@@ -141,16 +143,18 @@
   --theme-selection-background: #204E8A;
   --theme-selection-background-hover: #353B48;
   --theme-selection-focus-background: var(--grey-60);
   --theme-selection-focus-color: var(--grey-30);
   --theme-selection-color: #ffffff;
 
   /* Border color that splits the toolbars/panels/headers. */
   --theme-splitter-color: #3c3c3d;
+  --theme-emphasized-splitter-color: var(--grey-60);
+  --theme-emphasized-splitter-color-hover: var(--grey-50);
 
   --theme-comment: #939393;
   --theme-comment-alt: #939393;
 
   --theme-body-color: #909090;
   --theme-body-color-alt: var(--grey-50);
   --theme-body-color-inactive: var(--grey-40);
   --theme-content-color1: var(--grey-30);
--- a/devtools/client/webconsole/test/mochitest/browser_webconsole_split.js
+++ b/devtools/client/webconsole/test/mochitest/browser_webconsole_split.js
@@ -83,24 +83,27 @@ async function performTests() {
     const deck = toolbox.doc.querySelector("#toolbox-deck");
     const webconsolePanel = toolbox.webconsolePanel;
     const splitter = toolbox.doc.querySelector("#toolbox-console-splitter");
 
     const containerHeight = deck.parentNode.getBoundingClientRect().height;
     const deckHeight = deck.getBoundingClientRect().height;
     const webconsoleHeight = webconsolePanel.getBoundingClientRect().height;
     const splitterVisibility = !splitter.getAttribute("hidden");
+    // Splitter height will be 1px since the margin is negative.
+    const splitterHeight = splitterVisibility ? 1 : 0;
     const openedConsolePanel = toolbox.currentToolId === "webconsole";
     const menuLabel = await getMenuLabel(toolbox);
 
     return {
       deckHeight: deckHeight,
       containerHeight: containerHeight,
       webconsoleHeight: webconsoleHeight,
       splitterVisibility: splitterVisibility,
+      splitterHeight: splitterHeight,
       openedConsolePanel: openedConsolePanel,
       menuLabel,
     };
   }
 
   function getMenuLabel() {
     return new Promise(resolve => {
       const button = toolbox.doc.getElementById("toolbox-meatball-menu-button");
@@ -213,17 +216,19 @@ async function performTests() {
     currentUIState = await getCurrentUIState();
 
     ok(currentUIState.splitterVisibility,
        "Splitter is visible when console is split");
     ok(currentUIState.deckHeight > 0,
        "Deck has a height > 0 when console is split");
     ok(currentUIState.webconsoleHeight > 0,
        "Web console has a height > 0 when console is split");
-    is(Math.round(currentUIState.deckHeight + currentUIState.webconsoleHeight),
+    is(Math.round(currentUIState.deckHeight +
+                  currentUIState.webconsoleHeight +
+                  currentUIState.splitterHeight),
        currentUIState.containerHeight,
        "Everything adds up to container height");
     ok(!currentUIState.openedConsolePanel,
        "The console panel is not the current tool");
     is(currentUIState.menuLabel, "hide",
        "The menu item indicates the console is split");
 
     await toolbox.toggleSplitConsole();
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -4277,17 +4277,17 @@ nsDocShell::LoadURIWithOptions(const cha
 
 NS_IMETHODIMP
 nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
                              const char16_t* aURL,
                              nsIChannel* aFailedChannel,
                              bool* aDisplayedErrorPage)
 {
   *aDisplayedErrorPage = false;
-  // Get prompt and string bundle servcies
+  // Get prompt and string bundle services
   nsCOMPtr<nsIPrompt> prompter;
   nsCOMPtr<nsIStringBundle> stringBundle;
   GetPromptAndStringBundle(getter_AddRefs(prompter),
                            getter_AddRefs(stringBundle));
 
   NS_ENSURE_TRUE(stringBundle, NS_ERROR_FAILURE);
   NS_ENSURE_TRUE(prompter, NS_ERROR_FAILURE);
 
@@ -4298,29 +4298,33 @@ nsDocShell::DisplayLoadError(nsresult aE
   nsAutoString formatStrs[kMaxFormatStrArgs];
   uint32_t formatStrCount = 0;
   bool addHostPort = false;
   nsresult rv = NS_OK;
   nsAutoString messageStr;
   nsAutoCString cssClass;
   nsAutoCString errorPage;
 
-  errorPage.AssignLiteral("neterror");
-
   if (mLoadURIDelegate) {
-    bool loadErrorHandled = false;
+    nsCOMPtr<nsIURI> errorPageURI;
     rv = mLoadURIDelegate->HandleLoadError(aURI, aError,
                                            NS_ERROR_GET_MODULE(aError),
-                                           &loadErrorHandled);
-    if (NS_SUCCEEDED(rv) && loadErrorHandled) {
-      // The request has been handled, nothing to do here.
+                                           getter_AddRefs(errorPageURI));
+    if (NS_FAILED(rv)) {
       *aDisplayedErrorPage = false;
       return NS_OK;
     }
-  }
+
+    if (errorPageURI) {
+      *aDisplayedErrorPage = NS_SUCCEEDED(LoadErrorPage(errorPageURI, aURI, aFailedChannel));
+      return NS_OK;
+    }
+  }
+
+  errorPage.AssignLiteral("neterror");
 
   // Turn the error code into a human readable error message.
   if (NS_ERROR_UNKNOWN_PROTOCOL == aError) {
     NS_ENSURE_ARG_POINTER(aURI);
 
     // Extract the schemes into a comma delimited list.
     nsAutoCString scheme;
     aURI->GetScheme(scheme);
@@ -4752,26 +4756,16 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, 
 
     MOZ_LOG(gDocShellLog, LogLevel::Debug,
            ("nsDocShell[%p]::LoadErrorPage(\"%s\", \"%s\", {...}, [%s])\n", this,
             aURI ? aURI->GetSpecOrDefault().get() : "",
             NS_ConvertUTF16toUTF8(aURL).get(),
             chanName.get()));
   }
 #endif
-  mFailedChannel = aFailedChannel;
-  mFailedURI = aURI;
-  mFailedLoadType = mLoadType;
-
-  if (mLSHE) {
-    // Abandon mLSHE's BFCache entry and create a new one.  This way, if
-    // we go back or forward to another SHEntry with the same doc
-    // identifier, the error page won't persist.
-    mLSHE->AbandonBFCacheEntry();
-  }
 
   nsAutoCString url;
   if (aURI) {
     nsresult rv = aURI->GetSpec(url);
     NS_ENSURE_SUCCESS(rv, rv);
   } else if (aURL) {
     CopyUTF16toUTF8(MakeStringSpan(aURL), url);
   } else {
@@ -4828,17 +4822,34 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, 
   // end of the URL, so append it last.
   errorPageUrl.AppendLiteral("&d=");
   errorPageUrl.AppendASCII(escapedDescription.get());
 
   nsCOMPtr<nsIURI> errorPageURI;
   nsresult rv = NS_NewURI(getter_AddRefs(errorPageURI), errorPageUrl);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return InternalLoad(errorPageURI, nullptr, Nothing(), false, false, nullptr, RP_Unset,
+  return LoadErrorPage(errorPageURI, aURI, aFailedChannel);
+}
+
+nsresult
+nsDocShell::LoadErrorPage(nsIURI* aErrorURI, nsIURI* aFailedURI, nsIChannel* aFailedChannel)
+{
+  mFailedChannel = aFailedChannel;
+  mFailedURI = aFailedURI;
+  mFailedLoadType = mLoadType;
+
+  if (mLSHE) {
+    // Abandon mLSHE's BFCache entry and create a new one.  This way, if
+    // we go back or forward to another SHEntry with the same doc
+    // identifier, the error page won't persist.
+    mLSHE->AbandonBFCacheEntry();
+  }
+
+  return InternalLoad(aErrorURI, nullptr, Nothing(), false, false, nullptr, RP_Unset,
                       nsContentUtils::GetSystemPrincipal(), nullptr,
                       INTERNAL_LOAD_FLAGS_NONE, EmptyString(),
                       nullptr, VoidString(), nullptr, nullptr,
                       LOAD_ERROR_PAGE, nullptr, true, VoidString(), this,
                       nullptr, nullptr, nullptr);
 }
 
 NS_IMETHODIMP
@@ -9521,17 +9532,17 @@ nsDocShell::InternalLoad(nsIURI* aURI,
                                     : nullptr;
 
   const bool isDocumentAuxSandboxed = doc &&
     (doc->GetSandboxFlags() & SANDBOXED_AUXILIARY_NAVIGATION);
 
   const bool checkLoadDelegates = !(aFlags & INTERNAL_LOAD_FLAGS_DELEGATES_CHECKED);
   aFlags = aFlags & ~INTERNAL_LOAD_FLAGS_DELEGATES_CHECKED;
 
-  if (aURI && mLoadURIDelegate && checkLoadDelegates &&
+  if (aURI && mLoadURIDelegate && checkLoadDelegates && aLoadType != LOAD_ERROR_PAGE &&
       (!targetDocShell || targetDocShell == static_cast<nsIDocShell*>(this))) {
     // Dispatch only load requests for the current or a new window to the
     // delegate, e.g., to allow for GeckoView apps to handle the load event
     // outside of Gecko.
     const int where = (aWindowTarget.IsEmpty() || targetDocShell)
                       ? nsIBrowserDOMWindow::OPEN_CURRENTWINDOW
                       : nsIBrowserDOMWindow::OPEN_NEWWINDOW;
 
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -585,22 +585,28 @@ private: // member functions
 
   // Helper method that is called when a new document (including any
   // sub-documents - ie. frames) has been completely loaded.
   nsresult EndPageLoad(nsIWebProgress* aProgress,
                        nsIChannel* aChannel,
                        nsresult aResult);
 
 
+  // Builds an error page URI (e.g. about:neterror?etc) for the given aURI
+  // and displays it via the LoadErrorPage() overload below.
   nsresult LoadErrorPage(nsIURI* aURI, const char16_t* aURL,
-                           const char* aErrorPage,
-                           const char* aErrorType,
-                           const char16_t* aDescription,
-                           const char* aCSSClass,
-                           nsIChannel* aFailedChannel);
+                         const char* aErrorPage,
+                         const char* aErrorType,
+                         const char16_t* aDescription,
+                         const char* aCSSClass,
+                         nsIChannel* aFailedChannel);
+
+  // This method directly loads aErrorURI as an error page. aFailedURI and aFailedChannel
+  // come from DisplayLoadError() or the LoadErrorPage() overload above.
+  nsresult LoadErrorPage(nsIURI* aErrorURI, nsIURI* aFailedURI, nsIChannel* aFailedChannel);
 
   bool DisplayLoadError(nsresult aError, nsIURI* aURI, const char16_t* aURL,
                         nsIChannel* aFailedChannel)
   {
     bool didDisplayLoadError = false;
     DisplayLoadError(aError, aURI, aURL, aFailedChannel, &didDisplayLoadError);
     return didDisplayLoadError;
   }
new file mode 100644
--- /dev/null
+++ b/dom/events/test/file_bug1484371.html
@@ -0,0 +1,94 @@
+<html>
+  <head>
+    <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+    <script>
+      var mouseEnterCount = 0;
+      function mouseEnter() {
+        ++mouseEnterCount;
+      }
+      var mouseLeaveCount = 0;
+      function mouseLeave() {
+        ++mouseLeaveCount;
+      }
+
+      var pointerEnterCount = 0;
+      function pointerEnter() {
+        ++pointerEnterCount;
+      }
+      var pointerLeaveCount = 0;
+      function pointerLeave() {
+        ++pointerLeaveCount;
+      }
+
+      function pointerEventsEnabled() {
+        return "onpointerenter" in document.body;
+      }
+
+      function checkEventCounts(expected, msg) {
+        parent.is(mouseEnterCount, expected.mouseEnterCount, msg + ": mouseenter event count");
+        parent.is(mouseLeaveCount, expected.mouseLeaveCount, msg + ": mouseleave event count");
+        if (pointerEventsEnabled()) {
+          parent.is(pointerEnterCount, expected.pointerEnterCount, msg + ": pointerenter event count");
+          parent.is(pointerLeaveCount, expected.pointerLeaveCount, msg + ": pointerleave event count");
+        }
+      }
+
+      function test() {
+        var lightDiv = document.getElementById("lightDiv");
+        var host = document.getElementById("host");
+        var sr = host.attachShadow({mode: "closed"});
+        sr.innerHTML = "<div>shadow DOM<div>";
+        var shadowDiv = sr.firstChild;
+
+        host.addEventListener("mouseenter", mouseEnter, true);
+        host.addEventListener("mouseleave", mouseLeave, true);
+        host.addEventListener("pointerenter", pointerEnter, true);
+        host.addEventListener("pointerleave", pointerLeave, true);
+
+        shadowDiv.addEventListener("mouseenter", mouseEnter, true);
+        shadowDiv.addEventListener("mouseleave", mouseLeave, true);
+        shadowDiv.addEventListener("pointerenter", pointerEnter, true);
+        shadowDiv.addEventListener("pointerleave", pointerLeave, true);
+
+        synthesizeMouseAtCenter(lightDiv, { type: "mousemove" });
+        checkEventCounts({ mouseEnterCount: 0,
+                           mouseLeaveCount: 0,
+                           pointerEnterCount: 0,
+                           pointerLeaveCount: 0
+                         },
+                         "Entered light DOM"
+                         );
+
+        synthesizeMouseAtCenter(shadowDiv, { type: "mousemove" })
+        checkEventCounts({ mouseEnterCount: 2,
+                           mouseLeaveCount: 0,
+                           pointerEnterCount: 2,
+                           pointerLeaveCount: 0
+                         },
+                         "Entered shadow DOM");
+
+        synthesizeMouseAtCenter(lightDiv, { type: "mousemove" })
+        checkEventCounts({ mouseEnterCount: 2,
+                           mouseLeaveCount: 2,
+                           pointerEnterCount: 2,
+                           pointerLeaveCount: 2
+                         },
+                         "Left shadow DOM"
+                         );
+
+        parent.SimpleTest.finish();
+      }
+
+    function lazyRequestAnimationFrame(fn) {
+      requestAnimationFrame(
+        function() {
+          setTimeout(fn);
+        });
+    }
+    </script>
+  </head>
+  <body onload="lazyRequestAnimationFrame(test)">
+    <div id="lightDiv">light DOM</div>
+    <div id="host"></div>
+  </body>
+</html>
--- a/dom/events/test/mochitest.ini
+++ b/dom/events/test/mochitest.ini
@@ -200,12 +200,14 @@ support-files = window_bug1369072.html
 skip-if = toolkit == 'android'
 [test_bug1429572.html]
 support-files = window_bug1429572.html
 [test_bug1446834.html]
 support-files = file_bug1446834.html
 [test_bug1447993.html]
 support-files = window_bug1447993.html
 skip-if = toolkit == 'android'
+[test_bug1484371.html]
+support-files = file_bug1484371.html
 [test_dnd_with_modifiers.html]
 [test_hover_mouseleave.html]
 [test_slotted_mouse_event.html]
 [test_slotted_text_click.html]
new file mode 100644
--- /dev/null
+++ b/dom/events/test/test_bug1484371.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1484371
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 1484371</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+  /** Test for Bug 1484371 **/
+
+  SimpleTest.waitForExplicitFinish();
+
+  window.onload = function() {
+    SpecialPowers.pushPrefEnv({"set": [["dom.webcomponents.shadowdom.enabled", true]]},
+      function() {
+        document.getElementById("iframe").src = "file_bug1484371.html";
+      });
+  }
+
+  </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1484371">Mozilla Bug 1484371</a>
+<iframe id="iframe"></iframe>
+</body>
+</html>
--- a/dom/script/ScriptLoader.cpp
+++ b/dom/script/ScriptLoader.cpp
@@ -960,16 +960,49 @@ ScriptLoader::InstantiateModuleTree(Modu
     MOZ_ASSERT(!exception.isUndefined());
     moduleScript->SetErrorToRethrow(exception);
   }
 
   return true;
 }
 
 nsresult
+ScriptLoader::AssociateSourceElementsForModuleTree(JSContext* aCx,
+                                                   ModuleLoadRequest* aRequest)
+{
+  // Preloading can cause JS scripts to be compiled before DOM script element
+  // nodes have been created. This method ensures compiled scripts are
+  // associated with DOM element nodes before execution.
+
+  MOZ_ASSERT(aRequest);
+
+  ModuleScript* moduleScript = aRequest->mModuleScript;
+  if (moduleScript->SourceElementAssociated()) {
+    return NS_OK;
+  }
+
+  for (ModuleLoadRequest* childRequest : aRequest->mImports) {
+    nsresult rv = AssociateSourceElementsForModuleTree(aCx, childRequest);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  JS::Rooted<JSScript*> script(aCx, moduleScript->Script());
+  MOZ_ASSERT(script);
+
+  nsresult rv = nsJSUtils::InitModuleSourceElement(aCx, script, aRequest->Element());
+  NS_ENSURE_SUCCESS(rv, rv);
+  moduleScript->SetSourceElementAssociated();
+
+  // The script is now ready to be exposed to the debugger.
+  JS::ExposeScriptToDebugger(aCx, script);
+
+  return NS_OK;
+}
+
+nsresult
 ScriptLoader::RestartLoad(ScriptLoadRequest* aRequest)
 {
   MOZ_ASSERT(aRequest->IsBytecode());
   aRequest->mScriptBytecode.clearAndFree();
   TRACE_FOR_TEST(aRequest->Element(), "scriptloader_fallback");
 
   // Start a new channel from which we explicitly request to stream the source
   // instead of the bytecode.
@@ -2307,22 +2340,18 @@ ScriptLoader::EvaluateScript(ScriptLoadR
         JS_SetPendingException(cx, error);
         return NS_OK; // An error is reported by AutoEntryScript.
       }
 
       JS::Rooted<JSScript*> script(cx, moduleScript->Script());
       MOZ_ASSERT(script);
 
       if (!moduleScript->SourceElementAssociated()) {
-        rv = nsJSUtils::InitModuleSourceElement(cx, script, aRequest->Element());
+        rv = AssociateSourceElementsForModuleTree(cx, request);
         NS_ENSURE_SUCCESS(rv, rv);
-        moduleScript->SetSourceElementAssociated();
-
-        // The script is now ready to be exposed to the debugger.
-        JS::ExposeScriptToDebugger(cx, script);
       }
 
       rv = nsJSUtils::ModuleEvaluate(cx, script);
       MOZ_ASSERT(NS_FAILED(rv) == aes.HasException());
       if (NS_FAILED(rv)) {
         LOG(("ScriptLoadRequest (%p):   evaluation failed", aRequest));
         rv = NS_OK; // An error is reported by AutoEntryScript.
       }
--- a/dom/script/ScriptLoader.h
+++ b/dom/script/ScriptLoader.h
@@ -535,16 +535,19 @@ private:
   void ProcessLoadedModuleTree(ModuleLoadRequest* aRequest);
   bool InstantiateModuleTree(ModuleLoadRequest* aRequest);
   JS::Value FindFirstParseError(ModuleLoadRequest* aRequest);
   void StartFetchingModuleDependencies(ModuleLoadRequest* aRequest);
 
   RefPtr<mozilla::GenericPromise>
   StartFetchingModuleAndDependencies(ModuleLoadRequest* aParent, nsIURI* aURI);
 
+  nsresult AssociateSourceElementsForModuleTree(JSContext* aCx,
+                                                ModuleLoadRequest* aRequest);
+
   nsIDocument* mDocument;                   // [WEAK]
   nsCOMArray<nsIScriptLoaderObserver> mObservers;
   ScriptLoadRequestList mNonAsyncExternalScriptInsertedRequests;
   // mLoadingAsyncRequests holds async requests while they're loading; when they
   // have been loaded they are moved to mLoadedAsyncRequests.
   ScriptLoadRequestList mLoadingAsyncRequests;
   ScriptLoadRequestList mLoadedAsyncRequests;
   ScriptLoadRequestList mDeferRequests;
--- a/gfx/layers/LayerSorter.cpp
+++ b/gfx/layers/LayerSorter.cpp
@@ -74,18 +74,18 @@ static gfxFloat RecoverZDepth(const Matr
  * depths and use this point to determine an ordering for the two layers.
  * For layers that are intersecting in 3d space, this essentially guesses an 
  * order. In a lot of cases we only intersect right at the edge point (3d cubes
  * in particular) and this generates the 'correct' looking ordering. For planes
  * that truely intersect, then there is no correct ordering and this remains
  * unsolved without changing our rendering code.
  */
 static LayerSortOrder CompareDepth(Layer* aOne, Layer* aTwo) {
-  gfxRect ourRect = ThebesRect(aOne->GetLocalVisibleRegion().ToUnknownRegion().GetBounds());
-  gfxRect otherRect = ThebesRect(aTwo->GetLocalVisibleRegion().ToUnknownRegion().GetBounds());
+  gfxRect ourRect = ThebesRect(aOne->GetLocalVisibleRegion().GetBounds().ToUnknownRect());
+  gfxRect otherRect = ThebesRect(aTwo->GetLocalVisibleRegion().GetBounds().ToUnknownRect());
 
   MOZ_ASSERT(aOne->GetParent() && aOne->GetParent()->Extend3DContext() &&
              aTwo->GetParent() && aTwo->GetParent()->Extend3DContext());
   // Effective transform of leaves may had been projected to 2D.
   Matrix4x4 ourTransform =
     aOne->GetLocalTransform() * aOne->GetParent()->GetEffectiveTransform();
   Matrix4x4 otherTransform =
     aTwo->GetLocalTransform() * aTwo->GetParent()->GetEffectiveTransform();
--- a/gfx/layers/LayerTreeInvalidation.cpp
+++ b/gfx/layers/LayerTreeInvalidation.cpp
@@ -293,33 +293,33 @@ public:
 
   void CheckCanary()
   {
     mCanary.Check();
     mLayer->CheckCanary();
   }
 
   IntRect NewTransformedBoundsForLeaf() {
-    return TransformRect(mLayer->GetLocalVisibleRegion().ToUnknownRegion().GetBounds(),
+    return TransformRect(mLayer->GetLocalVisibleRegion().GetBounds().ToUnknownRect(),
                          GetTransformForInvalidation(mLayer));
   }
 
   IntRect OldTransformedBoundsForLeaf() {
-    return TransformRect(mVisibleRegion.ToUnknownRegion().GetBounds(), mTransform);
+    return TransformRect(mVisibleRegion.GetBounds().ToUnknownRect(), mTransform);
   }
 
   virtual Maybe<IntRect> NewTransformedBounds()
   {
-    return Some(TransformRect(mLayer->GetLocalVisibleRegion().ToUnknownRegion().GetBounds(),
+    return Some(TransformRect(mLayer->GetLocalVisibleRegion().GetBounds().ToUnknownRect(),
                               GetTransformForInvalidation(mLayer)));
   }
 
   virtual Maybe<IntRect> OldTransformedBounds()
   {
-    return Some(TransformRect(mVisibleRegion.ToUnknownRegion().GetBounds(), mTransform));
+    return Some(TransformRect(mVisibleRegion.GetBounds().ToUnknownRect(), mTransform));
   }
 
   virtual bool ComputeChangeInternal(const char* aPrefix,
                                      nsIntRegion& aOutRegion,
                                      NotifySubDocInvalidationFunc aCallback)
   {
     if (mLayer->AsHostLayer() && !mLayer->GetLocalVisibleRegion().ToUnknownRegion().IsEqual(mVisibleRegion)) {
       IntRect result = NewTransformedBoundsForLeaf();
@@ -786,17 +786,17 @@ LayerPropertiesBase::ComputeDifferences(
   NS_ASSERTION(aRoot, "Must have a layer tree to compare against!");
   if (mLayer != aRoot) {
     if (aCallback) {
       NotifySubdocumentInvalidation(aRoot, aCallback);
     } else {
       ClearInvalidations(aRoot);
     }
     IntRect bounds = TransformRect(
-      aRoot->GetLocalVisibleRegion().ToUnknownRegion().GetBounds(),
+      aRoot->GetLocalVisibleRegion().GetBounds().ToUnknownRect(),
       aRoot->GetLocalTransform());
     Maybe<IntRect> oldBounds = OldTransformedBounds();
     if (!oldBounds) {
       return false;
     }
     Maybe<IntRect> result = bounds.SafeUnion(oldBounds.value());
     if (!result) {
       LTI_LOG("overflowed bounds computing the union of layers %p and %p\n", mLayer.get(), aRoot);
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -1078,16 +1078,24 @@ ContainerLayer::Creates3DContextWithExte
        child = child->GetNextSibling()) {
       if (child->Extend3DContext()) {
         return true;
       }
   }
   return false;
 }
 
+RenderTargetIntRect
+ContainerLayer::GetIntermediateSurfaceRect()
+{
+  NS_ASSERTION(mUseIntermediateSurface, "Must have intermediate surface");
+  LayerIntRect bounds = GetLocalVisibleRegion().GetBounds();
+  return RenderTargetIntRect::FromUnknownRect(bounds.ToUnknownRect());
+}
+
 bool
 ContainerLayer::HasMultipleChildren()
 {
   uint32_t count = 0;
   for (Layer* child = GetFirstChild(); child; child = child->GetNextSibling()) {
     const Maybe<ParentLayerIntRect>& clipRect = child->GetLocalClipRect();
     if (clipRect && clipRect->IsEmpty())
       continue;
@@ -1130,17 +1138,17 @@ SortLayersWithBSPTree(nsTArray<Layer*>& 
   // Build a list of polygons to be sorted.
   for (Layer* layer : aArray) {
     // Ignore invisible layers.
     if (!layer->IsVisible()) {
       continue;
     }
 
     const gfx::IntRect& bounds =
-      layer->GetLocalVisibleRegion().ToUnknownRegion().GetBounds();
+      layer->GetLocalVisibleRegion().GetBounds().ToUnknownRect();
 
     const gfx::Matrix4x4& transform = layer->GetEffectiveTransform();
 
     if (transform.IsSingular()) {
       // Transform cannot be inverted.
       continue;
     }
 
@@ -2422,17 +2430,17 @@ void
 SetAntialiasingFlags(Layer* aLayer, DrawTarget* aTarget)
 {
   bool permitSubpixelAA = !(aLayer->GetContentFlags() & Layer::CONTENT_DISABLE_SUBPIXEL_AA);
   if (aTarget->IsCurrentGroupOpaque()) {
     aTarget->SetPermitSubpixelAA(permitSubpixelAA);
     return;
   }
 
-  const IntRect& bounds = aLayer->GetVisibleRegion().ToUnknownRegion().GetBounds();
+  const IntRect& bounds = aLayer->GetVisibleRegion().GetBounds().ToUnknownRect();
   gfx::Rect transformedBounds = aTarget->GetTransform().TransformBounds(gfx::Rect(Float(bounds.X()), Float(bounds.Y()),
                                                                                   Float(bounds.Width()), Float(bounds.Height())));
   transformedBounds.RoundOut();
   IntRect intTransformedBounds;
   transformedBounds.ToIntRect(&intTransformedBounds);
   permitSubpixelAA &= !(aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) ||
                       aTarget->GetOpaqueRect().Contains(intTransformedBounds);
   aTarget->SetPermitSubpixelAA(permitSubpixelAA);
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -2218,21 +2218,17 @@ public:
 
   /**
    * Returns the rectangle covered by the intermediate surface,
    * in this layer's coordinate system.
    *
    * NOTE: Since this layer has an intermediate surface it follows
    *       that LayerPixel == RenderTargetPixel
    */
-  RenderTargetIntRect GetIntermediateSurfaceRect()
-  {
-    NS_ASSERTION(mUseIntermediateSurface, "Must have intermediate surface");
-    return RenderTargetIntRect::FromUnknownRect(GetLocalVisibleRegion().ToUnknownRegion().GetBounds());
-  }
+  RenderTargetIntRect GetIntermediateSurfaceRect();
 
   /**
    * Returns true if this container has more than one non-empty child
    */
   bool HasMultipleChildren();
 
   /**
    * Returns true if this container supports children with component alpha.
--- a/gfx/layers/basic/BasicContainerLayer.cpp
+++ b/gfx/layers/basic/BasicContainerLayer.cpp
@@ -106,17 +106,17 @@ bool
 BasicContainerLayer::ChildrenPartitionVisibleRegion(const gfx::IntRect& aInRect)
 {
   Matrix transform;
   if (!GetEffectiveTransform().CanDraw2D(&transform) ||
       ThebesMatrix(transform).HasNonIntegerTranslation())
     return false;
 
   nsIntPoint offset(int32_t(transform._31), int32_t(transform._32));
-  gfx::IntRect rect = aInRect.Intersect(GetLocalVisibleRegion().ToUnknownRegion().GetBounds() + offset);
+  gfx::IntRect rect = aInRect.Intersect(GetLocalVisibleRegion().GetBounds().ToUnknownRect() + offset);
   nsIntRegion covered;
 
   for (Layer* l = mFirstChild; l; l = l->GetNextSibling()) {
     if (ToData(l)->IsHidden())
       continue;
 
     Matrix childTransform;
     if (!l->GetEffectiveTransform().CanDraw2D(&childTransform) ||
--- a/gfx/layers/client/ClientTiledPaintedLayer.cpp
+++ b/gfx/layers/client/ClientTiledPaintedLayer.cpp
@@ -435,17 +435,17 @@ ClientTiledPaintedLayer::EndPaint()
 
 void
 ClientTiledPaintedLayer::RenderLayer()
 {
   LayerManager::DrawPaintedLayerCallback callback =
     ClientManager()->GetPaintedLayerCallback();
   void *data = ClientManager()->GetPaintedLayerCallbackData();
 
-  IntSize layerSize = mVisibleRegion.ToUnknownRegion().GetBounds().Size();
+  IntSize layerSize = mVisibleRegion.GetBounds().ToUnknownRect().Size();
   IntSize tileSize = gfx::gfxVars::TileSize();
   bool isHalfTileWidthOrHeight = layerSize.width <= tileSize.width / 2 ||
     layerSize.height <= tileSize.height / 2;
 
   // Use single tile when layer is not scrollable, is smaller than one
   // tile, or when more than half of the tiles' pixels in either
   // dimension would be wasted.
   bool wantSingleTiledContentClient =
--- a/gfx/layers/composite/ContainerLayerComposite.cpp
+++ b/gfx/layers/composite/ContainerLayerComposite.cpp
@@ -68,17 +68,17 @@ DrawLayerInfo(const RenderTargetIntRect&
 
   std::stringstream ss;
   aLayer->PrintInfo(ss, "");
 
   LayerIntRegion visibleRegion = aLayer->GetVisibleRegion();
 
   uint32_t maxWidth = std::min<uint32_t>(visibleRegion.GetBounds().Width(), 500);
 
-  IntPoint topLeft = visibleRegion.ToUnknownRegion().GetBounds().TopLeft();
+  IntPoint topLeft = visibleRegion.GetBounds().ToUnknownRect().TopLeft();
   aManager->GetTextRenderer()->RenderText(
     aManager->GetCompositor(),
     ss.str().c_str(),
     topLeft,
     aLayer->GetEffectiveTransform(), 16,
     maxWidth);
 }
 
@@ -154,17 +154,17 @@ TransformLayerGeometry(Layer* aLayer, Ma
     aGeometry.reset();
   }
 }
 
 
 template<class ContainerT>
 static gfx::IntRect ContainerVisibleRect(ContainerT* aContainer)
 {
-  gfx::IntRect surfaceRect = aContainer->GetLocalVisibleRegion().ToUnknownRegion().GetBounds();
+  gfx::IntRect surfaceRect = aContainer->GetLocalVisibleRegion().GetBounds().ToUnknownRect();
   return surfaceRect;
 }
 
 
 /* all of the per-layer prepared data we need to maintain */
 struct PreparedLayer
 {
   PreparedLayer(Layer *aLayer,
@@ -527,17 +527,17 @@ CreateOrRecycleTarget(ContainerT* aConta
   }
 }
 
 template<class ContainerT> RefPtr<CompositingRenderTarget>
 CreateTemporaryTargetAndCopyFromBackground(ContainerT* aContainer,
                                            LayerManagerComposite* aManager)
 {
   Compositor* compositor = aManager->GetCompositor();
-  gfx::IntRect visibleRect = aContainer->GetLocalVisibleRegion().ToUnknownRegion().GetBounds();
+  gfx::IntRect visibleRect = aContainer->GetLocalVisibleRegion().GetBounds().ToUnknownRect();
   RefPtr<CompositingRenderTarget> previousTarget = compositor->GetCurrentRenderTarget();
   gfx::IntRect surfaceRect = gfx::IntRect(visibleRect.X(), visibleRect.Y(),
                                           visibleRect.Width(), visibleRect.Height());
 
   gfx::IntPoint sourcePoint = gfx::IntPoint(visibleRect.X(), visibleRect.Y());
 
   gfx::Matrix4x4 transform = aContainer->GetEffectiveTransform();
   DebugOnly<gfx::Matrix> transform2d;
@@ -591,17 +591,17 @@ ContainerRender(ContainerT* aContainer,
     } else {
       surface = aContainer->mPrepared->mTmpTarget;
     }
 
     if (!surface) {
       return;
     }
 
-    gfx::Rect visibleRect(aContainer->GetLocalVisibleRegion().ToUnknownRegion().GetBounds());
+    gfx::Rect visibleRect(aContainer->GetLocalVisibleRegion().GetBounds().ToUnknownRect());
 
     RefPtr<Compositor> compositor = aManager->GetCompositor();
 #ifdef MOZ_DUMP_PAINTING
     if (gfxEnv::DumpCompositorTextures()) {
       RefPtr<gfx::DataSourceSurface> surf = surface->Dump(compositor);
       if (surf) {
         WriteSnapshotToDumpFile(aContainer, surf);
       }
--- a/gfx/layers/composite/LayerManagerComposite.h
+++ b/gfx/layers/composite/LayerManagerComposite.h
@@ -749,17 +749,17 @@ RenderWithAllMasks(Layer* aLayer, Compos
   //  (1) The first mask
   //  (2) The list of intermediate masks (every mask except first and last)
   //  (3) The final mask.
   // Part (2) can be empty.
   // For parts (1) and (2) we need to allocate intermediate surfaces to render
   // into. The final mask gets rendered into the original render target.
 
   // Calculate the size of the intermediate surfaces.
-  gfx::Rect visibleRect(aLayer->GetLocalVisibleRegion().ToUnknownRegion().GetBounds());
+  gfx::Rect visibleRect(aLayer->GetLocalVisibleRegion().GetBounds().ToUnknownRect());
   gfx::Matrix4x4 transform = aLayer->GetEffectiveTransform();
   // TODO: Use RenderTargetIntRect and TransformBy here
   gfx::IntRect surfaceRect =
     RoundedOut(transform.TransformAndClipBounds(visibleRect, gfx::Rect(aClipRect)));
   if (surfaceRect.IsEmpty()) {
     return;
   }
 
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -1899,22 +1899,30 @@ CompositorOGL::Resume()
   return gl()->RenewSurface(GetWidget());
 #endif
   return true;
 }
 
 already_AddRefed<DataTextureSource>
 CompositorOGL::CreateDataTextureSource(TextureFlags aFlags)
 {
+  if (!gl()) {
+    return nullptr;
+  }
+
   return MakeAndAddRef<TextureImageTextureSourceOGL>(this, aFlags);
 }
 
 already_AddRefed<DataTextureSource>
 CompositorOGL::CreateDataTextureSourceAroundYCbCr(TextureHost* aTexture)
 {
+  if (!gl()) {
+    return nullptr;
+  }
+
   BufferTextureHost* bufferTexture = aTexture->AsBufferTextureHost();
   MOZ_ASSERT(bufferTexture);
 
   if (!bufferTexture) {
     return nullptr;
   }
 
   uint8_t* buf = bufferTexture->GetBuffer();
@@ -1986,16 +1994,20 @@ CompositorOGL::TryUnlockTextures()
     TextureSync::SetTexturesUnlocked(it.Key(), *it.UserData());
   }
 }
 #endif
 
 already_AddRefed<DataTextureSource>
 CompositorOGL::CreateDataTextureSourceAround(gfx::DataSourceSurface* aSurface)
 {
+  if (!gl()) {
+    return nullptr;
+  }
+
   return MakeAndAddRef<DirectMapTextureSource>(this, aSurface);
 }
 
 bool
 CompositorOGL::SupportsPartialTextureUpdate()
 {
   return CanUploadSubTextures(mGLContext);
 }
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -335,34 +335,43 @@ DirectMapTextureSource::Update(gfx::Data
   }
 
   return UpdateInternal(aSurface, aDestRegion, aSrcOffset, false);
 }
 
 bool
 DirectMapTextureSource::Sync(bool aBlocking)
 {
-  gl()->MakeCurrent();
+  if (!gl() || !gl()->MakeCurrent()) {
+    // We use this function to decide whether we can unlock the texture
+    // and clean it up. If we return false here and for whatever reason
+    // the context is absent or invalid, the compositor will keep a
+    // reference to this texture forever.
+    return true;
+  }
+
   if (!gl()->IsDestroyed()) {
     if (aBlocking) {
       gl()->fFinishObjectAPPLE(LOCAL_GL_TEXTURE, mTextureHandle);
     } else {
       return gl()->fTestObjectAPPLE(LOCAL_GL_TEXTURE, mTextureHandle);
     }
   }
   return true;
 }
 
 bool
 DirectMapTextureSource::UpdateInternal(gfx::DataSourceSurface* aSurface,
                                        nsIntRegion* aDestRegion,
                                        gfx::IntPoint* aSrcOffset,
                                        bool aInit)
 {
-  gl()->MakeCurrent();
+  if (!gl() || !gl()->MakeCurrent()) {
+    return false;
+  }
 
   if (aInit) {
     gl()->fGenTextures(1, &mTextureHandle);
     gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, mTextureHandle);
 
     gl()->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
                          LOCAL_GL_TEXTURE_STORAGE_HINT_APPLE,
                          LOCAL_GL_STORAGE_CACHED_APPLE);
--- a/gfx/tests/gtest/TestCompositor.cpp
+++ b/gfx/tests/gtest/TestCompositor.cpp
@@ -181,29 +181,29 @@ TEST(Gfx, CompositorSimpleTree)
       nsIntRegion(IntRect(0, 0, 100, 100)),
       nsIntRegion(IntRect(0, 50, 100, 100)),
     };
     RefPtr<Layer> root = CreateLayerTree("c(ooo)", layerVisibleRegion, nullptr, lmBase, layers);
 
     { // background
       ColorLayer* colorLayer = layers[1]->AsColorLayer();
       colorLayer->SetColor(Color(1.f, 0.f, 1.f, 1.f));
-      colorLayer->SetBounds(colorLayer->GetVisibleRegion().ToUnknownRegion().GetBounds());
+      colorLayer->SetBounds(colorLayer->GetVisibleRegion().GetBounds().ToUnknownRect());
     }
 
     {
       ColorLayer* colorLayer = layers[2]->AsColorLayer();
       colorLayer->SetColor(Color(1.f, 0.f, 0.f, 1.f));
-      colorLayer->SetBounds(colorLayer->GetVisibleRegion().ToUnknownRegion().GetBounds());
+      colorLayer->SetBounds(colorLayer->GetVisibleRegion().GetBounds().ToUnknownRect());
     }
 
     {
       ColorLayer* colorLayer = layers[3]->AsColorLayer();
       colorLayer->SetColor(Color(0.f, 0.f, 1.f, 1.f));
-      colorLayer->SetBounds(colorLayer->GetVisibleRegion().ToUnknownRegion().GetBounds());
+      colorLayer->SetBounds(colorLayer->GetVisibleRegion().GetBounds().ToUnknownRect());
     }
 
     RefPtr<DrawTarget> refDT = CreateDT();
     refDT->FillRect(Rect(0, 0, gCompWidth, gCompHeight), ColorPattern(Color(1.f, 0.f, 1.f, 1.f)));
     refDT->FillRect(Rect(0, 0, 100, 100), ColorPattern(Color(1.f, 0.f, 0.f, 1.f)));
     refDT->FillRect(Rect(0, 50, 100, 100), ColorPattern(Color(0.f, 0.f, 1.f, 1.f)));
     EXPECT_TRUE(CompositeAndCompare(layerManager, refDT));
   }
rename from js/rust/src/ac.rs
rename to js/rust/src/ar.rs
--- a/js/rust/src/ac.rs
+++ b/js/rust/src/ar.rs
@@ -1,56 +1,56 @@
 use jsapi::root::*;
 #[cfg(feature = "debugmozjs")]
 use std::ptr;
 
 #[derive(Debug)]
-pub struct AutoCompartment(JSAutoRealmAllowCCW);
+pub struct AutoRealm(JSAutoRealmAllowCCW);
 
-impl AutoCompartment {
+impl AutoRealm {
     #[cfg(feature = "debugmozjs")]
     pub unsafe fn with_obj(cx: *mut JSContext,
                            target: *mut JSObject)
-                           -> AutoCompartment
+                           -> AutoRealm
     {
         let mut notifier = mozilla::detail::GuardObjectNotifier {
             mStatementDone: ptr::null_mut(),
         };
 
-        AutoCompartment(
+        AutoRealm(
             JSAutoRealmAllowCCW::new(
                 cx,
                 target,
                 &mut notifier as *mut _))
     }
 
     #[cfg(not(feature = "debugmozjs"))]
     pub unsafe fn with_obj(cx: *mut JSContext,
                            target: *mut JSObject)
-                           -> AutoCompartment
+                           -> AutoRealm
     {
-        AutoCompartment(JSAutoRealmAllowCCW::new(cx, target))
+        AutoRealm(JSAutoRealmAllowCCW::new(cx, target))
     }
 
     #[cfg(feature = "debugmozjs")]
     pub unsafe fn with_script(cx: *mut JSContext,
                               target: *mut JSScript)
-                              -> AutoCompartment
+                              -> AutoRealm
     {
         let mut notifier = mozilla::detail::GuardObjectNotifier {
             mStatementDone: ptr::null_mut(),
         };
 
-        AutoCompartment(
+        AutoRealm(
             JSAutoRealmAllowCCW::new1(
                 cx,
                 target,
                 &mut notifier as *mut _))
     }
 
     #[cfg(not(feature = "debugmozjs"))]
     pub unsafe fn with_script(cx: *mut JSContext,
                               target: *mut JSScript)
-                              -> AutoCompartment
+                              -> AutoRealm
     {
-        AutoCompartment(JSAutoRealmAllowCCW::new1(cx, target))
+        AutoRealm(JSAutoRealmAllowCCW::new1(cx, target))
     }
 }
--- a/js/rust/src/lib.rs
+++ b/js/rust/src/lib.rs
@@ -18,17 +18,17 @@ extern crate libc;
 extern crate log;
 #[allow(unused_extern_crates)]
 extern crate mozjs_sys;
 extern crate num_traits;
 
 #[macro_use]
 pub mod rust;
 
-pub mod ac;
+pub mod ar;
 pub mod conversions;
 pub mod error;
 pub mod glue;
 pub mod heap;
 pub mod jsval;
 pub mod panic;
 pub mod sc;
 pub mod typedarray;
--- a/js/rust/src/rust.rs
+++ b/js/rust/src/rust.rs
@@ -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/. */
 
 //! Rust wrappers around the raw JS apis
 
-use ac::AutoCompartment;
+use ar::AutoRealm;
 use libc::c_uint;
 use std::cell::{Cell, UnsafeCell};
 use std::char;
 use std::ffi;
 use std::ptr;
 use std::slice;
 use std::mem;
 use std::u32;
@@ -226,17 +226,17 @@ impl Runtime {
         let (ptr, len) = if script_utf16.len() == 0 {
             static empty: &'static [u16] = &[];
             (empty.as_ptr(), 0)
         } else {
             (script_utf16.as_ptr(), script_utf16.len() as c_uint)
         };
         assert!(!ptr.is_null());
         unsafe {
-            let _ac = AutoCompartment::with_obj(self.cx(), glob.get());
+            let _ar = AutoRealm::with_obj(self.cx(), glob.get());
             let options = CompileOptionsWrapper::new(self.cx(), filename_cstr.as_ptr(), line_num);
 
             let mut srcBuf = JS::SourceBufferHolder {
                 data_: ptr,
                 length_: len as _,
                 ownsChars_: false
             };
             if !JS::Evaluate(self.cx(), options.ptr, &mut srcBuf, rval) {
--- a/js/rust/tests/callback.rs
+++ b/js/rust/tests/callback.rs
@@ -1,17 +1,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/. */
 
 #[macro_use]
 extern crate js;
 extern crate libc;
 
-use js::ac::AutoCompartment;
+use js::ar::AutoRealm;
 use js::jsapi::root::JS::CallArgs;
 use js::jsapi::root::JS::RealmOptions;
 use js::jsapi::root::JSContext;
 use js::jsapi::root::JS_DefineFunction;
 use js::jsapi::root::JS_EncodeStringToUTF8;
 use js::jsapi::root::JS_NewGlobalObject;
 use js::jsapi::root::JS_ReportErrorASCII;
 use js::jsapi::root::JS::OnNewGlobalHookOption;
@@ -29,17 +29,17 @@ fn callback() {
     let context = runtime.cx();
     let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook;
     let c_option = RealmOptions::default();
 
     unsafe {
         let global = JS_NewGlobalObject(context, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(), h_option, &c_option);
         rooted!(in(context) let global_root = global);
         let global = global_root.handle();
-        let _ac = AutoCompartment::with_obj(context, global.get());
+        let _ar = AutoRealm::with_obj(context, global.get());
         let function = JS_DefineFunction(context, global, b"puts\0".as_ptr() as *const libc::c_char,
                                          Some(puts), 1, 0);
         assert!(!function.is_null());
         let javascript = "puts('Test Iñtërnâtiônàlizætiøn ┬─┬ノ( º _ ºノ) ');";
         rooted!(in(context) let mut rval = UndefinedValue());
         let _ = runtime.evaluate_script(global, javascript, "test.js", 0, rval.handle_mut());
     }
 }
--- a/js/rust/tests/panic.rs
+++ b/js/rust/tests/panic.rs
@@ -20,17 +20,17 @@ fn panic() {
     let h_option = JS::OnNewGlobalHookOption::FireOnNewGlobalHook;
     let c_option = JS::RealmOptions::default();
 
     unsafe {
         let global = JS_NewGlobalObject(context, &SIMPLE_GLOBAL_CLASS,
                                         ptr::null_mut(), h_option, &c_option);
         rooted!(in(context) let global_root = global);
         let global = global_root.handle();
-        let _ac = js::ac::AutoCompartment::with_obj(context, global.get());
+        let _ar = js::ar::AutoRealm::with_obj(context, global.get());
         let function = JS_DefineFunction(context, global,
                                          b"test\0".as_ptr() as *const _,
                                          Some(test), 0, 0);
         assert!(!function.is_null());
         rooted!(in(context) let mut rval = UndefinedValue());
         let _ = runtime.evaluate_script(global, "test();", "test.js", 0,
                                         rval.handle_mut());
     }
--- a/js/rust/tests/rooting.rs
+++ b/js/rust/tests/rooting.rs
@@ -24,17 +24,17 @@ fn rooting() {
         let h_option = JS::OnNewGlobalHookOption::FireOnNewGlobalHook;
         let c_option = JS::RealmOptions::default();
 
         rooted!(in(cx) let global = JS_NewGlobalObject(cx,
                                                        &SIMPLE_GLOBAL_CLASS,
                                                        ptr::null_mut(),
                                                        h_option,
                                                        &c_option));
-        let _ac = js::ac::AutoCompartment::with_obj(cx, global.get());
+        let _ar = js::ar::AutoRealm::with_obj(cx, global.get());
         rooted!(in(cx) let prototype_proto = JS::GetRealmObjectPrototype(cx));
         rooted!(in(cx) let proto = JS_NewObjectWithUniqueType(cx,
                                                               &CLASS as *const _,
                                                               prototype_proto.handle()));
         define_methods(cx, proto.handle(), &METHODS[..]).unwrap();
     }
 }
 
--- a/js/rust/tests/runtime.rs
+++ b/js/rust/tests/runtime.rs
@@ -19,17 +19,17 @@ fn runtime() {
         let h_option = JS::OnNewGlobalHookOption::FireOnNewGlobalHook;
         let c_option = JS::RealmOptions::default();
 
         rooted!(in(cx) let global = JS_NewGlobalObject(cx,
                                                        &SIMPLE_GLOBAL_CLASS,
                                                        ptr::null_mut(),
                                                        h_option,
                                                        &c_option));
-        let _ac = js::ac::AutoCompartment::with_obj(cx, global.get());
+        let _ar = js::ar::AutoRealm::with_obj(cx, global.get());
         rooted!(in(cx) let _object = JS_NewObject(cx, &CLASS as *const _));
     }
 
     assert!(Runtime::new(false).is_err());
 }
 
 unsafe extern fn finalize(_fop: *mut JSFreeOp, _object: *mut JSObject) {
     assert!(!Runtime::get().is_null());
--- a/js/rust/tests/typedarray.rs
+++ b/js/rust/tests/typedarray.rs
@@ -19,17 +19,17 @@ fn typedarray() {
 
     unsafe {
         rooted!(in(cx) let global =
             JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
                                JS::OnNewGlobalHookOption::FireOnNewGlobalHook,
                                &JS::RealmOptions::default())
         );
 
-        let _ac = js::ac::AutoCompartment::with_obj(cx, global.get());
+        let _ar = js::ar::AutoRealm::with_obj(cx, global.get());
 
         rooted!(in(cx) let mut rval = UndefinedValue());
         assert!(rt.evaluate_script(global.handle(), "new Uint8Array([0, 2, 4])",
                                    "test", 1, rval.handle_mut()).is_ok());
         assert!(rval.is_object());
 
         typedarray!(in(cx) let array: Uint8Array = rval.to_object());
         assert_eq!(array.unwrap().as_slice(), &[0, 2, 4][..]);
@@ -77,15 +77,15 @@ fn typedarray_update_panic() {
 
     unsafe {
         rooted!(in(cx) let global =
             JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
                                JS::OnNewGlobalHookOption::FireOnNewGlobalHook,
                                &JS::RealmOptions::default())
         );
 
-        let _ac = js::ac::AutoCompartment::with_obj(cx, global.get());
+        let _ar = js::ar::AutoRealm::with_obj(cx, global.get());
         rooted!(in(cx) let mut rval = ptr::null_mut());
         let _ = Uint32Array::create(cx, CreateWith::Slice(&[1, 2, 3, 4, 5]), rval.handle_mut());
         typedarray!(in(cx) let mut array: Uint32Array = rval.get());
         array.as_mut().unwrap().update(&[0, 2, 4, 6, 8, 10]);
     }
 }
--- a/js/rust/tests/vec_conversion.rs
+++ b/js/rust/tests/vec_conversion.rs
@@ -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/. */
 
 #[macro_use]
 extern crate js;
 
-use js::ac::AutoCompartment;
+use js::ar::AutoRealm;
 use js::conversions::ConversionBehavior;
 use js::conversions::ConversionResult;
 use js::conversions::FromJSValConvertible;
 use js::conversions::ToJSValConvertible;
 use js::jsapi::root::JS::RealmOptions;
 use js::jsapi::root::JS::InitRealmStandardClasses;
 use js::jsapi::root::JS_NewGlobalObject;
 use js::jsapi::root::JS::OnNewGlobalHookOption;
@@ -37,17 +37,17 @@ fn vec_conversion() {
     let c_option = RealmOptions::default();
 
     unsafe {
         let global = JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS,
                                         ptr::null_mut(), h_option, &c_option);
         rooted!(in(cx) let global_root = global);
         let global = global_root.handle();
 
-        let _ac = AutoCompartment::with_obj(cx, global.get());
+        let _ar = AutoRealm::with_obj(cx, global.get());
         assert!(InitRealmStandardClasses(cx));
 
         rooted!(in(cx) let mut rval = UndefinedValue());
 
         let orig_vec: Vec<f32> = vec![1.0, 2.9, 3.0];
         orig_vec.to_jsval(cx, rval.handle_mut());
         assert_is_array(cx, rval.handle());
         let converted = Vec::<f32>::from_jsval(cx, rval.handle(), ()).unwrap();
--- a/layout/forms/nsNumberControlFrame.cpp
+++ b/layout/forms/nsNumberControlFrame.cpp
@@ -401,16 +401,18 @@ nsNumberControlFrame::CreateAnonymousCon
   }
 
   if (mContent->AsElement()->State().HasState(NS_EVENT_STATE_FOCUS)) {
     // We don't want to focus the frame but the text field.
     RefPtr<FocusTextField> focusJob = new FocusTextField(mContent, mTextField);
     nsContentUtils::AddScriptRunner(focusJob);
   }
 
+  SyncDisabledState(); // Sync disabled state of 'mTextField'.
+
   if (StyleDisplay()->mAppearance == StyleAppearance::Textfield) {
     // The author has elected to hide the spinner by setting this
     // -moz-appearance. We will reframe if it changes.
     return NS_OK;
   }
 
   // Create the ::-moz-number-spin-box pseudo-element:
   mSpinBox = MakeAnonymousElement(mOuterWrapper,
@@ -422,20 +424,16 @@ nsNumberControlFrame::CreateAnonymousCon
                                  nsGkAtoms::div,
                                  CSSPseudoElementType::mozNumberSpinUp);
 
   // Create the ::-moz-number-spin-down pseudo-element:
   mSpinDown = MakeAnonymousElement(mSpinBox,
                                    nsGkAtoms::div,
                                    CSSPseudoElementType::mozNumberSpinDown);
 
-  // FIXME(emilio): doesn't this need to be done in the appearance: textfield
-  // case as well?
-  SyncDisabledState();
-
   return NS_OK;
 }
 
 void
 nsNumberControlFrame::SetFocus(bool aOn, bool aRepaint)
 {
   GetTextFieldFrame()->SetFocus(aOn, aRepaint);
 }
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -40,16 +40,17 @@ args = [
     "-D_CRT_USE_BUILTIN_OFFSETOF",
     # Enable hidden attribute (which is not supported by MSVC and
     # thus not enabled by default with a MSVC-compatibile build)
     # to exclude hidden symbols from the generated file.
     "-DHAVE_VISIBILITY_HIDDEN_ATTRIBUTE=1",
 ]
 "arch=x86" = ["--target=i686-pc-win32"]
 "arch=x86_64" = ["--target=x86_64-pc-win32"]
+"arch=aarch64" = ["--target=aarch64-pc-windows-msvc"]
 
 [structs]
 headers = [
     "nsStyleStruct.h",
     "mozilla/StyleAnimationValue.h",
     "gfxFontConstants.h",
     "gfxFontFeatures.h",
     "nsStyleConsts.h",
--- a/layout/style/ServoCSSPropList.mako.py
+++ b/layout/style/ServoCSSPropList.mako.py
@@ -92,16 +92,18 @@ SERIALIZED_PREDEFINED_TYPES = [
     "Length",
     "LengthOrPercentage",
     "NonNegativeLength",
     "NonNegativeLengthOrPercentage",
     "ListStyleType",
     "OffsetPath",
     "Opacity",
     "Resize",
+    "basic_shape::ClippingShape",
+    "basic_shape::FloatAreaShape",
     "url::ImageUrlOrNone",
 ]
 
 def serialized_by_servo(prop):
     # If the property requires layout information, no such luck.
     if "GETCS_NEEDS_LAYOUT_FLUSH" in prop.flags:
         return False
     # No shorthands yet.
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -691,27 +691,16 @@ static_assert(ArrayLength(nsCSSProps::kF
               ArrayLength(nsCSSProps::kWidthKTable) + 1,
               "kFlexBasisKTable should have the same entries as "
               "kWidthKTable, plus one more for 'content'");
 
 // Specific keyword tables for XUL.properties
 
 // keyword tables for SVG properties
 
-const KTableEntry nsCSSProps::kClipPathGeometryBoxKTable[] = {
-  { eCSSKeyword_content_box, StyleGeometryBox::ContentBox },
-  { eCSSKeyword_padding_box, StyleGeometryBox::PaddingBox },
-  { eCSSKeyword_border_box, StyleGeometryBox::BorderBox },
-  { eCSSKeyword_margin_box, StyleGeometryBox::MarginBox },
-  { eCSSKeyword_fill_box, StyleGeometryBox::FillBox },
-  { eCSSKeyword_stroke_box, StyleGeometryBox::StrokeBox },
-  { eCSSKeyword_view_box, StyleGeometryBox::ViewBox },
-  { eCSSKeyword_UNKNOWN, -1 }
-};
-
 const KTableEntry nsCSSProps::kShapeRadiusKTable[] = {
   { eCSSKeyword_closest_side, StyleShapeRadius::ClosestSide },
   { eCSSKeyword_farthest_side, StyleShapeRadius::FarthestSide },
   { eCSSKeyword_UNKNOWN, -1 }
 };
 
 const KTableEntry nsCSSProps::kFilterFunctionKTable[] = {
   { eCSSKeyword_blur, NS_STYLE_FILTER_BLUR },
@@ -722,24 +711,16 @@ const KTableEntry nsCSSProps::kFilterFun
   { eCSSKeyword_opacity, NS_STYLE_FILTER_OPACITY },
   { eCSSKeyword_saturate, NS_STYLE_FILTER_SATURATE },
   { eCSSKeyword_sepia, NS_STYLE_FILTER_SEPIA },
   { eCSSKeyword_hue_rotate, NS_STYLE_FILTER_HUE_ROTATE },
   { eCSSKeyword_drop_shadow, NS_STYLE_FILTER_DROP_SHADOW },
   { eCSSKeyword_UNKNOWN, -1 }
 };
 
-const KTableEntry nsCSSProps::kShapeOutsideShapeBoxKTable[] = {
-  { eCSSKeyword_content_box, StyleGeometryBox::ContentBox },
-  { eCSSKeyword_padding_box, StyleGeometryBox::PaddingBox },
-  { eCSSKeyword_border_box, StyleGeometryBox::BorderBox },
-  { eCSSKeyword_margin_box, StyleGeometryBox::MarginBox },
-  { eCSSKeyword_UNKNOWN, -1 }
-};
-
 int32_t
 nsCSSProps::FindIndexOfKeyword(nsCSSKeyword aKeyword,
                                const KTableEntry aTable[])
 {
   if (eCSSKeyword_UNKNOWN == aKeyword) {
     // NOTE: we can have keyword tables where eCSSKeyword_UNKNOWN is used
     // not only for the sentinel, but also in the middle of the table to
     // knock out values that have been disabled by prefs, e.g. kDisplayKTable.
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -308,20 +308,18 @@ public:
 
   // Keyword/Enum value tables
   static const KTableEntry kTransformStyleKTable[];
   static const KTableEntry kImageLayerRepeatKTable[];
   // Not const because we modify its entries when the pref
   // "layout.css.background-clip.text" changes:
   static const KTableEntry kBorderImageRepeatKTable[];
   static const KTableEntry kBorderStyleKTable[];
-  static const KTableEntry kClipPathGeometryBoxKTable[];
   static const KTableEntry kShapeRadiusKTable[];
   static const KTableEntry kFilterFunctionKTable[];
-  static const KTableEntry kShapeOutsideShapeBoxKTable[];
   static const KTableEntry kBoxShadowTypeKTable[];
   static const KTableEntry kCursorKTable[];
   // Not const because we modify its entries when various
   // "layout.css.*.enabled" prefs changes:
   static KTableEntry kDisplayKTable[];
   // -- tables for parsing the {align,justify}-{content,items,self} properties --
   static const KTableEntry kAlignAllKeywords[];
   static const KTableEntry kAlignOverflowPosition[]; // <overflow-position>
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -5014,68 +5014,16 @@ nsComputedDOMStyle::CreatePrimitiveValue
 
   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
   val->SetIdent(nsCSSProps::ValueToKeywordEnum(aReferenceBox, aBoxKeywordTable));
   valueList->AppendCSSValue(val.forget());
 
   return valueList.forget();
 }
 
-already_AddRefed<CSSValue>
-nsComputedDOMStyle::GetShapeSource(
-  const StyleShapeSource& aShapeSource,
-  const KTableEntry aBoxKeywordTable[])
-{
-  switch (aShapeSource.GetType()) {
-    case StyleShapeSourceType::Shape:
-      return CreatePrimitiveValueForShapeSource(aShapeSource.GetBasicShape(),
-                                                aShapeSource.GetReferenceBox(),
-                                                aBoxKeywordTable);
-    case StyleShapeSourceType::Box:
-      return CreatePrimitiveValueForShapeSource(nullptr,
-                                                aShapeSource.GetReferenceBox(),
-                                                aBoxKeywordTable);
-    case StyleShapeSourceType::URL: {
-      RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
-      SetValueToURLValue(aShapeSource.GetURL(), val);
-      return val.forget();
-    }
-    case StyleShapeSourceType::None: {
-      RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
-      val->SetIdent(eCSSKeyword_none);
-      return val.forget();
-    }
-    case StyleShapeSourceType::Image: {
-      RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
-      SetValueToStyleImage(*aShapeSource.GetShapeImage(), val);
-      return val.forget();
-    }
-    case StyleShapeSourceType::Path: {
-      // Bug 1246764: we have to support this for clip-path. For now, no one
-      // uses this.
-      MOZ_ASSERT_UNREACHABLE("Unexpected SVG Path type.");
-    }
-  }
-  return nullptr;
-}
-
-already_AddRefed<CSSValue>
-nsComputedDOMStyle::DoGetClipPath()
-{
-  return GetShapeSource(StyleSVGReset()->mClipPath,
-                        nsCSSProps::kClipPathGeometryBoxKTable);
-}
-
-already_AddRefed<CSSValue>
-nsComputedDOMStyle::DoGetShapeOutside()
-{
-  return GetShapeSource(StyleDisplay()->mShapeOutside,
-                        nsCSSProps::kShapeOutsideShapeBoxKTable);
-}
-
 void
 nsComputedDOMStyle::SetCssTextToCoord(nsAString& aCssText,
                                       const nsStyleCoord& aCoord,
                                       bool aClampNegativeCalc)
 {
   RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
   SetValueToCoord(value, aCoord, aClampNegativeCalc);
   value->GetCssText(aCssText);
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -409,17 +409,16 @@ private:
   already_AddRefed<CSSValue> DoGetScrollSnapTypeX();
   already_AddRefed<CSSValue> DoGetScrollSnapTypeY();
   already_AddRefed<CSSValue> DoGetScrollSnapPointsX();
   already_AddRefed<CSSValue> DoGetScrollSnapPointsY();
   already_AddRefed<CSSValue> DoGetScrollSnapDestination();
   already_AddRefed<CSSValue> DoGetScrollSnapCoordinate();
   already_AddRefed<CSSValue> DoGetScrollbarFaceColor();
   already_AddRefed<CSSValue> DoGetScrollbarTrackColor();
-  already_AddRefed<CSSValue> DoGetShapeOutside();
 
   /* User interface properties */
   already_AddRefed<CSSValue> DoGetCaretColor();
   already_AddRefed<CSSValue> DoGetCursor();
   already_AddRefed<CSSValue> DoGetForceBrokenImageIcon();
 
   /* Column properties */
   already_AddRefed<CSSValue> DoGetColumnCount();
@@ -469,17 +468,16 @@ private:
 
   already_AddRefed<CSSValue> DoGetFillOpacity();
   already_AddRefed<CSSValue> DoGetStrokeMiterlimit();
   already_AddRefed<CSSValue> DoGetStrokeOpacity();
 
 
 
 
-  already_AddRefed<CSSValue> DoGetClipPath();
   already_AddRefed<CSSValue> DoGetFilter();
   already_AddRefed<CSSValue> DoGetPaintOrder();
 
 
   // For working around a MSVC bug. See related comment in
   // GenerateComputedDOMStyleGenerated.py.
   already_AddRefed<CSSValue> DummyGetter();
 
@@ -554,20 +552,16 @@ private:
   bool GetFrameBorderRectHeight(nscoord& aHeight);
 
   /* Helper functions for computing and serializing a nsStyleCoord. */
   void SetCssTextToCoord(nsAString& aCssText, const nsStyleCoord& aCoord,
                          bool aClampNegativeCalc);
   already_AddRefed<CSSValue> CreatePrimitiveValueForStyleFilter(
     const nsStyleFilter& aStyleFilter);
 
-  already_AddRefed<CSSValue>
-  GetShapeSource(const mozilla::StyleShapeSource& aShapeSource,
-                 const KTableEntry aBoxKeywordTable[]);
-
   template<typename ReferenceBox>
   already_AddRefed<CSSValue>
   CreatePrimitiveValueForShapeSource(
     const mozilla::UniquePtr<mozilla::StyleBasicShape>& aStyleBasicShape,
     ReferenceBox aReferenceBox,
     const KTableEntry aBoxKeywordTable[]);
 
   // Helper function for computing basic shape styles.
--- a/layout/style/test/test_transitions_per_property.html
+++ b/layout/style/test/test_transitions_per_property.html
@@ -724,26 +724,26 @@ const basicShapesTests = [
   },
   { start: "inset(100% 100% 100% 100% round 100% 100%) border-box",
     end: "inset(500% 500% 500% 500% round 500% 500%) border-box",
     expected: ["inset", ["200% round 200%"], "border-box"] },
   // matching functions with calc() values
   { start: "circle(calc(80px + 20px))", end: "circle(calc(200px + 300px))",
     expected: ["circle", ["200px at 50% 50%"]] },
   { start: "circle(calc(80% + 20%))", end: "circle(calc(200% + 300%))",
-    expected: ["circle", ["calc(0px + 200%) at 50% 50%"]] },
+    expected: ["circle", ["200% at 50% 50%"]] },
   { start: "circle(calc(10px + 20%))", end: "circle(calc(50px + 40%))",
-    expected: ["circle", ["calc(20px + 25%) at 50% 50%"]] },
+    expected: ["circle", ["calc(25% + 20px) at 50% 50%"]] },
   // matching functions with interpolation between percentage/pixel values
   { start: "circle(20px)", end: "circle(100%)",
-    expected: ["circle", ["calc(15px + 25%) at 50% 50%"]] },
+    expected: ["circle", ["calc(25% + 15px) at 50% 50%"]] },
   { start: "ellipse(100% 100px at 8px 20%) border-box",
     end:   "ellipse(40px 4%    at 80% 60px) border-box",
-    expected: ["ellipse", ["calc(10px + 75%) calc(75px + 1%) at " +
-                           "calc(6px + 20%) calc(15px + 15%)"],
+    expected: ["ellipse", ["calc(75% + 10px) calc(1% + 75px) at " +
+                           "calc(20% + 6px) calc(15% + 15px)"],
                "border-box"] },
   // no interpolation for keywords
   { start: "circle()", end: "circle(50px)",
     expected: ["circle", ["50px at 50% 50%"]] },
   { start: "circle(closest-side)", end: "circle(500px)",
     expected: ["circle", ["500px at 50% 50%"]] },
   { start: "circle(farthest-side)", end: "circle(500px)",
     expected: ["circle", ["500px at 50% 50%"]] },
@@ -757,17 +757,17 @@ const basicShapesTests = [
     expected: ["ellipse", ["500px 500px at 50% 50%"]] },
   { start: "ellipse(farthest-side closest-side)", end: "ellipse(500px 500px)",
     expected: ["ellipse", ["500px 500px at 50% 50%"]] },
   { start: "ellipse(farthest-side farthest-side)", end: "ellipse(500px 500px)",
     expected: ["ellipse", ["500px 500px at 50% 50%"]] },
   { start: "ellipse(500px 500px)", end: "ellipse(farthest-side farthest-side)",
     expected: ["ellipse", ["farthest-side farthest-side at 50% 50%"]] },
   { start: "ellipse(500px 500px)", end: "ellipse(closest-side closest-side)",
-    expected: ["ellipse", ["closest-side closest-side at 50% 50%"]] },
+    expected: ["ellipse", ["at 50% 50%"]] },
   // mismatching boxes
   { start: "circle(100px at 100px 100px) border-box",
     end: "circle(500px at 500px 500px) content-box",
     expected: ["circle", ["500px at 500px 500px"], "content-box"]
   },
   { start: "ellipse(100px 100px at 100px 100px) border-box",
     end: "ellipse(500px 500px at 500px 500px) content-box",
     expected: ["ellipse", ["500px 500px at 500px 500px"], "content-box"]
--- a/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
+++ b/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
@@ -623,18 +623,20 @@ public class CustomTabsActivity extends 
     }
 
     @Override
     public GeckoResult<GeckoSession> onNewSession(final GeckoSession session, final String uri) {
         // We should never get here because we abort loads that need a new session in onLoadRequest()
         throw new IllegalStateException("Unexpected new session");
     }
 
-    public void onLoadError(final GeckoSession session, final String urlStr,
-                            final int category, final int error) {
+    @Override
+    public GeckoResult<String> onLoadError(final GeckoSession session, final String urlStr,
+                                           final int category, final int error) {
+        return null;
     }
 
     /* GeckoSession.ProgressDelegate */
     @Override
     public void onPageStart(GeckoSession session, String url) {
         mCurrentUrl = url;
         mCanStop = true;
         updateActionBar();
--- a/mobile/android/base/java/org/mozilla/gecko/webapps/WebAppActivity.java
+++ b/mobile/android/base/java/org/mozilla/gecko/webapps/WebAppActivity.java
@@ -419,18 +419,20 @@ public class WebAppActivity extends AppC
     }
 
     @Override
     public GeckoResult<GeckoSession> onNewSession(final GeckoSession session, final String uri) {
         // We should never get here because we abort loads that need a new session in onLoadRequest()
         throw new IllegalStateException("Unexpected new session");
     }
 
-    public void onLoadError(final GeckoSession session, final String urlStr,
-                            final int category, final int error) {
+    @Override
+    public GeckoResult<String> onLoadError(final GeckoSession session, final String urlStr,
+                                           final int category, final int error) {
+        return null;
     }
 
     private void updateFullScreen() {
         boolean fullScreen = mIsFullScreenContent || mIsFullScreenMode;
         if (ActivityUtils.isFullScreen(this) == fullScreen) {
             return;
         }
 
--- a/mobile/android/chrome/geckoview/GeckoViewNavigationContent.js
+++ b/mobile/android/chrome/geckoview/GeckoViewNavigationContent.js
@@ -9,56 +9,47 @@ ChromeUtils.import("resource://gre/modul
 XPCOMUtils.defineLazyModuleGetters(this, {
   ErrorPageEventHandler: "chrome://geckoview/content/ErrorPageEventHandler.js",
   LoadURIDelegate: "resource://gre/modules/LoadURIDelegate.jsm",
 });
 
 // Implements nsILoadURIDelegate.
 class GeckoViewNavigationContent extends GeckoViewContentModule {
   onInit() {
-    this.onEnable();
-  }
-
-  onEnable() {
-    debug `onEnable`;
-
     docShell.loadURIDelegate = this;
   }
 
-  onDisable() {
-    debug `onDisable`;
-
-    docShell.loadURIDelegate = null;
-  }
-
   // nsILoadURIDelegate.
   loadURI(aUri, aWhere, aFlags, aTriggeringPrincipal) {
     debug `loadURI: uri=${aUri && aUri.spec}
                     where=${aWhere} flags=${aFlags}`;
 
+    if (!this.enabled) {
+      return Promise.resolve(false);
+    }
+
     // TODO: Remove this when we have a sensible error API.
     if (aUri && aUri.displaySpec.startsWith("about:certerror")) {
       addEventListener("click", ErrorPageEventHandler, true);
     }
 
     return LoadURIDelegate.load(content, this.eventDispatcher,
                                 aUri, aWhere, aFlags);
   }
 
   // nsILoadURIDelegate.
   handleLoadError(aUri, aError, aErrorModule) {
     debug `handleLoadError: uri=${aUri && aUri.spec}
                              uri2=${aUri && aUri.displaySpec}
                              error=${aError}`;
 
-    const handled = LoadURIDelegate.handleLoadError(content, this.eventDispatcher,
-                                                    aUri, aError, aErrorModule);
-    this.eventDispatcher.sendRequest({
-      type: "GeckoView:PageStop",
-      sucess: false,
-    });
+    if (!this.enabled) {
+      Components.returnCode = Cr.NS_ERROR_ABORT;
+      return null;
+    }
 
-    return handled;
+    return LoadURIDelegate.handleLoadError(content, this.eventDispatcher,
+                                           aUri, aError, aErrorModule);
   }
 }
 
 let {debug, warn} = GeckoViewNavigationContent.initLogging("GeckoViewNavigation");
 let module = GeckoViewNavigationContent.create(this);
--- a/mobile/android/chrome/geckoview/geckoview.js
+++ b/mobile/android/chrome/geckoview/geckoview.js
@@ -321,18 +321,16 @@ function startup() {
     onInit: {
       resource: "resource://gre/modules/GeckoViewContent.jsm",
       frameScript: "chrome://geckoview/content/GeckoViewContent.js",
     },
   }, {
     name: "GeckoViewNavigation",
     onInit: {
       resource: "resource://gre/modules/GeckoViewNavigation.jsm",
-    },
-    onEnable: {
       frameScript: "chrome://geckoview/content/GeckoViewNavigationContent.js",
     },
   }, {
     name: "GeckoViewProgress",
     onEnable: {
       resource: "resource://gre/modules/GeckoViewProgress.jsm",
       frameScript: "chrome://geckoview/content/GeckoViewProgressContent.js",
     },
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
@@ -27,17 +27,18 @@ open class BaseSessionTest(noErrorCollec
     companion object {
         const val CLICK_TO_RELOAD_HTML_PATH = "/assets/www/clickToReload.html"
         const val CONTENT_CRASH_URL = "about:crashcontent"
         const val DOWNLOAD_HTML_PATH = "/assets/www/download.html"
         const val FORMS_HTML_PATH = "/assets/www/forms.html"
         const val HELLO_HTML_PATH = "/assets/www/hello.html"
         const val HELLO2_HTML_PATH = "/assets/www/hello2.html"
         const val INPUTS_PATH = "/assets/www/inputs.html"
-        const val INVALID_URI = "http://www.test.invalid/"
+        const val UNKNOWN_HOST_URI = "http://www.test.invalid/"
+        const val INVALID_URI = "not a valid uri"
         const val LOREM_IPSUM_HTML_PATH = "/assets/www/loremIpsum.html"
         const val NEW_SESSION_HTML_PATH = "/assets/www/newSession.html"
         const val NEW_SESSION_CHILD_HTML_PATH = "/assets/www/newSession_child.html"
         const val SAVE_STATE_PATH = "/assets/www/saveState.html"
         const val TITLE_CHANGE_HTML_PATH = "/assets/www/titleChange.html"
         const val TRACKERS_PATH = "/assets/www/trackers.html"
     }
 
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt
@@ -15,71 +15,161 @@ import org.mozilla.geckoview.test.rule.G
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.Setting
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.WithDevToolsAPI
 import org.mozilla.geckoview.test.util.Callbacks
 
 import android.support.test.filters.MediumTest
 import android.support.test.runner.AndroidJUnit4
 import org.hamcrest.Matchers.*
 import org.junit.Assume.assumeThat
-import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @RunWith(AndroidJUnit4::class)
 @MediumTest
 @ReuseSession(false)
 class NavigationDelegateTest : BaseSessionTest() {
 
-    fun loadExpectError(testUri: String, expectedCategory: Int,
-                        expectedError: Int) {
+    fun testLoadErrorWithErrorPage(testUri: String, expectedCategory: Int,
+                                   expectedError: Int,
+                                   errorPageUrl: String?) {
+        sessionRule.delegateDuringNextWait(
+                object : Callbacks.ProgressDelegate, Callbacks.NavigationDelegate, Callbacks.ContentDelegate {
+                    @AssertCalled(count = 1, order = [1])
+                    override fun onLoadRequest(session: GeckoSession, uri: String,
+                                               where: Int, flags: Int): GeckoResult<Boolean>? {
+                        assertThat("URI should be " + testUri, uri, equalTo(testUri))
+                        return null
+                    }
+
+                    @AssertCalled(count = 1, order = [2])
+                    override fun onPageStart(session: GeckoSession, url: String) {
+                        assertThat("URI should be " + testUri, url, equalTo(testUri))
+                    }
+
+                    @AssertCalled(count = 1, order = [3])
+                    override fun onLoadError(session: GeckoSession, uri: String?,
+                                             category: Int, error: Int): GeckoResult<String>? {
+                        assertThat("Error category should match", category,
+                                equalTo(expectedCategory))
+                        assertThat("Error should match", error,
+                                equalTo(expectedError))
+                        return GeckoResult.fromValue(errorPageUrl)
+                    }
+
+                    @AssertCalled(count = 1, order = [4])
+                    override fun onPageStop(session: GeckoSession, success: Boolean) {
+                        assertThat("Load should fail", success, equalTo(false))
+                    }
+                })
+
         sessionRule.session.loadUri(testUri);
         sessionRule.waitForPageStop()
 
-        sessionRule.forCallbacksDuringWait(
-            object : Callbacks.ProgressDelegate, Callbacks.NavigationDelegate {
-            @AssertCalled(count = 1, order = [1])
-            override fun onLoadRequest(session: GeckoSession, uri: String,
-                                       where: Int, flags: Int): GeckoResult<Boolean>? {
-                assertThat("URI should be " + testUri, uri, equalTo(testUri))
-                return null
-            }
+        if (errorPageUrl != null) {
+            sessionRule.waitUntilCalled(object : Callbacks.ContentDelegate, Callbacks.NavigationDelegate {
+                @AssertCalled(count = 1, order = [1])
+                override fun onLocationChange(session: GeckoSession, url: String) {
+                    assertThat("URL should match", url, equalTo(testUri))
+                }
+
+                @AssertCalled(count = 1, order = [2])
+                override fun onTitleChange(session: GeckoSession, title: String) {
+                    assertThat("Title should not be empty", title, not(isEmptyOrNullString()))
+                }
+            })
+        }
+    }
+
+    fun testLoadExpectError(testUri: String, expectedCategory: Int,
+                            expectedError: Int) {
+        testLoadErrorWithErrorPage(testUri, expectedCategory,
+                expectedError, createTestUrl(HELLO_HTML_PATH))
+        testLoadErrorWithErrorPage(testUri, expectedCategory,
+                expectedError, null)
+    }
+
+    fun testLoadEarlyErrorWithErrorPage(testUri: String, expectedCategory: Int,
+                                        expectedError: Int,
+                                        errorPageUrl: String?) {
+        sessionRule.delegateDuringNextWait(
+                object : Callbacks.ProgressDelegate, Callbacks.NavigationDelegate, Callbacks.ContentDelegate {
 
-            @AssertCalled(count = 1, order = [2])
-            override fun onLoadError(session: GeckoSession, uri: String,
-                                     category: Int, error: Int) {
-                assertThat("Error category should match", category,
-                           equalTo(expectedCategory))
-                assertThat("Error should match", error,
-                           equalTo(expectedError))
-            }
+                    @AssertCalled(false)
+                    override fun onPageStart(session: GeckoSession, url: String) {
+                        assertThat("URI should be " + testUri, url, equalTo(testUri))
+                    }
+
+                    @AssertCalled(count = 1, order = [1])
+                    override fun onLoadError(session: GeckoSession, uri: String?,
+                                             category: Int, error: Int): GeckoResult<String>? {
+                        assertThat("Error category should match", category,
+                                equalTo(expectedCategory))
+                        assertThat("Error should match", error,
+                                equalTo(expectedError))
+                        return GeckoResult.fromValue(errorPageUrl)
+                    }
 
-            @AssertCalled(count = 1, order = [3])
-            override fun onPageStop(session: GeckoSession, success: Boolean) {
-                assertThat("Load should fail", success, equalTo(false))
-            }
-        })
+                    @AssertCalled(false)
+                    override fun onPageStop(session: GeckoSession, success: Boolean) {
+                    }
+                })
+
+        sessionRule.session.loadUri(testUri)
+        sessionRule.waitUntilCalled(Callbacks.NavigationDelegate::class, "onLoadError")
+
+        if (errorPageUrl != null) {
+            sessionRule.waitUntilCalled(object: Callbacks.ContentDelegate {
+                @AssertCalled(count = 1)
+                override fun onTitleChange(session: GeckoSession, title: String) {
+                    assertThat("Title should not be empty", title, not(isEmptyOrNullString()));
+                }
+            })
+        }
+    }
+
+    fun testLoadEarlyError(testUri: String, expectedCategory: Int,
+                           expectedError: Int) {
+        testLoadEarlyErrorWithErrorPage(testUri, expectedCategory, expectedError, createTestUrl(HELLO_HTML_PATH))
+        testLoadEarlyErrorWithErrorPage(testUri, expectedCategory, expectedError, null)
     }
 
     @Test fun loadFileNotFound() {
-        loadExpectError("file:///test.mozilla",
-                        GeckoSession.NavigationDelegate.ERROR_CATEGORY_URI,
-                        GeckoSession.NavigationDelegate.ERROR_FILE_NOT_FOUND)
+        testLoadExpectError("file:///test.mozilla",
+                GeckoSession.NavigationDelegate.ERROR_CATEGORY_URI,
+                GeckoSession.NavigationDelegate.ERROR_FILE_NOT_FOUND)
     }
 
     @Test fun loadUnknownHost() {
-        loadExpectError(INVALID_URI,
-                        GeckoSession.NavigationDelegate.ERROR_CATEGORY_URI,
-                        GeckoSession.NavigationDelegate.ERROR_UNKNOWN_HOST)
+        testLoadExpectError(UNKNOWN_HOST_URI,
+                GeckoSession.NavigationDelegate.ERROR_CATEGORY_URI,
+                GeckoSession.NavigationDelegate.ERROR_UNKNOWN_HOST)
+    }
+
+    @Test fun loadInvalidUri() {
+        testLoadEarlyError(INVALID_URI,
+                GeckoSession.NavigationDelegate.ERROR_CATEGORY_URI,
+                GeckoSession.NavigationDelegate.ERROR_MALFORMED_URI)
     }
 
     @Test fun loadBadPort() {
-        loadExpectError("http://localhost:1/",
-                        GeckoSession.NavigationDelegate.ERROR_CATEGORY_NETWORK,
-                        GeckoSession.NavigationDelegate.ERROR_PORT_BLOCKED)
+        testLoadEarlyError("http://localhost:1/",
+                GeckoSession.NavigationDelegate.ERROR_CATEGORY_NETWORK,
+                GeckoSession.NavigationDelegate.ERROR_PORT_BLOCKED)
+    }
+
+    @Test fun loadUntrusted() {
+        val uri = if (sessionRule.env.isAutomation) {
+            "https://expired.example.com/"
+        } else {
+            "https://expired.badssl.com/"
+        }
+        testLoadExpectError(uri,
+                GeckoSession.NavigationDelegate.ERROR_CATEGORY_SECURITY,
+                GeckoSession.NavigationDelegate.ERROR_SECURITY_BAD_CERT);
     }
 
     @Setting(key = Setting.Key.USE_TRACKING_PROTECTION, value = "true")
     @Test fun trackingProtectionBasic() {
         val category = TrackingProtectionDelegate.CATEGORY_TEST;
         sessionRule.runtime.settings.trackingProtectionCategories = category
         sessionRule.session.loadTestPath(TRACKERS_PATH)
 
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressDelegateTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressDelegateTest.kt
@@ -75,25 +75,25 @@ class ProgressDelegateTest : BaseSession
             override fun onPageStop(session: GeckoSession, success: Boolean) {
                 assertThat("Session should not be null", session, notNullValue())
                 assertThat("Load should succeed", success, equalTo(true))
             }
         })
     }
 
     @Test fun multipleLoads() {
-        sessionRule.session.loadUri(INVALID_URI)
+        sessionRule.session.loadUri(UNKNOWN_HOST_URI)
         sessionRule.session.loadTestPath(HELLO_HTML_PATH)
         sessionRule.waitForPageStops(2)
 
         sessionRule.forCallbacksDuringWait(object : Callbacks.ProgressDelegate {
             @AssertCalled(count = 2, order = [1, 3])
             override fun onPageStart(session: GeckoSession, url: String) {
                 assertThat("URL should match", url,
-                           endsWith(forEachCall(INVALID_URI, HELLO_HTML_PATH)))
+                           endsWith(forEachCall(UNKNOWN_HOST_URI, HELLO_HTML_PATH)))
             }
 
             @AssertCalled(count = 2, order = [2, 4])
             override fun onPageStop(session: GeckoSession, success: Boolean) {
                 // The first load is certain to fail because of interruption by the second load
                 // or by invalid domain name, whereas the second load is certain to succeed.
                 assertThat("Success flag should match", success,
                            equalTo(forEachCall(false, true)))
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestRunnerActivity.java
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestRunnerActivity.java
@@ -58,18 +58,18 @@ public class TestRunnerActivity extends 
         }
 
         @Override
         public GeckoResult<GeckoSession> onNewSession(GeckoSession session, String uri) {
             return GeckoResult.fromValue(createBackgroundSession(session.getSettings()));
         }
 
         @Override
-        public void onLoadError(GeckoSession session, String uri, int category, int error) {
-
+        public GeckoResult<String> onLoadError(GeckoSession session, String uri, int category, int error) {
+            return null;
         }
     };
 
     private GeckoSession.ContentDelegate mContentDelegate = new GeckoSession.ContentDelegate() {
         @Override
         public void onTitleChange(GeckoSession session, String title) {
 
         }
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/util/Callbacks.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/util/Callbacks.kt
@@ -57,18 +57,19 @@ class Callbacks private constructor() {
                                    flags: Int): GeckoResult<Boolean>? {
             return null
         }
 
         override fun onNewSession(session: GeckoSession, uri: String): GeckoResult<GeckoSession>? {
             return null
         }
 
-        override fun onLoadError(session: GeckoSession, uri: String,
-                                 category: Int, error: Int) {
+        override fun onLoadError(session: GeckoSession, uri: String?,
+                                 category: Int, error: Int): GeckoResult<String>? {
+            return null
         }
     }
 
     interface PermissionDelegate : GeckoSession.PermissionDelegate {
         override fun onAndroidPermissionsRequest(session: GeckoSession, permissions: Array<out String>, callback: GeckoSession.PermissionDelegate.Callback) {
             callback.reject()
         }
 
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
@@ -340,19 +340,47 @@ public class GeckoSession extends LayerS
                     final String uri = message.getString("uri");
                     final long errorCode = message.getLong("error");
                     final int errorModule = message.getInt("errorModule");
                     final int errorClass = message.getInt("errorClass");
                     final int error = convertGeckoError(errorCode, errorModule,
                                                         errorClass);
                     final int errorCat = getErrorCategory(errorModule, error);
 
-                    delegate.onLoadError(GeckoSession.this, uri, errorCat, error);
-
-                    callback.sendSuccess(!GeckoAppShell.isFennec());
+                    final GeckoResult<String> result = delegate.onLoadError(GeckoSession.this, uri, errorCat, error);
+                    if (result == null) {
+                        if (GeckoAppShell.isFennec()) {
+                            callback.sendSuccess(null);
+                        } else {
+                            callback.sendError("abort");
+                        }
+                        return;
+                    }
+
+                    result.then(new GeckoResult.OnValueListener<String, Void>() {
+                                    @Override
+                                    public GeckoResult<Void> onValue(@Nullable String url) throws Throwable {
+                                        if (url == null) {
+                                            if (GeckoAppShell.isFennec()) {
+                                                callback.sendSuccess(null);
+                                            } else {
+                                                callback.sendError("abort");
+                                            }
+                                        } else {
+                                            callback.sendSuccess(url);
+                                        }
+                                        return null;
+                                    }
+                                }, new GeckoResult.OnExceptionListener<Void>() {
+                                    @Override
+                                    public GeckoResult<Void> onException(@NonNull Throwable exception) throws Throwable {
+                                        callback.sendError(exception.getMessage());
+                                        return null;
+                                    }
+                                });
                 } else if ("GeckoView:OnNewSession".equals(event)) {
                     final String uri = message.getString("uri");
                     final GeckoResult<GeckoSession> result = delegate.onNewSession(GeckoSession.this, uri);
                     if (result == null) {
                         callback.sendSuccess(null);
                         return;
                     }
 
@@ -2481,20 +2509,21 @@ public class GeckoSession extends LayerS
         public static final int ERROR_SAFEBROWSING_HARMFUL_URI = 0x47;
         public static final int ERROR_SAFEBROWSING_PHISHING_URI = 0x57;
 
         /**
          * @param session The GeckoSession that initiated the callback.
          * @param uri The URI that failed to load.
          * @param category The error category.
          * @param error The error type.
+         * @return A URI to display as an error. Returning null will halt the load entirely.
          */
-        void onLoadError(GeckoSession session, String uri,
-                         @LoadErrorCategory int category,
-                         @LoadError int error);
+        GeckoResult<String> onLoadError(GeckoSession session, String uri,
+                                        @LoadErrorCategory int category,
+                                        @LoadError int error);
     }
 
     /**
      * GeckoSession applications implement this interface to handle prompts triggered by
      * content in the GeckoSession, such as alerts, authentication dialogs, and select list
      * pickers.
      **/
     public interface PromptDelegate {
new file mode 100644
--- /dev/null
+++ b/mobile/android/geckoview_example/src/main/assets/error.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Boom!</title>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
+    <style>
+        body {
+            background-color: red;
+            color: white;
+            font-family: sans;
+        }
+
+        div.container {
+            width: 75%;
+            margin: auto;
+            text-align: center;
+        }
+    </style>
+</head>
+<body>
+    <div class="container">
+        <h1>Boom!</h1>
+        <p>Something bad happened...</p>
+        <p>$ERROR</p>
+    </div>
+</body>
+</html>
\ No newline at end of file
--- a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
+++ b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
@@ -33,16 +33,20 @@ import android.support.v7.widget.Toolbar
 import android.util.Log;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.ProgressBar;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.util.LinkedList;
 import java.util.Locale;
 
 public class GeckoViewActivity extends AppCompatActivity {
     private static final String LOGTAG = "GeckoViewActivity";
     private static final String DEFAULT_URL = "https://mozilla.org";
     private static final String USE_MULTIPROCESS_EXTRA = "use_multiprocess";
     private static final String SEARCH_URI_BASE = "https://www.google.com/search?q=";
@@ -340,16 +344,58 @@ public class GeckoViewActivity extends A
         DownloadManager manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
         DownloadManager.Request req = new DownloadManager.Request(uri);
         req.setMimeType(response.contentType);
         req.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
         req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
         manager.enqueue(req);
     }
 
+    private String mErrorTemplate;
+    private String createErrorPage(final String error) {
+        if (mErrorTemplate == null) {
+            InputStream stream = null;
+            BufferedReader reader = null;
+            StringBuilder builder = new StringBuilder();
+            try {
+                stream = getResources().getAssets().open("error.html");
+                reader = new BufferedReader(new InputStreamReader(stream));
+
+                String line;
+                while ((line = reader.readLine()) != null) {
+                    builder.append(line);
+                    builder.append("\n");
+                }
+
+                mErrorTemplate = builder.toString();
+            } catch (IOException e) {
+                Log.d(LOGTAG, "Failed to open error page template", e);
+                return null;
+            } finally {
+                if (stream != null) {
+                    try {
+                        stream.close();
+                    } catch (IOException e) {
+                        Log.e(LOGTAG, "Failed to close error page template stream", e);
+                    }
+                }
+
+                if (reader != null) {
+                    try {
+                        reader.close();
+                    } catch (IOException e) {
+                        Log.e(LOGTAG, "Failed to close error page template reader", e);
+                    }
+                }
+            }
+        }
+
+        return mErrorTemplate.replace("$ERROR", error);
+    }
+
     private class ExampleContentDelegate implements GeckoSession.ContentDelegate {
         @Override
         public void onTitleChange(GeckoSession session, String title) {
             Log.i(LOGTAG, "Content title changed to " + title);
         }
 
         @Override
         public void onFullScreen(final GeckoSession session, final boolean fullScreen) {
@@ -586,21 +632,145 @@ public class GeckoViewActivity extends A
             intent.setData(Uri.parse(uri));
             intent.putExtra("session", newSession);
 
             startActivity(intent);
 
             return GeckoResult.fromValue(newSession);
         }
 
-        public void onLoadError(final GeckoSession session, final String uri,
-                                final int category, final int error) {
+        private String categoryToString(final int category) {
+            switch (category) {
+                case ERROR_CATEGORY_UNKNOWN:
+                    return "ERROR_CATEGORY_UNKNOWN";
+                case ERROR_CATEGORY_SECURITY:
+                    return "ERROR_CATEGORY_SECURITY";
+                case ERROR_CATEGORY_NETWORK:
+                    return "ERROR_CATEGORY_NETWORK";
+                case ERROR_CATEGORY_CONTENT:
+                    return "ERROR_CATEGORY_CONTENT";
+                case ERROR_CATEGORY_URI:
+                    return "ERROR_CATEGORY_URI";
+                case ERROR_CATEGORY_PROXY:
+                    return "ERROR_CATEGORY_PROXY";
+                case ERROR_CATEGORY_SAFEBROWSING:
+                    return "ERROR_CATEGORY_SAFEBROWSING";
+                default:
+                    return "UNKNOWN";
+            }
+        }
+
+        private String errorToString(final int error) {
+            switch (error) {
+                case ERROR_UNKNOWN:
+                    return "ERROR_UNKNOWN";
+                case ERROR_SECURITY_SSL:
+                    return "ERROR_SECURITY_SSL";
+                case ERROR_SECURITY_BAD_CERT:
+                    return "ERROR_SECURITY_BAD_CERT";
+                case ERROR_NET_RESET:
+                    return "ERROR_NET_RESET";
+                case ERROR_NET_INTERRUPT:
+                    return "ERROR_NET_INTERRUPT";
+                case ERROR_NET_TIMEOUT:
+                    return "ERROR_NET_TIMEOUT";
+                case ERROR_CONNECTION_REFUSED:
+                    return "ERROR_CONNECTION_REFUSED";
+                case ERROR_UNKNOWN_PROTOCOL:
+                    return "ERROR_UNKNOWN_PROTOCOL";
+                case ERROR_UNKNOWN_HOST:
+                    return "ERROR_UNKNOWN_HOST";
+                case ERROR_UNKNOWN_SOCKET_TYPE:
+                    return "ERROR_UNKNOWN_SOCKET_TYPE";
+                case ERROR_UNKNOWN_PROXY_HOST:
+                    return "ERROR_UNKNOWN_PROXY_HOST";
+                case ERROR_MALFORMED_URI:
+                    return "ERROR_MALFORMED_URI";
+                case ERROR_REDIRECT_LOOP:
+                    return "ERROR_REDIRECT_LOOP";
+                case ERROR_SAFEBROWSING_PHISHING_URI:
+                    return "ERROR_SAFEBROWSING_PHISHING_URI";
+                case ERROR_SAFEBROWSING_MALWARE_URI:
+                    return "ERROR_SAFEBROWSING_MALWARE_URI";
+                case ERROR_SAFEBROWSING_UNWANTED_URI:
+                    return "ERROR_SAFEBROWSING_UNWANTED_URI";
+                case ERROR_SAFEBROWSING_HARMFUL_URI:
+                    return "ERROR_SAFEBROWSING_HARMFUL_URI";
+                case ERROR_CONTENT_CRASHED:
+                    return "ERROR_CONTENT_CRASHED";
+                case ERROR_OFFLINE:
+                    return "ERROR_OFFLINE";
+                case ERROR_PORT_BLOCKED:
+                    return "ERROR_PORT_BLOCKED";
+                case ERROR_PROXY_CONNECTION_REFUSED:
+                    return "ERROR_PROXY_CONNECTION_REFUSED";
+                case ERROR_FILE_NOT_FOUND:
+                    return "ERROR_FILE_NOT_FOUND";
+                case ERROR_FILE_ACCESS_DENIED:
+                    return "ERROR_FILE_ACCESS_DENIED";
+                case ERROR_INVALID_CONTENT_ENCODING:
+                    return "ERROR_INVALID_CONTENT_ENCODING";
+                case ERROR_UNSAFE_CONTENT_TYPE:
+                    return "ERROR_UNSAFE_CONTENT_TYPE";
+                case ERROR_CORRUPTED_CONTENT:
+                    return "ERROR_CORRUPTED_CONTENT";
+                default:
+                    return "UNKNOWN";
+            }
+        }
+
+        private String createErrorPage(final int category, final int error) {
+            if (mErrorTemplate == null) {
+                InputStream stream = null;
+                BufferedReader reader = null;
+                StringBuilder builder = new StringBuilder();
+                try {
+                    stream = getResources().getAssets().open("error.html");
+                    reader = new BufferedReader(new InputStreamReader(stream));
+
+                    String line;
+                    while ((line = reader.readLine()) != null) {
+                        builder.append(line);
+                        builder.append("\n");
+                    }
+
+                    mErrorTemplate = builder.toString();
+                } catch (IOException e) {
+                    Log.d(LOGTAG, "Failed to open error page template", e);
+                    return null;
+                } finally {
+                    if (stream != null) {
+                        try {
+                            stream.close();
+                        } catch (IOException e) {
+                            Log.e(LOGTAG, "Failed to close error page template stream", e);
+                        }
+                    }
+
+                    if (reader != null) {
+                        try {
+                            reader.close();
+                        } catch (IOException e) {
+                            Log.e(LOGTAG, "Failed to close error page template reader", e);
+                        }
+                    }
+                }
+            }
+
+            return GeckoViewActivity.this.createErrorPage(categoryToString(category) + " : " + errorToString(error));
+        }
+
+        @Override
+        public GeckoResult<String> onLoadError(final GeckoSession session, final String uri,
+                                               final int category, final int error) {
             Log.d(LOGTAG, "onLoadError=" + uri +
                   " error category=" + category +
                   " error=" + error);
+
+            return GeckoResult.fromValue("data:text/html," + createErrorPage(category, error));
         }
     }
 
     private class ExampleTrackingProtectionDelegate implements GeckoSession.TrackingProtectionDelegate {
         private int mBlockedAds = 0;
         private int mBlockedAnalytics = 0;
         private int mBlockedSocial = 0;
         private int mBlockedContent = 0;
--- a/mobile/android/modules/geckoview/GeckoViewProgress.jsm
+++ b/mobile/android/modules/geckoview/GeckoViewProgress.jsm
@@ -212,39 +212,46 @@ class GeckoViewProgress extends GeckoVie
     debug `onSettingsUpdate: ${settings}`;
 
     IdentityHandler.setUseTrackingProtection(!!settings.useTrackingProtection);
     IdentityHandler.setUsePrivateMode(!!settings.usePrivateMode);
   }
 
   onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
     debug `onStateChange: isTopLevel=${aWebProgress.isTopLevel},
-                          flags=${aStateFlags}, status=${aStatus}`;
+                          flags=${aStateFlags}, status=${aStatus}
+                          loadType=${aWebProgress.loadType}`;
+
 
     if (!aWebProgress.isTopLevel) {
       return;
     }
 
     const uriSpec = aRequest.QueryInterface(Ci.nsIChannel).URI.displaySpec;
-    debug `onStateChange: uri=${uriSpec}`;
+    const isSuccess = aStatus == Cr.NS_OK;
+    const isStart = (aStateFlags & Ci.nsIWebProgressListener.STATE_START) != 0;
+    const isStop = (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) != 0;
 
-    if (aStateFlags & Ci.nsIWebProgressListener.STATE_START) {
+    debug `onStateChange: uri=${uriSpec} isSuccess=${isSuccess}
+           isStart=${isStart} isStop=${isStop}`;
+
+    if (isStart) {
       this._inProgress = true;
       const message = {
         type: "GeckoView:PageStart",
         uri: uriSpec,
       };
 
       this.eventDispatcher.sendRequest(message);
-    } else if ((aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) &&
-               !aWebProgress.isLoadingDocument) {
+    } else if (isStop && !aWebProgress.isLoadingDocument) {
       this._inProgress = false;
+
       let message = {
         type: "GeckoView:PageStop",
-        success: !aStatus
+        success: isSuccess
       };
 
       this.eventDispatcher.sendRequest(message);
     }
   }
 
   onSecurityChange(aWebProgress, aRequest, aState) {
     debug `onSecurityChange`;
@@ -267,23 +274,16 @@ class GeckoViewProgress extends GeckoVie
     this.eventDispatcher.sendRequest(message);
   }
 
   onLocationChange(aWebProgress, aRequest, aLocationURI, aFlags) {
     debug `onLocationChange: location=${aLocationURI.displaySpec},
                              flags=${aFlags}`;
 
     this._hostChanged = true;
-    if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) {
-      // We apparently don't get a STATE_STOP in onStateChange(), so emit PageStop here
-      this.eventDispatcher.sendRequest({
-        type: "GeckoView:PageStop",
-        success: false
-      });
-    }
   }
 
   // nsIObserver event handler
   observe(aSubject, aTopic, aData) {
     debug `observe: topic=${aTopic}`;
 
     switch (aTopic) {
       case "oop-frameloader-crashed": {
--- a/mobile/android/modules/geckoview/LoadURIDelegate.jsm
+++ b/mobile/android/modules/geckoview/LoadURIDelegate.jsm
@@ -2,21 +2,24 @@
 /* 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 = ["LoadURIDelegate"];
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+ChromeUtils.import("resource://gre/modules/GeckoViewUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   Services: "resource://gre/modules/Services.jsm",
 });
 
+GeckoViewUtils.initLogging("LoadURIDelegate", this);
+
 const LoadURIDelegate = {
   // Delegate URI loading to the app.
   // Return whether the loading has been handled.
   load: function(aWindow, aEventDispatcher, aUri, aWhere, aFlags) {
     if (!aWindow) {
       return Promise.resolve(false);
     }
 
@@ -36,28 +39,33 @@ const LoadURIDelegate = {
     try {
       let nssErrorsService = Cc["@mozilla.org/nss_errors_service;1"]
                              .getService(Ci.nsINSSErrorsService);
       errorClass = nssErrorsService.getErrorClass(aError);
     } catch (e) {}
 
     const msg = {
       type: "GeckoView:OnLoadError",
-      uri: aUri.spec,
+      uri: aUri && aUri.spec,
       error: aError,
       errorModule: aErrorModule,
       errorClass
     };
 
-    let handled = undefined;
+    let errorPageURI = undefined;
     aEventDispatcher.sendRequestForResult(msg).then(response => {
-      handled = response;
-    }, () => {
-      // There was an error or listener was not registered in GeckoSession,
-      // treat as unhandled.
-      handled = false;
+      try {
+        errorPageURI = Services.io.newURI(response);
+      } catch (e) {
+        warn `Failed to parse URI '${response}`;
+        errorPageURI = null;
+        Components.returnCode = Cr.NS_ERROR_ABORT;
+      }
+    }, e => {
+      errorPageURI = null;
+      Components.returnCode = Cr.NS_ERROR_ABORT;
     });
     Services.tm.spinEventLoopUntil(() =>
-        aWindow.closed || handled !== undefined);
+        aWindow.closed || errorPageURI !== undefined);
 
-    return handled || false;
+    return errorPageURI;
   }
 };
--- a/nsprpub/TAG-INFO
+++ b/nsprpub/TAG-INFO
@@ -1,1 +1,1 @@
-6e31156d7002
+34274ae8c85e
--- a/nsprpub/config/prdepend.h
+++ b/nsprpub/config/prdepend.h
@@ -5,9 +5,8 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSPR in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
-
--- a/nsprpub/configure.in
+++ b/nsprpub/configure.in
@@ -2101,16 +2101,20 @@ tools are selected during the Xcode/Deve
                 CFLAGS="$CFLAGS -arch:IA32"
             fi
 	fi
         ;;
     x86_64)
 	    AC_DEFINE(_AMD64_)
 	    USE_64=1
 	    ;;
+    aarch64)
+	    AC_DEFINE(_ARM64_)
+	    USE_64=1
+	    ;;
     ia64)
 	    AC_DEFINE(_IA64_)
 	    USE_64=1
 	    ;;
     *)
 	    AC_DEFINE(_CPU_ARCH_NOT_DEFINED)
 	    ;;
     esac
--- a/nsprpub/pr/include/md/_win95.cfg
+++ b/nsprpub/pr/include/md/_win95.cfg
@@ -209,16 +209,65 @@
 #define PR_ALIGN_OF_WORD    4
 #define PR_ALIGN_OF_DWORD   8
 #define PR_ALIGN_OF_DOUBLE  8
 #define PR_ALIGN_OF_POINTER 4
 
 #define PR_BYTES_PER_WORD_LOG2  2
 #define PR_BYTES_PER_DWORD_LOG2 3
 
+#elif defined(_M_ARM64) || defined(_ARM64_)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_WORD	8
+#define PR_BYTES_PER_DWORD	8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD	64
+#define PR_BITS_PER_DWORD	64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2	6
+#define PR_BITS_PER_DWORD_LOG2	6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD	8
+#define PR_ALIGN_OF_DWORD	8
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define PR_BYTES_PER_WORD_LOG2	3
+#define PR_BYTES_PER_DWORD_LOG2	3
+
 #else /* defined(_M_IX86) || defined(_X86_) */
 
 #error unknown processor architecture
 
 #endif /* defined(_M_IX86) || defined(_X86_) */
 
 #ifndef HAVE_LONG_LONG
 #define HAVE_LONG_LONG
--- a/nsprpub/pr/include/md/_win95.h
+++ b/nsprpub/pr/include/md/_win95.h
@@ -21,16 +21,18 @@
 #if defined(_M_IX86) || defined(_X86_)
 #define _PR_SI_ARCHITECTURE   "x86"
 #elif defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_)
 #define _PR_SI_ARCHITECTURE   "x86-64"
 #elif defined(_M_IA64) || defined(_IA64_)
 #define _PR_SI_ARCHITECTURE   "ia64"
 #elif defined(_M_ARM) || defined(_ARM_)
 #define _PR_SI_ARCHITECTURE   "arm"
+#elif defined(_M_ARM64)
+#define _PR_SI_ARCHITECTURE   "aarch64"
 #else
 #error unknown processor architecture
 #endif
 
 #define HAVE_DLL
 #undef  HAVE_THREAD_AFFINITY
 #define _PR_HAVE_GETADDRINFO
 #define _PR_INET6_PROBE
--- a/python/mozboot/mozboot/bootstrap.py
+++ b/python/mozboot/mozboot/bootstrap.py
@@ -292,53 +292,54 @@ class Bootstrapper(object):
     # We can't easily import mach_bootstrap.py because the bootstrapper may
     # run in self-contained mode and only the files in this directory will
     # be available. We /could/ refactor parts of mach_bootstrap.py to be
     # part of this directory to avoid the code duplication.
     def try_to_create_state_dir(self):
         state_dir, _ = get_state_dir()
 
         if not os.path.exists(state_dir):
+            should_create_state_dir = True
             if not self.instance.no_interactive:
                 choice = self.instance.prompt_int(
                     prompt=STATE_DIR_INFO.format(statedir=state_dir),
                     low=1,
                     high=2)
 
-                if choice == 1:
-                    print('Creating global state directory: %s' % state_dir)
-                    os.makedirs(state_dir, mode=0o770)
+                should_create_state_dir = choice == 1
+
+            # This directory is by default in $HOME, or overridden via an env
+            # var, so we probably shouldn't gate it on --no-system-changes.
+            if should_create_state_dir:
+                print('Creating global state directory: %s' % state_dir)
+                os.makedirs(state_dir, mode=0o770)
 
         state_dir_available = os.path.exists(state_dir)
         return state_dir_available, state_dir
 
     def maybe_install_private_packages_or_exit(self, state_dir,
                                                state_dir_available,
                                                have_clone,
                                                checkout_root):
-        # Install the clang packages needed for developing stylo, as well
-        # as the version of NodeJS that we currently support.
-        if not self.instance.no_interactive:
-            # The best place to install our packages is in the state directory
-            # we have.  If the user doesn't have one, we need them to re-run
-            # bootstrap and create the directory.
-            #
-            # XXX Android bootstrap just assumes the existence of the state
-            # directory and writes the NDK into it.  Should we do the same?
-            if not state_dir_available:
-                print(STYLO_NODEJS_DIRECTORY_MESSAGE.format(statedir=state_dir))
-                sys.exit(1)
+        # Install the clang packages needed for building the style system, as
+        # well as the version of NodeJS that we currently support.
 
-            if not have_clone:
-                print(STYLE_NODEJS_REQUIRES_CLONE)
-                sys.exit(1)
+        # The best place to install our packages is in the state directory
+        # we have.  We should have created one above in non-interactive mode.
+        if not state_dir_available:
+            print(STYLO_NODEJS_DIRECTORY_MESSAGE.format(statedir=state_dir))
+            sys.exit(1)
 
-            self.instance.state_dir = state_dir
-            self.instance.ensure_stylo_packages(state_dir, checkout_root)
-            self.instance.ensure_node_packages(state_dir, checkout_root)
+        if not have_clone:
+            print(STYLE_NODEJS_REQUIRES_CLONE)
+            sys.exit(1)
+
+        self.instance.state_dir = state_dir
+        self.instance.ensure_stylo_packages(state_dir, checkout_root)
+        self.instance.ensure_node_packages(state_dir, checkout_root)
 
     def bootstrap(self):
         if self.choice is None:
             # Like ['1. Firefox for Desktop', '2. Firefox for Android Artifact Mode', ...].
             labels = ['%s. %s' % (i + 1, name) for (i, (name, _)) in enumerate(APPLICATIONS_LIST)]
             prompt = APPLICATION_CHOICE % '\n'.join(labels)
             prompt_choice = self.instance.prompt_int(prompt=prompt, low=1, high=len(APPLICATIONS))
             name, application = APPLICATIONS_LIST[prompt_choice-1]
--- a/servo/components/style/gecko/conversions.rs
+++ b/servo/components/style/gecko/conversions.rs
@@ -14,16 +14,17 @@ use gecko_bindings::bindings;
 use gecko_bindings::structs::{self, nsCSSUnit, nsStyleCoord_CalcValue};
 use gecko_bindings::structs::{nsresult, SheetType, nsStyleImage};
 use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
 use std::f32::consts::PI;
 use stylesheets::{Origin, RulesMutateError};
 use values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image};
 use values::computed::{Integer, LengthOrPercentage, LengthOrPercentageOrAuto};
 use values::computed::{Percentage, TextAlign};
+use values::computed::image::LineDirection;
 use values::computed::url::ComputedImageUrl;
 use values::generics::box_::VerticalAlign;
 use values::generics::grid::{TrackListValue, TrackSize};
 use values::generics::image::{CompatMode, GradientItem, Image as GenericImage};
 use values::generics::rect::Rect;
 
 impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue {
     fn from(other: CalcLengthOrPercentage) -> nsStyleCoord_CalcValue {
@@ -134,16 +135,78 @@ impl Angle {
             nsCSSUnit::eCSSUnit_Grad => Angle::Grad(value),
             nsCSSUnit::eCSSUnit_Radian => Angle::Rad(value),
             nsCSSUnit::eCSSUnit_Turn => Angle::Turn(value),
             _ => panic!("Unexpected unit for angle"),
         }
     }
 }
 
+fn line_direction(
+    horizontal: LengthOrPercentage,
+    vertical: LengthOrPercentage,
+) -> LineDirection {
+    use values::computed::position::Position;
+    use values::specified::position::{X, Y};
+
+    let horizontal_percentage = match horizontal {
+        LengthOrPercentage::Percentage(percentage) => Some(percentage.0),
+        _ => None,
+    };
+
+    let vertical_percentage = match vertical {
+        LengthOrPercentage::Percentage(percentage) => Some(percentage.0),
+        _ => None,
+    };
+
+    let horizontal_as_corner = horizontal_percentage.and_then(|percentage| {
+        if percentage == 0.0 {
+            Some(X::Left)
+        } else if percentage == 1.0 {
+            Some(X::Right)
+        } else {
+            None
+        }
+    });
+
+    let vertical_as_corner = vertical_percentage.and_then(|percentage| {
+        if percentage == 0.0 {
+            Some(Y::Top)
+        } else if percentage == 1.0 {
+            Some(Y::Bottom)
+        } else {
+            None
+        }
+    });
+
+    if let (Some(hc), Some(vc)) = (horizontal_as_corner, vertical_as_corner) {
+        return LineDirection::Corner(hc, vc)
+    }
+
+    if let Some(hc) = horizontal_as_corner {
+        if vertical_percentage == Some(0.5) {
+            return LineDirection::Horizontal(hc)
+        }
+    }
+
+    if let Some(vc) = vertical_as_corner {
+        if horizontal_percentage == Some(0.5) {
+            return LineDirection::Vertical(vc)
+        }
+    }
+
+    LineDirection::MozPosition(
+        Some(Position {
+            horizontal,
+            vertical,
+        }),
+        None,
+    )
+}
+
 impl nsStyleImage {
     /// Set a given Servo `Image` value into this `nsStyleImage`.
     pub fn set(&mut self, image: Image) {
         match image {
             GenericImage::Gradient(boxed_gradient) => self.set_gradient(*boxed_gradient),
             GenericImage::Url(ref url) => unsafe {
                 bindings::Gecko_SetLayerImageImageValue(self, url.0.image_value.get());
             },
@@ -169,23 +232,23 @@ impl nsStyleImage {
                 }
             },
             GenericImage::Element(ref element) => unsafe {
                 bindings::Gecko_SetImageElement(self, element.as_ptr());
             },
         }
     }
 
+    // FIXME(emilio): This is really complex, we should use cbindgen for this.
     fn set_gradient(&mut self, gradient: Gradient) {
         use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_CORNER as CLOSEST_CORNER;
         use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE as CLOSEST_SIDE;
         use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER as FARTHEST_CORNER;
         use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE as FARTHEST_SIDE;
         use self::structs::nsStyleCoord;
-        use values::computed::image::LineDirection;
         use values::generics::image::{Circle, Ellipse, EndingShape, GradientKind, ShapeExtent};
         use values::specified::position::{X, Y};
 
         let stop_count = gradient.items.len();
         if stop_count >= ::std::u32::MAX as usize {
             warn!("stylo: Prevented overflow due to too many gradient stops");
             return;
         }
@@ -432,70 +495,35 @@ impl nsStyleImage {
         ComputedImageUrl::from_image_request(image_request)
     }
 
     unsafe fn get_gradient(self: &nsStyleImage) -> Box<Gradient> {
         use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_CORNER as CLOSEST_CORNER;
         use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE as CLOSEST_SIDE;
         use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER as FARTHEST_CORNER;
         use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE as FARTHEST_SIDE;
-        use values::computed::{Length, LengthOrPercentage};
+        use values::computed::Length;
         use values::computed::image::LineDirection;
         use values::computed::position::Position;
         use values::generics::image::{Circle, ColorStop, CompatMode, Ellipse};
         use values::generics::image::{EndingShape, GradientKind, ShapeExtent};
-        use values::specified::position::{X, Y};
 
         let gecko_gradient = bindings::Gecko_GetGradientImageValue(self)
             .as_ref()
             .unwrap();
         let angle = Angle::from_gecko_style_coord(&gecko_gradient.mAngle);
         let horizontal_style = LengthOrPercentage::from_gecko_style_coord(&gecko_gradient.mBgPosX);
         let vertical_style = LengthOrPercentage::from_gecko_style_coord(&gecko_gradient.mBgPosY);
 
         let kind = match gecko_gradient.mShape as u32 {
             structs::NS_STYLE_GRADIENT_SHAPE_LINEAR => {
                 let line_direction = match (angle, horizontal_style, vertical_style) {
                     (Some(a), None, None) => LineDirection::Angle(a),
                     (None, Some(horizontal), Some(vertical)) => {
-                        let horizontal_as_corner = match horizontal {
-                            LengthOrPercentage::Percentage(percentage) => {
-                                if percentage.0 == 0.0 {
-                                    Some(X::Left)
-                                } else if percentage.0 == 1.0 {
-                                    Some(X::Right)
-                                } else {
-                                    None
-                                }
-                            },
-                            _ => None,
-                        };
-                        let vertical_as_corner = match vertical {
-                            LengthOrPercentage::Percentage(percentage) => {
-                                if percentage.0 == 0.0 {
-                                    Some(Y::Top)
-                                } else if percentage.0 == 1.0 {
-                                    Some(Y::Bottom)
-                                } else {
-                                    None
-                                }
-                            },
-                            _ => None,
-                        };
-
-                        match (horizontal_as_corner, vertical_as_corner) {
-                            (Some(hc), Some(vc)) => LineDirection::Corner(hc, vc),
-                            _ => LineDirection::MozPosition(
-                                Some(Position {
-                                    horizontal,
-                                    vertical,
-                                }),
-                                None,
-                            ),
-                        }
+                        line_direction(horizontal, vertical)
                     },
                     (Some(_), Some(horizontal), Some(vertical)) => LineDirection::MozPosition(
                         Some(Position {
                             horizontal,
                             vertical,
                         }),
                         angle,
                     ),
@@ -738,27 +766,25 @@ pub mod basic_shape {
     impl<'a> From<&'a StyleBasicShape> for BasicShape {
         fn from(other: &'a StyleBasicShape) -> Self {
             match other.mType {
                 StyleBasicShapeType::Inset => {
                     let t = LengthOrPercentage::from_gecko_style_coord(&other.mCoordinates[0]);
                     let r = LengthOrPercentage::from_gecko_style_coord(&other.mCoordinates[1]);
                     let b = LengthOrPercentage::from_gecko_style_coord(&other.mCoordinates[2]);
                     let l = LengthOrPercentage::from_gecko_style_coord(&other.mCoordinates[3]);
-                    let round = (&other.mRadius).into();
+                    let round: BorderRadius = (&other.mRadius).into();
+                    let round = if round.all_zero() { None } else { Some(round) };
                     let rect = Rect::new(
                         t.expect("inset() offset should be a length, percentage, or calc value"),
                         r.expect("inset() offset should be a length, percentage, or calc value"),
                         b.expect("inset() offset should be a length, percentage, or calc value"),
                         l.expect("inset() offset should be a length, percentage, or calc value"),
                     );
-                    GenericBasicShape::Inset(InsetRect {
-                        rect: rect,
-                        round: Some(round),
-                    })
+                    GenericBasicShape::Inset(InsetRect { rect, round })
                 },
                 StyleBasicShapeType::Circle => GenericBasicShape::Circle(Circle {
                     radius: (&other.mCoordinates[0]).into(),
                     position: (&other.mPosition).into(),
                 }),
                 StyleBasicShapeType::Ellipse => GenericBasicShape::Ellipse(Ellipse {
                     semiaxis_x: (&other.mCoordinates[0]).into(),
                     semiaxis_y: (&other.mCoordinates[1]).into(),
--- a/servo/components/style/properties/longhands/background.mako.rs
+++ b/servo/components/style/properties/longhands/background.mako.rs
@@ -13,24 +13,27 @@
     initial_specified_value="SpecifiedValue::transparent()",
     spec="https://drafts.csswg.org/css-backgrounds/#background-color",
     animation_value_type="AnimatedColor",
     ignored_when_colors_disabled=True,
     allow_quirks=True,
     flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
 )}
 
-${helpers.predefined_type("background-image", "ImageLayer",
+${helpers.predefined_type(
+    "background-image",
+    "ImageLayer",
     initial_value="Either::First(None_)",
     initial_specified_value="Either::First(None_)",
     spec="https://drafts.csswg.org/css-backgrounds/#the-background-image",
     vector="True",
     animation_value_type="discrete",
     ignored_when_colors_disabled="True",
-    flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER")}
+    flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
+)}
 
 % for (axis, direction, initial) in [("x", "Horizontal", "left"), ("y", "Vertical", "top")]:
     ${helpers.predefined_type(
         "background-position-" + axis,
         "position::" + direction + "Position",
         initial_value="computed::LengthOrPercentage::zero()",
         initial_specified_value="SpecifiedValue::initial_specified_value()",
         spec="https://drafts.csswg.org/css-backgrounds-4/#propdef-background-position-" + axis,
@@ -47,23 +50,25 @@
     "computed::BackgroundRepeat::repeat()",
     initial_specified_value="specified::BackgroundRepeat::repeat()",
     animation_value_type="discrete",
     vector=True,
     spec="https://drafts.csswg.org/css-backgrounds/#the-background-repeat",
     flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
 )}
 
-${helpers.single_keyword("background-attachment",
-                         "scroll fixed" + (" local" if product == "gecko" else ""),
-                         vector=True,
-                         gecko_enum_prefix="StyleImageLayerAttachment",
-                         spec="https://drafts.csswg.org/css-backgrounds/#the-background-attachment",
-                         animation_value_type="discrete",
-                         flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER")}
+${helpers.single_keyword(
+    "background-attachment",
+    "scroll fixed" + (" local" if product == "gecko" else ""),
+    vector=True,
+    gecko_enum_prefix="StyleImageLayerAttachment",
+    spec="https://drafts.csswg.org/css-backgrounds/#the-background-attachment",
+    animation_value_type="discrete",
+    flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
+)}
 
 ${helpers.single_keyword(
     "background-clip",
     "border-box padding-box content-box",
     extra_gecko_values="text",
     vector=True, extra_prefixes="webkit",
     gecko_enum_prefix="StyleGeometryBox",
     gecko_inexhaustive=True,
@@ -91,17 +96,19 @@
     spec="https://drafts.csswg.org/css-backgrounds/#the-background-size",
     vector=True,
     vector_animation_type="repeatable_list",
     animation_value_type="BackgroundSizeList",
     flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
     extra_prefixes="webkit")}
 
 // https://drafts.fxtf.org/compositing/#background-blend-mode
-${helpers.single_keyword("background-blend-mode",
-                         """normal multiply screen overlay darken lighten color-dodge
-                            color-burn hard-light soft-light difference exclusion hue
-                            saturation color luminosity""",
-                         gecko_constant_prefix="NS_STYLE_BLEND",
-                         gecko_pref="layout.css.background-blend-mode.enabled",
-                         vector=True, products="gecko", animation_value_type="discrete",
-                         spec="https://drafts.fxtf.org/compositing/#background-blend-mode",
-                         flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER")}
+${helpers.single_keyword(
+    "background-blend-mode",
+    """normal multiply screen overlay darken lighten color-dodge
+    color-burn hard-light soft-light difference exclusion hue
+    saturation color luminosity""",
+    gecko_constant_prefix="NS_STYLE_BLEND",
+    gecko_pref="layout.css.background-blend-mode.enabled",
+    vector=True, products="gecko", animation_value_type="discrete",
+    spec="https://drafts.fxtf.org/compositing/#background-blend-mode",
+    flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
+)}
--- a/servo/components/style/properties/longhands/border.mako.rs
+++ b/servo/components/style/properties/longhands/border.mako.rs
@@ -56,87 +56,112 @@
         logical=is_logical,
         logical_group="border-width",
         flags="APPLIES_TO_FIRST_LETTER GETCS_NEEDS_LAYOUT_FLUSH",
         allow_quirks=not is_logical,
         servo_restyle_damage="reflow rebuild_and_reflow_inline"
     )}
 % endfor
 
-${helpers.gecko_keyword_conversion(Keyword('border-style',
-                                   "none solid double dotted dashed hidden groove ridge inset outset"),
-                                   type="::values::specified::BorderStyle")}
+${helpers.gecko_keyword_conversion(
+    Keyword('border-style',
+    "none solid double dotted dashed hidden groove ridge inset outset"),
+    type="::values::specified::BorderStyle",
+)}
 
 // FIXME(#4126): when gfx supports painting it, make this Size2D<LengthOrPercentage>
 % for corner in ["top-left", "top-right", "bottom-right", "bottom-left"]:
-    ${helpers.predefined_type("border-" + corner + "-radius", "BorderCornerRadius",
-                              "computed::BorderCornerRadius::zero()",
-                              "parse", extra_prefixes="webkit",
-                              spec="https://drafts.csswg.org/css-backgrounds/#border-%s-radius" % corner,
-                              boxed=True,
-                              flags="APPLIES_TO_FIRST_LETTER",
-                              animation_value_type="BorderCornerRadius")}
+    ${helpers.predefined_type(
+        "border-" + corner + "-radius",
+        "BorderCornerRadius",
+        "computed::BorderCornerRadius::zero()",
+        "parse",
+        extra_prefixes="webkit",
+        spec="https://drafts.csswg.org/css-backgrounds/#border-%s-radius" % corner,
+        boxed=True,
+        flags="APPLIES_TO_FIRST_LETTER",
+        animation_value_type="BorderCornerRadius",
+    )}
 % endfor
 
-${helpers.single_keyword("box-decoration-break", "slice clone",
-                         gecko_enum_prefix="StyleBoxDecorationBreak",
-                         gecko_pref="layout.css.box-decoration-break.enabled",
-                         spec="https://drafts.csswg.org/css-break/#propdef-box-decoration-break",
-                         products="gecko", animation_value_type="discrete")}
+${helpers.single_keyword(
+    "box-decoration-break",
+    "slice clone",
+    gecko_enum_prefix="StyleBoxDecorationBreak",
+    gecko_pref="layout.css.box-decoration-break.enabled",
+    spec="https://drafts.csswg.org/css-break/#propdef-box-decoration-break",
+    products="gecko",
+    animation_value_type="discrete",
+)}
 
-${helpers.single_keyword("-moz-float-edge", "content-box margin-box",
-                         gecko_ffi_name="mFloatEdge",
-                         gecko_enum_prefix="StyleFloatEdge",
-                         products="gecko",
-                         spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-float-edge)",
-                         animation_value_type="discrete")}
+${helpers.single_keyword(
+    "-moz-float-edge",
+    "content-box margin-box",
+    gecko_ffi_name="mFloatEdge",
+    gecko_enum_prefix="StyleFloatEdge",
+    products="gecko",
+    spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-float-edge)",
+    animation_value_type="discrete",
+)}
 
-${helpers.predefined_type("border-image-source", "ImageLayer",
+${helpers.predefined_type(
+    "border-image-source",
+    "ImageLayer",
     initial_value="Either::First(None_)",
     initial_specified_value="Either::First(None_)",
     spec="https://drafts.csswg.org/css-backgrounds/#the-background-image",
     vector=False,
     animation_value_type="discrete",
     flags="APPLIES_TO_FIRST_LETTER",
-    boxed=True)}
+    boxed=True,
+)}
 
-${helpers.predefined_type("border-image-outset", "LengthOrNumberRect",
+${helpers.predefined_type(
+    "border-image-outset",
+    "LengthOrNumberRect",
     parse_method="parse_non_negative",
     initial_value="computed::LengthOrNumberRect::all(computed::LengthOrNumber::zero())",
     initial_specified_value="specified::LengthOrNumberRect::all(specified::LengthOrNumber::zero())",
     spec="https://drafts.csswg.org/css-backgrounds/#border-image-outset",
     animation_value_type="discrete",
     flags="APPLIES_TO_FIRST_LETTER",
-    boxed=True)}
+    boxed=True,
+)}
 
 ${helpers.predefined_type(
     "border-image-repeat",
     "BorderImageRepeat",
     "computed::BorderImageRepeat::stretch()",
     initial_specified_value="specified::BorderImageRepeat::stretch()",
     animation_value_type="discrete",
     spec="https://drafts.csswg.org/css-backgrounds/#the-border-image-repeat",
     flags="APPLIES_TO_FIRST_LETTER",
 )}
 
-${helpers.predefined_type("border-image-width", "BorderImageWidth",
+${helpers.predefined_type(
+    "border-image-width",
+    "BorderImageWidth",
     initial_value="computed::BorderImageWidth::all(computed::BorderImageSideWidth::one())",
     initial_specified_value="specified::BorderImageWidth::all(specified::BorderImageSideWidth::one())",
     spec="https://drafts.csswg.org/css-backgrounds/#border-image-width",
     animation_value_type="discrete",
     flags="APPLIES_TO_FIRST_LETTER",
-    boxed=True)}
+    boxed=True,
+)}
 
-${helpers.predefined_type("border-image-slice", "BorderImageSlice",
+${helpers.predefined_type(
+    "border-image-slice",
+    "BorderImageSlice",
     initial_value="computed::NumberOrPercentage::Percentage(computed::Percentage(1.)).into()",
     initial_specified_value="specified::NumberOrPercentage::Percentage(specified::Percentage::new(1.)).into()",
     spec="https://drafts.csswg.org/css-backgrounds/#border-image-slice",
     animation_value_type="discrete",
     flags="APPLIES_TO_FIRST_LETTER",
-    boxed=True)}
+    boxed=True,
+)}
 
 #[cfg(feature = "gecko")]
 impl ::values::computed::BorderImageWidth {
     pub fn to_gecko_rect(&self, sides: &mut ::gecko_bindings::structs::nsStyleSides) {
         use gecko_bindings::sugar::ns_style_coord::{CoordDataMut, CoordDataValue};
         use gecko::values::GeckoStyleCoordConvertible;
         use values::generics::border::BorderImageSideWidth;
 
@@ -150,18 +175,19 @@ impl ::values::computed::BorderImageWidt
             },
             BorderImageSideWidth::Number(n) => {
                 sides.data_at_mut(${i}).set_value(CoordDataValue::Factor(n))
             },
         }
         % endfor
     }
 
-    pub fn from_gecko_rect(sides: &::gecko_bindings::structs::nsStyleSides)
-                           -> Option<::values::computed::BorderImageWidth> {
+    pub fn from_gecko_rect(
+        sides: &::gecko_bindings::structs::nsStyleSides,
+    ) -> Option<::values::computed::BorderImageWidth> {
         use gecko_bindings::structs::nsStyleUnit::{eStyleUnit_Factor, eStyleUnit_Auto};
         use gecko_bindings::sugar::ns_style_coord::CoordData;
         use gecko::values::GeckoStyleCoordConvertible;
         use values::computed::{LengthOrPercentage, Number};
         use values::generics::border::BorderImageSideWidth;
 
         Some(
             ::values::computed::BorderImageWidth::new(
--- a/servo/components/style/properties/longhands/box.mako.rs
+++ b/servo/components/style/properties/longhands/box.mako.rs
@@ -18,79 +18,68 @@
     initial_specified_value="specified::Display::inline()",
     animation_value_type="discrete",
     flags="APPLIES_TO_PLACEHOLDER",
     spec="https://drafts.csswg.org/css-display/#propdef-display",
     servo_restyle_damage="rebuild_and_reflow",
     needs_context=product == "gecko"
 )}
 
-// FIXME(emilio): Listing all the display values here is very unfortunate, we should teach C++ to use the
-// Rust enum directly, or generate the conversions to `StyleDisplay`.
-${helpers.gecko_keyword_conversion(
-    Keyword('display', """
-        inline block inline-block
-        table inline-table table-row-group table-header-group table-footer-group
-        table-row table-column-group table-column table-cell table-caption
-        list-item none flex inline-flex grid inline-grid ruby ruby-base ruby-base-container
-        ruby-text ruby-text-container contents flow-root -webkit-box
-        -webkit-inline-box -moz-box -moz-inline-box -moz-grid -moz-inline-grid
-        -moz-grid-group -moz-grid-line -moz-stack -moz-inline-stack -moz-deck
-        -moz-popup -moz-groupbox
-    """,
-    gecko_enum_prefix='StyleDisplay',
-    gecko_strip_moz_prefix=False),
-    type="::values::specified::Display"
+${helpers.single_keyword(
+    "-moz-top-layer",
+    "none top",
+    gecko_constant_prefix="NS_STYLE_TOP_LAYER",
+    gecko_ffi_name="mTopLayer",
+    products="gecko",
+    animation_value_type="none",
+    enabled_in="ua",
+    spec="Internal (not web-exposed)",
 )}
 
-${helpers.single_keyword("-moz-top-layer", "none top",
-                         gecko_constant_prefix="NS_STYLE_TOP_LAYER",
-                         gecko_ffi_name="mTopLayer",
-                         products="gecko", animation_value_type="none",
-                         enabled_in="ua",
-                         spec="Internal (not web-exposed)")}
-
-${helpers.single_keyword("position", "static absolute relative fixed sticky",
-                         animation_value_type="discrete",
-                         flags="CREATES_STACKING_CONTEXT ABSPOS_CB",
-                         spec="https://drafts.csswg.org/css-position/#position-property",
-                         servo_restyle_damage="rebuild_and_reflow")}
+${helpers.single_keyword(
+    "position",
+    "static absolute relative fixed sticky",
+    animation_value_type="discrete",
+    flags="CREATES_STACKING_CONTEXT ABSPOS_CB",
+    spec="https://drafts.csswg.org/css-position/#position-property",
+    servo_restyle_damage="rebuild_and_reflow",
+)}
 
 ${helpers.predefined_type(
     "float",
     "Float",
     "computed::Float::None",
     initial_specified_value="specified::Float::None",
     spec="https://drafts.csswg.org/css-box/#propdef-float",
     animation_value_type="discrete",
     needs_context=False,
     flags="APPLIES_TO_FIRST_LETTER",
     servo_restyle_damage="rebuild_and_reflow",
-    gecko_ffi_name="mFloat"
+    gecko_ffi_name="mFloat",
 )}
 
 ${helpers.predefined_type(
     "clear",
     "Clear",
     "computed::Clear::None",
     animation_value_type="discrete",
     needs_context=False,
     gecko_ffi_name="mBreakType",
     spec="https://drafts.csswg.org/css-box/#propdef-clear",
-    servo_restyle_damage="rebuild_and_reflow"
+    servo_restyle_damage="rebuild_and_reflow",
 )}
 
 ${helpers.predefined_type(
     "vertical-align",
     "VerticalAlign",
     "computed::VerticalAlign::baseline()",
     animation_value_type="ComputedValue",
     flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
     spec="https://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align",
-    servo_restyle_damage = "reflow"
+    servo_restyle_damage = "reflow",
 )}
 
 // CSS 2.1, Section 11 - Visual effects
 
 ${helpers.single_keyword("-servo-overflow-clip-box", "padding-box content-box",
     products="servo", animation_value_type="none", enabled_in="ua",
     spec="Internal, not web-exposed, \
           may be standardized in the future (https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-clip-box)")}
@@ -113,328 +102,368 @@
 
 <%
     overflow_custom_consts = { "-moz-hidden-unscrollable": "CLIP" }
 %>
 
 // FIXME(pcwalton, #2742): Implement scrolling for `scroll` and `auto`.
 //
 // We allow it to apply to placeholders for UA sheets, which set it !important.
-${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
-                         animation_value_type="discrete",
-                         extra_gecko_values="-moz-hidden-unscrollable",
-                         custom_consts=overflow_custom_consts,
-                         gecko_constant_prefix="NS_STYLE_OVERFLOW",
-                         flags="APPLIES_TO_PLACEHOLDER",
-                         spec="https://drafts.csswg.org/css-overflow/#propdef-overflow-x",
-                         servo_restyle_damage = "reflow")}
+${helpers.single_keyword(
+    "overflow-x",
+    "visible hidden scroll auto",
+    animation_value_type="discrete",
+    extra_gecko_values="-moz-hidden-unscrollable",
+    custom_consts=overflow_custom_consts,
+    gecko_constant_prefix="NS_STYLE_OVERFLOW",
+    flags="APPLIES_TO_PLACEHOLDER",
+    spec="https://drafts.csswg.org/css-overflow/#propdef-overflow-x",
+    servo_restyle_damage = "reflow",
+)}
 
 // FIXME(pcwalton, #2742): Implement scrolling for `scroll` and `auto`.
 //
 // We allow it to apply to placeholders for UA sheets, which set it !important.
 <%helpers:longhand name="overflow-y" animation_value_type="discrete"
                    flags="APPLIES_TO_PLACEHOLDER",
                    spec="https://drafts.csswg.org/css-overflow/#propdef-overflow-y"
                    servo_restyle_damage = "reflow">
     pub use super::overflow_x::{SpecifiedValue, parse, get_initial_value, computed_value};
 </%helpers:longhand>
 
 <% transition_extra_prefixes = "moz:layout.css.prefixes.transitions webkit" %>
 
-${helpers.predefined_type("transition-duration",
-                          "Time",
-                          "computed::Time::zero()",
-                          initial_specified_value="specified::Time::zero()",
-                          parse_method="parse_non_negative",
-                          vector=True,
-                          need_index=True,
-                          animation_value_type="none",
-                          extra_prefixes=transition_extra_prefixes,
-                          spec="https://drafts.csswg.org/css-transitions/#propdef-transition-duration")}
+${helpers.predefined_type(
+    "transition-duration",
+    "Time",
+    "computed::Time::zero()",
+    initial_specified_value="specified::Time::zero()",
+    parse_method="parse_non_negative",
+    vector=True,
+    need_index=True,
+    animation_value_type="none",
+    extra_prefixes=transition_extra_prefixes,
+    spec="https://drafts.csswg.org/css-transitions/#propdef-transition-duration",
+)}
 
-${helpers.predefined_type("transition-timing-function",
-                          "TimingFunction",
-                          "computed::TimingFunction::ease()",
-                          initial_specified_value="specified::TimingFunction::ease()",
-                          vector=True,
-                          need_index=True,
-                          animation_value_type="none",
-                          extra_prefixes=transition_extra_prefixes,
-                          spec="https://drafts.csswg.org/css-transitions/#propdef-transition-timing-function")}
+${helpers.predefined_type(
+    "transition-timing-function",
+    "TimingFunction",
+    "computed::TimingFunction::ease()",
+    initial_specified_value="specified::TimingFunction::ease()",
+    vector=True,
+    need_index=True,
+    animation_value_type="none",
+    extra_prefixes=transition_extra_prefixes,
+    spec="https://drafts.csswg.org/css-transitions/#propdef-tra