merge mozilla-inbound to mozilla-central. a=merge
authorSebastian Hengst <archaeopteryx@coole-files.de>
Sat, 10 Feb 2018 00:26:50 +0200
changeset 403195 c2cddb0cbb20
parent 403164 919570891f1c (current diff)
parent 403194 a5b741fac29b (diff)
child 403226 8b3c2c67d1bf
child 403255 0f5910e5ca66
push id33416
push userarchaeopteryx@coole-files.de
push date2018-02-09 22:32 +0000
treeherdermozilla-central@c2cddb0cbb20 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone60.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 mozilla-inbound to mozilla-central. a=merge
browser/base/content/browser.js
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
dom/interfaces/base/nsIDOMWindowUtils.idl
dom/interfaces/events/moz.build
dom/interfaces/events/nsIDOMAnimationEvent.idl
dom/interfaces/events/nsIDOMBeforeUnloadEvent.idl
dom/interfaces/events/nsIDOMCommandEvent.idl
dom/interfaces/events/nsIDOMKeyEvent.idl
dom/interfaces/events/nsIDOMMutationEvent.idl
dom/interfaces/events/nsIDOMSimpleGestureEvent.idl
dom/interfaces/events/nsIDOMTransitionEvent.idl
dom/ipc/test.xul
gfx/thebes/gfxPrefs.h
layout/generic/nsSubDocumentFrame.cpp
modules/libpref/init/all.js
toolkit/components/resistfingerprinting/nsRFPService.cpp
toolkit/modules/Finder.jsm
xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -26,17 +26,16 @@
 #include "States.h"
 #include "StyleInfo.h"
 #include "TableAccessible.h"
 #include "TableCellAccessible.h"
 #include "TreeWalker.h"
 #include "XULDocument.h"
 
 #include "nsIDOMElement.h"
-#include "nsIDOMKeyEvent.h"
 #include "nsIDOMXULButtonElement.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDOMXULLabelElement.h"
 #include "nsIDOMXULSelectCntrlEl.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
 #include "nsINodeList.h"
 #include "nsPIDOMWindow.h"
 
@@ -80,16 +79,17 @@
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Unused.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/CanvasRenderingContext2D.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "mozilla/dom/HTMLBodyElement.h"
+#include "mozilla/dom/KeyboardEventBinding.h"
 #include "mozilla/dom/TreeWalker.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible: nsISupports and cycle collection
@@ -257,23 +257,23 @@ Accessible::AccessKey() const
 
   if (!key)
     return KeyBinding();
 
   // Get modifier mask. Use ui.key.generalAccessKey (unless it is -1).
   switch (Preferences::GetInt("ui.key.generalAccessKey", -1)) {
   case -1:
     break;
-  case nsIDOMKeyEvent::DOM_VK_SHIFT:
+  case dom::KeyboardEventBinding::DOM_VK_SHIFT:
     return KeyBinding(key, KeyBinding::kShift);
-  case nsIDOMKeyEvent::DOM_VK_CONTROL:
+  case dom::KeyboardEventBinding::DOM_VK_CONTROL:
     return KeyBinding(key, KeyBinding::kControl);
-  case nsIDOMKeyEvent::DOM_VK_ALT:
+  case dom::KeyboardEventBinding::DOM_VK_ALT:
     return KeyBinding(key, KeyBinding::kAlt);
-  case nsIDOMKeyEvent::DOM_VK_META:
+  case dom::KeyboardEventBinding::DOM_VK_META:
     return KeyBinding(key, KeyBinding::kMeta);
   default:
     return KeyBinding();
   }
 
   // Determine the access modifier used in this context.
   nsIDocument* document = mContent->GetUncomposedDoc();
   if (!document)
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -20,17 +20,16 @@
 #include "xpcAccessibleDocument.h"
 
 #include "nsIMutableArray.h"
 #include "nsICommandManager.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMMutationEvent.h"
 #include "nsPIDOMWindow.h"
 #include "nsIEditingSession.h"
 #include "nsIFrame.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsImageFrame.h"
 #include "nsIPersistentProperties2.h"
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
@@ -43,16 +42,17 @@
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/HTMLEditor.h"
 #include "mozilla/TextEditor.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/DocumentType.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/MutationEventBinding.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Static member initialization
 
 static nsStaticAtom** kRelationAttrs[] =
@@ -714,17 +714,17 @@ DocAccessible::AttributeWillChange(nsIDo
       return;
 
     accessible = this;
   }
 
   // Update dependent IDs cache. Take care of elements that are accessible
   // because dependent IDs cache doesn't contain IDs from non accessible
   // elements.
-  if (aModType != nsIDOMMutationEvent::ADDITION)
+  if (aModType != dom::MutationEventBinding::ADDITION)
     RemoveDependentIDsFor(accessible, aAttribute);
 
   if (aAttribute == nsGkAtoms::id) {
     RelocateARIAOwnedIfNeeded(aElement);
   }
 
   // Store the ARIA attribute old value so that it can be used after
   // attribute change. Note, we assume there's no nested ARIA attribute
@@ -732,17 +732,17 @@ DocAccessible::AttributeWillChange(nsIDo
   // old values.
 
   // XXX TODO: bugs 472142, 472143.
   // Here we will want to cache whatever attribute values we are interested
   // in, such as the existence of aria-pressed for button (so we know if we
   // need to newly expose it as a toggle button) etc.
   if (aAttribute == nsGkAtoms::aria_checked ||
       aAttribute == nsGkAtoms::aria_pressed) {
-    mARIAAttrOldValue = (aModType != nsIDOMMutationEvent::ADDITION) ?
+    mARIAAttrOldValue = (aModType != dom::MutationEventBinding::ADDITION) ?
       nsAccUtils::GetARIAToken(aElement, aAttribute) : nullptr;
     return;
   }
 
   if (aAttribute == nsGkAtoms::aria_disabled ||
       aAttribute == nsGkAtoms::disabled)
     mStateBitWasOn = accessible->Unavailable();
 }
@@ -789,18 +789,18 @@ DocAccessible::AttributeChanged(nsIDocum
   // the accessible state wasn't changed, i.e. its state is initial state.
   AttributeChangedImpl(accessible, aNameSpaceID, aAttribute);
 
   // Update dependent IDs cache. Take care of accessible elements because no
   // accessible element means either the element is not accessible at all or
   // its accessible will be created later. It doesn't make sense to keep
   // dependent IDs for non accessible elements. For the second case we'll update
   // dependent IDs cache when its accessible is created.
-  if (aModType == nsIDOMMutationEvent::MODIFICATION ||
-      aModType == nsIDOMMutationEvent::ADDITION) {
+  if (aModType == dom::MutationEventBinding::MODIFICATION ||
+      aModType == dom::MutationEventBinding::ADDITION) {
     AddDependentIDsFor(accessible, aAttribute);
   }
 }
 
 // DocAccessible protected member
 void
 DocAccessible::AttributeChangedImpl(Accessible* aAccessible,
                                     int32_t aNameSpaceID, nsAtom* aAttribute)
--- a/accessible/tests/mochitest/grid.js
+++ b/accessible/tests/mochitest/grid.js
@@ -1,10 +1,8 @@
-const nsIDOMKeyEvent = Components.interfaces.nsIDOMKeyEvent;
-
 /**
  * Create grid object based on HTML table.
  */
 function grid(aTableIdentifier) {
   this.getRowCount = function getRowCount() {
     return this.table.rows.length - (this.table.tHead ? 1 : 0);
   };
   this.getColsCount = function getColsCount() {
@@ -54,63 +52,63 @@ function grid(aTableIdentifier) {
   };
 
   this.initGrid = function initGrid() {
     this.table.addEventListener("keypress", this);
     this.table.addEventListener("click", this);
   };
 
   this.handleEvent = function handleEvent(aEvent) {
-    if (aEvent instanceof nsIDOMKeyEvent)
+    if (aEvent instanceof KeyboardEvent)
       this.handleKeyEvent(aEvent);
     else
       this.handleClickEvent(aEvent);
   };
 
   this.handleKeyEvent = function handleKeyEvent(aEvent) {
     if (aEvent.target.localName != "td")
       return;
 
     var cell = aEvent.target;
     switch (aEvent.keyCode) {
-      case nsIDOMKeyEvent.DOM_VK_UP: {
+      case KeyboardEvent.DOM_VK_UP: {
         let colsCount = this.getColsCount();
         let idx = this.getIndexByCell(cell);
         var upidx = idx - colsCount;
         if (upidx >= 0) {
           cell.removeAttribute("tabindex");
           var upcell = this.getCellAtIndex(upidx);
           upcell.setAttribute("tabindex", "0");
           upcell.focus();
         }
         break;
       }
-      case nsIDOMKeyEvent.DOM_VK_DOWN: {
+      case KeyboardEvent.DOM_VK_DOWN: {
         let colsCount = this.getColsCount();
         let idx = this.getIndexByCell(cell);
         var downidx = idx + colsCount;
         if (downidx <= this.getMaxIndex()) {
           cell.removeAttribute("tabindex");
           var downcell = this.getCellAtIndex(downidx);
           downcell.setAttribute("tabindex", "0");
           downcell.focus();
         }
         break;
       }
-      case nsIDOMKeyEvent.DOM_VK_LEFT: {
+      case KeyboardEvent.DOM_VK_LEFT: {
         let idx = this.getIndexByCell(cell);
         if (idx > 0) {
           cell.removeAttribute("tabindex");
           var prevcell = this.getCellAtIndex(idx - 1);
           prevcell.setAttribute("tabindex", "0");
           prevcell.focus();
         }
         break;
       }
-      case nsIDOMKeyEvent.DOM_VK_RIGHT: {
+      case KeyboardEvent.DOM_VK_RIGHT: {
         let idx = this.getIndexByCell(cell);
         if (idx < this.getMaxIndex()) {
           cell.removeAttribute("tabindex");
           var nextcell = this.getCellAtIndex(idx + 1);
           nextcell.setAttribute("tabindex", "0");
           nextcell.focus();
         }
         break;
--- a/accessible/xul/XULMenuAccessible.cpp
+++ b/accessible/xul/XULMenuAccessible.cpp
@@ -14,26 +14,26 @@
 #include "XULFormControlAccessible.h"
 
 #include "nsIDOMElement.h"
 #include "nsIDOMXULElement.h"
 #include "nsIMutableArray.h"
 #include "nsIDOMXULContainerElement.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
 #include "nsIDOMXULMultSelectCntrlEl.h"
-#include "nsIDOMKeyEvent.h"
 #include "nsIServiceManager.h"
 #include "nsIPresShell.h"
 #include "nsIContent.h"
 #include "nsMenuBarFrame.h"
 #include "nsMenuPopupFrame.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/KeyboardEventBinding.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULMenuitemAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -170,26 +170,26 @@ XULMenuitemAccessible::AccessKey() const
       // If top level menu item, add Alt+ or whatever modifier text to string
       // No need to cache pref service, this happens rarely
       if (gMenuAccesskeyModifier == -1) {
         // Need to initialize cached global accesskey pref
         gMenuAccesskeyModifier = Preferences::GetInt("ui.key.menuAccessKey", 0);
       }
 
       switch (gMenuAccesskeyModifier) {
-        case nsIDOMKeyEvent::DOM_VK_CONTROL:
+        case dom::KeyboardEventBinding::DOM_VK_CONTROL:
           modifierKey = KeyBinding::kControl;
           break;
-        case nsIDOMKeyEvent::DOM_VK_ALT:
+        case dom::KeyboardEventBinding::DOM_VK_ALT:
           modifierKey = KeyBinding::kAlt;
           break;
-        case nsIDOMKeyEvent::DOM_VK_META:
+        case dom::KeyboardEventBinding::DOM_VK_META:
           modifierKey = KeyBinding::kMeta;
           break;
-        case nsIDOMKeyEvent::DOM_VK_WIN:
+        case dom::KeyboardEventBinding::DOM_VK_WIN:
           modifierKey = KeyBinding::kOS;
           break;
       }
     }
   }
 
   return KeyBinding(accesskey[0], modifierKey);
 }
--- a/accessible/xul/XULSelectControlAccessible.cpp
+++ b/accessible/xul/XULSelectControlAccessible.cpp
@@ -7,23 +7,23 @@
 #include "XULSelectControlAccessible.h"
 
 #include "nsAccessibilityService.h"
 #include "DocAccessible.h"
 
 #include "nsIDOMXULContainerElement.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
 #include "nsIDOMXULMultSelectCntrlEl.h"
-#include "nsIDOMKeyEvent.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMXULElement.h"
 #include "nsIMutableArray.h"
 #include "nsIServiceManager.h"
 
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/KeyboardEventBinding.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULSelectControlAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
--- a/browser/base/content/browser-pageActions.js
+++ b/browser/base/content/browser-pageActions.js
@@ -182,40 +182,44 @@ var BrowserPageActions = {
    *         suitable anchor will be used.
    * @param  panelNode (DOM node, optional)
    *         The panel to use.  This method takes a hands-off approach with
    *         regard to your panel in terms of attributes, styling, etc.
    */
   togglePanelForAction(action, panelNode = null) {
     let aaPanelNode = this.activatedActionPanelNode;
     if (panelNode) {
+      // Note that this particular code path will not prevent the panel from
+      // opening later if PanelMultiView.showPopup was called but the panel has
+      // not been opened yet.
       if (panelNode.state != "closed") {
-        panelNode.hidePopup();
+        PanelMultiView.hidePopup(panelNode);
         return;
       }
       if (aaPanelNode) {
-        aaPanelNode.hidePopup();
+        PanelMultiView.hidePopup(aaPanelNode);
       }
     } else if (aaPanelNode) {
-      aaPanelNode.hidePopup();
+      PanelMultiView.hidePopup(aaPanelNode);
       return;
     } else {
       panelNode = this._makeActivatedActionPanelForAction(action);
     }
 
     // Hide the main panel before showing the action's panel.
-    this.panelNode.hidePopup();
+    PanelMultiView.hidePopup(this.panelNode);
 
     let anchorNode = this.panelAnchorNodeForAction(action);
     anchorNode.setAttribute("open", "true");
     panelNode.addEventListener("popuphiding", () => {
       anchorNode.removeAttribute("open");
     }, { once: true });
 
-    panelNode.openPopup(anchorNode, "bottomcenter topright");
+    PanelMultiView.openPopup(panelNode, anchorNode, "bottomcenter topright")
+                  .catch(Cu.reportError);
   },
 
   _makeActivatedActionPanelForAction(action) {
     let panelNode = document.createElement("panel");
     panelNode.id = this._activatedActionPanelID;
     panelNode.classList.add("cui-widget-panel");
     panelNode.setAttribute("actionID", action.id);
     panelNode.setAttribute("role", "group");
@@ -549,17 +553,17 @@ var BrowserPageActions = {
         buttonNode.closest("panel") == this.panelNode) {
       let panelViewNodeID = this._panelViewNodeIDForActionID(action.id, false);
       let panelViewNode = document.getElementById(panelViewNodeID);
       action.subview.onShowing(panelViewNode);
       this.multiViewNode.showSubView(panelViewNode, buttonNode);
       return;
     }
     // Otherwise, hide the main popup in case it was open:
-    this.panelNode.hidePopup();
+    PanelMultiView.hidePopup(this.panelNode);
 
     // Toggle the activated action's panel if necessary
     if (action.subview || action.wantsIframe) {
       this.togglePanelForAction(action);
       return;
     }
 
     // Otherwise, run the action.
@@ -689,22 +693,22 @@ var BrowserPageActions = {
          event.keyCode != KeyEvent.DOM_VK_RETURN)) {
       return;
     }
 
     // If the activated-action panel is open and anchored to the main button,
     // close it.
     let panelNode = this.activatedActionPanelNode;
     if (panelNode && panelNode.anchorNode.id == this.mainButtonNode.id) {
-      panelNode.hidePopup();
+      PanelMultiView.hidePopup(panelNode);
       return;
     }
 
     if (this.panelNode.state == "open") {
-      this.panelNode.hidePopup();
+      PanelMultiView.hidePopup(this.panelNode);
     } else if (this.panelNode.state == "closed") {
       this.showPanel(event);
     }
   },
 
   /**
    * Show the page action panel
    *
@@ -718,20 +722,20 @@ var BrowserPageActions = {
       action.onShowingInPanel(buttonNode);
     }
 
     this.panelNode.hidden = false;
     this.panelNode.addEventListener("popuphiding", () => {
       this.mainButtonNode.removeAttribute("open");
     }, {once: true});
     this.mainButtonNode.setAttribute("open", "true");
-    this.panelNode.openPopup(this.mainButtonNode, {
+    PanelMultiView.openPopup(this.panelNode, this.mainButtonNode, {
       position: "bottomcenter topright",
       triggerEvent: event,
-    });
+    }).catch(Cu.reportError);
   },
 
   /**
    * Call this on the context menu's popupshowing event.
    *
    * @param  event (DOM event, required)
    *         The popupshowing event.
    * @param  popup (DOM node, required)
@@ -876,20 +880,20 @@ var BrowserPageActionFeedback = {
     return this.feedbackLabel = document.getElementById("pageActionFeedbackMessage");
   },
 
   show(action, event, textContentOverride) {
     this.feedbackLabel.textContent = this.panelNode.getAttribute((textContentOverride || action.id) + "Feedback");
     this.panelNode.hidden = false;
 
     let anchor = BrowserPageActions.panelAnchorNodeForAction(action, event);
-    this.panelNode.openPopup(anchor, {
+    PanelMultiView.openPopup(this.panelNode, anchor, {
       position: "bottomcenter topright",
       triggerEvent: event,
-    });
+    }).catch(Cu.reportError);
 
     this.panelNode.addEventListener("popupshown", () => {
       this.feedbackAnimationBox.setAttribute("animate", "true");
 
       // The timeout value used here allows the panel to stay open for
       // 1 second after the text transition (duration=120ms) has finished.
       setTimeout(() => {
         this.panelNode.hidePopup(true);
@@ -907,47 +911,47 @@ var BrowserPageActionFeedback = {
 // bookmark
 BrowserPageActions.bookmark = {
   onShowingInPanel(buttonNode) {
     // Update the button label via the bookmark observer.
     BookmarkingUI.updateBookmarkPageMenuItem();
   },
 
   onCommand(event, buttonNode) {
-    BrowserPageActions.panelNode.hidePopup();
+    PanelMultiView.hidePopup(BrowserPageActions.panelNode);
     BookmarkingUI.onStarCommand(event);
   },
 };
 
 // copy URL
 BrowserPageActions.copyURL = {
   onPlacedInPanel(buttonNode) {
     let action = PageActions.actionForID("copyURL");
     BrowserPageActions.takeActionTitleFromPanel(action);
   },
 
   onCommand(event, buttonNode) {
-    BrowserPageActions.panelNode.hidePopup();
+    PanelMultiView.hidePopup(BrowserPageActions.panelNode);
     Cc["@mozilla.org/widget/clipboardhelper;1"]
       .getService(Ci.nsIClipboardHelper)
       .copyString(gURLBar.makeURIReadable(gBrowser.selectedBrowser.currentURI).displaySpec);
     let action = PageActions.actionForID("copyURL");
     BrowserPageActionFeedback.show(action, event);
   },
 };
 
 // email link
 BrowserPageActions.emailLink = {
   onPlacedInPanel(buttonNode) {
     let action = PageActions.actionForID("emailLink");
     BrowserPageActions.takeActionTitleFromPanel(action);
   },
 
   onCommand(event, buttonNode) {
-    BrowserPageActions.panelNode.hidePopup();
+    PanelMultiView.hidePopup(BrowserPageActions.panelNode);
     MailIntegration.sendLinkForBrowser(gBrowser.selectedBrowser);
   },
 };
 
 // send to device
 BrowserPageActions.sendToDevice = {
   onPlacedInPanel(buttonNode) {
     let action = PageActions.actionForID("sendToDevice");
@@ -987,17 +991,17 @@ BrowserPageActions.sendToDevice = {
       item.classList.add("pageAction-sendToDevice-device", "subviewbutton");
       if (clientId) {
         item.classList.add("subviewbutton-iconic");
         item.setAttribute("tooltiptext", gSync.formatLastSyncDate(lastModified));
       }
 
       item.addEventListener("command", event => {
         if (panelNode) {
-          panelNode.hidePopup();
+          PanelMultiView.hidePopup(panelNode);
         }
         // There are items in the subview that don't represent devices: "Sign
         // in", "Learn about Sync", etc.  Device items will be .sendtab-target.
         if (event.target.classList.contains("sendtab-target")) {
           let action = PageActions.actionForID("sendToDevice");
           let textOverride = gSync.offline && "sendToDeviceOffline";
           BrowserPageActionFeedback.show(action, event, textOverride);
         }
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -31,16 +31,17 @@ XPCOMUtils.defineLazyModuleGetters(this,
   FormValidationHandler: "resource:///modules/FormValidationHandler.jsm",
   LanguagePrompt: "resource://gre/modules/LanguagePrompt.jsm",
   LightweightThemeManager: "resource://gre/modules/LightweightThemeManager.jsm",
   Log: "resource://gre/modules/Log.jsm",
   LoginManagerParent: "resource://gre/modules/LoginManagerParent.jsm",
   NewTabUtils: "resource://gre/modules/NewTabUtils.jsm",
   PageActions: "resource:///modules/PageActions.jsm",
   PageThumbs: "resource://gre/modules/PageThumbs.jsm",
+  PanelMultiView: "resource:///modules/PanelMultiView.jsm",
   PanelView: "resource:///modules/PanelMultiView.jsm",
   PluralForm: "resource://gre/modules/PluralForm.jsm",
   PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
   ProcessHangMonitor: "resource:///modules/ProcessHangMonitor.jsm",
   PromiseUtils: "resource://gre/modules/PromiseUtils.jsm",
   ReaderMode: "resource://gre/modules/ReaderMode.jsm",
   ReaderParent: "resource:///modules/ReaderParent.jsm",
   RecentWindow: "resource:///modules/RecentWindow.jsm",
@@ -7250,17 +7251,17 @@ var gIdentityHandler = {
 
   /**
    * Handler for mouseclicks on the "More Information" button in the
    * "identity-popup" panel.
    */
   handleMoreInfoClick(event) {
     displaySecurityInfo();
     event.stopPropagation();
-    this._identityPopup.hidePopup();
+    PanelMultiView.hidePopup(this._identityPopup);
   },
 
   showSecuritySubView() {
     this._identityPopupMultiView.showSubView("identity-popup-securityView",
                                              this._popupExpander);
 
     // Elements of hidden views have -moz-user-focus:ignore but setting that
     // per CSS selector doesn't blur a focused element in those hidden views.
@@ -7272,36 +7273,36 @@ var gIdentityHandler = {
     const kMIXED_CONTENT_UNBLOCK_EVENT = 2;
     let histogram =
       Services.telemetry.getHistogramById(
         "MIXED_CONTENT_UNBLOCK_COUNTER");
     histogram.add(kMIXED_CONTENT_UNBLOCK_EVENT);
     // Reload the page with the content unblocked
     BrowserReloadWithFlags(
       Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_MIXED_CONTENT);
-    this._identityPopup.hidePopup();
+    PanelMultiView.hidePopup(this._identityPopup);
   },
 
   enableMixedContentProtection() {
     gBrowser.selectedBrowser.messageManager.sendAsyncMessage(
       "MixedContent:ReenableProtection", {});
     BrowserReload();
-    this._identityPopup.hidePopup();
+    PanelMultiView.hidePopup(this._identityPopup);
   },
 
   removeCertException() {
     if (!this._uriHasHost) {
       Cu.reportError("Trying to revoke a cert exception on a URI without a host?");
       return;
     }
     let host = this._uri.host;
     let port = this._uri.port > 0 ? this._uri.port : 443;
     this._overrideService.clearValidityOverride(host, port);
     BrowserReloadSkipCache();
-    this._identityPopup.hidePopup();
+    PanelMultiView.hidePopup(this._identityPopup);
   },
 
   /**
    * Helper to parse out the important parts of _sslStatus (of the SSL cert in
    * particular) for use in constructing identity UI strings
   */
   getIdentityData() {
     var result = {};
@@ -7357,17 +7358,17 @@ var gIdentityHandler = {
       this._sslStatus.QueryInterface(Ci.nsISSLStatus);
     }
 
     // Then, update the user interface with the available data.
     this.refreshIdentityBlock();
     // Handle a location change while the Control Center is focused
     // by closing the popup (bug 1207542)
     if (shouldHidePopup) {
-      this._identityPopup.hidePopup();
+      PanelMultiView.hidePopup(this._identityPopup);
     }
 
     // NOTE: We do NOT update the identity popup (the control center) when
     // we receive a new security state on the existing page (i.e. from a
     // subframe). If the user opened the popup and looks at the provided
     // information we don't want to suddenly change the panel contents.
 
     // Finally, if there are warnings to issue, issue them
@@ -7821,17 +7822,18 @@ var gIdentityHandler = {
 
     // Update the popup strings
     this.refreshIdentityPopup();
 
     // Add the "open" attribute to the identity box for styling
     this._identityBox.setAttribute("open", "true");
 
     // Now open the popup, anchored off the primary chrome element
-    this._identityPopup.openPopup(this._identityIcon, "bottomcenter topleft");
+    PanelMultiView.openPopup(this._identityPopup, this._identityIcon,
+                             "bottomcenter topleft").catch(Cu.reportError);
   },
 
   onPopupShown(event) {
     if (event.target == this._identityPopup) {
       if (this._popupTriggeredByKeyboard) {
         // Move focus to the next available element in the identity popup.
         // This is required by role=alertdialog and fixes an issue where
         // an already open panel would steal focus from the identity popup.
@@ -7854,17 +7856,17 @@ var gIdentityHandler = {
     let position = elem.compareDocumentPosition(this._identityPopup);
 
     if (!(position & (Node.DOCUMENT_POSITION_CONTAINS |
                       Node.DOCUMENT_POSITION_CONTAINED_BY)) &&
         !this._identityPopup.hasAttribute("noautohide")) {
       // Hide the panel when focusing an element that is
       // neither an ancestor nor descendant unless the panel has
       // @noautohide (e.g. for a tour).
-      this._identityPopup.hidePopup();
+      PanelMultiView.hidePopup(this._identityPopup);
     }
   },
 
   observe(subject, topic, data) {
     if (topic == "perm-changed") {
       this.refreshIdentityBlock();
     }
   },
--- a/browser/base/content/test/general/browser_addCertException.js
+++ b/browser/base/content/test/general/browser_addCertException.js
@@ -9,17 +9,20 @@
 // using the button contained therein to load the certificate exception
 // dialog, using that to add an exception, and finally successfully visiting
 // the site, including showing the right identity box and control center icons.
 add_task(async function() {
   await BrowserTestUtils.openNewForegroundTab(gBrowser);
   await loadBadCertPage("https://expired.example.com");
 
   let { gIdentityHandler } = gBrowser.ownerGlobal;
+  let promisePanelOpen = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popupshown");
   gIdentityHandler._identityBox.click();
+  await promisePanelOpen;
+
   let promiseViewShown = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "ViewShown");
   document.getElementById("identity-popup-security-expander").click();
   await promiseViewShown;
 
   is_element_visible(document.getElementById("connection-icon"), "Should see connection icon");
   let connectionIconImage = gBrowser.ownerGlobal
         .getComputedStyle(document.getElementById("connection-icon"))
         .getPropertyValue("list-style-image");
--- a/browser/base/content/test/performance/browser_appmenu_reflows.js
+++ b/browser/base/content/test/performance/browser_appmenu_reflows.js
@@ -9,17 +9,17 @@
  *
  * See https://developer.mozilla.org/en-US/Firefox/Performance_best_practices_for_Firefox_fe_engineers
  * for tips on how to do that.
  */
 const EXPECTED_APPMENU_OPEN_REFLOWS = [
   {
     stack: [
       "openPopup@chrome://global/content/bindings/popup.xml",
-      "show/</<@chrome://browser/content/customizableui/panelUI.js",
+      "openPopup/this._openPopupPromise<@resource:///modules/PanelMultiView.jsm",
     ],
   },
 
   {
     stack: [
       "get_alignmentPosition@chrome://global/content/bindings/popup.xml",
       "adjustArrowPosition@chrome://global/content/bindings/popup.xml",
       "onxblpopuppositioned@chrome://global/content/bindings/popup.xml",
--- a/browser/base/content/test/siteIdentity/head.js
+++ b/browser/base/content/test/siteIdentity/head.js
@@ -199,17 +199,19 @@ async function assertMixedContentBlockin
     }
     if (passiveLoaded && activeBlocked) {
       is(connectionIconImage, "url(\"chrome://browser/skin/connection-mixed-passive-loaded.svg\")",
         "Using active blocked and passive loaded icon");
     }
   }
 
   // Make sure the identity popup has the correct mixedcontent states
+  let promisePanelOpen = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popupshown");
   gIdentityHandler._identityBox.click();
+  await promisePanelOpen;
   let popupAttr = doc.getElementById("identity-popup").getAttribute("mixedcontent");
   let bodyAttr = doc.getElementById("identity-popup-securityView-body").getAttribute("mixedcontent");
 
   is(popupAttr.includes("active-loaded"), activeLoaded,
       "identity-popup has expected attr for activeLoaded");
   is(bodyAttr.includes("active-loaded"), activeLoaded,
       "securityView-body has expected attr for activeLoaded");
 
--- a/browser/base/content/test/urlbar/browser_page_action_menu.js
+++ b/browser/base/content/test/urlbar/browser_page_action_menu.js
@@ -555,20 +555,20 @@ add_task(async function sendToDevice_inU
 
     // Click it to open its panel.
     let urlbarButton = document.getElementById(
       BrowserPageActions.urlbarButtonNodeIDForActionID(action.id)
     );
     Assert.notEqual(urlbarButton, null, "The urlbar button should exist");
     Assert.ok(!urlbarButton.disabled,
               "The urlbar button should not be disabled");
-    let panelPromise =
-      promisePanelShown(BrowserPageActions._activatedActionPanelID);
     EventUtils.synthesizeMouseAtCenter(urlbarButton, {});
-    await panelPromise;
+    // The panel element for _activatedActionPanelID is created synchronously
+    // only after the associated button has been clicked.
+    await promisePanelShown(BrowserPageActions._activatedActionPanelID);
     Assert.equal(urlbarButton.getAttribute("open"), "true",
       "Button has open attribute");
 
     // The devices should be shown in the subview.
     let expectedItems = [
       {
         id: "pageAction-urlbar-sendToDevice-notReady",
         display: "none",
--- a/browser/base/content/test/urlbar/head.js
+++ b/browser/base/content/test/urlbar/head.js
@@ -260,20 +260,24 @@ function promisePanelShown(panelIDOrNode
 }
 
 function promisePanelHidden(panelIDOrNode) {
   return promisePanelEvent(panelIDOrNode, "popuphidden");
 }
 
 function promisePanelEvent(panelIDOrNode, eventType) {
   return new Promise(resolve => {
-    let panel = typeof(panelIDOrNode) != "string" ? panelIDOrNode :
-                document.getElementById(panelIDOrNode);
-    if (!panel ||
-        (eventType == "popupshown" && panel.state == "open") ||
+    let panel = panelIDOrNode;
+    if (typeof panel == "string") {
+      panel = document.getElementById(panelIDOrNode);
+      if (!panel) {
+        throw new Error(`Panel with ID "${panelIDOrNode}" does not exist.`);
+      }
+    }
+    if ((eventType == "popupshown" && panel.state == "open") ||
         (eventType == "popuphidden" && panel.state == "closed")) {
       executeSoon(resolve);
       return;
     }
     panel.addEventListener(eventType, () => {
       executeSoon(resolve);
     }, { once: true });
   });
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -354,18 +354,18 @@ file, You can obtain one at http://mozil
               this.maybeReplayDeferredKeyEvents();
             }, this._deferredKeyEventTimeoutMs);
           }
         ]]></body>
       </method>
 
       <!-- The enter key is always deferred, so it's not included here. -->
       <field name="_keyCodesToDefer">new Set([
-        Ci.nsIDOMKeyEvent.DOM_VK_DOWN,
-        Ci.nsIDOMKeyEvent.DOM_VK_TAB,
+        KeyboardEvent.DOM_VK_DOWN,
+        KeyboardEvent.DOM_VK_TAB,
       ])</field>
       <field name="_deferredKeyEventQueue">[]</field>
       <field name="_deferredKeyEventTimeout">null</field>
       <field name="_deferredKeyEventTimeoutMs">200</field>
       <field name="_searchStartDate">0</field>
 
       <method name="maybeReplayDeferredKeyEvents">
         <body><![CDATA[
--- a/browser/components/customizableui/CustomizableUI.jsm
+++ b/browser/components/customizableui/CustomizableUI.jsm
@@ -9,16 +9,17 @@ this.EXPORTED_SYMBOLS = ["CustomizableUI
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   SearchWidgetTracker: "resource:///modules/SearchWidgetTracker.jsm",
   CustomizableWidgets: "resource:///modules/CustomizableWidgets.jsm",
   DeferredTask: "resource://gre/modules/DeferredTask.jsm",
+  PanelMultiView: "resource:///modules/PanelMultiView.jsm",
   PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
   ShortcutUtils: "resource://gre/modules/ShortcutUtils.jsm",
   LightweightThemeManager: "resource://gre/modules/LightweightThemeManager.jsm",
 });
 
 XPCOMUtils.defineLazyGetter(this, "gWidgetsBundle", function() {
   const kUrl = "chrome://browser/locale/customizableui/customizableWidgets.properties";
   return Services.strings.createBundle(kUrl);
@@ -1771,17 +1772,17 @@ var CustomizableUIInternal = {
       return true;
     }
     return inInput || !inItem;
   },
 
   hidePanelForNode(aNode) {
     let panel = this._getPanelForNode(aNode);
     if (panel) {
-      panel.hidePopup();
+      PanelMultiView.hidePopup(panel);
     }
   },
 
   maybeAutoHidePanel(aEvent) {
     if (aEvent.type == "keypress") {
       if (aEvent.keyCode != aEvent.DOM_VK_RETURN) {
         return;
       }
@@ -4257,29 +4258,29 @@ OverflowableToolbar.prototype = {
         break;
       case "mousedown":
         if (aEvent.button != 0) {
           break;
         }
         if (aEvent.target == this._chevron) {
           this._onClickChevron(aEvent);
         } else {
-          this._panel.hidePopup();
+          PanelMultiView.hidePopup(this._panel);
         }
         break;
       case "customizationstarting":
         this._disable();
         break;
       case "dragover":
         if (this._enabled) {
           this._showWithTimeout();
         }
         break;
       case "dragend":
-        this._panel.hidePopup();
+        PanelMultiView.hidePopup(this._panel);
         break;
       case "popuphiding":
         this._onPanelHiding(aEvent);
         break;
       case "resize":
         this._onResize(aEvent);
     }
   },
@@ -4295,31 +4296,33 @@ OverflowableToolbar.prototype = {
       let mainViewId = multiview.getAttribute("mainViewId");
       let mainView = doc.getElementById(mainViewId);
       let contextMenu = doc.getElementById(mainView.getAttribute("context"));
       gELS.addSystemEventListener(contextMenu, "command", this, true);
       let anchor = doc.getAnonymousElementByAttribute(this._chevron, "class", "toolbarbutton-icon");
       // Ensure we update the gEditUIVisible flag when opening the popup, in
       // case the edit controls are in it.
       this._panel.addEventListener("popupshowing", () => doc.defaultView.updateEditUIVisibility(), {once: true});
-      this._panel.openPopup(anchor || this._chevron, { triggerEvent: aEvent });
+      PanelMultiView.openPopup(this._panel, anchor || this._chevron, {
+        triggerEvent: aEvent,
+      }).catch(Cu.reportError);
       this._chevron.open = true;
 
       this._panel.addEventListener("popupshown", () => {
         this._panel.addEventListener("dragover", this);
         this._panel.addEventListener("dragend", this);
         resolve();
       }, {once: true});
     });
   },
 
   _onClickChevron(aEvent) {
     if (this._chevron.open) {
-      this._panel.hidePopup();
       this._chevron.open = false;
+      PanelMultiView.hidePopup(this._panel);
     } else if (this._panel.state != "hiding" && !this._chevron.disabled) {
       this.show(aEvent);
     }
   },
 
   _onPanelHiding(aEvent) {
     if (aEvent.target != this._panel) {
       // Ignore context menus, <select> popups, etc.
@@ -4601,16 +4604,16 @@ OverflowableToolbar.prototype = {
   _showWithTimeout() {
     this.show().then(() => {
       let window = this._toolbar.ownerGlobal;
       if (this._hideTimeoutId) {
         window.clearTimeout(this._hideTimeoutId);
       }
       this._hideTimeoutId = window.setTimeout(() => {
         if (!this._panel.firstChild.matches(":hover")) {
-          this._panel.hidePopup();
+          PanelMultiView.hidePopup(this._panel);
         }
       }, OVERFLOW_PANEL_HIDE_DELAY_MS);
     });
   },
 };
 
 CustomizableUIInternal.initialize();
--- a/browser/components/customizableui/PanelMultiView.jsm
+++ b/browser/components/customizableui/PanelMultiView.jsm
@@ -7,19 +7,23 @@
  * panel is opened may slide out to display a subview, which in turn may lead to
  * other subviews in a cascade menu pattern.
  *
  * The <panel> element should contain a <panelmultiview> element. Views are
  * declared using <panelview> elements that are usually children of the main
  * <panelmultiview> element, although they don't need to be, as views can also
  * be imported into the panel from other panels or popup sets.
  *
- * The main view can be declared using the mainViewId attribute, and specific
- * subviews can slide in using the showSubView method. Backwards navigation can
- * be done using the goBack method or through a button in the subview headers.
+ * The panel should be opened asynchronously using the openPopup static method
+ * on the PanelMultiView object. This will display the view specified using the
+ * mainViewId attribute on the contained <panelmultiview> element.
+ *
+ * Specific subviews can slide in using the showSubView method, and backwards
+ * navigation can be done using the goBack method or through a button in the
+ * subview headers.
  *
  * This diagram shows how <panelview> nodes move during navigation:
  *
  *   In this <panelmultiview>     In other panels    Action
  *             ┌───┬───┬───┐        ┌───┬───┐
  *             │(A)│ B │ C │        │ D │ E │          Open panel
  *             └───┴───┴───┘        └───┴───┘
  *         ┌───┬───┬───┐            ┌───┬───┐
@@ -42,16 +46,17 @@
 "use strict";
 
 this.EXPORTED_SYMBOLS = [
   "PanelMultiView",
   "PanelView",
 ];
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.defineModuleGetter(this, "AppConstants",
   "resource://gre/modules/AppConstants.jsm");
 ChromeUtils.defineModuleGetter(this, "BrowserUtils",
   "resource://gre/modules/BrowserUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "CustomizableUI",
   "resource:///modules/CustomizableUI.jsm");
 
 const TRANSITION_PHASES = Object.freeze({
@@ -129,16 +134,51 @@ this.AssociatedToNode = class {
     return event.defaultPrevented;
   }
 };
 
 /**
  * This is associated to <panelmultiview> elements by the panelUI.xml binding.
  */
 this.PanelMultiView = class extends this.AssociatedToNode {
+  /**
+   * Tries to open the specified <panel> and displays the main view specified
+   * with the "mainViewId" attribute on the <panelmultiview> node it contains.
+   *
+   * If the panel does not contain a <panelmultiview>, it is opened directly.
+   * This allows consumers like page actions to accept different panel types.
+   *
+   * @see The non-static openPopup method for details.
+   */
+  static async openPopup(panelNode, ...args) {
+    let panelMultiViewNode = panelNode.querySelector("panelmultiview");
+    if (panelMultiViewNode) {
+      return this.forNode(panelMultiViewNode).openPopup(...args);
+    }
+    panelNode.openPopup(...args);
+    return true;
+  }
+
+  /**
+   * Closes the specified <panel> which contains a <panelmultiview> node.
+   *
+   * If the panel does not contain a <panelmultiview>, it is closed directly.
+   * This allows consumers like page actions to accept different panel types.
+   *
+   * @see The non-static hidePopup method for details.
+   */
+  static hidePopup(panelNode) {
+    let panelMultiViewNode = panelNode.querySelector("panelmultiview");
+    if (panelMultiViewNode) {
+      this.forNode(panelMultiViewNode).hidePopup();
+    } else {
+      panelNode.hidePopup();
+    }
+  }
+
   get _panel() {
     return this.node.parentNode;
   }
 
   get _mainViewId() {
     return this.node.getAttribute("mainViewId");
   }
   get _mainView() {
@@ -189,17 +229,24 @@ this.PanelMultiView = class extends this
   /**
    * @return {Promise} showSubView() returns a promise, which is kept here for
    *                   random access.
    */
   get currentShowPromise() {
     return this._currentShowPromise || Promise.resolve();
   }
 
+  constructor(node) {
+    super(node);
+    this._openPopupPromise = Promise.resolve(false);
+    this._openPopupCancelCallback = () => {};
+  }
+
   connect() {
+    this.connected = true;
     this.knownViews = new Set(Array.from(
       this.node.getElementsByTagName("panelview"),
       node => PanelView.forNode(node)));
     this.openViews = [];
     this.__transitioning = false;
     this.showingSubView = false;
 
     const {document, window} = this;
@@ -259,21 +306,162 @@ this.PanelMultiView = class extends this
 
     this._moveOutKids(this._viewStack);
     this._panel.removeEventListener("mousemove", this);
     this._panel.removeEventListener("popupshowing", this);
     this._panel.removeEventListener("popuppositioned", this);
     this._panel.removeEventListener("popupshown", this);
     this._panel.removeEventListener("popuphidden", this);
     this.window.removeEventListener("keydown", this);
-    this.node = this._viewContainer = this._viewStack = this.__dwu =
+    this.node = this._openPopupPromise = this._openPopupCancelCallback =
+      this._viewContainer = this._viewStack = this.__dwu =
       this._panelViewCache = this._transitionDetails = null;
   }
 
   /**
+   * Tries to open the panel associated with this PanelMultiView, and displays
+   * the main view specified with the "mainViewId" attribute.
+   *
+   * The hidePopup method can be called while the operation is in progress to
+   * prevent the panel from being displayed. View events may also cancel the
+   * operation, so there is no guarantee that the panel will become visible.
+   *
+   * The "popuphidden" event will be fired either when the operation is canceled
+   * or when the popup is closed later. This event can be used for example to
+   * reset the "open" state of the anchor or tear down temporary panels.
+   *
+   * If this method is called again before the panel is shown, the result
+   * depends on the operation currently in progress. If the operation was not
+   * canceled, the panel is opened using the arguments from the previous call,
+   * and this call is ignored. If the operation was canceled, it will be
+   * retried again using the arguments from this call.
+   *
+   * It's not necessary for the <panelmultiview> binding to be connected when
+   * this method is called, but the containing panel must have its display
+   * turned on, for example it shouldn't have the "hidden" attribute.
+   *
+   * @param args
+   *        Arguments to be forwarded to the openPopup method of the panel.
+   *
+   * @resolves With true as soon as the request to display the panel has been
+   *           sent, or with false if the operation was canceled. The state of
+   *           the panel at this point is not guaranteed. It may be still
+   *           showing, completely shown, or completely hidden.
+   * @rejects If an exception is thrown at any point in the process before the
+   *          request to display the panel is sent.
+   */
+  async openPopup(...args) {
+    // Set up the function that allows hidePopup or a second call to showPopup
+    // to cancel the specific panel opening operation that we're starting below.
+    // This function must be synchronous, meaning we can't use Promise.race,
+    // because hidePopup wants to dispatch the "popuphidden" event synchronously
+    // even if the panel has not been opened yet.
+    let canCancel = true;
+    let cancelCallback = this._openPopupCancelCallback = () => {
+      // If the cancel callback is called and the panel hasn't been prepared
+      // yet, cancel showing it. Setting canCancel to false will prevent the
+      // popup from opening. If the panel has opened by the time the cancel
+      // callback is called, canCancel will be false already, and we will not
+      // fire the "popuphidden" event.
+      if (canCancel && this.node) {
+        canCancel = false;
+        this.dispatchCustomEvent("popuphidden");
+      }
+    };
+
+    // Create a promise that is resolved with the result of the last call to
+    // this method, where errors indicate that the panel was not opened.
+    let openPopupPromise = this._openPopupPromise.catch(() => {
+      return false;
+    });
+
+    // Make the preparation done before showing the panel non-reentrant. The
+    // promise created here will be resolved only after the panel preparation is
+    // completed, even if a cancellation request is received in the meantime.
+    return this._openPopupPromise = openPopupPromise.then(async wasShown => {
+      // The panel may have been destroyed in the meantime.
+      if (!this.node) {
+        return false;
+      }
+      // If the panel has been already opened there is nothing more to do. We
+      // check the actual state of the panel rather than setting some state in
+      // our handler of the "popuphidden" event because this has a lower chance
+      // of locking indefinitely if events aren't raised in the expected order.
+      if (wasShown && ["open", "showing"].includes(this._panel.state)) {
+        return true;
+      }
+      try {
+        // Most of the panel elements in the browser window have their display
+        // turned off for performance reasons, typically by setting the "hidden"
+        // attribute. If the caller has just turned on the display, the XBL
+        // binding for the <panelmultiview> element may still be disconnected.
+        // In this case, give the layout code a chance to run.
+        if (!this.connected) {
+          await BrowserUtils.promiseLayoutFlushed(this.document, "layout",
+                                                  () => {});
+          // The XBL binding must be connected at this point. If this is not the
+          // case, the calling code should be updated to unhide the panel.
+          if (!this.connected) {
+            throw new Error("The binding for the panelmultiview element isn't" +
+                            " connected. The containing panel may still have" +
+                            " its display turned off by the hidden attribute.");
+          }
+        }
+        // (The rest of the asynchronous preparation goes here.)
+      } catch (ex) {
+        cancelCallback();
+        throw ex;
+      }
+      // If a cancellation request was received there is nothing more to do.
+      if (!canCancel || !this.node) {
+        return false;
+      }
+      // We have to set canCancel to false before opening the popup because the
+      // hidePopup method of PanelMultiView can be re-entered by event handlers.
+      // If the openPopup call fails, however, we still have to dispatch the
+      // "popuphidden" event even if canCancel was set to false.
+      try {
+        canCancel = false;
+        this._panel.openPopup(...args);
+        return true;
+      } catch (ex) {
+        this.dispatchCustomEvent("popuphidden");
+        throw ex;
+      }
+    });
+  }
+
+  /**
+   * Closes the panel associated with this PanelMultiView.
+   *
+   * If the openPopup method was called but the panel has not been displayed
+   * yet, the operation is canceled and the panel will not be displayed, but the
+   * "popuphidden" event is fired synchronously anyways.
+   *
+   * This means that by the time this method returns all the operations handled
+   * by the "popuphidden" event are completed, for example resetting the "open"
+   * state of the anchor, and the panel is already invisible.
+   */
+  hidePopup() {
+    if (!this.node) {
+      return;
+    }
+
+    // If we have already reached the _panel.openPopup call in the openPopup
+    // method, we can call hidePopup. Otherwise, we have to cancel the latest
+    // request to open the panel, which will have no effect if the request has
+    // been canceled already.
+    if (["open", "showing"].includes(this._panel.state)) {
+      this._panel.hidePopup();
+    } else {
+      this._openPopupCancelCallback();
+    }
+  }
+
+  /**
    * Remove any child subviews into the panelViewCache, to ensure
    * they remain usable even if this panelmultiview instance is removed
    * from the DOM.
    * @param viewNodeContainer the container from which to remove subviews
    */
   _moveOutKids(viewNodeContainer) {
     if (!this._panelViewCache)
       return;
--- a/browser/components/customizableui/content/panelUI.js
+++ b/browser/components/customizableui/content/panelUI.js
@@ -1,16 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 ChromeUtils.defineModuleGetter(this, "AppMenuNotifications",
                                "resource://gre/modules/AppMenuNotifications.jsm");
 ChromeUtils.defineModuleGetter(this, "NewTabUtils",
                                "resource://gre/modules/NewTabUtils.jsm");
+ChromeUtils.defineModuleGetter(this, "PanelMultiView",
+                               "resource:///modules/PanelMultiView.jsm");
 ChromeUtils.defineModuleGetter(this, "ScrollbarSampler",
                                "resource:///modules/ScrollbarSampler.jsm");
 
 /**
  * Maintains the state and dispatches events for the main menu panel.
  */
 
 const PanelUI = {
@@ -210,32 +212,34 @@ const PanelUI = {
           anchor = aEvent.target;
         }
 
         this.panel.addEventListener("popupshown", function() {
           resolve();
         }, {once: true});
 
         anchor = this._getPanelAnchor(anchor);
-        this.panel.openPopup(anchor, { triggerEvent: domEvent });
+        PanelMultiView.openPopup(this.panel, anchor, {
+          triggerEvent: domEvent,
+        }).catch(Cu.reportError);
       }, (reason) => {
         console.error("Error showing the PanelUI menu", reason);
       });
     });
   },
 
   /**
    * If the menu panel is being shown, hide it.
    */
   hide() {
     if (document.documentElement.hasAttribute("customizing")) {
       return;
     }
 
-    this.panel.hidePopup();
+    PanelMultiView.hidePopup(this.panel);
   },
 
   observe(subject, topic, status) {
     switch (topic) {
       case "fullscreen-nav-toolbox":
         if (this._notifications) {
           this._updateNotifications(false);
         }
@@ -462,20 +466,20 @@ const PanelUI = {
       }
 
       let anchor = this._getPanelAnchor(aAnchor);
 
       if (aAnchor != anchor && aAnchor.id) {
         anchor.setAttribute("consumeanchor", aAnchor.id);
       }
 
-      tempPanel.openPopup(anchor, {
+      PanelMultiView.openPopup(tempPanel, anchor, {
         position: "bottomcenter topright",
         triggerEvent: domEvent,
-      });
+      }).catch(Cu.reportError);
     }
   },
 
   /**
    * Sets up the event listener for when the Library view is shown.
    *
    * @param {panelview} viewNode The library view.
    */
@@ -615,19 +619,17 @@ const PanelUI = {
   },
 
   updateOverflowStatus() {
     let hasKids = this.overflowFixedList.hasChildNodes();
     if (hasKids && !this.navbar.hasAttribute("nonemptyoverflow")) {
       this.navbar.setAttribute("nonemptyoverflow", "true");
       this.overflowPanel.setAttribute("hasfixeditems", "true");
     } else if (!hasKids && this.navbar.hasAttribute("nonemptyoverflow")) {
-      if (this.overflowPanel.state != "closed") {
-        this.overflowPanel.hidePopup();
-      }
+      PanelMultiView.hidePopup(this.overflowPanel);
       this.overflowPanel.removeAttribute("hasfixeditems");
       this.navbar.removeAttribute("nonemptyoverflow");
     }
   },
 
   onWidgetAfterDOMChange(aNode, aNextNode, aContainer, aWasRemoval) {
     if (aContainer == this.overflowFixedList) {
       this.updateOverflowStatus();
--- a/browser/components/downloads/content/downloads.js
+++ b/browser/components/downloads/content/downloads.js
@@ -243,17 +243,17 @@ var DownloadsPanel = {
   hidePanel() {
     DownloadsCommon.log("Closing the downloads panel.");
 
     if (!this.isPanelShowing) {
       DownloadsCommon.log("Downloads panel is not showing - nothing to do.");
       return;
     }
 
-    this.panel.hidePopup();
+    PanelMultiView.hidePopup(this.panel);
 
     // Ensure that we allow the panel to be reopened.  Note that, if the popup
     // was open, then the onPopupHidden event handler has already updated the
     // current state, otherwise we must update the state ourselves.
     this._state = this.kStateHidden;
     DownloadsCommon.log("Downloads panel is now closed.");
   },
 
@@ -411,31 +411,31 @@ var DownloadsPanel = {
     }
 
     let richListBox = DownloadsView.richListBox;
 
     // If the user has pressed the tab, up, or down cursor key, start keyboard
     // navigation, thus enabling focusrings in the panel.  Keyboard navigation
     // is automatically disabled if the user moves the mouse on the panel, or
     // if the panel is closed.
-    if ((aEvent.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_TAB ||
-        aEvent.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_UP ||
-        aEvent.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_DOWN) &&
+    if ((aEvent.keyCode == aEvent.DOM_VK_TAB ||
+         aEvent.keyCode == aEvent.DOM_VK_UP ||
+         aEvent.keyCode == aEvent.DOM_VK_DOWN) &&
         !this.keyFocusing) {
       this.keyFocusing = true;
       // Ensure there's a selection, we will show the focus ring around it and
       // prevent the richlistbox from changing the selection.
       if (DownloadsView.richListBox.selectedIndex == -1) {
         DownloadsView.richListBox.selectedIndex = 0;
       }
       aEvent.preventDefault();
       return;
     }
 
-    if (aEvent.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_DOWN) {
+    if (aEvent.keyCode == aEvent.DOM_VK_DOWN) {
       // If the last element in the list is selected, or the footer is already
       // focused, focus the footer.
       if (richListBox.selectedItem === richListBox.lastChild ||
           document.activeElement.parentNode.id === "downloadsFooter") {
         DownloadsFooter.focus();
         aEvent.preventDefault();
         return;
       }
@@ -450,26 +450,26 @@ var DownloadsPanel = {
   /**
    * Keydown listener that listens for the keys to start key focusing, as well
    * as the the accel-V "paste" event, which initiates a file download if the
    * pasted item can be resolved to a URI.
    */
   _onKeyDown(aEvent) {
     // If the footer is focused and the downloads list has at least 1 element
     // in it, focus the last element in the list when going up.
-    if (aEvent.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_UP &&
+    if (aEvent.keyCode == aEvent.DOM_VK_UP &&
         document.activeElement.parentNode.id === "downloadsFooter" &&
         DownloadsView.richListBox.firstChild) {
       DownloadsView.richListBox.focus();
       DownloadsView.richListBox.selectedItem = DownloadsView.richListBox.lastChild;
       aEvent.preventDefault();
       return;
     }
 
-    let pasting = aEvent.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_V &&
+    let pasting = aEvent.keyCode == aEvent.DOM_VK_V &&
                   aEvent.getModifierState("Accel");
 
     if (!pasting) {
       return;
     }
 
     DownloadsCommon.log("Received a paste event.");
 
@@ -563,17 +563,18 @@ var DownloadsPanel = {
       // still exist, and update the allowed items interactions accordingly.  We
       // do these checks on a background thread, and don't prevent the panel to
       // be displayed while these checks are being performed.
       for (let viewItem of DownloadsView._visibleViewItems.values()) {
         viewItem.download.refresh().catch(Cu.reportError);
       }
 
       DownloadsCommon.log("Opening downloads panel popup.");
-      this.panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, null);
+      PanelMultiView.openPopup(this.panel, anchor, "bottomcenter topright",
+                               0, 0, false, null).catch(Cu.reportError);
     });
   },
 };
 
 XPCOMUtils.defineConstant(this, "DownloadsPanel", DownloadsPanel);
 
 // DownloadsOverlayLoader
 
--- a/browser/components/resistfingerprinting/test/browser/browser_spoofing_keyboard_event.js
+++ b/browser/components/resistfingerprinting/test/browser/browser_spoofing_keyboard_event.js
@@ -3,627 +3,626 @@
  *   when fingerprinting resistance is enable.
  */
 
 const CC = Components.Constructor;
 
 const kStrictKeyPressEvents =
   SpecialPowers.getBoolPref("dom.keyboardevent.keypress.dispatch_non_printable_keys_only_system_group_in_content");
 
-const nsIDOMKeyEvent = Ci.nsIDOMKeyEvent;
 const SHOULD_DELIVER_KEYDOWN          = 0x1;
 const SHOULD_DELIVER_KEYPRESS         = 0x2;
 const SHOULD_DELIVER_KEYUP            = 0x4;
 const SHOULD_DELIVER_ALL_FOR_PRINTABLE = SHOULD_DELIVER_KEYDOWN |
                                          SHOULD_DELIVER_KEYPRESS |
                                          SHOULD_DELIVER_KEYUP;
 const SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE =
   kStrictKeyPressEvents ? (SHOULD_DELIVER_KEYDOWN | SHOULD_DELIVER_KEYUP) : SHOULD_DELIVER_ALL_FOR_PRINTABLE;
 
 const TEST_PATH = "http://example.net/browser/browser/" +
                   "components/resistfingerprinting/test/browser/";
 
 // The test cases for english content.
 const TEST_CASES_EN = [
   { key: "KEY_ArrowDown", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "ArrowDown", code: "ArrowDown", charCode: 0, keyCode: nsIDOMKeyEvent.DOM_VK_DOWN,
+    result: { key: "ArrowDown", code: "ArrowDown", charCode: 0, keyCode: KeyboardEvent.DOM_VK_DOWN,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_ArrowLeft", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "ArrowLeft", code: "ArrowLeft", charCode: 0, keyCode: nsIDOMKeyEvent.DOM_VK_LEFT,
+    result: { key: "ArrowLeft", code: "ArrowLeft", charCode: 0, keyCode: KeyboardEvent.DOM_VK_LEFT,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_ArrowRight", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "ArrowRight", code: "ArrowRight", charCode: 0, keyCode: nsIDOMKeyEvent.DOM_VK_RIGHT,
+    result: { key: "ArrowRight", code: "ArrowRight", charCode: 0, keyCode: KeyboardEvent.DOM_VK_RIGHT,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_ArrowUp", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "ArrowUp", code: "ArrowUp", charCode: 0, keyCode: nsIDOMKeyEvent.DOM_VK_UP,
+    result: { key: "ArrowUp", code: "ArrowUp", charCode: 0, keyCode: KeyboardEvent.DOM_VK_UP,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_CapsLock", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_KEYDOWN,
-    result: { key: "CapsLock", code: "CapsLock", charCode: 0, keyCode: nsIDOMKeyEvent.DOM_VK_CAPS_LOCK,
+    result: { key: "CapsLock", code: "CapsLock", charCode: 0, keyCode: KeyboardEvent.DOM_VK_CAPS_LOCK,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_End", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "End", code: "End", charCode: 0, keyCode: nsIDOMKeyEvent.DOM_VK_END,
+    result: { key: "End", code: "End", charCode: 0, keyCode: KeyboardEvent.DOM_VK_END,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_Enter", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "Enter", code: "Enter", charCode: 0, keyCode: nsIDOMKeyEvent.DOM_VK_RETURN,
+    result: { key: "Enter", code: "Enter", charCode: 0, keyCode: KeyboardEvent.DOM_VK_RETURN,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_Escape", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "Escape", code: "Escape", charCode: 0, keyCode: nsIDOMKeyEvent.DOM_VK_ESCAPE,
+    result: { key: "Escape", code: "Escape", charCode: 0, keyCode: KeyboardEvent.DOM_VK_ESCAPE,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_Home", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "Home", code: "Home", charCode: 0, keyCode: nsIDOMKeyEvent.DOM_VK_HOME,
+    result: { key: "Home", code: "Home", charCode: 0, keyCode: KeyboardEvent.DOM_VK_HOME,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_Meta", modifiers: { location: KeyboardEvent.DOM_KEY_LOCATION_LEFT, metaKey: true },
     expectedKeyEvent: SHOULD_DELIVER_KEYDOWN,
-    result: { key: "Meta", code: "OSLeft", charCode: 0, keyCode: nsIDOMKeyEvent.DOM_VK_WIN,
+    result: { key: "Meta", code: "OSLeft", charCode: 0, keyCode: KeyboardEvent.DOM_VK_WIN,
               location: KeyboardEvent.DOM_KEY_LOCATION_LEFT, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_Meta", modifiers: { location: KeyboardEvent.DOM_KEY_LOCATION_RIGHT, metaKey: true },
     expectedKeyEvent: SHOULD_DELIVER_KEYDOWN,
-    result: { key: "Meta", code: "OSRight", charCode: 0, keyCode: nsIDOMKeyEvent.DOM_VK_WIN,
+    result: { key: "Meta", code: "OSRight", charCode: 0, keyCode: KeyboardEvent.DOM_VK_WIN,
               location: KeyboardEvent.DOM_KEY_LOCATION_RIGHT, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_OS", modifiers: { location: KeyboardEvent.DOM_KEY_LOCATION_LEFT, osKey: true },
     expectedKeyEvent: SHOULD_DELIVER_KEYDOWN,
-    result: { key: "OS", code: "OSLeft", charCode: 0, keyCode: nsIDOMKeyEvent.DOM_VK_WIN,
+    result: { key: "OS", code: "OSLeft", charCode: 0, keyCode: KeyboardEvent.DOM_VK_WIN,
               location: KeyboardEvent.DOM_KEY_LOCATION_LEFT, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_OS", modifiers: { location: KeyboardEvent.DOM_KEY_LOCATION_RIGHT, osKey: true },
     expectedKeyEvent: SHOULD_DELIVER_KEYDOWN,
-    result: { key: "OS", code: "OSRight", charCode: 0, keyCode: nsIDOMKeyEvent.DOM_VK_WIN,
+    result: { key: "OS", code: "OSRight", charCode: 0, keyCode: KeyboardEvent.DOM_VK_WIN,
               location: KeyboardEvent.DOM_KEY_LOCATION_RIGHT, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_PageDown", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "PageDown", code: "PageDown", charCode: 0, keyCode: nsIDOMKeyEvent.DOM_VK_PAGE_DOWN,
+    result: { key: "PageDown", code: "PageDown", charCode: 0, keyCode: KeyboardEvent.DOM_VK_PAGE_DOWN,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_PageUp", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "PageUp", code: "PageUp", charCode: 0, keyCode: nsIDOMKeyEvent.DOM_VK_PAGE_UP,
+    result: { key: "PageUp", code: "PageUp", charCode: 0, keyCode: KeyboardEvent.DOM_VK_PAGE_UP,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: " ", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: " ", code: "Space", charCode: 32, keyCode: nsIDOMKeyEvent.DOM_VK_SPACE,
+    result: { key: " ", code: "Space", charCode: 32, keyCode: KeyboardEvent.DOM_VK_SPACE,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: ",", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: ",", code: "Comma", charCode: 44, keyCode: nsIDOMKeyEvent.DOM_VK_COMMA,
+    result: { key: ",", code: "Comma", charCode: 44, keyCode: KeyboardEvent.DOM_VK_COMMA,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "<", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "<", code: "Comma", charCode: 60, keyCode: nsIDOMKeyEvent.DOM_VK_COMMA,
+    result: { key: "<", code: "Comma", charCode: 60, keyCode: KeyboardEvent.DOM_VK_COMMA,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "[", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "[", code: "BracketLeft", charCode: 91, keyCode: nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET,
+    result: { key: "[", code: "BracketLeft", charCode: 91, keyCode: KeyboardEvent.DOM_VK_OPEN_BRACKET,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "{", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "{", code: "BracketLeft", charCode: 123, keyCode: nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET,
+    result: { key: "{", code: "BracketLeft", charCode: 123, keyCode: KeyboardEvent.DOM_VK_OPEN_BRACKET,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "]", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "]", code: "BracketRight", charCode: 93, keyCode: nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET,
+    result: { key: "]", code: "BracketRight", charCode: 93, keyCode: KeyboardEvent.DOM_VK_CLOSE_BRACKET,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "}", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "}", code: "BracketRight", charCode: 125, keyCode: nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET,
+    result: { key: "}", code: "BracketRight", charCode: 125, keyCode: KeyboardEvent.DOM_VK_CLOSE_BRACKET,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "\\", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "\\", code: "Backslash", charCode: 92, keyCode: nsIDOMKeyEvent.DOM_VK_BACK_SLASH,
+    result: { key: "\\", code: "Backslash", charCode: 92, keyCode: KeyboardEvent.DOM_VK_BACK_SLASH,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "|", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "|", code: "Backslash", charCode: 124, keyCode: nsIDOMKeyEvent.DOM_VK_BACK_SLASH,
+    result: { key: "|", code: "Backslash", charCode: 124, keyCode: KeyboardEvent.DOM_VK_BACK_SLASH,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: ";", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: ";", code: "Semicolon", charCode: 59, keyCode: nsIDOMKeyEvent.DOM_VK_SEMICOLON,
+    result: { key: ";", code: "Semicolon", charCode: 59, keyCode: KeyboardEvent.DOM_VK_SEMICOLON,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: ":", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: ":", code: "Semicolon", charCode: 58, keyCode: nsIDOMKeyEvent.DOM_VK_SEMICOLON,
+    result: { key: ":", code: "Semicolon", charCode: 58, keyCode: KeyboardEvent.DOM_VK_SEMICOLON,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: ".", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: ".", code: "Period", charCode: 46, keyCode: nsIDOMKeyEvent.DOM_VK_PERIOD,
+    result: { key: ".", code: "Period", charCode: 46, keyCode: KeyboardEvent.DOM_VK_PERIOD,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: ">", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: ">", code: "Period", charCode: 62, keyCode: nsIDOMKeyEvent.DOM_VK_PERIOD,
+    result: { key: ">", code: "Period", charCode: 62, keyCode: KeyboardEvent.DOM_VK_PERIOD,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "/", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "/", code: "Slash", charCode: 47, keyCode: nsIDOMKeyEvent.DOM_VK_SLASH,
+    result: { key: "/", code: "Slash", charCode: 47, keyCode: KeyboardEvent.DOM_VK_SLASH,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "?", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "?", code: "Slash", charCode: 63, keyCode: nsIDOMKeyEvent.DOM_VK_SLASH,
+    result: { key: "?", code: "Slash", charCode: 63, keyCode: KeyboardEvent.DOM_VK_SLASH,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "'", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "'", code: "Quote", charCode: 39, keyCode: nsIDOMKeyEvent.DOM_VK_QUOTE,
+    result: { key: "'", code: "Quote", charCode: 39, keyCode: KeyboardEvent.DOM_VK_QUOTE,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "\"", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "\"", code: "Quote", charCode: 34, keyCode: nsIDOMKeyEvent.DOM_VK_QUOTE,
+    result: { key: "\"", code: "Quote", charCode: 34, keyCode: KeyboardEvent.DOM_VK_QUOTE,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "-", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "-", code: "Minus", charCode: 45, keyCode: nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS,
+    result: { key: "-", code: "Minus", charCode: 45, keyCode: KeyboardEvent.DOM_VK_HYPHEN_MINUS,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "_", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "_", code: "Minus", charCode: 95, keyCode: nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS,
+    result: { key: "_", code: "Minus", charCode: 95, keyCode: KeyboardEvent.DOM_VK_HYPHEN_MINUS,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "=", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "=", code: "Equal", charCode: 61, keyCode: nsIDOMKeyEvent.DOM_VK_EQUALS,
+    result: { key: "=", code: "Equal", charCode: 61, keyCode: KeyboardEvent.DOM_VK_EQUALS,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "+", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "+", code: "Equal", charCode: 43, keyCode: nsIDOMKeyEvent.DOM_VK_EQUALS,
+    result: { key: "+", code: "Equal", charCode: 43, keyCode: KeyboardEvent.DOM_VK_EQUALS,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "a", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "a", code: "KeyA", charCode: 97, keyCode: nsIDOMKeyEvent.DOM_VK_A,
+    result: { key: "a", code: "KeyA", charCode: 97, keyCode: KeyboardEvent.DOM_VK_A,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "A", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "A", code: "KeyA", charCode: 65, keyCode: nsIDOMKeyEvent.DOM_VK_A,
+    result: { key: "A", code: "KeyA", charCode: 65, keyCode: KeyboardEvent.DOM_VK_A,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "b", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "b", code: "KeyB", charCode: 98, keyCode: nsIDOMKeyEvent.DOM_VK_B,
+    result: { key: "b", code: "KeyB", charCode: 98, keyCode: KeyboardEvent.DOM_VK_B,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "B", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "B", code: "KeyB", charCode: 66, keyCode: nsIDOMKeyEvent.DOM_VK_B,
+    result: { key: "B", code: "KeyB", charCode: 66, keyCode: KeyboardEvent.DOM_VK_B,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "c", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "c", code: "KeyC", charCode: 99, keyCode: nsIDOMKeyEvent.DOM_VK_C,
+    result: { key: "c", code: "KeyC", charCode: 99, keyCode: KeyboardEvent.DOM_VK_C,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "C", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "C", code: "KeyC", charCode: 67, keyCode: nsIDOMKeyEvent.DOM_VK_C,
+    result: { key: "C", code: "KeyC", charCode: 67, keyCode: KeyboardEvent.DOM_VK_C,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "d", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "d", code: "KeyD", charCode: 100, keyCode: nsIDOMKeyEvent.DOM_VK_D,
+    result: { key: "d", code: "KeyD", charCode: 100, keyCode: KeyboardEvent.DOM_VK_D,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "D", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "D", code: "KeyD", charCode: 68, keyCode: nsIDOMKeyEvent.DOM_VK_D,
+    result: { key: "D", code: "KeyD", charCode: 68, keyCode: KeyboardEvent.DOM_VK_D,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "e", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "e", code: "KeyE", charCode: 101, keyCode: nsIDOMKeyEvent.DOM_VK_E,
+    result: { key: "e", code: "KeyE", charCode: 101, keyCode: KeyboardEvent.DOM_VK_E,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "E", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "E", code: "KeyE", charCode: 69, keyCode: nsIDOMKeyEvent.DOM_VK_E,
+    result: { key: "E", code: "KeyE", charCode: 69, keyCode: KeyboardEvent.DOM_VK_E,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "f", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "f", code: "KeyF", charCode: 102, keyCode: nsIDOMKeyEvent.DOM_VK_F,
+    result: { key: "f", code: "KeyF", charCode: 102, keyCode: KeyboardEvent.DOM_VK_F,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "F", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "F", code: "KeyF", charCode: 70, keyCode: nsIDOMKeyEvent.DOM_VK_F,
+    result: { key: "F", code: "KeyF", charCode: 70, keyCode: KeyboardEvent.DOM_VK_F,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "g", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "g", code: "KeyG", charCode: 103, keyCode: nsIDOMKeyEvent.DOM_VK_G,
+    result: { key: "g", code: "KeyG", charCode: 103, keyCode: KeyboardEvent.DOM_VK_G,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "G", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "G", code: "KeyG", charCode: 71, keyCode: nsIDOMKeyEvent.DOM_VK_G,
+    result: { key: "G", code: "KeyG", charCode: 71, keyCode: KeyboardEvent.DOM_VK_G,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "h", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "h", code: "KeyH", charCode: 104, keyCode: nsIDOMKeyEvent.DOM_VK_H,
+    result: { key: "h", code: "KeyH", charCode: 104, keyCode: KeyboardEvent.DOM_VK_H,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "H", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "H", code: "KeyH", charCode: 72, keyCode: nsIDOMKeyEvent.DOM_VK_H,
+    result: { key: "H", code: "KeyH", charCode: 72, keyCode: KeyboardEvent.DOM_VK_H,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "i", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "i", code: "KeyI", charCode: 105, keyCode: nsIDOMKeyEvent.DOM_VK_I,
+    result: { key: "i", code: "KeyI", charCode: 105, keyCode: KeyboardEvent.DOM_VK_I,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "I", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "I", code: "KeyI", charCode: 73, keyCode: nsIDOMKeyEvent.DOM_VK_I,
+    result: { key: "I", code: "KeyI", charCode: 73, keyCode: KeyboardEvent.DOM_VK_I,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "j", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "j", code: "KeyJ", charCode: 106, keyCode: nsIDOMKeyEvent.DOM_VK_J,
+    result: { key: "j", code: "KeyJ", charCode: 106, keyCode: KeyboardEvent.DOM_VK_J,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "J", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "J", code: "KeyJ", charCode: 74, keyCode: nsIDOMKeyEvent.DOM_VK_J,
+    result: { key: "J", code: "KeyJ", charCode: 74, keyCode: KeyboardEvent.DOM_VK_J,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "k", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "k", code: "KeyK", charCode: 107, keyCode: nsIDOMKeyEvent.DOM_VK_K,
+    result: { key: "k", code: "KeyK", charCode: 107, keyCode: KeyboardEvent.DOM_VK_K,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "K", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "K", code: "KeyK", charCode: 75, keyCode: nsIDOMKeyEvent.DOM_VK_K,
+    result: { key: "K", code: "KeyK", charCode: 75, keyCode: KeyboardEvent.DOM_VK_K,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "l", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "l", code: "KeyL", charCode: 108, keyCode: nsIDOMKeyEvent.DOM_VK_L,
+    result: { key: "l", code: "KeyL", charCode: 108, keyCode: KeyboardEvent.DOM_VK_L,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "L", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "L", code: "KeyL", charCode: 76, keyCode: nsIDOMKeyEvent.DOM_VK_L,
+    result: { key: "L", code: "KeyL", charCode: 76, keyCode: KeyboardEvent.DOM_VK_L,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "m", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "m", code: "KeyM", charCode: 109, keyCode: nsIDOMKeyEvent.DOM_VK_M,
+    result: { key: "m", code: "KeyM", charCode: 109, keyCode: KeyboardEvent.DOM_VK_M,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "M", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "M", code: "KeyM", charCode: 77, keyCode: nsIDOMKeyEvent.DOM_VK_M,
+    result: { key: "M", code: "KeyM", charCode: 77, keyCode: KeyboardEvent.DOM_VK_M,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "n", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "n", code: "KeyN", charCode: 110, keyCode: nsIDOMKeyEvent.DOM_VK_N,
+    result: { key: "n", code: "KeyN", charCode: 110, keyCode: KeyboardEvent.DOM_VK_N,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "N", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "N", code: "KeyN", charCode: 78, keyCode: nsIDOMKeyEvent.DOM_VK_N,
+    result: { key: "N", code: "KeyN", charCode: 78, keyCode: KeyboardEvent.DOM_VK_N,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "o", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "o", code: "KeyO", charCode: 111, keyCode: nsIDOMKeyEvent.DOM_VK_O,
+    result: { key: "o", code: "KeyO", charCode: 111, keyCode: KeyboardEvent.DOM_VK_O,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "O", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "O", code: "KeyO", charCode: 79, keyCode: nsIDOMKeyEvent.DOM_VK_O,
+    result: { key: "O", code: "KeyO", charCode: 79, keyCode: KeyboardEvent.DOM_VK_O,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "p", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "p", code: "KeyP", charCode: 112, keyCode: nsIDOMKeyEvent.DOM_VK_P,
+    result: { key: "p", code: "KeyP", charCode: 112, keyCode: KeyboardEvent.DOM_VK_P,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "P", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "P", code: "KeyP", charCode: 80, keyCode: nsIDOMKeyEvent.DOM_VK_P,
+    result: { key: "P", code: "KeyP", charCode: 80, keyCode: KeyboardEvent.DOM_VK_P,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "q", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "q", code: "KeyQ", charCode: 113, keyCode: nsIDOMKeyEvent.DOM_VK_Q,
+    result: { key: "q", code: "KeyQ", charCode: 113, keyCode: KeyboardEvent.DOM_VK_Q,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "Q", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "Q", code: "KeyQ", charCode: 81, keyCode: nsIDOMKeyEvent.DOM_VK_Q,
+    result: { key: "Q", code: "KeyQ", charCode: 81, keyCode: KeyboardEvent.DOM_VK_Q,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "r", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "r", code: "KeyR", charCode: 114, keyCode: nsIDOMKeyEvent.DOM_VK_R,
+    result: { key: "r", code: "KeyR", charCode: 114, keyCode: KeyboardEvent.DOM_VK_R,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "R", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "R", code: "KeyR", charCode: 82, keyCode: nsIDOMKeyEvent.DOM_VK_R,
+    result: { key: "R", code: "KeyR", charCode: 82, keyCode: KeyboardEvent.DOM_VK_R,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "s", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "s", code: "KeyS", charCode: 115, keyCode: nsIDOMKeyEvent.DOM_VK_S,
+    result: { key: "s", code: "KeyS", charCode: 115, keyCode: KeyboardEvent.DOM_VK_S,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "S", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "S", code: "KeyS", charCode: 83, keyCode: nsIDOMKeyEvent.DOM_VK_S,
+    result: { key: "S", code: "KeyS", charCode: 83, keyCode: KeyboardEvent.DOM_VK_S,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "t", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "t", code: "KeyT", charCode: 116, keyCode: nsIDOMKeyEvent.DOM_VK_T,
+    result: { key: "t", code: "KeyT", charCode: 116, keyCode: KeyboardEvent.DOM_VK_T,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "T", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "T", code: "KeyT", charCode: 84, keyCode: nsIDOMKeyEvent.DOM_VK_T,
+    result: { key: "T", code: "KeyT", charCode: 84, keyCode: KeyboardEvent.DOM_VK_T,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "u", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "u", code: "KeyU", charCode: 117, keyCode: nsIDOMKeyEvent.DOM_VK_U,
+    result: { key: "u", code: "KeyU", charCode: 117, keyCode: KeyboardEvent.DOM_VK_U,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "U", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "U", code: "KeyU", charCode: 85, keyCode: nsIDOMKeyEvent.DOM_VK_U,
+    result: { key: "U", code: "KeyU", charCode: 85, keyCode: KeyboardEvent.DOM_VK_U,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "v", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "v", code: "KeyV", charCode: 118, keyCode: nsIDOMKeyEvent.DOM_VK_V,
+    result: { key: "v", code: "KeyV", charCode: 118, keyCode: KeyboardEvent.DOM_VK_V,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "V", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "V", code: "KeyV", charCode: 86, keyCode: nsIDOMKeyEvent.DOM_VK_V,
+    result: { key: "V", code: "KeyV", charCode: 86, keyCode: KeyboardEvent.DOM_VK_V,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "w", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "w", code: "KeyW", charCode: 119, keyCode: nsIDOMKeyEvent.DOM_VK_W,
+    result: { key: "w", code: "KeyW", charCode: 119, keyCode: KeyboardEvent.DOM_VK_W,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "W", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "W", code: "KeyW", charCode: 87, keyCode: nsIDOMKeyEvent.DOM_VK_W,
+    result: { key: "W", code: "KeyW", charCode: 87, keyCode: KeyboardEvent.DOM_VK_W,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "x", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "x", code: "KeyX", charCode: 120, keyCode: nsIDOMKeyEvent.DOM_VK_X,
+    result: { key: "x", code: "KeyX", charCode: 120, keyCode: KeyboardEvent.DOM_VK_X,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "X", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "X", code: "KeyX", charCode: 88, keyCode: nsIDOMKeyEvent.DOM_VK_X,
+    result: { key: "X", code: "KeyX", charCode: 88, keyCode: KeyboardEvent.DOM_VK_X,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "y", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "y", code: "KeyY", charCode: 121, keyCode: nsIDOMKeyEvent.DOM_VK_Y,
+    result: { key: "y", code: "KeyY", charCode: 121, keyCode: KeyboardEvent.DOM_VK_Y,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "Y", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "Y", code: "KeyY", charCode: 89, keyCode: nsIDOMKeyEvent.DOM_VK_Y,
+    result: { key: "Y", code: "KeyY", charCode: 89, keyCode: KeyboardEvent.DOM_VK_Y,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "z", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "z", code: "KeyZ", charCode: 122, keyCode: nsIDOMKeyEvent.DOM_VK_Z,
+    result: { key: "z", code: "KeyZ", charCode: 122, keyCode: KeyboardEvent.DOM_VK_Z,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "Z", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "Z", code: "KeyZ", charCode: 90, keyCode: nsIDOMKeyEvent.DOM_VK_Z,
+    result: { key: "Z", code: "KeyZ", charCode: 90, keyCode: KeyboardEvent.DOM_VK_Z,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "0", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "0", code: "Digit0", charCode: 48, keyCode: nsIDOMKeyEvent.DOM_VK_0,
+    result: { key: "0", code: "Digit0", charCode: 48, keyCode: KeyboardEvent.DOM_VK_0,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "1", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "1", code: "Digit1", charCode: 49, keyCode: nsIDOMKeyEvent.DOM_VK_1,
+    result: { key: "1", code: "Digit1", charCode: 49, keyCode: KeyboardEvent.DOM_VK_1,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "2", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "2", code: "Digit2", charCode: 50, keyCode: nsIDOMKeyEvent.DOM_VK_2,
+    result: { key: "2", code: "Digit2", charCode: 50, keyCode: KeyboardEvent.DOM_VK_2,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "3", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "3", code: "Digit3", charCode: 51, keyCode: nsIDOMKeyEvent.DOM_VK_3,
+    result: { key: "3", code: "Digit3", charCode: 51, keyCode: KeyboardEvent.DOM_VK_3,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "4", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "4", code: "Digit4", charCode: 52, keyCode: nsIDOMKeyEvent.DOM_VK_4,
+    result: { key: "4", code: "Digit4", charCode: 52, keyCode: KeyboardEvent.DOM_VK_4,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "5", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "5", code: "Digit5", charCode: 53, keyCode: nsIDOMKeyEvent.DOM_VK_5,
+    result: { key: "5", code: "Digit5", charCode: 53, keyCode: KeyboardEvent.DOM_VK_5,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "6", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "6", code: "Digit6", charCode: 54, keyCode: nsIDOMKeyEvent.DOM_VK_6,
+    result: { key: "6", code: "Digit6", charCode: 54, keyCode: KeyboardEvent.DOM_VK_6,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "7", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "7", code: "Digit7", charCode: 55, keyCode: nsIDOMKeyEvent.DOM_VK_7,
+    result: { key: "7", code: "Digit7", charCode: 55, keyCode: KeyboardEvent.DOM_VK_7,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "8", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "8", code: "Digit8", charCode: 56, keyCode: nsIDOMKeyEvent.DOM_VK_8,
+    result: { key: "8", code: "Digit8", charCode: 56, keyCode: KeyboardEvent.DOM_VK_8,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "9", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "9", code: "Digit9", charCode: 57, keyCode: nsIDOMKeyEvent.DOM_VK_9,
+    result: { key: "9", code: "Digit9", charCode: 57, keyCode: KeyboardEvent.DOM_VK_9,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: ")", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: ")", code: "Digit0", charCode: 41, keyCode: nsIDOMKeyEvent.DOM_VK_0,
+    result: { key: ")", code: "Digit0", charCode: 41, keyCode: KeyboardEvent.DOM_VK_0,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "!", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "!", code: "Digit1", charCode: 33, keyCode: nsIDOMKeyEvent.DOM_VK_1,
+    result: { key: "!", code: "Digit1", charCode: 33, keyCode: KeyboardEvent.DOM_VK_1,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "@", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "@", code: "Digit2", charCode: 64, keyCode: nsIDOMKeyEvent.DOM_VK_2,
+    result: { key: "@", code: "Digit2", charCode: 64, keyCode: KeyboardEvent.DOM_VK_2,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "#", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "#", code: "Digit3", charCode: 35, keyCode: nsIDOMKeyEvent.DOM_VK_3,
+    result: { key: "#", code: "Digit3", charCode: 35, keyCode: KeyboardEvent.DOM_VK_3,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "$", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "$", code: "Digit4", charCode: 36, keyCode: nsIDOMKeyEvent.DOM_VK_4,
+    result: { key: "$", code: "Digit4", charCode: 36, keyCode: KeyboardEvent.DOM_VK_4,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "%", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "%", code: "Digit5", charCode: 37, keyCode: nsIDOMKeyEvent.DOM_VK_5,
+    result: { key: "%", code: "Digit5", charCode: 37, keyCode: KeyboardEvent.DOM_VK_5,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "^", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "^", code: "Digit6", charCode: 94, keyCode: nsIDOMKeyEvent.DOM_VK_6,
+    result: { key: "^", code: "Digit6", charCode: 94, keyCode: KeyboardEvent.DOM_VK_6,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "&", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "&", code: "Digit7", charCode: 38, keyCode: nsIDOMKeyEvent.DOM_VK_7,
+    result: { key: "&", code: "Digit7", charCode: 38, keyCode: KeyboardEvent.DOM_VK_7,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "*", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "*", code: "Digit8", charCode: 42, keyCode: nsIDOMKeyEvent.DOM_VK_8,
+    result: { key: "*", code: "Digit8", charCode: 42, keyCode: KeyboardEvent.DOM_VK_8,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "(", modifiers: { shiftKey: true }, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_PRINTABLE,
-    result: { key: "(", code: "Digit9", charCode: 40, keyCode: nsIDOMKeyEvent.DOM_VK_9,
+    result: { key: "(", code: "Digit9", charCode: 40, keyCode: KeyboardEvent.DOM_VK_9,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: true,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_F1", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "F1", code: "F1", charCode: 112, keyCode: nsIDOMKeyEvent.DOM_VK_F1,
+    result: { key: "F1", code: "F1", charCode: 112, keyCode: KeyboardEvent.DOM_VK_F1,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_F2", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "F2", code: "F2", charCode: 113, keyCode: nsIDOMKeyEvent.DOM_VK_F2,
+    result: { key: "F2", code: "F2", charCode: 113, keyCode: KeyboardEvent.DOM_VK_F2,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_F3", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "F3", code: "F3", charCode: 114, keyCode: nsIDOMKeyEvent.DOM_VK_F3,
+    result: { key: "F3", code: "F3", charCode: 114, keyCode: KeyboardEvent.DOM_VK_F3,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_F4", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "F4", code: "F4", charCode: 115, keyCode: nsIDOMKeyEvent.DOM_VK_F4,
+    result: { key: "F4", code: "F4", charCode: 115, keyCode: KeyboardEvent.DOM_VK_F4,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_F5", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "F5", code: "F5", charCode: 116, keyCode: nsIDOMKeyEvent.DOM_VK_F5,
+    result: { key: "F5", code: "F5", charCode: 116, keyCode: KeyboardEvent.DOM_VK_F5,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_F7", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "F7", code: "F7", charCode: 118, keyCode: nsIDOMKeyEvent.DOM_VK_F7,
+    result: { key: "F7", code: "F7", charCode: 118, keyCode: KeyboardEvent.DOM_VK_F7,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_F8", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "F8", code: "F8", charCode: 119, keyCode: nsIDOMKeyEvent.DOM_VK_F8,
+    result: { key: "F8", code: "F8", charCode: 119, keyCode: KeyboardEvent.DOM_VK_F8,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_F9", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "F9", code: "F9", charCode: 120, keyCode: nsIDOMKeyEvent.DOM_VK_F9,
+    result: { key: "F9", code: "F9", charCode: 120, keyCode: KeyboardEvent.DOM_VK_F9,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_F10", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "F10", code: "F10", charCode: 121, keyCode: nsIDOMKeyEvent.DOM_VK_F10,
+    result: { key: "F10", code: "F10", charCode: 121, keyCode: KeyboardEvent.DOM_VK_F10,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_F11", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "F11", code: "F11", charCode: 122, keyCode: nsIDOMKeyEvent.DOM_VK_F11,
+    result: { key: "F11", code: "F11", charCode: 122, keyCode: KeyboardEvent.DOM_VK_F11,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
   { key: "KEY_F12", modifiers: {}, expectedKeyEvent: SHOULD_DELIVER_ALL_FOR_NON_PRINTABLE,
-    result: { key: "F12", code: "F12", charCode: 123, keyCode: nsIDOMKeyEvent.DOM_VK_F12,
+    result: { key: "F12", code: "F12", charCode: 123, keyCode: KeyboardEvent.DOM_VK_F12,
               location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, altKey: false, shiftKey: false,
               ctrlKey: false, altGraphKey: false }
   },
 ];
 
 async function testKeyEvent(aTab, aTestCase) {
   // Prepare all expected key events.
   let testEvents = [];
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -2021,17 +2021,17 @@
               this.selectedButton = null;
               return false;
             }
             this.popup.selectedIndex = -1;
             this.advanceSelection(!event.shiftKey, true, false);
             return !!this.selectedButton;
           }
 
-          if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_UP) {
+          if (event.keyCode == KeyboardEvent.DOM_VK_UP) {
             if (event.altKey) {
               // Keep the currently selected result in the list (if any) as a
               // secondary "alt" selection and move the selection up within the
               // buttons.
               this.advanceSelection(false, false, false);
               return true;
             }
             if (numListItems == 0) {
@@ -2069,17 +2069,17 @@
               this.selectedButton = null;
               return false;
             }
             // Moving up/left within the buttons.
             this.advanceSelection(false, true, false);
             return true;
           }
 
-          if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_DOWN) {
+          if (event.keyCode == KeyboardEvent.DOM_VK_DOWN) {
             if (event.altKey) {
               // Keep the currently selected result in the list (if any) as a
               // secondary "alt" selection and move the selection down within
               // the buttons.
               this.advanceSelection(true, false, false);
               return true;
             }
             if (numListItems == 0) {
@@ -2123,27 +2123,27 @@
               }
               // Moving down/right within the buttons.
               this.advanceSelection(true, true, false);
               return true;
             }
             return false;
           }
 
-          if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_LEFT) {
+          if (event.keyCode == KeyboardEvent.DOM_VK_LEFT) {
             if (this.selectedButton &&
                 (this.compact || this.selectedButton.engine)) {
               // Moving left within the buttons.
               this.advanceSelection(false, this.compact, true);
               return true;
             }
             return false;
           }
 
-          if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_RIGHT) {
+          if (event.keyCode == KeyboardEvent.DOM_VK_RIGHT) {
             if (this.selectedButton &&
                 (this.compact || this.selectedButton.engine)) {
               // Moving right within the buttons.
               this.advanceSelection(true, this.compact, true);
               return true;
             }
             return false;
           }
--- a/browser/extensions/formautofill/FormAutofillContent.jsm
+++ b/browser/extensions/formautofill/FormAutofillContent.jsm
@@ -615,17 +615,17 @@ var FormAutofillContent = {
               .QueryInterface(Ci.nsIInterfaceRequestor)
               .getInterface(Ci.nsIContentFrameMessageManager);
   },
 
   _onKeyDown(e) {
     let lastAutoCompleteResult = ProfileAutocomplete.lastProfileAutoCompleteResult;
     let focusedInput = FormAutofillContent.activeInput;
 
-    if (e.keyCode != Ci.nsIDOMKeyEvent.DOM_VK_RETURN || !lastAutoCompleteResult ||
+    if (e.keyCode != e.DOM_VK_RETURN || !lastAutoCompleteResult ||
         !focusedInput || focusedInput != ProfileAutocomplete.lastProfileAutoCompleteFocusedInput) {
       return;
     }
 
     let selectedIndex = ProfileAutocomplete._getSelectedIndex(e.target.ownerGlobal);
     let selectedRowStyle = lastAutoCompleteResult.getStyleAt(selectedIndex);
     focusedInput.addEventListener("DOMAutoComplete", () => {
       if (selectedRowStyle == "autofill-footer") {
--- a/browser/modules/test/browser/browser_PageActions.js
+++ b/browser/modules/test/browser/browser_PageActions.js
@@ -426,17 +426,17 @@ add_task(async function withSubview() {
                "onSubviewPlacedCount should be inc'ed");
   Assert.equal(onSubviewShowingCount, 2,
                "onSubviewShowingCount should be inc'ed");
   let panelViewButtonNodeUrlbar =
     document.getElementById(panelViewButtonIDUrlbar);
   Assert.notEqual(panelViewButtonNodeUrlbar, null, "panelViewButtonNodeUrlbar");
   onButtonCommandExpectedButtonID = panelViewButtonIDUrlbar;
   EventUtils.synthesizeMouseAtCenter(panelViewButtonNodeUrlbar, {});
-  await promisePanelHidden(BrowserPageActions._activatedActionPanelID);
+  assertActivatedPageActionPanelHidden();
   Assert.equal(onButtonCommandCallCount, 2,
                "onButtonCommandCallCount should be inc'ed");
 
   // Remove the action.
   action.remove();
   panelButtonNode = document.getElementById(panelButtonID);
   Assert.equal(panelButtonNode, null, "panelButtonNode");
   urlbarButtonNode = document.getElementById(urlbarButtonID);
@@ -527,31 +527,31 @@ add_task(async function withIframe() {
 
   // The activated-action panel should have opened, anchored to the action's
   // urlbar button.
   let aaPanel =
     document.getElementById(BrowserPageActions._activatedActionPanelID);
   Assert.notEqual(aaPanel, null, "activated-action panel");
   Assert.equal(aaPanel.anchorNode.id, urlbarButtonID, "aaPanel.anchorNode.id");
   EventUtils.synthesizeMouseAtCenter(urlbarButtonNode, {});
-  await promisePanelHidden(BrowserPageActions._activatedActionPanelID);
+  assertActivatedPageActionPanelHidden();
 
   // Click the action's urlbar button.
   EventUtils.synthesizeMouseAtCenter(urlbarButtonNode, {});
   await promisePanelShown(BrowserPageActions._activatedActionPanelID);
   Assert.equal(onCommandCallCount, 0, "onCommandCallCount should remain 0");
   Assert.equal(onIframeShowingCount, 2, "onIframeShowingCount should be inc'ed");
 
   // The activated-action panel should have opened, again anchored to the
   // action's urlbar button.
   aaPanel = document.getElementById(BrowserPageActions._activatedActionPanelID);
   Assert.notEqual(aaPanel, null, "aaPanel");
   Assert.equal(aaPanel.anchorNode.id, urlbarButtonID, "aaPanel.anchorNode.id");
   EventUtils.synthesizeMouseAtCenter(urlbarButtonNode, {});
-  await promisePanelHidden(BrowserPageActions._activatedActionPanelID);
+  assertActivatedPageActionPanelHidden();
 
   // Hide the action's button in the urlbar.
   action.pinnedToUrlbar = false;
   urlbarButtonNode = document.getElementById(urlbarButtonID);
   Assert.equal(urlbarButtonNode, null, "urlbarButtonNode");
 
   // Open the panel, click the action's button.
   await promisePageActionPanelOpen();
@@ -562,17 +562,17 @@ add_task(async function withIframe() {
 
   // The activated-action panel should have opened, this time anchored to the
   // main page action button in the urlbar.
   aaPanel = document.getElementById(BrowserPageActions._activatedActionPanelID);
   Assert.notEqual(aaPanel, null, "aaPanel");
   Assert.equal(aaPanel.anchorNode.id, BrowserPageActions.mainButtonNode.id,
                "aaPanel.anchorNode.id");
   EventUtils.synthesizeMouseAtCenter(BrowserPageActions.mainButtonNode, {});
-  await promisePanelHidden(BrowserPageActions._activatedActionPanelID);
+  assertActivatedPageActionPanelHidden();
 
   // Remove the action.
   action.remove();
   panelButtonNode = document.getElementById(panelButtonID);
   Assert.equal(panelButtonNode, null, "panelButtonNode");
   urlbarButtonNode = document.getElementById(urlbarButtonID);
   Assert.equal(urlbarButtonNode, null, "urlbarButtonNode");
 });
@@ -1411,16 +1411,20 @@ add_task(async function contextMenu() {
   // urlbar tests that run after this one can break if the mouse is left over
   // the area where the urlbar popup appears, which seems to happen due to the
   // above synthesized mouse events.  Move it over the urlbar.
   EventUtils.synthesizeMouseAtCenter(gURLBar, { type: "mousemove" });
   gURLBar.focus();
 });
 
 
+function assertActivatedPageActionPanelHidden() {
+  Assert.ok(!document.getElementById(BrowserPageActions._activatedActionPanelID));
+}
+
 function promisePageActionPanelOpen() {
   let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor)
                   .getInterface(Ci.nsIDOMWindowUtils);
   return BrowserTestUtils.waitForCondition(() => {
     // Wait for the main page action button to become visible.  It's hidden for
     // some URIs, so depending on when this is called, it may not yet be quite
     // visible.  It's up to the caller to make sure it will be visible.
     info("Waiting for main page action button to have non-0 size");
@@ -1454,20 +1458,24 @@ function promisePanelShown(panelIDOrNode
 }
 
 function promisePanelHidden(panelIDOrNode) {
   return promisePanelEvent(panelIDOrNode, "popuphidden");
 }
 
 function promisePanelEvent(panelIDOrNode, eventType) {
   return new Promise(resolve => {
-    let panel = typeof(panelIDOrNode) != "string" ? panelIDOrNode :
-                document.getElementById(panelIDOrNode);
-    if (!panel ||
-        (eventType == "popupshown" && panel.state == "open") ||
+    let panel = panelIDOrNode;
+    if (typeof panel == "string") {
+      panel = document.getElementById(panelIDOrNode);
+      if (!panel) {
+        throw new Error(`Panel with ID "${panelIDOrNode}" does not exist.`);
+      }
+    }
+    if ((eventType == "popupshown" && panel.state == "open") ||
         (eventType == "popuphidden" && panel.state == "closed")) {
       executeSoon(resolve);
       return;
     }
     panel.addEventListener(eventType, () => {
       executeSoon(resolve);
     }, { once: true });
   });
--- 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 14.0
-Comparison: https://github.com/devtools-html/debugger.html/compare/release-13...release-14
-Commit: https://github.com/devtools-html/debugger.html/commit/5805cf467
+Version 15.0
+Comparison: https://github.com/devtools-html/debugger.html/compare/release-14...release-15
+Commit: https://github.com/devtools-html/debugger.html/commit/5e4e388cfbba8
 
 Packages:
 - babel-plugin-transform-es2015-modules-commonjs @6.26.0
 - babel-preset-react @6.24.1
 - react @15.6.2
 - react-dom @15.6.2
 - webpack @3.10.0
--- a/devtools/client/debugger/new/debugger.css
+++ b/devtools/client/debugger/new/debugger.css
@@ -1095,17 +1095,16 @@ html .arrow.expanded svg {
 
   white-space: nowrap;
   overflow: auto;
   min-width: 100%;
 
   display: grid;
   grid-template-columns: 1fr;
   align-content: start;
-
 }
 
 .managed-tree .tree button {
   display: block;
 }
 
 .managed-tree .tree .node {
   padding: 2px 3px 2px 3px;
@@ -1669,29 +1668,50 @@ html[dir="rtl"] .arrow svg,
   font-size: 12px;
 }
 
 .outline-list {
   list-style-type: none;
   flex: 1 0 100%;
   padding: 10px 0px;
   margin: 0;
+  font-family: var(--monospace-font-family);
 }
 
 .outline-list__class-list {
   list-style: none;
   margin: 0;
   padding: 0;
 }
 
+.outline-list__class-list .function-signature .function-name {
+  color: var(--theme-highlight-green);
+}
+
+.outline-list .function-signature .paren {
+  color: inherit;
+}
+
 .outline-list h2 {
   font-weight: normal;
   font-size: 1em;
   margin: 10px 0 10px 10px;
-  color: var(--theme-body-color);
+  color: var(--blue-55);
+}
+
+.outline-list h2:hover {
+  background: var(--theme-toolbar-background-hover);
+}
+
+.theme-dark .outline-list h2 {
+  color: var(--theme-highlight-blue);
+}
+
+.outline-list h2 .keyword {
+  color: var(--theme-highlight-red);
 }
 
 .outline-list__element {
   padding: 3px 10px 3px 10px;
   cursor: default;
   white-space: nowrap;
 }
 
@@ -1766,22 +1786,23 @@ html[dir="rtl"] .arrow svg,
  * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 .toggle-button {
   transform: translate(0, 0px);
   transition: transform 0.25s ease-in-out;
   padding: 5px;
 }
 
-.toggle-button.vertical {
-  padding: 2.5px 2.5px;
+.toggle-button .togglePanes {
+  vertical-align: -2px;
 }
 
 .toggle-button svg {
   fill: var(--theme-comment);
+  vertical-align: 0;
 }
 
 :root.theme-dark .toggle-button svg {
   fill: var(--theme-comment-alt);
 }
 
 .toggle-button.end {
   margin-inline-end: 0px;
@@ -3765,72 +3786,63 @@ img.ignore-exceptions {
   z-index: 10;
   user-select: none;
 }
 
 .theme-dark .welcomebox {
   background-color: var(--theme-body-background);
 }
 
-.alignlabel {
-  display: inline-block;
-}
-
-.welcomebox .normal-layout {
-  display: none;
-}
-
 .welcomebox .command-bar-button {
   position: absolute;
   top: auto;
   offset-inline-end: 0;
   offset-inline-start: auto;
   bottom: 0;
 }
 
+.alignlabel {
+  display: flex;
+  white-space: nowrap;
+}
+
 .shortcutKeys {
-  text-align: right;
-  float: left;
   font-family: Courier;
 }
 
+.shortcutKey,
+.shortcutLabel {
+  flex: 1;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
 .shortcutKey {
-  display: inline-block;
-  margin-right: 10px;
+  text-align: right;
+  padding-right: 10px;
   font-family: Courier;
 }
 
+.shortcutLabel {
+  text-align: left;
+  padding-left: 10px;
+}
+
 .shortcutFunction {
-  text-align: left;
-  float: left;
-  margin-left: 25px;
+  flex: 1;
   color: var(--theme-comment);
 }
 
+.shortcutFunction p {
+  display: flex;
+}
+
 html .welcomebox .toggle-button-end.collapsed {
   bottom: 1px;
 }
-
-@media (max-width: 430px) {
-  .welcomebox .small-size-layout {
-    display: inline-block;
-  }
-
-  .welcomebox .normal-layout {
-    display: none;
-  }
-
-  .shortcutFunction {
-    margin-left: 0;
-  }
-
-  .shortcutKey {
-    display: block;
-  }
-}
 /* 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/>. */
 
 .source-header {
   border-bottom: 1px solid var(--theme-splitter-color);
   width: 100%;
   height: 30px;
--- a/devtools/client/debugger/new/debugger.js
+++ b/devtools/client/debugger/new/debugger.js
@@ -13920,17 +13920,17 @@ module.exports = "<!-- This Source Code 
 /* 955 */,
 /* 956 */,
 /* 957 */,
 /* 958 */,
 /* 959 */,
 /* 960 */
 /***/ (function(module, exports) {
 
-module.exports = "# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this\n# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n# LOCALIZATION NOTE These strings are used inside the Debugger\n# which is available from the Web Developer sub-menu -> 'Debugger'.\n# The correct localization of this file might be to keep it in\n# English, or another language commonly spoken among web developers.\n# You want to make that choice consistent across the developer tools.\n# A good criteria is the language in which you'd find the best\n# documentation on web development on the web.\n\n# LOCALIZATION NOTE (collapsePanes): This is the tooltip for the button\n# that collapses the left and right panes in the debugger UI.\ncollapsePanes=Collapse panes\n\n# LOCALIZATION NOTE (copySource): This is the text that appears in the\n# context menu to copy the selected source of file open.\ncopySource=Copy\ncopySource.accesskey=y\n\n# LOCALIZATION NOTE (copySourceUri2): This is the text that appears in the\n# context menu to copy the source URI of file open.\ncopySourceUri2=Copy source URI\ncopySourceUri2.accesskey=u\n\n# LOCALIZATION NOTE (setDirectoryRoot.label): This is the text that appears in the\n# context menu to set a directory as root directory\nsetDirectoryRoot.label=Set directory root\nsetDirectoryRoot.accesskey=r\n\n# LOCALIZATION NOTE (removeDirectoryRoot.label): This is the text that appears in the\n# context menu to remove a directory as root directory\nremoveDirectoryRoot.label=Remove directory root\nremoveDirectoryRoot.accesskey=d\n\n# LOCALIZATION NOTE (copyFunction.label): This is the text that appears in the\n# context menu to copy the function the user selected\ncopyFunction.label=Copy function\ncopyFunction.accesskey=F\n\n# LOCALIZATION NOTE (copyStackTrace): This is the text that appears in the\n# context menu to copy the stack trace methods, file names and row number.\ncopyStackTrace=Copy stack trace\ncopyStackTrace.accesskey=c\n\n# LOCALIZATION NOTE (expandPanes): This is the tooltip for the button\n# that expands the left and right panes in the debugger UI.\nexpandPanes=Expand panes\n\n# LOCALIZATION NOTE (pauseButtonTooltip): The tooltip that is displayed for the pause\n# button when the debugger is in a running state.\npauseButtonTooltip=Pause %S\n\n# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for\n# the pause button after it's been clicked but before the next JavaScript to run.\npausePendingButtonTooltip=Waiting for next execution\n\n# LOCALIZATION NOTE (resumeButtonTooltip): The label that is displayed on the pause\n# button when the debugger is in a paused state.\nresumeButtonTooltip=Resume %S\n\n# LOCALIZATION NOTE (stepOverTooltip): The label that is displayed on the\n# button that steps over a function call.\nstepOverTooltip=Step over %S\n\n# LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the\n# button that steps into a function call.\nstepInTooltip=Step in %S\n\n# LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the\n# button that steps out of a function call.\nstepOutTooltip=Step out %S\n\n# LOCALIZATION NOTE (pauseButtonItem): The label that is displayed for the dropdown pause\n# list item when the debugger is in a running state.\npauseButtonItem=Pause on Next Statement\n\n# LOCALIZATION NOTE (ignoreExceptionsItem): The pause on exceptions button description\n# when the debugger will not pause on exceptions.\nignoreExceptionsItem=Ignore exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptionsItem): The pause on exceptions dropdown\n# item shown when a user is adding a new breakpoint.\npauseOnUncaughtExceptionsItem=Pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptionsItem): The pause on exceptions button description\n# when the debugger will pause on all exceptions.\npauseOnExceptionsItem=Pause on all exceptions\n\n# LOCALIZATION NOTE (workersHeader): The text to display in the events\n# header.\nworkersHeader=Workers\n\n# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list\n# when there are no workers.\nnoWorkersText=This page has no workers.\n\n# LOCALIZATION NOTE (noSourcesText): The text to display in the sources list\n# when there are no sources.\nnoSourcesText=This page has no sources.\n\n# LOCALIZATION NOTE (noEventListenersText): The text to display in the events tab\n# when there are no events.\nnoEventListenersText=No event listeners to display.\n\n# LOCALIZATION NOTE (eventListenersHeader): The text to display in the events\n# header.\neventListenersHeader=Event listeners\n\n# LOCALIZATION NOTE (noStackFramesText): The text to display in the call stack tab\n# when there are no stack frames.\nnoStackFramesText=No stack frames to display\n\n# LOCALIZATION NOTE (eventCheckboxTooltip): The tooltip text to display when\n# the user hovers over the checkbox used to toggle an event breakpoint.\neventCheckboxTooltip=Toggle breaking on this event\n\n# LOCALIZATION NOTE (eventOnSelector): The text to display in the events tab\n# for every event item, between the event type and event selector.\neventOnSelector=on\n\n# LOCALIZATION NOTE (eventInSource): The text to display in the events tab\n# for every event item, between the event selector and listener's owner source.\neventInSource=in\n\n# LOCALIZATION NOTE (eventNodes): The text to display in the events tab when\n# an event is listened on more than one target node.\neventNodes=%S nodes\n\n# LOCALIZATION NOTE (eventNative): The text to display in the events tab when\n# a listener is added from plugins, thus getting translated to native code.\neventNative=[native code]\n\n# LOCALIZATION NOTE (*Events): The text to display in the events tab for\n# each group of sub-level event entries.\nanimationEvents=Animation\naudioEvents=Audio\nbatteryEvents=Battery\nclipboardEvents=Clipboard\ncompositionEvents=Composition\ndeviceEvents=Device\ndisplayEvents=Display\ndragAndDropEvents=Drag and Drop\ngamepadEvents=Gamepad\nindexedDBEvents=IndexedDB\ninteractionEvents=Interaction\nkeyboardEvents=Keyboard\nmediaEvents=HTML5 Media\nmouseEvents=Mouse\nmutationEvents=Mutation\nnavigationEvents=Navigation\npointerLockEvents=Pointer Lock\nsensorEvents=Sensor\nstorageEvents=Storage\ntimeEvents=Time\ntouchEvents=Touch\notherEvents=Other\n\n# LOCALIZATION NOTE (blackboxCheckboxTooltip2): The tooltip text to display when\n# the user hovers over the checkbox used to toggle blackboxing its associated\n# source.\nblackboxCheckboxTooltip2=Toggle blackboxing\n\n# LOCALIZATION NOTE (sources.search.key2): Key shortcut to open the search for\n# searching all the source files the debugger has seen.\n# Do not localize \"CmdOrCtrl+P\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsources.search.key2=CmdOrCtrl+P\n\n# LOCALIZATION NOTE (sources.search.alt.key): A second key shortcut to open the\n# search for searching all the source files the debugger has seen.\n# Do not localize \"CmdOrCtrl+O\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsources.search.alt.key=CmdOrCtrl+O\n\n# LOCALIZATION NOTE (projectTextSearch.key): A key shortcut to open the\n# full project text search for searching all the files the debugger has seen.\n# Do not localize \"CmdOrCtrl+Shift+F\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nprojectTextSearch.key=CmdOrCtrl+Shift+F\n\n# LOCALIZATION NOTE (functionSearch.key): A key shortcut to open the\n# modal for searching functions in a file.\n# Do not localize \"CmdOrCtrl+Shift+O\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nfunctionSearch.key=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE (toggleBreakpoint.key): A key shortcut to toggle\n# breakpoints.\n# Do not localize \"CmdOrCtrl+B\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\ntoggleBreakpoint.key=CmdOrCtrl+B\n\n# LOCALIZATION NOTE (toggleCondPanel.key): A key shortcut to toggle\n# the conditional breakpoint panel.\n# Do not localize \"CmdOrCtrl+Shift+B\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\ntoggleCondPanel.key=CmdOrCtrl+Shift+B\n\n# LOCALIZATION NOTE (stepOut.key): A key shortcut to\n# step out.\nstepOut.key=Shift+F11\n\n# LOCALIZATION NOTE (shortcuts.header.editor): Sections header in\n# the shortcuts modal for keyboard shortcuts related to editing.\nshortcuts.header.editor=Editor\n\n# LOCALIZATION NOTE (shortcuts.header.stepping): Sections header in\n# the shortcuts modal for keyboard shortcuts related to stepping.\nshortcuts.header.stepping=Stepping\n\n# LOCALIZATION NOTE (shortcuts.header.search): Sections header in\n# the shortcuts modal for keyboard shortcuts related to search.\nshortcuts.header.search=Search\n\n# LOCALIZATION NOTE (projectTextSearch.placeholder): A placeholder shown\n# when searching across all of the files in a project.\nprojectTextSearch.placeholder=Find in files…\n\n# LOCALIZATION NOTE (projectTextSearch.noResults): The center pane Text Search\n# message when the query did not match any text of all files in a project.\nprojectTextSearch.noResults=No results found\n\n# LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger\n# does not have any sources.\nsources.noSourcesAvailable=This page has no sources\n\n# LOCALIZATION NOTE (sourceSearch.search.key2): Key shortcut to open the search\n# for searching within a the currently opened files in the editor\n# Do not localize \"CmdOrCtrl+F\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsourceSearch.search.key2=CmdOrCtrl+F\n\n# LOCALIZATION NOTE (sourceSearch.search.placeholder): placeholder text in\n# the source search input bar\nsourceSearch.search.placeholder=Search in file…\n\n# LOCALIZATION NOTE (sourceSearch.search.again.key2): Key shortcut to highlight\n# the next occurrence of the last search triggered from a source search\n# Do not localize \"CmdOrCtrl+G\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsourceSearch.search.again.key2=CmdOrCtrl+G\n\n# LOCALIZATION NOTE (sourceSearch.search.againPrev.key2): Key shortcut to highlight\n# the previous occurrence of the last search triggered from a source search\n# Do not localize \"CmdOrCtrl+Shift+G\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsourceSearch.search.againPrev.key2=CmdOrCtrl+Shift+G\n\n# LOCALIZATION NOTE (sourceSearch.resultsSummary1): Shows a summary of\n# the number of matches for autocomplete\nsourceSearch.resultsSummary1=%d results\n\n# LOCALIZATION NOTE (noMatchingStringsText): The text to display in the\n# global search results when there are no matching strings after filtering.\nnoMatchingStringsText=No matches found\n\n# LOCALIZATION NOTE (emptySearchText): This is the text that appears in the\n# filter text box when it is empty and the scripts container is selected.\nemptySearchText=Search scripts (%S)\n\n# LOCALIZATION NOTE (emptyVariablesFilterText): This is the text that\n# appears in the filter text box for the variables view container.\nemptyVariablesFilterText=Filter variables\n\n# LOCALIZATION NOTE (emptyPropertiesFilterText): This is the text that\n# appears in the filter text box for the editor's variables view bubble.\nemptyPropertiesFilterText=Filter properties\n\n# LOCALIZATION NOTE (searchPanelFilter): This is the text that appears in the\n# filter panel popup for the filter scripts operation.\nsearchPanelFilter=Filter scripts (%S)\n\n# LOCALIZATION NOTE (searchPanelGlobal): This is the text that appears in the\n# filter panel popup for the global search operation.\nsearchPanelGlobal=Search in all files (%S)\n\n# LOCALIZATION NOTE (searchPanelFunction): This is the text that appears in the\n# filter panel popup for the function search operation.\nsearchPanelFunction=Search for function definition (%S)\n\n# LOCALIZATION NOTE (searchPanelToken): This is the text that appears in the\n# filter panel popup for the token search operation.\nsearchPanelToken=Find in this file (%S)\n\n# LOCALIZATION NOTE (searchPanelGoToLine): This is the text that appears in the\n# filter panel popup for the line search operation.\nsearchPanelGoToLine=Go to line (%S)\n\n# LOCALIZATION NOTE (searchPanelVariable): This is the text that appears in the\n# filter panel popup for the variables search operation.\nsearchPanelVariable=Filter variables (%S)\n\n# LOCALIZATION NOTE (breakpointMenuItem): The text for all the elements that\n# are displayed in the breakpoints menu item popup.\nbreakpointMenuItem.setConditional=Configure conditional breakpoint\nbreakpointMenuItem.enableSelf2.label=Enable\nbreakpointMenuItem.enableSelf2.accesskey=E\nbreakpointMenuItem.disableSelf2.label=Disable\nbreakpointMenuItem.disableSelf2.accesskey=D\nbreakpointMenuItem.deleteSelf2.label=Remove\nbreakpointMenuItem.deleteSelf2.accesskey=R\nbreakpointMenuItem.enableOthers2.label=Enable others\nbreakpointMenuItem.enableOthers2.accesskey=o\nbreakpointMenuItem.disableOthers2.label=Disable others\nbreakpointMenuItem.disableOthers2.accesskey=s\nbreakpointMenuItem.deleteOthers2.label=Remove others\nbreakpointMenuItem.deleteOthers2.accesskey=h\nbreakpointMenuItem.enableAll2.label=Enable all\nbreakpointMenuItem.enableAll2.accesskey=b\nbreakpointMenuItem.disableAll2.label=Disable all\nbreakpointMenuItem.disableAll2.accesskey=k\nbreakpointMenuItem.deleteAll2.label=Remove all\nbreakpointMenuItem.deleteAll2.accesskey=a\nbreakpointMenuItem.removeCondition2.label=Remove condition\nbreakpointMenuItem.removeCondition2.accesskey=c\nbreakpointMenuItem.addCondition2.label=Add condition\nbreakpointMenuItem.addCondition2.accesskey=A\nbreakpointMenuItem.editCondition2.label=Edit condition\nbreakpointMenuItem.editCondition2.accesskey=n\nbreakpointMenuItem.enableSelf=Enable breakpoint\nbreakpointMenuItem.enableSelf.accesskey=E\nbreakpointMenuItem.disableSelf=Disable breakpoint\nbreakpointMenuItem.disableSelf.accesskey=D\nbreakpointMenuItem.deleteSelf=Remove breakpoint\nbreakpointMenuItem.deleteSelf.accesskey=R\nbreakpointMenuItem.enableOthers=Enable others\nbreakpointMenuItem.enableOthers.accesskey=o\nbreakpointMenuItem.disableOthers=Disable others\nbreakpointMenuItem.disableOthers.accesskey=s\nbreakpointMenuItem.deleteOthers=Remove others\nbreakpointMenuItem.deleteOthers.accesskey=h\nbreakpointMenuItem.enableAll=Enable all breakpoints\nbreakpointMenuItem.enableAll.accesskey=b\nbreakpointMenuItem.disableAll=Disable all breakpoints\nbreakpointMenuItem.disableAll.accesskey=k\nbreakpointMenuItem.deleteAll=Remove all breakpoints\nbreakpointMenuItem.deleteAll.accesskey=a\nbreakpointMenuItem.removeCondition.label=Remove breakpoint condition\nbreakpointMenuItem.removeCondition.accesskey=c\nbreakpointMenuItem.editCondition.label=Edit breakpoint condition\nbreakpointMenuItem.editCondition.accesskey=n\n\n# LOCALIZATION NOTE (breakpoints.header): Breakpoints right sidebar pane header.\nbreakpoints.header=Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.none): The text that appears when there are\n# no breakpoints present\nbreakpoints.none=No breakpoints\n\n# LOCALIZATION NOTE (breakpoints.enable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.enable=Enable breakpoints\n\n# LOCALIZATION NOTE (breakpoints.disable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.disable=Disable breakpoints\n\n# LOCALIZATION NOTE (breakpoints.removeBreakpointTooltip): The tooltip that is displayed\n# for remove breakpoint button in right sidebar\nbreakpoints.removeBreakpointTooltip=Remove breakpoint\n\n# LOCALIZATION NOTE (callStack.header): Call Stack right sidebar pane header.\ncallStack.header=Call stack\n\n# LOCALIZATION NOTE (callStack.notPaused): Call Stack right sidebar pane\n# message when not paused.\ncallStack.notPaused=Not paused\n\n# LOCALIZATION NOTE (callStack.collapse): Call Stack right sidebar pane\n# message to hide some of the frames that are shown.\ncallStack.collapse=Collapse rows\n\n# LOCALIZATION NOTE (callStack.expand): Call Stack right sidebar pane\n# message to show more of the frames.\ncallStack.expand=Expand rows\n\n# LOCALIZATION NOTE (editor.searchResults): Editor Search bar message\n# for the summarizing the selected search result. e.g. 5 of 10 results.\neditor.searchResults=%d of %d results\n\n# LOCALIZATION NOTE (editor.singleResult): Copy shown when there is one result.\neditor.singleResult=1 result\n\n# LOCALIZATION NOTE (editor.noResults): Editor Search bar message\n# for when no results found.\neditor.noResults=No results\n\n# LOCALIZATION NOTE (editor.searchResults.nextResult): Editor Search bar\n# tooltip for traversing to the Next Result\neditor.searchResults.nextResult=Next result\n\n# LOCALIZATION NOTE (editor.searchResults.prevResult): Editor Search bar\n# tooltip for traversing to the Previous Result\neditor.searchResults.prevResult=Previous result\n\n# LOCALIZATION NOTE (editor.searchTypeToggleTitle): Search bar title for\n# toggling search type buttons(function search, variable search)\neditor.searchTypeToggleTitle=Search for:\n\n# LOCALIZATION NOTE (editor.continueToHere.label): Editor gutter context\n# menu item for jumping to a new paused location\neditor.continueToHere.label=Continue to here\neditor.continueToHere.accesskey=H\n\n# LOCALIZATION NOTE (editor.addBreakpoint): Editor gutter context menu item\n# for adding a breakpoint on a line.\neditor.addBreakpoint=Add breakpoint\n\n# LOCALIZATION NOTE (editor.disableBreakpoint): Editor gutter context menu item\n# for disabling a breakpoint on a line.\neditor.disableBreakpoint=Disable breakpoint\neditor.disableBreakpoint.accesskey=D\n\n# LOCALIZATION NOTE (editor.enableBreakpoint): Editor gutter context menu item\n# for enabling a breakpoint on a line.\neditor.enableBreakpoint=Enable breakpoint\n\n# LOCALIZATION NOTE (editor.removeBreakpoint): Editor gutter context menu item\n# for removing a breakpoint on a line.\neditor.removeBreakpoint=Remove breakpoint\n\n# LOCALIZATION NOTE (editor.editBreakpoint): Editor gutter context menu item\n# for setting a breakpoint condition on a line.\neditor.editBreakpoint=Edit breakpoint\n\n# LOCALIZATION NOTE (editor.addConditionalBreakpoint): Editor gutter context\n# menu item for adding a breakpoint condition on a line.\neditor.addConditionalBreakpoint=Add conditional breakpoint\neditor.addConditionalBreakpoint.accesskey=c\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Placeholder text for\n# input element inside ConditionalPanel component\neditor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true\n\n# LOCALIZATION NOTE (editor.conditionalPanel.close): Tooltip text for\n# close button inside ConditionalPanel component\neditor.conditionalPanel.close=Cancel edit breakpoint and close\n\n# LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item\n# for navigating to a source mapped location\neditor.jumpToMappedLocation1=Jump to %S location\neditor.jumpToMappedLocation1.accesskey=m\n\n# LOCALIZATION NOTE (framework.disableGrouping): This is the text that appears in the\n# context menu to disable framework grouping.\nframework.disableGrouping=Disable framework grouping\nframework.disableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (framework.enableGrouping): This is the text that appears in the\n# context menu to enable framework grouping.\nframework.enableGrouping=Enable framework grouping\nframework.enableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (generated): Source Map term for a server source location\ngenerated=generated\n\n# LOCALIZATION NOTE (original): Source Map term for a debugger UI source location\noriginal=original\n\n# LOCALIZATION NOTE (expressions.placeholder): Placeholder text for expression\n# input element\nexpressions.placeholder=Add watch expression\n# LOCALIZATION NOTE (expressions.errorMsg): Error text for expression\n# input element\nexpressions.errorMsg=Invalid expression…\nexpressions.label=Add watch expression\nexpressions.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item\n# for closing the selected tab below the mouse.\nsourceTabs.closeTab=Close tab\nsourceTabs.closeTab.accesskey=c\n\n# LOCALIZATION NOTE (sourceTabs.closeOtherTabs): Editor source tab context menu item\n# for closing the other tabs.\nsourceTabs.closeOtherTabs=Close other tabs\nsourceTabs.closeOtherTabs.accesskey=o\n\n# LOCALIZATION NOTE (sourceTabs.closeTabsToEnd): Editor source tab context menu item\n# for closing the tabs to the end (the right for LTR languages) of the selected tab.\nsourceTabs.closeTabsToEnd=Close tabs to the right\nsourceTabs.closeTabsToEnd.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeAllTabs): Editor source tab context menu item\n# for closing all tabs.\nsourceTabs.closeAllTabs=Close all tabs\nsourceTabs.closeAllTabs.accesskey=a\n\n# LOCALIZATION NOTE (sourceTabs.revealInTree): Editor source tab context menu item\n# for revealing source in tree.\nsourceTabs.revealInTree=Reveal in tree\nsourceTabs.revealInTree.accesskey=r\n\n# LOCALIZATION NOTE (sourceTabs.prettyPrint): Editor source tab context menu item\n# for pretty printing the source.\nsourceTabs.prettyPrint=Pretty print source\nsourceTabs.prettyPrint.accesskey=p\n\n# LOCALIZATION NOTE (sourceFooter.blackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.blackbox=Blackbox source\nsourceFooter.blackbox.accesskey=B\n\n# LOCALIZATION NOTE (sourceFooter.unblackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.unblackbox=Unblackbox source\nsourceFooter.unblackbox.accesskey=b\n\n# LOCALIZATION NOTE (sourceFooter.blackboxed): Text associated\n# with a blackboxed source\nsourceFooter.blackboxed=Blackboxed source\n\n# LOCALIZATION NOTE (sourceFooter.mappedSource): Text associated\n# with a mapped source. %S is replaced by the source map origin.\nsourceFooter.mappedSource=(From %S)\n\n# LOCALIZATION NOTE (sourceFooter.mappedSourceTooltip): Tooltip text associated\n# with a mapped source. %S is replaced by the source map origin.\nsourceFooter.mappedSourceTooltip=(Source mapped from %S)\n\n# LOCALIZATION NOTE (sourceFooter.codeCoverage): Text associated\n# with a code coverage button\nsourceFooter.codeCoverage=Code coverage\n\n# LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed\n# for close tab button in source tabs.\nsourceTabs.closeTabButtonTooltip=Close tab\n\n# LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header.\nscopes.header=Scopes\n\n# LOCALIZATION NOTE (scopes.notAvailable): Scopes right sidebar pane message\n# for when the debugger is paused, but there isn't pause data.\nscopes.notAvailable=Scopes unavailable\n\n# LOCALIZATION NOTE (scopes.notPaused): Scopes right sidebar pane message\n# for when the debugger is not paused.\nscopes.notPaused=Not paused\n\n# LOCALIZATION NOTE (scopes.block): Refers to a block of code in\n# the scopes pane when the debugger is paused.\nscopes.block=Block\n\n# LOCALIZATION NOTE (sources.header): Sources left sidebar header\nsources.header=Sources\n\n# LOCALIZATION NOTE (outline.header): Outline left sidebar header\noutline.header=Outline\n\n# LOCALIZATION NOTE (outline.noFunctions): Outline text when there are no functions to display\noutline.noFunctions=No functions\n\n# LOCALIZATION NOTE (sources.search): Sources left sidebar prompt\n# e.g. Cmd+P to search. On a mac, we use the command unicode character.\n# On windows, it's ctrl.\nsources.search=%S to search\n\n# LOCALIZATION NOTE (watchExpressions.header): Watch Expressions right sidebar\n# pane header.\nwatchExpressions.header=Watch expressions\n\n# LOCALIZATION NOTE (watchExpressions.refreshButton): Watch Expressions header\n# button for refreshing the expressions.\nwatchExpressions.refreshButton=Refresh\n\n# LOCALIZATION NOTE (welcome.search): The center pane welcome panel's\n# search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on\n# a mac we use the unicode character.\nwelcome.search=%S To search for sources\n\n# LOCALIZATION NOTE (welcome.findInFiles): The center pane welcome panel's\n# search prompt. e.g. cmd+f to search for files. On windows, it's ctrl+shift+f, on\n# a mac we use the unicode character.\nwelcome.findInFiles=%S To find in files\n\n# LOCALIZATION NOTE (welcome.searchFunction): Label displayed in the welcome\n# panel. %S is replaced by the keyboard shortcut to search for functions.\nwelcome.searchFunction=%S To search for functions in file\n\n# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search\n# prompt for searching for files.\nsourceSearch.search=Search sources…\n\n# LOCALIZATION NOTE (sourceSearch.noResults2): The center pane Source Search\n# message when the query did not match any of the sources.\nsourceSearch.noResults2=No results found\n\n# LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip\n# when the debugger will not pause on exceptions.\nignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptions): The pause on exceptions button\n# tooltip when the debugger will pause on uncaught exceptions.\npauseOnUncaughtExceptions=Pause on uncaught exceptions. Click to pause on all exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptions): The pause on exceptions button tooltip\n# when the debugger will pause on all exceptions.\npauseOnExceptions=Pause on all exceptions. Click to ignore exceptions\n\n# LOCALIZATION NOTE (loadingText): The text that is displayed in the script\n# editor when the loading process has started but there is no file to display\n# yet.\nloadingText=Loading\\u2026\n\n# LOCALIZATION NOTE (wasmIsNotAvailable): The text that is displayed in the\n# script editor when the WebAssembly source is not available.\nwasmIsNotAvailable=Please refresh to debug this module\n\n# LOCALIZATION NOTE (errorLoadingText3): The text that is displayed in the debugger\n# viewer when there is an error loading a file\nerrorLoadingText3=Error loading this URI: %S\n\n# LOCALIZATION NOTE (addWatchExpressionText): The text that is displayed in the\n# watch expressions list to add a new item.\naddWatchExpressionText=Add watch expression\n\n# LOCALIZATION NOTE (addWatchExpressionButton): The button that is displayed in the\n# variables view popup.\naddWatchExpressionButton=Watch\n\n# LOCALIZATION NOTE (emptyVariablesText): The text that is displayed in the\n# variables pane when there are no variables to display.\nemptyVariablesText=No variables to display\n\n# LOCALIZATION NOTE (scopeLabel): The text that is displayed in the variables\n# pane as a header for each variable scope (e.g. \"Global scope, \"With scope\",\n# etc.).\nscopeLabel=%S scope\n\n# LOCALIZATION NOTE (watchExpressionsScopeLabel): The name of the watch\n# expressions scope. This text is displayed in the variables pane as a header for\n# the watch expressions scope.\nwatchExpressionsScopeLabel=Watch expressions\n\n# LOCALIZATION NOTE (globalScopeLabel): The name of the global scope. This text\n# is added to scopeLabel and displayed in the variables pane as a header for\n# the global scope.\nglobalScopeLabel=Global\n\n# LOCALIZATION NOTE (variablesViewErrorStacktrace): This is the text that is\n# shown before the stack trace in an error.\nvariablesViewErrorStacktrace=Stack trace:\n\n# LOCALIZATION NOTE (variablesViewMoreObjects): the text that is displayed\n# when you have an object preview that does not show all of the elements. At the end of the list\n# you see \"N more...\" in the web console output.\n# This is a semi-colon list of plural forms.\n# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals\n# #1 number of remaining items in the object\n# example: 3 more…\nvariablesViewMoreObjects=#1 more…;#1 more…\n\n# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed\n# in the variables list on an item with an editable name.\nvariablesEditableNameTooltip=Double click to edit\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in the variables list on an item with an editable value.\nvariablesEditableValueTooltip=Click to change value\n\n# LOCALIZATION NOTE (variablesCloseButtonTooltip): The text that is displayed\n# in the variables list on an item which can be removed.\nvariablesCloseButtonTooltip=Click to remove\n\n# LOCALIZATION NOTE (variablesEditButtonTooltip): The text that is displayed\n# in the variables list on a getter or setter which can be edited.\nvariablesEditButtonTooltip=Click to set value\n\n# LOCALIZATION NOTE (variablesDomNodeValueTooltip): The text that is displayed\n# in a tooltip on the \"open in inspector\" button in the the variables list for a\n# DOMNode item.\nvariablesDomNodeValueTooltip=Click to select the node in the inspector\n\n# LOCALIZATION NOTE (configurable|...|Tooltip): The text that is displayed\n# in the variables list on certain variables or properties as tooltips.\n# Expanations of what these represent can be found at the following links:\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n# It's probably best to keep these in English.\nconfigurableTooltip=configurable\nenumerableTooltip=enumerable\nwritableTooltip=writable\nfrozenTooltip=frozen\nsealedTooltip=sealed\nextensibleTooltip=extensible\noverriddenTooltip=overridden\nWebIDLTooltip=WebIDL\n\n# LOCALIZATION NOTE (variablesSeparatorLabel): The text that is displayed\n# in the variables list as a separator between the name and value.\nvariablesSeparatorLabel=:\n\n# LOCALIZATION NOTE (watchExpressionsSeparatorLabel2): The text that is displayed\n# in the watch expressions list as a separator between the code and evaluation.\nwatchExpressionsSeparatorLabel2=\\u0020→\n\n# LOCALIZATION NOTE (functionSearchSeparatorLabel): The text that is displayed\n# in the functions search panel as a separator between function's inferred name\n# and its real name (if available).\nfunctionSearchSeparatorLabel=←\n\n# LOCALIZATION NOTE(gotoLineModal.placeholder): The placeholder\n# text displayed when the user searches for specific lines in a file\n# Do not localize \"CmdOrCtrl+;\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\ngotoLineModal.placeholder=Go to line…\ngotoLineModal.key=CmdOrCtrl+;\ngotoLineModal.title=Go to a line number in a file\n\n# LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder\n# text displayed when the user searches for functions in a file\nsymbolSearch.search.functionsPlaceholder=Search functions…\nsymbolSearch.search.functionsPlaceholder.title=Search for a function in a file\n\n# LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder\n# text displayed when the user searches for variables in a file\nsymbolSearch.search.variablesPlaceholder=Search variables…\nsymbolSearch.search.variablesPlaceholder.title=Search for a variable in a file\n\n# LOCALIZATION NOTE(symbolSearch.search.key2): The Key Shortcut for\n# searching for a function or variable\n# Do not localize \"CmdOrCtrl+Shift+O\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsymbolSearch.search.key2=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.modifiersLabel): A label\n# preceding the group of modifiers\nsymbolSearch.searchModifier.modifiersLabel=Modifiers:\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.regex): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.regex=Regex\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.caseSensitive): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.caseSensitive=Case sensitive\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.wholeWord): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.wholeWord=Whole word\n\n# LOCALIZATION NOTE (resumptionOrderPanelTitle): This is the text that appears\n# as a description in the notification panel popup, when multiple debuggers are\n# open in separate tabs and the user tries to resume them in the wrong order.\n# The substitution parameter is the URL of the last paused window that must be\n# resumed first.\nresumptionOrderPanelTitle=There are one or more paused debuggers. Please resume the most-recently paused debugger first at: %S\n\nvariablesViewOptimizedOut=(optimized away)\nvariablesViewUninitialized=(uninitialized)\nvariablesViewMissingArgs=(unavailable)\n\nanonymousSourcesLabel=Anonymous sources\n\nexperimental=This is an experimental feature\n\n# LOCALIZATION NOTE (whyPaused.debuggerStatement): The text that is displayed\n# in a info block explaining how the debugger is currently paused due to a `debugger`\n# statement in the code\nwhyPaused.debuggerStatement=Paused on debugger statement\n\n# LOCALIZATION NOTE (whyPaused.breakpoint): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a breakpoint\nwhyPaused.breakpoint=Paused on breakpoint\n\n# LOCALIZATION NOTE (whyPaused.exception): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an exception\nwhyPaused.exception=Paused on exception\n\n# LOCALIZATION NOTE (whyPaused.resumeLimit): The text that is displayed\n# in a info block explaining how the debugger is currently paused while stepping\n# in or out of the stack\nwhyPaused.resumeLimit=Paused while stepping\n\n# LOCALIZATION NOTE (whyPaused.pauseOnDOMEvents): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# dom event\nwhyPaused.pauseOnDOMEvents=Paused on event listener\n\n# LOCALIZATION NOTE (whyPaused.breakpointConditionThrown): The text that is displayed\n# in an info block when evaluating a conditional breakpoint throws an error\nwhyPaused.breakpointConditionThrown=Error with conditional breakpoint\n\n# LOCALIZATION NOTE (whyPaused.xhr): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# xml http request\nwhyPaused.xhr=Paused on XMLHttpRequest\n\n# LOCALIZATION NOTE (whyPaused.promiseRejection): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# promise rejection\nwhyPaused.promiseRejection=Paused on promise rejection\n\n# LOCALIZATION NOTE (whyPaused.assert): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# assert\nwhyPaused.assert=Paused on assertion\n\n# LOCALIZATION NOTE (whyPaused.debugCommand): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# debugger statement\nwhyPaused.debugCommand=Paused on debugged function\n\n# LOCALIZATION NOTE (whyPaused.other): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an event\n# listener breakpoint set\nwhyPaused.other=Debugger paused\n\n# LOCALIZATION NOTE (ctrl): The text that is used for documenting\n# keyboard shortcuts that use the control key\nctrl=Ctrl\n\n# LOCALIZATION NOTE (anonymous): The text that is displayed when the\n# display name is null.\nanonymous=(anonymous)\n\n# LOCALIZATION NOTE (shortcuts.toggleBreakpoint): text describing\n# keyboard shortcut action for toggling breakpoint\nshortcuts.toggleBreakpoint=Toggle Breakpoint\nshortcuts.toggleBreakpoint.accesskey=B\n\n# LOCALIZATION NOTE (shortcuts.toggleCondPanel): text describing\n# keyboard shortcut action for toggling conditional panel keyboard\nshortcuts.toggleCondPanel=Toggle Conditional Panel\n\n# LOCALIZATION NOTE (shortcuts.pauseOrResume): text describing\n# keyboard shortcut action for pause of resume\nshortcuts.pauseOrResume=Pause/Resume\n\n# LOCALIZATION NOTE (shortcuts.stepOver): text describing\n# keyboard shortcut action for stepping over\nshortcuts.stepOver=Step Over\n\n# LOCALIZATION NOTE (shortcuts.stepIn): text describing\n# keyboard shortcut action for stepping in\nshortcuts.stepIn=Step In\n\n# LOCALIZATION NOTE (shortcuts.stepOut): text describing\n# keyboard shortcut action for stepping out\nshortcuts.stepOut=Step Out\n\n# LOCALIZATION NOTE (shortcuts.fileSearch): text describing\n# keyboard shortcut action for source file search\nshortcuts.fileSearch=Source File Search\n\n# LOCALIZATION NOTE (shortcuts.gotoLine): text describing\n# keyboard shortcut for jumping to a specific line\nshortcuts.gotoLine=Go to line\n\n# LOCALIZATION NOTE (shortcuts.searchAgain): text describing\n# keyboard shortcut action for searching again\nshortcuts.searchAgain=Search Again\n\n# LOCALIZATION NOTE (shortcuts.projectSearch): text describing\n# keyboard shortcut action for full project search\nshortcuts.projectSearch=Full Project Search\n\n# LOCALIZATION NOTE (shortcuts.functionSearch): text describing\n# keyboard shortcut action for function search\nshortcuts.functionSearch=Function Search\n\n# LOCALIZATION NOTE (shortcuts.buttonName): text describing\n# keyboard shortcut button text\nshortcuts.buttonName=Keyboard shortcuts\n"
+module.exports = "# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this\n# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n# LOCALIZATION NOTE These strings are used inside the Debugger\n# which is available from the Web Developer sub-menu -> 'Debugger'.\n# The correct localization of this file might be to keep it in\n# English, or another language commonly spoken among web developers.\n# You want to make that choice consistent across the developer tools.\n# A good criteria is the language in which you'd find the best\n# documentation on web development on the web.\n\n# LOCALIZATION NOTE (collapsePanes): This is the tooltip for the button\n# that collapses the left and right panes in the debugger UI.\ncollapsePanes=Collapse panes\n\n# LOCALIZATION NOTE (copySource): This is the text that appears in the\n# context menu to copy the selected source of file open.\ncopySource=Copy\ncopySource.accesskey=y\n\n# LOCALIZATION NOTE (copySourceUri2): This is the text that appears in the\n# context menu to copy the source URI of file open.\ncopySourceUri2=Copy source URI\ncopySourceUri2.accesskey=u\n\n# LOCALIZATION NOTE (setDirectoryRoot.label): This is the text that appears in the\n# context menu to set a directory as root directory\nsetDirectoryRoot.label=Set directory root\nsetDirectoryRoot.accesskey=r\n\n# LOCALIZATION NOTE (removeDirectoryRoot.label): This is the text that appears in the\n# context menu to remove a directory as root directory\nremoveDirectoryRoot.label=Remove directory root\nremoveDirectoryRoot.accesskey=d\n\n# LOCALIZATION NOTE (copyFunction.label): This is the text that appears in the\n# context menu to copy the function the user selected\ncopyFunction.label=Copy function\ncopyFunction.accesskey=F\n\n# LOCALIZATION NOTE (copyStackTrace): This is the text that appears in the\n# context menu to copy the stack trace methods, file names and row number.\ncopyStackTrace=Copy stack trace\ncopyStackTrace.accesskey=c\n\n# LOCALIZATION NOTE (expandPanes): This is the tooltip for the button\n# that expands the left and right panes in the debugger UI.\nexpandPanes=Expand panes\n\n# LOCALIZATION NOTE (pauseButtonTooltip): The tooltip that is displayed for the pause\n# button when the debugger is in a running state.\npauseButtonTooltip=Pause %S\n\n# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for\n# the pause button after it's been clicked but before the next JavaScript to run.\npausePendingButtonTooltip=Waiting for next execution\n\n# LOCALIZATION NOTE (resumeButtonTooltip): The label that is displayed on the pause\n# button when the debugger is in a paused state.\nresumeButtonTooltip=Resume %S\n\n# LOCALIZATION NOTE (stepOverTooltip): The label that is displayed on the\n# button that steps over a function call.\nstepOverTooltip=Step over %S\n\n# LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the\n# button that steps into a function call.\nstepInTooltip=Step in %S\n\n# LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the\n# button that steps out of a function call.\nstepOutTooltip=Step out %S\n\n# LOCALIZATION NOTE (pauseButtonItem): The label that is displayed for the dropdown pause\n# list item when the debugger is in a running state.\npauseButtonItem=Pause on Next Statement\n\n# LOCALIZATION NOTE (ignoreExceptionsItem): The pause on exceptions button description\n# when the debugger will not pause on exceptions.\nignoreExceptionsItem=Ignore exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptionsItem): The pause on exceptions dropdown\n# item shown when a user is adding a new breakpoint.\npauseOnUncaughtExceptionsItem=Pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptionsItem): The pause on exceptions button description\n# when the debugger will pause on all exceptions.\npauseOnExceptionsItem=Pause on all exceptions\n\n# LOCALIZATION NOTE (workersHeader): The text to display in the events\n# header.\nworkersHeader=Workers\n\n# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list\n# when there are no workers.\nnoWorkersText=This page has no workers.\n\n# LOCALIZATION NOTE (noSourcesText): The text to display in the sources list\n# when there are no sources.\nnoSourcesText=This page has no sources.\n\n# LOCALIZATION NOTE (noEventListenersText): The text to display in the events tab\n# when there are no events.\nnoEventListenersText=No event listeners to display.\n\n# LOCALIZATION NOTE (eventListenersHeader): The text to display in the events\n# header.\neventListenersHeader=Event listeners\n\n# LOCALIZATION NOTE (noStackFramesText): The text to display in the call stack tab\n# when there are no stack frames.\nnoStackFramesText=No stack frames to display\n\n# LOCALIZATION NOTE (eventCheckboxTooltip): The tooltip text to display when\n# the user hovers over the checkbox used to toggle an event breakpoint.\neventCheckboxTooltip=Toggle breaking on this event\n\n# LOCALIZATION NOTE (eventOnSelector): The text to display in the events tab\n# for every event item, between the event type and event selector.\neventOnSelector=on\n\n# LOCALIZATION NOTE (eventInSource): The text to display in the events tab\n# for every event item, between the event selector and listener's owner source.\neventInSource=in\n\n# LOCALIZATION NOTE (eventNodes): The text to display in the events tab when\n# an event is listened on more than one target node.\neventNodes=%S nodes\n\n# LOCALIZATION NOTE (eventNative): The text to display in the events tab when\n# a listener is added from plugins, thus getting translated to native code.\neventNative=[native code]\n\n# LOCALIZATION NOTE (*Events): The text to display in the events tab for\n# each group of sub-level event entries.\nanimationEvents=Animation\naudioEvents=Audio\nbatteryEvents=Battery\nclipboardEvents=Clipboard\ncompositionEvents=Composition\ndeviceEvents=Device\ndisplayEvents=Display\ndragAndDropEvents=Drag and Drop\ngamepadEvents=Gamepad\nindexedDBEvents=IndexedDB\ninteractionEvents=Interaction\nkeyboardEvents=Keyboard\nmediaEvents=HTML5 Media\nmouseEvents=Mouse\nmutationEvents=Mutation\nnavigationEvents=Navigation\npointerLockEvents=Pointer Lock\nsensorEvents=Sensor\nstorageEvents=Storage\ntimeEvents=Time\ntouchEvents=Touch\notherEvents=Other\n\n# LOCALIZATION NOTE (blackboxCheckboxTooltip2): The tooltip text to display when\n# the user hovers over the checkbox used to toggle blackboxing its associated\n# source.\nblackboxCheckboxTooltip2=Toggle blackboxing\n\n# LOCALIZATION NOTE (sources.search.key2): Key shortcut to open the search for\n# searching all the source files the debugger has seen.\n# Do not localize \"CmdOrCtrl+P\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsources.search.key2=CmdOrCtrl+P\n\n# LOCALIZATION NOTE (sources.search.alt.key): A second key shortcut to open the\n# search for searching all the source files the debugger has seen.\n# Do not localize \"CmdOrCtrl+O\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsources.search.alt.key=CmdOrCtrl+O\n\n# LOCALIZATION NOTE (projectTextSearch.key): A key shortcut to open the\n# full project text search for searching all the files the debugger has seen.\n# Do not localize \"CmdOrCtrl+Shift+F\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nprojectTextSearch.key=CmdOrCtrl+Shift+F\n\n# LOCALIZATION NOTE (functionSearch.key): A key shortcut to open the\n# modal for searching functions in a file.\n# Do not localize \"CmdOrCtrl+Shift+O\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nfunctionSearch.key=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE (toggleBreakpoint.key): A key shortcut to toggle\n# breakpoints.\n# Do not localize \"CmdOrCtrl+B\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\ntoggleBreakpoint.key=CmdOrCtrl+B\n\n# LOCALIZATION NOTE (toggleCondPanel.key): A key shortcut to toggle\n# the conditional breakpoint panel.\n# Do not localize \"CmdOrCtrl+Shift+B\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\ntoggleCondPanel.key=CmdOrCtrl+Shift+B\n\n# LOCALIZATION NOTE (stepOut.key): A key shortcut to\n# step out.\nstepOut.key=Shift+F11\n\n# LOCALIZATION NOTE (shortcuts.header.editor): Sections header in\n# the shortcuts modal for keyboard shortcuts related to editing.\nshortcuts.header.editor=Editor\n\n# LOCALIZATION NOTE (shortcuts.header.stepping): Sections header in\n# the shortcuts modal for keyboard shortcuts related to stepping.\nshortcuts.header.stepping=Stepping\n\n# LOCALIZATION NOTE (shortcuts.header.search): Sections header in\n# the shortcuts modal for keyboard shortcuts related to search.\nshortcuts.header.search=Search\n\n# LOCALIZATION NOTE (projectTextSearch.placeholder): A placeholder shown\n# when searching across all of the files in a project.\nprojectTextSearch.placeholder=Find in files…\n\n# LOCALIZATION NOTE (projectTextSearch.noResults): The center pane Text Search\n# message when the query did not match any text of all files in a project.\nprojectTextSearch.noResults=No results found\n\n# LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger\n# does not have any sources.\nsources.noSourcesAvailable=This page has no sources\n\n# LOCALIZATION NOTE (sourceSearch.search.key2): Key shortcut to open the search\n# for searching within a the currently opened files in the editor\n# Do not localize \"CmdOrCtrl+F\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsourceSearch.search.key2=CmdOrCtrl+F\n\n# LOCALIZATION NOTE (sourceSearch.search.placeholder): placeholder text in\n# the source search input bar\nsourceSearch.search.placeholder=Search in file…\n\n# LOCALIZATION NOTE (sourceSearch.search.again.key2): Key shortcut to highlight\n# the next occurrence of the last search triggered from a source search\n# Do not localize \"CmdOrCtrl+G\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsourceSearch.search.again.key2=CmdOrCtrl+G\n\n# LOCALIZATION NOTE (sourceSearch.search.againPrev.key2): Key shortcut to highlight\n# the previous occurrence of the last search triggered from a source search\n# Do not localize \"CmdOrCtrl+Shift+G\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsourceSearch.search.againPrev.key2=CmdOrCtrl+Shift+G\n\n# LOCALIZATION NOTE (sourceSearch.resultsSummary1): Shows a summary of\n# the number of matches for autocomplete\nsourceSearch.resultsSummary1=%d results\n\n# LOCALIZATION NOTE (noMatchingStringsText): The text to display in the\n# global search results when there are no matching strings after filtering.\nnoMatchingStringsText=No matches found\n\n# LOCALIZATION NOTE (emptySearchText): This is the text that appears in the\n# filter text box when it is empty and the scripts container is selected.\nemptySearchText=Search scripts (%S)\n\n# LOCALIZATION NOTE (emptyVariablesFilterText): This is the text that\n# appears in the filter text box for the variables view container.\nemptyVariablesFilterText=Filter variables\n\n# LOCALIZATION NOTE (emptyPropertiesFilterText): This is the text that\n# appears in the filter text box for the editor's variables view bubble.\nemptyPropertiesFilterText=Filter properties\n\n# LOCALIZATION NOTE (searchPanelFilter): This is the text that appears in the\n# filter panel popup for the filter scripts operation.\nsearchPanelFilter=Filter scripts (%S)\n\n# LOCALIZATION NOTE (searchPanelGlobal): This is the text that appears in the\n# filter panel popup for the global search operation.\nsearchPanelGlobal=Search in all files (%S)\n\n# LOCALIZATION NOTE (searchPanelFunction): This is the text that appears in the\n# filter panel popup for the function search operation.\nsearchPanelFunction=Search for function definition (%S)\n\n# LOCALIZATION NOTE (searchPanelToken): This is the text that appears in the\n# filter panel popup for the token search operation.\nsearchPanelToken=Find in this file (%S)\n\n# LOCALIZATION NOTE (searchPanelGoToLine): This is the text that appears in the\n# filter panel popup for the line search operation.\nsearchPanelGoToLine=Go to line (%S)\n\n# LOCALIZATION NOTE (searchPanelVariable): This is the text that appears in the\n# filter panel popup for the variables search operation.\nsearchPanelVariable=Filter variables (%S)\n\n# LOCALIZATION NOTE (breakpointMenuItem): The text for all the elements that\n# are displayed in the breakpoints menu item popup.\nbreakpointMenuItem.setConditional=Configure conditional breakpoint\nbreakpointMenuItem.enableSelf2.label=Enable\nbreakpointMenuItem.enableSelf2.accesskey=E\nbreakpointMenuItem.disableSelf2.label=Disable\nbreakpointMenuItem.disableSelf2.accesskey=D\nbreakpointMenuItem.deleteSelf2.label=Remove\nbreakpointMenuItem.deleteSelf2.accesskey=R\nbreakpointMenuItem.enableOthers2.label=Enable others\nbreakpointMenuItem.enableOthers2.accesskey=o\nbreakpointMenuItem.disableOthers2.label=Disable others\nbreakpointMenuItem.disableOthers2.accesskey=s\nbreakpointMenuItem.deleteOthers2.label=Remove others\nbreakpointMenuItem.deleteOthers2.accesskey=h\nbreakpointMenuItem.enableAll2.label=Enable all\nbreakpointMenuItem.enableAll2.accesskey=b\nbreakpointMenuItem.disableAll2.label=Disable all\nbreakpointMenuItem.disableAll2.accesskey=k\nbreakpointMenuItem.deleteAll2.label=Remove all\nbreakpointMenuItem.deleteAll2.accesskey=a\nbreakpointMenuItem.removeCondition2.label=Remove condition\nbreakpointMenuItem.removeCondition2.accesskey=c\nbreakpointMenuItem.addCondition2.label=Add condition\nbreakpointMenuItem.addCondition2.accesskey=A\nbreakpointMenuItem.editCondition2.label=Edit condition\nbreakpointMenuItem.editCondition2.accesskey=n\nbreakpointMenuItem.enableSelf=Enable breakpoint\nbreakpointMenuItem.enableSelf.accesskey=E\nbreakpointMenuItem.disableSelf=Disable breakpoint\nbreakpointMenuItem.disableSelf.accesskey=D\nbreakpointMenuItem.deleteSelf=Remove breakpoint\nbreakpointMenuItem.deleteSelf.accesskey=R\nbreakpointMenuItem.enableOthers=Enable others\nbreakpointMenuItem.enableOthers.accesskey=o\nbreakpointMenuItem.disableOthers=Disable others\nbreakpointMenuItem.disableOthers.accesskey=s\nbreakpointMenuItem.deleteOthers=Remove others\nbreakpointMenuItem.deleteOthers.accesskey=h\nbreakpointMenuItem.enableAll=Enable all breakpoints\nbreakpointMenuItem.enableAll.accesskey=b\nbreakpointMenuItem.disableAll=Disable all breakpoints\nbreakpointMenuItem.disableAll.accesskey=k\nbreakpointMenuItem.deleteAll=Remove all breakpoints\nbreakpointMenuItem.deleteAll.accesskey=a\nbreakpointMenuItem.removeCondition.label=Remove breakpoint condition\nbreakpointMenuItem.removeCondition.accesskey=c\nbreakpointMenuItem.editCondition.label=Edit breakpoint condition\nbreakpointMenuItem.editCondition.accesskey=n\n\n# LOCALIZATION NOTE (breakpoints.header): Breakpoints right sidebar pane header.\nbreakpoints.header=Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.none): The text that appears when there are\n# no breakpoints present\nbreakpoints.none=No breakpoints\n\n# LOCALIZATION NOTE (breakpoints.enable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.enable=Enable breakpoints\n\n# LOCALIZATION NOTE (breakpoints.disable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.disable=Disable breakpoints\n\n# LOCALIZATION NOTE (breakpoints.removeBreakpointTooltip): The tooltip that is displayed\n# for remove breakpoint button in right sidebar\nbreakpoints.removeBreakpointTooltip=Remove breakpoint\n\n# LOCALIZATION NOTE (callStack.header): Call Stack right sidebar pane header.\ncallStack.header=Call stack\n\n# LOCALIZATION NOTE (callStack.notPaused): Call Stack right sidebar pane\n# message when not paused.\ncallStack.notPaused=Not paused\n\n# LOCALIZATION NOTE (callStack.collapse): Call Stack right sidebar pane\n# message to hide some of the frames that are shown.\ncallStack.collapse=Collapse rows\n\n# LOCALIZATION NOTE (callStack.expand): Call Stack right sidebar pane\n# message to show more of the frames.\ncallStack.expand=Expand rows\n\n# LOCALIZATION NOTE (editor.searchResults): Editor Search bar message\n# for the summarizing the selected search result. e.g. 5 of 10 results.\neditor.searchResults=%d of %d results\n\n# LOCALIZATION NOTE (editor.singleResult): Copy shown when there is one result.\neditor.singleResult=1 result\n\n# LOCALIZATION NOTE (editor.noResults): Editor Search bar message\n# for when no results found.\neditor.noResults=No results\n\n# LOCALIZATION NOTE (editor.searchResults.nextResult): Editor Search bar\n# tooltip for traversing to the Next Result\neditor.searchResults.nextResult=Next result\n\n# LOCALIZATION NOTE (editor.searchResults.prevResult): Editor Search bar\n# tooltip for traversing to the Previous Result\neditor.searchResults.prevResult=Previous result\n\n# LOCALIZATION NOTE (editor.searchTypeToggleTitle): Search bar title for\n# toggling search type buttons(function search, variable search)\neditor.searchTypeToggleTitle=Search for:\n\n# LOCALIZATION NOTE (editor.continueToHere.label): Editor gutter context\n# menu item for jumping to a new paused location\neditor.continueToHere.label=Continue to here\neditor.continueToHere.accesskey=H\n\n# LOCALIZATION NOTE (editor.addBreakpoint): Editor gutter context menu item\n# for adding a breakpoint on a line.\neditor.addBreakpoint=Add breakpoint\n\n# LOCALIZATION NOTE (editor.disableBreakpoint): Editor gutter context menu item\n# for disabling a breakpoint on a line.\neditor.disableBreakpoint=Disable breakpoint\neditor.disableBreakpoint.accesskey=D\n\n# LOCALIZATION NOTE (editor.enableBreakpoint): Editor gutter context menu item\n# for enabling a breakpoint on a line.\neditor.enableBreakpoint=Enable breakpoint\n\n# LOCALIZATION NOTE (editor.removeBreakpoint): Editor gutter context menu item\n# for removing a breakpoint on a line.\neditor.removeBreakpoint=Remove breakpoint\n\n# LOCALIZATION NOTE (editor.editBreakpoint): Editor gutter context menu item\n# for setting a breakpoint condition on a line.\neditor.editBreakpoint=Edit breakpoint\n\n# LOCALIZATION NOTE (editor.addConditionalBreakpoint): Editor gutter context\n# menu item for adding a breakpoint condition on a line.\neditor.addConditionalBreakpoint=Add conditional breakpoint\neditor.addConditionalBreakpoint.accesskey=c\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Placeholder text for\n# input element inside ConditionalPanel component\neditor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true\n\n# LOCALIZATION NOTE (editor.conditionalPanel.close): Tooltip text for\n# close button inside ConditionalPanel component\neditor.conditionalPanel.close=Cancel edit breakpoint and close\n\n# LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item\n# for navigating to a source mapped location\neditor.jumpToMappedLocation1=Jump to %S location\neditor.jumpToMappedLocation1.accesskey=m\n\n# LOCALIZATION NOTE (framework.disableGrouping): This is the text that appears in the\n# context menu to disable framework grouping.\nframework.disableGrouping=Disable framework grouping\nframework.disableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (framework.enableGrouping): This is the text that appears in the\n# context menu to enable framework grouping.\nframework.enableGrouping=Enable framework grouping\nframework.enableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (generated): Source Map term for a server source location\ngenerated=generated\n\n# LOCALIZATION NOTE (original): Source Map term for a debugger UI source location\noriginal=original\n\n# LOCALIZATION NOTE (expressions.placeholder): Placeholder text for expression\n# input element\nexpressions.placeholder=Add watch expression\n# LOCALIZATION NOTE (expressions.errorMsg): Error text for expression\n# input element\nexpressions.errorMsg=Invalid expression…\nexpressions.label=Add watch expression\nexpressions.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item\n# for closing the selected tab below the mouse.\nsourceTabs.closeTab=Close tab\nsourceTabs.closeTab.accesskey=c\n\n# LOCALIZATION NOTE (sourceTabs.closeOtherTabs): Editor source tab context menu item\n# for closing the other tabs.\nsourceTabs.closeOtherTabs=Close other tabs\nsourceTabs.closeOtherTabs.accesskey=o\n\n# LOCALIZATION NOTE (sourceTabs.closeTabsToEnd): Editor source tab context menu item\n# for closing the tabs to the end (the right for LTR languages) of the selected tab.\nsourceTabs.closeTabsToEnd=Close tabs to the right\nsourceTabs.closeTabsToEnd.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeAllTabs): Editor source tab context menu item\n# for closing all tabs.\nsourceTabs.closeAllTabs=Close all tabs\nsourceTabs.closeAllTabs.accesskey=a\n\n# LOCALIZATION NOTE (sourceTabs.revealInTree): Editor source tab context menu item\n# for revealing source in tree.\nsourceTabs.revealInTree=Reveal in tree\nsourceTabs.revealInTree.accesskey=r\n\n# LOCALIZATION NOTE (sourceTabs.prettyPrint): Editor source tab context menu item\n# for pretty printing the source.\nsourceTabs.prettyPrint=Pretty print source\nsourceTabs.prettyPrint.accesskey=p\n\n# LOCALIZATION NOTE (sourceFooter.blackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.blackbox=Blackbox source\nsourceFooter.blackbox.accesskey=B\n\n# LOCALIZATION NOTE (sourceFooter.unblackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.unblackbox=Unblackbox source\nsourceFooter.unblackbox.accesskey=b\n\n# LOCALIZATION NOTE (sourceFooter.blackboxed): Text associated\n# with a blackboxed source\nsourceFooter.blackboxed=Blackboxed source\n\n# LOCALIZATION NOTE (sourceFooter.mappedSource): Text associated\n# with a mapped source. %S is replaced by the source map origin.\nsourceFooter.mappedSource=(From %S)\n\n# LOCALIZATION NOTE (sourceFooter.mappedSourceTooltip): Tooltip text associated\n# with a mapped source. %S is replaced by the source map origin.\nsourceFooter.mappedSourceTooltip=(Source mapped from %S)\n\n# LOCALIZATION NOTE (sourceFooter.codeCoverage): Text associated\n# with a code coverage button\nsourceFooter.codeCoverage=Code coverage\n\n# LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed\n# for close tab button in source tabs.\nsourceTabs.closeTabButtonTooltip=Close tab\n\n# LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header.\nscopes.header=Scopes\n\n# LOCALIZATION NOTE (scopes.notAvailable): Scopes right sidebar pane message\n# for when the debugger is paused, but there isn't pause data.\nscopes.notAvailable=Scopes unavailable\n\n# LOCALIZATION NOTE (scopes.notPaused): Scopes right sidebar pane message\n# for when the debugger is not paused.\nscopes.notPaused=Not paused\n\n# LOCALIZATION NOTE (scopes.block): Refers to a block of code in\n# the scopes pane when the debugger is paused.\nscopes.block=Block\n\n# LOCALIZATION NOTE (sources.header): Sources left sidebar header\nsources.header=Sources\n\n# LOCALIZATION NOTE (outline.header): Outline left sidebar header\noutline.header=Outline\n\n# LOCALIZATION NOTE (outline.noFunctions): Outline text when there are no functions to display\noutline.noFunctions=No functions\n\n# LOCALIZATION NOTE (sources.search): Sources left sidebar prompt\n# e.g. Cmd+P to search. On a mac, we use the command unicode character.\n# On windows, it's ctrl.\nsources.search=%S to search\n\n# LOCALIZATION NOTE (watchExpressions.header): Watch Expressions right sidebar\n# pane header.\nwatchExpressions.header=Watch expressions\n\n# LOCALIZATION NOTE (watchExpressions.refreshButton): Watch Expressions header\n# button for refreshing the expressions.\nwatchExpressions.refreshButton=Refresh\n\n# LOCALIZATION NOTE (welcome.search): The center pane welcome panel's\n# search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on\n# a mac we use the unicode character.\nwelcome.search=%S to search for sources\n\n# LOCALIZATION NOTE (welcome.findInFiles): The center pane welcome panel's\n# search prompt. e.g. cmd+f to search for files. On windows, it's ctrl+shift+f, on\n# a mac we use the unicode character.\nwelcome.findInFiles=%S to find in files\n\n# LOCALIZATION NOTE (welcome.searchFunction): Label displayed in the welcome\n# panel. %S is replaced by the keyboard shortcut to search for functions.\nwelcome.searchFunction=%S to search for functions in file\n\n# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search\n# prompt for searching for files.\nsourceSearch.search=Search sources…\n\n# LOCALIZATION NOTE (sourceSearch.noResults2): The center pane Source Search\n# message when the query did not match any of the sources.\nsourceSearch.noResults2=No results found\n\n# LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip\n# when the debugger will not pause on exceptions.\nignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptions): The pause on exceptions button\n# tooltip when the debugger will pause on uncaught exceptions.\npauseOnUncaughtExceptions=Pause on uncaught exceptions. Click to pause on all exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptions): The pause on exceptions button tooltip\n# when the debugger will pause on all exceptions.\npauseOnExceptions=Pause on all exceptions. Click to ignore exceptions\n\n# LOCALIZATION NOTE (loadingText): The text that is displayed in the script\n# editor when the loading process has started but there is no file to display\n# yet.\nloadingText=Loading\\u2026\n\n# LOCALIZATION NOTE (wasmIsNotAvailable): The text that is displayed in the\n# script editor when the WebAssembly source is not available.\nwasmIsNotAvailable=Please refresh to debug this module\n\n# LOCALIZATION NOTE (errorLoadingText3): The text that is displayed in the debugger\n# viewer when there is an error loading a file\nerrorLoadingText3=Error loading this URI: %S\n\n# LOCALIZATION NOTE (addWatchExpressionText): The text that is displayed in the\n# watch expressions list to add a new item.\naddWatchExpressionText=Add watch expression\n\n# LOCALIZATION NOTE (addWatchExpressionButton): The button that is displayed in the\n# variables view popup.\naddWatchExpressionButton=Watch\n\n# LOCALIZATION NOTE (emptyVariablesText): The text that is displayed in the\n# variables pane when there are no variables to display.\nemptyVariablesText=No variables to display\n\n# LOCALIZATION NOTE (scopeLabel): The text that is displayed in the variables\n# pane as a header for each variable scope (e.g. \"Global scope, \"With scope\",\n# etc.).\nscopeLabel=%S scope\n\n# LOCALIZATION NOTE (watchExpressionsScopeLabel): The name of the watch\n# expressions scope. This text is displayed in the variables pane as a header for\n# the watch expressions scope.\nwatchExpressionsScopeLabel=Watch expressions\n\n# LOCALIZATION NOTE (globalScopeLabel): The name of the global scope. This text\n# is added to scopeLabel and displayed in the variables pane as a header for\n# the global scope.\nglobalScopeLabel=Global\n\n# LOCALIZATION NOTE (variablesViewErrorStacktrace): This is the text that is\n# shown before the stack trace in an error.\nvariablesViewErrorStacktrace=Stack trace:\n\n# LOCALIZATION NOTE (variablesViewMoreObjects): the text that is displayed\n# when you have an object preview that does not show all of the elements. At the end of the list\n# you see \"N more...\" in the web console output.\n# This is a semi-colon list of plural forms.\n# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals\n# #1 number of remaining items in the object\n# example: 3 more…\nvariablesViewMoreObjects=#1 more…;#1 more…\n\n# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed\n# in the variables list on an item with an editable name.\nvariablesEditableNameTooltip=Double click to edit\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in the variables list on an item with an editable value.\nvariablesEditableValueTooltip=Click to change value\n\n# LOCALIZATION NOTE (variablesCloseButtonTooltip): The text that is displayed\n# in the variables list on an item which can be removed.\nvariablesCloseButtonTooltip=Click to remove\n\n# LOCALIZATION NOTE (variablesEditButtonTooltip): The text that is displayed\n# in the variables list on a getter or setter which can be edited.\nvariablesEditButtonTooltip=Click to set value\n\n# LOCALIZATION NOTE (variablesDomNodeValueTooltip): The text that is displayed\n# in a tooltip on the \"open in inspector\" button in the the variables list for a\n# DOMNode item.\nvariablesDomNodeValueTooltip=Click to select the node in the inspector\n\n# LOCALIZATION NOTE (configurable|...|Tooltip): The text that is displayed\n# in the variables list on certain variables or properties as tooltips.\n# Expanations of what these represent can be found at the following links:\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n# It's probably best to keep these in English.\nconfigurableTooltip=configurable\nenumerableTooltip=enumerable\nwritableTooltip=writable\nfrozenTooltip=frozen\nsealedTooltip=sealed\nextensibleTooltip=extensible\noverriddenTooltip=overridden\nWebIDLTooltip=WebIDL\n\n# LOCALIZATION NOTE (variablesSeparatorLabel): The text that is displayed\n# in the variables list as a separator between the name and value.\nvariablesSeparatorLabel=:\n\n# LOCALIZATION NOTE (watchExpressionsSeparatorLabel2): The text that is displayed\n# in the watch expressions list as a separator between the code and evaluation.\nwatchExpressionsSeparatorLabel2=\\u0020→\n\n# LOCALIZATION NOTE (functionSearchSeparatorLabel): The text that is displayed\n# in the functions search panel as a separator between function's inferred name\n# and its real name (if available).\nfunctionSearchSeparatorLabel=←\n\n# LOCALIZATION NOTE(gotoLineModal.placeholder): The placeholder\n# text displayed when the user searches for specific lines in a file\ngotoLineModal.placeholder=Go to line…\n\n# LOCALIZATION NOTE(gotoLineModal.title): The message shown to users\n# to open the go to line modal\ngotoLineModal.title=Go to a line number in a file\n\n# LOCALIZATION NOTE(gotoLineModal.key2): The shortcut for opening the\n# go to line modal\n# Do not localize \"CmdOrCtrl+;\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\ngotoLineModal.key2=CmdOrCtrl+;\n\n# LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder\n# text displayed when the user searches for functions in a file\nsymbolSearch.search.functionsPlaceholder=Search functions…\nsymbolSearch.search.functionsPlaceholder.title=Search for a function in a file\n\n# LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder\n# text displayed when the user searches for variables in a file\nsymbolSearch.search.variablesPlaceholder=Search variables…\nsymbolSearch.search.variablesPlaceholder.title=Search for a variable in a file\n\n# LOCALIZATION NOTE(symbolSearch.search.key2): The Key Shortcut for\n# searching for a function or variable\n# Do not localize \"CmdOrCtrl+Shift+O\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsymbolSearch.search.key2=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.modifiersLabel): A label\n# preceding the group of modifiers\nsymbolSearch.searchModifier.modifiersLabel=Modifiers:\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.regex): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.regex=Regex\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.caseSensitive): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.caseSensitive=Case sensitive\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.wholeWord): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.wholeWord=Whole word\n\n# LOCALIZATION NOTE (resumptionOrderPanelTitle): This is the text that appears\n# as a description in the notification panel popup, when multiple debuggers are\n# open in separate tabs and the user tries to resume them in the wrong order.\n# The substitution parameter is the URL of the last paused window that must be\n# resumed first.\nresumptionOrderPanelTitle=There are one or more paused debuggers. Please resume the most-recently paused debugger first at: %S\n\nvariablesViewOptimizedOut=(optimized away)\nvariablesViewUninitialized=(uninitialized)\nvariablesViewMissingArgs=(unavailable)\n\nanonymousSourcesLabel=Anonymous sources\n\nexperimental=This is an experimental feature\n\n# LOCALIZATION NOTE (whyPaused.debuggerStatement): The text that is displayed\n# in a info block explaining how the debugger is currently paused due to a `debugger`\n# statement in the code\nwhyPaused.debuggerStatement=Paused on debugger statement\n\n# LOCALIZATION NOTE (whyPaused.breakpoint): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a breakpoint\nwhyPaused.breakpoint=Paused on breakpoint\n\n# LOCALIZATION NOTE (whyPaused.exception): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an exception\nwhyPaused.exception=Paused on exception\n\n# LOCALIZATION NOTE (whyPaused.resumeLimit): The text that is displayed\n# in a info block explaining how the debugger is currently paused while stepping\n# in or out of the stack\nwhyPaused.resumeLimit=Paused while stepping\n\n# LOCALIZATION NOTE (whyPaused.pauseOnDOMEvents): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# dom event\nwhyPaused.pauseOnDOMEvents=Paused on event listener\n\n# LOCALIZATION NOTE (whyPaused.breakpointConditionThrown): The text that is displayed\n# in an info block when evaluating a conditional breakpoint throws an error\nwhyPaused.breakpointConditionThrown=Error with conditional breakpoint\n\n# LOCALIZATION NOTE (whyPaused.xhr): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# xml http request\nwhyPaused.xhr=Paused on XMLHttpRequest\n\n# LOCALIZATION NOTE (whyPaused.promiseRejection): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# promise rejection\nwhyPaused.promiseRejection=Paused on promise rejection\n\n# LOCALIZATION NOTE (whyPaused.assert): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# assert\nwhyPaused.assert=Paused on assertion\n\n# LOCALIZATION NOTE (whyPaused.debugCommand): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# debugger statement\nwhyPaused.debugCommand=Paused on debugged function\n\n# LOCALIZATION NOTE (whyPaused.other): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an event\n# listener breakpoint set\nwhyPaused.other=Debugger paused\n\n# LOCALIZATION NOTE (ctrl): The text that is used for documenting\n# keyboard shortcuts that use the control key\nctrl=Ctrl\n\n# LOCALIZATION NOTE (anonymous): The text that is displayed when the\n# display name is null.\nanonymous=(anonymous)\n\n# LOCALIZATION NOTE (shortcuts.toggleBreakpoint): text describing\n# keyboard shortcut action for toggling breakpoint\nshortcuts.toggleBreakpoint=Toggle Breakpoint\nshortcuts.toggleBreakpoint.accesskey=B\n\n# LOCALIZATION NOTE (shortcuts.toggleCondPanel): text describing\n# keyboard shortcut action for toggling conditional panel keyboard\nshortcuts.toggleCondPanel=Toggle Conditional Panel\n\n# LOCALIZATION NOTE (shortcuts.pauseOrResume): text describing\n# keyboard shortcut action for pause of resume\nshortcuts.pauseOrResume=Pause/Resume\n\n# LOCALIZATION NOTE (shortcuts.stepOver): text describing\n# keyboard shortcut action for stepping over\nshortcuts.stepOver=Step Over\n\n# LOCALIZATION NOTE (shortcuts.stepIn): text describing\n# keyboard shortcut action for stepping in\nshortcuts.stepIn=Step In\n\n# LOCALIZATION NOTE (shortcuts.stepOut): text describing\n# keyboard shortcut action for stepping out\nshortcuts.stepOut=Step Out\n\n# LOCALIZATION NOTE (shortcuts.fileSearch): text describing\n# keyboard shortcut action for source file search\nshortcuts.fileSearch=Source File Search\n\n# LOCALIZATION NOTE (shortcuts.gotoLine): text describing\n# keyboard shortcut for jumping to a specific line\nshortcuts.gotoLine=Go to line\n\n# LOCALIZATION NOTE (shortcuts.searchAgain): text describing\n# keyboard shortcut action for searching again\nshortcuts.searchAgain=Search Again\n\n# LOCALIZATION NOTE (shortcuts.projectSearch): text describing\n# keyboard shortcut action for full project search\nshortcuts.projectSearch=Full Project Search\n\n# LOCALIZATION NOTE (shortcuts.functionSearch): text describing\n# keyboard shortcut action for function search\nshortcuts.functionSearch=Function Search\n\n# LOCALIZATION NOTE (shortcuts.buttonName): text describing\n# keyboard shortcut button text\nshortcuts.buttonName=Keyboard shortcuts\n"
 
 /***/ }),
 /* 961 */,
 /* 962 */,
 /* 963 */,
 /* 964 */,
 /* 965 */
 /***/ (function(module, exports) {
@@ -16140,110 +16140,237 @@ module.exports = "<!-- This Source Code 
 /* 1350 */,
 /* 1351 */,
 /* 1352 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
-var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /* 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/>. */
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
 
 var _expressions = __webpack_require__(1417);
 
-var expressions = _interopRequireWildcard(_expressions);
+Object.keys(_expressions).forEach(function (key) {
+  if (key === "default" || key === "__esModule") return;
+  Object.defineProperty(exports, key, {
+    enumerable: true,
+    get: function () {
+      return _expressions[key];
+    }
+  });
+});
 
 var _sources = __webpack_require__(1369);
 
-var sources = _interopRequireWildcard(_sources);
+Object.keys(_sources).forEach(function (key) {
+  if (key === "default" || key === "__esModule") return;
+  Object.defineProperty(exports, key, {
+    enumerable: true,
+    get: function () {
+      return _sources[key];
+    }
+  });
+});
 
 var _pause = __webpack_require__(1394);
 
-var pause = _interopRequireWildcard(_pause);
+Object.keys(_pause).forEach(function (key) {
+  if (key === "default" || key === "__esModule") return;
+  Object.defineProperty(exports, key, {
+    enumerable: true,
+    get: function () {
+      return _pause[key];
+    }
+  });
+});
 
 var _debuggee = __webpack_require__(1418);
 
-var debuggee = _interopRequireWildcard(_debuggee);
+Object.keys(_debuggee).forEach(function (key) {
+  if (key === "default" || key === "__esModule") return;
+  Object.defineProperty(exports, key, {
+    enumerable: true,
+    get: function () {
+      return _debuggee[key];
+    }
+  });
+});
 
 var _breakpoints = __webpack_require__(1378);
 
-var breakpoints = _interopRequireWildcard(_breakpoints);
+Object.keys(_breakpoints).forEach(function (key) {
+  if (key === "default" || key === "__esModule") return;
+  Object.defineProperty(exports, key, {
+    enumerable: true,
+    get: function () {
+      return _breakpoints[key];
+    }
+  });
+});
 
 var _pendingBreakpoints = __webpack_require__(1419);
 
-var pendingBreakpoints = _interopRequireWildcard(_pendingBreakpoints);
-
-var _eventListeners = __webpack_require__(1420);
-
-var eventListeners = _interopRequireWildcard(_eventListeners);
+Object.keys(_pendingBreakpoints).forEach(function (key) {
+  if (key === "default" || key === "__esModule") return;
+  Object.defineProperty(exports, key, {
+    enumerable: true,
+    get: function () {
+      return _pendingBreakpoints[key];
+    }
+  });
+});
 
 var _ui = __webpack_require__(1421);
 
-var ui = _interopRequireWildcard(_ui);
+Object.keys(_ui).forEach(function (key) {
+  if (key === "default" || key === "__esModule") return;
+  Object.defineProperty(exports, key, {
+    enumerable: true,
+    get: function () {
+      return _ui[key];
+    }
+  });
+});
 
 var _fileSearch = __webpack_require__(1422);
 
-var fileSearch = _interopRequireWildcard(_fileSearch);
+Object.keys(_fileSearch).forEach(function (key) {
+  if (key === "default" || key === "__esModule") return;
+  Object.defineProperty(exports, key, {
+    enumerable: true,
+    get: function () {
+      return _fileSearch[key];
+    }
+  });
+});
 
 var _ast = __webpack_require__(1383);
 
-var ast = _interopRequireWildcard(_ast);
+Object.keys(_ast).forEach(function (key) {
+  if (key === "default" || key === "__esModule") return;
+  Object.defineProperty(exports, key, {
+    enumerable: true,
+    get: function () {
+      return _ast[key];
+    }
+  });
+});
 
 var _coverage = __webpack_require__(1423);
 
-var coverage = _interopRequireWildcard(_coverage);
+Object.keys(_coverage).forEach(function (key) {
+  if (key === "default" || key === "__esModule") return;
+  Object.defineProperty(exports, key, {
+    enumerable: true,
+    get: function () {
+      return _coverage[key];
+    }
+  });
+});
 
 var _projectTextSearch = __webpack_require__(1424);
 
-var projectTextSearch = _interopRequireWildcard(_projectTextSearch);
-
-var _quickOpen = __webpack_require__(1635);
-
-var quickOpen = _interopRequireWildcard(_quickOpen);
+Object.keys(_projectTextSearch).forEach(function (key) {
+  if (key === "default" || key === "__esModule") return;
+  Object.defineProperty(exports, key, {
+    enumerable: true,
+    get: function () {
+      return _projectTextSearch[key];
+    }
+  });
+});
 
 var _sourceTree = __webpack_require__(1426);
 
-var sourceTree = _interopRequireWildcard(_sourceTree);
+Object.keys(_sourceTree).forEach(function (key) {
+  if (key === "default" || key === "__esModule") return;
+  Object.defineProperty(exports, key, {
+    enumerable: true,
+    get: function () {
+      return _sourceTree[key];
+    }
+  });
+});
+
+var _eventListeners = __webpack_require__(1420);
+
+Object.defineProperty(exports, "getEventListeners", {
+  enumerable: true,
+  get: function () {
+    return _eventListeners.getEventListeners;
+  }
+});
+
+var _quickOpen = __webpack_require__(1635);
+
+Object.defineProperty(exports, "getQuickOpenEnabled", {
+  enumerable: true,
+  get: function () {
+    return _quickOpen.getQuickOpenEnabled;
+  }
+});
+Object.defineProperty(exports, "getQuickOpenQuery", {
+  enumerable: true,
+  get: function () {
+    return _quickOpen.getQuickOpenQuery;
+  }
+});
+Object.defineProperty(exports, "getQuickOpenType", {
+  enumerable: true,
+  get: function () {
+    return _quickOpen.getQuickOpenType;
+  }
+});
 
 var _breakpointAtLocation = __webpack_require__(1503);
 
-var _breakpointAtLocation2 = _interopRequireDefault(_breakpointAtLocation);
+Object.defineProperty(exports, "getBreakpointAtLocation", {
+  enumerable: true,
+  get: function () {
+    return _breakpointAtLocation.getBreakpointAtLocation;
+  }
+});
 
 var _visibleBreakpoints = __webpack_require__(1427);
 
-var _visibleBreakpoints2 = _interopRequireDefault(_visibleBreakpoints);
+Object.defineProperty(exports, "getVisibleBreakpoints", {
+  enumerable: true,
+  get: function () {
+    return _visibleBreakpoints.getVisibleBreakpoints;
+  }
+});
 
 var _isSelectedFrameVisible = __webpack_require__(1505);
 
-var _isSelectedFrameVisible2 = _interopRequireDefault(_isSelectedFrameVisible);
+Object.defineProperty(exports, "isSelectedFrameVisible", {
+  enumerable: true,
+  get: function () {
+    return _isSelectedFrameVisible.isSelectedFrameVisible;
+  }
+});
 
 var _getCallStackFrames = __webpack_require__(1779);
 
-var _getCallStackFrames2 = _interopRequireDefault(_getCallStackFrames);
+Object.defineProperty(exports, "getCallStackFrames", {
+  enumerable: true,
+  get: function () {
+    return _getCallStackFrames.getCallStackFrames;
+  }
+});
 
 var _visibleSelectedFrame = __webpack_require__(1780);
 
-var _visibleSelectedFrame2 = _interopRequireDefault(_visibleSelectedFrame);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-
-/**
- * @param object - location
- */
-
-module.exports = _extends({}, expressions, sources, pause, debuggee, breakpoints, pendingBreakpoints, eventListeners, ui, ast, coverage, fileSearch, projectTextSearch, quickOpen, sourceTree, {
-  getBreakpointAtLocation: _breakpointAtLocation2.default,
-  getVisibleBreakpoints: _visibleBreakpoints2.default,
-  isSelectedFrameVisible: _isSelectedFrameVisible2.default,
-  getCallStackFrames: _getCallStackFrames2.default,
-  getVisibleSelectedFrame: _visibleSelectedFrame2.default
+Object.defineProperty(exports, "getVisibleSelectedFrame", {
+  enumerable: true,
+  get: function () {
+    return _visibleSelectedFrame.getVisibleSelectedFrame;
+  }
 });
 
 /***/ }),
 /* 1353 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -16934,24 +17061,24 @@ function getFileURL(source) {
   }
 
   return resolveFileURL(url);
 }
 
 const contentTypeModeMap = {
   "text/javascript": { name: "javascript" },
   "text/typescript": { name: "javascript", typescript: true },
-  "text/coffeescript": "coffeescript",
+  "text/coffeescript": { name: "coffeescript" },
   "text/typescript-jsx": {
     name: "jsx",
     base: { name: "javascript", typescript: true }
   },
-  "text/jsx": "jsx",
-  "text/x-elm": "elm",
-  "text/x-clojure": "clojure",
+  "text/jsx": { name: "jsx" },
+  "text/x-elm": { name: "elm" },
+  "text/x-clojure": { name: "clojure" },
   "text/wasm": { name: "text" },
   "text/html": { name: "htmlmixed" }
 };
 
 function getSourcePath(url) {
   if (!url) {
     return "";
   }
@@ -16995,27 +17122,27 @@ function getSourceLineCount(source) {
 function getMode(source, symbols) {
   const { contentType, text, isWasm, url } = source;
 
   if (!text || isWasm) {
     return { name: "text" };
   }
 
   if (url && url.match(/\.jsx$/i) || symbols && symbols.hasJsx) {
-    return "jsx";
+    return { name: "jsx" };
   }
 
   const languageMimeMap = [{ ext: ".c", mode: "text/x-csrc" }, { ext: ".kt", mode: "text/x-kotlin" }, { ext: ".cpp", mode: "text/x-c++src" }, { ext: ".m", mode: "text/x-objectivec" }, { ext: ".rs", mode: "text/x-rustsrc" }];
 
   // check for C and other non JS languages
   if (url) {
     const result = languageMimeMap.find(({ ext }) => url.endsWith(ext));
 
     if (result !== undefined) {
-      return result.mode;
+      return { name: result.mode };
     }
   }
 
   // if the url ends with .marko we set the name to Javascript so
   // syntax highlighting works for marko too
   if (url && url.match(/\.marko$/i)) {
     return { name: "javascript" };
   }
@@ -18134,17 +18261,17 @@ var _extends = Object.assign || function
                                                                                                                                                                                                                                                                    * 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/>. */
 
 /**
  * Sources reducer
  * @module reducers/sources
  */
 
-exports.initialState = initialState;
+exports.initialSourcesState = initialSourcesState;
 exports.removeSourceFromTabList = removeSourceFromTabList;
 exports.removeSourcesFromTabList = removeSourcesFromTabList;
 exports.getNewSelectedSourceId = getNewSelectedSourceId;
 exports.getSource = getSource;
 exports.getSourceByURL = getSourceByURL;
 exports.getGeneratedSource = getGeneratedSource;
 exports.getPendingSelectedLocation = getPendingSelectedLocation;
 exports.getPrettySource = getPrettySource;
@@ -18166,27 +18293,27 @@ var _source = __webpack_require__(1356);
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 var _prefs = __webpack_require__(226);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
-function initialState() {
+function initialSourcesState() {
   return (0, _makeRecord2.default)({
     sources: I.Map(),
     selectedLocation: undefined,
     pendingSelectedLocation: _prefs.prefs.pendingSelectedLocation,
     sourcesText: I.Map(),
     tabs: I.List(restoreTabs())
   })();
 }
 
-function update(state = initialState(), action) {
+function update(state = initialSourcesState(), action) {
   let location = null;
 
   switch (action.type) {
     case "UPDATE_SOURCE":
       {
         const source = action.source;
         return updateSource(state, source);
       }
@@ -18253,20 +18380,20 @@ function update(state = initialState(), 
       }
       break;
 
     case "NAVIGATE":
       const source = getSelectedSource({ sources: state });
       const url = source && source.get("url");
 
       if (!url) {
-        return initialState();
-      }
-
-      return initialState().set("pendingSelectedLocation", { url });
+        return initialSourcesState();
+      }
+
+      return initialSourcesState().set("pendingSelectedLocation", { url });
   }
 
   return state;
 }
 
 function getTextPropsFromAction(action) {
   const { value, sourceId } = action;
 
@@ -18517,17 +18644,17 @@ function isExactUrlMatch(pathPart, debug
   return host.replace(/^www\./, "") === pathPart.replace(/^www\./, "");
 }
 
 function isDirectory(url) {
   const parts = url.path.split("/").filter(p => p !== "");
 
   // Assume that all urls point to files except when they end with '/'
   // Or directory node has children
-  return parts.length === 0 || url.path.slice(-1) === "/" || nodeHasChildren(url);
+  return (parts.length === 0 || url.path.slice(-1) === "/" || nodeHasChildren(url)) && url.name != "(index)";
 }
 
 function getExtension(source) {
   const parsedUrl = (0, _url.parse)(source.get("url")).pathname;
   if (!parsedUrl) {
     return "";
   }
   return parsedUrl.split(".").pop();
@@ -18855,17 +18982,17 @@ var _extends = Object.assign || function
                                                                                                                                                                                                                                                                    * 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/>. */
 
 /**
  * Breakpoints reducer
  * @module reducers/breakpoints
  */
 
-exports.initialState = initialState;
+exports.initialBreakpointsState = initialBreakpointsState;
 exports.getBreakpoints = getBreakpoints;
 exports.getBreakpoint = getBreakpoint;
 exports.getBreakpointsDisabled = getBreakpointsDisabled;
 exports.getBreakpointsLoading = getBreakpointsLoading;
 exports.getBreakpointsForSource = getBreakpointsForSource;
 exports.getBreakpointForLine = getBreakpointForLine;
 exports.getHiddenBreakpoint = getHiddenBreakpoint;
 exports.getHiddenBreakpointLocation = getHiddenBreakpointLocation;
@@ -18881,24 +19008,24 @@ var _makeRecord2 = _interopRequireDefaul
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 var _breakpoint = __webpack_require__(1364);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
-function initialState() {
+function initialBreakpointsState() {
   return (0, _makeRecord2.default)({
     breakpoints: I.Map(),
     breakpointsDisabled: false
   })();
 }
 
-function update(state = initialState(), action) {
+function update(state = initialBreakpointsState(), action) {
   switch (action.type) {
     case "ADD_BREAKPOINT":
       {
         return addBreakpoint(state, action);
       }
 
     case "SYNC_BREAKPOINT":
       {
@@ -18927,17 +19054,17 @@ function update(state = initialState(), 
 
     case "REMAP_BREAKPOINTS":
       {
         return remapBreakpoints(state, action);
       }
 
     case "NAVIGATE":
       {
-        return initialState();
+        return initialBreakpointsState();
       }
   }
 
   return state;
 }
 
 function addBreakpoint(state, action) {
   if (action.status === "start" && action.breakpoint) {
@@ -19232,22 +19359,22 @@ var _extends = Object.assign || function
 
 exports.getLibraryFromUrl = getLibraryFromUrl;
 exports.annotateFrame = annotateFrame;
 exports.simplifyDisplayName = simplifyDisplayName;
 exports.formatDisplayName = formatDisplayName;
 exports.formatCopyName = formatCopyName;
 exports.collapseFrames = collapseFrames;
 
-var _lodash = __webpack_require__(2);
-
 var _utils = __webpack_require__(1366);
 
 var _source = __webpack_require__(1356);
 
+var _lodash = __webpack_require__(2);
+
 function getFrameUrl(frame) {
   return (0, _lodash.get)(frame, "source.url", "") || "";
 }
 
 const libraryMap = [{
   label: "Backbone",
   pattern: /backbone/i
 }, {
@@ -19695,17 +19822,17 @@ var _extends = Object.assign || function
                                                                                                                                                                                                                                                                    * 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/>. */
 
 /**
  * Ast reducer
  * @module reducers/ast
  */
 
-exports.initialState = initialState;
+exports.initialASTState = initialASTState;
 exports.getSymbols = getSymbols;
 exports.hasSymbols = hasSymbols;
 exports.isEmptyLineInSource = isEmptyLineInSource;
 exports.getEmptyLines = getEmptyLines;
 exports.getOutOfScopeLocations = getOutOfScopeLocations;
 exports.getPreview = getPreview;
 exports.getSourceMetaData = getSourceMetaData;
 exports.getInScopeLines = getInScopeLines;
@@ -19717,28 +19844,28 @@ var I = _interopRequireWildcard(_immutab
 var _makeRecord = __webpack_require__(1361);
 
 var _makeRecord2 = _interopRequireDefault(_makeRecord);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
-function initialState() {
+function initialASTState() {
   return (0, _makeRecord2.default)({
     symbols: I.Map(),
     emptyLines: I.Map(),
     outOfScopeLocations: null,
     inScopeLines: null,
     preview: null,
     sourceMetaData: I.Map()
   })();
 }
 
-function update(state = initialState(), action) {
+function update(state = initialASTState(), action) {
   switch (action.type) {
     case "SET_SYMBOLS":
       {
         const { source, symbols } = action;
         return state.setIn(["symbols", source.id], symbols);
       }
 
     case "SET_EMPTY_LINES":
@@ -19779,17 +19906,17 @@ function update(state = initialState(), 
 
     case "RESUME":
       {
         return state.set("outOfScopeLocations", null);
       }
 
     case "NAVIGATE":
       {
-        return initialState();
+        return initialASTState();
       }
 
     case "SET_SOURCE_METADATA":
       {
         return state.setIn(["sourceMetaData", action.sourceId], action.sourceMetaData);
       }
 
     default:
@@ -19842,17 +19969,17 @@ function getPreview(state) {
   return state.ast.get("preview");
 }
 
 const emptySourceMetaData = {};
 function getSourceMetaData(state, sourceId) {
   return state.ast.getIn(["sourceMetaData", sourceId]) || emptySourceMetaData;
 }
 
-function getInScopeLines(state, sourceId) {
+function getInScopeLines(state) {
   return state.ast.get("inScopeLines");
 }
 
 exports.default = update;
 
 /***/ }),
 /* 1384 */
 /***/ (function(module, exports, __webpack_require__) {
@@ -20433,17 +20560,17 @@ exports.join = join;
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.getSelectedFrame = exports.getAllPopupObjectProperties = exports.State = undefined;
+exports.getSelectedFrame = exports.getAllPopupObjectProperties = exports.createPauseState = undefined;
 
 var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /* This Source Code Form is subject to the terms of the Mozilla Public
                                                                                                                                                                                                                                                                    * License, v. 2.0. If a copy of the MPL was not distributed with this
                                                                                                                                                                                                                                                                    * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 /* eslint complexity: ["error", 30]*/
 
 /**
@@ -20472,17 +20599,17 @@ exports.getChromeScopes = getChromeScope
 var _reselect = __webpack_require__(993);
 
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 var _prefs = __webpack_require__(226);
 
 var _sources = __webpack_require__(1369);
 
-const State = exports.State = () => ({
+const createPauseState = exports.createPauseState = () => ({
   why: null,
   isWaitingOnBreak: false,
   frames: undefined,
   selectedFrameId: undefined,
   frameScopes: {
     generated: {},
     original: {}
   },
@@ -20500,17 +20627,17 @@ const emptyPauseState = {
   frameScopes: {
     generated: {},
     original: {}
   },
   selectedFrameId: null,
   loadedObjects: {}
 };
 
-function update(state = State(), action) {
+function update(state = createPauseState(), action) {
   switch (action.type) {
     case "PAUSED":
       {
         const { selectedFrameId, frames, loadedObjects, why } = action;
 
         // turn this into an object keyed by object id
         const objectMap = {};
         loadedObjects.forEach(obj => {
@@ -20583,17 +20710,17 @@ function update(state = State(), action)
 
       return _extends({}, state, {
         loadedObjects: _extends({}, state.loadedObjects, {
           [action.objectId]: action.properties
         })
       });
 
     case "CONNECT":
-      return _extends({}, State(), {
+      return _extends({}, createPauseState(), {
         debuggeeUrl: action.url,
         canRewind: action.canRewind
       });
 
     case "PAUSE_ON_EXCEPTIONS":
       const { shouldPauseOnExceptions, shouldIgnoreCaughtExceptions } = action;
 
       _prefs.prefs.pauseOnExceptions = shouldPauseOnExceptions;
@@ -21841,19 +21968,19 @@ var _extends = Object.assign || function
                                                                                                                                                                                                                                                                    * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 __webpack_require__(1311);
 
-var _devtoolsComponents = __webpack_require__(1441);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+const { Tree } = __webpack_require__(1441);
 
 class ManagedTree extends _react.Component {
   constructor(props) {
     super(props);
 
     this.setExpanded = (item, isExpanded, shouldIncludeChildren) => {
       const expandItem = i => {
         const path = this.props.getPath(i);
@@ -21941,17 +22068,17 @@ class ManagedTree extends _react.Compone
     }
   }
 
   render() {
     const { expanded, focusedItem } = this.state;
     return _react2.default.createElement(
       "div",
       { className: "managed-tree" },
-      _react2.default.createElement(_devtoolsComponents.Tree, _extends({}, this.props, {
+      _react2.default.createElement(Tree, _extends({}, this.props, {
         isExpanded: item => expanded.has(this.props.getPath(item)),
         focused: focusedItem,
         getKey: this.props.getPath,
         onExpand: item => this.setExpanded(item, true, false),
         onCollapse: item => this.setExpanded(item, false, false),
         onFocus: this.focusItem,
         renderItem: (...args) => this.props.renderItem(...args, {
           setExpanded: this.setExpanded
@@ -22920,46 +23047,46 @@ async function findScopeByName(source, n
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.getExpressionError = exports.getExpressions = exports.State = undefined;
+exports.getExpressionError = exports.getExpressions = exports.createExpressionState = undefined;
 exports.getExpression = getExpression;
 
 var _makeRecord = __webpack_require__(1361);
 
 var _makeRecord2 = _interopRequireDefault(_makeRecord);
 
 var _immutable = __webpack_require__(146);
 
 var _lodash = __webpack_require__(2);
 
 var _reselect = __webpack_require__(993);
 
 var _prefs = __webpack_require__(226);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-const State = exports.State = (0, _makeRecord2.default)({
+const createExpressionState = exports.createExpressionState = (0, _makeRecord2.default)({
   expressions: (0, _immutable.List)(restoreExpressions()),
   expressionError: false
 }); /* 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/>. */
 
 /**
  * Expressions reducer
  * @module reducers/expressions
  */
 
-function update(state = State(), action) {
+function update(state = createExpressionState(), action) {
   switch (action.type) {
     case "ADD_EXPRESSION":
       if (action.expressionError) {
         return state.set("expressionError", !!action.expressionError);
       }
       return appendToList(state, ["expressions"], {
         input: action.input,
         value: null,
@@ -23043,42 +23170,42 @@ exports.default = update;
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.getWorkers = exports.State = undefined;
+exports.getWorkers = exports.createDebuggeeState = undefined;
 exports.default = debuggee;
 exports.getWorker = getWorker;
 
 var _reselect = __webpack_require__(993);
 
 var _immutable = __webpack_require__(146);
 
 var _makeRecord = __webpack_require__(1361);
 
 var _makeRecord2 = _interopRequireDefault(_makeRecord);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-const State = exports.State = (0, _makeRecord2.default)({
+const createDebuggeeState = exports.createDebuggeeState = (0, _makeRecord2.default)({
   workers: (0, _immutable.List)()
 }); /* 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/>. */
 
 /**
  * Debuggee reducer
  * @module reducers/debuggee
  */
 
-function debuggee(state = State(), action) {
+function debuggee(state = createDebuggeeState(), action) {
   switch (action.type) {
     case "SET_WORKERS":
       return state.set("workers", (0, _immutable.List)(action.workers));
     default:
       return state;
   }
 }
 
@@ -23095,17 +23222,17 @@ function getWorker(state, url) {
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.initialState = initialState;
+exports.initialPendingBreakpointsState = initialPendingBreakpointsState;
 exports.getPendingBreakpoints = getPendingBreakpoints;
 exports.getPendingBreakpointsForSource = getPendingBreakpointsForSource;
 
 var _immutable = __webpack_require__(146);
 
 var I = _interopRequireWildcard(_immutable);
 
 var _makeRecord = __webpack_require__(1361);
@@ -23124,23 +23251,23 @@ function _interopRequireWildcard(obj) { 
  * 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/>. */
 
 /**
  * Pending breakpoints reducer
  * @module reducers/pending-breakpoints
  */
 
-function initialState() {
+function initialPendingBreakpointsState() {
   return (0, _makeRecord2.default)({
     pendingBreakpoints: restorePendingBreakpoints()
   })();
 }
 
-function update(state = initialState(), action) {
+function update(state = initialPendingBreakpointsState(), action) {
   switch (action.type) {
     case "ADD_BREAKPOINT":
       {
         if (action.breakpoint.hidden) {
           return state;
         }
         return addBreakpoint(state, action);
       }
@@ -23230,17 +23357,17 @@ function removeBreakpoint(state, action)
 // Selectors
 // TODO: these functions should be moved out of the reducer
 
 function getPendingBreakpoints(state) {
   return state.pendingBreakpoints.pendingBreakpoints;
 }
 
 function getPendingBreakpointsForSource(state, sourceUrl) {
-  const pendingBreakpoints = state.pendingBreakpoints.pendingBreakpoints || [];
+  const pendingBreakpoints = state.pendingBreakpoints.pendingBreakpoints || I.Map();
   return pendingBreakpoints.filter(pendingBreakpoint => pendingBreakpoint.location.sourceUrl === sourceUrl);
 }
 
 function restorePendingBreakpoints() {
   return I.Map(_prefs.prefs.pendingBreakpoints);
 }
 
 exports.default = update;
@@ -23260,38 +23387,38 @@ exports.getEventListeners = getEventList
  * 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/. */
 
 /**
  * Event listeners reducer
  * @module reducers/event-listeners
  */
 
-const initialState = {
+const initialEventListenersState = {
   activeEventNames: [],
   listeners: [],
   fetchingListeners: false
 };
 
-function update(state = initialState, action, emit) {
+function update(state = initialEventListenersState, action, emit) {
   switch (action.type) {
     case "UPDATE_EVENT_BREAKPOINTS":
       state.activeEventNames = action.eventNames;
       // emit("activeEventNames", state.activeEventNames);
       break;
     case "FETCH_EVENT_LISTENERS":
       if (action.status === "begin") {
         state.fetchingListeners = true;
       } else if (action.status === "done") {
         state.fetchingListeners = false;
         state.listeners = action.listeners;
       }
       break;
     case "NAVIGATE":
-      return initialState;
+      return initialEventListenersState;
   }
 
   return state;
 }
 
 function getEventListeners(state) {
   return state.eventListeners.listeners;
 }
@@ -23303,17 +23430,17 @@ exports.default = update;
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.State = undefined;
+exports.createUIState = undefined;
 exports.getSelectedPrimaryPaneTab = getSelectedPrimaryPaneTab;
 exports.getActiveSearch = getActiveSearch;
 exports.getContextMenu = getContextMenu;
 exports.getFrameworkGroupingState = getFrameworkGroupingState;
 exports.getShownSource = getShownSource;
 exports.getPaneCollapse = getPaneCollapse;
 exports.getHighlightedLineRange = getHighlightedLineRange;
 exports.getConditionalPanelLine = getConditionalPanelLine;
@@ -23332,31 +23459,31 @@ function _interopRequireDefault(obj) { r
  * 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/>. */
 
 /**
  * UI reducer
  * @module reducers/ui
  */
 
-const State = exports.State = (0, _makeRecord2.default)({
+const createUIState = exports.createUIState = (0, _makeRecord2.default)({
   selectedPrimaryPaneTab: "sources",
   activeSearch: null,
   contextMenu: {},
   shownSource: "",
   projectDirectoryRoot: "",
   startPanelCollapsed: _prefs.prefs.startPanelCollapsed,
   endPanelCollapsed: _prefs.prefs.endPanelCollapsed,
   frameworkGroupingOn: _prefs.prefs.frameworkGroupingOn,
   highlightedLineRange: undefined,
   conditionalPanelLine: null,
   orientation: "horizontal"
 });
 
-function update(state = State(), action) {
+function update(state = createUIState(), action) {
   switch (action.type) {
     case "TOGGLE_ACTIVE_SEARCH":
       {
         return state.set("activeSearch", action.value);
       }
 
     case "TOGGLE_FRAMEWORK_GROUPING":
       {
@@ -23485,17 +23612,17 @@ exports.default = update;
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.State = undefined;
+exports.createFileSearchState = undefined;
 exports.getFileSearchQuery = getFileSearchQuery;
 exports.getFileSearchModifiers = getFileSearchModifiers;
 exports.getFileSearchResults = getFileSearchResults;
 
 var _makeRecord = __webpack_require__(1361);
 
 var _makeRecord2 = _interopRequireDefault(_makeRecord);
 
@@ -23507,32 +23634,32 @@ function _interopRequireDefault(obj) { r
  * 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/>. */
 
 /**
  * File Search reducer
  * @module reducers/fileSearch
  */
 
-const State = exports.State = (0, _makeRecord2.default)({
+const createFileSearchState = exports.createFileSearchState = (0, _makeRecord2.default)({
   query: "",
   searchResults: {
     matches: [],
     matchIndex: -1,
     index: -1,
     count: 0
   },
   modifiers: (0, _makeRecord2.default)({
     caseSensitive: _prefs.prefs.fileSearchCaseSensitive,
     wholeWord: _prefs.prefs.fileSearchWholeWord,
     regexMatch: _prefs.prefs.fileSearchRegexMatch
   })()
 });
 
-function update(state = State(), action) {
+function update(state = createFileSearchState(), action) {
   switch (action.type) {
     case "UPDATE_FILE_SEARCH_QUERY":
       {
         return state.set("query", action.query);
       }
 
     case "UPDATE_SEARCH_RESULTS":
       {
@@ -23586,17 +23713,17 @@ exports.default = update;
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.State = undefined;
+exports.createCoverageState = undefined;
 exports.getHitCountForSource = getHitCountForSource;
 exports.getCoverageEnabled = getCoverageEnabled;
 
 var _makeRecord = __webpack_require__(1361);
 
 var _makeRecord2 = _interopRequireDefault(_makeRecord);
 
 var _immutable = __webpack_require__(146);
@@ -23606,29 +23733,29 @@ var I = _interopRequireWildcard(_immutab
 var _fromJS = __webpack_require__(1502);
 
 var _fromJS2 = _interopRequireDefault(_fromJS);
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-const State = exports.State = (0, _makeRecord2.default)({
+const createCoverageState = exports.createCoverageState = (0, _makeRecord2.default)({
   coverageOn: false,
   hitCount: I.Map()
 }); /* 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/>. */
 
 /**
  * Code coverage reducer
  * @module reducers/coverage
  */
 
-function update(state = State(), action) {
+function update(state = createCoverageState(), action) {
   switch (action.type) {
     case "RECORD_COVERAGE":
       return state.mergeIn(["hitCount"], (0, _fromJS2.default)(action.value.coverage)).setIn(["coverageOn"], true);
 
     default:
       {
         return state;
       }
@@ -23654,17 +23781,17 @@ exports.default = update;
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.statusType = undefined;
-exports.InitialState = InitialState;
+exports.initialProjectTextSearchState = initialProjectTextSearchState;
 exports.getTextSearchResults = getTextSearchResults;
 exports.getTextSearchStatus = getTextSearchStatus;
 exports.getTextSearchQuery = getTextSearchQuery;
 
 var _immutable = __webpack_require__(146);
 
 var I = _interopRequireWildcard(_immutable);
 
@@ -23689,25 +23816,25 @@ function _interopRequireWildcard(obj) { 
 
 const statusType = exports.statusType = {
   initial: "INITIAL",
   fetching: "FETCHING",
   done: "DONE",
   error: "ERROR"
 };
 
-function InitialState() {
+function initialProjectTextSearchState() {
   return (0, _makeRecord2.default)({
     query: "",
     results: I.List(),
     status: statusType.initial
   })();
 }
 
-function update(state = InitialState(), action) {
+function update(state = initialProjectTextSearchState(), action) {
   switch (action.type) {
     case "ADD_QUERY":
       const actionCopy = action;
       return state.update("query", value => actionCopy.query);
 
     case "CLEAR_QUERY":
       return state.merge({
         query: "",
@@ -23802,17 +23929,17 @@ function getExpandedState(state) {
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.default = getVisibleBreakpoints;
+exports.getVisibleBreakpoints = getVisibleBreakpoints;
 
 var _breakpoints = __webpack_require__(1378);
 
 var _sources = __webpack_require__(1369);
 
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 function getLocation(breakpoint, isGeneratedSource) {
@@ -24049,41 +24176,43 @@ var _createStore = __webpack_require__(1
 var _createStore2 = _interopRequireDefault(_createStore);
 
 var _reducers = __webpack_require__(1516);
 
 var _reducers2 = _interopRequireDefault(_reducers);
 
 var _selectors = __webpack_require__(1352);
 
-var _selectors2 = _interopRequireDefault(_selectors);
+var selectors = _interopRequireWildcard(_selectors);
 
 var _App = __webpack_require__(1518);
 
 var _App2 = _interopRequireDefault(_App);
 
 var _prefs = __webpack_require__(226);
 
+function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function bootstrapStore(client, { services, toolboxActions }) {
   const createStore = (0, _createStore2.default)({
     log: (0, _devtoolsConfig.isTesting)() || (0, _devtoolsConfig.getValue)("logging.actions"),
     timing: (0, _devtoolsConfig.isDevelopment)(),
     makeThunkArgs: (args, state) => {
       return _extends({}, args, { client }, services, toolboxActions);
     }
   });
 
   const store = createStore((0, _redux.combineReducers)(_reducers2.default));
   store.subscribe(() => updatePrefs(store.getState()));
 
   const actions = (0, _redux.bindActionCreators)(__webpack_require__(1354).default, store.dispatch);
 
-  return { store, actions, selectors: _selectors2.default };
+  return { store, actions, selectors };
 }
 
 function bootstrapApp(connection, { store, actions }) {
   window.appStore = store;
 
   // Expose the bound actions so external things can do things like
   // selecting a source.
   window.actions = {
@@ -24110,17 +24239,17 @@ function teardownWorkers() {
     (0, _devtoolsSourceMap.stopSourceMapWorker)();
   }
   (0, _prettyPrint.stopPrettyPrintWorker)();
   (0, _parser.stopParserWorker)();
   (0, _search.stopSearchWorker)();
 }
 
 function updatePrefs(state) {
-  const pendingBreakpoints = _selectors2.default.getPendingBreakpoints(state);
+  const pendingBreakpoints = selectors.getPendingBreakpoints(state);
 
   if (_prefs.prefs.pendingBreakpoints !== pendingBreakpoints) {
     _prefs.prefs.pendingBreakpoints = pendingBreakpoints;
   }
 }
 
 /***/ }),
 /* 1431 */
@@ -24419,19 +24548,27 @@ Object.defineProperty(exports, "__esModu
 exports.showLoading = exports.showErrorMessage = exports.showSourceText = exports.clearEditor = exports.updateDocument = exports.updateLineNumberFormat = exports.clearDocuments = exports.removeDocument = exports.hasDocument = exports.setDocument = exports.getDocument = undefined;
 
 var _source = __webpack_require__(1356);
 
 var _wasm = __webpack_require__(1401);
 
 var _ui = __webpack_require__(1439);
 
-let sourceDocs = {}; /* 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/>. */
+var _sourceEditor = __webpack_require__(197);
+
+var _sourceEditor2 = _interopRequireDefault(_sourceEditor);
+
+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/>. */
+
+let sourceDocs = {};
 
 function getDocument(key) {
   return sourceDocs[key];
 }
 
 function hasDocument(key) {
   return !!getDocument(key);
 }
@@ -24531,17 +24668,22 @@ function setEditorText(editor, source) {
 function showSourceText(editor, source, symbols) {
   if (!source) {
     return;
   }
 
   if (hasDocument(source.id)) {
     const doc = getDocument(source.id);
     if (editor.codeMirror.doc === doc) {
-      editor.setMode((0, _source.getMode)(source, symbols));
+      const mode = (0, _source.getMode)(source, symbols);
+
+      if (doc.mode.name !== mode.name) {
+        editor.setMode(mode);
+      }
+
       return;
     }
 
     editor.replaceDocument(doc);
     updateLineNumberFormat(editor, source.id);
     editor.setMode((0, _source.getMode)(source, symbols));
     return doc;
   }
@@ -26040,24 +26182,24 @@ class FrameComponent extends _react.Comp
       toggleFrameworkGrouping,
       toggleBlackBox,
       frameworkGroupingOn
     } = this.props;
     (0, _FrameMenu2.default)(frame, frameworkGroupingOn, { copyStackTrace, toggleFrameworkGrouping, toggleBlackBox }, event);
   }
 
   onMouseDown(e, frame, selectedFrame) {
-    if (e.nativeEvent.which == 3 || selectedFrame.id === frame.id) {
+    if (e.nativeEvent.which == 3) {
       return;
     }
     this.props.selectFrame(frame);
   }
 
   onKeyUp(event, frame, selectedFrame) {
-    if (event.key != "Enter" || selectedFrame.id == frame.id) {
+    if (event.key != "Enter") {
       return;
     }
     this.props.selectFrame(frame);
   }
 
   render() {
     const {
       frame,
@@ -29251,28 +29393,25 @@ async function onConnect(connection, { s
   const client = getClient(connection);
   const commands = client.clientCommands;
   const { store, actions, selectors } = (0, _bootstrap.bootstrapStore)(commands, {
     services,
     toolboxActions
   });
 
   (0, _bootstrap.bootstrapWorkers)();
-  const { bpClients } = await client.onConnect(connection, actions);
+  await client.onConnect(connection, actions);
   await loadFromPrefs(actions);
 
   if (!(0, _devtoolsConfig.isFirefoxPanel)()) {
     (0, _dbg.setupHelper)({
       store,
       actions,
       selectors,
-      client: client.clientCommands,
-      connection,
-      bpClients,
-      services
+      client: client.clientCommands
     });
   }
 
   (0, _bootstrap.bootstrapApp)(connection, { store, actions });
 
   return { store, actions, selectors, client: commands };
 }
 
@@ -29519,17 +29658,17 @@ function setBreakpointCondition(breakpoi
     return { id: breakpointId };
   });
 }
 
 function evaluateInFrame(frameId, script) {
   return evaluate(script, { frameId });
 }
 
-function evaluate(script, { frameId }) {
+function evaluate(script, { frameId } = {}) {
   const params = frameId ? { frameActor: frameId } : {};
   if (!tabTarget || !tabTarget.activeConsole) {
     return Promise.resolve();
   }
 
   return new Promise(resolve => {
     tabTarget.activeConsole.evaluateJS(script, result => resolve(result), params);
   });
@@ -29784,17 +29923,17 @@ module.exports = fromJS;
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.default = getBreakpointAtLocation;
+exports.getBreakpointAtLocation = getBreakpointAtLocation;
 
 var _sources = __webpack_require__(1369);
 
 var _breakpoints = __webpack_require__(1378);
 
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 function isGenerated(selectedSource) {
@@ -29861,17 +30000,17 @@ function getBreakpointAtLocation(state, 
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.default = isSelectedFrameVisible;
+exports.isSelectedFrameVisible = isSelectedFrameVisible;
 
 var _pause = __webpack_require__(1394);
 
 var _sources = __webpack_require__(1369);
 
 /*
  * Checks to if the selected frame's source is currently
  * selected.
@@ -30416,23 +30555,23 @@ Object.defineProperty(exports, "__esModu
  * 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/. */
 
 /**
  * Async request reducer
  * @module reducers/async-request
  */
 
-const initialState = [];
-
-function update(state = initialState, action) {
+const initialAsyncRequestState = [];
+
+function update(state = initialAsyncRequestState, action) {
   const { seqId } = action;
 
   if (action.type === "NAVIGATE") {
-    return initialState;
+    return initialAsyncRequestState;
   } else if (seqId) {
     let newState;
     if (action.status === "start") {
       newState = [...state, seqId];
     } else if (action.status === "error" || action.status === "done") {
       newState = state.filter(id => id !== seqId);
     }
 
@@ -30472,18 +30611,16 @@ var _prefs = __webpack_require__(226);
 var _actions = __webpack_require__(1354);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 var _ShortcutsModal = __webpack_require__(1535);
 
 var _selectors = __webpack_require__(1352);
 
-var _ui = __webpack_require__(1439);
-
 var _devtoolsModules = __webpack_require__(1376);
 
 __webpack_require__(1305);
 
 __webpack_require__(1306);
 
 __webpack_require__(1307);
 
@@ -30518,27 +30655,26 @@ var _Tabs = __webpack_require__(1614);
 var _Tabs2 = _interopRequireDefault(_Tabs);
 
 var _QuickOpenModal = __webpack_require__(1652);
 
 var _QuickOpenModal2 = _interopRequireDefault(_QuickOpenModal);
 
 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/>. */
-
-const shortcuts = new _devtoolsModules.KeyShortcuts({ window });
+const shortcuts = new _devtoolsModules.KeyShortcuts({ window }); /* This Source Code Form is subject to the terms of the Mozilla Public
+                                                                  * License, v. 2.0. If a copy of the MPL was not distributed with this
+                                                                  * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 const { appinfo } = _devtoolsModules.Services;
 
 const isMacOS = appinfo.OS === "Darwin";
 
-const verticalLayoutBreakpoint = window.matchMedia("(min-width: 800px)");
+const horizontalLayoutBreakpoint = window.matchMedia("(min-width: 800px)");
+const verticalLayoutBreakpoint = window.matchMedia("(min-width: 10px) and (max-width: 800px)");
 
 class App extends _react.Component {
 
   constructor(props) {
     super(props);
     this.state = {
       shortcutsModalEnabled: false,
       startPanelSize: 0,
@@ -30554,38 +30690,40 @@ class App extends _react.Component {
     this.onCommandSlash = this.onCommandSlash.bind(this);
   }
 
   getChildContext() {
     return { shortcuts };
   }
 
   componentDidMount() {
+    horizontalLayoutBreakpoint.addListener(this.onLayoutChange);
     verticalLayoutBreakpoint.addListener(this.onLayoutChange);
     this.setOrientation();
 
     shortcuts.on(L10N.getStr("symbolSearch.search.key2"), (_, e) => this.toggleQuickOpenModal(_, e, "@"));
 
     const searchKeys = [L10N.getStr("sources.search.key2"), L10N.getStr("sources.search.alt.key")];
     searchKeys.forEach(key => shortcuts.on(key, this.toggleQuickOpenModal));
 
-    shortcuts.on(L10N.getStr("gotoLineModal.key"), (_, e) => this.toggleQuickOpenModal(_, e, ":"));
+    shortcuts.on(L10N.getStr("gotoLineModal.key2"), (_, e) => this.toggleQuickOpenModal(_, e, ":"));
 
     shortcuts.on("Escape", this.onEscape);
     shortcuts.on("Cmd+/", this.onCommandSlash);
   }
 
   componentWillUnmount() {
+    horizontalLayoutBreakpoint.removeListener(this.onLayoutChange);
     verticalLayoutBreakpoint.removeListener(this.onLayoutChange);
     shortcuts.off(L10N.getStr("symbolSearch.search.key2"), this.toggleQuickOpenModal);
 
     const searchKeys = [L10N.getStr("sources.search.key2"), L10N.getStr("sources.search.alt.key")];
     searchKeys.forEach(key => shortcuts.off(key, this.toggleQuickOpenModal));
 
-    shortcuts.off(L10N.getStr("gotoLineModal.key"), this.toggleQuickOpenModal);
+    shortcuts.off(L10N.getStr("gotoLineModal.key2"), this.toggleQuickOpenModal);
 
     shortcuts.off("Escape", this.onEscape);
   }
 
   onEscape(_, e) {
     const {
       activeSearch,
       quickOpenEnabled,
@@ -30630,19 +30768,23 @@ class App extends _react.Component {
     return;
   }
 
   onLayoutChange() {
     this.setOrientation();
   }
 
   setOrientation() {
-    const orientation = verticalLayoutBreakpoint.matches ? "horizontal" : "vertical";
-    if ((0, _ui.isVisible)()) {
-      this.props.setOrientation(orientation);
+    // If the orientation does not match (if it is not visible) it will
+    // not setOrientation, or if it is the same as before, calling
+    // setOrientation will not cause a rerender.
+    if (horizontalLayoutBreakpoint.matches) {
+      this.props.setOrientation("horizontal");
+    } else if (verticalLayoutBreakpoint.matches) {
+      this.props.setOrientation("vertical");
     }
   }
 
   renderEditorPane() {
     const { startPanelCollapsed, endPanelCollapsed } = this.props;
     const { endPanelSize, startPanelSize } = this.state;
     const horizontal = this.isHorizontal();
 
@@ -31871,17 +32013,17 @@ class ShortcutsModal extends _react.Comp
   renderSearchShortcuts() {
     return _react2.default.createElement(
       "ul",
       { className: "shortcuts-list" },
       this.renderShorcutItem(L10N.getStr("shortcuts.fileSearch"), (0, _text.formatKeyShortcut)(L10N.getStr("sources.search.key2"))),
       this.renderShorcutItem(L10N.getStr("shortcuts.searchAgain"), (0, _text.formatKeyShortcut)(L10N.getStr("sourceSearch.search.again.key2"))),
       this.renderShorcutItem(L10N.getStr("shortcuts.projectSearch"), (0, _text.formatKeyShortcut)(L10N.getStr("projectTextSearch.key"))),
       this.renderShorcutItem(L10N.getStr("shortcuts.functionSearch"), (0, _text.formatKeyShortcut)(L10N.getStr("functionSearch.key"))),
-      this.renderShorcutItem(L10N.getStr("shortcuts.gotoLine"), (0, _text.formatKeyShortcut)(L10N.getStr("gotoLineModal.key")))
+      this.renderShorcutItem(L10N.getStr("shortcuts.gotoLine"), (0, _text.formatKeyShortcut)(L10N.getStr("gotoLineModal.key2")))
     );
   }
 
   renderShortcutsContent() {
     return _react2.default.createElement(
       "div",
       {
         className: (0, _classnames2.default)("shortcuts-content", this.props.additionalClass)
@@ -33721,25 +33863,40 @@ class Outline extends _react.Component {
 
   renderClassFunctions(klass, functions) {
     if (klass == null || functions.length == 0) {
       return null;
     }
 
     const classFunc = functions.find(func => func.name === klass);
     const classFunctions = functions.filter(func => func.klass === klass);
+    const classInfo = this.props.symbols.classes.find(c => c.name === klass);
+
+    const heading = classFunc ? _react2.default.createElement(
+      "h2",
+      null,
+      this.renderFunction(classFunc)
+    ) : _react2.default.createElement(
+      "h2",
+      {
+        onClick: classInfo ? () => this.selectItem(classInfo.location) : null
+      },
+      _react2.default.createElement(
+        "span",
+        { className: "keyword" },
+        "class"
+      ),
+      " ",
+      klass
+    );
 
     return _react2.default.createElement(
       "div",
       { className: "outline-list__class", key: klass },
-      _react2.default.createElement(
-        "h2",
-        null,
-        classFunc ? this.renderFunction(classFunc) : `class ${klass}`
-      ),
+      heading,
       _react2.default.createElement(
         "ul",
         { className: "outline-list__class-list" },
         classFunctions.map(func => this.renderFunction(func))
       )
     );
   }
 
@@ -34113,18 +34270,24 @@ var _initialiseProps = function () {
     const icon = this.getIcon(sources, item, depth);
 
     return _react2.default.createElement(
       "div",
       {
         className: (0, _classnames2.default)("node", { focused }),
         key: item.path,
         onClick: e => {
-          this.selectItem(item);
-          setExpanded(item, !expanded, e.altKey);
+          e.stopPropagation();
+          this.focusItem(item);
+
+          if ((0, _sourcesTree.isDirectory)(item)) {
+            setExpanded(item, !expanded, e.altKey);
+          } else {
+            this.selectItem(item);
+          }
         },
         onContextMenu: e => this.onContextMenu(e, item)
       },
       arrow,
       icon,
       _react2.default.createElement(
         "span",
         { className: "label" },
@@ -35298,16 +35461,20 @@ Object.defineProperty(exports, "__esModu
 var _react = __webpack_require__(0);
 
 var _lodash = __webpack_require__(2);
 
 var _reactRedux = __webpack_require__(1189);
 
 var _selectors = __webpack_require__(1352);
 
+/* 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 HighlightLines extends _react.Component {
 
   constructor() {
     super();
     this.highlightLineRange = this.highlightLineRange.bind(this);
   }
 
   componentDidMount() {
@@ -35361,19 +35528,17 @@ class HighlightLines extends _react.Comp
         codeMirror.addLineClass(line, "line", "highlight-lines");
       });
     });
   }
 
   render() {
     return null;
   }
-} /* 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/>. */
+}
 
 exports.default = (0, _reactRedux.connect)(state => ({
   highlightedLineRange: (0, _selectors.getHighlightedLineRange)(state)
 }))(HighlightLines);
 
 /***/ }),
 /* 1558 */
 /***/ (function(module, exports, __webpack_require__) {
@@ -38567,26 +38732,26 @@ var _react = __webpack_require__(0);
 var _react2 = _interopRequireDefault(_react);
 
 var _Breakpoint = __webpack_require__(1589);
 
 var _Breakpoint2 = _interopRequireDefault(_Breakpoint);
 
 var _selectors = __webpack_require__(1352);
 
-var _visibleBreakpoints = __webpack_require__(1427);
-
-var _visibleBreakpoints2 = _interopRequireDefault(_visibleBreakpoints);
-
 var _breakpoint = __webpack_require__(1364);
 
 var _source = __webpack_require__(1356);
 
 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 Breakpoints extends _react.Component {
   shouldComponentUpdate(nextProps) {
     if (nextProps.selectedSource && !(0, _source.isLoaded)(nextProps.selectedSource)) {
       return false;
     }
 
     return true;
   }
@@ -38606,22 +38771,20 @@ class Breakpoints extends _react.Compone
           key: (0, _breakpoint.makeLocationId)(bp.location),
           breakpoint: bp,
           selectedSource: selectedSource,
           editor: editor
         });
       })
     );
   }
-} /* 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/>. */
+}
 
 exports.default = (0, _reactRedux.connect)(state => ({
-  breakpoints: (0, _visibleBreakpoints2.default)(state),
+  breakpoints: (0, _selectors.getVisibleBreakpoints)(state),
   selectedSource: (0, _selectors.getSelectedSource)(state)
 }))(Breakpoints);
 
 /***/ }),
 /* 1589 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -38840,16 +39003,18 @@ var _lodash = __webpack_require__(2);
 var _CallSite = __webpack_require__(1592);
 
 var _CallSite2 = _interopRequireDefault(_CallSite);
 
 var _selectors = __webpack_require__(1352);
 
 var _editor = __webpack_require__(1358);
 
+var _wasm = __webpack_require__(1401);
+
 var _actions = __webpack_require__(1354);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function getCallSiteAtLocation(callSites, location) {
   return callSites.find(callSite => (0, _lodash.isEqualWith)(callSite.location, location, (cloc, loc) => {
@@ -38907,17 +39072,17 @@ class CallSites extends _react.Component
 
     if (!e.altKey && !target.classList.contains("call-site-bp") || !target.classList.contains("call-site") && !target.classList.contains("call-site-bp")) {
       return;
     }
 
     const { sourceId } = selectedLocation;
     const { line, column } = (0, _editor.getTokenLocation)(editor.codeMirror, target);
 
-    this.toggleBreakpoint(line, (0, _editor.isWasm)(sourceId) ? undefined : column);
+    this.toggleBreakpoint(line, (0, _wasm.isWasm)(sourceId) ? undefined : column);
   }
 
   toggleBreakpoint(line, column = undefined) {
     const {
       selectedSource,
       selectedLocation,
       addBreakpoint,
       removeBreakpoint,
@@ -41272,17 +41437,18 @@ class EventListeners extends _react.Comp
   }
 }
 
 exports.default = (0, _reactRedux.connect)(state => {
   const listeners = (0, _selectors.getEventListeners)(state).map(l => {
     return _extends({}, l, {
       breakpoint: (0, _selectors.getBreakpoint)(state, {
         sourceId: l.sourceId,
-        line: l.line
+        line: l.line,
+        column: null
       })
     });
   });
 
   return { listeners };
 }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(EventListeners);
 
 /***/ }),
@@ -41986,17 +42152,19 @@ class Scopes extends _react.Component {
         renderItem: this.renderItem
       })
     );
   }
 }
 
 exports.default = (0, _reactRedux.connect)(state => ({
   isPaused: (0, _selectors.isPaused)(state),
-  loadedObjects: (0, _selectors.getLoadedObjects)(state),
+  loadedObjects: () => {
+    throw new Error("This is not implemented.");
+  },
   scopes: (0, _selectors.getChromeScopes)(state)
 }), dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Scopes);
 
 /***/ }),
 /* 1611 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -42096,17 +42264,17 @@ class Scopes extends _react.PureComponen
 } /* 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/>. */
 
 exports.default = (0, _reactRedux.connect)(state => {
   const selectedFrame = (0, _selectors.getSelectedFrame)(state);
   const selectedSource = (0, _selectors.getSelectedSource)(state);
 
-  const { scope: frameScopes, pending } = (0, _selectors.getFrameScope)(state, selectedSource && selectedSource.get("id"), selectedFrame.id) || { pending: false };
+  const { scope: frameScopes, pending } = (0, _selectors.getFrameScope)(state, selectedSource && selectedSource.get("id"), selectedFrame.id) || { scope: null, pending: false };
 
   return {
     selectedFrame,
     isPaused: (0, _selectors.isPaused)(state),
     isLoading: pending,
     why: (0, _selectors.getPauseReason)(state),
     frameScopes: frameScopes
   };
@@ -42176,74 +42344,50 @@ class WelcomeBox extends _react.Componen
     const searchProjectLabel = L10N.getStr("welcome.findInFiles").substring(2);
     const { setActiveSearch, openQuickOpen } = this.props;
 
     return _react2.default.createElement(
       "div",
       { className: "welcomebox" },
       _react2.default.createElement(
         "div",
-        { className: "alignlabel small-size-layout" },
+        { className: "alignlabel" },
         _react2.default.createElement(
           "div",
           { className: "shortcutFunction" },
           _react2.default.createElement(
             "p",
             { onClick: () => openQuickOpen() },
             _react2.default.createElement(
               "span",
               { className: "shortcutKey" },
               searchSourcesShortcut
             ),
-            searchSourcesLabel
+            _react2.default.createElement(
+              "span",
+              { className: "shortcutLabel" },
+              searchSourcesLabel
+            )
           ),
           _react2.default.createElement(
             "p",
             { onClick: setActiveSearch.bind(null, "project") },
             _react2.default.createElement(
               "span",
               { className: "shortcutKey" },
               searchProjectShortcut
             ),
-            searchProjectLabel
+            _react2.default.createElement(
+              "span",
+              { className: "shortcutLabel" },
+              searchProjectLabel
+            )
           )
         ),
         this.renderToggleButton()
-      ),
-      _react2.default.createElement(
-        "div",
-        { className: "alignlabel normal-layout" },
-        _react2.default.createElement(
-          "div",
-          { className: "shortcutKeys" },
-          _react2.default.createElement(
-            "p",
-            { onClick: () => openQuickOpen() },
-            searchSourcesShortcut
-          ),
-          _react2.default.createElement(
-            "p",
-            { onClick: setActiveSearch.bind(null, "project") },
-            searchProjectShortcut
-          )
-        ),
-        _react2.default.createElement(
-          "div",
-          { className: "shortcutFunction" },
-          _react2.default.createElement(
-            "p",
-            { onClick: () => openQuickOpen() },
-            searchSourcesLabel
-          ),
-          _react2.default.createElement(
-            "p",
-            { onClick: setActiveSearch.bind(null, "project") },
-            searchProjectLabel
-          )
-        )
       )
     );
   }
 }
 
 exports.default = (0, _reactRedux.connect)(state => ({
   endPanelCollapsed: (0, _selectors.getPaneCollapse)(state, "end")
 }), dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(WelcomeBox);
@@ -42724,17 +42868,30 @@ async function findGeneratedBinding(sour
     // Since the map takes the closest location, sometimes mapping a
     // binding's location can point at the start of a binding listed after
     // it, so we need to make sure it maps to a location that actually has
     // a size in order to avoid picking up the wrong descriptor.
     if (gen.line === genEnd.line && gen.column === genEnd.column) {
       return null;
     }
 
-    return generatedAstBindings.find(val => val.loc.start.line === gen.line && val.loc.start.column === gen.column);
+    return generatedAstBindings.find(val => {
+      if (val.loc.start.line !== gen.line) {
+        return false;
+      }
+
+      // Allow the mapping to point anywhere within the generated binding
+      // location to allow for less than perfect sourcemaps. Since you also
+      // need at least one character between identifiers, we also give one
+      // characters of space at the front the generated binding in order
+      // to increase the probability of finding the right mapping.
+      const start = val.loc.start.column - 1;
+      const end = val.loc.end.column;
+      return gen.column >= start && gen.column <= end;
+    });
   }, null);
 
   if (genContent && genContent.desc) {
     return genContent.desc;
   } else if (genContent) {
     // If there is no descriptor for 'this', then this is not the top-level
     // 'this' that the server gave us a binding for, and we can just ignore it.
     if (name === "this") {
@@ -42848,17 +43005,17 @@ function buildGeneratedBindingList(scope
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.State = undefined;
+exports.createQuickOpenState = undefined;
 exports.default = update;
 exports.getQuickOpenEnabled = getQuickOpenEnabled;
 exports.getQuickOpenQuery = getQuickOpenQuery;
 exports.getQuickOpenType = getQuickOpenType;
 
 var _makeRecord = __webpack_require__(1361);
 
 var _makeRecord2 = _interopRequireDefault(_makeRecord);
@@ -42871,35 +43028,35 @@ function _interopRequireDefault(obj) { r
  * 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/. */
 
 /**
  * Quick Open reducer
  * @module reducers/quick-open
  */
 
-const State = exports.State = (0, _makeRecord2.default)({
+const createQuickOpenState = exports.createQuickOpenState = (0, _makeRecord2.default)({
   enabled: false,
   query: "",
   searchType: "sources"
 });
 
-function update(state = State(), action) {
+function update(state = createQuickOpenState(), action) {
   switch (action.type) {
     case "OPEN_QUICK_OPEN":
       if (action.query != null) {
         return state.merge({
           enabled: true,
           query: action.query,
           searchType: (0, _quickOpen.parseQuickOpenQuery)(action.query)
         });
       }
       return state.set("enabled", true);
     case "CLOSE_QUICK_OPEN":
-      return State();
+      return createQuickOpenState();
     case "SET_QUICK_OPEN_QUERY":
       return state.merge({
         query: action.query,
         searchType: (0, _quickOpen.parseQuickOpenQuery)(action.query)
       });
     default:
       return state;
   }
@@ -43192,32 +43349,47 @@ function reverseStepOver() {
 function reverseStepOut() {
   return ({ dispatch, getState }) => {
     if ((0, _selectors.isPaused)(getState())) {
       return dispatch(command("reverseStepOut"));
     }
   };
 }
 
+/*
+ * Checks for await or yield calls on the paused line
+ * This avoids potentially expensive parser calls when we are likely
+ * not at an async expression.
+ */
+function hasAwait(source, pauseLocation) {
+  const { line, column } = pauseLocation;
+  if (!source.text) {
+    return false;
+  }
+
+  return source.text.split("\n")[line - 1].slice(column, column + 200).match(/(yield|await)/);
+}
+
 /**
  * @memberOf actions/pause
  * @static
  * @param stepType
  * @returns {function(ThunkArgs)}
  */
 function astCommand(stepType) {
   return async ({ dispatch, getState, sourceMaps }) => {
     if (!_prefs.features.asyncStepping) {
       return dispatch(command(stepType));
     }
 
     if (stepType == "stepOver") {
+      // This type definition is ambiguous:
       const frame = (0, _selectors.getTopFrame)(getState());
       const source = (0, _selectors.getSelectedSource)(getState()).toJS();
-      if (source) {
+      if (source && hasAwait(source, frame.location)) {
         const nextLocation = await (0, _parser.getNextStep)(source.id, frame.location);
         if (nextLocation) {
           await dispatch((0, _breakpoints.addHiddenBreakpoint)(nextLocation));
           return dispatch(command("resume"));
         }
       }
     }
 
@@ -44385,17 +44557,16 @@ exports.waitUntilService = waitUntilServ
  *     // Do anything here. You only need to accept the arguments
  *     // if you need them. `action` is the action that satisfied
  *     // the predicate.
  *   }
  * }
  * ```
  */
 const NAME = exports.NAME = "@@service/waitUntil";
-
 function waitUntilService({ dispatch, getState }) {
   let pending = [];
 
   function checkPending(action) {
     const readyRequests = [];
     const stillPending = [];
 
     // Find the pending requests whose predicates are satisfied with
@@ -47169,34 +47340,36 @@ function isMinified(source) {
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
+exports.getCallStackFrames = undefined;
 
 var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /* 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/>. */
 
 exports.formatCallStackFrames = formatCallStackFrames;
-exports.default = getCallStackFrames;
 
 var _sources = __webpack_require__(1369);
 
 var _pause = __webpack_require__(1394);
 
 var _frame = __webpack_require__(1380);
 
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 var _lodash = __webpack_require__(2);
 
+var _reselect = __webpack_require__(993);
+
 function getLocation(frame, isGeneratedSource) {
   return isGeneratedSource ? frame.generatedLocation || frame.location : frame.location;
 }
 
 function getSourceForFrame(sources, frame, isGeneratedSource) {
   const sourceId = getLocation(frame, isGeneratedSource).sourceId;
   return (0, _sources.getSourceInSources)(sources, sourceId);
 }
@@ -47212,34 +47385,29 @@ function appendSource(sources, frame, se
 function formatCallStackFrames(frames, sources, selectedSource) {
   if (!frames) {
     return null;
   }
 
   return frames.filter(frame => getSourceForFrame(sources, frame)).map(frame => appendSource(sources, frame, selectedSource)).filter(frame => !(0, _lodash.get)(frame, "source.isBlackBoxed")).map(_frame.annotateFrame);
 }
 
-function getCallStackFrames(state) {
-  const selectedSource = (0, _sources.getSelectedSource)(state);
-  const sources = (0, _sources.getSources)(state);
-  const frames = (0, _pause.getFrames)(state);
-
-  return formatCallStackFrames(frames, sources, selectedSource);
-}
+const getCallStackFrames = exports.getCallStackFrames = (0, _reselect.createSelector)(_sources.getSelectedSource, _sources.getSources, _pause.getFrames, (selectedSource, sources, frames) => formatCallStackFrames(frames, sources, selectedSource));
 
 /***/ }),
 /* 1780 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
+exports.getVisibleSelectedFrame = undefined;
 
 var _sources = __webpack_require__(1369);
 
 var _pause = __webpack_require__(1394);
 
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 var _reselect = __webpack_require__(993);
@@ -47251,31 +47419,29 @@ var _reselect = __webpack_require__(993)
 function getLocation(frame, location) {
   if (!location) {
     return frame.location;
   }
 
   return !(0, _devtoolsSourceMap.isOriginalId)(location.sourceId) ? frame.generatedLocation || frame.location : frame.location;
 }
 
-const getVisibleSelectedFrame = (0, _reselect.createSelector)(_sources.getSelectedLocation, _pause.getSelectedFrame, (selectedLocation, selectedFrame) => {
+const getVisibleSelectedFrame = exports.getVisibleSelectedFrame = (0, _reselect.createSelector)(_sources.getSelectedLocation, _pause.getSelectedFrame, (selectedLocation, selectedFrame) => {
   if (!selectedFrame) {
     return null;
   }
 
   const { id } = selectedFrame;
 
   return {
     id,
     location: getLocation(selectedFrame, selectedLocation)
   };
 });
 
-exports.default = getVisibleSelectedFrame;
-
 /***/ }),
 /* 1781 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
@@ -47284,27 +47450,25 @@ Object.defineProperty(exports, "__esModu
 exports.setInScopeLines = setInScopeLines;
 
 var _selectors = __webpack_require__(1352);
 
 var _source = __webpack_require__(1356);
 
 var _lodash = __webpack_require__(2);
 
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
-
 function getOutOfScopeLines(outOfScopeLocations) {
   if (!outOfScopeLocations) {
     return null;
   }
 
   return (0, _lodash.uniq)((0, _lodash.flatMap)(outOfScopeLocations, location => (0, _lodash.range)(location.start.line, location.end.line)));
-}
+} /* 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 setInScopeLines() {
   return ({ dispatch, getState }) => {
     const source = (0, _selectors.getSelectedSource)(getState());
     const outOfScopeLocations = (0, _selectors.getOutOfScopeLocations)(getState());
 
     if (!source || !source.get("text")) {
       return;
@@ -49907,20 +50071,17 @@ function getHiddenTabs(sourceTabs, sourc
   }
 
   return sourceTabs.filter((tab, index) => {
     const element = sourceTabEls[index];
     return element && hasTopOffset(element);
   });
 }
 
-function getSourceAnnotation(source, getMetaData) {
-  const sourceId = source.get("id");
-  const sourceMetaData = getMetaData(sourceId);
-
+function getSourceAnnotation(source, sourceMetaData) {
   const framework = sourceMetaData && sourceMetaData.framework ? sourceMetaData.framework : false;
 
   if (framework) {
     return _react2.default.createElement("img", { className: framework.toLowerCase() });
   }
 
   if ((0, _source.isPretty)(source)) {
     return _react2.default.createElement("img", { className: "prettyPrint" });
@@ -50658,17 +50819,17 @@ class Tab extends _react.PureComponent {
       hidden: () => tabSources.size === 1
     }, {
       item: _extends({}, tabMenuItems.closeTabsToEnd, {
         click: () => {
           const tabIndex = tabSources.findIndex(t => t.get("id") == tab);
           closeTabs(tabURLs.filter((t, i) => i > tabIndex));
         }
       }),
-      hidden: () => tabSources.some((t, i) => t === tab && tabSources.size - 1 === i)
+      hidden: () => tabSources.size === 1 || tabSources.some((t, i) => t === tab && tabSources.size - 1 === i)
     }, {
       item: _extends({}, tabMenuItems.closeAllTabs, { click: () => closeTabs(tabURLs) })
     }, { item: { type: "separator" } }, {
       item: _extends({}, tabMenuItems.copySourceUri2, {
         click: () => (0, _clipboard.copyToTheClipboard)(sourceTab.get("url"))
       })
     }];
 
@@ -50696,24 +50857,24 @@ class Tab extends _react.PureComponent {
   }
 
   render() {
     const {
       selectedSource,
       selectSource,
       closeTab,
       source,
-      getMetaData
+      sourceMetaData
     } = this.props;
     const src = source.toJS();
     const filename = (0, _source.getFilename)(src);
     const sourceId = source.get("id");
     const active = selectedSource && sourceId == selectedSource.get("id") && !this.isProjectSearchEnabled() && !this.isSourceSearchEnabled();
     const isPrettyCode = (0, _source.isPretty)(source);
-    const sourceAnnotation = (0, _tabs.getSourceAnnotation)(source, getMetaData);
+    const sourceAnnotation = (0, _tabs.getSourceAnnotation)(source, sourceMetaData);
 
     function onClickClose(ev) {
       ev.stopPropagation();
       closeTab(source.get("url"));
     }
 
     const className = (0, _classnames2.default)("source-tab", {
       active,
@@ -50737,22 +50898,22 @@ class Tab extends _react.PureComponent {
       ),
       _react2.default.createElement(_Close2.default, {
         handleClick: onClickClose,
         tooltip: L10N.getStr("sourceTabs.closeTabButtonTooltip")
       })
     );
   }
 }
-
 exports.default = (0, _reactRedux.connect)(state => {
+  const selectedSource = (0, _selectors.getSelectedSource)(state);
   return {
     tabSources: (0, _selectors.getSourcesForTabs)(state),
-    selectedSource: (0, _selectors.getSelectedSource)(state),
-    getMetaData: sourceId => (0, _selectors.getSourceMetaData)(state, sourceId),
+    selectedSource: selectedSource,
+    sourceMetaData: (0, _selectors.getSourceMetaData)(state, selectedSource && selectedSource.get("id")),
     activeSearch: (0, _selectors.getActiveSearch)(state)
   };
 }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Tab);
 
 /***/ }),
 /* 2019 */,
 /* 2020 */,
 /* 2021 */,
@@ -51075,37 +51236,69 @@ var _redux = __webpack_require__(3);
 var _timings = __webpack_require__(1657);
 
 var timings = _interopRequireWildcard(_timings);
 
 var _prefs = __webpack_require__(226);
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
-function setupHelper(obj) {
-  const selectors = Object.keys(obj.selectors).reduce((bound, selector) => {
+function findSource(dbg, url) {
+  const sources = dbg.selectors.getSources();
+  const source = sources.find(s => (s.get("url") || "").includes(url));
+
+  if (!source) {
+    return;
+  }
+
+  return source.toJS();
+}
+
+function sendPacket(dbg, packet, callback) {
+  dbg.connection.tabConnection.debuggerClient.request(packet).then(callback || console.log);
+}
+
+function evaluate(dbg, expression, callback) {
+  dbg.client.evaluate(expression).then(callback || console.log);
+}
+
+function bindSelectors(obj) {
+  return Object.keys(obj.selectors).reduce((bound, selector) => {
     bound[selector] = (a, b, c) => obj.selectors[selector](obj.store.getState(), a, b, c);
     return bound;
   }, {});
-
-  const sendPacket = (packet, cbk) => obj.connection.tabConnection.debuggerClient.request(packet).then(cbk || console.log);
-
+}
+
+function getCM() {
+  const cm = document.querySelector(".CodeMirror");
+  return cm && cm.CodeMirror;
+}
+
+function setupHelper(obj) {
+  const selectors = bindSelectors(obj);
   const actions = (0, _redux.bindActionCreators)(obj.actions, obj.store.dispatch);
-  window.dbg = _extends({}, obj, {
+  const dbg = _extends({}, obj, {
     selectors,
     actions,
     prefs: _prefs.prefs,
     features: _prefs.features,
     timings,
-    sendPacket
-  });
+    getCM,
+    helpers: {
+      findSource: url => findSource(dbg, url),
+      evaluate: (expression, cbk) => evaluate(dbg, expression, cbk),
+      sendPacket: (packet, cbk) => sendPacket(dbg, packet, cbk)
+    }
+  });
+
+  window.dbg = dbg;
 
   console.group("Development Notes");
   const baseUrl = "https://devtools-html.github.io/debugger.html";
-  const localDevelopmentUrl = `${baseUrl}/docs/local-development.html`;
+  const localDevelopmentUrl = `${baseUrl}/docs/dbg.html`;
   console.log("Debugging Tips", localDevelopmentUrl);
   console.log("dbg", window.dbg);
   console.groupEnd();
 }
 
 /***/ }),
 /* 2247 */
 /***/ (function(module, exports) {
--- a/devtools/client/debugger/new/parser-worker.js
+++ b/devtools/client/debugger/new/parser-worker.js
@@ -35276,16 +35276,22 @@ module.exports = {"builtin":{"Array":fal
 /* 2252 */,
 /* 2253 */,
 /* 2254 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.createParseJSScopeVisitor = createParseJSScopeVisitor;
+exports.findScopes = findScopes;
+
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 var _getFunctionName = __webpack_require__(1621);
 
 var _getFunctionName2 = _interopRequireDefault(_getFunctionName);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
@@ -35371,18 +35377,20 @@ function parseDeclarator(declaratorId, t
     parseDeclarator(declaratorId.argument, targetScope, type);
   }
 }
 
 function isLetOrConst(node) {
   return node.kind === "let" || node.kind === "const";
 }
 
-function hasLetOrConst(path) {
-  return path.node.body.some(node => isLexicalVariable(node));
+function hasLexicalDeclaration(path) {
+  const isFunctionBody = path.parentPath.isFunction({ body: path.node });
+
+  return path.node.body.some(node => isLexicalVariable(node) || !isFunctionBody && node.type === "FunctionDeclaration" || node.type === "ClassDeclaration");
 }
 function isLexicalVariable(node) {
   return isNode(node, "VariableDeclaration") && isLetOrConst(node);
 }
 
 function findIdentifierInScopes(scope, name) {
   // Find nearest outer scope with the specifed name and add reference.
   for (let s = scope; s; s = s.parent) {
@@ -35493,32 +35501,34 @@ function createParseJSScopeVisitor(sourc
           parent = createTempScope("block", "Function Expression", parent, location);
           parent.names[tree.id.name] = {
             type: "const",
             declarations: [tree.id.loc],
             refs: []
           };
         }
 
+        if (path.isFunctionDeclaration() && isNode(tree.id, "Identifier")) {
+          // This ignores Annex B function declaration hoisting, which
+          // is probably a fine assumption.
+          const fnScope = getVarScope(parent);
+          parent.names[tree.id.name] = {
+            type: fnScope === parent ? "var" : "let",
+            declarations: [tree.id.loc],
+            refs: []
+          };
+        }
+
         const scope = createTempScope("function", (0, _getFunctionName2.default)(path), parent, {
           // Being at the start of a function doesn't count as
           // being inside of it.
           start: tree.params[0] ? tree.params[0].loc.start : location.start,
           end: location.end
         });
-        if (path.isFunctionDeclaration() && isNode(tree.id, "Identifier")) {
-          // This ignores Annex B function declaration hoisting, which
-          // is probably a fine assumption.
-          const fnScope = getVarScope(parent);
-          scope.names[tree.id.name] = {
-            type: fnScope === scope ? "var" : "let",
-            declarations: [tree.id.loc],
-            refs: []
-          };
-        }
+
         tree.params.forEach(param => parseDeclarator(param, scope, "var"));
 
         if (!path.isArrowFunctionExpression()) {
           scope.names.this = {
             type: "implicit",
             declarations: [],
             refs: []
           };
@@ -35555,39 +35565,39 @@ function createParseJSScopeVisitor(sourc
       if (path.isForXStatement() || path.isForStatement()) {
         const init = tree.init || tree.left;
         if (isNode(init, "VariableDeclaration") && isLetOrConst(init)) {
           // Debugger will create new lexical environment for the for.
           savedParents.set(path, parent);
           parent = createTempScope("block", "For", parent, {
             // Being at the start of a for loop doesn't count as
             // being inside it.
-            start: init.start,
+            start: init.loc.start,
             end: location.end
           });
         }
         return;
       }
       if (path.isCatchClause()) {
         savedParents.set(path, parent);
         parent = createTempScope("block", "Catch", parent, location);
         parseDeclarator(tree.param, parent, "var");
         return;
       }
       if (path.isBlockStatement()) {
-        if (hasLetOrConst(path)) {
+        if (hasLexicalDeclaration(path)) {
           // Debugger will create new lexical environment for the block.
           savedParents.set(path, parent);
           parent = createTempScope("block", "Block", parent, location);
         }
         return;
       }
       if (path.isVariableDeclaration() && (path.node.kind === "var" ||
       // Lexical declarations in for statements are handled above.
-      !path.parentPath.isForStatement({ init: tree }) || !path.parentPath.isXStatement({ left: tree }))) {
+      !path.parentPath.isForStatement({ init: tree }) || !path.parentPath.isForXStatement({ left: tree }))) {
         // Finds right lexical environment
         const hoistAt = !isLetOrConst(tree) ? getVarScope(parent) : parent;
         tree.declarations.forEach(declarator => {
           parseDeclarator(declarator.id, hoistAt, tree.kind);
         });
         return;
       }
       if (path.isImportDeclaration()) {
@@ -35618,17 +35628,17 @@ function createParseJSScopeVisitor(sourc
         const scope = findIdentifierInScopes(parent, "this");
         if (scope) {
           scope.names.this.refs.push(tree.loc);
         }
       }
 
       if (path.parentPath.isClassProperty({ value: tree })) {
         savedParents.set(path, parent);
-        parent = createTempScope("block", "Class Field", parent, location);
+        parent = createTempScope("function", "Class Field", parent, location);
         parent.names.this = {
           type: "implicit",
           declarations: [],
           refs: []
         };
         parent.names.arguments = {
           type: "implicit",
           declarations: [],
@@ -35725,16 +35735,11 @@ function findScopes(scopes, location) {
       displayName: i.displayName,
       start: i.start,
       end: i.end,
       bindings: i.bindings
     };
   });
 }
 
-module.exports = {
-  createParseJSScopeVisitor,
-  findScopes
-};
-
 /***/ })
 /******/ ]);
 });
\ No newline at end of file
--- a/devtools/client/debugger/new/test/mochitest/browser.ini
+++ b/devtools/client/debugger/new/test/mochitest/browser.ini
@@ -1,16 +1,18 @@
 [DEFAULT]
 tags = devtools
 subsuite = devtools
 skip-if = (os == 'linux' && debug && bits == 32)
 support-files =
   head.js
   !/devtools/client/commandline/test/helpers.js
   !/devtools/client/framework/test/shared-head.js
+  examples/babel/fixtures/for-of/output.js
+  examples/babel/fixtures/for-of/output.js.map
   examples/sourcemaps/bundle.js
   examples/sourcemaps/bundle.js.map
   examples/sourcemaps2/main.min.js
   examples/sourcemaps2/main.js
   examples/sourcemaps2/main.js.map
   examples/sourcemaps3/bundle.js
   examples/sourcemaps3/bundle.js.map
   examples/sourcemaps3/sorted.js
@@ -32,16 +34,17 @@ support-files =
   examples/sum/sum.min.js
   examples/sum/sum.min.js.map
   examples/reload/code_reload_1.js
   examples/reload/code_reload_2.js
   examples/reload/doc-reload.html
   examples/reload/sjs_code_reload.sjs
   examples/doc-async.html
   examples/doc-asm.html
+  examples/doc-babel.html
   examples/doc-content-script-sources.html
   examples/doc-scripts.html
   examples/doc-script-mutate.html
   examples/doc-script-switching.html
   examples/doc-exceptions.html
   examples/doc-iframes.html
   examples/doc-frames.html
   examples/doc-debugger-statements.html
@@ -70,16 +73,17 @@ support-files =
   examples/frames.js
   examples/script-mutate.js
   examples/script-switching-02.js
   examples/script-switching-01.js
   examples/times2.js
 
 [browser_dbg-asm.js]
 [browser_dbg-async-stepping.js]
+[browser_dbg-babel-for-of.js]
 [browser_dbg-breaking.js]
 [browser_dbg-breaking-from-console.js]
 [browser_dbg-breakpoints.js]
 [browser_dbg-breakpoints-toggle.js]
 [browser_dbg-breakpoints-reloading.js]
 [browser_dbg-breakpoints-cond.js]
 [browser_dbg-browser-content-toolbox.js]
 skip-if = !e10s # This test is only valid in e10s
@@ -103,17 +107,16 @@ skip-if = true # regular failures during
 skip-if = os == "linux" # bug 1351952
 [browser_dbg-layout-changes.js]
 [browser_dbg-outline.js]
 [browser_dbg-pause-exceptions.js]
 [browser_dbg-pause-ux.js]
 skip-if = os == "win"
 [browser_dbg-navigation.js]
 [browser_dbg-minified.js]
-skip-if = true
 [browser_dbg-pretty-print.js]
 [browser_dbg-pretty-print-console.js]
 [browser_dbg-pretty-print-paused.js]
 [browser_dbg-preview.js]
 skip-if = os == "win"
 [browser_dbg-preview-source-maps.js]
 skip-if = os == "win"
 [browser_dbg-returnvalues.js]
@@ -123,17 +126,16 @@ skip-if = os == "win" # Bug 1393121
 [browser_dbg-quick-open.js]
 skip-if = true # regular failures during release in Bug 1415300
 [browser_dbg-search-project.js]
 [browser_dbg-sourcemaps.js]
 [browser_dbg-sourcemaps-reload.js]
 [browser_dbg-sourcemaps-reloading.js]
 [browser_dbg-sourcemaps2.js]
 [browser_dbg-sourcemaps3.js]
-skip-if = true
 [browser_dbg-sourcemaps-bogus.js]
 [browser_dbg-sources.js]
 [browser_dbg-sources-named-eval.js]
 [browser_dbg-tabs.js]
 [browser_dbg-tabs-pretty-print.js]
 [browser_dbg-toggling-tools.js]
 skip-if = true # Bug 1414124
 [browser_dbg-wasm-sourcemaps.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-babel-for-of.js
@@ -0,0 +1,49 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Tests loading sourcemapped sources for Babel's compile for..of output.
+
+add_task(async function() {
+  await pushPref("devtools.debugger.features.map-scopes", true);
+
+  const dbg = await initDebugger("doc-babel.html");
+  const { selectors: { getBreakpoint, getBreakpoints }, getState } = dbg;
+
+  await waitForSources(dbg, "fixtures/for-of/input.js");
+
+  ok(true, "Original sources exist");
+  const sortedSrc = findSource(dbg, "fixtures/for-of/input.js");
+
+  await selectSource(dbg, sortedSrc);
+
+  // Test that breakpoint is not off by a line.
+  await addBreakpoint(dbg, sortedSrc, 5);
+  is(getBreakpoints(getState()).size, 1, "One breakpoint exists");
+  ok(
+    getBreakpoint(getState(), { sourceId: sortedSrc.id, line: 5, column: 4 }),
+    "Breakpoint has correct line"
+  );
+
+  invokeInTab("forOf");
+
+  await waitForPaused(dbg);
+
+  assertPausedLocation(dbg);
+
+  is(getScopeLabel(dbg, 1), "For");
+  is(getScopeLabel(dbg, 2), "x");
+  is(getScopeValue(dbg, 2), "1");
+
+  is(getScopeLabel(dbg, 3), "forOf");
+
+  await toggleScopeNode(dbg, 3);
+
+  is(getScopeLabel(dbg, 4), "doThing()");
+
+  is(getScopeLabel(dbg, 5), "Module");
+
+  await toggleScopeNode(dbg, 5);
+
+  is(getScopeLabel(dbg, 6), "forOf");
+  is(getScopeLabel(dbg, 7), "mod");
+});
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-minified.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-minified.js
@@ -18,19 +18,16 @@ add_task(async function() {
 
   await waitForSources(dbg, "sum.js");
 
   await selectSource(dbg, "sum.js");
   await addBreakpoint(dbg, "sum.js", 2);
 
   invokeInTab("test");
   await waitForPaused(dbg);
-  await waitForMappedScopes(dbg);
 
   is(getScopeNodeLabel(dbg, 1), "sum", "check scope label");
-  is(getScopeNodeLabel(dbg, 2), "<this>", "check scope label");
-  is(getScopeNodeLabel(dbg, 3), "arguments", "check scope label");
-
-  is(getScopeNodeLabel(dbg, 4), "first", "check scope label");
-  is(getScopeNodeValue(dbg, 4), "40", "check scope value");
-  is(getScopeNodeLabel(dbg, 5), "second", "check scope label");
-  is(getScopeNodeValue(dbg, 5), "2", "check scope value");
+  is(getScopeNodeLabel(dbg, 2), "first", "check scope label");
+  is(getScopeNodeValue(dbg, 2), "40", "check scope value");
+  is(getScopeNodeLabel(dbg, 3), "second", "check scope label");
+  is(getScopeNodeValue(dbg, 3), "2", "check scope value");
+  is(getScopeNodeLabel(dbg, 4), "Window", "check scope label");
 });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps3.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps3.js
@@ -1,31 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests loading sourcemapped sources, setting breakpoints, and
 // inspecting restored scopes.
 
-function toggleNode(dbg, index) {
-  clickElement(dbg, "scopeNode", index);
-}
-
-function getLabel(dbg, index) {
-  return findElement(dbg, "scopeNode", index).innerText;
-}
-
-function hasScopeNode(dbg, index) {
-  return !!findElement(dbg, "scopeNode", index);
-}
-
-async function waitForScopeNode(dbg, index) {
-  const selector = getSelector("scopeNode", index);
-  return waitForElementWithSelector(dbg, selector);
-}
-
 // This source map does not have source contents, so it's fetched separately
 add_task(async function() {
   // NOTE: the CORS call makes the test run times inconsistent
   requestLongerTimeout(2);
   await pushPref("devtools.debugger.features.map-scopes", true);
 
   const dbg = await initDebugger("doc-sourcemaps3.html");
   const { selectors: { getBreakpoint, getBreakpoints }, getState } = dbg;
@@ -45,41 +28,32 @@ add_task(async function() {
     "Breakpoint has correct line"
   );
 
   invokeInTab("test");
 
   await waitForPaused(dbg);
   assertPausedLocation(dbg);
 
-  await waitForDispatch(dbg, "MAP_SCOPES");
-
-  is(getLabel(dbg, 1), "Block");
-  is(getLabel(dbg, 2), "<this>");
-  is(getLabel(dbg, 3), "na");
-  is(getLabel(dbg, 4), "nb");
+  is(getScopeLabel(dbg, 1), "Block");
+  is(getScopeLabel(dbg, 2), "na");
+  is(getScopeLabel(dbg, 3), "nb");
 
-  is(getLabel(dbg, 5), "Block");
-  is(
-    hasScopeNode(dbg, 8) && !hasScopeNode(dbg, 9),
-    true,
-    "scope count before expand"
-  );
-  toggleNode(dbg, 5);
+  is(getScopeLabel(dbg, 4), "Block");
 
-  await waitForScopeNode(dbg, 9);
+  await toggleScopeNode(dbg, 4);
+
+  is(getScopeLabel(dbg, 5), "ma");
+  is(getScopeLabel(dbg, 6), "mb");
 
-  is(getLabel(dbg, 6), "ma");
-  is(getLabel(dbg, 7), "mb");
+  await toggleScopeNode(dbg, 7);
+
+  is(getScopeLabel(dbg, 8), "a");
+  is(getScopeLabel(dbg, 9), "b");
+
+  is(getScopeLabel(dbg, 10), "Module");
 
-  is(
-    hasScopeNode(dbg, 10) && !hasScopeNode(dbg, 11),
-    true,
-    "scope count before expand"
-  );
-  toggleNode(dbg, 8);
+  await toggleScopeNode(dbg, 10);
 
-  await waitForScopeNode(dbg, 11);
-
-  is(getLabel(dbg, 9), "a");
-  is(getLabel(dbg, 10), "arguments");
-  is(getLabel(dbg, 11), "b");
+  is(getScopeLabel(dbg, 11), "binaryLookup:o()");
+  is(getScopeLabel(dbg, 12), "comparer:t()");
+  is(getScopeLabel(dbg, 13), "fancySort");
 });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sources.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sources.js
@@ -29,27 +29,29 @@ add_task(async function() {
   await waitForSources(dbg, "simple1", "simple2", "nested-source", "long.js");
 
   // Expand nodes and make sure more sources appear.
   await assertSourceCount(dbg, 2);
   await clickElement(dbg, "sourceArrow", 2);
 
   await assertSourceCount(dbg, 7);
   await clickElement(dbg, "sourceArrow", 3);
-
   await assertSourceCount(dbg, 8);
 
-  // Select a source.
+  // Select a source
   ok(
     !findElementWithSelector(dbg, ".sources-list .focused"),
     "Source is not focused"
   );
+
   const selected = waitForDispatch(dbg, "SELECT_SOURCE");
   await clickElement(dbg, "sourceNode", 4);
   await selected;
+  await waitForSelectedSource(dbg);
+
   ok(
     findElementWithSelector(dbg, ".sources-list .focused"),
     "Source is focused"
   );
   ok(
     getSelectedSource(getState())
       .get("url")
       .includes("nested-source.js"),
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/babel/fixtures/for-of/input.js
@@ -0,0 +1,9 @@
+const mod = "module scoped";
+
+export default function forOf() {
+  for (const x of [1]) {
+    doThing(x);
+  }
+
+  function doThing(arg) {}
+}
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/babel/fixtures/for-of/output.js
@@ -0,0 +1,94 @@
+var forOf =
+/******/ (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, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = forOf;
+var mod = "module scoped";
+
+function forOf() {
+  var _arr = [1];
+
+  for (var _i = 0; _i < _arr.length; _i++) {
+    var x = _arr[_i];
+    doThing(x);
+  }
+
+  function doThing(arg) {}
+}
+module.exports = exports["default"];
+
+/***/ })
+/******/ ]);
+//# sourceMappingURL=output.js.map
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/babel/fixtures/for-of/output.js.map
@@ -0,0 +1,1 @@
+{"version":3,"sources":["webpack:///webpack/bootstrap 531bdb05a2e8461e48b3","webpack:///./fixtures/for-of/input.js"],"names":["forOf","mod","x","doThing","arg"],"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;;;;;;;;;;;;;kBC3DwBA,K;AAFxB,IAAMC,MAAM,eAAZ;;AAEe,SAASD,KAAT,GAAiB;AAAA,aACd,CAAC,CAAD,CADc;;AAC9B,2CAAqB;AAAhB,QAAME,YAAN;AACHC,YAAQD,CAAR;AACD;;AAED,WAASC,OAAT,CAAiBC,GAAjB,EAAsB,CAAE;AACzB","file":"fixtures/for-of/output.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 531bdb05a2e8461e48b3","const mod = \"module scoped\";\n\nexport default function forOf() {\n  for (const x of [1]) {\n    doThing(x);\n  }\n\n  function doThing(arg) {}\n}\n\n\n\n// WEBPACK FOOTER //\n// ./fixtures/for-of/input.js"],"sourceRoot":""}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/babel/package.json
@@ -0,0 +1,22 @@
+{
+  "name": "babel-sourcemaps",
+  "version": "1.0.0",
+  "description": "Rebuild assets for babel's test fixtures",
+  "scripts": {
+    "build": "webpack",
+    "watch": "webpack -w"
+  },
+  "keywords": [],
+  "author": "",
+  "license": "MPL-2.0",
+  "devDependencies": {
+    "babel-core": "^6.26.0",
+    "babel-loader": "^7.1.2",
+    "babel-plugin-add-module-exports": "^0.2.1",
+    "babel-preset-env": "^1.6.1",
+    "webpack": "^3.7.1"
+  },
+  "dependencies": {
+    "lodash": "^4.17.5"
+  }
+}
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/babel/webpack.config.js
@@ -0,0 +1,66 @@
+const fs = require("fs");
+const path = require("path");
+const _ = require("lodash");
+
+const fixtures = path.join(__dirname, "fixtures");
+
+const tests = fs.readdirSync(fixtures).map(name => {
+  const dirname = path.relative(__dirname, path.join(fixtures, name));
+
+  return {
+    name: _.camelCase(name),
+    dirname,
+    input: `./${path.join(dirname, "input.js")}`,
+    output: path.join(dirname, "output.js")
+  };
+});
+
+const html = path.join(__dirname, "..", "doc-babel.html");
+
+fs.writeFileSync(
+  html,
+  fs.readFileSync(html, "utf8").replace(
+    /\n\s*<!-- INJECTED-START[\s\S]*INJECTED-END -->\n/,
+    `
+    <!-- INJECTED-START -->
+    <!--
+      Content generated by examples/babel/webpack.config.js.
+      Run "yarn build" to update.
+    -->${tests
+      .map(
+        ({ name, output }) =>
+          `\n    <script src="${path.join("babel", output)}"></script>` +
+          `\n    <button onclick="${name}()">Run ${name}</button>`
+      )
+      .join("")}
+    <!-- INJECTED-END -->
+`
+  )
+);
+
+module.exports = tests.map(({ name, dirname, input, output }) => ({
+  context: __dirname,
+  entry: input,
+  output: {
+    path: __dirname,
+    filename: output,
+
+    libraryTarget: "var",
+    library: name
+  },
+  devtool: "sourcemap",
+  module: {
+    loaders: [
+      {
+        test: /\.js$/,
+        exclude: /node_modules/,
+        loader: "babel-loader",
+        options: {
+          babelrc: false,
+          presets: ["env"],
+          plugins: ["add-module-exports"]
+        }
+      }
+    ]
+  }
+}));
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/doc-babel.html
@@ -0,0 +1,19 @@
+ <!-- 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>
+  <head>
+    <meta charset="UTF-8">
+  </head>
+  <body>
+    <!-- INJECTED-START -->
+    <!--
+      Content generated by examples/babel/webpack.config.js.
+      Run "yarn build" to update.
+    -->
+    <script src="babel/fixtures/for-of/output.js"></script>
+    <button onclick="forOf()">Run forOf</button>
+    <!-- INJECTED-END -->
+  </body>
+</html>
--- a/devtools/client/debugger/new/test/mochitest/head.js
+++ b/devtools/client/debugger/new/test/mochitest/head.js
@@ -437,34 +437,16 @@ function waitForever() {
  * a placeholder for a better waitForX handler.
  *
  * e.g await waitForTime(500)
  */
 function waitForTime(ms) {
   return new Promise(r => setTimeout(r, ms));
 }
 
-/**
- * Waits for the debugger to be fully paused.
- *
- * @memberof mochitest/waits
- * @param {Object} dbg
- * @static
- */
-async function waitForMappedScopes(dbg) {
-  await waitForState(
-    dbg,
-    state => {
-      const scopes = dbg.selectors.getSelectedScope(state);
-      return scopes && scopes.sourceBindings;
-    },
-    "mapped scopes"
-  );
-}
-
 function isSelectedFrameSelected(dbg, state) {
   const frame = dbg.selectors.getVisibleSelectedFrame(state);
 
   // Make sure the source text is completely loaded for the
   // source we are paused in.
   const sourceId = frame.location.sourceId;
   const source = dbg.selectors.getSelectedSource(state);
 
@@ -957,17 +939,18 @@ const selectors = {
   editorFooter: ".editor-pane .source-footer",
   sourceNode: i => `.sources-list .tree-node:nth-child(${i}) .node`,
   sourceNodes: ".sources-list .tree-node",
   sourceArrow: i => `.sources-list .tree-node:nth-child(${i}) .arrow`,
   resultItems: ".result-list .result-item",
   fileMatch: ".managed-tree .result",
   popup: ".popover",
   tooltip: ".tooltip",
-  outlineItem: i => `.outline-list__element:nth-child(${i}) .function-signature`,
+  outlineItem: i =>
+    `.outline-list__element:nth-child(${i}) .function-signature`,
   outlineItems: ".outline-list__element"
 };
 
 function getSelector(elementName, ...args) {
   let selector = selectors[elementName];
   if (!selector) {
     throw new Error(`The selector ${elementName} is not defined`);
   }
@@ -1070,16 +1053,24 @@ function toggleScopes(dbg) {
 function toggleExpressionNode(dbg, index) {
   return toggleObjectInspectorNode(findElement(dbg, "expressionNode", index));
 }
 
 function toggleScopeNode(dbg, index) {
   return toggleObjectInspectorNode(findElement(dbg, "scopeNode", index));
 }
 
+function getScopeLabel(dbg, index) {
+  return findElement(dbg, "scopeNode", index).innerText;
+}
+
+function getScopeValue(dbg, index) {
+  return findElement(dbg, "scopeValue", index).innerText;
+}
+
 function toggleObjectInspectorNode(node) {
   const objectInspector = node.closest(".object-inspector");
   const properties = objectInspector.querySelectorAll(".node").length;
   node.click();
   return waitUntil(
     () => objectInspector.querySelectorAll(".node").length !== properties
   );
 }
--- a/devtools/client/locales/en-US/debugger.properties
+++ b/devtools/client/locales/en-US/debugger.properties
@@ -563,26 +563,26 @@ watchExpressions.header=Watch expression
 
 # LOCALIZATION NOTE (watchExpressions.refreshButton): Watch Expressions header
 # button for refreshing the expressions.
 watchExpressions.refreshButton=Refresh
 
 # LOCALIZATION NOTE (welcome.search): The center pane welcome panel's
 # search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on
 # a mac we use the unicode character.
-welcome.search=%S To search for sources
+welcome.search=%S to search for sources
 
 # LOCALIZATION NOTE (welcome.findInFiles): The center pane welcome panel's
 # search prompt. e.g. cmd+f to search for files. On windows, it's ctrl+shift+f, on
 # a mac we use the unicode character.
-welcome.findInFiles=%S To find in files
+welcome.findInFiles=%S to find in files
 
 # LOCALIZATION NOTE (welcome.searchFunction): Label displayed in the welcome
 # panel. %S is replaced by the keyboard shortcut to search for functions.
-welcome.searchFunction=%S To search for functions in file
+welcome.searchFunction=%S to search for functions in file
 
 # LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search
 # prompt for searching for files.
 sourceSearch.search=Search sources…
 
 # LOCALIZATION NOTE (sourceSearch.noResults2): The center pane Source Search
 # message when the query did not match any of the sources.
 sourceSearch.noResults2=No results found
@@ -700,21 +700,27 @@ watchExpressionsSeparatorLabel2=\u0020→
 
 # LOCALIZATION NOTE (functionSearchSeparatorLabel): The text that is displayed
 # in the functions search panel as a separator between function's inferred name
 # and its real name (if available).
 functionSearchSeparatorLabel=←
 
 # LOCALIZATION NOTE(gotoLineModal.placeholder): The placeholder
 # text displayed when the user searches for specific lines in a file
+gotoLineModal.placeholder=Go to line…
+
+# LOCALIZATION NOTE(gotoLineModal.title): The message shown to users
+# to open the go to line modal
+gotoLineModal.title=Go to a line number in a file
+
+# LOCALIZATION NOTE(gotoLineModal.key2): The shortcut for opening the
+# go to line modal
 # Do not localize "CmdOrCtrl+;", or change the format of the string. These are
 # key identifiers, not messages displayed to the user.
-gotoLineModal.placeholder=Go to line…
-gotoLineModal.key=CmdOrCtrl+;
-gotoLineModal.title=Go to a line number in a file
+gotoLineModal.key2=CmdOrCtrl+;
 
 # LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder
 # text displayed when the user searches for functions in a file
 symbolSearch.search.functionsPlaceholder=Search functions…
 symbolSearch.search.functionsPlaceholder.title=Search for a function in a file
 
 # LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder
 # text displayed when the user searches for variables in a file
--- a/devtools/client/shared/test/browser_inplace-editor-01.js
+++ b/devtools/client/shared/test/browser_inplace-editor-01.js
@@ -97,17 +97,17 @@ function testAdvanceCharsFunction(doc) {
   info("Testing advanceChars as a function");
   let def = defer();
 
   let firstTime = true;
 
   createInplaceEditorAndClick({
     initial: "",
     advanceChars: function (charCode, text, insertionPoint) {
-      if (charCode !== Components.interfaces.nsIDOMKeyEvent.DOM_VK_COLON) {
+      if (charCode !== KeyboardEvent.DOM_VK_COLON) {
         return false;
       }
       if (firstTime) {
         firstTime = false;
         return false;
       }
 
       // Just to make sure we check it somehow.
--- a/devtools/client/shared/test/browser_keycodes.js
+++ b/devtools/client/shared/test/browser_keycodes.js
@@ -2,11 +2,11 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 const {KeyCodes} = require("devtools/client/shared/keycodes");
 
 add_task(function* () {
   for (let key in KeyCodes) {
-    is(KeyCodes[key], Ci.nsIDOMKeyEvent[key], "checking value for " + key);
+    is(KeyCodes[key], KeyboardEvent[key], "checking value for " + key);
   }
 });
--- a/devtools/client/shared/test/unit/test_advanceValidate.js
+++ b/devtools/client/shared/test/unit/test_advanceValidate.js
@@ -4,24 +4,25 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 // Tests the advanceValidate function from rule-view.js.
 
 const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
 const {advanceValidate} = require("devtools/client/inspector/shared/utils");
+const {KeyCodes} = require("devtools/client/shared/keycodes");
 
 //                            1         2         3
 //                  0123456789012345678901234567890
 const sampleInput = '\\symbol "string" url(somewhere)';
 
 function testInsertion(where, result, testName) {
   info(testName);
-  equal(advanceValidate(Ci.nsIDOMKeyEvent.DOM_VK_SEMICOLON, sampleInput, where),
+  equal(advanceValidate(KeyCodes.DOM_VK_SEMICOLON, sampleInput, where),
         result, "testing advanceValidate at " + where);
 }
 
 function run_test() {
   testInsertion(4, true, "inside a symbol");
   testInsertion(1, false, "after a backslash");
   testInsertion(8, true, "after whitespace");
   testInsertion(11, false, "inside a string");
--- a/devtools/server/actors/highlighters.js
+++ b/devtools/server/actors/highlighters.js
@@ -302,25 +302,25 @@ exports.HighlighterActor = protocol.Acto
        * KEY: Action/scope
        * LEFT_KEY: wider or parent
        * RIGHT_KEY: narrower or child
        * ENTER/CARRIAGE_RETURN: Picks currentNode
        * ESC/CTRL+SHIFT+C: Cancels picker, picks currentNode
        */
       switch (event.keyCode) {
         // Wider.
-        case Ci.nsIDOMKeyEvent.DOM_VK_LEFT:
+        case event.DOM_VK_LEFT:
           if (!currentNode.parentElement) {
             return;
           }
           currentNode = currentNode.parentElement;
           break;
 
         // Narrower.
-        case Ci.nsIDOMKeyEvent.DOM_VK_RIGHT:
+        case event.DOM_VK_RIGHT:
           if (!currentNode.children.length) {
             return;
           }
 
           // Set firstElementChild by default
           let child = currentNode.firstElementChild;
           // If currentNode is parent of hoveredNode, then
           // previously selected childNode is set
@@ -330,26 +330,26 @@ exports.HighlighterActor = protocol.Acto
               child = sibling;
             }
           }
 
           currentNode = child;
           break;
 
         // Select the element.
-        case Ci.nsIDOMKeyEvent.DOM_VK_RETURN:
+        case event.DOM_VK_RETURN:
           this._onPick(event);
           return;
 
         // Cancel pick mode.
-        case Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE:
+        case event.DOM_VK_ESCAPE:
           this.cancelPick();
           this._walker.emit("picker-node-canceled");
           return;
-        case Ci.nsIDOMKeyEvent.DOM_VK_C:
+        case event.DOM_VK_C:
           if ((IS_OSX && event.metaKey && event.altKey) ||
             (!IS_OSX && event.ctrlKey && event.shiftKey)) {
             this.cancelPick();
             this._walker.emit("picker-node-canceled");
           }
           return;
         default: return;
       }
--- a/devtools/server/actors/object.js
+++ b/devtools/server/actors/object.js
@@ -1891,17 +1891,17 @@ DebuggerServer.ObjectActorPreviewers.Obj
     if (hooks.getGripDepth() < 2) {
       let target = obj.makeDebuggeeValue(rawObj.target);
       preview.target = hooks.createValueGrip(target);
     }
 
     let props = [];
     if (rawObj instanceof Ci.nsIDOMMouseEvent) {
       props.push("buttons", "clientX", "clientY", "layerX", "layerY");
-    } else if (rawObj instanceof Ci.nsIDOMKeyEvent) {
+    } else if (obj.class == "KeyboardEvent") {
       let modifiers = [];
       if (rawObj.altKey) {
         modifiers.push("Alt");
       }
       if (rawObj.ctrlKey) {
         modifiers.push("Control");
       }
       if (rawObj.metaKey) {
@@ -1909,19 +1909,19 @@ DebuggerServer.ObjectActorPreviewers.Obj
       }
       if (rawObj.shiftKey) {
         modifiers.push("Shift");
       }
       preview.eventKind = "key";
       preview.modifiers = modifiers;
 
       props.push("key", "charCode", "keyCode");
-    } else if (rawObj instanceof Ci.nsIDOMTransitionEvent) {
+    } else if (obj.class == "TransitionEvent") {
       props.push("propertyName", "pseudoElement");
-    } else if (rawObj instanceof Ci.nsIDOMAnimationEvent) {
+    } else if (obj.class == "AnimationEvent") {
       props.push("animationName", "pseudoElement");
     } else if (rawObj instanceof Ci.nsIDOMClipboardEvent) {
       props.push("clipboardData");
     }
 
     // Add event-specific properties.
     for (let prop of props) {
       let value = rawObj[prop];
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -48,21 +48,21 @@
 #include "nsNameSpaceManager.h"
 #include "nsContentList.h"
 #include "nsVariant.h"
 #include "nsDOMTokenList.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsError.h"
 #include "nsDOMString.h"
 #include "nsIScriptSecurityManager.h"
-#include "nsIDOMMutationEvent.h"
 #include "mozilla/dom/AnimatableBinding.h"
 #include "mozilla/dom/HTMLDivElement.h"
 #include "mozilla/dom/HTMLSpanElement.h"
 #include "mozilla/dom/KeyframeAnimationOptionsBinding.h"
+#include "mozilla/dom/MutationEventBinding.h"
 #include "mozilla/AnimationComparator.h"
 #include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/DeclarationBlockInlines.h"
 #include "mozilla/EffectSet.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/EventStateManager.h"
@@ -2485,18 +2485,18 @@ Element::MaybeCheckSameAttrVal(int32_t a
       bool valueMatches = aValue.EqualsAsStrings(*info.mValue);
       if (valueMatches && aPrefix == info.mName->GetPrefix()) {
         return true;
       }
       modification = true;
     }
   }
   *aModType = modification ?
-    static_cast<uint8_t>(nsIDOMMutationEvent::MODIFICATION) :
-    static_cast<uint8_t>(nsIDOMMutationEvent::ADDITION);
+    static_cast<uint8_t>(MutationEventBinding::MODIFICATION) :
+    static_cast<uint8_t>(MutationEventBinding::ADDITION);
   return false;
 }
 
 bool
 Element::OnlyNotifySameValueSet(int32_t aNamespaceID, nsAtom* aName,
                                 nsAtom* aPrefix,
                                 const nsAttrValueOrString& aValue,
                                 bool aNotify, nsAttrValue& aOldValue,
@@ -2534,17 +2534,17 @@ Element::SetSingleClassFromParser(nsAtom
   SetMayHaveClass();
 
   return SetAttrAndNotify(kNameSpaceID_None,
                           nsGkAtoms::_class,
                           nullptr, // prefix
                           nullptr, // old value
                           value,
                           nullptr,
-                          static_cast<uint8_t>(nsIDOMMutationEvent::ADDITION),
+                          static_cast<uint8_t>(MutationEventBinding::ADDITION),
                           false, // hasListeners
                           false, // notify
                           kCallAfterSetAttr,
                           document,
                           updateBatch);
 }
 
 nsresult
@@ -2750,17 +2750,17 @@ Element::SetAttrAndNotify(int32_t aNames
         oldValueAtom = aParsedValue.GetAsAtom();
       }
       RefPtr<nsAtom> newValueAtom = valueForAfterSetAttr.GetAsAtom();
       nsAutoString ns;
       nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNamespaceID, ns);
 
       LifecycleCallbackArgs args = {
         nsDependentAtomString(aName),
-        aModType == nsIDOMMutationEvent::ADDITION ?
+        aModType == MutationEventBinding::ADDITION ?
           VoidString() : nsDependentAtomString(oldValueAtom),
         nsDependentAtomString(newValueAtom),
         (ns.IsEmpty() ? VoidString() : ns)
       };
 
       nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eAttributeChanged,
         this, &args, nullptr, definition);
     }
@@ -2985,17 +2985,17 @@ Element::UnsetAttr(int32_t aNameSpaceID,
     return NS_OK;
   }
 
   nsIDocument *document = GetComposedDoc();
   mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
 
   if (aNotify) {
     nsNodeUtils::AttributeWillChange(this, aNameSpaceID, aName,
-                                     nsIDOMMutationEvent::REMOVAL,
+                                     MutationEventBinding::REMOVAL,
                                      nullptr);
   }
 
   nsresult rv = BeforeSetAttr(aNameSpaceID, aName, nullptr, aNotify);
   NS_ENSURE_SUCCESS(rv, rv);
 
   bool hasMutationListeners = aNotify &&
     nsContentUtils::HasMutationListeners(this,
@@ -3068,34 +3068,34 @@ Element::UnsetAttr(int32_t aNameSpaceID,
   NS_ENSURE_SUCCESS(rv, rv);
 
   UpdateState(aNotify);
 
   if (aNotify) {
     // We can always pass oldValue here since there is no new value which could
     // have corrupted it.
     nsNodeUtils::AttributeChanged(this, aNameSpaceID, aName,
-                                  nsIDOMMutationEvent::REMOVAL, &oldValue);
+                                  MutationEventBinding::REMOVAL, &oldValue);
   }
 
   if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::dir) {
     OnSetDirAttr(this, nullptr, hadValidDir, hadDirAuto, aNotify);
   }
 
   if (hasMutationListeners) {
     InternalMutationEvent mutation(true, eLegacyAttrModified);
 
     mutation.mRelatedNode = attrNode;
     mutation.mAttrName = aName;
 
     nsAutoString value;
     oldValue.ToString(value);
     if (!value.IsEmpty())
       mutation.mPrevAttrValue = NS_Atomize(value);
-    mutation.mAttrChange = nsIDOMMutationEvent::REMOVAL;
+    mutation.mAttrChange = MutationEventBinding::REMOVAL;
 
     mozAutoSubtreeModified subtree(OwnerDoc(), this);
     (new AsyncEventDispatcher(this, mutation))->RunDOMEventWhenSafe();
   }
 
   return NS_OK;
 }
 
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -732,18 +732,18 @@ public:
    * attribute is currently set, and the new value that is about to be set is
    * different to the current value. As a perf optimization the new and old
    * values will not actually be compared if we aren't notifying and we don't
    * have mutation listeners (in which case it's cheap to just return false
    * and let the caller go ahead and set the value).
    * @param aOldValue [out] Set to the old value of the attribute, but only if
    *   there are event listeners. If set, the type of aOldValue will be either
    *   nsAttrValue::eString or nsAttrValue::eAtom.
-   * @param aModType [out] Set to nsIDOMMutationEvent::MODIFICATION or to
-   *   nsIDOMMutationEvent::ADDITION, but only if this helper returns true
+   * @param aModType [out] Set to MutationEventBinding::MODIFICATION or to
+   *   MutationEventBinding::ADDITION, but only if this helper returns true
    * @param aHasListeners [out] Set to true if there are mutation event
    *   listeners listening for NS_EVENT_BITS_MUTATION_ATTRMODIFIED
    * @param aOldValueSet [out] Indicates whether an old attribute value has been
    *   stored in aOldValue. The bool will be set to true if a value was stored.
    */
   bool MaybeCheckSameAttrVal(int32_t aNamespaceID, nsAtom* aName,
                              nsAtom* aPrefix,
                              const nsAttrValueOrString& aValue,
@@ -759,18 +759,18 @@ public:
    * @param aName The local name of the attribute
    * @param aPrefix The prefix of the attribute
    * @param aValue The value that the attribute is being changed to
    * @param aNotify If true, mutation listeners will be notified if they exist
    *   and the attribute value is changing
    * @param aOldValue [out] Set to the old value of the attribute, but only if
    *   there are event listeners. If set, the type of aOldValue will be either
    *   nsAttrValue::eString or nsAttrValue::eAtom.
-   * @param aModType [out] Set to nsIDOMMutationEvent::MODIFICATION or to
-   *   nsIDOMMutationEvent::ADDITION, but only if this helper returns true
+   * @param aModType [out] Set to MutationEventBinding::MODIFICATION or to
+   *   MutationEventBinding::ADDITION, but only if this helper returns true
    * @param aHasListeners [out] Set to true if there are mutation event
    *   listeners listening for NS_EVENT_BITS_MUTATION_ATTRMODIFIED
    * @param aOldValueSet [out] Indicates whether an old attribute value has been
    *   stored in aOldValue. The bool will be set to true if a value was stored.
    */
   bool OnlyNotifySameValueSet(int32_t aNamespaceID, nsAtom* aName,
                               nsAtom* aPrefix,
                               const nsAttrValueOrString& aValue,
@@ -1734,17 +1734,17 @@ protected:
    * @param aMaybeScriptedPrincipal
    *                      the principal of the scripted caller responsible for
    *                      setting the attribute, or null if no scripted caller
    *                      can be determined. A null value here does not
    *                      guarantee that there is no scripted caller, but a
    *                      non-null value does guarantee that a scripted caller
    *                      with the given principal is directly responsible for
    *                      the attribute change.
-   * @param aModType      nsIDOMMutationEvent::MODIFICATION or ADDITION.  Only
+   * @param aModType      MutationEventBinding::MODIFICATION or ADDITION.  Only
    *                      needed if aFireMutation or aNotify is true.
    * @param aFireMutation should mutation-events be fired?
    * @param aNotify       should we notify document-observers?
    * @param aCallAfterSetAttr should we call AfterSetAttr?
    * @param aComposedDocument The current composed document of the element.
    */
   nsresult SetAttrAndNotify(int32_t aNamespaceID,
                             nsAtom* aName,
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -54,17 +54,16 @@
 #include "nsDOMCSSAttrDeclaration.h"
 #include "nsNameSpaceManager.h"
 #include "nsContentList.h"
 #include "nsDOMTokenList.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsError.h"
 #include "nsDOMString.h"
 #include "nsIScriptSecurityManager.h"
-#include "nsIDOMMutationEvent.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "mozilla/MouseEvents.h"
 #include "nsNodeUtils.h"
 #include "nsDocument.h"
 #include "nsAttrValueOrString.h"
 #ifdef MOZ_XUL
 #include "nsXULElement.h"
 #endif /* MOZ_XUL */
--- a/dom/base/TextInputProcessor.cpp
+++ b/dom/base/TextInputProcessor.cpp
@@ -6,16 +6,17 @@
 
 #include "gfxPrefs.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/EventForwards.h"
 #include "mozilla/TextEventDispatcher.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TextInputProcessor.h"
 #include "mozilla/widget/IMEData.h"
+#include "mozilla/dom/KeyboardEvent.h"
 #include "nsContentUtils.h"
 #include "nsIDocShell.h"
 #include "nsIWidget.h"
 #include "nsPIDOMWindow.h"
 #include "nsPresContext.h"
 
 using namespace mozilla::widget;
 
@@ -563,56 +564,64 @@ TextInputProcessor::MaybeDispatchKeyupFo
   }
 
   result.mCanContinue = NS_SUCCEEDED(IsValidStateForComposition());
   return result;
 }
 
 nsresult
 TextInputProcessor::PrepareKeyboardEventForComposition(
-                      nsIDOMKeyEvent* aDOMKeyEvent,
+                      KeyboardEvent* aDOMKeyEvent,
                       uint32_t& aKeyFlags,
                       uint8_t aOptionalArgc,
                       WidgetKeyboardEvent*& aKeyboardEvent)
 {
   aKeyboardEvent = nullptr;
 
   aKeyboardEvent =
     aOptionalArgc && aDOMKeyEvent ?
-      aDOMKeyEvent->AsEvent()->WidgetEventPtr()->AsKeyboardEvent() : nullptr;
+      aDOMKeyEvent->WidgetEventPtr()->AsKeyboardEvent() : nullptr;
   if (!aKeyboardEvent || aOptionalArgc < 2) {
     aKeyFlags = 0;
   }
 
   if (!aKeyboardEvent) {
     return NS_OK;
   }
 
   if (NS_WARN_IF(!IsValidEventTypeForComposition(*aKeyboardEvent))) {
     return NS_ERROR_INVALID_ARG;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TextInputProcessor::StartComposition(nsIDOMKeyEvent* aDOMKeyEvent,
+TextInputProcessor::StartComposition(nsIDOMEvent* aDOMKeyEvent,
                                      uint32_t aKeyFlags,
                                      uint8_t aOptionalArgc,
                                      bool* aSucceeded)
 {
   MOZ_RELEASE_ASSERT(aSucceeded, "aSucceeded must not be nullptr");
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
   *aSucceeded = false;
 
+  RefPtr<KeyboardEvent> keyEvent;
+  if (aDOMKeyEvent) {
+    keyEvent = aDOMKeyEvent->InternalDOMEvent()->AsKeyboardEvent();
+    if (NS_WARN_IF(!keyEvent)) {
+      return NS_ERROR_INVALID_ARG;
+    }
+  }
+
   RefPtr<TextEventDispatcher> kungFuDeathGrip(mDispatcher);
 
   WidgetKeyboardEvent* keyboardEvent;
   nsresult rv =
-    PrepareKeyboardEventForComposition(aDOMKeyEvent, aKeyFlags, aOptionalArgc,
+    PrepareKeyboardEventForComposition(keyEvent, aKeyFlags, aOptionalArgc,
                                        keyboardEvent);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   EventDispatcherResult dispatcherResult =
     MaybeDispatchKeydownForComposition(keyboardEvent, aKeyFlags);
   if (NS_WARN_IF(NS_FAILED(dispatcherResult.mResult)) ||
@@ -679,35 +688,43 @@ TextInputProcessor::SetCaretInPendingCom
   nsresult rv = IsValidStateForComposition();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return kungFuDeathGrip->SetCaretInPendingComposition(aOffset, 0);
 }
 
 NS_IMETHODIMP
-TextInputProcessor::FlushPendingComposition(nsIDOMKeyEvent* aDOMKeyEvent,
+TextInputProcessor::FlushPendingComposition(nsIDOMEvent* aDOMKeyEvent,
                                             uint32_t aKeyFlags,
                                             uint8_t aOptionalArgc,
                                             bool* aSucceeded)
 {
   MOZ_RELEASE_ASSERT(aSucceeded, "aSucceeded must not be nullptr");
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   // Even if this doesn't flush pending composition actually, we need to reset
   // pending composition for starting next composition with new user input.
   AutoPendingCompositionResetter resetter(this);
 
   *aSucceeded = false;
   RefPtr<TextEventDispatcher> kungFuDeathGrip(mDispatcher);
   bool wasComposing = IsComposing();
 
+  RefPtr<KeyboardEvent> keyEvent;
+  if (aDOMKeyEvent) {
+    keyEvent = aDOMKeyEvent->InternalDOMEvent()->AsKeyboardEvent();
+    if (NS_WARN_IF(!keyEvent)) {
+      return NS_ERROR_INVALID_ARG;
+    }
+  }
+
   WidgetKeyboardEvent* keyboardEvent;
   nsresult rv =
-    PrepareKeyboardEventForComposition(aDOMKeyEvent, aKeyFlags, aOptionalArgc,
+    PrepareKeyboardEventForComposition(keyEvent, aKeyFlags, aOptionalArgc,
                                        keyboardEvent);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   EventDispatcherResult dispatcherResult =
     MaybeDispatchKeydownForComposition(keyboardEvent, aKeyFlags);
   if (NS_WARN_IF(NS_FAILED(dispatcherResult.mResult)) ||
@@ -731,46 +748,62 @@ TextInputProcessor::FlushPendingComposit
 
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TextInputProcessor::CommitComposition(nsIDOMKeyEvent* aDOMKeyEvent,
+TextInputProcessor::CommitComposition(nsIDOMEvent* aDOMKeyEvent,
                                       uint32_t aKeyFlags,
                                       uint8_t aOptionalArgc)
 {
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
+  RefPtr<KeyboardEvent> keyEvent;
+  if (aDOMKeyEvent) {
+    keyEvent = aDOMKeyEvent->InternalDOMEvent()->AsKeyboardEvent();
+    if (NS_WARN_IF(!keyEvent)) {
+      return NS_ERROR_INVALID_ARG;
+    }
+  }
+
   WidgetKeyboardEvent* keyboardEvent;
   nsresult rv =
-    PrepareKeyboardEventForComposition(aDOMKeyEvent, aKeyFlags, aOptionalArgc,
+    PrepareKeyboardEventForComposition(keyEvent, aKeyFlags, aOptionalArgc,
                                        keyboardEvent);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return CommitCompositionInternal(keyboardEvent, aKeyFlags);
 }
 
 NS_IMETHODIMP
 TextInputProcessor::CommitCompositionWith(const nsAString& aCommitString,
-                                          nsIDOMKeyEvent* aDOMKeyEvent,
+                                          nsIDOMEvent* aDOMKeyEvent,
                                           uint32_t aKeyFlags,
                                           uint8_t aOptionalArgc,
                                           bool* aSucceeded)
 {
   MOZ_RELEASE_ASSERT(aSucceeded, "aSucceeded must not be nullptr");
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
+  RefPtr<KeyboardEvent> keyEvent;
+  if (aDOMKeyEvent) {
+    keyEvent = aDOMKeyEvent->InternalDOMEvent()->AsKeyboardEvent();
+    if (NS_WARN_IF(!keyEvent)) {
+      return NS_ERROR_INVALID_ARG;
+    }
+  }
+
   WidgetKeyboardEvent* keyboardEvent;
   nsresult rv =
-    PrepareKeyboardEventForComposition(aDOMKeyEvent, aKeyFlags, aOptionalArgc,
+    PrepareKeyboardEventForComposition(keyEvent, aKeyFlags, aOptionalArgc,
                                        keyboardEvent);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return CommitCompositionInternal(keyboardEvent, aKeyFlags,
                                    &aCommitString, aSucceeded);
 }
@@ -814,25 +847,33 @@ TextInputProcessor::CommitCompositionInt
 
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TextInputProcessor::CancelComposition(nsIDOMKeyEvent* aDOMKeyEvent,
+TextInputProcessor::CancelComposition(nsIDOMEvent* aDOMKeyEvent,
                                       uint32_t aKeyFlags,
                                       uint8_t aOptionalArgc)
 {
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
+  RefPtr<KeyboardEvent> keyEvent;
+  if (aDOMKeyEvent) {
+    keyEvent = aDOMKeyEvent->InternalDOMEvent()->AsKeyboardEvent();
+    if (NS_WARN_IF(!keyEvent)) {
+      return NS_ERROR_INVALID_ARG;
+    }
+  }
+
   WidgetKeyboardEvent* keyboardEvent;
   nsresult rv =
-    PrepareKeyboardEventForComposition(aDOMKeyEvent, aKeyFlags, aOptionalArgc,
+    PrepareKeyboardEventForComposition(keyEvent, aKeyFlags, aOptionalArgc,
                                        keyboardEvent);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return CancelCompositionInternal(keyboardEvent, aKeyFlags);
 }
 
@@ -1022,31 +1063,31 @@ TextInputProcessor::PrepareKeyboardEvent
   }
 
   aKeyboardEvent.mIsSynthesizedByTIP = (mForTests)? false : true;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TextInputProcessor::Keydown(nsIDOMKeyEvent* aDOMKeyEvent,
+TextInputProcessor::Keydown(nsIDOMEvent* aDOMKeyEvent,
                             uint32_t aKeyFlags,
                             uint8_t aOptionalArgc,
                             uint32_t* aConsumedFlags)
 {
   MOZ_RELEASE_ASSERT(aConsumedFlags, "aConsumedFlags must not be nullptr");
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
   if (!aOptionalArgc) {
     aKeyFlags = 0;
   }
   if (NS_WARN_IF(!aDOMKeyEvent)) {
     return NS_ERROR_INVALID_ARG;
   }
   WidgetKeyboardEvent* originalKeyEvent =
-    aDOMKeyEvent->AsEvent()->WidgetEventPtr()->AsKeyboardEvent();
+    aDOMKeyEvent->InternalDOMEvent()->WidgetEventPtr()->AsKeyboardEvent();
   if (NS_WARN_IF(!originalKeyEvent)) {
     return NS_ERROR_INVALID_ARG;
   }
   return KeydownInternal(*originalKeyEvent, aKeyFlags, true, *aConsumedFlags);
 }
 
 nsresult
 TextInputProcessor::KeydownInternal(const WidgetKeyboardEvent& aKeyboardEvent,
@@ -1109,31 +1150,31 @@ TextInputProcessor::KeydownInternal(cons
       (status == nsEventStatus_eConsumeNoDefault) ? KEYPRESS_IS_CONSUMED :
                                                     KEYEVENT_NOT_CONSUMED;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TextInputProcessor::Keyup(nsIDOMKeyEvent* aDOMKeyEvent,
+TextInputProcessor::Keyup(nsIDOMEvent* aDOMKeyEvent,
                           uint32_t aKeyFlags,
                           uint8_t aOptionalArgc,
                           bool* aDoDefault)
 {
   MOZ_RELEASE_ASSERT(aDoDefault, "aDoDefault must not be nullptr");
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
   if (!aOptionalArgc) {
     aKeyFlags = 0;
   }
   if (NS_WARN_IF(!aDOMKeyEvent)) {
     return NS_ERROR_INVALID_ARG;
   }
   WidgetKeyboardEvent* originalKeyEvent =
-    aDOMKeyEvent->AsEvent()->WidgetEventPtr()->AsKeyboardEvent();
+    aDOMKeyEvent->InternalDOMEvent()->WidgetEventPtr()->AsKeyboardEvent();
   if (NS_WARN_IF(!originalKeyEvent)) {
     return NS_ERROR_INVALID_ARG;
   }
   return KeyupInternal(*originalKeyEvent, aKeyFlags, *aDoDefault);
 }
 
 nsresult
 TextInputProcessor::KeyupInternal(const WidgetKeyboardEvent& aKeyboardEvent,
--- a/dom/base/TextInputProcessor.h
+++ b/dom/base/TextInputProcessor.h
@@ -12,16 +12,20 @@
 #include "mozilla/TextEventDispatcher.h"
 #include "mozilla/TextEventDispatcherListener.h"
 #include "nsITextInputProcessor.h"
 #include "nsITextInputProcessorCallback.h"
 #include "nsTArray.h"
 
 namespace mozilla {
 
+namespace dom {
+class KeyboardEvent;
+} // namespace dom
+
 class TextInputProcessor final : public nsITextInputProcessor
                                , public widget::TextEventDispatcherListener
 {
   typedef mozilla::widget::IMENotification IMENotification;
   typedef mozilla::widget::IMENotificationRequests IMENotificationRequests;
   typedef mozilla::widget::TextEventDispatcher TextEventDispatcher;
 
 public:
@@ -72,17 +76,17 @@ private:
                          bool& aDoDefault);
   nsresult IsValidStateForComposition();
   void UnlinkFromTextEventDispatcher();
   nsresult PrepareKeyboardEventToDispatch(WidgetKeyboardEvent& aKeyboardEvent,
                                           uint32_t aKeyFlags);
   bool IsValidEventTypeForComposition(
          const WidgetKeyboardEvent& aKeyboardEvent) const;
   nsresult PrepareKeyboardEventForComposition(
-             nsIDOMKeyEvent* aDOMKeyEvent,
+             dom::KeyboardEvent* aDOMKeyEvent,
              uint32_t& aKeyFlags,
              uint8_t aOptionalArgc,
              WidgetKeyboardEvent*& aKeyboardEvent);
 
   struct EventDispatcherResult
   {
     nsresult mResult;
     bool     mDoDefault;
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -72,16 +72,19 @@ EXPORTS += [
     'nsDOMNavigationTiming.h',
     'nsDOMString.h',
     'nsDOMTokenList.h',
     'nsFocusManager.h',
     'nsFrameMessageManager.h',
     'nsGenericDOMDataNode.h',
     'nsGkAtomList.h',
     'nsGkAtoms.h',
+    'nsGlobalWindow.h',  # Because binding headers include it.
+    'nsGlobalWindowInner.h',  # Because binding headers include it.
+    'nsGlobalWindowOuter.h',  # Because binding headers include it.
     'nsIAnimationObserver.h',
     'nsIAttribute.h',
     'nsIContent.h',
     'nsIContentInlines.h',
     'nsIContentIterator.h',
     'nsIContentSerializer.h',
     'nsIdentifierMapEntry.h',
     'nsIDocument.h',
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -47,16 +47,17 @@
 #include "mozilla/dom/ElementInlines.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/FileSystemSecurity.h"
 #include "mozilla/dom/FileBlobImpl.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "mozilla/dom/HTMLSlotElement.h"
 #include "mozilla/dom/HTMLTemplateElement.h"
 #include "mozilla/dom/IDTracker.h"
+#include "mozilla/dom/KeyboardEventBinding.h"
 #include "mozilla/dom/IPCBlobUtils.h"
 #include "mozilla/dom/NodeBinding.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/dom/TouchEvent.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/dom/XULCommandEvent.h"
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -69,17 +69,16 @@ class nsIContent;
 class nsIContentPolicy;
 class nsIContentSecurityPolicy;
 class nsIDocShellTreeItem;
 class nsIDocumentLoaderFactory;
 class nsIDOMDocument;
 class nsIDOMDocumentFragment;
 class nsIDOMEvent;
 class nsIDOMHTMLInputElement;
-class nsIDOMKeyEvent;
 class nsIDOMNode;
 class nsIDragSession;
 class nsIEventTarget;
 class nsIFragmentContentSink;
 class nsIFrame;
 class nsIImageLoadingContent;
 class nsIInterfaceRequestor;
 class nsIIOService;
--- a/dom/base/nsDOMMutationObserver.cpp
+++ b/dom/base/nsDOMMutationObserver.cpp
@@ -12,17 +12,16 @@
 
 #include "mozilla/dom/Animation.h"
 #include "mozilla/dom/KeyframeEffectReadOnly.h"
 #include "mozilla/dom/DocGroup.h"
 
 #include "nsContentUtils.h"
 #include "nsCSSPseudoElements.h"
 #include "nsError.h"
-#include "nsIDOMMutationEvent.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsServiceManagerUtils.h"
 #include "nsTextFragment.h"
 #include "nsThreadUtils.h"
 
 using namespace mozilla;
 
 using mozilla::dom::TreeOrderComparator;
--- a/dom/base/nsDOMMutationObserver.h
+++ b/dom/base/nsDOMMutationObserver.h
@@ -15,18 +15,18 @@
 #include "nsStubAnimationObserver.h"
 #include "nsCOMArray.h"
 #include "nsTArray.h"
 #include "nsIVariant.h"
 #include "nsContentList.h"
 #include "mozilla/dom/Element.h"
 #include "nsClassHashtable.h"
 #include "nsNodeUtils.h"
-#include "nsIDOMMutationEvent.h"
 #include "nsWrapperCache.h"
+#include "mozilla/dom/MutationEventBinding.h"
 #include "mozilla/dom/MutationObserverBinding.h"
 #include "nsIDocument.h"
 #include "mozilla/dom/Animation.h"
 #include "nsIAnimationObserver.h"
 #include "nsGlobalWindow.h"
 
 class nsDOMMutationObserver;
 using mozilla::dom::MutationObservingInfo;
@@ -406,17 +406,17 @@ public:
 
   virtual void AttributeSetToCurrentValue(nsIDocument* aDocument,
                                           mozilla::dom::Element* aElement,
                                           int32_t aNameSpaceID,
                                           nsAtom* aAttribute) override
   {
     // We can reuse AttributeWillChange implementation.
     AttributeWillChange(aDocument, aElement, aNameSpaceID, aAttribute,
-                        nsIDOMMutationEvent::MODIFICATION, nullptr);
+                        mozilla::dom::MutationEventBinding::MODIFICATION, nullptr);
   }
 
 protected:
   nsMutationReceiver(nsINode* aTarget, nsDOMMutationObserver* aObserver);
 
   nsMutationReceiver(nsINode* aRegisterTarget, nsMutationReceiverBase* aParent)
   : nsMutationReceiverBase(aRegisterTarget, aParent)
   {
--- a/dom/base/nsIMutationObserver.h
+++ b/dom/base/nsIMutationObserver.h
@@ -152,17 +152,17 @@ public:
    * AttributeChanged).
    *
    * @param aDocument    The owner-document of aContent. Can be null.
    * @param aContent     The element whose attribute will change
    * @param aNameSpaceID The namespace id of the changing attribute
    * @param aAttribute   The name of the changing attribute
    * @param aModType     Whether or not the attribute will be added, changed, or
    *                     removed. The constants are defined in
-   *                     nsIDOMMutationEvent.h.
+   *                     MutationEvent.webidl.
    * @param aNewValue    The new value, IF it has been preparsed by
    *                     BeforeSetAttr, otherwise null.
    *
    * @note Callers of this method might not hold a strong reference to the
    *       observer.  The observer is responsible for making sure it stays
    *       alive for the duration of the call as needed.  The observer may
    *       assume that this call will happen when there are script blockers on
    *       the stack.
@@ -178,17 +178,17 @@ public:
    * Notification that an attribute of an element has changed.
    *
    * @param aDocument    The owner-document of aContent. Can be null.
    * @param aElement     The element whose attribute changed
    * @param aNameSpaceID The namespace id of the changed attribute
    * @param aAttribute   The name of the changed attribute
    * @param aModType     Whether or not the attribute was added, changed, or
    *                     removed. The constants are defined in
-   *                     nsIDOMMutationEvent.h.
+   *                     MutationEvent.webidl.
    * @param aOldValue    The old value, if either the old value or the new
    *                     value are StoresOwnData() (or absent); null otherwise.
    *
    * @note Callers of this method might not hold a strong reference to the
    *       observer.  The observer is responsible for making sure it stays
    *       alive for the duration of the call as needed.  The observer may
    *       assume that this call will happen when there are script blockers on
    *       the stack.
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -57,17 +57,16 @@
 #include "nsICategoryManager.h"
 #include "nsIContentIterator.h"
 #include "nsIControllers.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentType.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMEventListener.h"
-#include "nsIDOMMutationEvent.h"
 #include "nsIDOMNodeList.h"
 #include "nsILinkHandler.h"
 #include "mozilla/dom/NodeInfo.h"
 #include "mozilla/dom/NodeInfoInlines.h"
 #include "nsIPresShell.h"
 #include "nsIScriptError.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptSecurityManager.h"
--- a/dom/base/nsStyledElement.cpp
+++ b/dom/base/nsStyledElement.cpp
@@ -5,25 +5,25 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsStyledElement.h"
 #include "mozAutoDocUpdate.h"
 #include "nsGkAtoms.h"
 #include "nsAttrValue.h"
 #include "nsAttrValueInlines.h"
 #include "mozilla/dom/ElementInlines.h"
+#include "mozilla/dom/MutationEventBinding.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "nsDOMCSSDeclaration.h"
 #include "nsDOMCSSAttrDeclaration.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIDocument.h"
 #include "mozilla/DeclarationBlockInlines.h"
 #include "nsCSSParser.h"
 #include "mozilla/css/Loader.h"
-#include "nsIDOMMutationEvent.h"
 #include "nsXULElement.h"
 #include "nsContentUtils.h"
 #include "nsStyleUtil.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // Use the CC variant of this, even though this class does not define
@@ -99,18 +99,18 @@ nsStyledElement::SetInlineStyleDeclarati
   else if (aNotify && IsInUncomposedDoc()) {
     modification = !!mAttrsAndChildren.GetAttr(nsGkAtoms::style);
   }
 
   nsAttrValue attrValue(do_AddRef(aDeclaration), aSerialized);
 
   // XXXbz do we ever end up with ADDITION here?  I doubt it.
   uint8_t modType = modification ?
-    static_cast<uint8_t>(nsIDOMMutationEvent::MODIFICATION) :
-    static_cast<uint8_t>(nsIDOMMutationEvent::ADDITION);
+    static_cast<uint8_t>(MutationEventBinding::MODIFICATION) :
+    static_cast<uint8_t>(MutationEventBinding::ADDITION);
 
   nsIDocument* document = GetComposedDoc();
   mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
   return SetAttrAndNotify(kNameSpaceID_None, nsGkAtoms::style, nullptr,
                           oldValueSet ? &oldValue : nullptr, attrValue,
                           nullptr, modType,
                           hasListeners, aNotify, kDontCallAfterSetAttr,
                           document, updateBatch);
--- a/dom/base/nsTextNode.cpp
+++ b/dom/base/nsTextNode.cpp
@@ -8,17 +8,16 @@
  * Implementation of DOM Core's nsIDOMText node.
  */
 
 #include "nsTextNode.h"
 #include "mozilla/dom/TextBinding.h"
 #include "nsContentUtils.h"
 #include "mozilla/dom/DirectionalityUtils.h"
 #include "nsIDOMEventListener.h"
-#include "nsIDOMMutationEvent.h"
 #include "nsIDocument.h"
 #include "nsThreadUtils.h"
 #include "nsStubMutationObserver.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #ifdef DEBUG
 #include "nsRange.h"
 #endif
 #include "nsDocument.h"
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -1797,16 +1797,21 @@ class IDLNamespace(IDLInterfaceOrNamespa
                 if not attr.hasValue():
                     raise WebIDLError("[%s] must have a value" % identifier,
                                       [attr.location])
             elif (identifier == "ProtoObjectHack" or
                   identifier == "ChromeOnly"):
                 if not attr.noArguments():
                     raise WebIDLError("[%s] must not have arguments" % identifier,
                                       [attr.location])
+            elif identifier == "Pref":
+                # Known extended attributes that take a string value
+                if not attr.hasValue():
+                    raise WebIDLError("[%s] must have a value" % identifier,
+                                      [attr.location])
             else:
                 raise WebIDLError("Unknown extended attribute %s on namespace" %
                                   identifier,
                                   [attr.location])
 
             attrlist = attr.listValue()
             self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True
 
--- a/dom/browser-element/mochitest/file_focus.html
+++ b/dom/browser-element/mochitest/file_focus.html
@@ -8,17 +8,17 @@ document.getElementById('url').innerHTML
 
 <script>
   // The input element is getting synthesized key events and will prevent
   // default on the first ESC keydown event.
 
   var alreadyBlocked = false;
 
   addEventListener('keydown', function(e) {
-    if (e.keyCode == SpecialPowers.Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE &&
+    if (e.keyCode == KeyboardEvent.DOM_VK_ESCAPE &&
         alreadyBlocked == false) {
       alreadyBlocked = true;
       e.preventDefault();
     }
   });
 </script>
 </body>
 </html>
--- a/dom/events/AnimationEvent.cpp
+++ b/dom/events/AnimationEvent.cpp
@@ -22,17 +22,16 @@ AnimationEvent::AnimationEvent(EventTarg
   }
   else {
     mEventIsInternal = true;
     mEvent->mTime = PR_Now();
   }
 }
 
 NS_INTERFACE_MAP_BEGIN(AnimationEvent)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMAnimationEvent)
 NS_INTERFACE_MAP_END_INHERITING(Event)
 
 NS_IMPL_ADDREF_INHERITED(AnimationEvent, Event)
 NS_IMPL_RELEASE_INHERITED(AnimationEvent, Event)
 
 //static
 already_AddRefed<AnimationEvent>
 AnimationEvent::Constructor(const GlobalObject& aGlobal,
@@ -51,41 +50,33 @@ AnimationEvent::Constructor(const Global
   internalEvent->mElapsedTime = aParam.mElapsedTime;
   internalEvent->mPseudoElement = aParam.mPseudoElement;
 
   e->SetTrusted(trusted);
   e->SetComposed(aParam.mComposed);
   return e.forget();
 }
 
-NS_IMETHODIMP
+void
 AnimationEvent::GetAnimationName(nsAString& aAnimationName)
 {
   aAnimationName = mEvent->AsAnimationEvent()->mAnimationName;
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-AnimationEvent::GetElapsedTime(float* aElapsedTime)
-{
-  *aElapsedTime = ElapsedTime();
-  return NS_OK;
-}
 
 float
 AnimationEvent::ElapsedTime()
 {
   return mEvent->AsAnimationEvent()->mElapsedTime;
 }
 
-NS_IMETHODIMP
+void
 AnimationEvent::GetPseudoElement(nsAString& aPseudoElement)
 {
   aPseudoElement = mEvent->AsAnimationEvent()->mPseudoElement;
-  return NS_OK;
 }
 
 } // namespace dom
 } // namespace mozilla
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
--- a/dom/events/AnimationEvent.h
+++ b/dom/events/AnimationEvent.h
@@ -4,51 +4,47 @@
  * 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/. */
 #ifndef mozilla_dom_AnimationEvent_h_
 #define mozilla_dom_AnimationEvent_h_
 
 #include "mozilla/EventForwards.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/AnimationEventBinding.h"
-#include "nsIDOMAnimationEvent.h"
 #include "nsStringFwd.h"
 
 namespace mozilla {
 namespace dom {
 
-class AnimationEvent : public Event,
-                       public nsIDOMAnimationEvent
+class AnimationEvent : public Event
 {
 public:
   AnimationEvent(EventTarget* aOwner,
                  nsPresContext* aPresContext,
                  InternalAnimationEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
-  NS_FORWARD_TO_EVENT
-  NS_DECL_NSIDOMANIMATIONEVENT
 
   static already_AddRefed<AnimationEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const AnimationEventInit& aParam,
               ErrorResult& aRv);
 
   virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
   {
     return AnimationEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
-  // xpidl implementation
-  // GetAnimationName(nsAString& aAnimationName);
-  // GetPseudoElement(nsAString& aPseudoElement);
+  void GetAnimationName(nsAString& aAnimationName);
 
   float ElapsedTime();
 
+  void GetPseudoElement(nsAString& aPseudoElement);
+
 protected:
   ~AnimationEvent() {}
 };
 
 } // namespace dom
 } // namespace mozilla
 
 already_AddRefed<mozilla::dom::AnimationEvent>
--- a/dom/events/BeforeUnloadEvent.cpp
+++ b/dom/events/BeforeUnloadEvent.cpp
@@ -8,31 +8,28 @@
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_ADDREF_INHERITED(BeforeUnloadEvent, Event)
 NS_IMPL_RELEASE_INHERITED(BeforeUnloadEvent, Event)
 
 NS_INTERFACE_MAP_BEGIN(BeforeUnloadEvent)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMBeforeUnloadEvent)
 NS_INTERFACE_MAP_END_INHERITING(Event)
 
-NS_IMETHODIMP
+void
 BeforeUnloadEvent::SetReturnValue(const nsAString& aReturnValue)
 {
   mText = aReturnValue;
-  return NS_OK;  // Don't throw an exception
 }
 
-NS_IMETHODIMP
+void
 BeforeUnloadEvent::GetReturnValue(nsAString& aReturnValue)
 {
   aReturnValue = mText;
-  return NS_OK;  // Don't throw an exception
 }
 
 } // namespace dom
 } // namespace mozilla
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
--- a/dom/events/BeforeUnloadEvent.h
+++ b/dom/events/BeforeUnloadEvent.h
@@ -4,44 +4,44 @@
  * 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/. */
 
 #ifndef mozilla_dom_BeforeUnloadEvent_h_
 #define mozilla_dom_BeforeUnloadEvent_h_
 
 #include "mozilla/dom/BeforeUnloadEventBinding.h"
 #include "mozilla/dom/Event.h"
-#include "nsIDOMBeforeUnloadEvent.h"
 
 namespace mozilla {
 namespace dom {
 
-class BeforeUnloadEvent : public Event,
-                          public nsIDOMBeforeUnloadEvent
+class BeforeUnloadEvent : public Event
 {
 public:
   BeforeUnloadEvent(EventTarget* aOwner,
                     nsPresContext* aPresContext,
                     WidgetEvent* aEvent)
     : Event(aOwner, aPresContext, aEvent)
   {
   }
 
+  virtual BeforeUnloadEvent* AsBeforeUnloadEvent() override
+  {
+    return this;
+  }
+
   virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
   {
     return BeforeUnloadEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   NS_DECL_ISUPPORTS_INHERITED
 
-  // Forward to Event
-  NS_FORWARD_TO_EVENT
-
-  // nsIDOMBeforeUnloadEvent Interface
-  NS_DECL_NSIDOMBEFOREUNLOADEVENT
+  void GetReturnValue(nsAString& aReturnValue);
+  void SetReturnValue(const nsAString& aReturnValue);
 
 protected:
   ~BeforeUnloadEvent() {}
 
   nsString mText;
 };
 
 } // namespace dom
--- a/dom/events/CommandEvent.cpp
+++ b/dom/events/CommandEvent.cpp
@@ -22,46 +22,30 @@ CommandEvent::CommandEvent(EventTarget* 
   if (aEvent) {
     mEventIsInternal = false;
   } else {
     mEventIsInternal = true;
   }
 }
 
 NS_INTERFACE_MAP_BEGIN(CommandEvent)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMCommandEvent)
 NS_INTERFACE_MAP_END_INHERITING(Event)
 
 NS_IMPL_ADDREF_INHERITED(CommandEvent, Event)
 NS_IMPL_RELEASE_INHERITED(CommandEvent, Event)
 
-NS_IMETHODIMP
+void
 CommandEvent::GetCommand(nsAString& aCommand)
 {
   nsAtom* command = mEvent->AsCommandEvent()->mCommand;
   if (command) {
     command->ToString(aCommand);
   } else {
     aCommand.Truncate();
   }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-CommandEvent::InitCommandEvent(const nsAString& aTypeArg,
-                               bool aCanBubbleArg,
-                               bool aCancelableArg,
-                               const nsAString& aCommand)
-{
-  NS_ENSURE_TRUE(!mEvent->mFlags.mIsBeingDispatched, NS_OK);
-
-  Event::InitEvent(aTypeArg, aCanBubbleArg, aCancelableArg);
-
-  mEvent->AsCommandEvent()->mCommand = NS_Atomize(aCommand);
-  return NS_OK;
 }
 
 } // namespace dom
 } // namespace mozilla
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
--- a/dom/events/CommandEvent.h
+++ b/dom/events/CommandEvent.h
@@ -5,49 +5,35 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_CommandEvent_h_
 #define mozilla_dom_CommandEvent_h_
 
 #include "mozilla/EventForwards.h"
 #include "mozilla/dom/CommandEventBinding.h"
 #include "mozilla/dom/Event.h"
-#include "nsIDOMCommandEvent.h"
 
 namespace mozilla {
 namespace dom {
 
-class CommandEvent : public Event,
-                     public nsIDOMCommandEvent
+class CommandEvent : public Event
 {
 public:
   CommandEvent(EventTarget* aOwner,
                nsPresContext* aPresContext,
                WidgetCommandEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
 
-  NS_DECL_NSIDOMCOMMANDEVENT
-
-  // Forward to base class
-  NS_FORWARD_TO_EVENT
-
   virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
   {
     return CommandEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
-  void InitCommandEvent(const nsAString& aType,
-                        bool aCanBubble,
-                        bool aCancelable,
-                        const nsAString& aCommand,
-                        ErrorResult& aRv)
-  {
-    aRv = InitCommandEvent(aType, aCanBubble, aCancelable, aCommand);
-  }
+  void GetCommand(nsAString& aCommand);
 
 protected:
   ~CommandEvent() {}
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/events/Event.h
+++ b/dom/events/Event.h
@@ -24,21 +24,23 @@
 
 class nsIContent;
 class nsIDOMEventTarget;
 class nsPresContext;
 
 namespace mozilla {
 namespace dom {
 
+class BeforeUnloadEvent;
 class EventTarget;
 class EventMessageAutoOverride;
 // ExtendableEvent is a ServiceWorker event that is not
 // autogenerated since it has some extra methods.
 class ExtendableEvent;
+class KeyboardEvent;
 class TimeEvent;
 class WantsPopupControlCheck;
 #define GENERATED_EVENT(EventClass_) class EventClass_;
 #include "mozilla/dom/GeneratedEventList.h"
 #undef GENERATED_EVENT
 
 // Dummy class so we can cast through it to get from nsISupports to
 // Event subclasses with only two non-ambiguous static casts.
@@ -107,16 +109,28 @@ public:
   // autogenerated since it has some extra methods.
   virtual ExtendableEvent* AsExtendableEvent()
   {
     return nullptr;
   }
 
   virtual TimeEvent* AsTimeEvent() { return nullptr; }
 
+  // BeforeUnloadEvent is not autogenerated because it has a setter.
+  virtual BeforeUnloadEvent* AsBeforeUnloadEvent()
+  {
+    return nullptr;
+  }
+
+  // KeyboardEvent has all sorts of non-autogeneratable bits so far.
+  virtual KeyboardEvent* AsKeyboardEvent()
+  {
+    return nullptr;
+  }
+
   // nsIDOMEvent Interface
   NS_DECL_NSIDOMEVENT
 
   void InitPresContextData(nsPresContext* aPresContext);
 
   // Returns true if the event should be trusted.
   bool Init(EventTarget* aGlobal);
 
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -51,17 +51,16 @@
 #include "nsIWebNavigation.h"
 #include "nsIContentViewer.h"
 #include "nsFrameManager.h"
 #include "nsITabChild.h"
 #include "nsPluginFrame.h"
 #include "nsMenuPopupFrame.h"
 
 #include "nsIDOMXULElement.h"
-#include "nsIDOMKeyEvent.h"
 #include "nsIObserverService.h"
 #include "nsIDocShell.h"
 #include "nsIDOMWheelEvent.h"
 #include "nsIDOMUIEvent.h"
 #include "nsIMozBrowserFrame.h"
 
 #include "nsSubDocumentFrame.h"
 #include "nsLayoutUtils.h"
--- a/dom/events/JSEventHandler.cpp
+++ b/dom/events/JSEventHandler.cpp
@@ -7,26 +7,26 @@
 #include "nsString.h"
 #include "nsIServiceManager.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIXPConnect.h"
 #include "nsIMutableArray.h"
 #include "nsVariant.h"
-#include "nsIDOMBeforeUnloadEvent.h"
 #include "nsGkAtoms.h"
 #include "xpcpublic.h"
 #include "nsJSEnvironment.h"
 #include "nsDOMJSUtils.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/CycleCollectedJSContext.h"
 #include "mozilla/HoldDropJSObjects.h"
 #include "mozilla/JSEventHandler.h"
 #include "mozilla/Likely.h"
+#include "mozilla/dom/BeforeUnloadEvent.h"
 #include "mozilla/dom/ErrorEvent.h"
 #include "mozilla/dom/WorkerPrivate.h"
 
 namespace mozilla {
 
 using namespace dom;
 
 JSEventHandler::JSEventHandler(nsISupports* aTarget,
@@ -183,17 +183,17 @@ JSEventHandler::HandleEvent(nsIDOMEvent*
       mTypedHandler.OnBeforeUnloadEventHandler();
     ErrorResult rv;
     nsString retval;
     handler->Call(mTarget, *(aEvent->InternalDOMEvent()), retval, rv);
     if (rv.Failed()) {
       return rv.StealNSResult();
     }
 
-    nsCOMPtr<nsIDOMBeforeUnloadEvent> beforeUnload = do_QueryInterface(aEvent);
+    BeforeUnloadEvent* beforeUnload = event->AsBeforeUnloadEvent();
     NS_ENSURE_STATE(beforeUnload);
 
     if (!DOMStringIsNull(retval)) {
       event->PreventDefaultInternal(isChromeHandler);
 
       nsAutoString text;
       beforeUnload->GetReturnValue(text);
 
--- a/dom/events/JSEventHandler.h
+++ b/dom/events/JSEventHandler.h
@@ -8,17 +8,16 @@
 #define mozilla_JSEventHandler_h_
 
 #include "mozilla/Attributes.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/EventHandlerBinding.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsAtom.h"
-#include "nsIDOMKeyEvent.h"
 #include "nsIDOMEventListener.h"
 #include "nsIScriptContext.h"
 
 namespace mozilla {
 
 class TypedEventHandler
 {
 public:
--- a/dom/events/KeyboardEvent.cpp
+++ b/dom/events/KeyboardEvent.cpp
@@ -30,17 +30,16 @@ KeyboardEvent::KeyboardEvent(EventTarget
     mEvent->AsKeyboardEvent()->mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
   }
 }
 
 NS_IMPL_ADDREF_INHERITED(KeyboardEvent, UIEvent)
 NS_IMPL_RELEASE_INHERITED(KeyboardEvent, UIEvent)
 
 NS_INTERFACE_MAP_BEGIN(KeyboardEvent)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMKeyEvent)
 NS_INTERFACE_MAP_END_INHERITING(UIEvent)
 
 bool
 KeyboardEvent::AltKey(CallerType aCallerType)
 {
   bool altState = mEvent->AsKeyboardEvent()->IsAlt();
 
   if (!ShouldResistFingerprinting(aCallerType)) {
@@ -48,115 +47,64 @@ KeyboardEvent::AltKey(CallerType aCaller
   }
 
   // We need to give a spoofed state for Alt key since it could be used as a
   // modifier key in certain keyboard layout. For example, the '@' key for
   // German keyboard for MAC is Alt+L.
   return GetSpoofedModifierStates(Modifier::MODIFIER_ALT, altState);
 }
 
-NS_IMETHODIMP
-KeyboardEvent::GetAltKey(bool* aIsDown)
-{
-  NS_ENSURE_ARG_POINTER(aIsDown);
-  *aIsDown = AltKey();
-  return NS_OK;
-}
-
 bool
 KeyboardEvent::CtrlKey(CallerType aCallerType)
 {
   bool ctrlState = mEvent->AsKeyboardEvent()->IsControl();
 
   if (!ShouldResistFingerprinting(aCallerType)) {
     return ctrlState;
   }
 
   // We need to give a spoofed state for Control key since it could be used as a
   // modifier key in certain asian keyboard layouts.
   return GetSpoofedModifierStates(Modifier::MODIFIER_CONTROL, ctrlState);
 }
 
-NS_IMETHODIMP
-KeyboardEvent::GetCtrlKey(bool* aIsDown)
-{
-  NS_ENSURE_ARG_POINTER(aIsDown);
-  *aIsDown = CtrlKey();
-  return NS_OK;
-}
-
 bool
 KeyboardEvent::ShiftKey(CallerType aCallerType)
 {
   bool shiftState = mEvent->AsKeyboardEvent()->IsShift();
 
   if (!ShouldResistFingerprinting(aCallerType)) {
     return shiftState;
   }
 
   return GetSpoofedModifierStates(Modifier::MODIFIER_SHIFT, shiftState);
 }
 
-NS_IMETHODIMP
-KeyboardEvent::GetShiftKey(bool* aIsDown)
-{
-  NS_ENSURE_ARG_POINTER(aIsDown);
-  *aIsDown = ShiftKey();
-  return NS_OK;
-}
-
 bool
 KeyboardEvent::MetaKey()
 {
   return mEvent->AsKeyboardEvent()->IsMeta();
 }
 
-NS_IMETHODIMP
-KeyboardEvent::GetMetaKey(bool* aIsDown)
-{
-  NS_ENSURE_ARG_POINTER(aIsDown);
-  *aIsDown = MetaKey();
-  return NS_OK;
-}
-
 bool
 KeyboardEvent::Repeat()
 {
   return mEvent->AsKeyboardEvent()->mIsRepeat;
 }
 
-NS_IMETHODIMP
-KeyboardEvent::GetRepeat(bool* aIsRepeat)
-{
-  NS_ENSURE_ARG_POINTER(aIsRepeat);
-  *aIsRepeat = Repeat();
-  return NS_OK;
-}
-
 bool
 KeyboardEvent::IsComposing()
 {
   return mEvent->AsKeyboardEvent()->mIsComposing;
 }
 
-NS_IMETHODIMP
-KeyboardEvent::GetModifierState(const nsAString& aKey,
-                                bool* aState)
-{
-  NS_ENSURE_ARG_POINTER(aState);
-
-  *aState = GetModifierState(aKey);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-KeyboardEvent::GetKey(nsAString& aKeyName)
+void
+KeyboardEvent::GetKey(nsAString& aKeyName) const
 {
   mEvent->AsKeyboardEvent()->GetDOMKeyName(aKeyName);
-  return NS_OK;
 }
 
 void
 KeyboardEvent::GetCode(nsAString& aCodeName, CallerType aCallerType)
 {
   if (!ShouldResistFingerprinting(aCallerType)) {
     mEvent->AsKeyboardEvent()->GetDOMCodeName(aCodeName);
     return;
@@ -200,24 +148,16 @@ void KeyboardEvent::GetInitDict(Keyboard
   aParam.mModifierSymbol = internalEvent->IsSymbol();
   aParam.mModifierSymbolLock = internalEvent->IsSymbolLocked();
 
   // EventInit
   aParam.mBubbles =  internalEvent->mFlags.mBubbles;
   aParam.mCancelable = internalEvent->mFlags.mCancelable;
 }
 
-NS_IMETHODIMP
-KeyboardEvent::GetCharCode(uint32_t* aCharCode)
-{
-  NS_ENSURE_ARG_POINTER(aCharCode);
-  *aCharCode = CharCode();
-  return NS_OK;
-}
-
 uint32_t
 KeyboardEvent::CharCode()
 {
   // If this event is initialized with ctor, we shouldn't check event type.
   if (mInitializedByCtor) {
     return mEvent->AsKeyboardEvent()->mCharCode;
   }
 
@@ -231,24 +171,16 @@ KeyboardEvent::CharCode()
   case eAccessKeyNotFound:
     return mEvent->AsKeyboardEvent()->mCharCode;
   default:
     break;
   }
   return 0;
 }
 
-NS_IMETHODIMP
-KeyboardEvent::GetKeyCode(uint32_t* aKeyCode)
-{
-  NS_ENSURE_ARG_POINTER(aKeyCode);
-  *aKeyCode = KeyCode();
-  return NS_OK;
-}
-
 uint32_t
 KeyboardEvent::KeyCode(CallerType aCallerType)
 {
   // If this event is initialized with ctor, we shouldn't check event type.
   if (mInitializedByCtor) {
     return mEvent->AsKeyboardEvent()->mKeyCode;
   }
 
@@ -304,25 +236,16 @@ KeyboardEvent::Which()
       }
     default:
       break;
   }
 
   return 0;
 }
 
-NS_IMETHODIMP
-KeyboardEvent::GetLocation(uint32_t* aLocation)
-{
-  NS_ENSURE_ARG_POINTER(aLocation);
-
-  *aLocation = Location();
-  return NS_OK;
-}
-
 uint32_t
 KeyboardEvent::Location()
 {
   return mEvent->AsKeyboardEvent()->mLocation;
 }
 
 // static
 already_AddRefed<KeyboardEvent>
@@ -366,38 +289,31 @@ KeyboardEvent::InitWithKeyboardEventInit
   }
   internalEvent->mCodeNameIndex =
     WidgetKeyboardEvent::GetCodeNameIndex(aParam.mCode);
   if (internalEvent->mCodeNameIndex == CODE_NAME_INDEX_USE_STRING) {
     internalEvent->mCodeValue = aParam.mCode;
   }
 }
 
-NS_IMETHODIMP
-KeyboardEvent::InitKeyEvent(const nsAString& aType,
-                            bool aCanBubble,
-                            bool aCancelable,
-                            mozIDOMWindow* aView,
-                            bool aCtrlKey,
-                            bool aAltKey,
-                            bool aShiftKey,
-                            bool aMetaKey,
-                            uint32_t aKeyCode,
-                            uint32_t aCharCode)
+void
+KeyboardEvent::InitKeyEvent(const nsAString& aType, bool aCanBubble,
+                            bool aCancelable, nsGlobalWindowInner* aView,
+                            bool aCtrlKey, bool aAltKey,
+                            bool aShiftKey, bool aMetaKey,
+                            uint32_t aKeyCode, uint32_t aCharCode)
 {
-  NS_ENSURE_TRUE(!mEvent->mFlags.mIsBeingDispatched, NS_OK);
+  NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
 
   UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, 0);
 
   WidgetKeyboardEvent* keyEvent = mEvent->AsKeyboardEvent();
   keyEvent->InitBasicModifiers(aCtrlKey, aAltKey, aShiftKey, aMetaKey);
   keyEvent->mKeyCode = aKeyCode;
   keyEvent->mCharCode = aCharCode;
-
-  return NS_OK;
 }
 
 void
 KeyboardEvent::InitKeyboardEvent(const nsAString& aType,
                                  bool aCanBubble,
                                  bool aCancelable,
                                  nsGlobalWindowInner* aView,
                                  const nsAString& aKey,
@@ -447,17 +363,17 @@ KeyboardEvent::ShouldResistFingerprintin
   //   4. The caller type is system.
   //   5. The pref privcy.resistFingerprinting' is false, we fast return here since
   //      we don't need to do any QI of following codes.
   if (mInitializedByCtor ||
       aCallerType == CallerType::System ||
       mEvent->mFlags.mInSystemGroup ||
       !nsContentUtils::ShouldResistFingerprinting() ||
       mEvent->AsKeyboardEvent()->mLocation ==
-        nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD) {
+        KeyboardEventBinding::DOM_KEY_LOCATION_NUMPAD) {
     return false;
   }
 
   nsCOMPtr<nsIDocument> doc = GetDocument();
 
   return doc && !nsContentUtils::IsChromeDoc(doc);
 }
 
--- a/dom/events/KeyboardEvent.h
+++ b/dom/events/KeyboardEvent.h
@@ -5,45 +5,44 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_KeyboardEvent_h_
 #define mozilla_dom_KeyboardEvent_h_
 
 #include "mozilla/dom/UIEvent.h"
 #include "mozilla/dom/KeyboardEventBinding.h"
 #include "mozilla/EventForwards.h"
-#include "nsIDOMKeyEvent.h"
 #include "nsRFPService.h"
 
 namespace mozilla {
 namespace dom {
 
-class KeyboardEvent : public UIEvent,
-                      public nsIDOMKeyEvent
+class KeyboardEvent : public UIEvent
 {
 public:
   KeyboardEvent(EventTarget* aOwner,
                 nsPresContext* aPresContext,
                 WidgetKeyboardEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMKeyEvent Interface
-  NS_DECL_NSIDOMKEYEVENT
-
-  // Forward to base class
-  NS_FORWARD_TO_UIEVENT
+  virtual KeyboardEvent* AsKeyboardEvent() override
+  {
+    return this;
+  }
 
   static already_AddRefed<KeyboardEvent> Constructor(
                                            const GlobalObject& aGlobal,
                                            const nsAString& aType,
                                            const KeyboardEventInit& aParam,
                                            ErrorResult& aRv);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
+  virtual JSObject*
+    WrapObjectInternal(JSContext* aCx,
+                       JS::Handle<JSObject*> aGivenProto) override
   {
     return KeyboardEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   bool AltKey(CallerType aCallerType = CallerType::System);
   bool CtrlKey(CallerType aCallerType = CallerType::System);
   bool ShiftKey(CallerType aCallerType = CallerType::System);
   bool MetaKey();
@@ -58,33 +57,29 @@ public:
     }
 
     Modifiers modifier = WidgetInputEvent::GetModifier(aKey);
     return GetSpoofedModifierStates(modifier, modifierState);
   }
 
   bool Repeat();
   bool IsComposing();
+  void GetKey(nsAString& aKey) const;
   uint32_t CharCode();
   uint32_t KeyCode(CallerType aCallerType = CallerType::System);
   virtual uint32_t Which() override;
   uint32_t Location();
 
   void GetCode(nsAString& aCode, CallerType aCallerType = CallerType::System);
   void GetInitDict(KeyboardEventInit& aParam);
 
   void InitKeyEvent(const nsAString& aType, bool aCanBubble, bool aCancelable,
                     nsGlobalWindowInner* aView, bool aCtrlKey, bool aAltKey,
                     bool aShiftKey, bool aMetaKey,
-                    uint32_t aKeyCode, uint32_t aCharCode)
-  {
-    auto* view = aView ? aView->AsInner() : nullptr;
-    InitKeyEvent(aType, aCanBubble, aCancelable, view, aCtrlKey, aAltKey,
-                 aShiftKey, aMetaKey, aKeyCode, aCharCode);
-  }
+                    uint32_t aKeyCode, uint32_t aCharCode);
 
   void InitKeyboardEvent(const nsAString& aType,
                          bool aCanBubble, bool aCancelable,
                          nsGlobalWindowInner* aView, const nsAString& aKey,
                          uint32_t aLocation, bool aCtrlKey, bool aAltKey,
                          bool aShiftKey, bool aMetaKey, ErrorResult& aRv);
 
 protected:
--- a/dom/events/MutationEvent.cpp
+++ b/dom/events/MutationEvent.cpp
@@ -18,105 +18,83 @@ MutationEvent::MutationEvent(EventTarget
                              InternalMutationEvent* aEvent)
   : Event(aOwner, aPresContext,
           aEvent ? aEvent : new InternalMutationEvent(false, eVoidEvent))
 {
   mEventIsInternal = (aEvent == nullptr);
 }
 
 NS_INTERFACE_MAP_BEGIN(MutationEvent)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMMutationEvent)
 NS_INTERFACE_MAP_END_INHERITING(Event)
 
 NS_IMPL_ADDREF_INHERITED(MutationEvent, Event)
 NS_IMPL_RELEASE_INHERITED(MutationEvent, Event)
 
 already_AddRefed<nsINode>
 MutationEvent::GetRelatedNode()
 {
   nsCOMPtr<nsINode> n =
     do_QueryInterface(mEvent->AsMutationEvent()->mRelatedNode);
   return n.forget();
 }
 
-NS_IMETHODIMP
-MutationEvent::GetRelatedNode(nsIDOMNode** aRelatedNode)
-{
-  nsCOMPtr<nsINode> relatedNode = GetRelatedNode();
-  nsCOMPtr<nsIDOMNode> relatedDOMNode = relatedNode ? relatedNode->AsDOMNode() : nullptr;
-  relatedDOMNode.forget(aRelatedNode);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MutationEvent::GetPrevValue(nsAString& aPrevValue)
+void
+MutationEvent::GetPrevValue(nsAString& aPrevValue) const
 {
   InternalMutationEvent* mutation = mEvent->AsMutationEvent();
   if (mutation->mPrevAttrValue)
     mutation->mPrevAttrValue->ToString(aPrevValue);
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-MutationEvent::GetNewValue(nsAString& aNewValue)
+void
+MutationEvent::GetNewValue(nsAString& aNewValue) const
 {
   InternalMutationEvent* mutation = mEvent->AsMutationEvent();
   if (mutation->mNewAttrValue)
       mutation->mNewAttrValue->ToString(aNewValue);
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-MutationEvent::GetAttrName(nsAString& aAttrName)
+void
+MutationEvent::GetAttrName(nsAString& aAttrName) const
 {
   InternalMutationEvent* mutation = mEvent->AsMutationEvent();
   if (mutation->mAttrName)
       mutation->mAttrName->ToString(aAttrName);
-  return NS_OK;
 }
 
 uint16_t
 MutationEvent::AttrChange()
 {
   return mEvent->AsMutationEvent()->mAttrChange;
 }
 
-NS_IMETHODIMP
-MutationEvent::GetAttrChange(uint16_t* aAttrChange)
+void
+MutationEvent::InitMutationEvent(const nsAString& aType,
+                                 bool aCanBubble, bool aCancelable,
+                                 nsINode* aRelatedNode,
+                                 const nsAString& aPrevValue,
+                                 const nsAString& aNewValue,
+                                 const nsAString& aAttrName,
+                                 uint16_t& aAttrChange,
+                                 ErrorResult& aRv)
 {
-  *aAttrChange = AttrChange();
-  return NS_OK;
-}
+  NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
 
-NS_IMETHODIMP
-MutationEvent::InitMutationEvent(const nsAString& aTypeArg,
-                                 bool aCanBubbleArg,
-                                 bool aCancelableArg,
-                                 nsIDOMNode* aRelatedNodeArg,
-                                 const nsAString& aPrevValueArg,
-                                 const nsAString& aNewValueArg,
-                                 const nsAString& aAttrNameArg,
-                                 uint16_t aAttrChangeArg)
-{
-  NS_ENSURE_TRUE(!mEvent->mFlags.mIsBeingDispatched, NS_OK);
-
-  Event::InitEvent(aTypeArg, aCanBubbleArg, aCancelableArg);
+  Event::InitEvent(aType, aCanBubble, aCancelable);
 
   InternalMutationEvent* mutation = mEvent->AsMutationEvent();
-  mutation->mRelatedNode = aRelatedNodeArg;
-  if (!aPrevValueArg.IsEmpty())
-    mutation->mPrevAttrValue = NS_Atomize(aPrevValueArg);
-  if (!aNewValueArg.IsEmpty())
-    mutation->mNewAttrValue = NS_Atomize(aNewValueArg);
-  if (!aAttrNameArg.IsEmpty()) {
-    mutation->mAttrName = NS_Atomize(aAttrNameArg);
+  mutation->mRelatedNode = aRelatedNode ? aRelatedNode->AsDOMNode() : nullptr;
+  if (!aPrevValue.IsEmpty())
+    mutation->mPrevAttrValue = NS_Atomize(aPrevValue);
+  if (!aNewValue.IsEmpty())
+    mutation->mNewAttrValue = NS_Atomize(aNewValue);
+  if (!aAttrName.IsEmpty()) {
+    mutation->mAttrName = NS_Atomize(aAttrName);
   }
-  mutation->mAttrChange = aAttrChangeArg;
-
-  return NS_OK;
+  mutation->mAttrChange = aAttrChange;
 }
 
 } // namespace dom
 } // namespace mozilla
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
--- a/dom/events/MutationEvent.h
+++ b/dom/events/MutationEvent.h
@@ -5,63 +5,51 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_MutationEvent_h_
 #define mozilla_dom_MutationEvent_h_
 
 #include "mozilla/EventForwards.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/MutationEventBinding.h"
-#include "nsIDOMMutationEvent.h"
 #include "nsINode.h"
 
 namespace mozilla {
 namespace dom {
 
-class MutationEvent : public Event,
-                      public nsIDOMMutationEvent
+class MutationEvent : public Event
 {
 public:
   MutationEvent(EventTarget* aOwner,
                 nsPresContext* aPresContext,
                 InternalMutationEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
 
-  NS_DECL_NSIDOMMUTATIONEVENT
-
-  // Forward to base class
-  NS_FORWARD_TO_EVENT
-
   virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
   {
     return MutationEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
-  // xpidl implementation
-  // GetPrevValue(nsAString& aPrevValue);
-  // GetNewValue(nsAString& aNewValue);
-  // GetAttrName(nsAString& aAttrName);
+  void GetPrevValue(nsAString& aPrevValue) const;
+  void GetNewValue(nsAString& aNewValue) const;
+  void GetAttrName(nsAString& aAttrName) const;
 
   already_AddRefed<nsINode> GetRelatedNode();
 
   uint16_t AttrChange();
 
   void InitMutationEvent(const nsAString& aType,
-                         bool& aCanBubble, bool& aCancelable,
+                         bool aCanBubble, bool aCancelable,
                          nsINode* aRelatedNode,
                          const nsAString& aPrevValue,
                          const nsAString& aNewValue,
                          const nsAString& aAttrName,
-                         uint16_t& aAttrChange, ErrorResult& aRv)
-  {
-    aRv = InitMutationEvent(aType, aCanBubble, aCancelable,
-                            aRelatedNode ? aRelatedNode->AsDOMNode() : nullptr,
-                            aPrevValue, aNewValue, aAttrName, aAttrChange);
-  }
+                         uint16_t& aAttrChange,
+                         ErrorResult& aRv);
 
 protected:
   ~MutationEvent() {}
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/events/SimpleGestureEvent.cpp
+++ b/dom/events/SimpleGestureEvent.cpp
@@ -32,82 +32,48 @@ SimpleGestureEvent::SimpleGestureEvent(E
       nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
   }
 }
 
 NS_IMPL_ADDREF_INHERITED(SimpleGestureEvent, MouseEvent)
 NS_IMPL_RELEASE_INHERITED(SimpleGestureEvent, MouseEvent)
 
 NS_INTERFACE_MAP_BEGIN(SimpleGestureEvent)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMSimpleGestureEvent)
 NS_INTERFACE_MAP_END_INHERITING(MouseEvent)
 
 uint32_t
-SimpleGestureEvent::AllowedDirections()
+SimpleGestureEvent::AllowedDirections() const
 {
   return mEvent->AsSimpleGestureEvent()->mAllowedDirections;
 }
 
-NS_IMETHODIMP
-SimpleGestureEvent::GetAllowedDirections(uint32_t* aAllowedDirections)
-{
-  NS_ENSURE_ARG_POINTER(aAllowedDirections);
-  *aAllowedDirections = AllowedDirections();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
+void
 SimpleGestureEvent::SetAllowedDirections(uint32_t aAllowedDirections)
 {
   mEvent->AsSimpleGestureEvent()->mAllowedDirections = aAllowedDirections;
-  return NS_OK;
 }
 
 uint32_t
-SimpleGestureEvent::Direction()
+SimpleGestureEvent::Direction() const
 {
   return mEvent->AsSimpleGestureEvent()->mDirection;
 }
 
-NS_IMETHODIMP
-SimpleGestureEvent::GetDirection(uint32_t* aDirection)
-{
-  NS_ENSURE_ARG_POINTER(aDirection);
-  *aDirection = Direction();
-  return NS_OK;
-}
-
 double
-SimpleGestureEvent::Delta()
+SimpleGestureEvent::Delta() const
 {
   return mEvent->AsSimpleGestureEvent()->mDelta;
 }
 
-NS_IMETHODIMP
-SimpleGestureEvent::GetDelta(double* aDelta)
-{
-  NS_ENSURE_ARG_POINTER(aDelta);
-  *aDelta = Delta();
-  return NS_OK;
-}
-
 uint32_t
-SimpleGestureEvent::ClickCount()
+SimpleGestureEvent::ClickCount() const
 {
   return mEvent->AsSimpleGestureEvent()->mClickCount;
 }
 
-NS_IMETHODIMP
-SimpleGestureEvent::GetClickCount(uint32_t* aClickCount)
-{
-  NS_ENSURE_ARG_POINTER(aClickCount);
-  *aClickCount = ClickCount();
-  return NS_OK;
-}
-
 void
 SimpleGestureEvent::InitSimpleGestureEvent(const nsAString& aTypeArg,
                                            bool aCanBubbleArg,
                                            bool aCancelableArg,
                                            nsGlobalWindowInner* aViewArg,
                                            int32_t aDetailArg,
                                            int32_t aScreenX,
                                            int32_t aScreenY,
--- a/dom/events/SimpleGestureEvent.h
+++ b/dom/events/SimpleGestureEvent.h
@@ -2,50 +2,44 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_SimpleGestureEvent_h_
 #define mozilla_dom_SimpleGestureEvent_h_
 
-#include "nsIDOMSimpleGestureEvent.h"
 #include "mozilla/dom/MouseEvent.h"
 #include "mozilla/dom/SimpleGestureEventBinding.h"
 #include "mozilla/EventForwards.h"
 
 class nsPresContext;
 
 namespace mozilla {
 namespace dom {
 
-class SimpleGestureEvent : public MouseEvent,
-                           public nsIDOMSimpleGestureEvent
+class SimpleGestureEvent : public MouseEvent
 {
 public:
   SimpleGestureEvent(EventTarget* aOwner,
                      nsPresContext* aPresContext,
                      WidgetSimpleGestureEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
 
-  NS_DECL_NSIDOMSIMPLEGESTUREEVENT
-
-  // Forward to base class
-  NS_FORWARD_TO_MOUSEEVENT
-
   virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
   {
     return SimpleGestureEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
-  uint32_t AllowedDirections();
-  uint32_t Direction();
-  double Delta();
-  uint32_t ClickCount();
+  uint32_t AllowedDirections() const;
+  void SetAllowedDirections(uint32_t aAllowedDirections);
+  uint32_t Direction() const;
+  double Delta() const;
+  uint32_t ClickCount() const;
 
   void InitSimpleGestureEvent(const nsAString& aType,
                               bool aCanBubble,
                               bool aCancelable,
                               nsGlobalWindowInner* aView,
                               int32_t aDetail,
                               int32_t aScreenX,
                               int32_t aScreenY,
--- a/dom/events/TransitionEvent.cpp
+++ b/dom/events/TransitionEvent.cpp
@@ -22,17 +22,16 @@ TransitionEvent::TransitionEvent(EventTa
   }
   else {
     mEventIsInternal = true;
     mEvent->mTime = PR_Now();
   }
 }
 
 NS_INTERFACE_MAP_BEGIN(TransitionEvent)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMTransitionEvent)
 NS_INTERFACE_MAP_END_INHERITING(Event)
 
 NS_IMPL_ADDREF_INHERITED(TransitionEvent, Event)
 NS_IMPL_RELEASE_INHERITED(TransitionEvent, Event)
 
 // static
 already_AddRefed<TransitionEvent>
 TransitionEvent::Constructor(const GlobalObject& aGlobal,
@@ -51,41 +50,32 @@ TransitionEvent::Constructor(const Globa
   internalEvent->mElapsedTime = aParam.mElapsedTime;
   internalEvent->mPseudoElement = aParam.mPseudoElement;
 
   e->SetTrusted(trusted);
   e->SetComposed(aParam.mComposed);
   return e.forget();
 }
 
-NS_IMETHODIMP
-TransitionEvent::GetPropertyName(nsAString& aPropertyName)
+void
+TransitionEvent::GetPropertyName(nsAString& aPropertyName) const
 {
   aPropertyName = mEvent->AsTransitionEvent()->mPropertyName;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-TransitionEvent::GetElapsedTime(float* aElapsedTime)
-{
-  *aElapsedTime = ElapsedTime();
-  return NS_OK;
 }
 
 float
 TransitionEvent::ElapsedTime()
 {
   return mEvent->AsTransitionEvent()->mElapsedTime;
 }
 
-NS_IMETHODIMP
-TransitionEvent::GetPseudoElement(nsAString& aPseudoElement)
+void
+TransitionEvent::GetPseudoElement(nsAString& aPseudoElement) const
 {
   aPseudoElement = mEvent->AsTransitionEvent()->mPseudoElement;
-  return NS_OK;
 }
 
 } // namespace dom
 } // namespace mozilla
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
--- a/dom/events/TransitionEvent.h
+++ b/dom/events/TransitionEvent.h
@@ -4,48 +4,43 @@
  * 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/. */
 #ifndef mozilla_dom_TransitionEvent_h_
 #define mozilla_dom_TransitionEvent_h_
 
 #include "mozilla/EventForwards.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/TransitionEventBinding.h"
-#include "nsIDOMTransitionEvent.h"
 #include "nsStringFwd.h"
 
 namespace mozilla {
 namespace dom {
 
-class TransitionEvent : public Event,
-                        public nsIDOMTransitionEvent
+class TransitionEvent : public Event
 {
 public:
   TransitionEvent(EventTarget* aOwner,
                   nsPresContext* aPresContext,
                   InternalTransitionEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
-  NS_FORWARD_TO_EVENT
-  NS_DECL_NSIDOMTRANSITIONEVENT
 
   static already_AddRefed<TransitionEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const TransitionEventInit& aParam,
               ErrorResult& aRv);
 
   virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
   {
     return TransitionEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
-  // xpidl implementation
-  // GetPropertyName(nsAString& aPropertyName)
-  // GetPseudoElement(nsAString& aPreudoElement)
+  void GetPropertyName(nsAString& aPropertyName) const;
+  void GetPseudoElement(nsAString& aPreudoElement) const;
 
   float ElapsedTime();
 
 protected:
   ~TransitionEvent() {}
 };
 
 } // namespace dom
--- a/dom/events/UIEvent.h
+++ b/dom/events/UIEvent.h
@@ -31,27 +31,30 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(UIEvent, Event)
 
   // nsIDOMUIEvent Interface
   NS_DECL_NSIDOMUIEVENT
 
   // Forward to Event
   NS_FORWARD_TO_EVENT_NO_SERIALIZATION_NO_DUPLICATION
+  using Event::GetCurrentTarget;  // Because the forwarding thing shadows it.
   NS_IMETHOD DuplicatePrivateData() override;
   NS_IMETHOD_(void) Serialize(IPC::Message* aMsg, bool aSerializeInterfaceType) override;
   NS_IMETHOD_(bool) Deserialize(const IPC::Message* aMsg, PickleIterator* aIter) override;
 
 
   static already_AddRefed<UIEvent> Constructor(const GlobalObject& aGlobal,
                                                const nsAString& aType,
                                                const UIEventInit& aParam,
                                                ErrorResult& aRv);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
+  virtual JSObject*
+    WrapObjectInternal(JSContext* aCx,
+                       JS::Handle<JSObject*> aGivenProto) override
   {
     return UIEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   void InitUIEvent(const nsAString& typeArg,
                    bool canBubbleArg,
                    bool cancelableArg,
                    nsGlobalWindowInner* viewArg,
@@ -116,16 +119,17 @@ protected:
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #define NS_FORWARD_TO_UIEVENT                               \
   NS_FORWARD_NSIDOMUIEVENT(UIEvent::)                       \
   NS_FORWARD_TO_EVENT_NO_SERIALIZATION_NO_DUPLICATION       \
+  using Event::GetCurrentTarget;  /* Forwarding shadows */  \
   NS_IMETHOD DuplicatePrivateData() override                \
   {                                                         \
     return UIEvent::DuplicatePrivateData();                 \
   }                                                         \
   NS_IMETHOD_(void) Serialize(IPC::Message* aMsg,           \
                               bool aSerializeInterfaceType) \
     override                                                \
   {                                                         \
--- a/dom/events/VirtualKeyCodeList.h
+++ b/dom/events/VirtualKeyCodeList.h
@@ -1,35 +1,35 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 // IWYU pragma: private, include "mozilla/KeyTextEvents.h"
 
 /**
- * This header file defines all DOM keys which are defined in nsIDOMKeyEvent.
+ * This header file defines all DOM keys which are defined in KeyboardEvent.
  * You must define NS_DEFINE_VK macro before including this.
  *
  * It must have two arguments, (aDOMKeyName, aDOMKeyCode)
  * aDOMKeyName is a key name in DOM.
- * aDOMKeyCode is one of nsIDOMKeyEvent::DOM_VK_*.
+ * aDOMKeyCode is one of mozilla::dom::KeyboardEventBinding::DOM_VK_*.
  *
  * Optionally, you can define NS_DISALLOW_SAME_KEYCODE.
  *
  * If NS_DISALLOW_SAME_KEYCODE is defined, same keyCode won't listed up.
  * This is useful when you create switch-case statement.
  */
 
 #define DEFINE_VK_INTERNAL(aKeyName) \
-  NS_DEFINE_VK(VK##aKeyName, nsIDOMKeyEvent::DOM_VK##aKeyName)
+  NS_DEFINE_VK(VK##aKeyName, mozilla::dom::KeyboardEventBinding::DOM_VK##aKeyName)
 
-// Some keycode may have different name in nsIDOMKeyEvent from its key name.
+// Some keycode may have different name in KeyboardEvent from its key name.
 #define DEFINE_VK_INTERNAL2(aKeyName, aKeyCodeName) \
-  NS_DEFINE_VK(VK##aKeyName, nsIDOMKeyEvent::DOM_VK##aKeyCodeName)
+  NS_DEFINE_VK(VK##aKeyName, mozilla::dom::KeyboardEventBinding::DOM_VK##aKeyCodeName)
 
 DEFINE_VK_INTERNAL(_CANCEL)
 DEFINE_VK_INTERNAL(_HELP)
 DEFINE_VK_INTERNAL2(_BACK, _BACK_SPACE)
 DEFINE_VK_INTERNAL(_TAB)
 DEFINE_VK_INTERNAL(_CLEAR)
 DEFINE_VK_INTERNAL(_RETURN)
 DEFINE_VK_INTERNAL(_SHIFT)
--- a/dom/html/HTMLImageElement.cpp
+++ b/dom/html/HTMLImageElement.cpp
@@ -8,29 +8,29 @@
 #include "mozilla/dom/HTMLImageElementBinding.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsMappedAttributes.h"
 #include "nsSize.h"
 #include "nsDocument.h"
 #include "nsIDocument.h"
-#include "nsIDOMMutationEvent.h"
 #include "nsIScriptContext.h"
 #include "nsIURL.h"
 #include "nsIIOService.h"
 #include "nsIServiceManager.h"
 #include "nsContentUtils.h"
 #include "nsContainerFrame.h"
 #include "nsNodeInfoManager.h"
 #include "mozilla/MouseEvents.h"
 #include "nsContentPolicyUtils.h"
 #include "nsIDOMWindow.h"
 #include "nsFocusManager.h"
 #include "mozilla/dom/HTMLFormElement.h"
+#include "mozilla/dom/MutationEventBinding.h"
 #include "nsAttrValueOrString.h"
 #include "imgLoader.h"
 #include "Image.h"
 
 // Responsive images!
 #include "mozilla/dom/HTMLSourceElement.h"
 #include "mozilla/dom/ResponsiveImageSelector.h"
 
@@ -261,18 +261,18 @@ HTMLImageElement::GetAttributeChangeHint
                                          int32_t aModType) const
 {
   nsChangeHint retval =
     nsGenericHTMLElement::GetAttributeChangeHint(aAttribute, aModType);
   if (aAttribute == nsGkAtoms::usemap ||
       aAttribute == nsGkAtoms::ismap) {
     retval |= nsChangeHint_ReconstructFrame;
   } else if (aAttribute == nsGkAtoms::alt) {
-    if (aModType == nsIDOMMutationEvent::ADDITION ||
-        aModType == nsIDOMMutationEvent::REMOVAL) {
+    if (aModType == MutationEventBinding::ADDITION ||
+        aModType == MutationEventBinding::REMOVAL) {
       retval |= nsChangeHint_ReconstructFrame;
     }
   }
   return retval;
 }
 
 NS_IMETHODIMP_(bool)
 HTMLImageElement::IsAttributeMapped(const nsAtom* aAttribute) const
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -59,17 +59,16 @@
 #include "nsIDOMEvent.h"
 #include "nsIDOMNodeList.h"
 #include "nsLinebreakConverter.h" //to strip out carriage returns
 #include "nsReadableUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsVariant.h"
 
-#include "nsIDOMMutationEvent.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/GenericSpecifiedValuesInlines.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "mozilla/TextEditor.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TouchEvents.h"
--- a/dom/html/ImageDocument.cpp
+++ b/dom/html/ImageDocument.cpp
@@ -10,17 +10,16 @@
 #include "mozilla/dom/HTMLImageElement.h"
 #include "nsRect.h"
 #include "nsIImageLoadingContent.h"
 #include "nsGenericHTMLElement.h"
 #include "nsDocShell.h"
 #include "nsIDocumentInlines.h"
 #include "nsDOMTokenList.h"
 #include "nsIDOMEvent.h"
-#include "nsIDOMKeyEvent.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIDOMEventListener.h"
 #include "nsIFrame.h"
 #include "nsGkAtoms.h"
 #include "imgIRequest.h"
 #include "imgILoader.h"
 #include "imgIContainer.h"
 #include "imgINotificationObserver.h"
--- a/dom/html/nsDOMStringMap.cpp
+++ b/dom/html/nsDOMStringMap.cpp
@@ -6,17 +6,17 @@
 
 #include "nsDOMStringMap.h"
 
 #include "jsapi.h"
 #include "nsError.h"
 #include "nsGenericHTMLElement.h"
 #include "nsContentUtils.h"
 #include "mozilla/dom/DOMStringMapBinding.h"
-#include "nsIDOMMutationEvent.h"
+#include "mozilla/dom/MutationEventBinding.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMStringMap)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMStringMap)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
@@ -251,16 +251,16 @@ bool nsDOMStringMap::AttrToDataProp(cons
 }
 
 void
 nsDOMStringMap::AttributeChanged(nsIDocument *aDocument, Element* aElement,
                                  int32_t aNameSpaceID, nsAtom* aAttribute,
                                  int32_t aModType,
                                  const nsAttrValue* aOldValue)
 {
-  if ((aModType == nsIDOMMutationEvent::ADDITION ||
-       aModType == nsIDOMMutationEvent::REMOVAL) &&
+  if ((aModType == MutationEventBinding::ADDITION ||
+       aModType == MutationEventBinding::REMOVAL) &&
       aNameSpaceID == kNameSpaceID_None &&
       StringBeginsWith(nsDependentAtomString(aAttribute),
                        NS_LITERAL_STRING("data-"))) {
     ++mExpandoAndGeneration.generation;
   }
 }
--- a/dom/html/test/file_fullscreen-esc-exit-inner.html
+++ b/dom/html/test/file_fullscreen-esc-exit-inner.html
@@ -29,17 +29,17 @@ function ok(condition, msg) {
 function is(a, b, msg) {
   parent.is(a, b, msg);
 }
 
 var escKeyReceived = false;
 var escKeySent = false;
 
 function keyHandler(event) {
-  if (escKeyReceived == SpecialPowers.Ci.nsIDOMKeyEvent.DOM_VK_ESC) {
+  if (escKeyReceived == KeyboardEvent.DOM_VK_ESC) {
     escKeyReceived = true;
   }
 }
 
 window.addEventListener("keydown", keyHandler, true);
 window.addEventListener("keyup", keyHandler, true);
 window.addEventListener("keypress", keyHandler, true);
 
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -733,17 +733,17 @@ interface nsIDOMWindowUtils : nsISupport
    *
    * Cannot be accessed from unprivileged context (not
    * content-accessible) Will throw a DOM security error if called
    * without chrome privileges.
    *
    * @param aType event type
    * @param aX x offset in CSS pixels
    * @param aY y offset in CSS pixels
-   * @param aDirection direction, using constants defined in nsIDOMSimpleGestureEvent
+   * @param aDirection direction, using constants defined in SimpleGestureEvent.webidl
    * @param aDelta  amount of magnification or rotation for magnify and rotation events
    * @param aModifiers modifiers pressed, using constants defined in nsIDOMNSEvent
    * @param aClickCount For tap gestures, the number of taps.
    */
   void sendSimpleGestureEvent(in AString aType,
                               in float aX,
                               in float aY,
                               in unsigned long aDirection,
--- a/dom/interfaces/base/nsITextInputProcessor.idl
+++ b/dom/interfaces/base/nsITextInputProcessor.idl
@@ -1,16 +1,16 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
-interface nsIDOMKeyEvent;
+interface nsIDOMEvent;
 interface mozIDOMWindow;
 interface nsITextInputProcessorCallback;
 
 /**
  * An nsITextInputProcessor instance is associated with a top level widget which
  * handles native IME.  It's associated by calling beginInputTransaction() or
  * beginInputTransactionForTests().  While an instance has composition, nobody
  * can steal the rights to make composition on the top level widget.  In other
@@ -306,17 +306,17 @@ interface nsITextInputProcessor : nsISup
    *                        dispatches only keydown event first.  Otherwise,
    *                        dispatches keydown first and keyup at last.
    * @param aKeyFlags       See KEY_* constants.
    * @return                Returns true if composition starts normally.
    *                        Otherwise, returns false because it might be
    *                        canceled by the web application.
    */
   [optional_argc]
-    boolean startComposition([optional] in nsIDOMKeyEvent aKeyboardEvent,
+    boolean startComposition([optional] in nsIDOMEvent aKeyboardEvent,
                              [optional] in unsigned long aKeyFlags);
 
   /**
    * Set new composition string.  Pending composition will be flushed by
    * a call of flushPendingComposition().  However, if the new composition
    * string isn't empty, you need to call appendClauseToPendingComposition() to
    * fill all characters of aString with one or more clauses before flushing.
    * Note that if you need to commit or cancel composition, use
@@ -397,31 +397,31 @@ interface nsITextInputProcessor : nsISup
    * @return                Returns true if there is a composition already or
    *                        starting composition automatically.
    *                        Otherwise, i.e., if it cannot start composition
    *                        automatically, e.g., canceled by web apps, returns
    *                        false.
    */
   [optional_argc]
     boolean flushPendingComposition(
-      [optional] in nsIDOMKeyEvent aKeyboardEvent,
+      [optional] in nsIDOMEvent aKeyboardEvent,
       [optional] in unsigned long aKeyFlags);
 
   /**
    * commitComposition() will commit composition with the last composition
    * string.  If there is no composition, this will throw an exception.
    *
    * @param aKeyboardEvent  Key event which causes the commit composition.
    *                        If its type value is "keydown", this method
    *                        dispatches only keydown event first.  Otherwise,
    *                        dispatches keydown first and keyup at last.
    * @param aKeyFlags       See KEY_* constants.
    */
   [optional_argc]
-    void commitComposition([optional] in nsIDOMKeyEvent aKeyboardEvent,
+    void commitComposition([optional] in nsIDOMEvent aKeyboardEvent,
                            [optional] in unsigned long aKeyFlags);
 
   /**
    * commitCompositionWith() will commit composition with the specific string.
    * If there is no composition, this will start composition and commit it
    * with the specified string.
    *
    * @param aCommitString   The string to be committed.
@@ -433,17 +433,17 @@ interface nsITextInputProcessor : nsISup
    * @return                Returns true if there is a composition already or
    *                        starting composition automatically.
    *                        Otherwise, i.e., if it cannot start composition
    *                        automatically, e.g., canceled by web apps, returns
    *                        false.
    */
   [optional_argc]
     boolean commitCompositionWith(in DOMString aCommitString,
-                                  [optional] in nsIDOMKeyEvent aKeyboardEvent,
+                                  [optional] in nsIDOMEvent aKeyboardEvent,
                                   [optional] in unsigned long aKeyFlags);
 
   /**
    * cancelComposition() will cancel composition.  This is for now the same as
    * calling commitComposition("").  However, in the future, this might work
    * better.  If your IME needs to cancel composition, use this instead of
    * commitComposition().
    *
@@ -452,17 +452,17 @@ interface nsITextInputProcessor : nsISup
    *
    * @param aKeyboardEvent  Key event which causes the canceling composition.
    *                        If its type value is "keydown", this method
    *                        dispatches only keydown event first.  Otherwise,
    *                        dispatches keydown first and keyup at last.
    * @param aKeyFlags       See KEY_* constants.
    */
   [optional_argc]
-    void cancelComposition([optional] in nsIDOMKeyEvent aKeyboardEvent,
+    void cancelComposition([optional] in nsIDOMEvent aKeyboardEvent,
                            [optional] in unsigned long aKeyFlags);
 
   // Specifying KEY_DEFAULT_PREVENTED can dispatch key events whose
   // defaultPrevented are true.  Note that if this is specified, keypress event
   // won't be fired.
   const unsigned long KEY_DEFAULT_PREVENTED                        = 0x00000001;
   // If KEY_NON_PRINTABLE_KEY is specified and the .key value isn't valid
   // key name, the methods will throws an exception.  In other words, this
@@ -542,24 +542,24 @@ interface nsITextInputProcessor : nsISup
    *                        this case.
    *                        KEYPRESS_IS_CONSUMED, if the keypress event(s) is
    *                        consumed when dispatched.
    *                        Note that keypress event is always consumed by
    *                        native code for the printable keys (indicating the
    *                        default action has been taken).
    */
   [optional_argc]
-    unsigned long keydown(in nsIDOMKeyEvent aKeyboardEvent,
+    unsigned long keydown(in nsIDOMEvent aKeyboardEvent,
                           [optional] in unsigned long aKeyFlags);
 
   /**
    * Similar to keydown(), but this dispatches only a keyup event.
    */
   [optional_argc]
-    boolean keyup(in nsIDOMKeyEvent aKeyboardEvent,
+    boolean keyup(in nsIDOMEvent aKeyboardEvent,
                   [optional] in unsigned long aKeyFlags);
 
   /**
    * getModifierState() returns modifier state managed by this instance.
    *
    * @param aModifier       One of modifier key names.  This doesn't support
    *                        virtual modifiers like "Accel".
    * @return                true if the modifier key is active.  Otherwise,
--- a/dom/interfaces/events/moz.build
+++ b/dom/interfaces/events/moz.build
@@ -3,34 +3,27 @@
 # 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/.
 
 with Files("**"):
     BUG_COMPONENT = ("Core", "DOM: Events")
 
 XPIDL_SOURCES += [
-    'nsIDOMAnimationEvent.idl',
-    'nsIDOMBeforeUnloadEvent.idl',
     'nsIDOMClipboardEvent.idl',
-    'nsIDOMCommandEvent.idl',
     'nsIDOMCustomEvent.idl',
     'nsIDOMDataTransfer.idl',
     'nsIDOMDragEvent.idl',
     'nsIDOMEvent.idl',
     'nsIDOMEventListener.idl',
     'nsIDOMEventTarget.idl',
     'nsIDOMFocusEvent.idl',
-    'nsIDOMKeyEvent.idl',
     'nsIDOMMouseEvent.idl',
     'nsIDOMMouseScrollEvent.idl',
-    'nsIDOMMutationEvent.idl',
     'nsIDOMNotifyPaintEvent.idl',
     'nsIDOMNSEvent.idl',
     'nsIDOMScrollAreaEvent.idl',
-    'nsIDOMSimpleGestureEvent.idl',
-    'nsIDOMTransitionEvent.idl',
     'nsIDOMUIEvent.idl',
     'nsIDOMWheelEvent.idl',
 ]
 
 XPIDL_MODULE = 'dom_events'
 
deleted file mode 100644
--- a/dom/interfaces/events/nsIDOMAnimationEvent.idl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-/**
- * Animation events are defined in:
- * http://www.w3.org/TR/css3-animations/#animation-events-
- * http://dev.w3.org/csswg/css3-animations/#animation-events-
- */
-
-[builtinclass, uuid(ce6d1db3-53b8-4ade-9baa-70f4947200a2)]
-interface nsIDOMAnimationEvent : nsISupports
-{
-  readonly attribute DOMString          animationName;
-  readonly attribute float              elapsedTime;
-  readonly attribute DOMString          pseudoElement;
-};
deleted file mode 100644
--- a/dom/interfaces/events/nsIDOMBeforeUnloadEvent.idl
+++ /dev/null
@@ -1,26 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-/**
- * The nsIDOMBeforeUnloadEvent interface is the interface for events
- * sent to handlers of the "beforeunload" event. This event is
- * non-standard. Interface derived from Microsoft IE's event
- * implementation.
- *
- * http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/events.asp
- *
- */
-
-[builtinclass, uuid(26c83933-a5a4-455e-8c46-69fa24dfa991)]
-interface nsIDOMBeforeUnloadEvent : nsISupports
-{
-  /**
-   * Attribute used to pass back a return value from a beforeunload
-   * handler
-   */
-           attribute DOMString          returnValue;
-};
deleted file mode 100644
--- a/dom/interfaces/events/nsIDOMCommandEvent.idl
+++ /dev/null
@@ -1,17 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-[builtinclass, uuid(73a50e55-3eaa-4a38-a588-9b68a6d65032)]
-interface nsIDOMCommandEvent : nsISupports
-{
-  readonly attribute DOMString command;
-
-  void initCommandEvent(in DOMString typeArg,
-                        in boolean canBubbleArg,
-                        in boolean canCancelArg,
-                        in DOMString command);
-};
deleted file mode 100644
--- a/dom/interfaces/events/nsIDOMKeyEvent.idl
+++ /dev/null
@@ -1,258 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsIDOMUIEvent.idl"
-
-[builtinclass, uuid(2e52eb99-670d-469a-b51f-8efee2dd091d)]
-interface nsIDOMKeyEvent : nsIDOMUIEvent
-{
-  const unsigned long DOM_VK_CANCEL         = 0x03;
-  const unsigned long DOM_VK_HELP           = 0x06;
-  const unsigned long DOM_VK_BACK_SPACE     = 0x08;
-  const unsigned long DOM_VK_TAB            = 0x09;
-  const unsigned long DOM_VK_CLEAR          = 0x0C;
-  const unsigned long DOM_VK_RETURN         = 0x0D;
-  // DOM_VK_ENTER has been never used for representing native key events.
-  // Therefore, it's removed for preventing developers being confused.
-  // const unsigned long DOM_VK_ENTER          = 0x0E;
-  const unsigned long DOM_VK_SHIFT          = 0x10;
-  const unsigned long DOM_VK_CONTROL        = 0x11;
-  const unsigned long DOM_VK_ALT            = 0x12;
-  const unsigned long DOM_VK_PAUSE          = 0x13;
-  const unsigned long DOM_VK_CAPS_LOCK      = 0x14;
-  const unsigned long DOM_VK_KANA           = 0x15;
-  const unsigned long DOM_VK_HANGUL         = 0x15;
-  const unsigned long DOM_VK_EISU           = 0x16; // Japanese Mac keyboard only
-  const unsigned long DOM_VK_JUNJA          = 0x17;
-  const unsigned long DOM_VK_FINAL          = 0x18;
-  const unsigned long DOM_VK_HANJA          = 0x19;
-  const unsigned long DOM_VK_KANJI          = 0x19;
-  const unsigned long DOM_VK_ESCAPE         = 0x1B;
-  const unsigned long DOM_VK_CONVERT        = 0x1C;
-  const unsigned long DOM_VK_NONCONVERT     = 0x1D;
-  const unsigned long DOM_VK_ACCEPT         = 0x1E;
-  const unsigned long DOM_VK_MODECHANGE     = 0x1F;
-  const unsigned long DOM_VK_SPACE          = 0x20;
-  const unsigned long DOM_VK_PAGE_UP        = 0x21;
-  const unsigned long DOM_VK_PAGE_DOWN      = 0x22;
-  const unsigned long DOM_VK_END            = 0x23;
-  const unsigned long DOM_VK_HOME           = 0x24;
-  const unsigned long DOM_VK_LEFT           = 0x25;
-  const unsigned long DOM_VK_UP             = 0x26;
-  const unsigned long DOM_VK_RIGHT          = 0x27;
-  const unsigned long DOM_VK_DOWN           = 0x28;
-  const unsigned long DOM_VK_SELECT         = 0x29;
-  const unsigned long DOM_VK_PRINT          = 0x2A;
-  const unsigned long DOM_VK_EXECUTE        = 0x2B;
-  const unsigned long DOM_VK_PRINTSCREEN    = 0x2C;
-  const unsigned long DOM_VK_INSERT         = 0x2D;
-  const unsigned long DOM_VK_DELETE         = 0x2E;
-
-  // DOM_VK_0 - DOM_VK_9 match their ascii values
-  const unsigned long DOM_VK_0              = 0x30;
-  const unsigned long DOM_VK_1              = 0x31;
-  const unsigned long DOM_VK_2              = 0x32;
-  const unsigned long DOM_VK_3              = 0x33;
-  const unsigned long DOM_VK_4              = 0x34;
-  const unsigned long DOM_VK_5              = 0x35;
-  const unsigned long DOM_VK_6              = 0x36;
-  const unsigned long DOM_VK_7              = 0x37;
-  const unsigned long DOM_VK_8              = 0x38;
-  const unsigned long DOM_VK_9              = 0x39;
-
-  const unsigned long DOM_VK_COLON          = 0x3A;
-  const unsigned long DOM_VK_SEMICOLON      = 0x3B;
-  const unsigned long DOM_VK_LESS_THAN      = 0x3C;
-  const unsigned long DOM_VK_EQUALS         = 0x3D;
-  const unsigned long DOM_VK_GREATER_THAN   = 0x3E;
-  const unsigned long DOM_VK_QUESTION_MARK  = 0x3F;
-  const unsigned long DOM_VK_AT             = 0x40;
-
-  // DOM_VK_A - DOM_VK_Z match their ascii values
-  const unsigned long DOM_VK_A              = 0x41;
-  const unsigned long DOM_VK_B              = 0x42;
-  const unsigned long DOM_VK_C              = 0x43;
-  const unsigned long DOM_VK_D              = 0x44;
-  const unsigned long DOM_VK_E              = 0x45;
-  const unsigned long DOM_VK_F              = 0x46;
-  const unsigned long DOM_VK_G              = 0x47;
-  const unsigned long DOM_VK_H              = 0x48;
-  const unsigned long DOM_VK_I              = 0x49;
-  const unsigned long DOM_VK_J              = 0x4A;
-  const unsigned long DOM_VK_K              = 0x4B;
-  const unsigned long DOM_VK_L              = 0x4C;
-  const unsigned long DOM_VK_M              = 0x4D;
-  const unsigned long DOM_VK_N              = 0x4E;
-  const unsigned long DOM_VK_O              = 0x4F;
-  const unsigned long DOM_VK_P              = 0x50;
-  const unsigned long DOM_VK_Q              = 0x51;
-  const unsigned long DOM_VK_R              = 0x52;
-  const unsigned long DOM_VK_S              = 0x53;
-  const unsigned long DOM_VK_T              = 0x54;
-  const unsigned long DOM_VK_U              = 0x55;
-  const unsigned long DOM_VK_V              = 0x56;
-  const unsigned long DOM_VK_W              = 0x57;
-  const unsigned long DOM_VK_X              = 0x58;
-  const unsigned long DOM_VK_Y              = 0x59;
-  const unsigned long DOM_VK_Z              = 0x5A;
-
-  const unsigned long DOM_VK_WIN            = 0x5B;
-  const unsigned long DOM_VK_CONTEXT_MENU   = 0x5D;
-  const unsigned long DOM_VK_SLEEP          = 0x5F;
-
-  // Numpad keys
-  const unsigned long DOM_VK_NUMPAD0        = 0x60;
-  const unsigned long DOM_VK_NUMPAD1        = 0x61;
-  const unsigned long DOM_VK_NUMPAD2        = 0x62;
-  const unsigned long DOM_VK_NUMPAD3        = 0x63;
-  const unsigned long DOM_VK_NUMPAD4        = 0x64;
-  const unsigned long DOM_VK_NUMPAD5        = 0x65;
-  const unsigned long DOM_VK_NUMPAD6        = 0x66;
-  const unsigned long DOM_VK_NUMPAD7        = 0x67;
-  const unsigned long DOM_VK_NUMPAD8        = 0x68;
-  const unsigned long DOM_VK_NUMPAD9        = 0x69;
-  const unsigned long DOM_VK_MULTIPLY       = 0x6A;
-  const unsigned long DOM_VK_ADD            = 0x6B;
-  const unsigned long DOM_VK_SEPARATOR      = 0x6C;
-  const unsigned long DOM_VK_SUBTRACT       = 0x6D;
-  const unsigned long DOM_VK_DECIMAL        = 0x6E;
-  const unsigned long DOM_VK_DIVIDE         = 0x6F;
-
-  const unsigned long DOM_VK_F1             = 0x70;
-  const unsigned long DOM_VK_F2             = 0x71;
-  const unsigned long DOM_VK_F3             = 0x72;
-  const unsigned long DOM_VK_F4             = 0x73;
-  const unsigned long DOM_VK_F5             = 0x74;
-  const unsigned long DOM_VK_F6             = 0x75;
-  const unsigned long DOM_VK_F7             = 0x76;
-  const unsigned long DOM_VK_F8             = 0x77;
-  const unsigned long DOM_VK_F9             = 0x78;
-  const unsigned long DOM_VK_F10            = 0x79;
-  const unsigned long DOM_VK_F11            = 0x7A;
-  const unsigned long DOM_VK_F12            = 0x7B;
-  const unsigned long DOM_VK_F13            = 0x7C;
-  const unsigned long DOM_VK_F14            = 0x7D;
-  const unsigned long DOM_VK_F15            = 0x7E;
-  const unsigned long DOM_VK_F16            = 0x7F;
-  const unsigned long DOM_VK_F17            = 0x80;
-  const unsigned long DOM_VK_F18            = 0x81;
-  const unsigned long DOM_VK_F19            = 0x82;
-  const unsigned long DOM_VK_F20            = 0x83;
-  const unsigned long DOM_VK_F21            = 0x84;
-  const unsigned long DOM_VK_F22            = 0x85;
-  const unsigned long DOM_VK_F23            = 0x86;
-  const unsigned long DOM_VK_F24            = 0x87;
-
-  const unsigned long DOM_VK_NUM_LOCK       = 0x90;
-  const unsigned long DOM_VK_SCROLL_LOCK    = 0x91;
-
-  // OEM specific virtual keyCode of Windows should pass through DOM keyCode
-  // for compatibility with the other web browsers on Windows.
-  const unsigned long DOM_VK_WIN_OEM_FJ_JISHO   = 0x92;
-  const unsigned long DOM_VK_WIN_OEM_FJ_MASSHOU = 0x93;
-  const unsigned long DOM_VK_WIN_OEM_FJ_TOUROKU = 0x94;
-  const unsigned long DOM_VK_WIN_OEM_FJ_LOYA    = 0x95;
-  const unsigned long DOM_VK_WIN_OEM_FJ_ROYA    = 0x96;
-
-  const unsigned long DOM_VK_CIRCUMFLEX     = 0xA0;
-  const unsigned long DOM_VK_EXCLAMATION    = 0xA1;
-  const unsigned long DOM_VK_DOUBLE_QUOTE   = 0xA2;
-  const unsigned long DOM_VK_HASH           = 0xA3;
-  const unsigned long DOM_VK_DOLLAR         = 0xA4;
-  const unsigned long DOM_VK_PERCENT        = 0xA5;
-  const unsigned long DOM_VK_AMPERSAND      = 0xA6;
-  const unsigned long DOM_VK_UNDERSCORE     = 0xA7;
-  const unsigned long DOM_VK_OPEN_PAREN     = 0xA8;
-  const unsigned long DOM_VK_CLOSE_PAREN    = 0xA9;
-  const unsigned long DOM_VK_ASTERISK       = 0xAA;
-  const unsigned long DOM_VK_PLUS           = 0xAB;
-  const unsigned long DOM_VK_PIPE           = 0xAC;
-  const unsigned long DOM_VK_HYPHEN_MINUS   = 0xAD;
-
-  const unsigned long DOM_VK_OPEN_CURLY_BRACKET  = 0xAE;
-  const unsigned long DOM_VK_CLOSE_CURLY_BRACKET = 0xAF;
-
-  const unsigned long DOM_VK_TILDE          = 0xB0;
-
-  const unsigned long DOM_VK_VOLUME_MUTE    = 0xB5;
-  const unsigned long DOM_VK_VOLUME_DOWN    = 0xB6;
-  const unsigned long DOM_VK_VOLUME_UP      = 0xB7;
-
-  const unsigned long DOM_VK_COMMA          = 0xBC;
-  const unsigned long DOM_VK_PERIOD         = 0xBE;
-  const unsigned long DOM_VK_SLASH          = 0xBF;
-  const unsigned long DOM_VK_BACK_QUOTE     = 0xC0;
-  const unsigned long DOM_VK_OPEN_BRACKET   = 0xDB; // square bracket
-  const unsigned long DOM_VK_BACK_SLASH     = 0xDC;
-  const unsigned long DOM_VK_CLOSE_BRACKET  = 0xDD; // square bracket
-  const unsigned long DOM_VK_QUOTE          = 0xDE; // Apostrophe
-
-  const unsigned long DOM_VK_META           = 0xE0;
-  const unsigned long DOM_VK_ALTGR          = 0xE1;
-
-  // OEM specific virtual keyCode of Windows should pass through DOM keyCode
-  // for compatibility with the other web browsers on Windows.
-  const unsigned long DOM_VK_WIN_ICO_HELP    = 0xE3;
-  const unsigned long DOM_VK_WIN_ICO_00      = 0xE4;
-  const unsigned long DOM_VK_WIN_ICO_CLEAR   = 0xE6;
-  const unsigned long DOM_VK_WIN_OEM_RESET   = 0xE9;
-  const unsigned long DOM_VK_WIN_OEM_JUMP    = 0xEA;
-  const unsigned long DOM_VK_WIN_OEM_PA1     = 0xEB;
-  const unsigned long DOM_VK_WIN_OEM_PA2     = 0xEC;
-  const unsigned long DOM_VK_WIN_OEM_PA3     = 0xED;
-  const unsigned long DOM_VK_WIN_OEM_WSCTRL  = 0xEE;
-  const unsigned long DOM_VK_WIN_OEM_CUSEL   = 0xEF;
-  const unsigned long DOM_VK_WIN_OEM_ATTN    = 0xF0;
-  const unsigned long DOM_VK_WIN_OEM_FINISH  = 0xF1;
-  const unsigned long DOM_VK_WIN_OEM_COPY    = 0xF2;
-  const unsigned long DOM_VK_WIN_OEM_AUTO    = 0xF3;
-  const unsigned long DOM_VK_WIN_OEM_ENLW    = 0xF4;
-  const unsigned long DOM_VK_WIN_OEM_BACKTAB = 0xF5;
-
-  // Following keys are not used on most keyboards.  However, for compatibility
-  // with other browsers on Windows, we should define them.
-  const unsigned long DOM_VK_ATTN           = 0xF6;
-  const unsigned long DOM_VK_CRSEL          = 0xF7;
-  const unsigned long DOM_VK_EXSEL          = 0xF8;
-  const unsigned long DOM_VK_EREOF          = 0xF9;
-  const unsigned long DOM_VK_PLAY           = 0xFA;
-  const unsigned long DOM_VK_ZOOM           = 0xFB;
-  const unsigned long DOM_VK_PA1            = 0xFD;
-
-  // OEM specific virtual keyCode of Windows should pass through DOM keyCode
-  // for compatibility with the other web browsers on Windows.
-  const unsigned long DOM_VK_WIN_OEM_CLEAR  = 0xFE;
-
-  readonly attribute unsigned long    charCode;
-  readonly attribute unsigned long    keyCode;
-
-  readonly attribute boolean          altKey;
-  readonly attribute boolean          ctrlKey;
-  readonly attribute boolean          shiftKey;
-  readonly attribute boolean          metaKey;
-
-  void                      initKeyEvent(in DOMString typeArg,
-                                         in boolean canBubbleArg,
-                                         in boolean cancelableArg,
-                                         in mozIDOMWindow viewArg,
-                                         in boolean ctrlKeyArg,
-                                         in boolean altKeyArg,
-                                         in boolean shiftKeyArg,
-                                         in boolean metaKeyArg,
-                                         in unsigned long keyCodeArg,
-                                         in unsigned long charCodeArg);
-
-  bool getModifierState(in DOMString keyArg);
-
-  const unsigned long DOM_KEY_LOCATION_STANDARD = 0x00;
-  const unsigned long DOM_KEY_LOCATION_LEFT     = 0x01;
-  const unsigned long DOM_KEY_LOCATION_RIGHT    = 0x02;
-  const unsigned long DOM_KEY_LOCATION_NUMPAD   = 0x03;
-
-  readonly attribute unsigned long location;
-  readonly attribute boolean       repeat;
-
-  readonly attribute DOMString key;
-};
deleted file mode 100644
--- a/dom/interfaces/events/nsIDOMMutationEvent.idl
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-#include "nsIDOMNode.idl"
-
-[builtinclass, uuid(30c9997f-bc4c-4890-b890-febb6ae3051b)]
-interface nsIDOMMutationEvent : nsISupports
-{
-  const unsigned short      MODIFICATION       = 1;
-  const unsigned short      ADDITION           = 2;
-  const unsigned short      REMOVAL            = 3;
-  const unsigned short      SMIL               = 4;
-
-  readonly attribute nsIDOMNode       relatedNode;
-  readonly attribute DOMString        prevValue;
-  readonly attribute DOMString        newValue;
-  readonly attribute DOMString        attrName;
-  readonly attribute unsigned short   attrChange;
-  void                      initMutationEvent(in DOMString typeArg,
-                                              in boolean canBubbleArg,
-                                              in boolean cancelableArg,
-                                              in nsIDOMNode relatedNodeArg,
-                                              in DOMString prevValueArg,
-                                              in DOMString newValueArg,
-                                              in DOMString attrNameArg,
-											  in unsigned short attrChangeArg);
-};
deleted file mode 100644
--- a/dom/interfaces/events/nsIDOMSimpleGestureEvent.idl
+++ /dev/null
@@ -1,182 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-#include "nsIDOMMouseEvent.idl"
-
-/**
- * The nsIDOMSimpleGestureEvent interface is the datatype for all
- * Mozilla-specific simple gesture events in the Document Object Model.
- *
- * The following events are generated:
- *
- * MozSwipeGestureMayStart - Generated when the user starts a horizontal
- * swipe across the input device, but before we know whether the user
- * is actually scrolling past a scroll edge.
- * This event asks two questions:  Should a swipe really be started, and
- * in which directions should the user be able to swipe?  The first
- * question is answered by event listeners by calling or not calling
- * preventDefault() on the event.  Since a swipe swallows all scroll
- * events, the default action of the swipe start event is *not* to
- * start a swipe. Call preventDefault() if you want a swipe to be
- * started. Doing so won't necessarily result in a swipe being started,
- * it only communicates an intention. Once Gecko determines whether a
- * swipe should actually be started, it will send a MozSwipeGestureStart
- * event.
- * The second question (swipe-able directions) is answered in the
- * allowedDirections field.
- *
- * MozSwipeGestureStart - This event signals the start of a swipe.
- * It guarantees a future MozSwipeGestureEnd event that will signal
- * the end of a swipe animation.
- *
- * MozSwipeGestureUpdate - Generated periodically while the user is
- * continuing a horizontal swipe gesture.  The "delta" value represents
- * the current absolute gesture amount.  This event may even be sent
- * after a MozSwipeGesture event fired in order to allow for fluid
- * completion of a swipe animation.  The direction value is meaningless
- * on swipe update events.
- *
- * MozSwipeGestureEnd - Generated when the swipe animation is completed.
- *
- * MozSwipeGesture - Generated when the user releases a swipe across
- * across the input device.  This event signals that the actual swipe
- * operation is complete, even though the animation might not be finished
- * yet.  This event can be sent without accompanying start / update / end
- * events, and it can also be handled on its own if the consumer doesn't
- * want to handle swipe animation events.
- * Only the direction value has any significance, the delta value is
- * meaningless.
- *
- * MozMagnifyGestureStart - Generated when the user begins the magnify
- * ("pinch") gesture.  The "delta" value represents the initial
- * movement.
- *
- * MozMagnifyGestureUpdate - Generated periodically while the user is
- * continuing the magnify ("pinch") gesture.  The "delta" value
- * represents the movement since the last MozMagnifyGestureStart or
- * MozMagnifyGestureUpdate event.
- *
- * MozMagnifyGesture - Generated when the user has completed the
- * magnify ("pinch") gesture.  If you only want to receive a single
- * event when the magnify gesture is complete, you only need to hook
- * this event and can safely ignore the MozMagnifyGestureStart and the
- * MozMagnifyGestureUpdate events. The "delta" value is the cumulative
- * amount represented by the user's gesture.
- *
- * MozRotateGestureStart - Generated when the user begins the rotation
- * gesture.  The "delta" value represents the initial rotation.
- *
- * MozRotateGestureUpdate - Generated periodically while the user is
- * continuing the rotation gesture.  The "delta" value represents the
- * rotation since the last MozRotateGestureStart or
- * MozRotateGestureUpdate event.
- *
- * MozRotateGesture - Generated when the user has completed the
- * rotation gesture.  If you only want to receive a single event when
- * the rotation gesture is complete, you only need to hook this event
- * and can safely ignore the MozRotateGestureStart and the
- * MozRotateGestureUpdate events.  The "delta" value is the cumulative
- * amount of rotation represented by the user's gesture.
- *
- * MozTapGesture - Generated when the user executes a two finger
- * tap gesture on the input device. Client coordinates contain the
- * center point of the tap.
- * (XXX On OS X, only Lion (10.7) and up)
- *
- * MozPressTapGesture - Generated when the user executes a press
- * and tap two finger gesture (first finger down, second finger down,
- * second finger up, first finger up) on the input device.
- * Client coordinates contain the center pivot point of the action.
- * (XXX Not implemented on Mac)
- *
- * MozEdgeUIGesture - Generated when the user swipes the display to
- * invoke edge ui.
- * (XXX Win8 only)
- *
- * Default behavior:
- *
- * Some operating systems support default behaviors for gesture events
- * when they are not handled by the application. Consumers should
- * use event.preventDefault() to prevent default behavior when
- * consuming events.
- */
-
-[builtinclass, uuid(c397f9a2-4266-4291-b282-3efd6d7afc57)]
-interface nsIDOMSimpleGestureEvent : nsIDOMMouseEvent
-{
-  /* Swipe direction constants */
-  const unsigned long DIRECTION_UP = 1;
-  const unsigned long DIRECTION_DOWN = 2;
-  const unsigned long DIRECTION_LEFT = 4;
-  const unsigned long DIRECTION_RIGHT = 8;
-
-  /* Rotational direction constants */
-  const unsigned long ROTATION_COUNTERCLOCKWISE = 1;
-  const unsigned long ROTATION_CLOCKWISE = 2;
-
-  /* Read-write value for swipe events.
-   *
-   * Reports the directions that can be swiped to; multiple directions
-   * should be OR'ed together.
-   *
-   * The allowedDirections field is designed to be set on SwipeGestureMayStart
-   * events by event listeners.  Its value after event dispatch determines
-   * the behavior of the swipe animation that might be about to begin.
-   * Specifically, if the user swipes in a direction that can't be swiped
-   * to, the animation will have a bounce effect.
-   * Future SwipeGestureUpdate, SwipeGesture and SwipeGestureEnd events
-   * will carry the allowDirections value that was set on the SwipeMayStart
-   * event.  Changing this field on non-SwipeGestureMayStart events doesn't
-   * have any effect.
-   */
-  attribute unsigned long allowedDirections;
-
-  /* Direction of a gesture. Diagonals are indicated by OR'ing the
-   * applicable constants together.
-   *
-   * Swipes gestures may occur in any direction.
-   *
-   * Magnify gestures do not have a direction.
-   *
-   * Rotation gestures will be either ROTATION_COUNTERCLOCKWISE or
-   * ROTATION_CLOCKWISE.
-   */
-  readonly attribute unsigned long direction;
-
-  /* Delta value for magnify, rotate and swipe gestures.
-   *
-   * For rotation, the value is in degrees and is positive for
-   * clockwise rotation and negative for counterclockwise
-   * rotation.
-   *
-   * For magnification, the value will be positive for a "zoom in"
-   * (i.e, increased magnification) and negative for a "zoom out"
-   * (i.e., decreased magnification).  The particular units
-   * represented by the "delta" are currently implementation specific.
-   *
-   * XXX - The units for measuring magnification are currently
-   * unspecified because the units used by Mac OS X are currently
-   * undocumented.  The values are typically in the range of 0.0 to
-   * 100.0, but it is only safe currently to rely on the delta being
-   * positive or negative.
-   *
-   * For swipe start, update and end events, the value is a fraction
-   * of one "page".  If the resulting swipe will have DIRECTION_LEFT, the
-   * delta value will be positive; for DIRECTION_RIGHT, delta is negative.
-   * If this seems backwards to you, look at it this way:  If the current
-   * page is pushed to the right during the animation (positive delta),
-   * the page left to the current page will be visible after the swipe
-   * (DIRECTION_LEFT).
-   *
-   * Units on Windows represent the difference between the initial
-   * and current/final width between the two touch points on the input
-   * device and are measured in pixels.
-   */
-  readonly attribute double delta;
-
-  /* Click count value for taps. */
-  readonly attribute unsigned long clickCount;
-};
deleted file mode 100644
--- a/dom/interfaces/events/nsIDOMTransitionEvent.idl
+++ /dev/null
@@ -1,19 +0,0 @@
-/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-/**
- * Transition events are defined in:
- * http://www.w3.org/TR/css3-transitions/#transition-events-
- * http://dev.w3.org/csswg/css3-transitions/#transition-events-
- */
-
-[builtinclass, uuid(ee3499bf-0f14-4bb6-829c-19ad24fd4a85)]
-interface nsIDOMTransitionEvent : nsISupports {
-  readonly attribute DOMString           propertyName;
-  readonly attribute float               elapsedTime;
-  readonly attribute DOMString           pseudoElement;
-};
--- a/dom/ipc/ContentPrefs.cpp
+++ b/dom/ipc/ContentPrefs.cpp
@@ -122,16 +122,17 @@ const char* mozilla::dom::ContentPrefs::
   "javascript.options.ion.threshold",
   "javascript.options.ion.unsafe_eager_compilation",
   "javascript.options.jit.full_debug_checks",
   "javascript.options.native_regexp",
   "javascript.options.parallel_parsing",
   "javascript.options.shared_memory",
   "javascript.options.spectre.index_masking",
   "javascript.options.spectre.string_mitigations",
+  "javascript.options.spectre.value_masking",
   "javascript.options.streams",
   "javascript.options.strict",
   "javascript.options.strict.debug",
   "javascript.options.throw_on_asmjs_validation_failure",
   "javascript.options.throw_on_debuggee_would_run",
   "javascript.options.wasm",
   "javascript.options.wasm_baselinejit",
   "javascript.options.wasm_ionjit",
--- a/dom/serviceworkers/ServiceWorkerEvents.h
+++ b/dom/serviceworkers/ServiceWorkerEvents.h
@@ -69,17 +69,16 @@ protected:
   bool
   WaitOnPromise(Promise& aPromise);
 
   explicit ExtendableEvent(mozilla::dom::EventTarget* aOwner);
   ~ExtendableEvent() {}
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
-  NS_FORWARD_TO_EVENT
 
   void
   SetKeepAliveHandler(ExtensionsHandler* aExtensionsHandler);
 
   virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
   {
     return mozilla::dom::ExtendableEventBinding::Wrap(aCx, this, aGivenProto);
   }
@@ -279,18 +278,16 @@ protected:
   explicit ExtendableMessageEvent(EventTarget* aOwner);
   ~ExtendableMessageEvent();
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ExtendableMessageEvent,
                                                          ExtendableEvent)
 
-  NS_FORWARD_TO_EVENT
-
   virtual JSObject* WrapObjectInternal(
     JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
   {
     return mozilla::dom::ExtendableMessageEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   static already_AddRefed<ExtendableMessageEvent>
   Constructor(mozilla::dom::EventTarget* aOwner,
@@ -304,26 +301,24 @@ public:
               const ExtendableMessageEventInit& aOptions,
               ErrorResult& aRv);
 
   void GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData,
                ErrorResult& aRv);
 
   void GetSource(Nullable<OwningClientOrServiceWorkerOrMessagePort>& aValue) const;
 
-  NS_IMETHOD GetOrigin(nsAString& aOrigin)
+  void GetOrigin(nsAString& aOrigin) const
   {
     aOrigin = mOrigin;
-    return NS_OK;
   }
 
-  NS_IMETHOD GetLastEventId(nsAString& aLastEventId)
+  void GetLastEventId(nsAString& aLastEventId) const
   {
     aLastEventId = mLastEventId;
-    return NS_OK;
   }
 
   void GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts);
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/smil/nsSMILTimeValueSpec.cpp
+++ b/dom/smil/nsSMILTimeValueSpec.cpp
@@ -9,17 +9,16 @@
 #include "mozilla/dom/TimeEvent.h"
 #include "nsSMILTimeValueSpec.h"
 #include "nsSMILInterval.h"
 #include "nsSMILTimeContainer.h"
 #include "nsSMILTimeValue.h"
 #include "nsSMILTimedElement.h"
 #include "nsSMILInstanceTime.h"
 #include "nsSMILParserUtils.h"
-#include "nsIDOMKeyEvent.h"
 #include "nsString.h"
 #include <limits>
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 //----------------------------------------------------------------------
 // Nested class: EventListener
--- a/dom/svg/SVGTransformableElement.cpp
+++ b/dom/svg/SVGTransformableElement.cpp
@@ -1,22 +1,22 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "gfx2DGlue.h"
+#include "mozilla/dom/MutationEventBinding.h"
 #include "mozilla/dom/SVGAnimatedTransformList.h"
 #include "mozilla/dom/SVGGraphicsElementBinding.h"
 #include "mozilla/dom/SVGTransformableElement.h"
 #include "mozilla/dom/SVGMatrix.h"
 #include "mozilla/dom/SVGSVGElement.h"
 #include "nsContentUtils.h"
-#include "nsIDOMMutationEvent.h"
 #include "nsIFrame.h"
 #include "nsSVGDisplayableFrame.h"
 #include "mozilla/dom/SVGRect.h"
 #include "nsSVGUtils.h"
 #include "SVGContentUtils.h"
 
 using namespace mozilla::gfx;
 
@@ -60,21 +60,21 @@ SVGTransformableElement::GetAttributeCha
     nsIFrame* frame =
       const_cast<SVGTransformableElement*>(this)->GetPrimaryFrame();
     retval |= nsChangeHint_InvalidateRenderingObservers;
     if (!frame || (frame->GetStateBits() & NS_FRAME_IS_NONDISPLAY)) {
       return retval;
     }
 
     bool isAdditionOrRemoval = false;
-    if (aModType == nsIDOMMutationEvent::ADDITION ||
-        aModType == nsIDOMMutationEvent::REMOVAL) {
+    if (aModType == MutationEventBinding::ADDITION ||
+        aModType == MutationEventBinding::REMOVAL) {
       isAdditionOrRemoval = true;
     } else {
-      MOZ_ASSERT(aModType == nsIDOMMutationEvent::MODIFICATION,
+      MOZ_ASSERT(aModType == MutationEventBinding::MODIFICATION,
                  "Unknown modification type.");
       if (!mTransforms ||
           !mTransforms->HasTransform()) {
         // New value is empty, treat as removal.
         isAdditionOrRemoval = true;
       } else if (mTransforms->RequiresFrameReconstruction()) {
         // Old value was empty, treat as addition.
         isAdditionOrRemoval = true;
@@ -128,21 +128,21 @@ SVGTransformableElement::SetAnimateMotio
     return;
   }
   bool transformSet = mTransforms && mTransforms->IsExplicitlySet();
   bool prevSet = mAnimateMotionTransform || transformSet;
   mAnimateMotionTransform = aMatrix ? new gfx::Matrix(*aMatrix) : nullptr;
   bool nowSet = mAnimateMotionTransform || transformSet;
   int32_t modType;
   if (prevSet && !nowSet) {
-    modType = nsIDOMMutationEvent::REMOVAL;
+    modType = MutationEventBinding::REMOVAL;
   } else if(!prevSet && nowSet) {
-    modType = nsIDOMMutationEvent::ADDITION;
+    modType = MutationEventBinding::ADDITION;
   } else {
-    modType = nsIDOMMutationEvent::MODIFICATION;
+    modType = MutationEventBinding::MODIFICATION;
   }
   DidAnimateTransformList(modType);
   nsIFrame* frame = GetPrimaryFrame();
   if (frame) {
     // If the result of this transform and any other transforms on this frame
     // is the identity matrix, then DoApplyRenderingChangeToTree won't handle
     // our nsChangeHint_UpdateTransformLayer hint since aFrame->IsTransformed()
     // will return false. That's fine, but we still need to schedule a repaint,
--- a/dom/svg/nsSVGAnimatedTransformList.cpp
+++ b/dom/svg/nsSVGAnimatedTransformList.cpp
@@ -1,25 +1,25 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsSVGAnimatedTransformList.h"
 
+#include "mozilla/dom/MutationEventBinding.h"
 #include "mozilla/dom/SVGAnimatedTransformList.h"
 #include "mozilla/dom/SVGAnimationElement.h"
 #include "mozilla/Move.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsSVGTransform.h"
 #include "nsSMILValue.h"
 #include "SVGContentUtils.h"
 #include "SVGTransformListSMILType.h"
-#include "nsIDOMMutationEvent.h"
 
 namespace mozilla {
 
 using namespace dom;
 
 nsresult
 nsSVGAnimatedTransformList::SetBaseValueString(const nsAString& aValue,
                                                nsSVGElement* aSVGElement)
@@ -119,19 +119,19 @@ nsSVGAnimatedTransformList::SetAnimValue
   if (NS_FAILED(rv)) {
     // OOM. We clear the animation, and, importantly, ClearAnimValue() ensures
     // that mAnimVal and its DOM wrapper (if any) will have the same length!
     ClearAnimValue(aElement);
     return rv;
   }
   int32_t modType;
   if(prevSet) {
-    modType = nsIDOMMutationEvent::MODIFICATION;
+    modType = MutationEventBinding::MODIFICATION;
   } else {
-    modType = nsIDOMMutationEvent::ADDITION;
+    modType = MutationEventBinding::ADDITION;
   }
   aElement->DidAnimateTransformList(modType);
   return NS_OK;
 }
 
 void
 nsSVGAnimatedTransformList::ClearAnimValue(nsSVGElement *aElement)
 {
@@ -143,19 +143,19 @@ nsSVGAnimatedTransformList::ClearAnimVal
     // keep the length of our animVal's DOM wrapper list in sync, and again we
     // must do that before touching mAnimVal. See comments above.
     //
     domWrapper->InternalAnimValListWillChangeLengthTo(mBaseVal.Length());
   }
   mAnimVal = nullptr;
   int32_t modType;
   if (HasTransform() || aElement->GetAnimateMotionTransform()) {
-    modType = nsIDOMMutationEvent::MODIFICATION;
+    modType = MutationEventBinding::MODIFICATION;
   } else {
-    modType = nsIDOMMutationEvent::REMOVAL;
+    modType = MutationEventBinding::REMOVAL;
   }
   aElement->DidAnimateTransformList(modType);
 }
 
 bool
 nsSVGAnimatedTransformList::IsExplicitlySet() const
 {
   // Like other methods of this name, we need to know when a transform value has
--- a/dom/svg/nsSVGElement.cpp
+++ b/dom/svg/nsSVGElement.cpp
@@ -12,17 +12,16 @@
 
 #include "mozilla/dom/SVGLengthBinding.h"
 #include "mozilla/dom/SVGSVGElement.h"
 #include "mozilla/dom/SVGTests.h"
 #include "nsContentUtils.h"
 #include "nsICSSDeclaration.h"
 #include "nsIContentInlines.h"
 #include "nsIDocument.h"
-#include "nsIDOMMutationEvent.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "mozAutoDocUpdate.h"
 #include "nsError.h"
 #include "nsIPresShell.h"
 #include "nsGkAtoms.h"
 #ifdef MOZ_OLD_STYLE
 #include "nsRuleWalker.h"
 #include "mozilla/css/Declaration.h"
@@ -50,16 +49,17 @@
 #include "SVGContentUtils.h"
 #include "SVGGeometryElement.h"
 #include "nsIFrame.h"
 #include "nsQueryObject.h"
 #include <stdarg.h>
 #include "SVGMotionSMILAttr.h"
 #include "nsAttrValueOrString.h"
 #include "nsSMILAnimationController.h"
+#include "mozilla/dom/MutationEventBinding.h"
 #include "mozilla/dom/SVGElementBinding.h"
 #include "mozilla/DeclarationBlock.h"
 #include "mozilla/DeclarationBlockInlines.h"
 #include "mozilla/Unused.h"
 #include "mozilla/RestyleManager.h"
 #include "mozilla/RestyleManagerInlines.h"
 
 using namespace mozilla;
@@ -1444,18 +1444,18 @@ nsSVGElement::WillChangeValue(nsAtom* aN
   if (attrValue &&
       nsContentUtils::HasMutationListeners(this,
                                            NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
                                            this)) {
     emptyOrOldAttrValue.SetToSerialized(*attrValue);
   }
 
   uint8_t modType = attrValue
-                  ? static_cast<uint8_t>(nsIDOMMutationEvent::MODIFICATION)
-                  : static_cast<uint8_t>(nsIDOMMutationEvent::ADDITION);
+                  ? static_cast<uint8_t>(MutationEventBinding::MODIFICATION)
+                  : static_cast<uint8_t>(MutationEventBinding::ADDITION);
   nsNodeUtils::AttributeWillChange(this, kNameSpaceID_None, aName, modType,
                                    nullptr);
 
   // This is not strictly correct--the attribute value parameter for
   // BeforeSetAttr should reflect the value that *will* be set but that implies
   // allocating, e.g. an extra nsSVGLength2, and isn't necessary at the moment
   // since no SVG elements overload BeforeSetAttr. For now we just pass the
   // current value.
@@ -1490,18 +1490,18 @@ nsSVGElement::DidChangeValue(nsAtom* aNa
                              const nsAttrValue& aEmptyOrOldValue,
                              nsAttrValue& aNewValue)
 {
   bool hasListeners =
     nsContentUtils::HasMutationListeners(this,
                                          NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
                                          this);
   uint8_t modType = HasAttr(kNameSpaceID_None, aName)
-                  ? static_cast<uint8_t>(nsIDOMMutationEvent::MODIFICATION)
-                  : static_cast<uint8_t>(nsIDOMMutationEvent::ADDITION);
+                  ? static_cast<uint8_t>(MutationEventBinding::MODIFICATION)
+                  : static_cast<uint8_t>(MutationEventBinding::ADDITION);
 
   nsIDocument* document = GetComposedDoc();
   mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL,
                                kNotifyDocumentObservers);
   // XXX Really, the fourth argument to SetAttrAndNotify should be null if
   // aEmptyOrOldValue does not represent the actual previous value of the
   // attribute, but currently SVG elements do not even use the old attribute
   // value in |AfterSetAttr|, so this should be ok.
@@ -1625,17 +1625,17 @@ nsSVGElement::DidAnimateLength(uint8_t a
   ClearAnyCachedPath();
 
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     LengthAttributesInfo info = GetLengthInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mLengthInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::SMIL);
+                            MutationEventBinding::SMIL);
   }
 }
 
 nsSVGLength2*
 nsSVGElement::GetAnimatedLength(const nsAtom *aAttrName)
 {
   LengthAttributesInfo lengthInfo = GetLengthInfo();
 
@@ -1722,17 +1722,17 @@ void
 nsSVGElement::DidAnimateLengthList(uint8_t aAttrEnum)
 {
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     LengthListAttributesInfo info = GetLengthListInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mLengthListInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::SMIL);
+                            MutationEventBinding::SMIL);
   }
 }
 
 void
 nsSVGElement::GetAnimatedLengthListValues(SVGUserUnitList *aFirst, ...)
 {
   LengthListAttributesInfo info = GetLengthListInfo();
 
@@ -1810,17 +1810,17 @@ nsSVGElement::DidAnimateNumberList(uint8
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     NumberListAttributesInfo info = GetNumberListInfo();
     MOZ_ASSERT(aAttrEnum < info.mNumberListCount, "aAttrEnum out of range");
 
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mNumberListInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::SMIL);
+                            MutationEventBinding::SMIL);
   }
 }
 
 SVGAnimatedNumberList*
 nsSVGElement::GetAnimatedNumberList(uint8_t aAttrEnum)
 {
   NumberListAttributesInfo info = GetNumberListInfo();
   if (aAttrEnum < info.mNumberListCount) {
@@ -1871,17 +1871,17 @@ nsSVGElement::DidAnimatePointList()
 
   ClearAnyCachedPath();
 
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     frame->AttributeChanged(kNameSpaceID_None,
                             GetPointListAttrName(),
-                            nsIDOMMutationEvent::SMIL);
+                            MutationEventBinding::SMIL);
   }
 }
 
 nsAttrValue
 nsSVGElement::WillChangePathSegList()
 {
   MOZ_ASSERT(GetPathDataAttrName(),
              "Changing non-existent path seg list?");
@@ -1908,17 +1908,17 @@ nsSVGElement::DidAnimatePathSegList()
 
   ClearAnyCachedPath();
 
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     frame->AttributeChanged(kNameSpaceID_None,
                             GetPathDataAttrName(),
-                            nsIDOMMutationEvent::SMIL);
+                            MutationEventBinding::SMIL);
   }
 }
 
 nsSVGElement::NumberAttributesInfo
 nsSVGElement::GetNumberInfo()
 {
   return NumberAttributesInfo(nullptr, nullptr, 0);
 }
@@ -1949,17 +1949,17 @@ void
 nsSVGElement::DidAnimateNumber(uint8_t aAttrEnum)
 {
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     NumberAttributesInfo info = GetNumberInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mNumberInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::SMIL);
+                            MutationEventBinding::SMIL);
   }
 }
 
 void
 nsSVGElement::GetAnimatedNumberValues(float *aFirst, ...)
 {
   NumberAttributesInfo info = GetNumberInfo();
 
@@ -2019,17 +2019,17 @@ void
 nsSVGElement::DidAnimateNumberPair(uint8_t aAttrEnum)
 {
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     NumberPairAttributesInfo info = GetNumberPairInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mNumberPairInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::SMIL);
+                            MutationEventBinding::SMIL);
   }
 }
 
 nsSVGElement::IntegerAttributesInfo
 nsSVGElement::GetIntegerInfo()
 {
   return IntegerAttributesInfo(nullptr, nullptr, 0);
 }
@@ -2060,17 +2060,17 @@ void
 nsSVGElement::DidAnimateInteger(uint8_t aAttrEnum)
 {
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     IntegerAttributesInfo info = GetIntegerInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mIntegerInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::SMIL);
+                            MutationEventBinding::SMIL);
   }
 }
 
 void
 nsSVGElement::GetAnimatedIntegerValues(int32_t *aFirst, ...)
 {
   IntegerAttributesInfo info = GetIntegerInfo();
 
@@ -2131,17 +2131,17 @@ void
 nsSVGElement::DidAnimateIntegerPair(uint8_t aAttrEnum)
 {
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     IntegerPairAttributesInfo info = GetIntegerPairInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mIntegerPairInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::SMIL);
+                            MutationEventBinding::SMIL);
   }
 }
 
 nsSVGElement::AngleAttributesInfo
 nsSVGElement::GetAngleInfo()
 {
   return AngleAttributesInfo(nullptr, nullptr, 0);
 }
@@ -2179,17 +2179,17 @@ void
 nsSVGElement::DidAnimateAngle(uint8_t aAttrEnum)
 {
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     AngleAttributesInfo info = GetAngleInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mAngleInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::SMIL);
+                            MutationEventBinding::SMIL);
   }
 }
 
 nsSVGElement::BooleanAttributesInfo
 nsSVGElement::GetBooleanInfo()
 {
   return BooleanAttributesInfo(nullptr, nullptr, 0);
 }
@@ -2218,17 +2218,17 @@ void
 nsSVGElement::DidAnimateBoolean(uint8_t aAttrEnum)
 {
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     BooleanAttributesInfo info = GetBooleanInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             *info.mBooleanInfo[aAttrEnum].mName,
-                            nsIDOMMutationEvent::SMIL);
+                            MutationEventBinding::SMIL);
   }
 }
 
 nsSVGElement::EnumAttributesInfo
 nsSVGElement::GetEnumInfo()
 {
   return EnumAttributesInfo(nullptr, nullptr, 0);