Merge mozilla-inbound to mozilla-central. a=merge
authorDorel Luca <dluca@mozilla.com>
Sat, 21 Apr 2018 02:00:04 +0300
changeset 470865 39ccabfd7d0712a45335325cb24b0e0b2ba498c7
parent 470771 e166407fe8b08f49f5fe7529048493676d158b63 (current diff)
parent 470864 5cc5665abf82c6b5480145a17e1927ae35118cdd (diff)
child 470866 d36d2c2ab772c4b5479e2516a87e830cab8da509
child 470896 b2174d5770ef7e79c958349fa04225c5ea4926ad
child 470989 e2da4a4bac5c9cdcbae8cb9bd08c08fd407cec87
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone61.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
accessible/jsat/Gestures.jsm
accessible/jsat/PointerAdapter.jsm
accessible/jsat/sounds/clicked.ogg
accessible/jsat/sounds/virtual_cursor_key.ogg
accessible/jsat/sounds/virtual_cursor_move.ogg
accessible/tests/mochitest/jsat/dom_helper.js
accessible/tests/mochitest/jsat/gestures.json
accessible/tests/mochitest/jsat/test_gesture_tracker.html
accessible/tests/mochitest/jsat/test_pointer_relay.html
accessible/tests/mochitest/jsat/test_quicknav_modes.html
devtools/client/scratchpad/scratchpad.js
dom/base/nsDOMWindowUtils.cpp
dom/base/nsIDOMClassInfo.h
dom/html/nsTextEditorState.cpp
dom/interfaces/base/nsIDOMWindowUtils.idl
dom/interfaces/events/nsIDOMEvent.idl
dom/interfaces/events/nsIDOMEventTarget.idl
editor/libeditor/EditorBase.cpp
editor/libeditor/EditorBase.h
js/xpconnect/src/qsObjectHelper.h
layout/base/nsCSSFrameConstructor.cpp
layout/inspector/InspectorUtils.cpp
layout/style/ServoStyleSet.cpp
servo/components/style/properties/longhand/position.mako.rs
testing/mochitest/chrome/test_sanityAddTask.xul
testing/mochitest/chrome/test_sanitySpawnTask.xul
testing/mochitest/tests/Harness_sanity/test_add_task.html
testing/mochitest/tests/Harness_sanity/test_spawn_task.html
testing/mochitest/tests/SimpleTest/LICENSE_SpawnTask
testing/mochitest/tests/SimpleTest/SpawnTask.js
testing/web-platform/meta/MANIFEST.json
testing/web-platform/meta/css/css-align/default-alignment/parse-justify-items-004.html.ini
--- a/accessible/base/DocManager.cpp
+++ b/accessible/base/DocManager.cpp
@@ -16,17 +16,17 @@
 #include "RootAccessibleWrap.h"
 #include "xpcAccessibleDocument.h"
 
 #ifdef A11Y_LOG
 #include "Logging.h"
 #endif
 
 #include "mozilla/EventListenerManager.h"
-#include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
+#include "mozilla/dom/Event.h" // for Event
 #include "nsCURILoader.h"
 #include "nsDocShellLoadTypes.h"
 #include "nsIChannel.h"
 #include "nsIDOMDocument.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIWebNavigation.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIWebProgress.h"
@@ -349,23 +349,22 @@ DocManager::OnSecurityChange(nsIWebProgr
   NS_NOTREACHED("notification excluded in AddProgressListener(...)");
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIDOMEventListener
 
 NS_IMETHODIMP
-DocManager::HandleEvent(nsIDOMEvent* aEvent)
+DocManager::HandleEvent(Event* aEvent)
 {
   nsAutoString type;
   aEvent->GetType(type);
 
-  nsCOMPtr<nsIDocument> document =
-    do_QueryInterface(aEvent->InternalDOMEvent()->GetTarget());
+  nsCOMPtr<nsIDocument> document = do_QueryInterface(aEvent->GetTarget());
   NS_ASSERTION(document, "pagehide or DOMContentLoaded for non document!");
   if (!document)
     return NS_OK;
 
   if (type.EqualsLiteral("pagehide")) {
     // 'pagehide' event is registered on every DOM document we create an
     // accessible for, process the event for the target. This document
     // accessible and all its sub document accessible are shutdown as result of
--- a/accessible/base/Logging.cpp
+++ b/accessible/base/Logging.cpp
@@ -824,17 +824,17 @@ logging::Node(const char* aDescr, nsINod
 {
   printf("    ");
 
   if (!aNode) {
     printf("%s: null\n", aDescr);
     return;
   }
 
-  if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {
+  if (aNode->IsDocument()) {
     printf("%s: %p, document\n", aDescr, static_cast<void*>(aNode));
     return;
   }
 
   nsINode* parentNode = aNode->GetParentNode();
   int32_t idxInParent = parentNode ? parentNode->ComputeIndexOf(aNode) : - 1;
 
   if (aNode->IsText()) {
@@ -903,17 +903,17 @@ logging::AccessibleInfo(const char* aDes
   }
 
   printf(", idx: %d", aAccessible->IndexInParent());
 
   nsINode* node = aAccessible->GetNode();
   if (!node) {
     printf(", node: null\n");
   }
-  else if (node->IsNodeOfType(nsINode::eDOCUMENT)) {
+  else if (node->IsDocument()) {
     printf(", document node: %p\n", static_cast<void*>(node));
   }
   else if (node->IsText()) {
     printf(", text node: %p\n", static_cast<void*>(node));
   }
   else if (node->IsElement()) {
     dom::Element* el = node->AsElement();
 
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -63,16 +63,17 @@
 #include "SVGGeometryFrame.h"
 #include "nsTreeBodyFrame.h"
 #include "nsTreeColumns.h"
 #include "nsTreeUtils.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsXBLBinding.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/dom/DOMStringList.h"
+#include "mozilla/dom/EventTarget.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "nsDeckFrame.h"
 
 #ifdef MOZ_XUL
 #include "XULAlertAccessible.h"
 #include "XULColorPickerAccessible.h"
 #include "XULComboboxAccessible.h"
@@ -370,17 +371,17 @@ nsAccessibilityService::ListenersChanged
 {
   uint32_t targetCount;
   nsresult rv = aEventChanges->GetLength(&targetCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   for (uint32_t i = 0 ; i < targetCount ; i++) {
     nsCOMPtr<nsIEventListenerChange> change = do_QueryElementAt(aEventChanges, i);
 
-    nsCOMPtr<nsIDOMEventTarget> target;
+    RefPtr<EventTarget> target;
     change->GetTarget(getter_AddRefs(target));
     nsCOMPtr<nsIContent> node(do_QueryInterface(target));
     if (!node || !node->IsHTMLElement()) {
       continue;
     }
 
     uint32_t changeCount;
     change->GetCountOfEventListenerChangesAffectingAccessibility(&changeCount);
@@ -1039,21 +1040,20 @@ nsAccessibilityService::CreateAccessible
 
   if (aIsSubtreeHidden)
     *aIsSubtreeHidden = false;
 
   DocAccessible* document = aContext->Document();
   MOZ_ASSERT(!document->GetAccessible(aNode),
              "We already have an accessible for this node.");
 
-  if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {
+  if (aNode->IsDocument()) {
     // If it's document node then ask accessible document loader for
     // document accessible, otherwise return null.
-    nsCOMPtr<nsIDocument> document(do_QueryInterface(aNode));
-    return GetDocAccessible(document);
+    return GetDocAccessible(aNode->AsDocument());
   }
 
   // We have a content node.
   if (!aNode->GetComposedDoc()) {
     NS_WARNING("Creating accessible for node with no document");
     return nullptr;
   }
 
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -556,16 +556,21 @@ Accessible::ChildAtPoint(int32_t aX, int
     if (popupChild == popupAcc)
       startFrame = popupFrame;
   }
 
   nsPresContext* presContext = startFrame->PresContext();
   nsRect screenRect = startFrame->GetScreenRectInAppUnits();
   nsPoint offset(presContext->DevPixelsToAppUnits(aX) - screenRect.X(),
                  presContext->DevPixelsToAppUnits(aY) - screenRect.Y());
+
+  // We need to take into account a non-1 resolution set on the presshell.
+  // This happens in mobile platforms with async pinch zooming.
+  offset = offset.RemoveResolution(presContext->PresShell()->GetResolution());
+
   nsIFrame* foundFrame = nsLayoutUtils::GetFrameForPoint(startFrame, offset);
 
   nsIContent* content = nullptr;
   if (!foundFrame || !(content = foundFrame->GetContent()))
     return fallbackAnswer;
 
   // Get accessible for the node with the point or the first accessible in
   // the DOM parent chain.
@@ -674,16 +679,20 @@ Accessible::Bounds() const
 
   nsIntRect screenRect;
   nsPresContext* presContext = mDoc->PresContext();
   screenRect.SetRect(presContext->AppUnitsToDevPixels(unionRectTwips.X()),
                      presContext->AppUnitsToDevPixels(unionRectTwips.Y()),
                      presContext->AppUnitsToDevPixels(unionRectTwips.Width()),
                      presContext->AppUnitsToDevPixels(unionRectTwips.Height()));
 
+  // We need to take into account a non-1 resolution set on the presshell.
+  // This happens in mobile platforms with async pinch zooming. Here we
+  // scale the bounds before adding the screen-relative offset.
+  screenRect.ScaleRoundOut(presContext->PresShell()->GetResolution());
   // We have the union of the rectangle, now we need to put it in absolute
   // screen coords.
   nsIntRect orgRectPixels = boundingFrame->GetScreenRectInAppUnits().
     ToNearestPixels(presContext->AppUnitsPerDevPixel());
   screenRect.MoveBy(orgRectPixels.X(), orgRectPixels.Y());
 
   return screenRect;
 }
--- a/accessible/generic/HyperTextAccessible.cpp
+++ b/accessible/generic/HyperTextAccessible.cpp
@@ -1267,16 +1267,26 @@ HyperTextAccessible::TextBounds(int32_t 
 
     bounds.UnionRect(bounds, GetBoundsInFrame(frame, offset1,
                                               nextOffset - prevOffset));
 
     prevOffset = nextOffset;
     offset1 = 0;
   }
 
+  // This document may have a resolution set, we will need to multiply
+  // the document-relative coordinates by that value and re-apply the doc's
+  // screen coordinates.
+  nsPresContext* presContext = mDoc->PresContext();
+  nsIFrame* rootFrame = presContext->PresShell()->GetRootFrame();
+  nsIntRect orgRectPixels = rootFrame->GetScreenRectInAppUnits().ToNearestPixels(presContext->AppUnitsPerDevPixel());
+  bounds.MoveBy(-orgRectPixels.X(), -orgRectPixels.Y());
+  bounds.ScaleRoundOut(presContext->PresShell()->GetResolution());
+  bounds.MoveBy(orgRectPixels.X(), orgRectPixels.Y());
+
   auto boundsX = bounds.X();
   auto boundsY = bounds.Y();
   nsAccUtils::ConvertScreenCoordsTo(&boundsX, &boundsY, aCoordType, this);
   bounds.MoveTo(boundsX, boundsY);
   return bounds;
 }
 
 already_AddRefed<TextEditor>
--- a/accessible/generic/RootAccessible.cpp
+++ b/accessible/generic/RootAccessible.cpp
@@ -225,21 +225,20 @@ void
 RootAccessible::DocumentActivated(DocAccessible* aDocument)
 {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIDOMEventListener
 
 NS_IMETHODIMP
-RootAccessible::HandleEvent(nsIDOMEvent* aDOMEvent)
+RootAccessible::HandleEvent(Event* aDOMEvent)
 {
   MOZ_ASSERT(aDOMEvent);
-  Event* event = aDOMEvent->InternalDOMEvent();
-  nsCOMPtr<nsINode> origTargetNode = do_QueryInterface(event->GetOriginalTarget());
+  nsCOMPtr<nsINode> origTargetNode = do_QueryInterface(aDOMEvent->GetOriginalTarget());
   if (!origTargetNode)
     return NS_OK;
 
 #ifdef A11Y_LOG
   if (logging::IsEnabled(logging::eDOMEvents)) {
     nsAutoString eventType;
     aDOMEvent->GetType(eventType);
     logging::DOMEvent("handled", origTargetNode, eventType);
@@ -248,30 +247,30 @@ RootAccessible::HandleEvent(nsIDOMEvent*
 
   DocAccessible* document =
     GetAccService()->GetDocAccessible(origTargetNode->OwnerDoc());
 
   if (document) {
     // Root accessible exists longer than any of its descendant documents so
     // that we are guaranteed notification is processed before root accessible
     // is destroyed.
-    document->HandleNotification<RootAccessible, nsIDOMEvent>
+    document->HandleNotification<RootAccessible, Event>
       (this, &RootAccessible::ProcessDOMEvent, aDOMEvent);
   }
 
   return NS_OK;
 }
 
 // RootAccessible protected
 void
-RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
+RootAccessible::ProcessDOMEvent(Event* aDOMEvent)
 {
   MOZ_ASSERT(aDOMEvent);
-  Event* event = aDOMEvent->InternalDOMEvent();
-  nsCOMPtr<nsINode> origTargetNode = do_QueryInterface(event->GetOriginalTarget());
+  nsCOMPtr<nsINode> origTargetNode =
+    do_QueryInterface(aDOMEvent->GetOriginalTarget());
 
   nsAutoString eventType;
   aDOMEvent->GetType(eventType);
 
 #ifdef A11Y_LOG
   if (logging::IsEnabled(logging::eDOMEvents))
     logging::DOMEvent("processed", origTargetNode, eventType);
 #endif
@@ -647,21 +646,21 @@ RootAccessible::HandlePopupHidingEvent(n
     RefPtr<AccEvent> event =
       new AccStateChangeEvent(widget, states::EXPANDED, false);
     document->FireDelayedEvent(event);
   }
 }
 
 #ifdef MOZ_XUL
 static void
-GetPropertyBagFromEvent(nsIDOMEvent* aEvent, nsIPropertyBag2** aPropertyBag)
+GetPropertyBagFromEvent(Event* aEvent, nsIPropertyBag2** aPropertyBag)
 {
   *aPropertyBag = nullptr;
 
-  CustomEvent* customEvent = aEvent->InternalDOMEvent()->AsCustomEvent();
+  CustomEvent* customEvent = aEvent->AsCustomEvent();
   if (!customEvent)
     return;
 
   AutoJSAPI jsapi;
   if (!jsapi.Init(customEvent->GetParentObject()))
     return;
 
   JSContext* cx = jsapi.cx();
@@ -677,17 +676,17 @@ GetPropertyBagFromEvent(nsIDOMEvent* aEv
   rv = UnwrapArg<nsIPropertyBag2>(cx, detailObj, getter_AddRefs(propBag));
   if (NS_FAILED(rv))
     return;
 
   propBag.forget(aPropertyBag);
 }
 
 void
-RootAccessible::HandleTreeRowCountChangedEvent(nsIDOMEvent* aEvent,
+RootAccessible::HandleTreeRowCountChangedEvent(Event* aEvent,
                                                XULTreeAccessible* aAccessible)
 {
   nsCOMPtr<nsIPropertyBag2> propBag;
   GetPropertyBagFromEvent(aEvent, getter_AddRefs(propBag));
   if (!propBag)
     return;
 
   nsresult rv;
@@ -699,17 +698,17 @@ RootAccessible::HandleTreeRowCountChange
   rv = propBag->GetPropertyAsInt32(NS_LITERAL_STRING("count"), &count);
   if (NS_FAILED(rv))
     return;
 
   aAccessible->InvalidateCache(index, count);
 }
 
 void
-RootAccessible::HandleTreeInvalidatedEvent(nsIDOMEvent* aEvent,
+RootAccessible::HandleTreeInvalidatedEvent(Event* aEvent,
                                            XULTreeAccessible* aAccessible)
 {
   nsCOMPtr<nsIPropertyBag2> propBag;
   GetPropertyBagFromEvent(aEvent, getter_AddRefs(propBag));
   if (!propBag)
     return;
 
   int32_t startRow = 0, endRow = -1, startCol = 0, endCol = -1;
--- a/accessible/generic/RootAccessible.h
+++ b/accessible/generic/RootAccessible.h
@@ -20,17 +20,17 @@ class RootAccessible : public DocAccessi
                        public nsIDOMEventListener
 {
   NS_DECL_ISUPPORTS_INHERITED
 
 public:
   RootAccessible(nsIDocument* aDocument, nsIPresShell* aPresShell);
 
   // nsIDOMEventListener
-  NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override;
+  NS_DECL_NSIDOMEVENTLISTENER
 
   // Accessible
   virtual void Shutdown() override;
   virtual mozilla::a11y::ENameValueFlag Name(nsString& aName) override;
   virtual Relation RelationByType(RelationType aType) override;
   virtual mozilla::a11y::role NativeRole() override;
   virtual uint64_t NativeState() override;
 
@@ -53,33 +53,33 @@ protected:
    * Add/remove DOM event listeners.
    */
   virtual nsresult AddEventListeners() override;
   virtual nsresult RemoveEventListeners() override;
 
   /**
    * Process the DOM event.
    */
-  void ProcessDOMEvent(nsIDOMEvent* aEvent);
+  void ProcessDOMEvent(dom::Event* aEvent);
 
   /**
    * Process "popupshown" event. Used by HandleEvent().
    */
   void HandlePopupShownEvent(Accessible* aAccessible);
 
   /*
    * Process "popuphiding" event. Used by HandleEvent().
    */
   void HandlePopupHidingEvent(nsINode* aNode);
 
 #ifdef MOZ_XUL
-    void HandleTreeRowCountChangedEvent(nsIDOMEvent* aEvent,
-                                        XULTreeAccessible* aAccessible);
-    void HandleTreeInvalidatedEvent(nsIDOMEvent* aEvent,
-                                    XULTreeAccessible* aAccessible);
+  void HandleTreeRowCountChangedEvent(dom::Event* aEvent,
+                                      XULTreeAccessible* aAccessible);
+  void HandleTreeInvalidatedEvent(dom::Event* aEvent,
+                                  XULTreeAccessible* aAccessible);
 
     uint32_t GetChromeFlags();
 #endif
 };
 
 inline RootAccessible*
 Accessible::AsRoot()
 {
--- a/accessible/html/HTMLSelectAccessible.cpp
+++ b/accessible/html/HTMLSelectAccessible.cpp
@@ -315,18 +315,17 @@ uint64_t
 HTMLSelectOptGroupAccessible::NativeInteractiveState() const
 {
   return NativelyUnavailable() ? states::UNAVAILABLE : 0;
 }
 
 bool
 HTMLSelectOptGroupAccessible::IsAcceptableChild(nsIContent* aEl) const
 {
-  return aEl->IsNodeOfType(nsINode::eDATA_NODE) ||
-    aEl->IsHTMLElement(nsGkAtoms::option);
+  return aEl->IsCharacterData() || aEl->IsHTMLElement(nsGkAtoms::option);
 }
 
 uint8_t
 HTMLSelectOptGroupAccessible::ActionCount()
 {
   return 0;
 }
 
--- a/accessible/jsat/AccessFu.jsm
+++ b/accessible/jsat/AccessFu.jsm
@@ -8,28 +8,26 @@ var EXPORTED_SYMBOLS = ["AccessFu"];
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/accessibility/Utils.jsm");
 
 if (Utils.MozBuildApp === "mobile/android") {
   ChromeUtils.import("resource://gre/modules/Messaging.jsm");
 }
 
-const QUICKNAV_MODES_PREF = "accessibility.accessfu.quicknav_modes";
-const QUICKNAV_INDEX_PREF = "accessibility.accessfu.quicknav_index";
-
 const GECKOVIEW_MESSAGE = {
   ACTIVATE: "GeckoView:AccessibilityActivate",
   VIEW_FOCUSED: "GeckoView:AccessibilityViewFocused",
   LONG_PRESS: "GeckoView:AccessibilityLongPress",
   BY_GRANULARITY: "GeckoView:AccessibilityByGranularity",
   NEXT: "GeckoView:AccessibilityNext",
   PREVIOUS: "GeckoView:AccessibilityPrevious",
   SCROLL_BACKWARD: "GeckoView:AccessibilityScrollBackward",
   SCROLL_FORWARD: "GeckoView:AccessibilityScrollForward",
+  EXPLORE_BY_TOUCH: "GeckoView:AccessibilityExploreByTouch"
 };
 
 var AccessFu = {
   /**
    * Initialize chrome-layer accessibility functionality.
    * If accessibility is enabled on the platform, then a special accessibility
    * mode is started.
    */
@@ -68,55 +66,35 @@ var AccessFu = {
    */
   _enable: function _enable() {
     if (this._enabled) {
       return;
     }
     this._enabled = true;
 
     ChromeUtils.import("resource://gre/modules/accessibility/Utils.jsm");
-    ChromeUtils.import("resource://gre/modules/accessibility/PointerAdapter.jsm");
     ChromeUtils.import("resource://gre/modules/accessibility/Presentation.jsm");
 
     for (let mm of Utils.AllMessageManagers) {
       this._addMessageListeners(mm);
       this._loadFrameScript(mm);
     }
 
     // Add stylesheet
     let stylesheetURL = "chrome://global/content/accessibility/AccessFu.css";
     let stylesheet = Utils.win.document.createProcessingInstruction(
       "xml-stylesheet", `href="${stylesheetURL}" type="text/css"`);
     Utils.win.document.insertBefore(stylesheet, Utils.win.document.firstChild);
     this.stylesheet = Cu.getWeakReference(stylesheet);
 
-
-    // Populate quicknav modes
-    this._quicknavModesPref =
-      new PrefCache(QUICKNAV_MODES_PREF, (aName, aValue, aFirstRun) => {
-        this.Input.quickNavMode.updateModes(aValue);
-        if (!aFirstRun) {
-          // If the modes change, reset the current mode index to 0.
-          Services.prefs.setIntPref(QUICKNAV_INDEX_PREF, 0);
-        }
-      }, true);
-
-    this._quicknavCurrentModePref =
-      new PrefCache(QUICKNAV_INDEX_PREF, (aName, aValue) => {
-        this.Input.quickNavMode.updateCurrentMode(Number(aValue));
-      }, true);
-
     // Check for output notification
     this._notifyOutputPref =
       new PrefCache("accessibility.accessfu.notify_output");
 
-
-    this.Input.start();
     Output.start();
-    PointerAdapter.start();
 
     if (Utils.MozBuildApp === "mobile/android") {
       Utils.win.WindowEventDispatcher.registerListener(this,
         Object.values(GECKOVIEW_MESSAGE));
     }
 
     Services.obs.addObserver(this, "remote-browser-shown");
     Services.obs.addObserver(this, "inprocess-browser-shown");
@@ -144,33 +122,30 @@ var AccessFu = {
 
     Utils.win.document.removeChild(this.stylesheet.get());
 
     for (let mm of Utils.AllMessageManagers) {
       mm.sendAsyncMessage("AccessFu:Stop");
       this._removeMessageListeners(mm);
     }
 
-    this.Input.stop();
     Output.stop();
-    PointerAdapter.stop();
 
     Utils.win.removeEventListener("TabOpen", this);
     Utils.win.removeEventListener("TabClose", this);
     Utils.win.removeEventListener("TabSelect", this);
 
     Services.obs.removeObserver(this, "remote-browser-shown");
     Services.obs.removeObserver(this, "inprocess-browser-shown");
 
     if (Utils.MozBuildApp === "mobile/android") {
       Utils.win.WindowEventDispatcher.unregisterListener(this,
         Object.values(GECKOVIEW_MESSAGE));
     }
 
-    delete this._quicknavModesPref;
     delete this._notifyOutputPref;
 
     if (this.doneCallback) {
       this.doneCallback();
       delete this.doneCallback;
     }
 
     Logger.info("AccessFu:Disabled");
@@ -277,33 +252,36 @@ var AccessFu = {
         let method = event.replace(/GeckoView:Accessibility(\w+)/, "move$1");
         this.Input.moveCursor(method, rule, "gesture");
         break;
       }
       case GECKOVIEW_MESSAGE.ACTIVATE:
         this.Input.activateCurrent(data);
         break;
       case GECKOVIEW_MESSAGE.LONG_PRESS:
-        this.Input.sendContextMenuMessage();
+        // XXX: Advertize long press on supported objects and implement action
         break;
       case GECKOVIEW_MESSAGE.SCROLL_FORWARD:
         this.Input.androidScroll("forward");
         break;
       case GECKOVIEW_MESSAGE.SCROLL_BACKWARD:
         this.Input.androidScroll("backward");
         break;
       case GECKOVIEW_MESSAGE.VIEW_FOCUSED:
         this._focused = data.gainFocus;
         if (this._focused) {
           this.autoMove({ forcePresent: true, noOpIfOnScreen: true });
         }
         break;
       case GECKOVIEW_MESSAGE.BY_GRANULARITY:
         this.Input.moveByGranularity(data);
         break;
+      case GECKOVIEW_MESSAGE.EXPLORE_BY_TOUCH:
+        this.Input.moveToPoint("Simple", ...data.coordinates);
+        break;
     }
   },
 
   observe: function observe(aSubject, aTopic, aData) {
     switch (aTopic) {
       case "remote-browser-shown":
       case "inprocess-browser-shown":
       {
@@ -370,40 +348,29 @@ var AccessFu = {
   // Layerview is focused
   _focused: false,
 
   // Keep track of message managers tha already have a 'content-script.js'
   // injected.
   _processedMessageManagers: [],
 
   /**
-   * Adjusts the given bounds relative to the given browser.
+   * Adjusts the given bounds that are defined in device display pixels
+   * to client-relative CSS pixels of the chrome window.
    * @param {Rect} aJsonBounds the bounds to adjust
-   * @param {browser} aBrowser the browser we want the bounds relative to
-   * @param {bool} aToCSSPixels whether to convert to CSS pixels (as opposed to
-   *               device pixels)
    */
-  adjustContentBounds(aJsonBounds, aBrowser, aToCSSPixels) {
+  screenToClientBounds(aJsonBounds) {
       let bounds = new Rect(aJsonBounds.left, aJsonBounds.top,
                             aJsonBounds.right - aJsonBounds.left,
                             aJsonBounds.bottom - aJsonBounds.top);
       let win = Utils.win;
       let dpr = win.devicePixelRatio;
-      let offset = { left: -win.mozInnerScreenX, top: -win.mozInnerScreenY };
 
-      // Add the offset; the offset is in CSS pixels, so multiply the
-      // devicePixelRatio back in before adding to preserve unit consistency.
-      bounds = bounds.translate(offset.left * dpr, offset.top * dpr);
-
-      // If we want to get to CSS pixels from device pixels, this needs to be
-      // further divided by the devicePixelRatio due to widget scaling.
-      if (aToCSSPixels) {
-        bounds = bounds.scale(1 / dpr, 1 / dpr);
-      }
-
+      bounds = bounds.scale(1 / dpr, 1 / dpr);
+      bounds = bounds.translate(-win.mozInnerScreenX, -win.mozInnerScreenY);
       return bounds.expandToIntegers();
     }
 };
 
 var Output = {
   brailleState: {
     startOffset: 0,
     endOffset: 0,
@@ -512,17 +479,17 @@ var Output = {
             doc.createElementNS("http://www.w3.org/1999/xhtml", "div"));
 
           this.highlightBox = Cu.getWeakReference(highlightBox);
         } else {
           highlightBox = this.highlightBox.get();
         }
 
         let padding = aDetail.padding;
-        let r = AccessFu.adjustContentBounds(aDetail.bounds, aBrowser, true);
+        let r = AccessFu.screenToClientBounds(aDetail.bounds);
 
         // First hide it to avoid flickering when changing the style.
         highlightBox.classList.remove("show");
         highlightBox.style.top = (r.top - padding) + "px";
         highlightBox.style.left = (r.left - padding) + "px";
         highlightBox.style.width = (r.width + padding * 2) + "px";
         highlightBox.style.height = (r.height + padding * 2) + "px";
         highlightBox.classList.add("show");
@@ -541,20 +508,16 @@ var Output = {
   },
 
   Android: function Android(aDetails, aBrowser) {
     const ANDROID_VIEW_TEXT_CHANGED = 0x10;
     const ANDROID_VIEW_TEXT_SELECTION_CHANGED = 0x2000;
 
     for (let androidEvent of aDetails) {
       androidEvent.type = "GeckoView:AccessibilityEvent";
-      if (androidEvent.bounds) {
-        androidEvent.bounds = AccessFu.adjustContentBounds(
-          androidEvent.bounds, aBrowser);
-      }
 
       switch (androidEvent.eventType) {
         case ANDROID_VIEW_TEXT_CHANGED:
           androidEvent.brailleOutput = this.brailleState.adjustText(
             androidEvent.text);
           break;
         case ANDROID_VIEW_TEXT_SELECTION_CHANGED:
           androidEvent.brailleOutput = this.brailleState.adjustSelection(
@@ -573,217 +536,16 @@ var Output = {
   Braille: function Braille(aDetails) {
     Logger.debug("Braille output: " + aDetails.output);
   }
 };
 
 var Input = {
   editState: {},
 
-  start: function start() {
-    // XXX: This is too disruptive on desktop for now.
-    // Might need to add special modifiers.
-    if (Utils.MozBuildApp != "browser") {
-      Utils.win.document.addEventListener("keypress", this, true);
-    }
-    Utils.win.addEventListener("mozAccessFuGesture", this, true);
-  },
-
-  stop: function stop() {
-    if (Utils.MozBuildApp != "browser") {
-      Utils.win.document.removeEventListener("keypress", this, true);
-    }
-    Utils.win.removeEventListener("mozAccessFuGesture", this, true);
-  },
-
-  handleEvent: function Input_handleEvent(aEvent) {
-    try {
-      switch (aEvent.type) {
-      case "keypress":
-        this._handleKeypress(aEvent);
-        break;
-      case "mozAccessFuGesture":
-        this._handleGesture(aEvent.detail);
-        break;
-      }
-    } catch (x) {
-      Logger.logException(x);
-    }
-  },
-
-  _handleGesture: function _handleGesture(aGesture) {
-    let gestureName = aGesture.type + aGesture.touches.length;
-    Logger.debug("Gesture", aGesture.type,
-                 "(fingers: " + aGesture.touches.length + ")");
-
-    switch (gestureName) {
-      case "dwell1":
-      case "explore1":
-        this.moveToPoint("Simple", aGesture.touches[0].x,
-          aGesture.touches[0].y);
-        break;
-      case "doubletap1":
-        this.activateCurrent();
-        break;
-      case "doubletaphold1":
-        Utils.dispatchChromeEvent("accessibility-control", "quicknav-menu");
-        break;
-      case "swiperight1":
-        this.moveCursor("moveNext", "Simple", "gestures");
-        break;
-      case "swipeleft1":
-        this.moveCursor("movePrevious", "Simple", "gesture");
-        break;
-      case "swipeup1":
-        this.moveCursor(
-          "movePrevious", this.quickNavMode.current, "gesture", true);
-        break;
-      case "swipedown1":
-        this.moveCursor("moveNext", this.quickNavMode.current, "gesture", true);
-        break;
-      case "exploreend1":
-      case "dwellend1":
-        this.activateCurrent(null, true);
-        break;
-      case "swiperight2":
-        if (aGesture.edge) {
-          Utils.dispatchChromeEvent("accessibility-control",
-            "edge-swipe-right");
-          break;
-        }
-        this.sendScrollMessage(-1, true);
-        break;
-      case "swipedown2":
-        if (aGesture.edge) {
-          Utils.dispatchChromeEvent("accessibility-control", "edge-swipe-down");
-          break;
-        }
-        this.sendScrollMessage(-1);
-        break;
-      case "swipeleft2":
-        if (aGesture.edge) {
-          Utils.dispatchChromeEvent("accessibility-control", "edge-swipe-left");
-          break;
-        }
-        this.sendScrollMessage(1, true);
-        break;
-      case "swipeup2":
-        if (aGesture.edge) {
-          Utils.dispatchChromeEvent("accessibility-control", "edge-swipe-up");
-          break;
-        }
-        this.sendScrollMessage(1);
-        break;
-      case "explore2":
-        Utils.CurrentBrowser.contentWindow.scrollBy(
-          -aGesture.deltaX, -aGesture.deltaY);
-        break;
-      case "swiperight3":
-        this.moveCursor("moveNext", this.quickNavMode.current, "gesture");
-        break;
-      case "swipeleft3":
-        this.moveCursor("movePrevious", this.quickNavMode.current, "gesture");
-        break;
-      case "swipedown3":
-        this.quickNavMode.next();
-        AccessFu.announce("quicknav_" + this.quickNavMode.current);
-        break;
-      case "swipeup3":
-        this.quickNavMode.previous();
-        AccessFu.announce("quicknav_" + this.quickNavMode.current);
-        break;
-      case "tripletap3":
-        Utils.dispatchChromeEvent("accessibility-control", "toggle-shade");
-        break;
-      case "tap2":
-        Utils.dispatchChromeEvent("accessibility-control", "toggle-pause");
-        break;
-    }
-  },
-
-  _handleKeypress: function _handleKeypress(aEvent) {
-    let target = aEvent.target;
-
-    // Ignore keys with modifiers so the content could take advantage of them.
-    if (aEvent.ctrlKey || aEvent.altKey || aEvent.metaKey) {
-      return;
-    }
-
-    switch (aEvent.keyCode) {
-      case 0:
-        // an alphanumeric key was pressed, handle it separately.
-        // If it was pressed with either alt or ctrl, just pass through.
-        // If it was pressed with meta, pass the key on without the meta.
-        if (this.editState.editing) {
-          return;
-        }
-
-        let key = String.fromCharCode(aEvent.charCode);
-        try {
-          let [methodName, rule] = this.keyMap[key];
-          this.moveCursor(methodName, rule, "keyboard");
-        } catch (x) {
-          return;
-        }
-        break;
-      case aEvent.DOM_VK_RIGHT:
-        if (this.editState.editing) {
-          if (!this.editState.atEnd) {
-            // Don't move forward if caret is not at end of entry.
-            // XXX: Fix for rtl
-            return;
-          }
-          target.blur();
-
-        }
-        this.moveCursor(aEvent.shiftKey ?
-          "moveLast" : "moveNext", "Simple", "keyboard");
-        break;
-      case aEvent.DOM_VK_LEFT:
-        if (this.editState.editing) {
-          if (!this.editState.atStart) {
-            // Don't move backward if caret is not at start of entry.
-            // XXX: Fix for rtl
-            return;
-          }
-          target.blur();
-
-        }
-        this.moveCursor(aEvent.shiftKey ?
-          "moveFirst" : "movePrevious", "Simple", "keyboard");
-        break;
-      case aEvent.DOM_VK_UP:
-        if (this.editState.multiline) {
-          if (!this.editState.atStart) {
-            // Don't blur content if caret is not at start of text area.
-            return;
-          }
-          target.blur();
-
-        }
-
-        if (Utils.MozBuildApp == "mobile/android") {
-          // Return focus to native Android browser chrome.
-          Utils.win.WindowEventDispatcher.dispatch("ToggleChrome:Focus");
-        }
-        break;
-      case aEvent.DOM_VK_RETURN:
-        if (this.editState.editing) {
-          return;
-        }
-        this.activateCurrent();
-        break;
-    default:
-      return;
-    }
-
-    aEvent.preventDefault();
-    aEvent.stopPropagation();
-  },
-
   moveToPoint: function moveToPoint(aRule, aX, aY) {
     // XXX: Bug 1013408 - There is no alignment between the chrome window's
     // viewport size and the content viewport size in Android. This makes
     // sending mouse events beyond its bounds impossible.
     if (Utils.MozBuildApp === "mobile/android") {
       let mm = Utils.getMessageManager(Utils.CurrentBrowser);
       mm.sendAsyncMessage("AccessFu:MoveToPoint",
         {rule: aRule, x: aX, y: aY, origin: "top"});
@@ -832,21 +594,16 @@ var Input = {
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
     let offset = aData && typeof aData.keyIndex === "number" ?
                  aData.keyIndex - Output.brailleState.startOffset : -1;
 
     mm.sendAsyncMessage("AccessFu:Activate",
                         {offset, activateIfKey: aActivateIfKey});
   },
 
-  sendContextMenuMessage: function sendContextMenuMessage() {
-    let mm = Utils.getMessageManager(Utils.CurrentBrowser);
-    mm.sendAsyncMessage("AccessFu:ContextMenu", {});
-  },
-
   setEditState: function setEditState(aEditState) {
     Logger.debug(() => { return ["setEditState", JSON.stringify(aEditState)]; });
     this.editState = aEditState;
   },
 
   // XXX: This is here for backwards compatability with screen reader simulator
   // it should be removed when the extension is updated on amo.
   scroll: function scroll(aPage, aHorizontal) {
@@ -857,87 +614,15 @@ var Input = {
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
     mm.sendAsyncMessage("AccessFu:Scroll",
       {page: aPage, horizontal: aHorizontal, origin: "top"});
   },
 
   doScroll: function doScroll(aDetails) {
     let horizontal = aDetails.horizontal;
     let page = aDetails.page;
-    let p = AccessFu.adjustContentBounds(
-      aDetails.bounds, Utils.CurrentBrowser, true).center();
+    let p = AccessFu.screenToClientBounds(aDetails.bounds).center();
     Utils.winUtils.sendWheelEvent(p.x, p.y,
       horizontal ? page : 0, horizontal ? 0 : page, 0,
       Utils.win.WheelEvent.DOM_DELTA_PAGE, 0, 0, 0, 0);
-  },
-
-  get keyMap() {
-    delete this.keyMap;
-    this.keyMap = {
-      a: ["moveNext", "Anchor"],
-      A: ["movePrevious", "Anchor"],
-      b: ["moveNext", "Button"],
-      B: ["movePrevious", "Button"],
-      c: ["moveNext", "Combobox"],
-      C: ["movePrevious", "Combobox"],
-      d: ["moveNext", "Landmark"],
-      D: ["movePrevious", "Landmark"],
-      e: ["moveNext", "Entry"],
-      E: ["movePrevious", "Entry"],
-      f: ["moveNext", "FormElement"],
-      F: ["movePrevious", "FormElement"],
-      g: ["moveNext", "Graphic"],
-      G: ["movePrevious", "Graphic"],
-      h: ["moveNext", "Heading"],
-      H: ["movePrevious", "Heading"],
-      i: ["moveNext", "ListItem"],
-      I: ["movePrevious", "ListItem"],
-      k: ["moveNext", "Link"],
-      K: ["movePrevious", "Link"],
-      l: ["moveNext", "List"],
-      L: ["movePrevious", "List"],
-      p: ["moveNext", "PageTab"],
-      P: ["movePrevious", "PageTab"],
-      r: ["moveNext", "RadioButton"],
-      R: ["movePrevious", "RadioButton"],
-      s: ["moveNext", "Separator"],
-      S: ["movePrevious", "Separator"],
-      t: ["moveNext", "Table"],
-      T: ["movePrevious", "Table"],
-      x: ["moveNext", "Checkbox"],
-      X: ["movePrevious", "Checkbox"]
-    };
-
-    return this.keyMap;
-  },
-
-  quickNavMode: {
-    get current() {
-      return this.modes[this._currentIndex];
-    },
-
-    previous: function quickNavMode_previous() {
-      Services.prefs.setIntPref(QUICKNAV_INDEX_PREF,
-        this._currentIndex > 0 ?
-          this._currentIndex - 1 : this.modes.length - 1);
-    },
-
-    next: function quickNavMode_next() {
-      Services.prefs.setIntPref(QUICKNAV_INDEX_PREF,
-        this._currentIndex + 1 >= this.modes.length ?
-          0 : this._currentIndex + 1);
-    },
-
-    updateModes: function updateModes(aModes) {
-      if (aModes) {
-        this.modes = aModes.split(",");
-      } else {
-        this.modes = [];
-      }
-    },
-
-    updateCurrentMode: function updateCurrentMode(aModeIndex) {
-      Logger.debug("Quicknav mode:", this.modes[aModeIndex]);
-      this._currentIndex = aModeIndex;
-    }
   }
 };
 AccessFu.Input = Input;
--- a/accessible/jsat/ContentControl.jsm
+++ b/accessible/jsat/ContentControl.jsm
@@ -39,25 +39,23 @@ this.ContentControl.prototype = {
                        "AccessFu:MoveByGranularity",
                        "AccessFu:AndroidScroll"],
 
   start: function cc_start() {
     let cs = this._contentScope.get();
     for (let message of this.messagesOfInterest) {
       cs.addMessageListener(message, this);
     }
-    cs.addEventListener("mousemove", this);
   },
 
   stop: function cc_stop() {
     let cs = this._contentScope.get();
     for (let message of this.messagesOfInterest) {
       cs.removeMessageListener(message, this);
     }
-    cs.removeEventListener("mousemove", this);
   },
 
   get document() {
     return this._contentScope.get().content.document;
   },
 
   get window() {
     return this._contentScope.get().content;
@@ -101,17 +99,17 @@ this.ContentControl.prototype = {
 
     // Counter-intuitive, but scrolling backward (ie. up), actually should
     // increase range values.
     if (this.adjustRange(position, aMessage.json.direction === "backward")) {
       return;
     }
 
     this._contentScope.get().sendAsyncMessage("AccessFu:DoScroll",
-      { bounds: Utils.getBounds(position, true),
+      { bounds: Utils.getBounds(position),
         page: aMessage.json.direction === "forward" ? 1 : -1,
         horizontal: false });
   },
 
   handleMoveCursor: function cc_handleMoveCursor(aMessage) {
     let origin = aMessage.json.origin;
     let action = aMessage.json.action;
     let adjustRange = aMessage.json.adjustRange;
@@ -153,34 +151,21 @@ this.ContentControl.prototype = {
       // to it.
       this.sendToParent(aMessage);
     } else {
       this._contentScope.get().sendAsyncMessage("AccessFu:Present",
         Presentation.noMove(action));
     }
   },
 
-  handleEvent: function cc_handleEvent(aEvent) {
-    if (aEvent.type === "mousemove") {
-      this.handleMoveToPoint(
-        { json: { x: aEvent.screenX, y: aEvent.screenY, rule: "Simple" } });
-    }
-    if (!Utils.getMessageManager(aEvent.target)) {
-      aEvent.preventDefault();
-    } else {
-      aEvent.target.focus();
-    }
-  },
-
   handleMoveToPoint: function cc_handleMoveToPoint(aMessage) {
     let [x, y] = [aMessage.json.x, aMessage.json.y];
     let rule = TraversalRules[aMessage.json.rule];
 
-    let dpr = this.window.devicePixelRatio;
-    this.vc.moveToPoint(rule, x * dpr, y * dpr, true);
+    this.vc.moveToPoint(rule, x, y, true);
   },
 
   handleClearCursor: function cc_handleClearCursor(aMessage) {
     let forwarded = this.sendToChild(this.vc, aMessage);
     this.vc.position = null;
     if (!forwarded) {
       this._contentScope.get().sendAsyncMessage("AccessFu:CursorCleared");
     }
deleted file mode 100644
--- a/accessible/jsat/Gestures.jsm
+++ /dev/null
@@ -1,951 +0,0 @@
-/* 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/. */
-
-/* exported GestureSettings, GestureTracker */
-
-/** ****************************************************************************
-  All gestures have the following pathways when being resolved(v)/rejected(x):
-               Tap -> DoubleTap        (x)
-                   -> Dwell            (x)
-                   -> Swipe            (x)
-
-         DoubleTap -> TripleTap        (x)
-                   -> TapHold          (x)
-
-         TripleTap -> DoubleTapHold    (x)
-
-             Dwell -> DwellEnd         (v)
-
-             Swipe -> Explore          (x)
-
-           TapHold -> TapHoldEnd       (v)
-
-     DoubleTapHold -> DoubleTapHoldEnd (v)
-
-          DwellEnd -> Explore          (x)
-
-        TapHoldEnd -> Explore          (x)
-
-  DoubleTapHoldEnd -> Explore          (x)
-
-        ExploreEnd -> Explore          (x)
-
-           Explore -> ExploreEnd       (v)
-******************************************************************************/
-
-"use strict";
-
-var EXPORTED_SYMBOLS = ["GestureSettings", "GestureTracker"]; // jshint ignore:line
-
-ChromeUtils.defineModuleGetter(this, "Utils", // jshint ignore:line
-  "resource://gre/modules/accessibility/Utils.jsm");
-ChromeUtils.defineModuleGetter(this, "Logger", // jshint ignore:line
-  "resource://gre/modules/accessibility/Utils.jsm");
-ChromeUtils.defineModuleGetter(this, "setTimeout", // jshint ignore:line
-  "resource://gre/modules/Timer.jsm");
-ChromeUtils.defineModuleGetter(this, "clearTimeout", // jshint ignore:line
-  "resource://gre/modules/Timer.jsm");
-ChromeUtils.defineModuleGetter(this, "PromiseUtils", // jshint ignore:line
-  "resource://gre/modules/PromiseUtils.jsm");
-
-// Default maximum duration of swipe
-const SWIPE_MAX_DURATION = 200;
-// Default maximum amount of time allowed for a gesture to be considered a
-// multitouch
-const MAX_MULTITOUCH = 125;
-// Default maximum consecutive pointer event timeout
-const MAX_CONSECUTIVE_GESTURE_DELAY = 200;
-// Default delay before tap turns into dwell
-const DWELL_THRESHOLD = 250;
-// Minimal swipe distance in inches
-const SWIPE_MIN_DISTANCE = 0.4;
-// Maximum distance the pointer could move during a tap in inches
-const TAP_MAX_RADIUS = 0.2;
-// Directness coefficient. It is based on the maximum 15 degree angle between
-// consequent pointer move lines.
-const DIRECTNESS_COEFF = 1.44;
-// Amount in inches from the edges of the screen for it to be an edge swipe
-const EDGE = 0.1;
-// Multiply timeouts by this constant, x2 works great too for slower users.
-const TIMEOUT_MULTIPLIER = 1;
-// A single pointer down/up sequence periodically precedes the tripple swipe
-// gesture on Android. This delay acounts for that.
-const IS_ANDROID = Utils.MozBuildApp === "mobile/android" &&
-  Utils.AndroidSdkVersion >= 14;
-
-/**
- * A point object containing distance travelled data.
- * @param {Object} aPoint A point object that looks like: {
- *   x: x coordinate in pixels,
- *   y: y coordinate in pixels
- * }
- */
-function Point(aPoint) {
-  this.startX = this.x = aPoint.x;
-  this.startY = this.y = aPoint.y;
-  this.distanceTraveled = 0;
-  this.totalDistanceTraveled = 0;
-}
-
-Point.prototype = {
-  /**
-   * Update the current point coordiates.
-   * @param  {Object} aPoint A new point coordinates.
-   */
-  update: function Point_update(aPoint) {
-    let lastX = this.x;
-    let lastY = this.y;
-    this.x = aPoint.x;
-    this.y = aPoint.y;
-    this.distanceTraveled = this.getDistanceToCoord(lastX, lastY);
-    this.totalDistanceTraveled += this.distanceTraveled;
-  },
-
-  reset: function Point_reset() {
-    this.distanceTraveled = 0;
-    this.totalDistanceTraveled = 0;
-  },
-
-  /**
-   * Get distance between the current point coordinates and the given ones.
-   * @param  {Number} aX A pixel value for the x coordinate.
-   * @param  {Number} aY A pixel value for the y coordinate.
-   * @return {Number} A distance between point's current and the given
-   * coordinates.
-   */
-  getDistanceToCoord: function Point_getDistanceToCoord(aX, aY) {
-    return Math.hypot(this.x - aX, this.y - aY);
-  },
-
-  /**
-   * Get the direct distance travelled by the point so far.
-   */
-  get directDistanceTraveled() {
-    return this.getDistanceToCoord(this.startX, this.startY);
-  }
-};
-
-/**
- * An externally accessible collection of settings used in gesture resolition.
- * @type {Object}
- */
-var GestureSettings = { // jshint ignore:line
-  /**
-   * Maximum duration of swipe
-   * @type {Number}
-   */
-  swipeMaxDuration: SWIPE_MAX_DURATION * TIMEOUT_MULTIPLIER,
-
-  /**
-   * Maximum amount of time allowed for a gesture to be considered a multitouch.
-   * @type {Number}
-   */
-  maxMultitouch: MAX_MULTITOUCH * TIMEOUT_MULTIPLIER,
-
-  /**
-   * Maximum consecutive pointer event timeout.
-   * @type {Number}
-   */
-  maxConsecutiveGestureDelay:
-    MAX_CONSECUTIVE_GESTURE_DELAY * TIMEOUT_MULTIPLIER,
-
-  /**
-   * A maximum time we wait for a next pointer down event to consider a sequence
-   * a multi-action gesture.
-   * @type {Number}
-   */
-  maxGestureResolveTimeout:
-    MAX_CONSECUTIVE_GESTURE_DELAY * TIMEOUT_MULTIPLIER,
-
-  /**
-   * Delay before tap turns into dwell
-   * @type {Number}
-   */
-  dwellThreshold: DWELL_THRESHOLD * TIMEOUT_MULTIPLIER,
-
-  /**
-   * Minimum distance that needs to be travelled for the pointer move to be
-   * fired.
-   * @type {Number}
-   */
-  travelThreshold: 0.025
-};
-
-/**
- * An interface that handles the pointer events and calculates the appropriate
- * gestures.
- * @type {Object}
- */
-var GestureTracker = { // jshint ignore:line
-  /**
-   * Reset GestureTracker to its initial state.
-   * @return {[type]} [description]
-   */
-  reset: function GestureTracker_reset() {
-    if (this.current) {
-      this.current.clearTimer();
-    }
-    delete this.current;
-  },
-
-  /**
-   * Create a new gesture object and attach resolution handler to it as well as
-   * handle the incoming pointer event.
-   * @param  {Object} aDetail A new pointer event detail.
-   * @param  {Number} aTimeStamp A new pointer event timeStamp.
-   * @param  {Function} aGesture A gesture constructor (default: Tap).
-   */
-  _init: function GestureTracker__init(aDetail, aTimeStamp, aGesture) {
-    // Only create a new gesture on |pointerdown| event.
-    if (aDetail.type !== "pointerdown") {
-      return;
-    }
-    let GestureConstructor = aGesture || (IS_ANDROID ? DoubleTap : Tap);
-    this._create(GestureConstructor);
-    this._update(aDetail, aTimeStamp);
-  },
-
-  /**
-   * Handle the incoming pointer event with the existing gesture object(if
-   * present) or with the newly created one.
-   * @param  {Object} aDetail A new pointer event detail.
-   * @param  {Number} aTimeStamp A new pointer event timeStamp.
-   */
-  handle: function GestureTracker_handle(aDetail, aTimeStamp) {
-    Logger.gesture(() => {
-      return ["Pointer event", Utils.dpi, "at:", aTimeStamp, JSON.stringify(aDetail)];
-    });
-    this[this.current ? "_update" : "_init"](aDetail, aTimeStamp);
-  },
-
-  /**
-   * Create a new gesture object and attach resolution handler to it.
-   * @param  {Function} aGesture A gesture constructor.
-   * @param  {Number} aTimeStamp An original pointer event timeStamp.
-   * @param  {Array} aPoints All changed points associated with the new pointer
-   * event.
-   * @param {?String} aLastEvent Last pointer event type.
-   */
-  _create: function GestureTracker__create(aGesture, aTimeStamp, aPoints, aLastEvent) {
-    this.current = new aGesture(aTimeStamp, aPoints, aLastEvent); /* A constructor name should start with an uppercase letter. */ // jshint ignore:line
-    this.current.then(this._onFulfill.bind(this));
-  },
-
-  /**
-   * Handle the incoming pointer event with the existing gesture object.
-   * @param  {Object} aDetail A new pointer event detail.
-   * @param  {Number} aTimeStamp A new pointer event timeStamp.
-   */
-  _update: function GestureTracker_update(aDetail, aTimeStamp) {
-    this.current[aDetail.type](aDetail.points, aTimeStamp);
-  },
-
-  /**
-   * A resolution handler function for the current gesture promise.
-   * @param  {Object} aResult A resolution payload with the relevant gesture id
-   * and an optional new gesture contructor.
-   */
-  _onFulfill: function GestureTracker__onFulfill(aResult) {
-    let {id, gestureType} = aResult;
-    let current = this.current;
-    // Do nothing if there's no existing gesture or there's already a newer
-    // gesture.
-    if (!current || current.id !== id) {
-      return;
-    }
-    // Only create a gesture if we got a constructor.
-    if (gestureType) {
-      this._create(gestureType, current.startTime, current.points,
-        current.lastEvent);
-    } else {
-      this.current.clearTimer();
-      delete this.current;
-    }
-  }
-};
-
-/**
- * Compile a mozAccessFuGesture detail structure.
- * @param  {String} aType A gesture type.
- * @param  {Object} aPoints Gesture's points.
- * @param  {String} xKey A default key for the x coordinate. Default is
- * 'startX'.
- * @param  {String} yKey A default key for the y coordinate. Default is
- * 'startY'.
- * @return {Object} a mozAccessFuGesture detail structure.
- */
-function compileDetail(aType, aPoints, keyMap = {x: "startX", y: "startY"}) {
-  let touches = [];
-  let maxDeltaX = 0;
-  let maxDeltaY = 0;
-  for (let identifier in aPoints) {
-    let point = aPoints[identifier];
-    let touch = {};
-    for (let key in keyMap) {
-      touch[key] = point[keyMap[key]];
-    }
-    touches.push(touch);
-    let deltaX = point.x - point.startX;
-    let deltaY = point.y - point.startY;
-    // Determine the maximum x and y travel intervals.
-    if (Math.abs(maxDeltaX) < Math.abs(deltaX)) {
-      maxDeltaX = deltaX;
-    }
-    if (Math.abs(maxDeltaY) < Math.abs(deltaY)) {
-      maxDeltaY = deltaY;
-    }
-    // Since the gesture is resolving, reset the points' distance information
-    // since they are passed to the next potential gesture.
-    point.reset();
-  }
-  return {
-    type: aType,
-    touches,
-    deltaX: maxDeltaX,
-    deltaY: maxDeltaY
-  };
-}
-
-/**
- * A general gesture object.
- * @param {Number} aTimeStamp An original pointer event's timeStamp that started
- * the gesture resolution sequence.
- * @param {Object} aPoints An existing set of points (from previous events).
- * Default is an empty object.
- * @param {?String} aLastEvent Last pointer event type.
- */
-function Gesture(aTimeStamp, aPoints = {}, aLastEvent = undefined) {
-  this.startTime = Date.now();
-  Logger.gesture("Creating", this.id, "gesture.");
-  this.points = aPoints;
-  this.lastEvent = aLastEvent;
-  this._deferred = PromiseUtils.defer();
-  // Call this._handleResolve or this._handleReject when the promise is
-  // fulfilled with either resolve or reject.
-  this.promise = this._deferred.promise.then(this._handleResolve.bind(this),
-    this._handleReject.bind(this));
-  this.startTimer(aTimeStamp);
-}
-
-Gesture.prototype = {
-  /**
-   * Get the gesture timeout delay.
-   * @return {Number}
-   */
-  _getDelay: function Gesture__getDelay() {
-    // If nothing happens withing the
-    // GestureSettings.maxConsecutiveGestureDelay, we should not wait for any
-    // more pointer events and consider them the part of the same gesture -
-    // reject this gesture promise.
-    return GestureSettings.maxConsecutiveGestureDelay;
-  },
-
-  /**
-   * Clear the existing timer.
-   */
-  clearTimer: function Gesture_clearTimer() {
-    Logger.gesture("clearTimeout", this.type);
-    clearTimeout(this._timer);
-    delete this._timer;
-  },
-
-  /**
-   * Start the timer for gesture timeout.
-   * @param {Number} aTimeStamp An original pointer event's timeStamp that
-   * started the gesture resolution sequence.
-   */
-  startTimer: function Gesture_startTimer(aTimeStamp) {
-    Logger.gesture("startTimer", this.type);
-    this.clearTimer();
-    let delay = this._getDelay(aTimeStamp);
-    let handler = () => {
-      Logger.gesture("timer handler");
-      this.clearTimer();
-      if (!this._inProgress) {
-        this._deferred.reject();
-      } else if (this._rejectToOnWait) {
-        this._deferred.reject(this._rejectToOnWait);
-      }
-    };
-    if (delay <= 0) {
-      handler();
-    } else {
-      this._timer = setTimeout(handler, delay);
-    }
-  },
-
-  /**
-   * Add a gesture promise resolution callback.
-   * @param  {Function} aCallback
-   */
-  then: function Gesture_then(aCallback) {
-    this.promise.then(aCallback);
-  },
-
-  /**
-   * Update gesture's points. Test the points set with the optional gesture test
-   * function.
-   * @param  {Array} aPoints An array with the changed points from the new
-   * pointer event.
-   * @param {String} aType Pointer event type.
-   * @param  {Boolean} aCanCreate A flag that enables including the new points.
-   * Default is false.
-   * @param  {Boolean} aNeedComplete A flag that indicates that the gesture is
-   * completing. Default is false.
-   * @return {Boolean} Indicates whether the gesture can be complete (it is
-   * set to true iff the aNeedComplete is true and there was a change to at
-   * least one point that belongs to the gesture).
-   */
-  _update: function Gesture__update(aPoints, aType, aCanCreate = false, aNeedComplete = false) {
-    let complete;
-    let lastEvent;
-    for (let point of aPoints) {
-      let identifier = point.identifier;
-      let gesturePoint = this.points[identifier];
-      if (gesturePoint) {
-        if (aType === "pointerdown" && aCanCreate) {
-          // scratch the previous pointer with that id.
-          this.points[identifier] = new Point(point);
-        } else {
-          gesturePoint.update(point);
-        }
-        if (aNeedComplete) {
-          // Since the gesture is completing and at least one of the gesture
-          // points is updated, set the return value to true.
-          complete = true;
-        }
-        lastEvent = lastEvent || aType;
-      } else if (aCanCreate) {
-        // Only create a new point if aCanCreate is true.
-        this.points[identifier] =
-          new Point(point);
-        lastEvent = lastEvent || aType;
-      }
-    }
-    this.lastEvent = lastEvent || this.lastEvent;
-    // If test function is defined test the points.
-    if (this.test) {
-      this.test(complete);
-    }
-    return complete;
-  },
-
-  /**
-   * Emit a mozAccessFuGesture (when the gesture is resolved).
-   * @param  {Object} aDetail a compiled mozAccessFuGesture detail structure.
-   */
-  _emit: function Gesture__emit(aDetail) {
-    let evt = new Utils.win.CustomEvent("mozAccessFuGesture", {
-      bubbles: true,
-      cancelable: true,
-      detail: aDetail
-    });
-    Utils.win.dispatchEvent(evt);
-  },
-
-  /**
-   * Handle the pointer down event.
-   * @param  {Array} aPoints A new pointer down points.
-   * @param  {Number} aTimeStamp A new pointer down timeStamp.
-   */
-  pointerdown: function Gesture_pointerdown(aPoints, aTimeStamp) {
-    this._inProgress = true;
-    this._update(aPoints, "pointerdown",
-      aTimeStamp - this.startTime < GestureSettings.maxMultitouch);
-  },
-
-  /**
-   * Handle the pointer move event.
-   * @param  {Array} aPoints A new pointer move points.
-   */
-  pointermove: function Gesture_pointermove(aPoints) {
-    this._update(aPoints, "pointermove");
-  },
-
-  /**
-   * Handle the pointer up event.
-   * @param  {Array} aPoints A new pointer up points.
-   */
-  pointerup: function Gesture_pointerup(aPoints) {
-    let complete = this._update(aPoints, "pointerup", false, true);
-    if (complete) {
-      this._deferred.resolve();
-    }
-  },
-
-  /**
-   * A subsequent gesture constructor to resolve the current one to. E.g.
-   * tap->doubletap, dwell->dwellend, etc.
-   * @type {Function}
-   */
-  resolveTo: null,
-
-  /**
-   * A unique id for the gesture. Composed of the type + timeStamp.
-   */
-  get id() {
-    delete this._id;
-    this._id = this.type + this.startTime;
-    return this._id;
-  },
-
-  /**
-   * A gesture promise resolve callback. Compile and emit the gesture.
-   * @return {Object} Returns a structure to the gesture handler that looks like
-   * this: {
-   *   id: current gesture id,
-   *   gestureType: an optional subsequent gesture constructor.
-   * }
-   */
-  _handleResolve: function Gesture__handleResolve() {
-    if (this.isComplete) {
-      return;
-    }
-    Logger.gesture("Resolving", this.id, "gesture.");
-    this.isComplete = true;
-    this.clearTimer();
-    let detail = this.compile();
-    if (detail) {
-      this._emit(detail);
-    }
-    return {
-      id: this.id,
-      gestureType: this.resolveTo
-    };
-  },
-
-  /**
-   * A gesture promise reject callback.
-   * @return {Object} Returns a structure to the gesture handler that looks like
-   * this: {
-   *   id: current gesture id,
-   *   gestureType: an optional subsequent gesture constructor.
-   * }
-   */
-  _handleReject: function Gesture__handleReject(aRejectTo) {
-    if (this.isComplete) {
-      return;
-    }
-    Logger.gesture("Rejecting", this.id, "gesture.");
-    this.isComplete = true;
-    this.clearTimer();
-    return {
-      id: this.id,
-      gestureType: aRejectTo
-    };
-  },
-
-  /**
-   * A default compilation function used to build the mozAccessFuGesture event
-   * detail. The detail always includes the type and the touches associated
-   * with the gesture.
-   * @return {Object} Gesture event detail.
-   */
-  compile: function Gesture_compile() {
-    return compileDetail(this.type, this.points);
-  }
-};
-
-/**
- * A mixin for an explore related object.
- */
-function ExploreGesture() {
-  this.compile = () => {
-    // Unlike most of other gestures explore based gestures compile using the
-    // current point position and not the start one.
-    return compileDetail(this.type, this.points, {x: "x", y: "y"});
-  };
-}
-
-/**
- * Check the in progress gesture for completion.
- */
-function checkProgressGesture(aGesture) {
-  aGesture._inProgress = true;
-  if (aGesture.lastEvent === "pointerup") {
-    if (aGesture.test) {
-      aGesture.test(true);
-    }
-    aGesture._deferred.resolve();
-  }
-}
-
-/**
- * A common travel gesture. When the travel gesture is created, all subsequent
- * pointer events' points are tested for their total distance traveled. If that
- * distance exceeds the _threshold distance, the gesture will be rejected to a
- * _travelTo gesture.
- * @param {Number} aTimeStamp An original pointer event's timeStamp that started
- * the gesture resolution sequence.
- * @param {Object} aPoints An existing set of points (from previous events).
- * @param {?String} aLastEvent Last pointer event type.
- * @param {Function} aTravelTo A contructor for the gesture to reject to when
- * travelling (default: Explore).
- * @param {Number} aThreshold Travel threshold (default:
- * GestureSettings.travelThreshold).
- */
-function TravelGesture(aTimeStamp, aPoints, aLastEvent, aTravelTo = Explore, aThreshold = GestureSettings.travelThreshold) {
-  Gesture.call(this, aTimeStamp, aPoints, aLastEvent);
-  this._travelTo = aTravelTo;
-  this._threshold = aThreshold;
-}
-
-TravelGesture.prototype = Object.create(Gesture.prototype);
-
-/**
- * Test the gesture points for travel. The gesture will be rejected to
- * this._travelTo gesture iff at least one point crosses this._threshold.
- */
-TravelGesture.prototype.test = function TravelGesture_test() {
-  if (!this._travelTo) {
-    return;
-  }
-  for (let identifier in this.points) {
-    let point = this.points[identifier];
-    if (point.totalDistanceTraveled / Utils.dpi > this._threshold) {
-      this._deferred.reject(this._travelTo);
-      return;
-    }
-  }
-};
-
-/**
- * DwellEnd gesture.
- * @param {Number} aTimeStamp An original pointer event's timeStamp that started
- * the gesture resolution sequence.
- * @param {Object} aPoints An existing set of points (from previous events).
- * @param {?String} aLastEvent Last pointer event type.
- */
-function DwellEnd(aTimeStamp, aPoints, aLastEvent) {
-  this._inProgress = true;
-  // If the pointer travels, reject to Explore.
-  TravelGesture.call(this, aTimeStamp, aPoints, aLastEvent);
-  checkProgressGesture(this);
-}
-
-DwellEnd.prototype = Object.create(TravelGesture.prototype);
-DwellEnd.prototype.type = "dwellend";
-
-/**
- * TapHoldEnd gesture. This gesture can be represented as the following diagram:
- * pointerdown-pointerup-pointerdown-*wait*-pointerup.
- * @param {Number} aTimeStamp An original pointer event's timeStamp that started
- * the gesture resolution sequence.
- * @param {Object} aPoints An existing set of points (from previous events).
- * @param {?String} aLastEvent Last pointer event type.
- */
-function TapHoldEnd(aTimeStamp, aPoints, aLastEvent) {
-  this._inProgress = true;
-  // If the pointer travels, reject to Explore.
-  TravelGesture.call(this, aTimeStamp, aPoints, aLastEvent);
-  checkProgressGesture(this);
-}
-
-TapHoldEnd.prototype = Object.create(TravelGesture.prototype);
-TapHoldEnd.prototype.type = "tapholdend";
-
-/**
- * DoubleTapHoldEnd gesture. This gesture can be represented as the following
- * diagram:
- * pointerdown-pointerup-pointerdown-pointerup-pointerdown-*wait*-pointerup.
- * @param {Number} aTimeStamp An original pointer event's timeStamp that started
- * the gesture resolution sequence.
- * @param {Object} aPoints An existing set of points (from previous events).
- * @param {?String} aLastEvent Last pointer event type.
- */
-function DoubleTapHoldEnd(aTimeStamp, aPoints, aLastEvent) {
-  this._inProgress = true;
-  // If the pointer travels, reject to Explore.
-  TravelGesture.call(this, aTimeStamp, aPoints, aLastEvent);
-  checkProgressGesture(this);
-}
-
-DoubleTapHoldEnd.prototype = Object.create(TravelGesture.prototype);
-DoubleTapHoldEnd.prototype.type = "doubletapholdend";
-
-/**
- * A common tap gesture object.
- * @param {Number} aTimeStamp An original pointer event's timeStamp that started
- * the gesture resolution sequence.
- * @param {Object} aPoints An existing set of points (from previous events).
- * @param {?String} aLastEvent Last pointer event type.
- * @param {Function} aRejectToOnWait A constructor for the next gesture to
- * reject to in case no pointermove or pointerup happens within the
- * GestureSettings.dwellThreshold.
- * @param {Function} aTravelTo An optional constuctor for the next gesture to
- * reject to in case the the TravelGesture test fails.
- * @param {Function} aRejectToOnPointerDown A constructor for the gesture to
- * reject to if a finger comes down immediately after the tap.
- */
-function TapGesture(aTimeStamp, aPoints, aLastEvent, aRejectToOnWait, aTravelTo, aRejectToOnPointerDown) {
-  this._rejectToOnWait = aRejectToOnWait;
-  this._rejectToOnPointerDown = aRejectToOnPointerDown;
-  // If the pointer travels, reject to aTravelTo.
-  TravelGesture.call(this, aTimeStamp, aPoints, aLastEvent, aTravelTo,
-    TAP_MAX_RADIUS);
-}
-
-TapGesture.prototype = Object.create(TravelGesture.prototype);
-TapGesture.prototype._getDelay = function TapGesture__getDelay() {
-  // If, for TapGesture, no pointermove or pointerup happens within the
-  // GestureSettings.dwellThreshold, reject.
-  // Note: the original pointer event's timeStamp is irrelevant here.
-  return GestureSettings.dwellThreshold;
-};
-
-TapGesture.prototype.pointerup = function TapGesture_pointerup(aPoints) {
-    if (this._rejectToOnPointerDown) {
-      let complete = this._update(aPoints, "pointerup", false, true);
-      if (complete) {
-        this.clearTimer();
-        if (GestureSettings.maxGestureResolveTimeout) {
-          this._pointerUpTimer = setTimeout(() => {
-            clearTimeout(this._pointerUpTimer);
-            delete this._pointerUpTimer;
-            this._deferred.resolve();
-          }, GestureSettings.maxGestureResolveTimeout);
-        } else {
-          this._deferred.resolve();
-        }
-      }
-    } else {
-      TravelGesture.prototype.pointerup.call(this, aPoints);
-    }
-};
-
-TapGesture.prototype.pointerdown = function TapGesture_pointerdown(aPoints, aTimeStamp) {
-  if (this._pointerUpTimer) {
-    clearTimeout(this._pointerUpTimer);
-    delete this._pointerUpTimer;
-    this._deferred.reject(this._rejectToOnPointerDown);
-  } else {
-    TravelGesture.prototype.pointerdown.call(this, aPoints, aTimeStamp);
-  }
-};
-
-
-/**
- * Tap gesture.
- * @param {Number} aTimeStamp An original pointer event's timeStamp that started
- * the gesture resolution sequence.
- * @param {Object} aPoints An existing set of points (from previous events).
- * @param {?String} aLastEvent Last pointer event type.
- */
-function Tap(aTimeStamp, aPoints, aLastEvent) {
-  // If the pointer travels, reject to Swipe.
-  TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, Dwell, Swipe, DoubleTap);
-}
-
-Tap.prototype = Object.create(TapGesture.prototype);
-Tap.prototype.type = "tap";
-
-
-/**
- * Double Tap gesture.
- * @param {Number} aTimeStamp An original pointer event's timeStamp that started
- * the gesture resolution sequence.
- * @param {Object} aPoints An existing set of points (from previous events).
- * @param {?String} aLastEvent Last pointer event type.
- */
-function DoubleTap(aTimeStamp, aPoints, aLastEvent) {
-  this._inProgress = true;
-  TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, TapHold, null, TripleTap);
-}
-
-DoubleTap.prototype = Object.create(TapGesture.prototype);
-DoubleTap.prototype.type = "doubletap";
-
-/**
- * Triple Tap gesture.
- * @param {Number} aTimeStamp An original pointer event's timeStamp that started
- * the gesture resolution sequence.
- * @param {Object} aPoints An existing set of points (from previous events).
- * @param {?String} aLastEvent Last pointer event type.
- */
-function TripleTap(aTimeStamp, aPoints, aLastEvent) {
-  this._inProgress = true;
-  TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, DoubleTapHold, null, null);
-}
-
-TripleTap.prototype = Object.create(TapGesture.prototype);
-TripleTap.prototype.type = "tripletap";
-
-/**
- * Common base object for gestures that are created as resolved.
- * @param {Number} aTimeStamp An original pointer event's timeStamp that started
- * the gesture resolution sequence.
- * @param {Object} aPoints An existing set of points (from previous events).
- * @param {?String} aLastEvent Last pointer event type.
- */
-function ResolvedGesture(aTimeStamp, aPoints, aLastEvent) {
-  Gesture.call(this, aTimeStamp, aPoints, aLastEvent);
-  // Resolve the guesture right away.
-  this._deferred.resolve();
-}
-
-ResolvedGesture.prototype = Object.create(Gesture.prototype);
-
-/**
- * Dwell gesture
- * @param {Number} aTimeStamp An original pointer event's timeStamp that started
- * the gesture resolution sequence.
- * @param {Object} aPoints An existing set of points (from previous events).
- * @param {?String} aLastEvent Last pointer event type.
- */
-function Dwell(aTimeStamp, aPoints, aLastEvent) {
-  ResolvedGesture.call(this, aTimeStamp, aPoints, aLastEvent);
-}
-
-Dwell.prototype = Object.create(ResolvedGesture.prototype);
-Dwell.prototype.type = "dwell";
-Dwell.prototype.resolveTo = DwellEnd;
-
-/**
- * TapHold gesture
- * @param {Number} aTimeStamp An original pointer event's timeStamp that started
- * the gesture resolution sequence.
- * @param {Object} aPoints An existing set of points (from previous events).
- * @param {?String} aLastEvent Last pointer event type.
- */
-function TapHold(aTimeStamp, aPoints, aLastEvent) {
-  ResolvedGesture.call(this, aTimeStamp, aPoints, aLastEvent);
-}
-
-TapHold.prototype = Object.create(ResolvedGesture.prototype);
-TapHold.prototype.type = "taphold";
-TapHold.prototype.resolveTo = TapHoldEnd;
-
-/**
- * DoubleTapHold gesture
- * @param {Number} aTimeStamp An original pointer event's timeStamp that started
- * the gesture resolution sequence.
- * @param {Object} aPoints An existing set of points (from previous events).
- * @param {?String} aLastEvent Last pointer event type.
- */
-function DoubleTapHold(aTimeStamp, aPoints, aLastEvent) {
-  ResolvedGesture.call(this, aTimeStamp, aPoints, aLastEvent);
-}
-
-DoubleTapHold.prototype = Object.create(ResolvedGesture.prototype);
-DoubleTapHold.prototype.type = "doubletaphold";
-DoubleTapHold.prototype.resolveTo = DoubleTapHoldEnd;
-
-/**
- * Explore gesture
- * @param {Number} aTimeStamp An original pointer event's timeStamp that started
- * the gesture resolution sequence.
- * @param {Object} aPoints An existing set of points (from previous events).
- * @param {?String} aLastEvent Last pointer event type.
- */
-function Explore(aTimeStamp, aPoints, aLastEvent) {
-  ExploreGesture.call(this);
-  ResolvedGesture.call(this, aTimeStamp, aPoints, aLastEvent);
-}
-
-Explore.prototype = Object.create(ResolvedGesture.prototype);
-Explore.prototype.type = "explore";
-Explore.prototype.resolveTo = ExploreEnd;
-
-/**
- * ExploreEnd gesture.
- * @param {Number} aTimeStamp An original pointer event's timeStamp that started
- * the gesture resolution sequence.
- * @param {Object} aPoints An existing set of points (from previous events).
- * @param {?String} aLastEvent Last pointer event type.
- */
-function ExploreEnd(aTimeStamp, aPoints, aLastEvent) {
-  this._inProgress = true;
-  ExploreGesture.call(this);
-  // If the pointer travels, reject to Explore.
-  TravelGesture.call(this, aTimeStamp, aPoints, aLastEvent);
-  checkProgressGesture(this);
-}
-
-ExploreEnd.prototype = Object.create(TravelGesture.prototype);
-ExploreEnd.prototype.type = "exploreend";
-
-/**
- * Swipe gesture.
- * @param {Number} aTimeStamp An original pointer event's timeStamp that started
- * the gesture resolution sequence.
- * @param {Object} aPoints An existing set of points (from previous events).
- * @param {?String} aLastEvent Last pointer event type.
- */
-function Swipe(aTimeStamp, aPoints, aLastEvent) {
-  this._inProgress = true;
-  this._rejectToOnWait = Explore;
-  Gesture.call(this, aTimeStamp, aPoints, aLastEvent);
-  checkProgressGesture(this);
-}
-
-Swipe.prototype = Object.create(Gesture.prototype);
-Swipe.prototype.type = "swipe";
-Swipe.prototype._getDelay = function Swipe__getDelay(aTimeStamp) {
-  // Swipe should be completed within the GestureSettings.swipeMaxDuration from
-  // the initial pointer down event.
-  return GestureSettings.swipeMaxDuration - this.startTime + aTimeStamp;
-};
-
-/**
- * Determine wither the gesture was Swipe or Explore.
- * @param  {Booler} aComplete A flag that indicates whether the gesture is and
- * will be complete after the test.
- */
-Swipe.prototype.test = function Swipe_test(aComplete) {
-  if (!aComplete) {
-    // No need to test if the gesture is not completing or can't be complete.
-    return;
-  }
-  let reject = true;
-  // If at least one point travelled for more than SWIPE_MIN_DISTANCE and it was
-  // direct enough, consider it a Swipe.
-  for (let identifier in this.points) {
-    let point = this.points[identifier];
-    let directDistance = point.directDistanceTraveled;
-    if (directDistance / Utils.dpi >= SWIPE_MIN_DISTANCE ||
-      directDistance * DIRECTNESS_COEFF >= point.totalDistanceTraveled) {
-      reject = false;
-    }
-  }
-  if (reject) {
-    this._deferred.reject(Explore);
-  }
-};
-
-/**
- * Compile a swipe related mozAccessFuGesture event detail.
- * @return {Object} A mozAccessFuGesture detail object.
- */
-Swipe.prototype.compile = function Swipe_compile() {
-  let type = this.type;
-  let detail = compileDetail(type, this.points,
-    {x1: "startX", y1: "startY", x2: "x", y2: "y"});
-  let deltaX = detail.deltaX;
-  let deltaY = detail.deltaY;
-  let edge = EDGE * Utils.dpi;
-  if (Math.abs(deltaX) > Math.abs(deltaY)) {
-    // Horizontal swipe.
-    let startPoints = detail.touches.map(touch => touch.x1);
-    if (deltaX > 0) {
-      detail.type = type + "right";
-      detail.edge = Math.min.apply(null, startPoints) <= edge;
-    } else {
-      detail.type = type + "left";
-      detail.edge =
-        Utils.win.screen.width - Math.max.apply(null, startPoints) <= edge;
-    }
-  } else {
-    // Vertical swipe.
-    let startPoints = detail.touches.map(touch => touch.y1);
-    if (deltaY > 0) {
-      detail.type = type + "down";
-      detail.edge = Math.min.apply(null, startPoints) <= edge;
-    } else {
-      detail.type = type + "up";
-      detail.edge =
-        Utils.win.screen.height - Math.max.apply(null, startPoints) <= edge;
-    }
-  }
-  return detail;
-};
deleted file mode 100644
--- a/accessible/jsat/PointerAdapter.jsm
+++ /dev/null
@@ -1,158 +0,0 @@
-/* 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/. */
-
-/* exported PointerRelay, PointerAdapter */
-
-"use strict";
-
-var EXPORTED_SYMBOLS = ["PointerRelay", "PointerAdapter"]; // jshint ignore:line
-
-ChromeUtils.defineModuleGetter(this, "Utils", // jshint ignore:line
-  "resource://gre/modules/accessibility/Utils.jsm");
-ChromeUtils.defineModuleGetter(this, "Logger", // jshint ignore:line
-  "resource://gre/modules/accessibility/Utils.jsm");
-ChromeUtils.defineModuleGetter(this, "GestureSettings", // jshint ignore:line
-  "resource://gre/modules/accessibility/Gestures.jsm");
-ChromeUtils.defineModuleGetter(this, "GestureTracker", // jshint ignore:line
-  "resource://gre/modules/accessibility/Gestures.jsm");
-
-// The virtual touch ID generated by a mouse event.
-const MOUSE_ID = "mouse";
-// Synthesized touch ID.
-const SYNTH_ID = -1;
-
-var PointerRelay = { // jshint ignore:line
-  /**
-   * A mapping of events we should be intercepting. Entries with a value of
-   * |true| are used for compiling high-level gesture events. Entries with a
-   * value of |false| are cancelled and do not propogate to content.
-   */
-  get _eventsOfInterest() {
-    delete this._eventsOfInterest;
-
-    switch (Utils.widgetToolkit) {
-      case "android":
-        this._eventsOfInterest = {
-          "touchstart": true,
-          "touchmove": true,
-          "touchend": true };
-        break;
-
-      default:
-        // Desktop.
-        this._eventsOfInterest = {
-          "mousemove": true,
-          "mousedown": true,
-          "mouseup": true,
-          "click": false
-        };
-        if ("ontouchstart" in Utils.win) {
-          for (let eventType of ["touchstart", "touchmove", "touchend"]) {
-            this._eventsOfInterest[eventType] = true;
-          }
-        }
-        break;
-    }
-
-    return this._eventsOfInterest;
-  },
-
-  _eventMap: {
-    "touchstart": "pointerdown",
-    "mousedown": "pointerdown",
-    "touchmove": "pointermove",
-    "mousemove": "pointermove",
-    "touchend": "pointerup",
-    "mouseup": "pointerup"
-  },
-
-  start: function PointerRelay_start(aOnPointerEvent) {
-    Logger.debug("PointerRelay.start");
-    this.onPointerEvent = aOnPointerEvent;
-    for (let eventType in this._eventsOfInterest) {
-      Utils.win.addEventListener(eventType, this, true, true);
-    }
-  },
-
-  stop: function PointerRelay_stop() {
-    Logger.debug("PointerRelay.stop");
-    delete this.lastPointerMove;
-    delete this.onPointerEvent;
-    for (let eventType in this._eventsOfInterest) {
-      Utils.win.removeEventListener(eventType, this, true, true);
-    }
-  },
-
-  handleEvent: function PointerRelay_handleEvent(aEvent) {
-    // Don't bother with chrome mouse events.
-    if (Utils.MozBuildApp === "browser" && aEvent.view.top.isChromeWindow) {
-      return;
-    }
-    // aEvent might not be a mouse event here at all; don't do the
-    // mozInputSource check unless it is.
-    if (("mozInputSource" in aEvent &&
-         aEvent.mozInputSource === aEvent.MOZ_SOURCE_UNKNOWN) ||
-        aEvent.isSynthesized) {
-      // Ignore events that are scripted or clicks from the a11y API.
-      return;
-    }
-
-    let changedTouches = aEvent.changedTouches || [{
-      identifier: MOUSE_ID,
-      screenX: aEvent.screenX,
-      screenY: aEvent.screenY,
-      target: aEvent.target
-    }];
-
-    if (Utils.widgetToolkit === "android" &&
-      changedTouches.length === 1 && changedTouches[0].identifier === 1) {
-      return;
-    }
-
-    if (changedTouches.length === 1 &&
-        changedTouches[0].identifier === SYNTH_ID) {
-      return;
-    }
-
-    aEvent.preventDefault();
-    aEvent.stopImmediatePropagation();
-
-    let type = aEvent.type;
-    if (!this._eventsOfInterest[type]) {
-      return;
-    }
-    let pointerType = this._eventMap[type];
-    this.onPointerEvent({
-      type: pointerType,
-      points: Array.prototype.map.call(changedTouches,
-        function mapTouch(aTouch) {
-          return {
-            identifier: aTouch.identifier,
-            x: aTouch.screenX,
-            y: aTouch.screenY
-          };
-        }
-      )
-    });
-  }
-};
-
-var PointerAdapter = { // jshint ignore:line
-  start: function PointerAdapter_start() {
-    Logger.debug("PointerAdapter.start");
-    GestureTracker.reset();
-    PointerRelay.start(this.handleEvent);
-  },
-
-  stop: function PointerAdapter_stop() {
-    Logger.debug("PointerAdapter.stop");
-    PointerRelay.stop();
-    GestureTracker.reset();
-  },
-
-  handleEvent: function PointerAdapter_handleEvent(aDetail) {
-    let timeStamp = Date.now();
-    GestureTracker.handle(aDetail, timeStamp);
-  }
-};
--- a/accessible/jsat/Utils.jsm
+++ b/accessible/jsat/Utils.jsm
@@ -297,39 +297,31 @@ var Utils = { // jshint ignore:line
   getContentResolution: function _getContentResolution(aAccessible) {
     let res = { value: 1 };
     aAccessible.document.window.QueryInterface(
       Ci.nsIInterfaceRequestor).getInterface(
       Ci.nsIDOMWindowUtils).getResolution(res);
     return res.value;
   },
 
-  getBounds: function getBounds(aAccessible, aPreserveContentScale) {
+  getBounds: function getBounds(aAccessible) {
     let objX = {}, objY = {}, objW = {}, objH = {};
     aAccessible.getBounds(objX, objY, objW, objH);
 
-    let scale = aPreserveContentScale ? 1 :
-      this.getContentResolution(aAccessible);
-
-    return new Rect(objX.value, objY.value, objW.value, objH.value).scale(
-      scale, scale);
+    return new Rect(objX.value, objY.value, objW.value, objH.value);
   },
 
   getTextBounds: function getTextBounds(aAccessible, aStart, aEnd,
                                         aPreserveContentScale) {
     let accText = aAccessible.QueryInterface(Ci.nsIAccessibleText);
     let objX = {}, objY = {}, objW = {}, objH = {};
     accText.getRangeExtents(aStart, aEnd, objX, objY, objW, objH,
       Ci.nsIAccessibleCoordinateType.COORDTYPE_SCREEN_RELATIVE);
 
-    let scale = aPreserveContentScale ? 1 :
-      this.getContentResolution(aAccessible);
-
-    return new Rect(objX.value, objY.value, objW.value, objH.value).scale(
-      scale, scale);
+    return new Rect(objX.value, objY.value, objW.value, objH.value);
   },
 
   /**
    * Get current display DPI.
    */
   get dpi() {
     delete this.dpi;
     this.dpi = this.winUtils.displayDPI;
--- a/accessible/jsat/content-script.js
+++ b/accessible/jsat/content-script.js
@@ -57,59 +57,45 @@ function forwardToChild(aMessage, aListe
     // so we remove the real screen offset here.
     newJSON.x -= content.mozInnerScreenX;
     newJSON.y -= content.mozInnerScreenY;
   }
   mm.sendAsyncMessage(aMessage.name, newJSON);
   return true;
 }
 
-function activateContextMenu(aMessage) {
-  let position = Utils.getVirtualCursor(content.document).position;
-  if (!forwardToChild(aMessage, activateContextMenu, position)) {
-    let center = Utils.getBounds(position, true).center();
-
-    let evt = content.document.createEvent("HTMLEvents");
-    evt.initEvent("contextmenu", true, true);
-    evt.clientX = center.x;
-    evt.clientY = center.y;
-    position.DOMNode.dispatchEvent(evt);
-  }
-}
-
 function presentCaretChange(aText, aOldOffset, aNewOffset) {
   if (aOldOffset !== aNewOffset) {
     let msg = Presentation.textSelectionChanged(aText, aNewOffset, aNewOffset,
                                                 aOldOffset, aOldOffset, true);
     sendAsyncMessage("AccessFu:Present", msg);
   }
 }
 
 function scroll(aMessage) {
   let position = Utils.getVirtualCursor(content.document).position;
   if (!forwardToChild(aMessage, scroll, position)) {
     sendAsyncMessage("AccessFu:DoScroll",
-                     { bounds: Utils.getBounds(position, true),
+                     { bounds: Utils.getBounds(position),
                        page: aMessage.json.page,
                        horizontal: aMessage.json.horizontal });
   }
 }
 
 addMessageListener(
   "AccessFu:Start",
   function(m) {
     if (m.json.logLevel) {
       Logger.logLevel = Logger[m.json.logLevel];
     }
 
     Logger.debug("AccessFu:Start");
     if (m.json.buildApp)
       Utils.MozBuildApp = m.json.buildApp;
 
-    addMessageListener("AccessFu:ContextMenu", activateContextMenu);
     addMessageListener("AccessFu:Scroll", scroll);
 
     if (!contentControl) {
       contentControl = new ContentControl(this);
     }
     contentControl.start();
 
     if (!eventManager) {
@@ -134,16 +120,15 @@ addMessageListener(
     }
   });
 
 addMessageListener(
   "AccessFu:Stop",
   function(m) {
     Logger.debug("AccessFu:Stop");
 
-    removeMessageListener("AccessFu:ContextMenu", activateContextMenu);
     removeMessageListener("AccessFu:Scroll", scroll);
 
     eventManager.stop();
     contentControl.stop();
   });
 
 sendAsyncMessage("AccessFu:Ready");
--- a/accessible/jsat/jar.mn
+++ b/accessible/jsat/jar.mn
@@ -1,10 +1,7 @@
 # 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/.
 
 toolkit.jar:
     content/global/accessibility/AccessFu.css (AccessFu.css)
     content/global/accessibility/content-script.js (content-script.js)
-    content/global/accessibility/virtual_cursor_move.ogg (sounds/virtual_cursor_move.ogg)
-    content/global/accessibility/virtual_cursor_key.ogg (sounds/virtual_cursor_key.ogg)
-    content/global/accessibility/clicked.ogg (sounds/clicked.ogg)
--- a/accessible/jsat/moz.build
+++ b/accessible/jsat/moz.build
@@ -4,17 +4,15 @@
 # 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/.
 
 EXTRA_JS_MODULES.accessibility += [
     'AccessFu.jsm',
     'Constants.jsm',
     'ContentControl.jsm',
     'EventManager.jsm',
-    'Gestures.jsm',
     'OutputGenerator.jsm',
-    'PointerAdapter.jsm',
     'Presentation.jsm',
     'Traversal.jsm',
     'Utils.jsm'
 ]
 
-JAR_MANIFESTS += ['jar.mn']
\ No newline at end of file
+JAR_MANIFESTS += ['jar.mn']
deleted file mode 100644
index 68388018e5e3054e07a9e59fe4dcb5100843f6fc..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index b29b55b449519d7f489f4a383a13cf77c663a71d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index da97934605c8661999d0ea78e5e4f2bb330b880d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/accessible/tests/browser/bounds/browser.ini
+++ b/accessible/tests/browser/bounds/browser.ini
@@ -1,11 +1,13 @@
 [DEFAULT]
 support-files =
   head.js
   !/accessible/tests/browser/events.js
   !/accessible/tests/browser/shared-head.js
   !/accessible/tests/mochitest/*.js
   !/accessible/tests/mochitest/letters.gif
 
+[browser_test_resolution.js]
+skip-if = e10s && os == 'win' # bug 1372296
 [browser_test_zoom.js]
 [browser_test_zoom_text.js]
 skip-if = e10s && os == 'win' # bug 1372296
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/bounds/browser_test_resolution.js
@@ -0,0 +1,57 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+/* import-globals-from ../../mochitest/layout.js */
+
+async function testScaledBounds(browser, accDoc, scale, id, type = "object") {
+  let acc = findAccessibleChildByID(accDoc, id);
+
+  // Get document offset
+  let [docX, docY] = getBounds(accDoc);
+
+  // Get the unscaled bounds of the accessible
+  let [x, y, width, height] = type == "text" ?
+    getRangeExtents(acc, 0, -1, COORDTYPE_SCREEN_RELATIVE) : getBounds(acc);
+
+  await ContentTask.spawn(browser, scale, _scale => {
+    setResolution(document, _scale);
+  });
+
+  let [scaledX, scaledY, scaledWidth, scaledHeight] = type == "text" ?
+    getRangeExtents(acc, 0, -1, COORDTYPE_SCREEN_RELATIVE) : getBounds(acc);
+
+  let name = prettyName(acc);
+  isWithin(scaledWidth, width * scale, 2, "Wrong scaled width of " + name);
+  isWithin(scaledHeight, height * scale, 2, "Wrong scaled height of " + name);
+  isWithin(scaledX - docX, (x - docX) * scale, 2, "Wrong scaled x of " + name);
+  isWithin(scaledY - docY, (y - docY) * scale, 2, "Wrong scaled y of " + name);
+
+  await ContentTask.spawn(browser, {}, () => {
+    setResolution(document, 1.0);
+  });
+}
+
+async function runTests(browser, accDoc) {
+  loadFrameScripts(browser, { name: "layout.js", dir: MOCHITESTS_DIR });
+
+  await testScaledBounds(browser, accDoc, 2.0, "p1");
+  await testScaledBounds(browser, accDoc, 0.5, "p2");
+  await testScaledBounds(browser, accDoc, 3.5, "b1");
+
+  await testScaledBounds(browser, accDoc, 2.0, "p1", "text");
+  await testScaledBounds(browser, accDoc, 0.75, "p2", "text");
+}
+
+/**
+ * Test accessible boundaries when page is zoomed
+ */
+addAccessibleTask(`
+<p id='p1' style='font-family: monospace;'>Tilimilitryamdiya</p>
+<p id="p2">para 2</p>
+<button id="b1">Hello</button>
+`,
+  runTests
+);
--- a/accessible/tests/mochitest/common.js
+++ b/accessible/tests/mochitest/common.js
@@ -40,17 +40,16 @@ const nsIAccessibleSelectable = Ci.nsIAc
 const nsIAccessibleTable = Ci.nsIAccessibleTable;
 const nsIAccessibleTableCell = Ci.nsIAccessibleTableCell;
 const nsIAccessibleTraversalRule = Ci.nsIAccessibleTraversalRule;
 const nsIAccessibleValue = Ci.nsIAccessibleValue;
 
 const nsIObserverService = Ci.nsIObserverService;
 
 const nsIDOMDocument = Ci.nsIDOMDocument;
-const nsIDOMEvent = Ci.nsIDOMEvent;
 const nsIDOMNode = Ci.nsIDOMNode;
 const nsIDOMWindow = Ci.nsIDOMWindow;
 
 const nsIPropertyElement = Ci.nsIPropertyElement;
 
 // //////////////////////////////////////////////////////////////////////////////
 // OS detect
 
--- a/accessible/tests/mochitest/events.js
+++ b/accessible/tests/mochitest/events.js
@@ -824,32 +824,33 @@ function eventQueue(aEventType) {
 // eventQueue static members and constants
 
 const kInvokerNotScheduled = 0;
 const kInvokerPending = 1;
 const kInvokerCanceled = 2;
 
 eventQueue.getEventTypeAsString =
   function eventQueue_getEventTypeAsString(aEventOrChecker) {
-  if (aEventOrChecker instanceof nsIDOMEvent)
+  if (Event.isInstance(aEventOrChecker))
     return aEventOrChecker.type;
 
   if (aEventOrChecker instanceof nsIAccessibleEvent)
     return eventTypeToString(aEventOrChecker.eventType);
 
   return (typeof aEventOrChecker.type == "string") ?
     aEventOrChecker.type : eventTypeToString(aEventOrChecker.type);
 };
 
 eventQueue.getEventTargetDescr =
   function eventQueue_getEventTargetDescr(aEventOrChecker, aDontForceTarget) {
-  if (aEventOrChecker instanceof nsIDOMEvent)
+  if (Event.isInstance(aEventOrChecker))
     return prettyName(aEventOrChecker.originalTarget);
 
-  if (aEventOrChecker instanceof nsIDOMEvent)
+  // XXXbz this block doesn't seem to be reachable...
+  if (Event.isInstance(aEventOrChecker))
     return prettyName(aEventOrChecker.accessible);
 
   var descr = aEventOrChecker.targetDescr;
   if (descr)
     return descr;
 
   if (aDontForceTarget)
     return "no target description";
@@ -872,41 +873,41 @@ eventQueue.getEventTarget = function eve
         return aChecker.target.ownerDocument;
     }
   }
   return aChecker.target.ownerDocument;
 };
 
 eventQueue.compareEventTypes =
   function eventQueue_compareEventTypes(aChecker, aEvent) {
-  var eventType = (aEvent instanceof nsIDOMEvent) ?
+  var eventType = Event.isInstance(aEvent) ?
     aEvent.type : aEvent.eventType;
   return aChecker.type == eventType;
 };
 
 eventQueue.compareEvents = function eventQueue_compareEvents(aChecker, aEvent) {
   if (!eventQueue.compareEventTypes(aChecker, aEvent))
     return false;
 
   // If checker provides "match" function then allow the checker to decide
   // whether event is matched.
   if ("match" in aChecker)
     return aChecker.match(aEvent);
 
   var target1 = aChecker.target;
   if (target1 instanceof nsIAccessible) {
-    var target2 = (aEvent instanceof nsIDOMEvent) ?
+    var target2 = Event.isInstance(aEvent) ?
       getAccessible(aEvent.target) : aEvent.accessible;
 
     return target1 == target2;
   }
 
   // If original target isn't suitable then extend interface to support target
   // (original target is used in test_elm_media.html).
-  var target2 = (aEvent instanceof nsIDOMEvent) ?
+  var target2 = Event.isInstance(aEvent) ?
     aEvent.originalTarget : aEvent.DOMNode;
   return target1 == target2;
 };
 
 eventQueue.isSameEvent = function eventQueue_isSameEvent(aChecker, aEvent) {
   // We don't have stored info about handled event other than its type and
   // target, thus we should filter text change and state change events since
   // they may occur on the same element because of complex changes.
@@ -937,17 +938,17 @@ eventQueue.invokerStatusToMsg =
 };
 
 eventQueue.logEvent = function eventQueue_logEvent(aOrigEvent, aMatchedChecker,
                                                    aScenarioIdx, aEventIdx,
                                                    aAreExpectedEventsLeft,
                                                    aInvokerStatus) {
   // Dump DOM event information. Skip a11y event since it is dumped by
   // gA11yEventObserver.
-  if (aOrigEvent instanceof nsIDOMEvent) {
+  if (Event.isInstance(aOrigEvent)) {
     var info = "Event type: " + eventQueue.getEventTypeAsString(aOrigEvent);
     info += ". Target: " + eventQueue.getEventTargetDescr(aOrigEvent);
     gLogger.logToDOM(info);
   }
 
   var infoMsg = "unhandled expected events: " + aAreExpectedEventsLeft +
     ", " + eventQueue.invokerStatusToMsg(aInvokerStatus);
 
--- a/accessible/tests/mochitest/jsat/a11y.ini
+++ b/accessible/tests/mochitest/jsat/a11y.ini
@@ -1,30 +1,25 @@
 [DEFAULT]
 support-files =
-  dom_helper.js
-  gestures.json
   jsatcommon.js
   output.js
   doc_traversal.html
   doc_content_integration.html
   doc_content_text.html
   !/accessible/tests/mochitest/*.js
   !/accessible/tests/mochitest/moz.png
 skip-if = (os == 'win' && (os_version == '5.1' || os_version == '5.2'))
 
 [test_alive.html]
 [test_content_integration.html]
 skip-if = buildapp == 'mulet'
 [test_content_text.html]
 skip-if = buildapp == 'mulet'
 [test_explicit_names.html]
-[test_gesture_tracker.html]
 [test_hints.html]
 [test_landmarks.html]
 [test_live_regions.html]
 [test_output_mathml.html]
 [test_output.html]
-[test_quicknav_modes.html]
 [test_tables.html]
-[test_pointer_relay.html]
 [test_traversal.html]
 [test_traversal_helper.html]
deleted file mode 100644
--- a/accessible/tests/mochitest/jsat/dom_helper.js
+++ /dev/null
@@ -1,204 +0,0 @@
-"use strict";
-
-/* exported loadJSON, eventMap */
-
-ChromeUtils.import("resource://gre/modules/Geometry.jsm");
-
-var win = getMainChromeWindow(window);
-
-/**
- * Convert inch based point coordinates into pixels.
- * @param  {Array} aPoints Array of coordinates in inches.
- * @return {Array} Array of coordinates in pixels.
- */
-function convertPointCoordinates(aPoints) {
-  var dpi = Utils.dpi;
-  return aPoints.map(function convert(aPoint) {
-    return {
-      x: aPoint.x * dpi,
-      y: aPoint.y * dpi,
-      identifier: aPoint.identifier
-    };
-  });
-}
-
-/**
- * For a given list of points calculate their coordinates in relation to the
- * document body.
- * @param  {Array} aTouchPoints An array of objects of the following format: {
- *   base: {String}, // Id of an element to server as a base for the touch.
- *   x: {Number},    // An optional x offset from the base element's geometric
- *                   // centre.
- *   y: {Number}     // An optional y offset from the base element's geometric
- *                   // centre.
- * }
- * @return {JSON} An array of {x, y} coordinations.
- */
-function calculateTouchListCoordinates(aTouchPoints) {
-  var coords = [];
-  for (var i = 0, target = aTouchPoints[i]; i < aTouchPoints.length; ++i) {
-    var bounds = getBoundsForDOMElm(target.base);
-    var parentBounds = getBoundsForDOMElm("root");
-    var point = new Point(target.x || 0, target.y || 0);
-    point.scale(Utils.dpi);
-    point.add(bounds[0], bounds[1]);
-    point.add(bounds[2] / 2, bounds[3] / 2);
-    point.subtract(parentBounds[0], parentBounds[0]);
-    coords.push({
-      x: point.x,
-      y: point.y
-    });
-  }
-  return coords;
-}
-
-/**
- * Send a touch event with specified touchPoints.
- * @param  {Array} aTouchPoints An array of points to be associated with
- * touches.
- * @param  {String} aName A name of the touch event.
- */
-function sendTouchEvent(aTouchPoints, aName) {
-  var touchList = sendTouchEvent.touchList;
-  if (aName === "touchend") {
-    sendTouchEvent.touchList = null;
-  } else {
-    var coords = calculateTouchListCoordinates(aTouchPoints);
-    var touches = [];
-    for (var i = 0; i < coords.length; ++i) {
-      var {x, y} = coords[i];
-      var node = document.elementFromPoint(x, y);
-      var touch = document.createTouch(window, node, aName === "touchstart" ?
-        1 : touchList.item(i).identifier, x, y, x, y);
-      touches.push(touch);
-    }
-    touchList = document.createTouchList(touches);
-    sendTouchEvent.touchList = touchList;
-  }
-  var evt = document.createEvent("TouchEvent");
-  evt.initTouchEvent(aName, true, true, window, 0, false, false, false, false,
-    touchList, touchList, touchList);
-  document.dispatchEvent(evt);
-}
-
-sendTouchEvent.touchList = null;
-
-/**
- * A map of event names to the functions that actually send them.
- * @type {Object}
- */
-var eventMap = {
-  touchstart: sendTouchEvent,
-  touchend: sendTouchEvent,
-  touchmove: sendTouchEvent
-};
-
-/**
- * Attach a listener for the mozAccessFuGesture event that tests its
- * type.
- * @param  {Array} aExpectedGestures A stack of expected event types.
- * @param  {String} aTitle Title of this sequence, if any.
- * Note: the listener is removed once the stack reaches 0.
- */
-function testMozAccessFuGesture(aExpectedGestures, aTitle) {
-  var types = aExpectedGestures;
-  function handleGesture(aEvent) {
-    if (aEvent.detail.type !== types[0].type) {
-      info("Got " + aEvent.detail.type + " waiting for " + types[0].type);
-      // The is not the event of interest.
-      return;
-    }
-    is(!!aEvent.detail.edge, !!types[0].edge);
-    is(aEvent.detail.touches.length, types[0].fingers || 1,
-      "failed to count fingers: " + types[0].type);
-    ok(true, "Received correct mozAccessFuGesture: " +
-      JSON.stringify(types.shift()) + ". (" + aTitle + ")");
-    if (types.length === 0) {
-      win.removeEventListener("mozAccessFuGesture", handleGesture);
-      if (AccessFuTest.sequenceCleanup) {
-        AccessFuTest.sequenceCleanup();
-      }
-      AccessFuTest.nextTest();
-    }
-  }
-  win.addEventListener("mozAccessFuGesture", handleGesture);
-}
-
-/**
- * Reset the thresholds and max delays that affect gesture rejection.
- * @param {Number} aTimeStamp Gesture time stamp.
- * @param {Boolean} aRemoveDwellThreshold An optional flag to reset dwell
- * threshold.
- * @param {Boolean} aRemoveSwipeMaxDuration An optional flag to reset swipe max
- * duration.
- */
-function setTimers(aTimeStamp, aRemoveDwellThreshold, aRemoveSwipeMaxDuration) {
-  if (!aRemoveDwellThreshold && !aRemoveSwipeMaxDuration) {
-    return;
-  }
-  if (aRemoveDwellThreshold) {
-    GestureSettings.dwellThreshold = 0;
-  }
-  if (aRemoveSwipeMaxDuration) {
-    GestureSettings.swipeMaxDuration = 0;
-  }
-  GestureTracker.current.clearTimer();
-  GestureTracker.current.startTimer(aTimeStamp);
-}
-
-function resetTimers(aRemoveGestureResolveDelay) {
-  GestureSettings.dwellThreshold = AccessFuTest.dwellThreshold;
-  GestureSettings.swipeMaxDuration = AccessFuTest.swipeMaxDuration;
-  GestureSettings.maxGestureResolveTimeout = aRemoveGestureResolveDelay ?
-    0 : AccessFuTest.maxGestureResolveTimeout;
-}
-
-/**
- * An extention to AccessFuTest that adds an ability to test a sequence of
- * pointer events and their expected mozAccessFuGesture events.
- * @param {Object} aSequence An object that has a list of pointer events to be
- * generated and the expected mozAccessFuGesture events.
- */
-AccessFuTest.addSequence = function AccessFuTest_addSequence(aSequence) {
-  AccessFuTest.addFunc(function testSequence() {
-    testMozAccessFuGesture(aSequence.expectedGestures, aSequence.title);
-    var events = aSequence.events;
-    function fireEvent(aEvent) {
-      var event = {
-        points: convertPointCoordinates(aEvent.points),
-        type: aEvent.type
-      };
-      var timeStamp = Date.now();
-      resetTimers(aEvent.removeGestureResolveDelay);
-      GestureTracker.handle(event, timeStamp);
-      setTimers(timeStamp, aEvent.removeDwellThreshold,
-        aEvent.removeSwipeMaxDuration);
-      processEvents();
-    }
-    function processEvents() {
-      if (events.length === 0) {
-        return;
-      }
-      var event = events.shift();
-      SimpleTest.executeSoon(function() {
-        fireEvent(event);
-      });
-    }
-    processEvents();
-  });
-};
-
-/**
- * A helper function that loads JSON files.
- * @param {String} aPath A path to a JSON file.
- * @param {Function} aCallback A callback to be called on success.
- */
-function loadJSON(aPath, aCallback) {
-  var request = new XMLHttpRequest();
-  request.open("GET", aPath, true);
-  request.responseType = "json";
-  request.onload = function onload() {
-    aCallback(request.response);
-  };
-  request.send();
-}
deleted file mode 100644
--- a/accessible/tests/mochitest/jsat/gestures.json
+++ /dev/null
@@ -1,352 +0,0 @@
-[
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}],
-       "removeGestureResolveDelay": true }
-    ],
-    "expectedGestures": [{ "type": "tap" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointermove",
-        "points": [{"x": 1.03, "y": 1.03, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1.03, "y": 1.03, "identifier": 1}],
-       "removeGestureResolveDelay": true }
-    ],
-    "expectedGestures": [{ "type": "tap" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}],
-        "removeDwellThreshold": true},
-      {"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "dwell" }, { "type": "dwellend" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointermove",
-        "points": [{"x": 1.03, "y": 1.02, "identifier": 1}]},
-      {"type": "pointerup",
-        "points": [{"x": 1.03, "y": 1.02, "identifier": 1}]},
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointermove",
-        "points": [{"x": 0.97, "y": 1.01, "identifier": 1}]},
-      {"type": "pointerup",
-        "points": [{"x": 0.97, "y": 1.01, "identifier": 1}],
-        "removeGestureResolveDelay": true }
-    ],
-    "expectedGestures": [{ "type": "doubletap" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}],
-       "removeGestureResolveDelay": true }
-    ],
-    "expectedGestures": [{ "type": "tripletap" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}],
-        "removeDwellThreshold": true},
-      {"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "doubletaphold" },
-      { "type": "doubletapholdend" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}],
-        "removeDwellThreshold": true},
-      {"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "taphold" }, { "type": "tapholdend" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointermove", "points": [{"x": 1.5, "y": 1, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1.5, "y": 1, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "swiperight" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointermove", "points": [{"x": 1.15, "y": 1, "identifier": 1}]},
-      {"type": "pointermove", "points": [{"x": 1.3, "y": 1, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1.3, "y": 1, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "swiperight" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1.5, "y": 1, "identifier": 1}]},
-      {"type": "pointermove", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "swipeleft" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointermove", "points": [{"x": 1, "y": 1.5, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1, "y": 1.5, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "swipedown" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1.5, "identifier": 1}]},
-      {"type": "pointermove", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "swipeup" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointermove",
-        "points": [{"x": 1.5, "y": 1.1, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1.5, "y": 1.1, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "swiperight" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown",
-        "points": [{"x": 1.5, "y": 1.1, "identifier": 1}]},
-      {"type": "pointermove", "points": [{"x": 1, "y": 0.95, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1, "y": 0.95, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "swipeleft" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointermove",
-        "points": [{"x": 0.9, "y": 1.5, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 0.9, "y": 1.5, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "swipedown" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown",
-        "points": [{"x": 1.1, "y": 1.5, "identifier": 1}]},
-      {"type": "pointermove", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "swipeup" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1},
-        {"x": 1, "y": 1.5, "identifier": 2}]},
-      {"type": "pointermove", "points": [{"x": 1.5, "y": 1, "identifier": 1},
-        {"x": 1.5, "y": 1.5, "identifier": 2}]},
-      {"type": "pointerup", "points": [{"x": 1.5, "y": 1, "identifier": 1},
-        {"x": 1.5, "y": 1.5, "identifier": 2}]}
-    ],
-    "expectedGestures": [{ "type": "swiperight", "fingers": 2 }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1},
-        {"x": 1, "y": 1.5, "identifier": 2}]},
-      {"type": "pointermove", "points": [{"x": 1.5, "y": 1, "identifier": 1},
-        {"x": 1.5, "y": 1.5, "identifier": 2}]},
-      {"type": "pointerup", "points": [{"x": 1.5, "y": 1, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1.5, "y": 1.5, "identifier": 2}]}
-    ],
-    "expectedGestures": [{ "type": "swiperight", "fingers": 2 }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1},
-        {"x": 1, "y": 1.5, "identifier": 2},
-        {"x": 1, "y": 2, "identifier": 3}]},
-      {"type": "pointermove", "points": [{"x": 1.5, "y": 1, "identifier": 1},
-        {"x": 1.5, "y": 1.5, "identifier": 2},
-        {"x": 1.5, "y": 2, "identifier": 3}]},
-      {"type": "pointerup", "points": [{"x": 1.5, "y": 1, "identifier": 1},
-        {"x": 1.5, "y": 1.5, "identifier": 2},
-        {"x": 1.5, "y": 2, "identifier": 3}]}
-    ],
-    "expectedGestures": [{ "type": "swiperight", "fingers": 3 }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown",
-        "points": [{"x": 1.6, "y": 1.5, "identifier": 1}],
-        "removeDwellThreshold": true},
-      {"type": "pointermove", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "dwell" }, { "type": "explore" },
-      { "type": "exploreend" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown",
-        "points": [{"x": 1.6, "y": 1.5, "identifier": 1}],
-        "removeDwellThreshold": true},
-      {"type": "pointermove", "points": [{"x": 1, "y": 1, "identifier": 1}]},
-      {"type": "pointermove", "points": [{"x": 2, "y": 2, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 2, "y": 2, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "dwell" }, { "type": "explore" },
-      { "type": "explore" }, { "type": "exploreend" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown",
-        "points": [{"x": 1.6, "y": 1.5, "identifier": 1}]},
-      {"type": "pointermove", "points": [{"x": 1, "y": 1, "identifier": 1}],
-        "removeSwipeMaxDuration": true},
-      {"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "explore" }, { "type": "exploreend" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1.5, "identifier": 1}]},
-      {"type": "pointermove", "points": [{"x": 1, "y": 1, "identifier": 1}],
-        "removeSwipeMaxDuration": true},
-      {"type": "pointermove", "points": [{"x": 1.5, "y": 1, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1.5, "y": 1, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "explore" }, { "type": "explore" },
-      { "type": "exploreend" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}],
-        "removeDwellThreshold": true},
-      {"type": "pointermove",
-        "points": [{"x": 1.5, "y": 1.5, "identifier": 1}]},
-      {"type": "pointermove",
-        "points": [{"x": 1.55, "y": 1.5, "identifier": 1}]},
-      {"type": "pointermove",
-        "points": [{"x": 1.6, "y": 1.5, "identifier": 1}]},
-      {"type": "pointermove",
-        "points": [{"x": 1.65, "y": 1.5, "identifier": 1}]},
-      {"type": "pointermove",
-        "points": [{"x": 1.7, "y": 1.5, "identifier": 1}]},
-      {"type": "pointermove",
-        "points": [{"x": 1.75, "y": 1.5, "identifier": 1}]},
-      {"type": "pointerup", "points": [{"x": 1.75, "y": 1.5, "identifier": 1}]}
-    ],
-    "expectedGestures": [{ "type": "dwell" }, { "type": "explore" },
-      { "type": "explore" }, { "type": "exploreend" }]
-  },
-  {
-    "events": [
-      {"type": "pointerdown", "points": [{"x": 0.075, "y": 1, "identifier": 1},
-        {"x": 1, "y": 1.5, "identifier": 2}]},
-      {"type": "pointermove", "points": [{"x": 1.5, "y": 1, "identifier": 1},
-        {"x": 1.5, "y": 1.5, "identifier": 2}]},
-      {"type": "pointerup", "points": [{"x": 1.5, "y": 1, "identifier": 1},
-        {"x": 1.5, "y": 1.5, "identifier": 2}]}
-    ],
-    "expectedGestures": [{ "type": "swiperight", "edge": true, "fingers": 2 }]
-  },
-  {
-    "title": "Bug 1182311 - 3 finger triple tap is not reliable 1/2",
-    "events": [
-      {"points": [
-        {"y": 1.88467, "x": 0.89311, "identifier": 0},
-        {"y": 2.78481, "x": 0.56259, "identifier": 1},
-        {"y": 1.35021, "x": 1.37834, "identifier": 2}], "type": "pointerdown"},
-      {"points": [
-        {"y": 1.88467, "x": 0.89311, "identifier": 0},
-        {"y": 2.78481, "x": 0.56259, "identifier": 1},
-        {"y": 1.35021, "x": 1.37834, "identifier": 2}], "type": "pointerup"},
-      {"points": [
-        {"y": 1.76512, "x": 0.98453, "identifier": 0},
-        {"y": 1.1744, "x": 1.4346, "identifier": 1},
-        {"y": 2.5879, "x": 0.61181, "identifier": 2}], "type": "pointerdown"},
-      {"points": [
-        {"y": 1.76512, "x": 0.98453, "identifier": 0},
-        {"y": 1.1744, "x": 1.4346, "identifier": 1},
-        {"y": 2.5879, "x": 0.61181, "identifier": 2}], "type": "pointerup"},
-      {"points": [
-        {"y": 1.30098, "x": 1.52602, "identifier": 0},
-        {"y": 1.94093, "x": 1.02672, "identifier": 1},
-        {"y": 2.67229, "x": 0.75246, "identifier": 2}], "type": "pointerdown"},
-      {"points": [
-        {"y": 1.30098, "x": 1.52602, "identifier": 0},
-        {"y": 1.94093, "x": 1.02672, "identifier": 1},
-        {"y": 2.67229, "x": 0.75246, "identifier": 2}], "type": "pointerup",
-       "removeGestureResolveDelay": true}],
-    "expectedGestures": [{ "type": "tripletap", "fingers": 3 }]
-  },
-  {
-    "title": "Bug 1182311 - 3 finger triple tap is not reliable 2/2",
-    "events": [
-      {"type": "pointerdown",
-       "points": [{"identifier": 0, "x": 2.21875, "y": 1.510417}]},
-      {"type": "pointerdown",
-       "points": [{"identifier": 1, "x": 1.479167, "y": 2.53125}]},
-      {"type": "pointerdown",
-       "points": [{"identifier": 2, "x": 1.072917, "y": 3.739583}]},
-      {"type": "pointermove",
-       "points": [{"identifier": 1, "x": 1.46875, "y": 2.53125}]},
-      {"type": "pointermove",
-       "points": [{"identifier": 1, "x": 1.447917, "y": 2.46875}]},
-      {"type": "pointerup",
-       "points": [{"identifier": 0, "x": 2.21875, "y": 1.510417}]},
-      {"type": "pointerup",
-       "points": [{"identifier": 1, "x": 1.447917, "y": 2.489583}]},
-      {"type": "pointerup",
-       "points": [{"identifier": 2, "x": 1.072917, "y": 3.739583}]},
-      {"type": "pointerdown",
-       "points": [{"identifier": 0, "x": 2.114583, "y": 1.572917}]},
-      {"type": "pointerdown",
-       "points": [{"identifier": 1, "x": 1.364583, "y": 2.614583}]},
-      {"type": "pointerdown",
-       "points": [{"identifier": 2, "x": 0.927083, "y": 3.864583}]},
-      {"type": "pointermove",
-       "points": [{"identifier": 1, "x": 1.364583, "y": 2.614583}]},
-      {"type": "pointermove",
-       "points": [{"identifier": 0, "x": 2.114583, "y": 1.572917}]},
-      {"type": "pointerup",
-       "points": [{"identifier": 1, "x": 1.364583, "y": 2.614583}]},
-      {"type": "pointerup",
-       "points": [{"identifier": 2, "x": 0.927083, "y": 3.864583}]},
-      {"type": "pointerup",
-       "points": [{"identifier": 0, "x": 2.114583, "y": 1.572917}]},
-      {"type": "pointerdown",
-       "points": [{"identifier": 0, "x": 1.4375, "y": 2.59375}]},
-      {"type": "pointerdown",
-       "points": [{"identifier": 1, "x": 1.083333, "y": 3.71875}]},
-      {"type": "pointerdown",
-       "points": [{"identifier": 2, "x": 2.15625, "y": 1.489583}]},
-      {"type": "pointermove",
-       "points": [{"identifier": 0, "x": 1.4375, "y": 2.59375},
-                  {"identifier": 2, "x": 2.15625, "y": 1.489583}]},
-      {"type": "pointermove",
-       "points": [{"identifier": 0, "x": 1.4375, "y": 2.59375},
-                  {"identifier": 2, "x": 2.15625, "y": 1.489583}]},
-      {"type": "pointerup",
-       "points": [{"identifier": 1, "x": 1.083333, "y": 3.71875}],
-       "removeGestureResolveDelay": true}
-    ],
-    "expectedGestures": [{ "type": "tripletap", "fingers": 3 }]
-  }
-
-]
--- a/accessible/tests/mochitest/jsat/jsatcommon.js
+++ b/accessible/tests/mochitest/jsat/jsatcommon.js
@@ -12,17 +12,16 @@ var gTestFuncs = [];
 /**
   * A global Iterator for the array of test functions.
   */
 var gIterator;
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/accessibility/Utils.jsm");
 ChromeUtils.import("resource://gre/modules/accessibility/EventManager.jsm");
-ChromeUtils.import("resource://gre/modules/accessibility/Gestures.jsm");
 
 var AccessFuTest = {
 
   addFunc: function AccessFuTest_addFunc(aFunc) {
     if (aFunc) {
       gTestFuncs.push(aFunc);
     }
   },
@@ -94,24 +93,16 @@ var AccessFuTest = {
   waitForExplicitFinish: function AccessFuTest_waitForExplicitFinish() {
     this._waitForExplicitFinish = true;
   },
 
   finish: function AccessFuTest_finish() {
     // Disable the console service logging.
     Logger.test = false;
     Logger.logLevel = Logger.INFO;
-    // Reset Gesture Settings.
-    GestureSettings.dwellThreshold = this.dwellThreshold =
-      this.originalDwellThreshold;
-    GestureSettings.swipeMaxDuration = this.swipeMaxDuration =
-      this.originalSwipeMaxDuration;
-    GestureSettings.maxGestureResolveTimeout =
-      this.maxGestureResolveTimeout =
-      this.originalMaxGestureResolveTimeout;
     // Finish through idle callback to let AccessFu._disable complete.
     SimpleTest.executeSoon(function() {
       AccessFu.detach();
       SimpleTest.finish();
     });
   },
 
   nextTest: function AccessFuTest_nextTest() {
@@ -153,30 +144,16 @@ var AccessFuTest = {
       Logger.logLevel = Logger.DEBUG;
     };
 
     AccessFu.attach(chromeWin, true);
 
     var prefs = [["accessibility.accessfu.notify_output", 1]];
     prefs.push.apply(prefs, aAdditionalPrefs);
 
-    this.originalDwellThreshold = GestureSettings.dwellThreshold;
-    this.originalSwipeMaxDuration = GestureSettings.swipeMaxDuration;
-    this.originalMaxGestureResolveTimeout =
-      GestureSettings.maxGestureResolveTimeout;
-    // https://bugzilla.mozilla.org/show_bug.cgi?id=1001945 - sometimes
-    // SimpleTest.executeSoon timeout is bigger than the timer settings in
-    // GestureSettings that causes intermittents.
-    this.dwellThreshold = GestureSettings.dwellThreshold =
-      GestureSettings.dwellThreshold * 10;
-    this.swipeMaxDuration = GestureSettings.swipeMaxDuration =
-      GestureSettings.swipeMaxDuration * 10;
-    this.maxGestureResolveTimeout = GestureSettings.maxGestureResolveTimeout =
-      GestureSettings.maxGestureResolveTimeout * 10;
-
     SpecialPowers.pushPrefEnv({ "set": prefs }, function() {
       if (AccessFuTest._waitForExplicitFinish) {
         // Run all test functions asynchronously.
         AccessFuTest.nextTest();
       } else {
         // Run all test functions synchronously.
         gTestFuncs.forEach(testFunc => testFunc());
         AccessFuTest.finish();
deleted file mode 100644
--- a/accessible/tests/mochitest/jsat/test_gesture_tracker.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<html>
-
-<head>
-  <title>AccessFu tests for gesture tracker.</title>
-
-  <link rel="stylesheet" type="text/css"
-        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
-  <script type="application/javascript"
-          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="../common.js"></script>
-  <script type="application/javascript" src="../layout.js"></script>
-  <script type="application/javascript" src="./jsatcommon.js"></script>
-  <script type="application/javascript" src="./dom_helper.js"></script>
-  <script type="application/javascript">
-
-    function startGestureTracker() {
-      GestureTracker.reset();
-      AccessFuTest.nextTest();
-    }
-
-    function stopGestureTracker() {
-      GestureTracker.reset();
-      AccessFuTest.finish();
-    }
-
-    function doTest() {
-      loadJSON("./gestures.json", function onSuccess(gestures) {
-        AccessFuTest.addFunc(startGestureTracker);
-        AccessFuTest.sequenceCleanup = GestureTracker.reset.bind(
-          GestureTracker);
-        gestures.forEach(AccessFuTest.addSequence);
-        AccessFuTest.addFunc(stopGestureTracker);
-        AccessFuTest.waitForExplicitFinish();
-        Logger.logLevel = Logger.GESTURE;
-        AccessFuTest.runTests();
-      });
-    }
-
-    SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
-  </script>
-
-</head>
-<body>
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=981015"
-     title="AccessFu tests for gesture tracker.">
-    Mozilla Bug 981015
-  </a>
-</body>
-</html>
deleted file mode 100644
--- a/accessible/tests/mochitest/jsat/test_pointer_relay.html
+++ /dev/null
@@ -1,95 +0,0 @@
-<html>
-
-<head>
-  <title>AccessFu tests for pointer relay.</title>
-
-  <link rel="stylesheet" type="text/css"
-        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
-  <script type="application/javascript"
-          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="../common.js"></script>
-  <script type="application/javascript" src="../layout.js"></script>
-  <script type="application/javascript" src="./jsatcommon.js"></script>
-  <script type="application/javascript" src="./dom_helper.js"></script>
-  <script type="application/javascript">
-
-    ChromeUtils.import(
-      "resource://gre/modules/accessibility/PointerAdapter.jsm");
-
-    var tests = [
-      {
-        type: "touchstart", target: [{base: "button"}],
-        expected: {type: "pointerdown", length: 1}
-      },
-      {
-        type: "touchmove", target: [{base: "button"}],
-        expected: {type: "pointermove", length: 1}
-      },
-      {
-        type: "touchend", target: [{base: "button"}],
-        expected: {type: "pointerup"}
-      },
-      {
-        type: "touchstart", target: [{base: "button"},
-          {base: "button", x: 0.5, y: 0.3}],
-          expected: {type: "pointerdown", length: 2}
-      },
-      {
-        type: "touchend", target: [{base: "button"},
-          {base: "button", x: 0.5, y: 0.3}],
-          expected: {type: "pointerup"}
-      },
-      {
-        type: "touchstart", target: [{base: "button"},
-          {base: "button", x: 0.5, y: 0.3},
-          {base: "button", x: 0.5, y: -0.3}],
-          expected: {type: "pointerdown", length: 3}
-      },
-      {
-        type: "touchend", target: [{base: "button"},
-          {base: "button", x: 0.5, y: 0.3},
-          {base: "button", x: 0.5, y: -0.3}],
-          expected: {type: "pointerup"}
-      }
-    ];
-
-    function makeTestFromSpec(test) {
-      return function runTest() {
-        PointerRelay.start(function onPointerEvent(aDetail) {
-          is(aDetail.type, test.expected.type,
-            "mozAccessFuPointerEvent is correct.");
-          if (test.expected.length) {
-            is(aDetail.points.length, test.expected.length,
-            "mozAccessFuPointerEvent points length is correct.");
-          }
-          PointerRelay.stop();
-          AccessFuTest.nextTest();
-        });
-        eventMap[test.type](test.target, test.type);
-      };
-    }
-
-    function doTest() {
-      tests.forEach(function addTest(test) {
-        AccessFuTest.addFunc(makeTestFromSpec(test));
-      });
-      AccessFuTest.waitForExplicitFinish();
-      AccessFuTest.runTests();
-    }
-
-    SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
-  </script>
-
-</head>
-<body id="root">
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=976082"
-     title="[AccessFu] Provide tests for pointer relay.">
-    Mozilla Bug 981015
-  </a>
-  <div>
-    <button id="button">I am a button</button>
-  </div>
-</body>
-</html>
deleted file mode 100644
--- a/accessible/tests/mochitest/jsat/test_quicknav_modes.html
+++ /dev/null
@@ -1,105 +0,0 @@
-<html>
-
-<head>
-  <title>AccessFu test for enabling</title>
-
-  <link rel="stylesheet" type="text/css"
-        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
-  <script type="application/javascript"
-          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript"
-          src="../common.js"></script>
-  <script type="application/javascript"
-          src="./jsatcommon.js"></script>
-  <script type="application/javascript">
-
-    function startAccessFu() {
-      AccessFuTest.once_log("EventManager.start", AccessFuTest.nextTest);
-      AccessFu._enable();
-    }
-
-    function nextMode(aCurrentMode, aNextMode) {
-      return function() {
-        is(AccessFu.Input.quickNavMode.current, aCurrentMode,
-          "initial current mode is correct");
-        AccessFu.Input.quickNavMode.next();
-        _expectMode(aNextMode, AccessFuTest.nextTest);
-      };
-    }
-
-    function prevMode(aCurrentMode, aNextMode) {
-      return function() {
-        is(AccessFu.Input.quickNavMode.current, aCurrentMode,
-          "initial current mode is correct");
-        AccessFu.Input.quickNavMode.previous();
-        _expectMode(aNextMode, AccessFuTest.nextTest);
-      };
-    }
-
-    function setMode(aModeIndex, aExpectedMode) {
-      return function() {
-        SpecialPowers.pushPrefEnv(
-          {"set": [["accessibility.accessfu.quicknav_index", aModeIndex]]},
-          function() {
-            _expectMode(aExpectedMode, AccessFuTest.nextTest);
-        });
-      };
-    }
-
-    function reconfigureModes() {
-      SpecialPowers.pushPrefEnv(
-        {"set": [["accessibility.accessfu.quicknav_modes", "Landmark,Button,Entry,Graphic"]]},
-        function() {
-          // When the modes are reconfigured, the current mode should
-          // be set to the first in the new list.
-          _expectMode("Landmark", AccessFuTest.nextTest);
-      });
-    }
-
-    function _expectMode(aExpectedMode, aCallback) {
-      if (AccessFu.Input.quickNavMode.current === aExpectedMode) {
-        ok(true, "correct mode");
-        aCallback();
-      } else {
-        AccessFuTest.once_log("Quicknav mode: " + aExpectedMode, function() {
-          ok(true, "correct mode");
-          aCallback();
-        });
-      }
-    }
-
-    function stopAccessFu() {
-      ok(AccessFu._enabled, "AccessFu is enabled.");
-      AccessFuTest.once_log("EventManager.stop", () => AccessFuTest.finish());
-      AccessFu._disable();
-    }
-
-    function doTest() {
-      AccessFuTest.addFunc(startAccessFu);
-      AccessFuTest.addFunc(nextMode("Link", "Heading"));
-      AccessFuTest.addFunc(nextMode("Heading", "FormElement"));
-      AccessFuTest.addFunc(nextMode("FormElement", "Link"));
-      AccessFuTest.addFunc(nextMode("Link", "Heading"));
-      AccessFuTest.addFunc(prevMode("Heading", "Link"));
-      AccessFuTest.addFunc(prevMode("Link", "FormElement"));
-      AccessFuTest.addFunc(setMode(1, "Heading"));
-      AccessFuTest.addFunc(reconfigureModes);
-      AccessFuTest.addFunc(stopAccessFu);
-      AccessFuTest.waitForExplicitFinish();
-      AccessFuTest.runTests([   // Will call SimpleTest.finish();
-        ["accessibility.accessfu.quicknav_modes", "Link,Heading,FormElement"]]);
-    }
-
-    SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
-  </script>
-
-</head>
-<body>
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=811307"
-     title="[AccessFu] Add mochitest for enabling">
-    Mozilla Bug 811307
-  </a>
-</body>
-</html>
--- a/accessible/tests/mochitest/layout.js
+++ b/accessible/tests/mochitest/layout.js
@@ -64,16 +64,28 @@ function zoomDocument(aDocument, aZoom) 
     getInterface(Ci.nsIWebNavigation).
     QueryInterface(Ci.nsIDocShell);
   var docViewer = docShell.contentViewer;
 
   docViewer.fullZoom = aZoom;
 }
 
 /**
+ * Set the relative resolution of this document. This is what apz does.
+ * On non-mobile platforms you won't see a visible change.
+ */
+function setResolution(aDocument, aZoom) {
+  var windowUtils = aDocument.defaultView.
+    QueryInterface(Ci.nsIInterfaceRequestor).
+    getInterface(Ci.nsIDOMWindowUtils);
+
+  windowUtils.setResolutionAndScaleTo(aZoom);
+}
+
+/**
  * Return child accessible at the given point.
  *
  * @param aIdentifier        [in] accessible identifier
  * @param aX                 [in] x coordinate of the point relative accessible
  * @param aY                 [in] y coordinate of the point relative accessible
  * @param aFindDeepestChild  [in] points whether deepest or nearest child should
  *                           be returned
  * @return                   the child accessible at the given point
@@ -191,16 +203,24 @@ function getPos(aID) {
  */
 function getBounds(aID) {
   var accessible = getAccessible(aID);
   var x = {}, y = {}, width = {}, height = {};
   accessible.getBounds(x, y, width, height);
   return [x.value, y.value, width.value, height.value];
 }
 
+function getRangeExtents(aID, aStartOffset, aEndOffset, aCoordOrigin) {
+  var hyperText = getAccessible(aID, [nsIAccessibleText]);
+  var x = {}, y = {}, width = {}, height = {};
+  hyperText.getRangeExtents(aStartOffset, aEndOffset,
+                            x, y, width, height, aCoordOrigin);
+  return [x.value, y.value, width.value, height.value];
+}
+
 /**
  * Return DOM node coordinates relative the screen and its size in device
  * pixels.
  */
 function getBoundsForDOMElm(aID) {
   var x = 0, y = 0, width = 0, height = 0;
 
   var elm = getNode(aID);
--- a/accessible/windows/sdn/sdnAccessible.cpp
+++ b/accessible/windows/sdn/sdnAccessible.cpp
@@ -218,17 +218,17 @@ sdnAccessible::get_computedStyle(unsigne
   if (!aStyleProperties || aStyleValues || !aNumStyleProperties)
     return E_INVALIDARG;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   *aNumStyleProperties = 0;
 
-  if (mNode->IsNodeOfType(nsINode::eDOCUMENT))
+  if (mNode->IsDocument())
     return S_FALSE;
 
   nsCOMPtr<nsICSSDeclaration> cssDecl =
     nsWinUtils::GetComputedStyleDeclaration(mNode->AsContent());
   NS_ENSURE_TRUE(cssDecl, E_FAIL);
 
   uint32_t length = cssDecl->Length();
 
@@ -261,17 +261,17 @@ sdnAccessible::get_computedStyleForPrope
                                               BSTR __RPC_FAR* aStyleValues)
 {
   if (!aStyleProperties || !aStyleValues)
     return E_INVALIDARG;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
-  if (mNode->IsNodeOfType(nsINode::eDOCUMENT))
+  if (mNode->IsDocument())
     return S_FALSE;
 
   nsCOMPtr<nsICSSDeclaration> cssDecl =
     nsWinUtils::GetComputedStyleDeclaration(mNode->AsContent());
   NS_ENSURE_TRUE(cssDecl, E_FAIL);
 
   uint32_t index = 0;
   for (index = 0; index < aNumStyleProperties; index++) {
--- a/browser/app/permissions
+++ b/browser/app/permissions
@@ -1,27 +1,28 @@
-# This file has default permissions for the permission manager.
-# The file-format is strict:
-# * matchtype \t type \t permission \t host
-# * "origin" should be used for matchtype, "host" is supported for legacy reasons
-# * type is a string that identifies the type of permission (e.g. "cookie")
-# * permission is an integer between 1 and 15
-# See nsPermissionManager.cpp for more...
-
-# UITour
-origin	uitour	1	https://www.mozilla.org
-origin	uitour	1	https://screenshots.firefox.com
-origin	uitour	1	https://support.mozilla.org
-origin	uitour	1	https://addons.mozilla.org
-origin	uitour	1	https://discovery.addons.mozilla.org
-origin	uitour	1	about:home
-origin	uitour	1	about:newtab
-
-# XPInstall
-origin	install	1	https://addons.mozilla.org
-origin	install	1	https://testpilot.firefox.com
-
-# Remote troubleshooting
-origin	remote-troubleshooting	1	https://input.mozilla.org
-origin	remote-troubleshooting	1	https://support.mozilla.org
-
-# Hybrid Content Telemetry - https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/telemetry/collection/hybrid-content.html
-origin	hc_telemetry	1	https://discovery.addons.mozilla.org
+# This file has default permissions for the permission manager.
+# The file-format is strict:
+# * matchtype \t type \t permission \t host
+# * "origin" should be used for matchtype, "host" is supported for legacy reasons
+# * type is a string that identifies the type of permission (e.g. "cookie")
+# * permission is an integer between 1 and 15
+# See nsPermissionManager.cpp for more...
+
+# UITour
+origin	uitour	1	https://www.mozilla.org
+origin	uitour	1	https://screenshots.firefox.com
+origin	uitour	1	https://support.mozilla.org
+origin	uitour	1	https://addons.mozilla.org
+origin	uitour	1	https://discovery.addons.mozilla.org
+origin	uitour	1	about:home
+origin	uitour	1	about:newtab
+
+# XPInstall
+origin	install	1	https://addons.mozilla.org
+origin	install	1	https://testpilot.firefox.com
+
+# Remote troubleshooting
+origin	remote-troubleshooting	1	https://input.mozilla.org
+origin	remote-troubleshooting	1	https://support.mozilla.org
+
+# Hybrid Content Telemetry - https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/telemetry/collection/hybrid-content.html
+# Adding hc_telemetry permission to a new domain requires Data Collection Review: https://wiki.mozilla.org/Firefox/Data_Collection
+origin	hc_telemetry	1	https://discovery.addons.mozilla.org
--- a/browser/base/content/test/general/browser_gestureSupport.js
+++ b/browser/base/content/test/general/browser_gestureSupport.js
@@ -60,23 +60,23 @@ function test_gestureListener(evt) {
   isnot(evt.screenY, 0,
         "evt.screenY (" + evt.screenY + ") does not match expected value");
 
   is(evt.direction, test_expectedDirection,
      "evt.direction (" + evt.direction + ") does not match expected value");
   is(evt.delta, test_expectedDelta,
      "evt.delta (" + evt.delta + ") does not match expected value");
 
-  is(evt.shiftKey, (test_expectedModifiers & Ci.nsIDOMEvent.SHIFT_MASK) != 0,
+  is(evt.shiftKey, (test_expectedModifiers & Event.SHIFT_MASK) != 0,
      "evt.shiftKey did not match expected value");
-  is(evt.ctrlKey, (test_expectedModifiers & Ci.nsIDOMEvent.CONTROL_MASK) != 0,
+  is(evt.ctrlKey, (test_expectedModifiers & Event.CONTROL_MASK) != 0,
      "evt.ctrlKey did not match expected value");
-  is(evt.altKey, (test_expectedModifiers & Ci.nsIDOMEvent.ALT_MASK) != 0,
+  is(evt.altKey, (test_expectedModifiers & Event.ALT_MASK) != 0,
      "evt.altKey did not match expected value");
-  is(evt.metaKey, (test_expectedModifiers & Ci.nsIDOMEvent.META_MASK) != 0,
+  is(evt.metaKey, (test_expectedModifiers & Event.META_MASK) != 0,
      "evt.metaKey did not match expected value");
 
   if (evt.type == "MozTapGesture") {
     is(evt.clickCount, test_expectedClickCount, "evt.clickCount does not match");
   }
 
   test_eventCount++;
 }
@@ -158,29 +158,29 @@ function test_TestEventListeners() {
   test_clicks("MozPressTapGesture", 1);
 
   // simple delivery test for edgeui gestures
   e("MozEdgeUIStarted", 0, 0, 0);
   e("MozEdgeUICanceled", 0, 0, 0);
   e("MozEdgeUICompleted", 0, 0, 0);
 
   // event.shiftKey
-  let modifier = Ci.nsIDOMEvent.SHIFT_MASK;
+  let modifier = Event.SHIFT_MASK;
   e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_RIGHT, 0, modifier);
 
   // event.metaKey
-  modifier = Ci.nsIDOMEvent.META_MASK;
+  modifier = Event.META_MASK;
   e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_RIGHT, 0, modifier);
 
   // event.altKey
-  modifier = Ci.nsIDOMEvent.ALT_MASK;
+  modifier = Event.ALT_MASK;
   e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_RIGHT, 0, modifier);
 
   // event.ctrlKey
-  modifier = Ci.nsIDOMEvent.CONTROL_MASK;
+  modifier = Event.CONTROL_MASK;
   e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_RIGHT, 0, modifier);
 }
 
 function test_eventDispatchListener(evt) {
   test_eventCount++;
   evt.stopPropagation();
 }
 
--- a/browser/base/content/test/sanitize/browser_sanitize-timespans.js
+++ b/browser/base/content/test/sanitize/browser_sanitize-timespans.js
@@ -1,10 +1,13 @@
 requestLongerTimeout(2);
 
+const {PlacesTestUtils} =
+  ChromeUtils.import("resource://testing-common/PlacesTestUtils.jsm", {});
+
 // Bug 453440 - Test the timespan-based logic of the sanitizer code
 var now_mSec = Date.now();
 var now_uSec = now_mSec * 1000;
 
 const kMsecPerMin = 60 * 1000;
 const kUsecPerMin = 60 * 1000000;
 
 function promiseFormHistoryRemoved() {
@@ -421,56 +424,47 @@ async function onHistoryReady() {
   ok(!(await PlacesUtils.history.hasVisits("http://before-today.com")),
      "Pretend visit to before-today.com should now be deleted");
 
   await countEntries("b4today", "b4today form entry should be deleted", checkZero);
 
   ok(!(await downloadExists(publicList, "fakefile-old")), "Year old download should now be deleted");
 }
 
-function setupHistory() {
-  return new Promise(resolve => {
+async function setupHistory() {
 
-    let places = [];
+  let places = [];
 
-    function addPlace(aURI, aTitle, aVisitDate) {
-      places.push({
-        uri: aURI,
-        title: aTitle,
-        visits: [{
-          visitDate: aVisitDate,
-          transitionType: Ci.nsINavHistoryService.TRANSITION_LINK
-        }]
-      });
-    }
+  function addPlace(aURI, aTitle, aVisitDate) {
+    places.push({
+      uri: aURI,
+      title: aTitle,
+      visitDate: aVisitDate,
+      transition: Ci.nsINavHistoryService.TRANSITION_LINK
+    });
+  }
 
-    addPlace(makeURI("http://10minutes.com/"), "10 minutes ago", now_uSec - 10 * kUsecPerMin);
-    addPlace(makeURI("http://1hour.com/"), "Less than 1 hour ago", now_uSec - 45 * kUsecPerMin);
-    addPlace(makeURI("http://1hour10minutes.com/"), "1 hour 10 minutes ago", now_uSec - 70 * kUsecPerMin);
-    addPlace(makeURI("http://2hour.com/"), "Less than 2 hours ago", now_uSec - 90 * kUsecPerMin);
-    addPlace(makeURI("http://2hour10minutes.com/"), "2 hours 10 minutes ago", now_uSec - 130 * kUsecPerMin);
-    addPlace(makeURI("http://4hour.com/"), "Less than 4 hours ago", now_uSec - 180 * kUsecPerMin);
-    addPlace(makeURI("http://4hour10minutes.com/"), "4 hours 10 minutesago", now_uSec - 250 * kUsecPerMin);
+  addPlace("http://10minutes.com/", "10 minutes ago", now_uSec - 10 * kUsecPerMin);
+  addPlace("http://1hour.com/", "Less than 1 hour ago", now_uSec - 45 * kUsecPerMin);
+  addPlace("http://1hour10minutes.com/", "1 hour 10 minutes ago", now_uSec - 70 * kUsecPerMin);
+  addPlace("http://2hour.com/", "Less than 2 hours ago", now_uSec - 90 * kUsecPerMin);
+  addPlace("http://2hour10minutes.com/", "2 hours 10 minutes ago", now_uSec - 130 * kUsecPerMin);
+  addPlace("http://4hour.com/", "Less than 4 hours ago", now_uSec - 180 * kUsecPerMin);
+  addPlace("http://4hour10minutes.com/", "4 hours 10 minutesago", now_uSec - 250 * kUsecPerMin);
 
-    let today = new Date();
-    today.setHours(0);
-    today.setMinutes(0);
-    today.setSeconds(1);
-    addPlace(makeURI("http://today.com/"), "Today", today.getTime() * 1000);
+  let today = new Date();
+  today.setHours(0);
+  today.setMinutes(0);
+  today.setSeconds(1);
+  addPlace("http://today.com/", "Today", today.getTime() * 1000);
 
-    let lastYear = new Date();
-    lastYear.setFullYear(lastYear.getFullYear() - 1);
-    addPlace(makeURI("http://before-today.com/"), "Before Today", lastYear.getTime() * 1000);
-    PlacesUtils.asyncHistory.updatePlaces(places, {
-      handleError: () => ok(false, "Unexpected error in adding visit."),
-      handleResult: () => { },
-      handleCompletion: () => resolve()
-    });
-
-  });
+  let lastYear = new Date();
+  lastYear.setFullYear(lastYear.getFullYear() - 1);
+  addPlace("http://before-today.com/", "Before Today", lastYear.getTime() * 1000);
+  await PlacesTestUtils.addVisits(places);
 }
 
 async function setupFormHistory() {
 
   function searchEntries(terms, params) {
     return new Promise((resolve, reject) => {
 
       let results = [];
--- a/browser/components/extensions/test/mochitest/test_ext_all_apis.html
+++ b/browser/components/extensions/test/mochitest/test_ext_all_apis.html
@@ -1,15 +1,15 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>WebExtension test</title>
   <meta charset="utf-8">
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
 </head>
 <body>
 <script>
 "use strict";
 /* exported expectedContentApisTargetSpecific, expectedBackgroundApisTargetSpecific */
 let expectedContentApisTargetSpecific = [
--- a/browser/components/places/tests/browser/browser_library_downloads.js
+++ b/browser/components/places/tests/browser/browser_library_downloads.js
@@ -5,64 +5,47 @@
 /*
  * Tests bug 564900: Add folder specifically for downloads to Library left pane.
  * https://bugzilla.mozilla.org/show_bug.cgi?id=564900
  * This test visits various pages then opens the Library and ensures
  * that both the Downloads folder shows up and that the correct visits
  * are shown in it.
  */
 
-var now = Date.now();
+add_task(async function test() {
+  // Add visits.
+  await PlacesTestUtils.addVisits([{
+    uri: "http://mozilla.org",
+    transition: PlacesUtils.history.TRANSITION_TYPED
+  }, {
+    uri: "http://google.com",
+    transition: PlacesUtils.history.TRANSITION_DOWNLOAD
+  }, {
+    uri: "http://en.wikipedia.org",
+    transition: PlacesUtils.history.TRANSITION_TYPED
+  }, {
+    uri: "http://ubuntu.org",
+    transition: PlacesUtils.history.TRANSITION_DOWNLOAD
+  }]);
 
-function test() {
-  waitForExplicitFinish();
+  let library = await promiseLibrary("Downloads");
 
-  let onLibraryReady = function(win) {
-    // Add visits to compare contents with.
-    let places = [
-      { uri: NetUtil.newURI("http://mozilla.com"),
-        visits: [ new VisitInfo(PlacesUtils.history.TRANSITION_TYPED) ]
-      },
-      { uri: NetUtil.newURI("http://google.com"),
-        visits: [ new VisitInfo(PlacesUtils.history.TRANSITION_DOWNLOAD) ]
-      },
-      { uri: NetUtil.newURI("http://en.wikipedia.org"),
-        visits: [ new VisitInfo(PlacesUtils.history.TRANSITION_TYPED) ]
-      },
-      { uri: NetUtil.newURI("http://ubuntu.org"),
-        visits: [ new VisitInfo(PlacesUtils.history.TRANSITION_DOWNLOAD) ]
-      },
-    ];
-    PlacesUtils.asyncHistory.updatePlaces(places, {
-      handleResult() {},
-      handleError() {
-        ok(false, "gHistory.updatePlaces() failed");
-      },
-      handleCompletion() {
-        // Make sure Downloads is present.
-        isnot(win.PlacesOrganizer._places.selectedNode, null,
-              "Downloads is present and selected");
+  registerCleanupFunction(async () => {
+    await library.close();
+    await PlacesUtils.history.clear();
+  });
+
+  // Make sure Downloads is present.
+  Assert.notEqual(library.PlacesOrganizer._places.selectedNode, null,
+    "Downloads is present and selected");
 
+  // Check results.
+  let testURIs = ["http://ubuntu.org/", "http://google.com/"];
 
-        // Check results.
-        let testURIs = ["http://ubuntu.org/", "http://google.com/"];
-        for (let element of win.ContentArea.currentView
-                                           .associatedElement.children) {
-          is(element._shell.download.source.url, testURIs.shift(),
-             "URI matches");
-        }
+  await BrowserTestUtils.waitForCondition(() =>
+    library.ContentArea.currentView.associatedElement.children.length == testURIs.length);
 
-        win.close();
-        PlacesUtils.history.clear().then(finish);
-      }
-    });
-  };
-
-  openLibrary(onLibraryReady, "Downloads");
-}
-
-function VisitInfo(aTransitionType) {
-  this.transitionType =
-    aTransitionType === undefined ?
-      PlacesUtils.history.TRANSITION_LINK : aTransitionType;
-  this.visitDate = now++ * 1000;
-}
-VisitInfo.prototype = {};
+  for (let element of library.ContentArea.currentView
+                                          .associatedElement.children) {
+    Assert.equal(element._shell.download.source.url, testURIs.shift(),
+      "URI matches");
+  }
+});
--- a/browser/components/resistfingerprinting/test/mochitest/test_bug863246_resource_uri.html
+++ b/browser/components/resistfingerprinting/test/mochitest/test_bug863246_resource_uri.html
@@ -1,12 +1,12 @@
 <!DOCTYPE html>
 <meta charset="utf8">
 <script src="/tests/SimpleTest/SimpleTest.js"></script>
-<script src="/tests/SimpleTest/SpawnTask.js"></script>
+<script src="/tests/SimpleTest/AddTask.js"></script>
 <script>
 /* global SimpleTest SpecialPowers add_task */
 
 function waitForDOMContentLoaded() {
   return new Promise((aResolve) => {
     document.addEventListener("DOMContentLoaded", aResolve);
   });
 }
--- a/browser/components/resistfingerprinting/test/mochitest/test_reduce_time_precision.html
+++ b/browser/components/resistfingerprinting/test/mochitest/test_reduce_time_precision.html
@@ -3,17 +3,17 @@
 <!--
 Tor bug
 https://trac.torproject.org/projects/tor/ticket/1517
 -->
 <head>
   <meta charset="utf-8">
   <title>Test for Tor Bug 1517 and Mozilla Bug 1424341</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
 <a target="_blank" href="https://trac.torproject.org/projects/tor/ticket/1517">Tor Bug 1517</a>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1424341">Mozilla Bug 1424341</a>
 
 <!-- Canvas for testing 'currentTime' -->
 <canvas id="test-canvas" width="100" height="100"></canvas>
--- a/browser/components/sessionstore/nsISessionStoreUtils.idl
+++ b/browser/components/sessionstore/nsISessionStoreUtils.idl
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface mozIDOMWindowProxy;
-interface nsIDOMEventTarget;
+webidl EventTarget;
 
 /**
  * A callback passed to nsISessionStoreUtils.forEachNonDynamicChildFrame().
  */
 [function, scriptable, uuid(8199ebf7-76c0-43d6-bcbe-913dd3de3ebf)]
 interface nsISessionStoreUtilsFrameCallback : nsISupports
 {
   /**
@@ -38,32 +38,30 @@ interface nsISessionStoreUtils : nsISupp
    * Takes the given listener, wraps it in a filter that filters out events from
    * dynamic docShells, and adds that filter as a listener for the given event
    * type on the given event target.  The listener that was added is returned
    * (as nsISupports) so that it can later be removed via
    * removeDynamicFrameFilteredListener.
    *
    * This is implemented as a native filter, rather than a JS-based one, for
    * performance reasons.
-   *
-   * Once bug 1444991 is fixed, this should start taking an EventTarget.
    */
   [implicit_jscontext]
-  nsISupports addDynamicFrameFilteredListener(in nsIDOMEventTarget target,
+  nsISupports addDynamicFrameFilteredListener(in EventTarget target,
                                               in AString type,
                                               in jsval listener,
                                               in boolean useCapture);
 
   /**
    * Remove the passed-in filtered listener from the given event target, if it's
    * currently a listener for the given event type there.  The 'listener'
    * argument must be something that was returned by
    * addDynamicFrameFilteredListener.
    *
    * This is needed, instead of the normal removeEventListener, because the
    * caller doesn't actually have something that WebIDL considers an
    * EventListener.
    */
-  void removeDynamicFrameFilteredListener(in nsIDOMEventTarget target,
+  void removeDynamicFrameFilteredListener(in EventTarget target,
                                           in AString type,
                                           in nsISupports listener,
                                           in boolean useCapture);
 };
--- a/browser/components/sessionstore/nsSessionStoreUtils.cpp
+++ b/browser/components/sessionstore/nsSessionStoreUtils.cpp
@@ -20,31 +20,31 @@ class DynamicFrameEventFilter final : pu
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(DynamicFrameEventFilter)
 
   explicit DynamicFrameEventFilter(EventListener* aListener)
     : mListener(aListener)
   { }
 
-  NS_IMETHODIMP HandleEvent(nsIDOMEvent* aEvent) override
+  NS_IMETHODIMP HandleEvent(Event* aEvent) override
   {
     if (mListener && TargetInNonDynamicDocShell(aEvent)) {
-      mListener->HandleEvent(*aEvent->InternalDOMEvent());
+      mListener->HandleEvent(*aEvent);
     }
 
     return NS_OK;
   }
 
 private:
   ~DynamicFrameEventFilter() { }
 
-  bool TargetInNonDynamicDocShell(nsIDOMEvent* aEvent)
+  bool TargetInNonDynamicDocShell(Event* aEvent)
   {
-    EventTarget* target = aEvent->InternalDOMEvent()->GetTarget();
+    EventTarget* target = aEvent->GetTarget();
     if (!target) {
       return false;
     }
 
     nsPIDOMWindowOuter* outer = target->GetOwnerGlobalForBindings();
     if (!outer) {
       return false;
     }
@@ -112,50 +112,48 @@ nsSessionStoreUtils::ForEachNonDynamicCh
 
     aCallback->HandleFrame(item->GetWindow(), childOffset);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSessionStoreUtils::AddDynamicFrameFilteredListener(nsIDOMEventTarget* aTarget,
+nsSessionStoreUtils::AddDynamicFrameFilteredListener(EventTarget* aTarget,
                                                      const nsAString& aType,
                                                      JS::Handle<JS::Value> aListener,
                                                      bool aUseCapture,
                                                      JSContext* aCx,
                                                      nsISupports** aResult)
 {
   if (NS_WARN_IF(!aListener.isObject())) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  nsCOMPtr<EventTarget> target = do_QueryInterface(aTarget);
-  NS_ENSURE_TRUE(target, NS_ERROR_NO_INTERFACE);
+  NS_ENSURE_TRUE(aTarget, NS_ERROR_NO_INTERFACE);
 
   JS::Rooted<JSObject*> obj(aCx, &aListener.toObject());
   RefPtr<EventListener> listener =
     new EventListener(aCx, obj, GetIncumbentGlobal());
 
   nsCOMPtr<nsIDOMEventListener> filter(new DynamicFrameEventFilter(listener));
 
-  nsresult rv = target->AddEventListener(aType, filter, aUseCapture);
+  nsresult rv = aTarget->AddEventListener(aType, filter, aUseCapture);
   NS_ENSURE_SUCCESS(rv, rv);
 
   filter.forget(aResult);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSessionStoreUtils::RemoveDynamicFrameFilteredListener(nsIDOMEventTarget* aTarget,
+nsSessionStoreUtils::RemoveDynamicFrameFilteredListener(EventTarget* aTarget,
                                                         const nsAString& aType,
                                                         nsISupports* aListener,
                                                         bool aUseCapture)
 {
-  nsCOMPtr<EventTarget> target = do_QueryInterface(aTarget);
-  NS_ENSURE_TRUE(target, NS_ERROR_NO_INTERFACE);
+  NS_ENSURE_TRUE(aTarget, NS_ERROR_NO_INTERFACE);
 
   nsCOMPtr<nsIDOMEventListener> listener = do_QueryInterface(aListener);
   NS_ENSURE_TRUE(listener, NS_ERROR_NO_INTERFACE);
 
-  target->RemoveEventListener(aType, listener, aUseCapture);
+  aTarget->RemoveEventListener(aType, listener, aUseCapture);
   return NS_OK;
 }
--- a/browser/extensions/formautofill/test/mochitest/test_autofocus_form.html
+++ b/browser/extensions/formautofill/test/mochitest/test_autofocus_form.html
@@ -1,25 +1,25 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <meta charset="utf-8">
   <title>Test basic autofill</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <script type="text/javascript" src="formautofill_common.js"></script>
   <script type="text/javascript" src="satchel_common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 Form autofill test: autocomplete on an autofocus form
 
 <script>
-/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/SpawnTask.js */
+/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/AddTask.js */
 /* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
 /* import-globals-from formautofill_common.js */
 
 "use strict";
 
 let MOCK_STORAGE = [{
   organization: "Sesame Street",
   "street-address": "123 Sesame Street.",
--- a/browser/extensions/formautofill/test/mochitest/test_basic_autocomplete_form.html
+++ b/browser/extensions/formautofill/test/mochitest/test_basic_autocomplete_form.html
@@ -1,25 +1,25 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <meta charset="utf-8">
   <title>Test basic autofill</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <script type="text/javascript" src="formautofill_common.js"></script>
   <script type="text/javascript" src="satchel_common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 Form autofill test: simple form address autofill
 
 <script>
-/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/SpawnTask.js */
+/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/AddTask.js */
 /* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
 /* import-globals-from formautofill_common.js */
 
 "use strict";
 
 let MOCK_STORAGE = [{
   organization: "Sesame Street",
   "street-address": "123 Sesame Street.\n2-line\n3-line",
--- a/browser/extensions/formautofill/test/mochitest/test_basic_creditcard_autocomplete_form.html
+++ b/browser/extensions/formautofill/test/mochitest/test_basic_creditcard_autocomplete_form.html
@@ -1,25 +1,25 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <meta charset="utf-8">
   <title>Test basic autofill</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <script type="text/javascript" src="formautofill_common.js"></script>
   <script type="text/javascript" src="satchel_common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 Form autofill test: simple form credit card autofill
 
 <script>
-/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/SpawnTask.js */
+/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/AddTask.js */
 /* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
 /* import-globals-from formautofill_common.js */
 
 "use strict";
 
 const MOCK_STORAGE = [{
   "cc-name": "John Doe",
   "cc-number": "1234567812345678",
--- a/browser/extensions/formautofill/test/mochitest/test_clear_form.html
+++ b/browser/extensions/formautofill/test/mochitest/test_clear_form.html
@@ -1,25 +1,25 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <meta charset="utf-8">
   <title>Test form autofill - clear form button</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <script type="text/javascript" src="formautofill_common.js"></script>
   <script type="text/javascript" src="satchel_common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 Form autofill test: clear form button
 
 <script>
-/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/SpawnTask.js */
+/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/AddTask.js */
 /* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
 /* import-globals-from formautofill_common.js */
 
 "use strict";
 
 const MOCK_ADDR_STORAGE = [{
   organization: "Sesame Street",
   "street-address": "2 Harrison St\nline2\nline3",
--- a/browser/extensions/formautofill/test/mochitest/test_creditcard_autocomplete_off.html
+++ b/browser/extensions/formautofill/test/mochitest/test_creditcard_autocomplete_off.html
@@ -1,25 +1,25 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <meta charset="utf-8">
   <title>Test basic autofill</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <script type="text/javascript" src="formautofill_common.js"></script>
   <script type="text/javascript" src="satchel_common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 Form autofill test: simple form credit card autofill
 
 <script>
-/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/SpawnTask.js */
+/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/AddTask.js */
 /* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
 /* import-globals-from formautofill_common.js */
 
 "use strict";
 
 const MOCK_STORAGE = [{
   "cc-name": "John Doe",
   "cc-number": "1234567812345678",
--- a/browser/extensions/formautofill/test/mochitest/test_form_changes.html
+++ b/browser/extensions/formautofill/test/mochitest/test_form_changes.html
@@ -1,25 +1,25 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <meta charset="utf-8">
   <title>Test basic autofill</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <script type="text/javascript" src="formautofill_common.js"></script>
   <script type="text/javascript" src="satchel_common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 Form autofill test: autocomplete on an autofocus form
 
 <script>
-/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/SpawnTask.js */
+/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/AddTask.js */
 /* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
 /* import-globals-from formautofill_common.js */
 
 "use strict";
 
 let MOCK_STORAGE = [{
   name: "John Doe",
   organization: "Sesame Street",
--- a/browser/extensions/formautofill/test/mochitest/test_formautofill_preview_highlight.html
+++ b/browser/extensions/formautofill/test/mochitest/test_formautofill_preview_highlight.html
@@ -1,25 +1,25 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <meta charset="utf-8">
   <title>Test form autofill - preview and highlight</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <script type="text/javascript" src="formautofill_common.js"></script>
   <script type="text/javascript" src="satchel_common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 Form autofill test: preview and highlight
 
 <script>
-/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/SpawnTask.js */
+/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/AddTask.js */
 /* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
 /* import-globals-from formautofill_common.js */
 
 "use strict";
 
 const MOCK_STORAGE = [{
   organization: "Sesame Street",
   "street-address": "123 Sesame Street.",
--- a/browser/extensions/formautofill/test/mochitest/test_multi_locale_CA_address_form.html
+++ b/browser/extensions/formautofill/test/mochitest/test_multi_locale_CA_address_form.html
@@ -1,25 +1,25 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <meta charset="utf-8">
   <title>Test basic autofill</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <script type="text/javascript" src="formautofill_common.js"></script>
   <script type="text/javascript" src="satchel_common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 Form autofill test: simple form address autofill
 
 <script>
-/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/SpawnTask.js */
+/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/AddTask.js */
 /* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
 /* import-globals-from formautofill_common.js */
 
 "use strict";
 
 let MOCK_STORAGE = [{
   organization: "Mozilla Vancouver",
   "street-address": "163 W Hastings St.\n#209\n3-line",
--- a/browser/extensions/formautofill/test/mochitest/test_multiple_forms.html
+++ b/browser/extensions/formautofill/test/mochitest/test_multiple_forms.html
@@ -1,24 +1,24 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <meta charset="utf-8">
   <title>Test autofill submit</title>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <script type="text/javascript" src="formautofill_common.js"></script>
   <script type="text/javascript" src="satchel_common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 
 <script>
-/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/SpawnTask.js */
+/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/AddTask.js */
 /* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
 /* import-globals-from formautofill_common.js */
 
 "use strict";
 
 let MOCK_STORAGE = [{
   "given-name": "John",
   "additional-name": "R",
--- a/browser/extensions/formautofill/test/mochitest/test_on_address_submission.html
+++ b/browser/extensions/formautofill/test/mochitest/test_on_address_submission.html
@@ -1,25 +1,25 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <meta charset="utf-8">
   <title>Test autofill submit</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <script type="text/javascript" src="formautofill_common.js"></script>
   <script type="text/javascript" src="satchel_common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 Form autofill test: check if address is saved/updated correctly
 
 <script>
-/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/SpawnTask.js */
+/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/AddTask.js */
 /* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
 /* import-globals-from formautofill_common.js */
 
 "use strict";
 
 let TEST_ADDRESSES = [{
   organization: "Sesame Street",
   "street-address": "123 Sesame Street.",
--- a/browser/modules/BrowserUsageTelemetry.jsm
+++ b/browser/modules/BrowserUsageTelemetry.jsm
@@ -505,17 +505,17 @@ let BrowserUsageTelemetry = {
 
     // The search signal was generated by typing something and pressing enter.
     this._recordSearch(engine, sourceName, "enter");
   },
 
   /**
    * Records the method by which the user selected a urlbar result.
    *
-   * @param {nsIDOMEvent} event
+   * @param {Event} event
    *        The event that triggered the selection.
    * @param {string} userSelectionBehavior
    *        How the user cycled through results before picking the current match.
    *        Could be one of "tab", "arrow" or "none".
    */
   recordUrlbarSelectedResultMethod(event, userSelectionBehavior = "none") {
     // The reason this method relies on urlbarListener instead of having the
     // caller pass in an index is that by the time the urlbar handles a
@@ -529,17 +529,17 @@ let BrowserUsageTelemetry = {
       "FX_URLBAR_SELECTED_RESULT_METHOD",
       userSelectionBehavior
     );
   },
 
   /**
    * Records the method by which the user selected a searchbar result.
    *
-   * @param {nsIDOMEvent} event
+   * @param {Event} event
    *        The event that triggered the selection.
    * @param {number} highlightedIndex
    *        The index that the user chose in the popup, or -1 if there wasn't a
    *        selection.
    */
   recordSearchbarSelectedResultMethod(event, highlightedIndex) {
     this._recordUrlOrSearchbarSelectedResultMethod(
       event, highlightedIndex,
--- a/devtools/client/commandline/test/helpers.js
+++ b/devtools/client/commandline/test/helpers.js
@@ -218,30 +218,30 @@ var { helpers, assert } = (function () {
       options.requisition = toolbar.requisition;
       return options;
     });
   };
 
 /**
  * Navigate the current tab to a URL
  */
-  helpers.navigate = Task.async(function* (url, options) {
+  helpers.navigate = async function(url, options) {
     options = options || {};
     options.chromeWindow = options.chromeWindow || window;
     options.tab = options.tab || options.chromeWindow.gBrowser.selectedTab;
 
     var tabbrowser = options.chromeWindow.gBrowser;
     options.browser = tabbrowser.getBrowserForTab(options.tab);
 
     let onLoaded = BrowserTestUtils.browserLoaded(options.browser);
     options.browser.loadURI(url);
-    yield onLoaded;
+    await onLoaded;
 
     return options;
-  });
+  };
 
 /**
  * Undo the effects of |helpers.openToolbar|
  * @param options The options object passed to |helpers.openToolbar|
  * @return A promise resolved (with undefined) when the toolbar is closed
  */
   helpers.closeToolbar = function (options) {
     var toolbar = gDevToolsBrowser.getDeveloperToolbar(options.chromeWindow).hide();
@@ -414,25 +414,25 @@ var { helpers, assert } = (function () {
  * 2. Open the developer toolbar
  * 3. Register the mock commands with the server process
  * 4. Wait for the proxy commands to be auto-regitstered with the client
  * 5. Register the mock converters with the client process
  * 6. Run all the tests
  * 7. Tear down all the setup
  */
   helpers.runTestModule = function (exports, name) {
-    return Task.spawn(function* () {
+    return (async function() {
       const uri = "data:text/html;charset=utf-8," +
                 "<style>div{color:red;}</style>" +
                 "<div id='gcli-root'>" + name + "</div>";
 
-      const options = yield helpers.openTab(uri);
+      const options = await helpers.openTab(uri);
       options.isRemote = true;
 
-      yield helpers.openToolbar(options);
+      await helpers.openToolbar(options);
 
       const system = options.requisition.system;
 
     // Register a one time listener with the local set of commands
       const addedDeferred = defer();
       const removedDeferred = defer();
       let state = "preAdd"; // Then 'postAdd' then 'postRemove'
 
@@ -447,40 +447,40 @@ var { helpers, assert } = (function () {
           if (state === "postAdd") {
             removedDeferred.resolve();
             state = "postRemove";
           }
         }
       });
 
     // Send a message to add the commands to the content process
-      const front = yield GcliFront.create(options.target);
-      yield front._testOnlyAddItemsByModule(MOCK_COMMANDS_URI);
+      const front = await GcliFront.create(options.target);
+      await front._testOnlyAddItemsByModule(MOCK_COMMANDS_URI);
 
     // This will cause the local set of commands to be updated with the
     // command proxies, wait for that to complete.
-      yield addedDeferred.promise;
+      await addedDeferred.promise;
 
     // Now we need to add the converters to the local GCLI
       const converters = mockCommands.items.filter(item => item.item === "converter");
       system.addItems(converters);
 
     // Next run the tests
-      yield helpers.runTests(options, exports);
+      await helpers.runTests(options, exports);
 
     // Finally undo the mock commands and converters
       system.removeItems(converters);
       const removePromise = system.commands.onCommandsChange.once();
-      yield front._testOnlyRemoveItemsByModule(MOCK_COMMANDS_URI);
-      yield removedDeferred.promise;
+      await front._testOnlyRemoveItemsByModule(MOCK_COMMANDS_URI);
+      await removedDeferred.promise;
 
     // And close everything down
-      yield helpers.closeToolbar(options);
-      yield helpers.closeTab(options);
-    }).then(finish, helpers.handleError);
+      await helpers.closeToolbar(options);
+      await helpers.closeTab(options);
+    })().then(finish, helpers.handleError);
   };
 
 /**
  * Ensure that the options object is setup correctly
  * options should contain an automator object that looks like this:
  * {
  *   getInputState: function() { ... },
  *   setCursor: function(cursor) { ... },
--- 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 40.0
+Version 41.0
 
-Comparison: https://github.com/devtools-html/debugger.html/compare/release-39...release-40
+Comparison: https://github.com/devtools-html/debugger.html/compare/release-40...release-41
 
 Packages:
 - babel-plugin-transform-es2015-modules-commonjs @6.26.0
 - babel-preset-react @6.24.1
 - react @16.2.0
 - react-dom @16.2.0
 - webpack @3.11.0
--- a/devtools/client/debugger/new/debugger.js
+++ b/devtools/client/debugger/new/debugger.js
@@ -2934,37 +2934,39 @@ exports.default = _Svg2.default;
 
 const {
   originalToGeneratedId,
   generatedToOriginalId,
   isGeneratedId,
   isOriginalId
 } = __webpack_require__(1389);
 
-const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1390);
+const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1363);
 
 const dispatcher = new WorkerDispatcher();
 
 const getOriginalURLs = dispatcher.task("getOriginalURLs");
-const getGeneratedLocation = dispatcher.task("getGeneratedLocation");
-const getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations");
+const getGeneratedRanges = dispatcher.task("getGeneratedRanges", { queue: true });
+const getGeneratedLocation = dispatcher.task("getGeneratedLocation", { queue: true });
+const getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations", { queue: true });
 const getOriginalLocation = dispatcher.task("getOriginalLocation");
 const getLocationScopes = dispatcher.task("getLocationScopes");
 const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
 const applySourceMap = dispatcher.task("applySourceMap");
 const clearSourceMaps = dispatcher.task("clearSourceMaps");
 const hasMappedSource = dispatcher.task("hasMappedSource");
 
 module.exports = {
   originalToGeneratedId,
   generatedToOriginalId,
   isGeneratedId,
   isOriginalId,
   hasMappedSource,
   getOriginalURLs,
+  getGeneratedRanges,
   getGeneratedLocation,
   getAllGeneratedLocations,
   getOriginalLocation,
   getLocationScopes,
   getOriginalSourceText,
   applySourceMap,
   clearSourceMaps,
   startSourceMapWorker: dispatcher.start.bind(dispatcher),
@@ -5460,194 +5462,16 @@ module.exports = {
   isOriginalId,
   isGeneratedId,
   getContentType,
   contentMapForTesting: contentMap
 };
 
 /***/ }),
 
-/***/ 1390:
-/***/ (function(module, exports, __webpack_require__) {
-
-/* 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 networkRequest = __webpack_require__(1391);
-const workerUtils = __webpack_require__(1392);
-
-module.exports = {
-  networkRequest,
-  workerUtils
-};
-
-/***/ }),
-
-/***/ 1391:
-/***/ (function(module, exports) {
-
-/* 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 networkRequest(url, opts) {
-  return fetch(url, {
-    cache: opts.loadFromCache ? "default" : "no-cache"
-  }).then(res => {
-    if (res.status >= 200 && res.status < 300) {
-      return res.text().then(text => ({ content: text }));
-    }
-    return Promise.reject(`request failed with status ${res.status}`);
-  });
-}
-
-module.exports = networkRequest;
-
-/***/ }),
-
-/***/ 1392:
-/***/ (function(module, exports) {
-
-function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
-
-function WorkerDispatcher() {
-  this.msgId = 1;
-  this.worker = 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/. */
-
-WorkerDispatcher.prototype = {
-  start(url) {
-    this.worker = new Worker(url);
-    this.worker.onerror = () => {
-      console.error(`Error in worker ${url}`);
-    };
-  },
-
-  stop() {
-    if (!this.worker) {
-      return;
-    }
-
-    this.worker.terminate();
-    this.worker = null;
-  },
-
-  task(method) {
-    return (...args) => {
-      return new Promise((resolve, reject) => {
-        const id = this.msgId++;
-        this.worker.postMessage({ id, method, args });
-
-        const listener = ({ data: result }) => {
-          if (result.id !== id) {
-            return;
-          }
-
-          if (!this.worker) {
-            return;
-          }
-
-          this.worker.removeEventListener("message", listener);
-          if (result.error) {
-            reject(result.error);
-          } else {
-            resolve(result.response);
-          }
-        };
-
-        this.worker.addEventListener("message", listener);
-      });
-    };
-  }
-};
-
-function workerHandler(publicInterface) {
-  return function (msg) {
-    const { id, method, args } = msg.data;
-    try {
-      const response = publicInterface[method].apply(undefined, args);
-      if (response instanceof Promise) {
-        response.then(val => self.postMessage({ id, response: val }),
-        // Error can't be sent via postMessage, so be sure to
-        // convert to string.
-        err => self.postMessage({ id, error: err.toString() }));
-      } else {
-        self.postMessage({ id, response });
-      }
-    } catch (error) {
-      // Error can't be sent via postMessage, so be sure to convert to
-      // string.
-      self.postMessage({ id, error: error.toString() });
-    }
-  };
-}
-
-function streamingWorkerHandler(publicInterface, { timeout = 100 } = {}, worker = self) {
-  let streamingWorker = (() => {
-    var _ref = _asyncToGenerator(function* (id, tasks) {
-      let isWorking = true;
-
-      const intervalId = setTimeout(function () {
-        isWorking = false;
-      }, timeout);
-
-      const results = [];
-      while (tasks.length !== 0 && isWorking) {
-        const { callback, context, args } = tasks.shift();
-        const result = yield callback.call(context, args);
-        results.push(result);
-      }
-      worker.postMessage({ id, status: "pending", data: results });
-      clearInterval(intervalId);
-
-      if (tasks.length !== 0) {
-        yield streamingWorker(id, tasks);
-      }
-    });
-
-    return function streamingWorker(_x, _x2) {
-      return _ref.apply(this, arguments);
-    };
-  })();
-
-  return (() => {
-    var _ref2 = _asyncToGenerator(function* (msg) {
-      const { id, method, args } = msg.data;
-      const workerMethod = publicInterface[method];
-      if (!workerMethod) {
-        console.error(`Could not find ${method} defined in worker.`);
-      }
-      worker.postMessage({ id, status: "start" });
-
-      try {
-        const tasks = workerMethod(args);
-        yield streamingWorker(id, tasks);
-        worker.postMessage({ id, status: "done" });
-      } catch (error) {
-        worker.postMessage({ id, status: "error", error });
-      }
-    });
-
-    return function (_x3) {
-      return _ref2.apply(this, arguments);
-    };
-  })();
-}
-
-module.exports = {
-  WorkerDispatcher,
-  workerHandler,
-  streamingWorkerHandler
-};
-
-/***/ }),
-
 /***/ 1393:
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
@@ -23499,17 +23323,17 @@ class Breakpoints extends _react.Compone
 
     const groupedBreakpoints = (0, _lodash.groupBy)((0, _lodash.sortBy)([...breakpoints.valueSeq()], bp => bp.location.line), bp => getBreakpointFilename(bp.source));
 
     return [...Object.keys(groupedBreakpoints).sort().map(filename => {
       return [_react2.default.createElement(
         "div",
         { className: "breakpoint-heading", title: filename, key: filename },
         filename
-      ), ...groupedBreakpoints[filename].filter(bp => !bp.hidden && bp.text).map((bp, i) => this.renderBreakpoint(bp))];
+      ), ...groupedBreakpoints[filename].filter(bp => !bp.hidden && bp.text).map(bp => this.renderBreakpoint(bp))];
     })];
   }
 
   render() {
     return _react2.default.createElement(
       "div",
       { className: "pane breakpoints-list" },
       this.renderExceptionsOptions(),
@@ -26801,17 +26625,17 @@ function findEmptyLines(selectedSource, 
     return [];
   }
 
   const pausePointsList = (0, _pausePoints.convertToList)(pausePoints);
 
   const breakpoints = pausePointsList.filter(point => point.types.break);
   const breakpointLines = breakpoints.map(point => point.location.line);
 
-  if (!selectedSource.text) {
+  if (!selectedSource.text || breakpointLines.length == 0) {
     return [];
   }
 
   const lineCount = selectedSource.text.split("\n").length;
   const sourceLines = (0, _lodash.range)(1, lineCount + 1);
   return (0, _lodash.xor)(sourceLines, breakpointLines);
 }
 
--- a/devtools/client/debugger/new/parser-worker.js
+++ b/devtools/client/debugger/new/parser-worker.js
@@ -773,37 +773,39 @@ module.exports = overArg;
 
 const {
   originalToGeneratedId,
   generatedToOriginalId,
   isGeneratedId,
   isOriginalId
 } = __webpack_require__(1389);
 
-const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1390);
+const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1363);
 
 const dispatcher = new WorkerDispatcher();
 
 const getOriginalURLs = dispatcher.task("getOriginalURLs");
-const getGeneratedLocation = dispatcher.task("getGeneratedLocation");
-const getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations");
+const getGeneratedRanges = dispatcher.task("getGeneratedRanges", { queue: true });
+const getGeneratedLocation = dispatcher.task("getGeneratedLocation", { queue: true });
+const getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations", { queue: true });
 const getOriginalLocation = dispatcher.task("getOriginalLocation");
 const getLocationScopes = dispatcher.task("getLocationScopes");
 const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
 const applySourceMap = dispatcher.task("applySourceMap");
 const clearSourceMaps = dispatcher.task("clearSourceMaps");
 const hasMappedSource = dispatcher.task("hasMappedSource");
 
 module.exports = {
   originalToGeneratedId,
   generatedToOriginalId,
   isGeneratedId,
   isOriginalId,
   hasMappedSource,
   getOriginalURLs,
+  getGeneratedRanges,
   getGeneratedLocation,
   getAllGeneratedLocations,
   getOriginalLocation,
   getLocationScopes,
   getOriginalSourceText,
   applySourceMap,
   clearSourceMaps,
   startSourceMapWorker: dispatcher.start.bind(dispatcher),
@@ -1224,194 +1226,16 @@ module.exports = {
   isOriginalId,
   isGeneratedId,
   getContentType,
   contentMapForTesting: contentMap
 };
 
 /***/ }),
 
-/***/ 1390:
-/***/ (function(module, exports, __webpack_require__) {
-
-/* 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 networkRequest = __webpack_require__(1391);
-const workerUtils = __webpack_require__(1392);
-
-module.exports = {
-  networkRequest,
-  workerUtils
-};
-
-/***/ }),
-
-/***/ 1391:
-/***/ (function(module, exports) {
-
-/* 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 networkRequest(url, opts) {
-  return fetch(url, {
-    cache: opts.loadFromCache ? "default" : "no-cache"
-  }).then(res => {
-    if (res.status >= 200 && res.status < 300) {
-      return res.text().then(text => ({ content: text }));
-    }
-    return Promise.reject(`request failed with status ${res.status}`);
-  });
-}
-
-module.exports = networkRequest;
-
-/***/ }),
-
-/***/ 1392:
-/***/ (function(module, exports) {
-
-function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
-
-function WorkerDispatcher() {
-  this.msgId = 1;
-  this.worker = 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/. */
-
-WorkerDispatcher.prototype = {
-  start(url) {
-    this.worker = new Worker(url);
-    this.worker.onerror = () => {
-      console.error(`Error in worker ${url}`);
-    };
-  },
-
-  stop() {
-    if (!this.worker) {
-      return;
-    }
-
-    this.worker.terminate();
-    this.worker = null;
-  },
-
-  task(method) {
-    return (...args) => {
-      return new Promise((resolve, reject) => {
-        const id = this.msgId++;
-        this.worker.postMessage({ id, method, args });
-
-        const listener = ({ data: result }) => {
-          if (result.id !== id) {
-            return;
-          }
-
-          if (!this.worker) {
-            return;
-          }
-
-          this.worker.removeEventListener("message", listener);
-          if (result.error) {
-            reject(result.error);
-          } else {
-            resolve(result.response);
-          }
-        };
-
-        this.worker.addEventListener("message", listener);
-      });
-    };
-  }
-};
-
-function workerHandler(publicInterface) {
-  return function (msg) {
-    const { id, method, args } = msg.data;
-    try {
-      const response = publicInterface[method].apply(undefined, args);
-      if (response instanceof Promise) {
-        response.then(val => self.postMessage({ id, response: val }),
-        // Error can't be sent via postMessage, so be sure to
-        // convert to string.
-        err => self.postMessage({ id, error: err.toString() }));
-      } else {
-        self.postMessage({ id, response });
-      }
-    } catch (error) {
-      // Error can't be sent via postMessage, so be sure to convert to
-      // string.
-      self.postMessage({ id, error: error.toString() });
-    }
-  };
-}
-
-function streamingWorkerHandler(publicInterface, { timeout = 100 } = {}, worker = self) {
-  let streamingWorker = (() => {
-    var _ref = _asyncToGenerator(function* (id, tasks) {
-      let isWorking = true;
-
-      const intervalId = setTimeout(function () {
-        isWorking = false;
-      }, timeout);
-
-      const results = [];
-      while (tasks.length !== 0 && isWorking) {
-        const { callback, context, args } = tasks.shift();
-        const result = yield callback.call(context, args);
-        results.push(result);
-      }
-      worker.postMessage({ id, status: "pending", data: results });
-      clearInterval(intervalId);
-
-      if (tasks.length !== 0) {
-        yield streamingWorker(id, tasks);
-      }
-    });
-
-    return function streamingWorker(_x, _x2) {
-      return _ref.apply(this, arguments);
-    };
-  })();
-
-  return (() => {
-    var _ref2 = _asyncToGenerator(function* (msg) {
-      const { id, method, args } = msg.data;
-      const workerMethod = publicInterface[method];
-      if (!workerMethod) {
-        console.error(`Could not find ${method} defined in worker.`);
-      }
-      worker.postMessage({ id, status: "start" });
-
-      try {
-        const tasks = workerMethod(args);
-        yield streamingWorker(id, tasks);
-        worker.postMessage({ id, status: "done" });
-      } catch (error) {
-        worker.postMessage({ id, status: "error", error });
-      }
-    });
-
-    return function (_x3) {
-      return _ref2.apply(this, arguments);
-    };
-  })();
-}
-
-module.exports = {
-  WorkerDispatcher,
-  workerHandler,
-  streamingWorkerHandler
-};
-
-/***/ }),
-
 /***/ 14:
 /***/ (function(module, exports) {
 
 /**
  * Checks if `value` is object-like. A value is object-like if it's not `null`
  * and has a `typeof` result of "object".
  *
  * @static
--- a/devtools/client/framework/test/browser_target_support.js
+++ b/devtools/client/framework/test/browser_target_support.js
@@ -56,17 +56,17 @@ function test() {
 
   getChromeActors((client, response) => {
     let options = {
       form: response,
       client: client,
       chrome: true
     };
 
-    TargetFactory.forRemoteTab(options).then(Task.async(testTarget).bind(null, client));
+    TargetFactory.forRemoteTab(options).then(testTarget.bind(null, client));
   });
 }
 
 function close(target, client) {
   target.on("close", () => {
     ok(true, "Target was closed");
     finish();
   });
--- a/devtools/client/framework/test/browser_toolbox_tool_ready.js
+++ b/devtools/client/framework/test/browser_toolbox_tool_ready.js
@@ -26,19 +26,19 @@ function performChecks(target) {
       ok(panel.isReady, toolId + " panel should be ready");
     }
 
     await toolbox.destroy();
   })();
 }
 
 function test() {
-  Task.spawn(async function() {
+  (async function() {
     toggleAllTools(true);
     let tab = await addTab("about:blank");
     let target = TargetFactory.forTab(tab);
     await target.makeRemote();
     await performChecks(target);
     gBrowser.removeCurrentTab();
     toggleAllTools(false);
     finish();
-  }, console.error);
+  })();
 }
--- a/devtools/client/framework/test/browser_toolbox_tool_remote_reopen.js
+++ b/devtools/client/framework/test/browser_toolbox_tool_remote_reopen.js
@@ -83,17 +83,17 @@ function getTarget(client) {
     });
     deferred.resolve(target);
   });
 
   return deferred.promise;
 }
 
 function test() {
-  Task.spawn(async function() {
+  (async function() {
     toggleAllTools(true);
     await addTab("about:blank");
 
     let client = await getClient();
     let target = await getTarget(client);
     await runTools(target);
 
     // Actor fronts should be destroyed now that the toolbox has closed, but
@@ -117,10 +117,10 @@ function test() {
         ok(false, "Front for " + actor + " still held in pool!");
       }
     }
 
     gBrowser.removeCurrentTab();
     DebuggerServer.destroy();
     toggleAllTools(false);
     finish();
-  }, console.error);
+  })();
 }
--- a/devtools/client/inspector/markup/test/browser_markup_toggle_03.js
+++ b/devtools/client/inspector/markup/test/browser_markup_toggle_03.js
@@ -4,50 +4,50 @@
 
 "use strict";
 
 // Test toggling (expand/collapse) elements by alt-clicking on twisties, which
 // should expand/collapse all the descendants
 
 const TEST_URL = URL_ROOT + "doc_markup_toggle.html";
 
-add_task(function* () {
-  let {inspector} = yield openInspectorForURL(TEST_URL);
+add_task(async function() {
+  let {inspector} = await openInspectorForURL(TEST_URL);
 
   info("Getting the container for the UL parent element");
-  let container = yield getContainerForSelector("ul", inspector);
+  let container = await getContainerForSelector("ul", inspector);
 
   info("Alt-clicking on collapsed expander should expand all children");
   let onUpdated = inspector.once("inspector-updated");
   EventUtils.synthesizeMouseAtCenter(container.expander, {altKey: true},
     inspector.markup.doc.defaultView);
-  yield onUpdated;
-  yield waitForMultipleChildrenUpdates(inspector);
+  await onUpdated;
+  await waitForMultipleChildrenUpdates(inspector);
 
   info("Checking that all nodes exist and are expanded");
-  let nodeFronts = yield getNodeFronts(inspector);
+  let nodeFronts = await getNodeFronts(inspector);
   for (let nodeFront of nodeFronts) {
     let nodeContainer = getContainerForNodeFront(nodeFront, inspector);
     ok(nodeContainer, "Container for node " + nodeFront.tagName + " exists");
     ok(nodeContainer.expanded,
       "Container for node " + nodeFront.tagName + " is expanded");
   }
 
   info("Alt-clicking on expanded expander should collapse all children");
   EventUtils.synthesizeMouseAtCenter(container.expander, {altKey: true},
     inspector.markup.doc.defaultView);
-  yield waitForMultipleChildrenUpdates(inspector);
+  await waitForMultipleChildrenUpdates(inspector);
   // No need to wait for inspector-updated here since we are not retrieving new nodes.
 
   info("Checking that all nodes are collapsed");
-  nodeFronts = yield getNodeFronts(inspector);
+  nodeFronts = await getNodeFronts(inspector);
   for (let nodeFront of nodeFronts) {
     let nodeContainer = getContainerForNodeFront(nodeFront, inspector);
     ok(!nodeContainer.expanded,
       "Container for node " + nodeFront.tagName + " is collapsed");
   }
 });
 
-function* getNodeFronts(inspector) {
-  let nodeList = yield inspector.walker.querySelectorAll(
+async function getNodeFronts(inspector) {
+  let nodeList = await inspector.walker.querySelectorAll(
     inspector.walker.rootNode, "ul, li, span, em");
   return nodeList.items();
 }
--- a/devtools/client/performance/docs/markers.md
+++ b/devtools/client/performance/docs/markers.md
@@ -17,17 +17,17 @@ Additionally, markers may be created fro
 common type of marker is probably going to be from a GeckoProcessType_Content's
 main thread when debugging content.
 
 ## DOMEvent
 
 Triggered when a DOM event occurs, like a click or a keypress.
 
 * unsigned short eventPhase - a number indicating what phase this event is
-  in (target, bubbling, capturing, maps to Ci.nsIDOMEvent constants)
+  in (target, bubbling, capturing, maps to Event constants)
 * DOMString type - the type of event, like "keypress" or "click"
 
 ## Reflow
 
 Reflow markers (labeled as "Layout") indicate when a change has occurred to
 a DOM element's positioning that requires the frame tree (rendering
 representation of the DOM) to figure out the new position of a handful of
 elements. Fired via `PresShell::DoReflow`
--- a/devtools/client/performance/modules/marker-formatters.js
+++ b/devtools/client/performance/modules/marker-formatters.js
@@ -2,17 +2,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 /**
  * This file contains utilities for creating elements for markers to be displayed,
  * and parsing out the blueprint to generate correct values for markers.
  */
-const { Ci } = require("chrome");
 const { L10N, PREFS } = require("devtools/client/performance/modules/global");
 
 // String used to fill in platform data when it should be hidden.
 const GECKO_SYMBOL = "(Gecko)";
 
 /**
  * Mapping of JS marker causes to a friendlier form. Only
  * markers that are considered "from content" should be labeled here.
@@ -63,23 +62,23 @@ exports.Formatters = {
 
     if ("type" in marker) {
       fields[L10N.getStr("marker.field.DOMEventType")] = marker.type;
     }
 
     if ("eventPhase" in marker) {
       let label;
       switch (marker.eventPhase) {
-        case Ci.nsIDOMEvent.AT_TARGET:
+        case Event.AT_TARGET:
           label = L10N.getStr("marker.value.DOMEventTargetPhase");
           break;
-        case Ci.nsIDOMEvent.CAPTURING_PHASE:
+        case Event.CAPTURING_PHASE:
           label = L10N.getStr("marker.value.DOMEventCapturingPhase");
           break;
-        case Ci.nsIDOMEvent.BUBBLING_PHASE:
+        case Event.BUBBLING_PHASE:
           label = L10N.getStr("marker.value.DOMEventBubblingPhase");
           break;
       }
       fields[L10N.getStr("marker.field.DOMEventPhase")] = label;
     }
 
     return fields;
   },
--- a/devtools/client/performance/test/unit/test_marker-utils.js
+++ b/devtools/client/performance/test/unit/test_marker-utils.js
@@ -39,17 +39,17 @@ add_task(function() {
   equal(fields.length, 1,
         "getMarkerFields() ignores fields that are not found on marker");
   equal(fields[0].label, "Event Type:",
         "getMarkerFields() returns an array with proper label");
   equal(fields[0].value, "mouseclick",
         "getMarkerFields() returns an array with proper value");
 
   fields = MarkerBlueprintUtils.getMarkerFields(
-    { name: "DOMEvent", eventPhase: Ci.nsIDOMEvent.AT_TARGET, type: "mouseclick" });
+    { name: "DOMEvent", eventPhase: Event.AT_TARGET, type: "mouseclick" });
   equal(fields.length, 2,
         "getMarkerFields() returns multiple fields when using a fields function");
   equal(fields[0].label, "Event Type:",
         "getMarkerFields() correctly returns fields via function (1)");
   equal(fields[0].value, "mouseclick",
         "getMarkerFields() correctly returns fields via function (2)");
   equal(fields[1].label, "Phase:",
         "getMarkerFields() correctly returns fields via function (3)");
--- a/devtools/client/scratchpad/scratchpad.js
+++ b/devtools/client/scratchpad/scratchpad.js
@@ -1586,17 +1586,17 @@ var Scratchpad = {
     statusBarField.textContent = this.strings.formatStringFromName(
       "scratchpad.statusBarLineCol", [ line + 1, ch + 1], 2);
   },
 
   /**
    * The Scratchpad window load event handler. This method
    * initializes the Scratchpad window and source editor.
    *
-   * @param nsIDOMEvent aEvent
+   * @param Event aEvent
    */
   onLoad: function SP_onLoad(aEvent) {
     if (aEvent.target != document) {
       return;
     }
 
     let chrome = Services.prefs.getBoolPref(DEVTOOLS_CHROME_ENABLED);
     if (chrome) {
@@ -1723,17 +1723,17 @@ var Scratchpad = {
   redo: function SP_redo() {
     this.editor.redo();
   },
 
   /**
    * The Scratchpad window unload event handler. This method unloads/destroys
    * the source editor.
    *
-   * @param nsIDOMEvent aEvent
+   * @param Event aEvent
    */
   onUnload: function SP_onUnload(aEvent) {
     if (aEvent.target != document) {
       return;
     }
 
     // This event is created only after user uses 'reload and run' feature.
     if (this._reloadAndRunEvent && this.gBrowser) {
@@ -1817,17 +1817,17 @@ var Scratchpad = {
     }
     return true;
   },
 
   /**
    * Handler for window close event. Prompts to save scratchpad if
    * there are unsaved changes.
    *
-   * @param nsIDOMEvent aEvent
+   * @param Event aEvent
    * @param function aCallback
    *        Optional function you want to call when file is saved/closed.
    *        Used mainly for tests.
    */
   onClose: function SP_onClose(aEvent, aCallback) {
     aEvent.preventDefault();
     this.close(aCallback);
   },
--- a/devtools/client/scratchpad/test/browser_scratchpad_autocomplete.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_autocomplete.js
@@ -5,17 +5,17 @@
 
 // Test the completions using numbers.
 const source = "0x1.";
 const completions = ["toExponential", "toFixed", "toString"];
 
 function test() {
   const options = { tabContent: "test scratchpad autocomplete" };
   openTabAndScratchpad(options)
-    .then(Task.async(runTests))
+    .then(runTests)
     .then(finish, console.error);
 }
 
 async function runTests([win, sp]) {
   const {editor} = sp;
   const editorWin = editor.container.contentWindow;
 
   // Show the completions popup.
--- a/devtools/client/scratchpad/test/browser_scratchpad_close_toolbox.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_close_toolbox.js
@@ -6,17 +6,17 @@
 
 var {TargetFactory} = require("devtools/client/framework/target");
 
 function test() {
   const options = {
     tabContent: "test closing toolbox and then reusing scratchpad"
   };
   openTabAndScratchpad(options)
-    .then(Task.async(runTests))
+    .then(runTests)
     .then(finish, console.error);
 }
 
 async function runTests([win, sp]) {
   // Use the scratchpad before opening the toolbox.
   const source = "window.foobar = 7;";
   sp.setText(source);
   let [,, result] = await sp.display();
--- a/devtools/client/scratchpad/test/browser_scratchpad_disable_view_menu_items.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_disable_view_menu_items.js
@@ -4,17 +4,17 @@
 // Test if the view menu items "Larger Font" and "Smaller Font" are disabled
 // when the font size reaches the maximum/minimum values.
 
 function test() {
   const options = {
     tabContent: 'test if view menu items "Larger Font" and "Smaller Font" are enabled/disabled.'
   };
   openTabAndScratchpad(options)
-    .then(Task.async(runTests))
+    .then(runTests)
     .then(finish, console.error);
 }
 
 async function runTests([win, sp]) {
   await testMaximumFontSize(win, sp);
 
   await testMinimumFontSize(win, sp);
 }
--- a/devtools/client/scratchpad/test/browser_scratchpad_inspect_primitives.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_inspect_primitives.js
@@ -4,17 +4,17 @@
 // Test that inspecting primitive values uses the object inspector, not an
 // inline comment.
 
 function test() {
   const options = {
     tabContent: "test inspecting primitive values"
   };
   openTabAndScratchpad(options)
-    .then(Task.async(runTests))
+    .then(runTests)
     .then(finish, console.error);
 }
 
 async function runTests([win, sp]) {
   // Inspect a number.
   await checkResults(sp, 7);
 
   // Inspect a string.
--- a/devtools/client/shared/components/test/mochitest/test_searchbox-with-autocomplete.html
+++ b/devtools/client/shared/components/test/mochitest/test_searchbox-with-autocomplete.html
@@ -5,17 +5,17 @@
 <html>
 <!--
 Test the searchbox and autocomplete-popup components
 -->
 <head>
   <meta charset="utf-8">
   <title>SearchBox component test</title>
   <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
+  <script src="chrome://mochikit/content/tests/SimpleTest/AddTask.js"></script>
   <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
 </head>
 <body>
 <script src="head.js"></script>
 <script>
 /* import-globals-from head.js */
 "use strict";
--- a/devtools/client/shared/components/test/mochitest/test_searchbox.html
+++ b/devtools/client/shared/components/test/mochitest/test_searchbox.html
@@ -5,17 +5,17 @@
 <html>
 <!--
 Test the searchbox component
 -->
 <head>
   <meta charset="utf-8">
   <title>SearchBox component test</title>
   <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
+  <script src="chrome://mochikit/content/tests/SimpleTest/AddTask.js"></script>
   <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
 </head>
 <body>
 <script src="head.js"></script>
 <script>
 /* import-globals-from head.js */
 "use strict";
--- a/devtools/client/shared/components/test/mochitest/test_stack-trace-source-maps.html
+++ b/devtools/client/shared/components/test/mochitest/test_stack-trace-source-maps.html
@@ -5,17 +5,17 @@
 <html>
 <!--
 Test the rendering of a stack trace with source maps
 -->
 <head>
   <meta charset="utf-8">
   <title>StackTrace component test</title>
   <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
+  <script src="chrome://mochikit/content/tests/SimpleTest/AddTask.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
 </head>
 <body>
 <script src="head.js"></script>
 <script>
 /* import-globals-from head.js */
 "use strict";
 
--- a/devtools/client/shared/components/test/mochitest/test_stack-trace.html
+++ b/devtools/client/shared/components/test/mochitest/test_stack-trace.html
@@ -5,17 +5,17 @@
 <html>
 <!--
 Test the rendering of a stack trace
 -->
 <head>
   <meta charset="utf-8">
   <title>StackTrace component test</title>
   <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
+  <script src="chrome://mochikit/content/tests/SimpleTest/AddTask.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
 </head>
 <body>
 <script src="head.js"></script>
 <script>
 /* import-globals-from head.js */
 "use strict";
 
--- a/devtools/client/shared/developer-toolbar.js
+++ b/devtools/client/shared/developer-toolbar.js
@@ -700,17 +700,17 @@ DeveloperToolbar.prototype._onPageError 
   this._updateErrorsCount(tabId);
 };
 
 /**
  * The |beforeunload| event handler. This function resets the errors count when
  * a different page starts loading.
  *
  * @private
- * @param nsIDOMEvent ev the beforeunload DOM event.
+ * @param Event ev the beforeunload DOM event.
  */
 DeveloperToolbar.prototype._onPageBeforeUnload = function(ev) {
   let window = ev.target.defaultView;
   if (window.top !== window) {
     return;
   }
 
   let tabs = this._chromeWindow.gBrowser.tabs;
--- a/devtools/client/webconsole/components/JSTerm.js
+++ b/devtools/client/webconsole/components/JSTerm.js
@@ -614,17 +614,17 @@ class JSTerm extends Component {
     }
   }
 
   /* eslint-disable complexity */
   /**
    * The inputNode "keypress" event handler.
    *
    * @private
-   * @param nsIDOMEvent event
+   * @param Event event
    */
   _keyPress(event) {
     let inputNode = this.inputNode;
     let inputValue = this.getInputValue();
     let inputUpdated = false;
 
     if (event.ctrlKey) {
       switch (event.charCode) {
--- a/devtools/server/actors/object/previewers.js
+++ b/devtools/server/actors/object/previewers.js
@@ -641,17 +641,17 @@ previewers.Object = [
                obj.class == "Comment") {
       preview.textContent = hooks.createValueGrip(rawObj.textContent);
     }
 
     return true;
   },
 
   function DOMEvent({obj, hooks}, grip, rawObj) {
-    if (isWorker || !rawObj || !(rawObj instanceof Ci.nsIDOMEvent)) {
+    if (isWorker || !rawObj || !Event.isInstance(rawObj)) {
       return false;
     }
 
     let preview = grip.preview = {
       kind: "DOMEvent",
       type: rawObj.type,
       properties: Object.create(null),
     };
--- a/devtools/server/socket/tests/test_websocket-server.html
+++ b/devtools/server/socket/tests/test_websocket-server.html
@@ -1,15 +1,15 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <meta charset="utf-8">
   <title>Mozilla Bug</title>
   <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
+  <script src="chrome://mochikit/content/tests/SimpleTest/AddTask.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
 </head>
 <body>
 <script>
 "use strict";
 
 window.onload = function() {
   const CC = Components.Constructor;
--- a/devtools/server/tests/mochitest/test_webextension-addon-debugging-connect.html
+++ b/devtools/server/tests/mochitest/test_webextension-addon-debugging-connect.html
@@ -2,17 +2,17 @@
 <html>
 <!--
 Bug 1302702 - Test connect to a webextension addon
 -->
 <head>
   <meta charset="utf-8">
   <title>Mozilla Bug</title>
   <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
+  <script src="chrome://mochikit/content/tests/SimpleTest/AddTask.js"></script>
   <script src="chrome://mochikit/content/tests/SimpleTest/ExtensionTestUtils.js"></script>
   <script src="webextension-helpers.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
 </head>
 <body>
 <pre id="test">
 <script type="application/javascript">
 "use strict";
--- a/devtools/server/tests/mochitest/test_webextension-addon-debugging-reload.html
+++ b/devtools/server/tests/mochitest/test_webextension-addon-debugging-reload.html
@@ -2,17 +2,17 @@
 <html>
 <!--
 Bug 1302702 - Test connect to a webextension addon
 -->
 <head>
   <meta charset="utf-8">
   <title>Mozilla Bug</title>
   <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
+  <script src="chrome://mochikit/content/tests/SimpleTest/AddTask.js"></script>
   <script src="webextension-helpers.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
 </head>
 <body>
 <pre id="test">
 <script type="application/javascript">
 "use strict";
 
--- a/devtools/shared/builtin-modules.js
+++ b/devtools/shared/builtin-modules.js
@@ -27,31 +27,33 @@ const {
 // Create a single Sandbox to access global properties needed in this module.
 // Sandbox are memory expensive, so we should create as little as possible.
 const {
   atob,
   btoa,
   ChromeUtils,
   CSS,
   CSSRule,
+  Event,
   FileReader,
   FormData,
   indexedDB,
   InspectorUtils,
   TextDecoder,
   TextEncoder,
   URL,
   XMLHttpRequest,
 } = Cu.Sandbox(CC("@mozilla.org/systemprincipal;1", "nsIPrincipal")(), {
   wantGlobalProperties: [
     "atob",
     "btoa",
     "ChromeUtils",
     "CSS",
     "CSSRule",
+    "Event",
     "FileReader",
     "FormData",
     "indexedDB",
     "TextDecoder",
     "TextEncoder",
     "InspectorUtils",
     "URL",
     "XMLHttpRequest",
@@ -258,16 +260,17 @@ exports.globals = {
   //   });
   //
   // Bug 1248830 will work out a better plan here for our content module
   // loading needs, especially as we head towards devtools.html.
   define(factory) {
     factory(this.require, this.exports, this.module);
   },
   Element: Ci.nsIDOMElement,
+  Event,
   FormData,
   isWorker: false,
   loader: {
     lazyGetter: defineLazyGetter,
     lazyImporter: defineLazyModuleGetter,
     lazyServiceGetter: defineLazyServiceGetter,
     lazyRequireGetter: lazyRequireGetter,
     // Defined by Loader.jsm
--- a/devtools/shared/security/tests/chrome/test_websocket-transport.html
+++ b/devtools/shared/security/tests/chrome/test_websocket-transport.html
@@ -1,15 +1,15 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <meta charset="utf-8">
   <title>Test the WebSocket debugger transport</title>
   <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
+  <script src="chrome://mochikit/content/tests/SimpleTest/AddTask.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
 </head>
 <body>
 <script>
 "use strict";
 
 window.onload = function() {
   const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1380,31 +1380,30 @@ nsDocShell::GetContentViewer(nsIContentV
   NS_ENSURE_ARG_POINTER(aContentViewer);
 
   *aContentViewer = mContentViewer;
   NS_IF_ADDREF(*aContentViewer);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDocShell::SetChromeEventHandler(nsIDOMEventTarget* aChromeEventHandler)
+nsDocShell::SetChromeEventHandler(EventTarget* aChromeEventHandler)
 {
   // Weak reference. Don't addref.
-  nsCOMPtr<EventTarget> handler = do_QueryInterface(aChromeEventHandler);
-  mChromeEventHandler = handler.get();
+  mChromeEventHandler = aChromeEventHandler;
 
   if (mScriptGlobal) {
     mScriptGlobal->SetChromeEventHandler(mChromeEventHandler);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDocShell::GetChromeEventHandler(nsIDOMEventTarget** aChromeEventHandler)
+nsDocShell::GetChromeEventHandler(EventTarget** aChromeEventHandler)
 {
   NS_ENSURE_ARG_POINTER(aChromeEventHandler);
   nsCOMPtr<EventTarget> handler = mChromeEventHandler;
   handler.forget(aChromeEventHandler);
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/docshell/base/nsDocShellTreeOwner.cpp
+++ b/docshell/base/nsDocShellTreeOwner.cpp
@@ -27,17 +27,16 @@
 #include "nsITooltipListener.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMElement.h"
 #include "Link.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/MouseEvent.h"
 #include "mozilla/dom/SVGTitleElement.h"
-#include "nsIDOMEvent.h"
 #include "nsIFormControl.h"
 #include "nsIImageLoadingContent.h"
 #include "nsIWebNavigation.h"
 #include "nsIPresShell.h"
 #include "nsIStringBundle.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowRoot.h"
 #include "nsIDOMWindowCollection.h"
@@ -52,17 +51,17 @@
 #include "imgIContainer.h"
 #include "nsPresContext.h"
 #include "nsViewManager.h"
 #include "nsView.h"
 #include "nsIConstraintValidation.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/dom/DragEvent.h"
-#include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
+#include "mozilla/dom/Event.h" // for Event
 #include "mozilla/dom/File.h" // for input type=file
 #include "mozilla/dom/FileList.h" // for input type=file
 #include "mozilla/TextEvents.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // A helper routine that navigates the tricky path from a |nsWebBrowser| to
@@ -920,20 +919,19 @@ nsDocShellTreeOwner::RemoveChromeListene
     elmP->RemoveEventListenerByType(this, NS_LITERAL_STRING("drop"),
                                     TrustedEventsAtSystemGroupBubble());
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDocShellTreeOwner::HandleEvent(nsIDOMEvent* aEvent)
+nsDocShellTreeOwner::HandleEvent(Event* aEvent)
 {
-  DragEvent* dragEvent =
-    aEvent ? aEvent->InternalDOMEvent()->AsDragEvent() : nullptr;
+  DragEvent* dragEvent = aEvent ? aEvent->AsDragEvent() : nullptr;
   if (NS_WARN_IF(!dragEvent)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   if (dragEvent->DefaultPrevented()) {
     return NS_OK;
   }
 
@@ -1145,17 +1143,17 @@ ChromeTooltipListener::RemoveTooltipList
                                             this, false);
     mTooltipListenerInstalled = false;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-ChromeTooltipListener::HandleEvent(nsIDOMEvent* aEvent)
+ChromeTooltipListener::HandleEvent(Event* aEvent)
 {
   nsAutoString eventType;
   aEvent->GetType(eventType);
 
   if (eventType.EqualsLiteral("mousedown")) {
     return HideTooltip();
   } else if (eventType.EqualsLiteral("keydown")) {
     WidgetKeyboardEvent* keyEvent = aEvent->WidgetEventPtr()->AsKeyboardEvent();
@@ -1174,19 +1172,19 @@ ChromeTooltipListener::HandleEvent(nsIDO
 
   NS_ERROR("Unexpected event type");
   return NS_OK;
 }
 
 // If we're a tooltip, fire off a timer to see if a tooltip should be shown. If
 // the timer fires, we cache the node in |mPossibleTooltipNode|.
 nsresult
-ChromeTooltipListener::MouseMove(nsIDOMEvent* aMouseEvent)
+ChromeTooltipListener::MouseMove(Event* aMouseEvent)
 {
-  MouseEvent* mouseEvent = aMouseEvent->InternalDOMEvent()->AsMouseEvent();
+  MouseEvent* mouseEvent = aMouseEvent->AsMouseEvent();
   if (!mouseEvent) {
     return NS_OK;
   }
 
   // stash the coordinates of the event so that we can still get back to it from
   // within the timer callback. On win32, we'll get a MouseMove event even when
   // a popup goes away -- even when the mouse doesn't change position! To get
   // around this, we make sure the mouse has really moved before proceeding.
@@ -1210,18 +1208,17 @@ ChromeTooltipListener::MouseMove(nsIDOME
 
   if (mTooltipTimer) {
     mTooltipTimer->Cancel();
   }
 
   if (!mShowingTooltip && !mTooltipShownOnce) {
     nsIEventTarget* target = nullptr;
 
-    nsCOMPtr<EventTarget> eventTarget =
-      aMouseEvent->InternalDOMEvent()->GetTarget();
+    nsCOMPtr<EventTarget> eventTarget = aMouseEvent->GetTarget();
     if (eventTarget) {
       mPossibleTooltipNode = do_QueryInterface(eventTarget);
       nsCOMPtr<nsIGlobalObject> global(eventTarget->GetOwnerGlobal());
       if (global) {
         target = global->EventTargetFor(TaskCategory::UI);
       }
     }
 
--- a/docshell/base/nsDocShellTreeOwner.h
+++ b/docshell/base/nsDocShellTreeOwner.h
@@ -26,16 +26,17 @@
 #include "nsIAuthPrompt.h"
 #include "nsITooltipListener.h"
 #include "nsITooltipTextProvider.h"
 #include "nsCTooltipTextProvider.h"
 #include "nsIDroppedLinkHandler.h"
 
 namespace mozilla {
 namespace dom {
+class Event;
 class EventTarget;
 } // namespace dom
 } // namespace mozilla
 
 class nsWebBrowser;
 class ChromeTooltipListener;
 
 // {6D10C180-6888-11d4-952B-0020183BF181}
@@ -136,18 +137,18 @@ class ChromeTooltipListener final : publ
 protected:
   virtual ~ChromeTooltipListener();
 
 public:
   NS_DECL_ISUPPORTS
 
   ChromeTooltipListener(nsWebBrowser* aInBrowser, nsIWebBrowserChrome* aInChrome);
 
-  NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override;
-  NS_IMETHOD MouseMove(nsIDOMEvent* aMouseEvent);
+  NS_DECL_NSIDOMEVENTLISTENER
+  NS_IMETHOD MouseMove(mozilla::dom::Event* aMouseEvent);
 
   // Add/remove the relevant listeners, based on what interfaces the embedding
   // chrome implements.
   NS_IMETHOD AddChromeListeners();
   NS_IMETHOD RemoveChromeListeners();
 
 private:
   // various delays for tooltips
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -34,17 +34,16 @@ class ClientSource;
 [ptr] native nsIPresShell(nsIPresShell);
 [ref] native MaybeURI(mozilla::Maybe<nsCOMPtr<nsIURI>>);
 [ref] native Encoding(const mozilla::Encoding*);
       native UniqueClientSource(mozilla::UniquePtr<mozilla::dom::ClientSource>);
 
 interface nsIURI;
 interface nsIChannel;
 interface nsIContentViewer;
-interface nsIDOMEventTarget;
 interface nsIDocShellLoadInfo;
 interface nsIEditor;
 interface nsIEditingSession;
 interface nsISimpleEnumerator;
 interface nsIInputStream;
 interface nsIRequest;
 interface nsISHEntry;
 interface nsILayoutHistoryState;
@@ -58,16 +57,18 @@ interface nsIReflowObserver;
 interface nsIScrollObserver;
 interface nsITabParent;
 interface nsITabChild;
 interface nsICommandManager;
 interface nsICommandParams;
 interface nsILoadURIDelegate;
 native TabChildRef(already_AddRefed<nsITabChild>);
 
+webidl EventTarget;
+
 [scriptable, builtinclass, uuid(049234fe-da10-478b-bc5d-bc6f9a1ba63d)]
 interface nsIDocShell : nsIDocShellTreeItem
 {
   /**
    * Loads a given URI.  This will give priority to loading the requested URI
    * in the object implementing this interface.  If it can't be loaded here
    * however, the URL dispatcher will go through its normal process of content
    * loading.
@@ -281,17 +282,17 @@ interface nsIDocShell : nsIDocShellTreeI
    * change as the underlying content changes.
    */
   readonly attribute nsIContentViewer contentViewer;
 
   /**
    * This attribute allows chrome to tie in to handle DOM events that may
    * be of interest to chrome.
    */
-  attribute nsIDOMEventTarget chromeEventHandler;
+  attribute EventTarget chromeEventHandler;
 
   /**
    * This allows chrome to set a custom User agent on a specific docshell
    */
   attribute DOMString customUserAgent;
 
   /**
    * Whether CSS error reporting is enabled.
--- a/dom/animation/test/mozilla/file_restyles.html
+++ b/dom/animation/test/mozilla/file_restyles.html
@@ -11,17 +11,17 @@ var info = opener.info.bind(opener);
 var original_finish = opener.SimpleTest.finish;
 var SimpleTest = opener.SimpleTest;
 SimpleTest.finish = function finish() {
   self.close();
   original_finish();
 }
 </script>
 <script src="/tests/SimpleTest/EventUtils.js"></script>
-<script src="/tests/SimpleTest/SpawnTask.js"></script>
+<script src="/tests/SimpleTest/AddTask.js"></script>
 <script src="/tests/SimpleTest/paint_listener.js"></script>
 <script src="../testcommon.js"></script>
 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
 <style>
 @keyframes opacity {
   from { opacity: 1; }
   to { opacity: 0; }
 }
--- a/dom/base/Attr.cpp
+++ b/dom/base/Attr.cpp
@@ -95,17 +95,17 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(Attr)
   return tmp->HasKnownLiveWrapper();
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
 
 // QueryInterface implementation for Attr
 NS_INTERFACE_TABLE_HEAD(Attr)
   NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY
   NS_INTERFACE_TABLE(Attr, nsINode, nsIAttribute, nsIDOMNode,
-                     nsIDOMEventTarget, EventTarget)
+                     EventTarget)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(Attr)
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
                                  new nsNodeSupportsWeakRefTearoff(this))
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(Attr)
 NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE(Attr,
                                                    nsNodeUtils::LastRelease(this))
@@ -257,17 +257,17 @@ Attr::SetTextContentInternal(const nsASt
                              ErrorResult& aError)
 {
   SetNodeValueInternal(aTextContent, aError);
 }
 
 bool
 Attr::IsNodeOfType(uint32_t aFlags) const
 {
-    return !(aFlags & ~eATTRIBUTE);
+    return false;
 }
 
 uint32_t
 Attr::GetChildCount() const
 {
   return 0;
 }
 
--- a/dom/base/Attr.h
+++ b/dom/base/Attr.h
@@ -8,16 +8,18 @@
  * Implementation of DOM Core's Attr node.
  */
 
 #ifndef mozilla_dom_Attr_h
 #define mozilla_dom_Attr_h
 
 #include "mozilla/Attributes.h"
 #include "nsIAttribute.h"
+#include "nsIContent.h" // For NS_IMPL_FROMNODE_HELPER, though looks like it
+                        // should live in nsINode.h?
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
 #include "nsString.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsStubMutationObserver.h"
 
 class nsIDocument;
@@ -35,16 +37,18 @@ class Attr final : public nsIAttribute,
 
 public:
   Attr(nsDOMAttributeMap* aAttrMap,
        already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
        const nsAString& aValue);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
+  NS_IMPL_FROMNODE_HELPER(Attr, IsAttr())
+
   // nsINode interface
   virtual void GetTextContentInternal(nsAString& aTextContent,
                                       OOMReporter& aError) override;
   virtual void SetTextContentInternal(const nsAString& aTextContent,
                                       nsIPrincipal* aSubjectPrincipal,
                                       ErrorResult& aError) override;
   virtual void GetNodeValueInternal(nsAString& aNodeValue) override;
   virtual void SetNodeValueInternal(const nsAString& aNodeValue,
--- a/dom/base/CharacterData.cpp
+++ b/dom/base/CharacterData.cpp
@@ -18,17 +18,16 @@
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLSlotElement.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsReadableUtils.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "nsIURI.h"
-#include "nsIDOMEvent.h"
 #include "nsCOMPtr.h"
 #include "nsDOMString.h"
 #include "nsChangeHint.h"
 #include "nsCOMArray.h"
 #include "nsNodeUtils.h"
 #include "mozilla/dom/DirectionalityUtils.h"
 #include "nsBindingManager.h"
 #include "nsCCUncollectableMarker.h"
@@ -658,17 +657,17 @@ nsXBLBinding *
 CharacterData::DoGetXBLBinding() const
 {
   return nullptr;
 }
 
 bool
 CharacterData::IsNodeOfType(uint32_t aFlags) const
 {
-  return !(aFlags & ~eDATA_NODE);
+  return false;
 }
 
 void
 CharacterData::SaveSubtreeState()
 {
 }
 
 #ifdef DEBUG
--- a/dom/base/Comment.cpp
+++ b/dom/base/Comment.cpp
@@ -20,22 +20,16 @@ namespace mozilla {
 namespace dom {
 
 Comment::~Comment()
 {
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(Comment, CharacterData, nsIDOMNode)
 
-bool
-Comment::IsNodeOfType(uint32_t aFlags) const
-{
-  return !(aFlags & ~(eCOMMENT | eDATA_NODE));
-}
-
 already_AddRefed<CharacterData>
 Comment::CloneDataNode(mozilla::dom::NodeInfo *aNodeInfo, bool aCloneText) const
 {
   RefPtr<mozilla::dom::NodeInfo> ni = aNodeInfo;
   RefPtr<Comment> it = new Comment(ni.forget());
   if (aCloneText) {
     it->mText = mText;
   }
--- a/dom/base/Comment.h
+++ b/dom/base/Comment.h
@@ -34,22 +34,21 @@ public:
   }
 
   explicit Comment(nsNodeInfoManager* aNodeInfoManager)
     : CharacterData(aNodeInfoManager->GetCommentNodeInfo())
   {
     Init();
   }
 
+  NS_IMPL_FROMNODE_HELPER(Comment, IsComment())
+
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsINode
-  virtual bool IsNodeOfType(uint32_t aFlags) const override;
-
   virtual already_AddRefed<CharacterData>
     CloneDataNode(mozilla::dom::NodeInfo *aNodeInfo,
                   bool aCloneText) const override;
 
   virtual nsIDOMNode* AsDOMNode() override { return this; }
 #ifdef DEBUG
   virtual void List(FILE* out, int32_t aIndent) const override;
   virtual void DumpContent(FILE* out = stdout, int32_t aIndent = 0,
--- a/dom/base/DocumentFragment.cpp
+++ b/dom/base/DocumentFragment.cpp
@@ -28,17 +28,17 @@ JSObject*
 DocumentFragment::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return DocumentFragmentBinding::Wrap(aCx, this, aGivenProto);
 }
 
 bool
 DocumentFragment::IsNodeOfType(uint32_t aFlags) const
 {
-  return !(aFlags & ~eDOCUMENT_FRAGMENT);
+  return false;
 }
 
 #ifdef DEBUG
 void
 DocumentFragment::List(FILE* out, int32_t aIndent) const
 {
   int32_t indent;
   for (indent = aIndent; --indent >= 0; ) {
@@ -115,17 +115,16 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(Docum
 
 // QueryInterface implementation for DocumentFragment
 NS_INTERFACE_MAP_BEGIN(DocumentFragment)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(DocumentFragment)
   NS_INTERFACE_MAP_ENTRY(nsIContent)
   NS_INTERFACE_MAP_ENTRY(nsINode)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
   NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
                                  new nsNodeSupportsWeakRefTearoff(this))
   // DOM bindings depend on the identity pointer being the
   // same as nsINode (which nsIContent inherits).
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContent)
 NS_INTERFACE_MAP_END
 
--- a/dom/base/DocumentFragment.h
+++ b/dom/base/DocumentFragment.h
@@ -105,10 +105,23 @@ protected:
   nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
                  bool aPreallocateChildren) const override;
   RefPtr<Element> mHost;
 };
 
 } // namespace dom
 } // namespace mozilla
 
+inline mozilla::dom::DocumentFragment*
+nsINode::AsDocumentFragment()
+{
+  MOZ_ASSERT(IsDocumentFragment());
+  return static_cast<mozilla::dom::DocumentFragment*>(this);
+}
+
+inline const mozilla::dom::DocumentFragment*
+nsINode::AsDocumentFragment() const
+{
+  MOZ_ASSERT(IsDocumentFragment());
+  return static_cast<const mozilla::dom::DocumentFragment*>(this);
+}
 
 #endif // mozilla_dom_DocumentFragment_h__
--- a/dom/base/DocumentType.cpp
+++ b/dom/base/DocumentType.cpp
@@ -52,31 +52,26 @@ DocumentType::DocumentType(already_AddRe
                            const nsAString& aInternalSubset) :
   CharacterData(aNodeInfo),
   mPublicId(aPublicId),
   mSystemId(aSystemId),
   mInternalSubset(aInternalSubset)
 {
   MOZ_ASSERT(mNodeInfo->NodeType() == DOCUMENT_TYPE_NODE,
              "Bad NodeType in aNodeInfo");
+  MOZ_ASSERT(!IsCharacterData());
 }
 
-DocumentType::~DocumentType()
-{
-}
+DocumentType::~DocumentType() = default;
 
 NS_IMPL_ISUPPORTS_INHERITED(DocumentType, CharacterData, nsIDOMNode)
 
 bool
 DocumentType::IsNodeOfType(uint32_t aFlags) const
 {
-  // Don't claim to be eDATA_NODE since we're just inheriting
-  // CharacterData for convenience. Doctypes aren't really
-  // data nodes (they have a null .nodeValue and don't implement
-  // the DOM CharacterData interface)
   return false;
 }
 
 const nsTextFragment*
 DocumentType::GetText()
 {
   return nullptr;
 }
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -36,17 +36,16 @@
 #include "nsIURL.h"
 #include "nsContainerFrame.h"
 #include "nsIAnonymousContentCreator.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsStyleConsts.h"
 #include "nsString.h"
 #include "nsUnicharUtils.h"
-#include "nsIDOMEvent.h"
 #include "nsDOMCID.h"
 #include "nsIServiceManager.h"
 #include "nsDOMCSSAttrDeclaration.h"
 #include "nsNameSpaceManager.h"
 #include "nsContentList.h"
 #include "nsVariant.h"
 #include "nsDOMTokenList.h"
 #include "nsXBLPrototypeBinding.h"
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -2030,16 +2030,21 @@ inline mozilla::dom::Element* nsINode::A
 }
 
 inline const mozilla::dom::Element* nsINode::AsElement() const
 {
   MOZ_ASSERT(IsElement());
   return static_cast<const mozilla::dom::Element*>(this);
 }
 
+inline mozilla::dom::Element* nsINode::GetParentElement() const
+{
+  return mParent && mParent->IsElement() ? mParent->AsElement() : nullptr;
+}
+
 /**
  * Macros to implement Clone(). _elementName is the class for which to implement
  * Clone.
  */
 #define NS_IMPL_ELEMENT_CLONE(_elementName)                                 \
 nsresult                                                                    \
 _elementName::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,   \
                     bool aPreallocateChildren) const                        \
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -43,17 +43,16 @@
 #include "nsNetUtil.h"
 #include "nsIFrame.h"
 #include "nsIAnonymousContentCreator.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsStyleConsts.h"
 #include "nsString.h"
 #include "nsUnicharUtils.h"
-#include "nsIDOMEvent.h"
 #include "nsDOMCID.h"
 #include "nsIServiceManager.h"
 #include "nsDOMCSSAttrDeclaration.h"
 #include "nsNameSpaceManager.h"
 #include "nsContentList.h"
 #include "nsDOMTokenList.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsError.h"
@@ -145,17 +144,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN(nsIContent)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   // Don't bother to QI to cycle collection, because our CC impl is
   // not doing anything anyway.
   NS_INTERFACE_MAP_ENTRY(nsIContent)
   NS_INTERFACE_MAP_ENTRY(nsINode)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
   NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
                                  new nsNodeSupportsWeakRefTearoff(this))
   // DOM bindings depend on the identity pointer being the
   // same as nsINode (which nsIContent inherits).
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -47,17 +47,17 @@
 #include "mozilla/dom/VRDisplay.h"
 #include "mozilla/dom/VRDisplayEvent.h"
 #include "mozilla/dom/VRServiceTest.h"
 #include "mozilla/dom/workerinternals/RuntimeService.h"
 #include "mozilla/Hal.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/StaticPtr.h"
 #include "Connection.h"
-#include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
+#include "mozilla/dom/Event.h" // for Event
 #include "nsGlobalWindow.h"
 #include "nsIIdleObserver.h"
 #include "nsIPermissionManager.h"
 #include "nsMimeTypes.h"
 #include "nsNetUtil.h"
 #include "nsRFPService.h"
 #include "nsStringStream.h"
 #include "nsComponentManagerUtils.h"
@@ -697,20 +697,20 @@ StaticRefPtr<VibrateWindowListener> gVib
 
 static bool
 MayVibrate(nsIDocument* doc) {
   // Hidden documents cannot start or stop a vibration.
   return (doc && !doc->Hidden());
 }
 
 NS_IMETHODIMP
-VibrateWindowListener::HandleEvent(nsIDOMEvent* aEvent)
+VibrateWindowListener::HandleEvent(Event* aEvent)
 {
   nsCOMPtr<nsIDocument> doc =
-    do_QueryInterface(aEvent->InternalDOMEvent()->GetTarget());
+    do_QueryInterface(aEvent->GetTarget());
 
   if (!MayVibrate(doc)) {
     // It's important that we call CancelVibrate(), not Vibrate() with an
     // empty list, because Vibrate() will fail if we're no longer focused, but
     // CancelVibrate() will succeed, so long as nobody else has started a new
     // vibration pattern.
     nsCOMPtr<nsPIDOMWindowInner> window = do_QueryReferent(mWindow);
     hal::CancelVibrate(window);
--- a/dom/base/ScreenOrientation.cpp
+++ b/dom/base/ScreenOrientation.cpp
@@ -11,16 +11,17 @@
 #include "nsGlobalWindow.h"
 #include "nsSandboxFlags.h"
 #include "nsScreen.h"
 
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/Hal.h"
 #include "mozilla/Preferences.h"
 
+#include "mozilla/dom/Event.h"
 #include "mozilla/dom/Promise.h"
 #include "nsContentUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(ScreenOrientation,
                                    DOMEventTargetHelper,
@@ -594,21 +595,21 @@ ScreenOrientation::ShouldResistFingerpri
     resist = nsContentUtils::ShouldResistFingerprinting(owner->GetDocShell());
   }
   return resist;
 }
 
 NS_IMPL_ISUPPORTS(ScreenOrientation::VisibleEventListener, nsIDOMEventListener)
 
 NS_IMETHODIMP
-ScreenOrientation::VisibleEventListener::HandleEvent(nsIDOMEvent* aEvent)
+ScreenOrientation::VisibleEventListener::HandleEvent(Event* aEvent)
 {
   // Document may have become visible, if the page is visible, run the steps
   // following the "now visible algorithm" as specified.
-  nsCOMPtr<EventTarget> target = aEvent->InternalDOMEvent()->GetCurrentTarget();
+  nsCOMPtr<EventTarget> target = aEvent->GetCurrentTarget();
   MOZ_ASSERT(target);
 
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(target);
   if (!doc || doc->Hidden()) {
     return NS_OK;
   }
 
   auto* win = nsGlobalWindowInner::Cast(doc->GetInnerWindow());
@@ -650,26 +651,26 @@ ScreenOrientation::VisibleEventListener:
   }
 
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS(ScreenOrientation::FullScreenEventListener, nsIDOMEventListener)
 
 NS_IMETHODIMP
-ScreenOrientation::FullScreenEventListener::HandleEvent(nsIDOMEvent* aEvent)
+ScreenOrientation::FullScreenEventListener::HandleEvent(Event* aEvent)
 {
 #ifdef DEBUG
   nsAutoString eventType;
   aEvent->GetType(eventType);
 
   MOZ_ASSERT(eventType.EqualsLiteral("fullscreenchange"));
 #endif
 
-  nsCOMPtr<EventTarget> target = aEvent->InternalDOMEvent()->GetCurrentTarget();
+  nsCOMPtr<EventTarget> target = aEvent->GetCurrentTarget();
   MOZ_ASSERT(target);
 
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(target);
   MOZ_ASSERT(doc);
 
   // We have to make sure that the event we got is the event sent when
   // fullscreen is disabled because we could get one when fullscreen
   // got enabled if the lock call is done at the same moment.
--- a/dom/base/Selection.cpp
+++ b/dom/base/Selection.cpp
@@ -3210,17 +3210,17 @@ Selection::ContainsNode(nsINode& aNode, 
 {
   nsresult rv;
   if (mRanges.Length() == 0) {
     return false;
   }
 
   // XXXbz this duplicates the GetNodeLength code in nsRange.cpp
   uint32_t nodeLength;
-  bool isData = aNode.IsNodeOfType(nsINode::eDATA_NODE);
+  bool isData = aNode.IsCharacterData();
   if (isData) {
     nodeLength = aNode.AsText()->TextLength();
   } else {
     nodeLength = aNode.GetChildCount();
   }
 
   nsTArray<nsRange*> overlappingRanges;
   rv = GetRangesForIntervalArray(&aNode, 0, &aNode, nodeLength,
--- a/dom/base/TextInputProcessor.cpp
+++ b/dom/base/TextInputProcessor.cpp
@@ -13,16 +13,17 @@
 #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 mozilla::dom::Event;
 using mozilla::dom::KeyboardEvent;
 using namespace mozilla::widget;
 
 namespace mozilla {
 
 /******************************************************************************
  * TextInputProcessorNotification
  ******************************************************************************/
@@ -598,28 +599,28 @@ TextInputProcessor::PrepareKeyboardEvent
   if (NS_WARN_IF(!IsValidEventTypeForComposition(*aKeyboardEvent))) {
     return NS_ERROR_INVALID_ARG;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TextInputProcessor::StartComposition(nsIDOMEvent* aDOMKeyEvent,
+TextInputProcessor::StartComposition(Event* 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();
+    keyEvent = aDOMKeyEvent->AsKeyboardEvent();
     if (NS_WARN_IF(!keyEvent)) {
       return NS_ERROR_INVALID_ARG;
     }
   }
 
   RefPtr<TextEventDispatcher> kungFuDeathGrip(mDispatcher);
 
   WidgetKeyboardEvent* keyboardEvent;
@@ -696,17 +697,17 @@ TextInputProcessor::SetCaretInPendingCom
   nsresult rv = IsValidStateForComposition();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return kungFuDeathGrip->SetCaretInPendingComposition(aOffset, 0);
 }
 
 NS_IMETHODIMP
-TextInputProcessor::FlushPendingComposition(nsIDOMEvent* aDOMKeyEvent,
+TextInputProcessor::FlushPendingComposition(Event* 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
@@ -714,17 +715,17 @@ TextInputProcessor::FlushPendingComposit
   AutoPendingCompositionResetter resetter(this);
 
   *aSucceeded = false;
   RefPtr<TextEventDispatcher> kungFuDeathGrip(mDispatcher);
   bool wasComposing = IsComposing();
 
   RefPtr<KeyboardEvent> keyEvent;
   if (aDOMKeyEvent) {
-    keyEvent = aDOMKeyEvent->InternalDOMEvent()->AsKeyboardEvent();
+    keyEvent = aDOMKeyEvent->AsKeyboardEvent();
     if (NS_WARN_IF(!keyEvent)) {
       return NS_ERROR_INVALID_ARG;
     }
   }
 
   WidgetKeyboardEvent* keyboardEvent;
   nsresult rv =
     PrepareKeyboardEventForComposition(keyEvent, aKeyFlags, aOptionalArgc,
@@ -756,25 +757,25 @@ TextInputProcessor::FlushPendingComposit
 
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TextInputProcessor::CommitComposition(nsIDOMEvent* aDOMKeyEvent,
+TextInputProcessor::CommitComposition(Event* aDOMKeyEvent,
                                       uint32_t aKeyFlags,
                                       uint8_t aOptionalArgc)
 {
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   RefPtr<KeyboardEvent> keyEvent;
   if (aDOMKeyEvent) {
-    keyEvent = aDOMKeyEvent->InternalDOMEvent()->AsKeyboardEvent();
+    keyEvent = aDOMKeyEvent->AsKeyboardEvent();
     if (NS_WARN_IF(!keyEvent)) {
       return NS_ERROR_INVALID_ARG;
     }
   }
 
   WidgetKeyboardEvent* keyboardEvent;
   nsresult rv =
     PrepareKeyboardEventForComposition(keyEvent, aKeyFlags, aOptionalArgc,
@@ -783,27 +784,27 @@ TextInputProcessor::CommitComposition(ns
     return rv;
   }
 
   return CommitCompositionInternal(keyboardEvent, aKeyFlags);
 }
 
 NS_IMETHODIMP
 TextInputProcessor::CommitCompositionWith(const nsAString& aCommitString,
-                                          nsIDOMEvent* aDOMKeyEvent,
+                                          Event* 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();
+    keyEvent = aDOMKeyEvent->AsKeyboardEvent();
     if (NS_WARN_IF(!keyEvent)) {
       return NS_ERROR_INVALID_ARG;
     }
   }
 
   WidgetKeyboardEvent* keyboardEvent;
   nsresult rv =
     PrepareKeyboardEventForComposition(keyEvent, aKeyFlags, aOptionalArgc,
@@ -855,25 +856,25 @@ TextInputProcessor::CommitCompositionInt
 
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TextInputProcessor::CancelComposition(nsIDOMEvent* aDOMKeyEvent,
+TextInputProcessor::CancelComposition(Event* aDOMKeyEvent,
                                       uint32_t aKeyFlags,
                                       uint8_t aOptionalArgc)
 {
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   RefPtr<KeyboardEvent> keyEvent;
   if (aDOMKeyEvent) {
-    keyEvent = aDOMKeyEvent->InternalDOMEvent()->AsKeyboardEvent();
+    keyEvent = aDOMKeyEvent->AsKeyboardEvent();
     if (NS_WARN_IF(!keyEvent)) {
       return NS_ERROR_INVALID_ARG;
     }
   }
 
   WidgetKeyboardEvent* keyboardEvent;
   nsresult rv =
     PrepareKeyboardEventForComposition(keyEvent, aKeyFlags, aOptionalArgc,
@@ -1071,31 +1072,31 @@ TextInputProcessor::PrepareKeyboardEvent
   }
 
   aKeyboardEvent.mIsSynthesizedByTIP = (mForTests)? false : true;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TextInputProcessor::Keydown(nsIDOMEvent* aDOMKeyEvent,
+TextInputProcessor::Keydown(Event* 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->InternalDOMEvent()->WidgetEventPtr()->AsKeyboardEvent();
+    aDOMKeyEvent->WidgetEventPtr()->AsKeyboardEvent();
   if (NS_WARN_IF(!originalKeyEvent)) {
     return NS_ERROR_INVALID_ARG;
   }
   return KeydownInternal(*originalKeyEvent, aKeyFlags, true, *aConsumedFlags);
 }
 
 nsresult
 TextInputProcessor::KeydownInternal(const WidgetKeyboardEvent& aKeyboardEvent,
@@ -1164,31 +1165,31 @@ TextInputProcessor::KeydownInternal(cons
       (status == nsEventStatus_eConsumeNoDefault) ? KEYPRESS_IS_CONSUMED :
                                                     KEYEVENT_NOT_CONSUMED;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TextInputProcessor::Keyup(nsIDOMEvent* aDOMKeyEvent,
+TextInputProcessor::Keyup(Event* 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->InternalDOMEvent()->WidgetEventPtr()->AsKeyboardEvent();
+    aDOMKeyEvent->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/nsContentAreaDragDrop.cpp
+++ b/dom/base/nsContentAreaDragDrop.cpp
@@ -13,17 +13,16 @@
 #include "nsString.h"
 
 // Interfaces needed to be included
 #include "nsCopySupport.h"
 #include "nsISelection.h"
 #include "nsISelectionController.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
-#include "nsIDOMEvent.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMRange.h"
 #include "nsIFormControl.h"
 #include "nsITransferable.h"
 #include "nsComponentManagerUtils.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsServiceManagerUtils.h"
--- a/dom/base/nsContentIterator.cpp
+++ b/dom/base/nsContentIterator.cpp
@@ -35,17 +35,17 @@ NodeIsInTraversalRange(nsINode* aNode, b
   if (NS_WARN_IF(!aStart.IsSet()) || NS_WARN_IF(!aEnd.IsSet()) ||
       NS_WARN_IF(!aNode)) {
     return false;
   }
 
   // If a leaf node contains an end point of the traversal range, it is
   // always in the traversal range.
   if (aNode == aStart.Container() || aNode == aEnd.Container()) {
-    if (aNode->IsNodeOfType(nsINode::eDATA_NODE)) {
+    if (aNode->IsCharacterData()) {
       return true; // text node or something
     }
     if (!aNode->HasChildren()) {
       MOZ_ASSERT(aNode != aStart.Container() || aStart.IsStartOfContainer(),
         "aStart.Container() doesn't have children and not a data node, "
         "aStart should be at the beginning of its container");
       MOZ_ASSERT(aNode != aEnd.Container() || aEnd.IsStartOfContainer(),
         "aEnd.Container() doesn't have children and not a data node, "
@@ -312,17 +312,17 @@ nsContentIterator::InitInternal(const Ra
 {
   // get common content parent
   mCommonParent =
     nsContentUtils::GetCommonAncestor(aStart.Container(), aEnd.Container());
   if (NS_WARN_IF(!mCommonParent)) {
     return NS_ERROR_FAILURE;
   }
 
-  bool startIsData = aStart.Container()->IsNodeOfType(nsINode::eDATA_NODE);
+  bool startIsData = aStart.Container()->IsCharacterData();
 
   // Check to see if we have a collapsed range, if so, there is nothing to
   // iterate over.
   //
   // XXX: CharacterDataNodes (text nodes) are currently an exception, since
   //      we always want to be able to iterate text nodes at the end points
   //      of a range.
 
@@ -405,17 +405,17 @@ nsContentIterator::InitInternal(const Ra
         mFirst = nullptr;
       }
     }
   }
 
 
   // Find last node in range.
 
-  bool endIsData = aEnd.Container()->IsNodeOfType(nsINode::eDATA_NODE);
+  bool endIsData = aEnd.Container()->IsCharacterData();
 
   if (endIsData || !aEnd.Container()->HasChildren() || aEnd.IsStartOfContainer()) {
     if (mPre) {
       if (NS_WARN_IF(!aEnd.Container()->IsContent())) {
         // Not much else to do here...
         mLast = nullptr;
       } else {
         // If the end node is a non-container element and the end offset is 0,
--- a/dom/base/nsContentList.cpp
+++ b/dom/base/nsContentList.cpp
@@ -988,23 +988,19 @@ nsContentList::AssertInSync()
   if (!mRootNode) {
     NS_ASSERTION(mElements.Length() == 0 && mState == LIST_DIRTY,
                  "Empty iterator isn't quite empty?");
     return;
   }
 
   // XXX This code will need to change if nsContentLists can ever match
   // elements that are outside of the document element.
-  nsIContent *root;
-  if (mRootNode->IsNodeOfType(nsINode::eDOCUMENT)) {
-    root = static_cast<nsIDocument*>(mRootNode)->GetRootElement();
-  }
-  else {
-    root = static_cast<nsIContent*>(mRootNode);
-  }
+  nsIContent* root = mRootNode->IsDocument()
+    ? mRootNode->AsDocument()->GetRootElement()
+    : mRootNode->AsContent();
 
   nsCOMPtr<nsIContentIterator> iter;
   if (mDeep) {
     iter = NS_NewPreContentIterator();
     iter->Init(root);
     iter->First();
   }
 
--- a/dom/base/nsContentPermissionHelper.cpp
+++ b/dom/base/nsContentPermissionHelper.cpp
@@ -23,17 +23,16 @@
 #include "nsComponentManagerUtils.h"
 #include "nsArrayUtils.h"
 #include "nsIMutableArray.h"
 #include "nsContentPermissionHelper.h"
 #include "nsJSUtils.h"
 #include "nsISupportsPrimitives.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIDocument.h"
-#include "nsIDOMEvent.h"
 #include "nsWeakPtr.h"
 
 using mozilla::Unused;          // <snicker>
 using namespace mozilla::dom;
 using namespace mozilla;
 
 #define kVisibilityChange "visibilitychange"
 
@@ -69,26 +68,25 @@ VisibilityChangeListener::VisibilityChan
                                 /* listener */ this,
                                 /* use capture */ true,
                                 /* wants untrusted */ false);
   }
 
 }
 
 NS_IMETHODIMP
-VisibilityChangeListener::HandleEvent(nsIDOMEvent* aEvent)
+VisibilityChangeListener::HandleEvent(Event* aEvent)
 {
   nsAutoString type;
   aEvent->GetType(type);
   if (!type.EqualsLiteral(kVisibilityChange)) {
     return NS_ERROR_FAILURE;
   }
 
-  nsCOMPtr<nsIDocument> doc =
-    do_QueryInterface(aEvent->InternalDOMEvent()->GetTarget());
+  nsCOMPtr<nsIDocument> doc = do_QueryInterface(aEvent->GetTarget());
   MOZ_ASSERT(doc);
 
   if (mCallback) {
     mCallback->NotifyVisibility(!doc->Hidden());
   }
 
   return NS_OK;
 }
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -2205,21 +2205,21 @@ nsContentUtils::IsAbsoluteURL(const nsAC
 
 //static
 bool
 nsContentUtils::InProlog(nsINode *aNode)
 {
   NS_PRECONDITION(aNode, "missing node to nsContentUtils::InProlog");
 
   nsINode* parent = aNode->GetParentNode();
-  if (!parent || !parent->IsNodeOfType(nsINode::eDOCUMENT)) {
+  if (!parent || !parent->IsDocument()) {
     return false;
   }
 
-  nsIDocument* doc = static_cast<nsIDocument*>(parent);
+  nsIDocument* doc = parent->AsDocument();
   nsIContent* root = doc->GetRootElement();
 
   return !root || doc->ComputeIndexOf(aNode) < doc->ComputeIndexOf(root);
 }
 
 nsIDocument*
 nsContentUtils::GetDocumentFromCaller()
 {
@@ -2407,20 +2407,21 @@ nsContentUtils::GetCrossDocParentNode(ns
 {
   NS_PRECONDITION(aChild, "The child is null!");
 
   nsINode* parent = aChild->GetParentNode();
   if (parent && parent->IsContent() && aChild->IsContent()) {
     parent = aChild->AsContent()->GetFlattenedTreeParent();
   }
 
-  if (parent || !aChild->IsNodeOfType(nsINode::eDOCUMENT))
+  if (parent || !aChild->IsDocument()) {
     return parent;
-
-  nsIDocument* doc = static_cast<nsIDocument*>(aChild);
+  }
+
+  nsIDocument* doc = aChild->AsDocument();
   nsIDocument* parentDoc = doc->GetParentDocument();
   return parentDoc ? parentDoc->FindContentForSubDocument(doc) : nullptr;
 }
 
 // static
 bool
 nsContentUtils::ContentIsDescendantOf(const nsINode* aPossibleDescendant,
                                       const nsINode* aPossibleAncestor)
@@ -2442,19 +2443,19 @@ nsContentUtils::ContentIsHostIncludingDe
   const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor)
 {
   NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!");
   NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!");
 
   do {
     if (aPossibleDescendant == aPossibleAncestor)
       return true;
-    if (aPossibleDescendant->NodeType() == nsINode::DOCUMENT_FRAGMENT_NODE) {
+    if (aPossibleDescendant->IsDocumentFragment()) {
       aPossibleDescendant =
-        static_cast<const DocumentFragment*>(aPossibleDescendant)->GetHost();
+        aPossibleDescendant->AsDocumentFragment()->GetHost();
     } else {
       aPossibleDescendant = aPossibleDescendant->GetParentNode();
     }
   } while (aPossibleDescendant);
 
   return false;
 }
 
@@ -4433,18 +4434,17 @@ nsresult GetEventAndTarget(nsIDocument* 
                                           CallerType::System, err);
   if (NS_WARN_IF(err.Failed())) {
     return err.StealNSResult();
   }
 
   event->InitEvent(aEventName, aCanBubble, aCancelable);
   event->SetTrusted(aTrusted);
 
-  nsresult rv = event->SetTarget(target);
-  NS_ENSURE_SUCCESS(rv, rv);
+  event->SetTarget(target);
 
   event.forget(aEvent);
   target.forget(aTargetOut);
   return NS_OK;
 }
 
 // static
 nsresult
@@ -6516,17 +6516,17 @@ bool
 nsContentUtils::CanAccessNativeAnon()
 {
   return LegacyIsCallerChromeOrNativeCode() || IsCallerContentXBL();
 }
 
 /* static */ nsresult
 nsContentUtils::DispatchXULCommand(nsIContent* aTarget,
                                    bool aTrusted,
-                                   nsIDOMEvent* aSourceEvent,
+                                   Event* aSourceEvent,
                                    nsIPresShell* aShell,
                                    bool aCtrl,
                                    bool aAlt,
                                    bool aShift,
                                    bool aMeta,
                                    uint16_t aInputSource)
 {
   NS_ENSURE_STATE(aTarget);
@@ -6534,18 +6534,17 @@ nsContentUtils::DispatchXULCommand(nsICo
   nsPresContext* presContext = doc->GetPresContext();
 
   RefPtr<XULCommandEvent> xulCommand = new XULCommandEvent(doc, presContext,
                                                            nullptr);
   xulCommand->InitCommandEvent(NS_LITERAL_STRING("command"), true, true,
                                nsGlobalWindowInner::Cast(doc->GetInnerWindow()),
                                0, aCtrl, aAlt, aShift,
                                aMeta,
-                               aSourceEvent ?
-                                 aSourceEvent->InternalDOMEvent() : nullptr,
+                               aSourceEvent,
                                aInputSource, IgnoreErrors());
 
   if (aShell) {
     nsEventStatus status = nsEventStatus_eIgnore;
     nsCOMPtr<nsIPresShell> kungFuDeathGrip = aShell;
     return aShell->HandleDOMEventWithTarget(aTarget, xulCommand, &status);
   }
 
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -65,17 +65,16 @@ class nsAtom;
 class nsIChannel;
 class nsIConsoleService;
 class nsIContent;
 class nsIContentPolicy;
 class nsIContentSecurityPolicy;
 class nsIDocShellTreeItem;
 class nsIDocumentLoaderFactory;
 class nsIDOMDocument;
-class nsIDOMEvent;
 class nsIDOMNode;
 class nsIDragSession;
 class nsIEventTarget;
 class nsIFragmentContentSink;
 class nsIFrame;
 class nsIImageLoadingContent;
 class nsIInterfaceRequestor;
 class nsIIOService;
@@ -126,16 +125,17 @@ class ErrorResult;
 class EventListenerManager;
 class HTMLEditor;
 
 namespace dom {
 class ChromeMessageBroadcaster;
 struct CustomElementDefinition;
 class DocumentFragment;
 class Element;
+class Event;
 class EventTarget;
 class HTMLInputElement;
 class IPCDataTransfer;
 class IPCDataTransferItem;
 struct LifecycleCallbackArgs;
 struct LifecycleAdoptedCallbackArgs;
 class NodeInfo;
 class nsIContentChild;
@@ -1351,22 +1351,22 @@ public:
                                    nsIDocument* aOwnerDoc);
 
   /**
    * This method creates and dispatches a trusted event.
    * Works only with events which can be created by calling
    * nsIDOMDocument::CreateEvent() with parameter "Events".
    * @param aDoc           The document which will be used to create the event.
    * @param aTarget        The target of the event, should be QIable to
-   *                       nsIDOMEventTarget.
+   *                       EventTarget.
    * @param aEventName     The name of the event.
    * @param aCanBubble     Whether the event can bubble.
    * @param aCancelable    Is the event cancelable.
    * @param aDefaultAction Set to true if default action should be taken,
-   *                       see nsIDOMEventTarget::DispatchEvent.
+   *                       see EventTarget::DispatchEvent.
    */
   static nsresult DispatchTrustedEvent(nsIDocument* aDoc,
                                        nsISupports* aTarget,
                                        const nsAString& aEventName,
                                        bool aCanBubble,
                                        bool aCancelable,
                                        bool *aDefaultAction = nullptr);
 
@@ -1374,17 +1374,17 @@ public:
    * This method creates and dispatches a trusted event using an event message.
    * @param aDoc           The document which will be used to create the event.
    * @param aTarget        The target of the event, should be QIable to
    *                       EventTarget.
    * @param aEventMessage  The event message.
    * @param aCanBubble     Whether the event can bubble.
    * @param aCancelable    Is the event cancelable.
    * @param aDefaultAction Set to true if default action should be taken,
-   *                       see nsIDOMEventTarget::DispatchEvent.
+   *                       see EventTarget::DispatchEvent.
    */
   template <class WidgetEventType>
   static nsresult DispatchTrustedEvent(nsIDocument* aDoc,
                                        nsISupports* aTarget,
                                        mozilla::EventMessage aEventMessage,
                                        bool aCanBubble,
                                        bool aCancelable,
                                        bool *aDefaultAction = nullptr,
@@ -1398,22 +1398,22 @@ public:
   }
 
   /**
    * This method creates and dispatches a untrusted event.
    * Works only with events which can be created by calling
    * nsIDOMDocument::CreateEvent() with parameter "Events".
    * @param aDoc           The document which will be used to create the event.
    * @param aTarget        The target of the event, should be QIable to
-   *                       nsIDOMEventTarget.
+   *                       EventTarget.
    * @param aEventName     The name of the event.
    * @param aCanBubble     Whether the event can bubble.
    * @param aCancelable    Is the event cancelable.
    * @param aDefaultAction Set to true if default action should be taken,
-   *                       see nsIDOMEventTarget::DispatchEvent.
+   *                       see EventTarget::DispatchEvent.
    */
   static nsresult DispatchUntrustedEvent(nsIDocument* aDoc,
                                          nsISupports* aTarget,
                                          const nsAString& aEventName,
                                          bool aCanBubble,
                                          bool aCancelable,
                                          bool *aDefaultAction = nullptr);
 
@@ -1422,17 +1422,17 @@ public:
    * This method creates and dispatches a untrusted event using an event message.
    * @param aDoc           The document which will be used to create the event.
    * @param aTarget        The target of the event, should be QIable to
    *                       EventTarget.
    * @param aEventMessage  The event message.
    * @param aCanBubble     Whether the event can bubble.
    * @param aCancelable    Is the event cancelable.
    * @param aDefaultAction Set to true if default action should be taken,
-   *                       see nsIDOMEventTarget::DispatchEvent.
+   *                       see EventTarget::DispatchEvent.
    */
   template <class WidgetEventType>
   static nsresult DispatchUntrustedEvent(nsIDocument* aDoc,
                                          nsISupports* aTarget,
                                          mozilla::EventMessage aEventMessage,
                                          bool aCanBubble,
                                          bool aCancelable,
                                          bool *aDefaultAction = nullptr,
@@ -1456,17 +1456,17 @@ public:
    * @param aDocument      The document which will be used to create the event,
    *                       and whose window's chrome handler will be used to
    *                       dispatch the event.
    * @param aTarget        The target of the event, used for event->SetTarget()
    * @param aEventName     The name of the event.
    * @param aCanBubble     Whether the event can bubble.
    * @param aCancelable    Is the event cancelable.
    * @param aDefaultAction Set to true if default action should be taken,
-   *                       see nsIDOMEventTarget::DispatchEvent.
+   *                       see EventTarget::DispatchEvent.
    */
   static nsresult DispatchChromeEvent(nsIDocument* aDoc,
                                       nsISupports* aTarget,
                                       const nsAString& aEventName,
                                       bool aCanBubble,
                                       bool aCancelable,
                                       bool *aDefaultAction = nullptr);
 
@@ -1484,22 +1484,22 @@ public:
    * propagation path will be used as the start of the event target chain.
    * This method is different than DispatchChromeEvent, which always dispatches
    * events to chrome event handler. DispatchEventOnlyToChrome works like
    * DispatchTrustedEvent in the case aTarget is a chrome object.
    * Works only with events which can be created by calling
    * nsIDOMDocument::CreateEvent() with parameter "Events".
    * @param aDoc           The document which will be used to create the event.
    * @param aTarget        The target of the event, should be QIable to
-   *                       nsIDOMEventTarget.
+   *                       EventTarget.
    * @param aEventName     The name of the event.
    * @param aCanBubble     Whether the event can bubble.
    * @param aCancelable    Is the event cancelable.
    * @param aDefaultAction Set to true if default action should be taken,
-   *                       see nsIDOMEventTarget::DispatchEvent.
+   *                       see EventTarget::DispatchEvent.
    */
   static nsresult DispatchEventOnlyToChrome(nsIDocument* aDoc,
                                             nsISupports* aTarget,
                                             const nsAString& aEventName,
                                             bool aCanBubble,
                                             bool aCancelable,
                                             bool *aDefaultAction = nullptr);
 
@@ -2099,17 +2099,17 @@ public:
   /**
    * This method creates and dispatches "command" event, which implements
    * XULCommandEvent.
    * If aShell is not null, dispatching goes via
    * nsIPresShell::HandleDOMEventWithTarget.
    */
   static nsresult DispatchXULCommand(nsIContent* aTarget,
                                      bool aTrusted,
-                                     nsIDOMEvent* aSourceEvent = nullptr,
+                                     mozilla::dom::Event* aSourceEvent = nullptr,
                                      nsIPresShell* aShell = nullptr,
                                      bool aCtrl = false,
                                      bool aAlt = false,
                                      bool aShift = false,
                                      bool aMeta = false,
                                      // Including MouseEventBinding here leads
                                      // to incude loops, unfortunately.
                                      uint16_t inputSource = 0 /* MouseEventBinding::MOZ_SOURCE_UNKNOWN */);
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -5,25 +5,25 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMWindowUtils.h"
 
 #include "mozilla/layers/CompositorBridgeChild.h"
 #include "mozilla/layers/LayerTransactionChild.h"
 #include "nsPresContext.h"
 #include "nsError.h"
-#include "nsIDOMEvent.h"
 #include "nsQueryContentEventResult.h"
 #include "nsGlobalWindow.h"
 #include "nsIDocument.h"
 #include "nsFocusManager.h"
 #include "nsFrameManager.h"
 #include "nsRefreshDriver.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/BlobBinding.h"
+#include "mozilla/dom/Event.h"
 #include "mozilla/dom/Touch.h"
 #include "mozilla/PendingAnimationTracker.h"
 #include "nsIObjectLoadingContent.h"
 #include "nsFrame.h"
 #include "mozilla/layers/ShadowLayers.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "ClientLayerManager.h"
 #include "nsQueryObject.h"
@@ -1846,17 +1846,17 @@ nsDOMWindowUtils::GetFullZoom(float* aFu
 
   *aFullZoom = presContext->DeviceContext()->GetFullZoom();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::DispatchDOMEventViaPresShell(nsIDOMNode* aTarget,
-                                               nsIDOMEvent* aEvent,
+                                               Event* aEvent,
                                                bool aTrusted,
                                                bool* aRetVal)
 {
   NS_ENSURE_STATE(aEvent);
   aEvent->SetTrusted(aTrusted);
   WidgetEvent* internalEvent = aEvent->WidgetEventPtr();
   NS_ENSURE_STATE(internalEvent);
   nsCOMPtr<nsIContent> content = do_QueryInterface(aTarget);
@@ -3646,25 +3646,25 @@ nsDOMWindowUtils::GetPaintFlashing(bool*
   nsPresContext* presContext = GetPresContext();
   if (presContext) {
     *aRetVal = presContext->GetPaintFlashing();
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::DispatchEventToChromeOnly(nsIDOMEventTarget* aTarget,
-                                            nsIDOMEvent* aEvent,
+nsDOMWindowUtils::DispatchEventToChromeOnly(EventTarget* aTarget,
+                                            Event* aEvent,
                                             bool* aRetVal)
 {
   *aRetVal = false;
   NS_ENSURE_STATE(aTarget && aEvent);
   aEvent->WidgetEventPtr()->mFlags.mOnlyChromeDispatch = true;
-  *aRetVal = EventTarget::From(aTarget)->
-    DispatchEvent(*aEvent->InternalDOMEvent(), CallerType::System, IgnoreErrors());
+  *aRetVal = aTarget->
+    DispatchEvent(*aEvent, CallerType::System, IgnoreErrors());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::RequestCompositorProperty(const nsAString& property,
                                             float* aResult)
 {
   if (nsIWidget* widget = GetWidget()) {
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -55,16 +55,17 @@
 #include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/BasicEvents.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/EventStateManager.h"
 
 #include "mozilla/dom/Attr.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/Event.h"
 #include "mozilla/dom/FramingChecker.h"
 #include "mozilla/dom/HTMLSharedElement.h"
 #include "nsGenericHTMLElement.h"
 #include "mozilla/dom/CDATASection.h"
 #include "mozilla/dom/ProcessingInstruction.h"
 #include "nsDOMString.h"
 #include "nsNodeUtils.h"
 #include "nsLayoutUtils.h" // for GetFrameForPoint
@@ -1735,17 +1736,16 @@ NS_INTERFACE_TABLE_HEAD(nsDocument)
   NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY
   NS_INTERFACE_TABLE_BEGIN
     NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(nsDocument, nsISupports, nsINode)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsINode)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDocument)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMDocument)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMNode)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIScriptObjectPrincipal)
-    NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMEventTarget)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, mozilla::dom::EventTarget)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsISupportsWeakReference)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIRadioGroupContainer)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIMutationObserver)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIApplicationCacheContainer)
   NS_INTERFACE_TABLE_END
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsDocument)
 NS_INTERFACE_MAP_END
@@ -4155,17 +4155,17 @@ nsIDocument::FindContentForSubDocument(n
     }
   }
   return nullptr;
 }
 
 bool
 nsIDocument::IsNodeOfType(uint32_t aFlags) const
 {
-  return !(aFlags & ~eDOCUMENT);
+  return false;
 }
 
 Element*
 nsIDocument::GetRootElement() const
 {
   return (mCachedRootElement && mCachedRootElement->GetParentNode() == this) ?
          mCachedRootElement : GetRootElementInternal();
 }
--- a/dom/base/nsDocumentEncoder.cpp
+++ b/dom/base/nsDocumentEncoder.cpp
@@ -538,20 +538,18 @@ nsDocumentEncoder::SerializeToStringIter
       // Check if we have siblings.
       node = current->GetNextSibling();
       if (!node) {
         // Perhaps parent node has siblings.
         current = current->GetParentNode();
 
         // Handle template element. If the parent is a template's content,
         // then adjust the parent to be the template element.
-        if (current && current != aNode &&
-            current->NodeType() == nsINode::DOCUMENT_FRAGMENT_NODE) {
-          DocumentFragment* frag = static_cast<DocumentFragment*>(current);
-          nsIContent* host = frag->GetHost();
+        if (current && current != aNode && current->IsDocumentFragment()) {
+          nsIContent* host = current->AsDocumentFragment()->GetHost();
           if (host && host->IsHTMLElement(nsGkAtoms::_template)) {
             current = host;
           }
         }
       }
     }
   }
 
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -30,17 +30,16 @@
 #include "nsIBrowser.h"
 #include "nsContentUtils.h"
 #include "nsIXPConnect.h"
 #include "nsUnicharUtils.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIScrollable.h"
 #include "nsFrameLoader.h"
-#include "nsIDOMEventTarget.h"
 #include "nsIFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsSubDocumentFrame.h"
 #include "nsError.h"
 #include "nsISHistory.h"
 #include "nsISHistoryInternal.h"
 #include "nsIXULWindow.h"
 #include "nsIMozBrowserFrame.h"
@@ -2049,23 +2048,23 @@ nsFrameLoader::MaybeCreateDocShell()
                            parentDocShell);
 
   if (mIsTopLevelContent) {
     mDocShell->SetCreatedDynamically(false);
   }
 
   // Make sure all shells have links back to the content element
   // in the nearest enclosing chrome shell.
-  nsCOMPtr<nsIDOMEventTarget> chromeEventHandler;
+  RefPtr<EventTarget> chromeEventHandler;
 
   if (parentType == nsIDocShellTreeItem::typeChrome) {
     // Our parent shell is a chrome shell. It is therefore our nearest
     // enclosing chrome shell.
 
-    chromeEventHandler = do_QueryInterface(mOwnerContent);
+    chromeEventHandler = mOwnerContent;
     NS_ASSERTION(chromeEventHandler,
                  "This mContent should implement this.");
   } else {
     // Our parent shell is a content shell. Get the chrome event
     // handler from it and use that for our shell as well.
 
     parentDocShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler));
   }
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -14,16 +14,17 @@
 #include "Navigator.h"
 #include "nsContentSecurityManager.h"
 #include "nsScreen.h"
 #include "nsHistory.h"
 #include "nsDOMNavigationTiming.h"
 #include "nsIDOMStorageManager.h"
 #include "mozilla/dom/DOMJSProxyHandler.h"
 #include "mozilla/dom/DOMPrefs.h"
+#include "mozilla/dom/EventTarget.h"
 #include "mozilla/dom/LocalStorage.h"
 #include "mozilla/dom/Storage.h"
 #include "mozilla/dom/IdleRequest.h"
 #include "mozilla/dom/Performance.h"
 #include "mozilla/dom/StorageEvent.h"
 #include "mozilla/dom/StorageEventBinding.h"
 #include "mozilla/dom/StorageNotifierService.h"
 #include "mozilla/dom/StorageUtils.h"
@@ -106,17 +107,16 @@
 #include "nsIBaseWindow.h"
 #include "nsIDeviceSensors.h"
 #include "nsIContent.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "Crypto.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMElement.h"
-#include "nsIDOMEvent.h"
 #include "nsIDOMOfflineResourceList.h"
 #include "nsDOMString.h"
 #include "nsIEmbeddingSiteWindow.h"
 #include "nsThreadUtils.h"
 #include "nsILoadContext.h"
 #include "nsIPresShell.h"
 #include "nsIScrollableFrame.h"
 #include "nsView.h"
@@ -1326,23 +1326,21 @@ nsGlobalWindowInner::FreeInnerObjects()
 
 //*****************************************************************************
 // nsGlobalWindowInner::nsISupports
 //*****************************************************************************
 
 // QueryInterface implementation for nsGlobalWindowInner
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindowInner)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  // Make sure this matches the cast in nsGlobalWindowInner::FromWrapper()
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventTarget)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, EventTarget)
   NS_INTERFACE_MAP_ENTRY(nsIDOMWindow)
   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
   NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObject)
   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
   NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
   if (aIID.Equals(NS_GET_IID(nsPIDOMWindowInner))) {
     foundInterface = static_cast<nsPIDOMWindowInner*>(this);
   } else
   if (aIID.Equals(NS_GET_IID(mozIDOMWindow))) {
     foundInterface = static_cast<mozIDOMWindow*>(this);
   } else
   if (aIID.Equals(NS_GET_IID(nsIDOMChromeWindow)) && IsChromeWindow()) {
@@ -1612,17 +1610,17 @@ nsGlobalWindowInner::IsBlackForCC(bool a
 {
   if (!nsCCUncollectableMarker::sGeneration) {
     return false;
   }
 
   return (nsCCUncollectableMarker::InGeneration(GetMarkedCCGeneration()) ||
           HasKnownLiveWrapper()) &&
          (!aTracingNeeded ||
-          HasNothingToTrace(static_cast<nsIDOMEventTarget*>(this)));
+          HasNothingToTrace(ToSupports(this)));
 }
 
 //*****************************************************************************
 // nsGlobalWindowInner::nsIScriptGlobalObject
 //*****************************************************************************
 
 nsresult
 nsGlobalWindowInner::EnsureScriptEnvironment()
@@ -2041,17 +2039,17 @@ nsGlobalWindowInner::PostHandleEvent(Eve
       break;
     default:
       return NS_OK;
   }
 
   /* mChromeEventHandler and mContext go dangling in the middle of this
    function under some circumstances (events that destroy the window)
    without this addref. */
-  nsCOMPtr<nsIDOMEventTarget> kungFuDeathGrip1(mChromeEventHandler);
+  RefPtr<EventTarget> kungFuDeathGrip1(mChromeEventHandler);
   mozilla::Unused << kungFuDeathGrip1; // These aren't referred to through the function
   nsCOMPtr<nsIScriptContext> kungFuDeathGrip2(GetContextInternal());
   mozilla::Unused << kungFuDeathGrip2; // These aren't referred to through the function
 
 
   if (aVisitor.mEvent->mMessage == eResize) {
     mIsHandlingResizeEvent = false;
   } else if (aVisitor.mEvent->mMessage == eUnload &&
@@ -4481,17 +4479,17 @@ nsGlobalWindowInner::Atob(const nsAStrin
 void
 nsGlobalWindowInner::Btoa(const nsAString& aBinaryData,
                           nsAString& aAsciiBase64String, ErrorResult& aError)
 {
   aError = nsContentUtils::Btoa(aBinaryData, aAsciiBase64String);
 }
 
 //*****************************************************************************
-// nsGlobalWindowInner::nsIDOMEventTarget
+// EventTarget
 //*****************************************************************************
 
 nsPIDOMWindowOuter*
 nsGlobalWindowInner::GetOwnerGlobalForBindings()
 {
   return nsPIDOMWindowOuter::GetFromCurrentInner(this);
 }
 
--- a/dom/base/nsGlobalWindowInner.h
+++ b/dom/base/nsGlobalWindowInner.h
@@ -19,17 +19,16 @@
 #include "nsAutoPtr.h"
 #include "nsWeakReference.h"
 #include "nsDataHashtable.h"
 #include "nsJSThingHashtable.h"
 #include "nsCycleCollectionParticipant.h"
 
 // Interfaces Needed
 #include "nsIBrowserDOMWindow.h"
-#include "nsIDOMEventTarget.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIDOMChromeWindow.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsITimer.h"
 #include "mozilla/EventListenerManager.h"
 #include "nsIPrincipal.h"
 #include "nsSize.h"
@@ -310,19 +309,16 @@ public:
   // nsIDOMChromeWindow (only implemented on chrome windows)
   NS_DECL_NSIDOMCHROMEWINDOW
 
   void CaptureEvents();
   void ReleaseEvents();
   void Dump(const nsAString& aStr);
   void SetResizable(bool aResizable) const;
 
-  // nsIDOMEventTarget
-  NS_DECL_NSIDOMEVENTTARGET
-
   virtual mozilla::EventListenerManager*
     GetExistingListenerManager() const override;
 
   virtual mozilla::EventListenerManager*
     GetOrCreateListenerManager() override;
 
   bool ComputeDefaultWantsUntrusted(mozilla::ErrorResult& aRv) final;
 
@@ -476,17 +472,17 @@ public:
   static void ShutDown();
   static bool IsCallerChrome();
 
   void CleanupCachedXBLHandlers();
 
   friend class WindowStateHolder;
 
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsGlobalWindowInner,
-                                                                   nsIDOMEventTarget)
+                                                                   mozilla::dom::EventTarget)
 
 #ifdef DEBUG
   // Call Unlink on this window. This may cause bad things to happen, so use
   // with caution.
   void RiskyUnlink();
 #endif
 
   virtual JSObject*
@@ -1504,23 +1500,23 @@ protected:
   friend class mozilla::dom::TimeoutManager;
   friend class IdleRequestExecutor;
   friend class nsGlobalWindowOuter;
 };
 
 inline nsISupports*
 ToSupports(nsGlobalWindowInner *p)
 {
-    return static_cast<nsIDOMEventTarget*>(p);
+  return static_cast<mozilla::dom::EventTarget*>(p);
 }
 
 inline nsISupports*
 ToCanonicalSupports(nsGlobalWindowInner *p)
 {
-    return static_cast<nsIDOMEventTarget*>(p);
+  return static_cast<mozilla::dom::EventTarget*>(p);
 }
 
 // XXX: EWW - This is an awful hack - let's not do this
 #include "nsGlobalWindowOuter.h"
 
 inline nsIGlobalObject*
 nsGlobalWindowInner::GetOwnerGlobal() const
 {
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -12,16 +12,17 @@
 
 // Local Includes
 #include "Navigator.h"
 #include "nsContentSecurityManager.h"
 #include "nsScreen.h"
 #include "nsHistory.h"
 #include "nsDOMNavigationTiming.h"
 #include "nsIDOMStorageManager.h"
+#include "mozilla/dom/EventTarget.h"
 #include "mozilla/dom/LocalStorage.h"
 #include "mozilla/dom/Storage.h"
 #include "mozilla/dom/IdleRequest.h"
 #include "mozilla/dom/Performance.h"
 #include "mozilla/dom/StorageEvent.h"
 #include "mozilla/dom/StorageEventBinding.h"
 #include "mozilla/dom/StorageNotifierService.h"
 #include "mozilla/dom/StorageUtils.h"
@@ -103,17 +104,16 @@
 #include "nsIBaseWindow.h"
 #include "nsIDeviceSensors.h"
 #include "nsIContent.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "Crypto.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMElement.h"
-#include "nsIDOMEvent.h"
 #include "nsIDOMOfflineResourceList.h"
 #include "nsDOMString.h"
 #include "nsIEmbeddingSiteWindow.h"
 #include "nsThreadUtils.h"
 #include "nsILoadContext.h"
 #include "nsIPresShell.h"
 #include "nsIScrollableFrame.h"
 #include "nsView.h"
@@ -1080,23 +1080,21 @@ nsGlobalWindowOuter::ClearControllers()
 
 //*****************************************************************************
 // nsGlobalWindowOuter::nsISupports
 //*****************************************************************************
 
 // QueryInterface implementation for nsGlobalWindowOuter
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindowOuter)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  // Make sure this matches the cast in nsGlobalWindowOuter::FromWrapper()
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventTarget)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, EventTarget)
   NS_INTERFACE_MAP_ENTRY(nsIDOMWindow)
   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
   NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObject)
   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
   NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
   if (aIID.Equals(NS_GET_IID(nsPIDOMWindowOuter))) {
     foundInterface = static_cast<nsPIDOMWindowOuter*>(this);
   } else
   if (aIID.Equals(NS_GET_IID(mozIDOMWindowProxy))) {
     foundInterface = static_cast<mozIDOMWindowProxy*>(this);
   } else
   if (aIID.Equals(NS_GET_IID(nsIDOMChromeWindow)) && IsChromeWindow()) {
@@ -1214,17 +1212,17 @@ nsGlobalWindowOuter::IsBlackForCC(bool a
 {
   if (!nsCCUncollectableMarker::sGeneration) {
     return false;
   }
 
   return (nsCCUncollectableMarker::InGeneration(GetMarkedCCGeneration()) ||
           HasKnownLiveWrapper()) &&
          (!aTracingNeeded ||
-          HasNothingToTrace(static_cast<nsIDOMEventTarget*>(this)));
+          HasNothingToTrace(ToSupports(this)));
 }
 
 //*****************************************************************************
 // nsGlobalWindowOuter::nsIScriptGlobalObject
 //*****************************************************************************
 
 nsresult
 nsGlobalWindowOuter::EnsureScriptEnvironment()
@@ -2129,17 +2127,17 @@ nsGlobalWindowOuter::SetDocShell(nsIDocS
     !mIsChrome && GetScriptableTopInternal() == this;
 
   if (mFrames) {
     mFrames->SetDocShell(aDocShell);
   }
 
   // Get our enclosing chrome shell and retrieve its global window impl, so
   // that we can do some forwarding to the chrome document.
-  nsCOMPtr<nsIDOMEventTarget> chromeEventHandler;
+  RefPtr<EventTarget> chromeEventHandler;
   mDocShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler));
   mChromeEventHandler = do_QueryInterface(chromeEventHandler);
   if (!mChromeEventHandler) {
     // We have no chrome event handler. If we have a parent,
     // get our chrome event handler from the parent. If
     // we don't have a parent, then we need to make a new
     // window root object that will function as a chrome event
     // handler and receive all events that occur anywhere inside
@@ -6396,17 +6394,17 @@ nsGlobalWindowOuter::FindOuter(const nsA
 
   // Launch the search with the passed in search string
   bool didFind = false;
   aError = finder->FindNext(&didFind);
   return didFind;
 }
 
 //*****************************************************************************
-// nsGlobalWindowOuter::nsIDOMEventTarget
+// EventTarget
 //*****************************************************************************
 
 nsPIDOMWindowOuter*
 nsGlobalWindowOuter::GetOwnerGlobalForBindings()
 {
   return this;
 }
 
--- a/dom/base/nsGlobalWindowOuter.h
+++ b/dom/base/nsGlobalWindowOuter.h
@@ -20,17 +20,16 @@
 #include "nsAutoPtr.h"
 #include "nsWeakReference.h"
 #include "nsDataHashtable.h"
 #include "nsJSThingHashtable.h"
 #include "nsCycleCollectionParticipant.h"
 
 // Interfaces Needed
 #include "nsIBrowserDOMWindow.h"
-#include "nsIDOMEventTarget.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIDOMChromeWindow.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsITimer.h"
 #include "mozilla/EventListenerManager.h"
 #include "nsIPrincipal.h"
 #include "nsSize.h"
@@ -267,19 +266,16 @@ public:
 
   mozilla::dom::ChromeMessageBroadcaster* GetMessageManager();
   mozilla::dom::ChromeMessageBroadcaster* GetGroupMessageManager(const nsAString& aGroup);
 
   nsresult
   OpenJS(const nsAString& aUrl, const nsAString& aName,
          const nsAString& aOptions, nsPIDOMWindowOuter **_retval);
 
-  // nsIDOMEventTarget
-  NS_DECL_NSIDOMEVENTTARGET
-
   virtual mozilla::EventListenerManager*
     GetExistingListenerManager() const override;
 
   virtual mozilla::EventListenerManager*
     GetOrCreateListenerManager() override;
 
   bool ComputeDefaultWantsUntrusted(mozilla::ErrorResult& aRv) final;
 
@@ -454,17 +450,17 @@ public:
 
   static void Init();
   static void ShutDown();
   static bool IsCallerChrome();
 
   friend class WindowStateHolder;
 
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsGlobalWindowOuter,
-                                                                   nsIDOMEventTarget)
+                                                                   mozilla::dom::EventTarget)
 
   virtual bool TakeFocus(bool aFocus, uint32_t aFocusMethod) override;
   virtual void SetReadyForFocus() override;
   virtual void PageHidden() override;
 
   virtual nsresult SetArguments(nsIArray* aArguments) override;
 
   void MaybeForgiveSpamCount();
@@ -1169,23 +1165,23 @@ protected:
 };
 
 // XXX: EWW - This is an awful hack - let's not do this
 #include "nsGlobalWindowInner.h"
 
 inline nsISupports*
 ToSupports(nsGlobalWindowOuter *p)
 {
-    return static_cast<nsIDOMEventTarget*>(p);
+  return static_cast<mozilla::dom::EventTarget*>(p);
 }
 
 inline nsISupports*
 ToCanonicalSupports(nsGlobalWindowOuter *p)
 {
-    return static_cast<nsIDOMEventTarget*>(p);
+  return static_cast<mozilla::dom::EventTarget*>(p);
 }
 
 inline nsIGlobalObject*
 nsGlobalWindowOuter::GetOwnerGlobal() const
 {
   return GetCurrentInnerWindowInternal();
 }
 
--- a/dom/base/nsIContent.h
+++ b/dom/base/nsIContent.h
@@ -935,16 +935,21 @@ public:
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIContent, NS_ICONTENT_IID)
 
 inline nsIContent* nsINode::AsContent()
 {
   MOZ_ASSERT(IsContent());
   return static_cast<nsIContent*>(this);
 }
 
+inline const nsIContent* nsINode::AsContent() const
+{
+  return const_cast<nsINode*>(this)->AsContent();
+}
+
 // Some checks are faster to do on nsIContent or Element than on
 // nsINode, so spit out FromNode versions taking those types too.
 #define NS_IMPL_FROMNODE_HELPER(_class, _check)                         \
   template<typename ArgType>                                            \
   static _class* FromNode(ArgType&& aNode)                              \
   {                                                                     \
     /* We need the double-cast in case aNode is a smartptr.  Those */   \
     /* can cast to superclasses of the type they're templated on, */    \
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -4602,9 +4602,23 @@ nsINode::GetParentObject() const
 {
   mozilla::dom::ParentObject p(OwnerDoc());
     // Note that mUseXBLScope is a no-op for chrome, and other places where we
     // don't use XBL scopes.
   p.mUseXBLScope = IsInAnonymousSubtree() && !IsAnonymousContentInSVGUseSubtree();
   return p;
 }
 
+inline nsIDocument*
+nsINode::AsDocument()
+{
+  MOZ_ASSERT(IsDocument());
+  return static_cast<nsIDocument*>(this);
+}
+
+inline const nsIDocument*
+nsINode::AsDocument() const
+{
+  MOZ_ASSERT(IsDocument());
+  return static_cast<const nsIDocument*>(this);
+}
+
 #endif /* nsIDocument_h___ */
--- a/dom/base/nsIDroppedLinkHandler.idl
+++ b/dom/base/nsIDroppedLinkHandler.idl
@@ -1,17 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 #include "nsIPrincipal.idl"
 
-interface nsIDOMEvent;
-
 webidl DragEvent;
 webidl DataTransfer;
 
 [scriptable, uuid(69E14F91-2E09-4CA6-A511-A715C99A2804)]
 interface nsIDroppedLinkItem : nsISupports
 {
   /**
    * Returns the URL of the link.
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -56,17 +56,16 @@
 #include "nsIAnonymousContentCreator.h"
 #include "nsAtom.h"
 #include "nsIBaseWindow.h"
 #include "nsICategoryManager.h"
 #include "nsIContentIterator.h"
 #include "nsIControllers.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMEvent.h"
 #include "nsIDOMEventListener.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"
@@ -339,18 +338,18 @@ static nsIContent* GetRootForContentSubt
   return aContent;
 }
 
 nsIContent*
 nsINode::GetSelectionRootContent(nsIPresShell* aPresShell)
 {
   NS_ENSURE_TRUE(aPresShell, nullptr);
 
-  if (IsNodeOfType(eDOCUMENT))
-    return static_cast<nsIDocument*>(this)->GetRootElement();
+  if (IsDocument())
+    return AsDocument()->GetRootElement();
   if (!IsContent())
     return nullptr;
 
   if (GetComposedDoc() != aPresShell->GetDocument()) {
     return nullptr;
   }
 
   if (static_cast<nsIContent*>(this)->HasIndependentSelection()) {
@@ -408,30 +407,28 @@ nsINode::GetSelectionRootContent(nsIPres
   return content;
 }
 
 nsINodeList*
 nsINode::ChildNodes()
 {
   nsSlots* slots = Slots();
   if (!slots->mChildNodes) {
-    // Check |!IsElement()| first to catch the common case
-    // without virtual call |IsNodeOfType|
-    slots->mChildNodes = !IsElement() && IsNodeOfType(nsINode::eATTRIBUTE) ?
-                           new nsAttrChildContentList(this) :
-                           new nsParentNodeChildContentList(this);
+    slots->mChildNodes = IsAttr()
+      ? new nsAttrChildContentList(this)
+      : new nsParentNodeChildContentList(this);
   }
 
   return slots->mChildNodes;
 }
 
 void
 nsINode::InvalidateChildNodes()
 {
-  MOZ_ASSERT(IsElement() || !IsNodeOfType(nsINode::eATTRIBUTE));
+  MOZ_ASSERT(!IsAttr());
 
   nsSlots* slots = GetExistingSlots();
   if (!slots || !slots->mChildNodes) {
     return;
   }
 
   auto childNodes =
     static_cast<nsParentNodeChildContentList*>(slots->mChildNodes.get());
@@ -524,17 +521,17 @@ void
 nsINode::GetNodeValueInternal(nsAString& aNodeValue)
 {
   SetDOMStringToNull(aNodeValue);
 }
 
 nsINode*
 nsINode::RemoveChild(nsINode& aOldChild, ErrorResult& aError)
 {
-  if (IsNodeOfType(eDATA_NODE)) {
+  if (IsCharacterData()) {
     // aOldChild can't be one of our children.
     aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
     return nullptr;
   }
 
   if (aOldChild.GetParentNode() == this) {
     nsContentUtils::MaybeFireNodeRemoved(&aOldChild, this, OwnerDoc());
   }
@@ -736,32 +733,31 @@ nsINode::CompareDocumentPosition(nsINode
   }
   if (GetNextSibling() == &aOtherNode) {
     MOZ_ASSERT(GetParentNode() == aOtherNode.GetParentNode());
     return NodeBinding::DOCUMENT_POSITION_FOLLOWING;
   }
 
   AutoTArray<const nsINode*, 32> parents1, parents2;
 
-  const nsINode *node1 = &aOtherNode, *node2 = this;
+  const nsINode* node1 = &aOtherNode;
+  const nsINode* node2 = this;
 
   // Check if either node is an attribute
-  const Attr* attr1 = nullptr;
-  if (node1->IsNodeOfType(nsINode::eATTRIBUTE)) {
-    attr1 = static_cast<const Attr*>(node1);
+  const Attr* attr1 = Attr::FromNode(node1);
+  if (attr1) {
     const Element* elem = attr1->GetElement();
     // If there is an owner element add the attribute
     // to the chain and walk up to the element
     if (elem) {
       node1 = elem;
       parents1.AppendElement(attr1);
     }
   }
-  if (node2->IsNodeOfType(nsINode::eATTRIBUTE)) {
-    const Attr* attr2 = static_cast<const Attr*>(node2);
+  if (auto* attr2 = Attr::FromNode(node2)) {
     const Element* elem = attr2->GetElement();
     if (elem == node1 && attr1) {
       // Both nodes are attributes on the same element.
       // Compare position between the attributes.
 
       uint32_t i;
       const nsAttrName* attrName;
       for (i = 0; (attrName = elem->GetAttrNameAt(i)); ++i) {
@@ -1290,17 +1286,17 @@ CheckForOutdatedParent(nsINode* aParent,
   }
 }
 
 nsresult
 nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
                          bool aNotify, nsAttrAndChildArray& aChildArray)
 {
   MOZ_ASSERT(!aKid->GetParentNode(), "Inserting node that already has parent");
-  MOZ_ASSERT(!IsNodeOfType(nsINode::eATTRIBUTE));
+  MOZ_ASSERT(!IsAttr());
 
   // The id-handling code, and in the future possibly other code, need to
   // react to unexpected attribute changes.
   nsMutationGuard::DidMutate();
 
   // Do this before checking the child-count since this could cause mutations
   nsIDocument* doc = GetUncomposedDoc();
   mozAutoDocUpdate updateBatch(GetComposedDoc(), UPDATE_CONTENT_MODEL, aNotify);
@@ -1334,18 +1330,17 @@ nsINode::doInsertChildAt(nsIContent* aKi
   bool isAppend = (aIndex == childCount);
 
   nsresult rv = aChildArray.InsertChildAt(aKid, aIndex);
   NS_ENSURE_SUCCESS(rv, rv);
   if (aIndex == 0) {
     mFirstChild = aKid;
   }
 
-  nsIContent* parent =
-    IsNodeOfType(eDOCUMENT) ? nullptr : static_cast<nsIContent*>(this);
+  nsIContent* parent = IsContent() ? AsContent() : nullptr;
 
   rv = aKid->BindToTree(doc, parent,
                         parent ? parent->GetBindingParent() : nullptr,
                         true);
   if (NS_FAILED(rv)) {
     if (GetFirstChild() == aKid) {
       mFirstChild = aKid->GetNextSibling();
     }
@@ -1645,17 +1640,17 @@ nsINode::doRemoveChildAt(uint32_t aIndex
   // NOTE: This function must not trigger any calls to
   // nsIDocument::GetRootElement() calls until *after* it has removed aKid from
   // aChildArray. Any calls before then could potentially restore a stale
   // value for our cached root element, per note in
   // nsDocument::RemoveChildNode().
   MOZ_ASSERT(aKid && aKid->GetParentNode() == this &&
              aKid == GetChildAt_Deprecated(aIndex) &&
              ComputeIndexOf(aKid) == (int32_t)aIndex, "Bogus aKid");
-  MOZ_ASSERT(!IsNodeOfType(nsINode::eATTRIBUTE));
+  MOZ_ASSERT(!IsAttr());
 
   nsMutationGuard::DidMutate();
   mozAutoDocUpdate updateBatch(GetComposedDoc(), UPDATE_CONTENT_MODEL, aNotify);
 
   nsIContent* previousSibling = aKid->GetPreviousSibling();
 
   if (GetFirstChild() == aKid) {
     mFirstChild = aKid->GetNextSibling();
@@ -1678,18 +1673,18 @@ nsINode::doRemoveChildAt(uint32_t aIndex
 // latter case it may be null.
 static
 bool IsAllowedAsChild(nsIContent* aNewChild, nsINode* aParent,
                       bool aIsReplace, nsINode* aRefChild)
 {
   MOZ_ASSERT(aNewChild, "Must have new child");
   MOZ_ASSERT_IF(aIsReplace, aRefChild);
   MOZ_ASSERT(aParent);
-  MOZ_ASSERT(aParent->IsNodeOfType(nsINode::eDOCUMENT) ||
-             aParent->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT) ||
+  MOZ_ASSERT(aParent->IsDocument() ||
+             aParent->IsDocumentFragment() ||
              aParent->IsElement(),
              "Nodes that are not documents, document fragments or elements "
              "can't be parents!");
 
   // A common case is that aNewChild has no kids, in which case
   // aParent can't be a descendant of aNewChild unless they're
   // actually equal to each other.  Fast-path that case, since aParent
   // could be pretty deep in the DOM tree.
@@ -1713,22 +1708,22 @@ bool IsAllowedAsChild(nsIContent* aNewCh
     return true;
   case nsINode::TEXT_NODE :
   case nsINode::CDATA_SECTION_NODE :
   case nsINode::ENTITY_REFERENCE_NODE :
     // Allowed under Elements and DocumentFragments
     return aParent->NodeType() != nsINode::DOCUMENT_NODE;
   case nsINode::ELEMENT_NODE :
     {
-      if (!aParent->IsNodeOfType(nsINode::eDOCUMENT)) {
+      if (!aParent->IsDocument()) {
         // Always ok to have elements under other elements or document fragments
         return true;
       }
 
-      nsIDocument* parentDocument = static_cast<nsIDocument*>(aParent);
+      nsIDocument* parentDocument = aParent->AsDocument();
       Element* rootElement = parentDocument->GetRootElement();
       if (rootElement) {
         // Already have a documentElement, so this is only OK if we're
         // replacing it.
         return aIsReplace && rootElement == aRefChild;
       }
 
       // We don't have a documentElement yet.  Our one remaining constraint is
@@ -1750,22 +1745,22 @@ bool IsAllowedAsChild(nsIContent* aNewCh
       // Now we're OK in the following two cases only:
       // 1) We're replacing something that's not before the doctype
       // 2) We're inserting before something that comes after the doctype
       return aIsReplace ? (insertIndex >= doctypeIndex) :
         insertIndex > doctypeIndex;
     }
   case nsINode::DOCUMENT_TYPE_NODE :
     {
-      if (!aParent->IsNodeOfType(nsINode::eDOCUMENT)) {
+      if (!aParent->IsDocument()) {
         // doctypes only allowed under documents
         return false;
       }
 
-      nsIDocument* parentDocument = static_cast<nsIDocument*>(aParent);
+      nsIDocument* parentDocument = aParent->AsDocument();
       nsIContent* docTypeContent = parentDocument->GetDoctype();
       if (docTypeContent) {
         // Already have a doctype, so this is only OK if we're replacing it
         return aIsReplace && docTypeContent == aRefChild;
       }
 
       // We don't have a doctype yet.  Our one remaining constraint is
       // that the doctype must come before the documentElement.
@@ -1790,17 +1785,17 @@ bool IsAllowedAsChild(nsIContent* aNewCh
     }
   case nsINode::DOCUMENT_FRAGMENT_NODE :
     {
       // Note that for now we only allow nodes inside document fragments if
       // they're allowed inside elements.  If we ever change this to allow
       // doctype nodes in document fragments, we'll need to update this code.
       // Also, there's a version of this code in ReplaceOrInsertBefore.  If you
       // change this code, change that too.
-      if (!aParent->IsNodeOfType(nsINode::eDOCUMENT)) {
+      if (!aParent->IsDocument()) {
         // All good here
         return true;
       }
 
       bool sawElement = false;
       for (nsIContent* child = aNewChild->GetFirstChild();
            child;
            child = child->GetNextSibling()) {
@@ -1841,19 +1836,17 @@ nsINode::EnsurePreInsertionValidity(nsIN
   }
   EnsurePreInsertionValidity2(false, aNewChild, aRefChild, aError);
 }
 
 void
 nsINode::EnsurePreInsertionValidity1(nsINode& aNewChild, nsINode* aRefChild,
                                      ErrorResult& aError)
 {
-  if ((!IsNodeOfType(eDOCUMENT) &&
-       !IsNodeOfType(eDOCUMENT_FRAGMENT) &&
-       !IsElement()) ||
+  if ((!IsDocument() && !IsDocumentFragment() && !IsElement()) ||
       !aNewChild.IsContent()) {
     aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
     return;
   }
 }
 
 void
 nsINode::EnsurePreInsertionValidity2(bool aReplace, nsINode& aNewChild,
@@ -2100,17 +2093,17 @@ nsINode::ReplaceOrInsertBefore(bool aRep
       } else {
         nodeToInsertBefore = aRefChild;
       }
 
       // And verify that newContent is still allowed as our child.  Sadly, we
       // need to reimplement the relevant part of IsAllowedAsChild() because
       // now our nodes are in an array and all.  If you change this code,
       // change the code there.
-      if (IsNodeOfType(nsINode::eDOCUMENT)) {
+      if (IsDocument()) {
         bool sawElement = false;
         for (uint32_t i = 0; i < count; ++i) {
           nsIContent* child = fragChildren->ElementAt(i);
           if (child->IsElement()) {
             if (sawElement) {
               // No good
               aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
               return nullptr;
@@ -2197,18 +2190,17 @@ nsINode::ReplaceOrInsertBefore(bool aRep
       mutationBatch->SetNextSibling(GetChildAt_Deprecated(insPos));
     }
 
     uint32_t count = fragChildren->Length();
     if (!count) {
       return result;
     }
 
-    bool appending =
-      !IsNodeOfType(eDOCUMENT) && uint32_t(insPos) == GetChildCount();
+    bool appending = !IsDocument() && uint32_t(insPos) == GetChildCount();
     nsIContent* firstInsertedContent = fragChildren->ElementAt(0);
 
     // Iterate through the fragment's children, and insert them in the new
     // parent
     for (uint32_t i = 0; i < count; ++i, ++insPos) {
       // XXXbz how come no reparenting here?  That seems odd...
       // Insert the child.
       aError = InsertChildAt_Deprecated(fragChildren->ElementAt(i), insPos,
@@ -2359,22 +2351,21 @@ nsINode::Contains(const nsINode* aOther)
   const nsIContent* other = static_cast<const nsIContent*>(aOther);
   if (this == OwnerDoc()) {
     // document.contains(aOther) returns true if aOther is in the document,
     // but is not in any anonymous subtree.
     // IsInUncomposedDoc() check is done already before this.
     return !other->IsInAnonymousSubtree();
   }
 
-  if (!IsElement() && !IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT)) {
+  if (!IsElement() && !IsDocumentFragment()) {
     return false;
   }
 
-  const nsIContent* thisContent = static_cast<const nsIContent*>(this);
-  if (thisContent->GetBindingParent() != other->GetBindingParent()) {
+  if (AsContent()->GetBindingParent() != other->GetBindingParent()) {
     return false;
   }
 
   return nsContentUtils::ContentIsDescendantOf(other, this);
 }
 
 uint32_t
 nsINode::Length() const
@@ -2444,17 +2435,18 @@ struct SelectorMatchInfo {
 template<bool onlyFirstMatch, class T>
 inline static void
 FindMatchingElementsWithId(const nsAString& aId, nsINode* aRoot,
                            SelectorMatchInfo* aMatchInfo,
                            T& aList)
 {
   MOZ_ASSERT(aRoot->IsInUncomposedDoc(),
              "Don't call me if the root is not in the document");
-  MOZ_ASSERT(aRoot->IsElement() || aRoot->IsNodeOfType(nsINode::eDOCUMENT),
+  // FIXME(emilio): It'd be nice to optimize this for shadow roots too.
+  MOZ_ASSERT(aRoot->IsElement() || aRoot->IsDocument(),
              "The optimization below to check ContentIsDescendantOf only for "
              "elements depends on aRoot being either an element or a "
              "document if it's in the document.  Note that document fragments "
              "can't be IsInUncomposedDoc(), so should never show up here.");
 
   const nsTArray<Element*>* elements = aRoot->OwnerDoc()->GetAllElementsForId(aId);
   if (!elements) {
     // Nothing to do; we're done
@@ -2519,17 +2511,17 @@ nsINode::QuerySelectorAll(const nsAStrin
   const bool useInvalidation = false;
   Servo_SelectorList_QueryAll(this, list, contentList.get(), useInvalidation);
   return contentList.forget();
 }
 
 Element*
 nsINode::GetElementById(const nsAString& aId)
 {
-  MOZ_ASSERT(IsElement() || IsNodeOfType(eDOCUMENT_FRAGMENT),
+  MOZ_ASSERT(IsElement() || IsDocumentFragment(),
              "Bogus this object for GetElementById call");
   if (IsInUncomposedDoc()) {
     ElementHolder holder;
     FindMatchingElementsWithId<true>(aId, this, nullptr, holder);
     return holder.mElement;
   }
 
   for (nsIContent* kid = GetFirstChild(); kid; kid = kid->GetNextNode(this)) {
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -72,16 +72,17 @@ inline bool IsSpaceCharacter(char16_t aC
 inline bool IsSpaceCharacter(char aChar) {
   return aChar == ' ' || aChar == '\t' || aChar == '\n' || aChar == '\r' ||
          aChar == '\f';
 }
 class AccessibleNode;
 struct BoxQuadOptions;
 struct ConvertCoordinateOptions;
 class DocGroup;
+class DocumentFragment;
 class DOMPoint;
 class DOMQuad;
 class DOMRectReadOnly;
 class Element;
 class EventHandlerNonNull;
 class L10nCallback;
 template<typename T> class Optional;
 class OwningNodeOrString;
@@ -406,32 +407,18 @@ public:
 #endif
 
   virtual ~nsINode();
 
   /**
    * Bit-flags to pass (or'ed together) to IsNodeOfType()
    */
   enum {
-    /** nsIDocument nodes */
-    eDOCUMENT            = 1 << 1,
-    /** nsIAttribute nodes */
-    eATTRIBUTE           = 1 << 2,
-    /** xml processing instructions */
-    ePROCESSING_INSTRUCTION = 1 << 4,
-    /** comment nodes */
-    eCOMMENT             = 1 << 5,
     /** form control elements */
     eHTML_FORM_CONTROL   = 1 << 6,
-    /** document fragments */
-    eDOCUMENT_FRAGMENT   = 1 << 7,
-    /** character data nodes (comments, PIs, text). */
-    eDATA_NODE           = 1 << 8,
-    /** HTMLMediaElement */
-    eMEDIA               = 1 << 9,
     /** animation elements */
     eANIMATION           = 1 << 10,
     /** filter elements that implement SVGFilterPrimitiveStandardAttributes */
     eFILTER              = 1 << 11,
     /** SVGGeometryElement */
     eSHAPE               = 1 << 12
   };
 
@@ -440,28 +427,59 @@ public:
    * type, such as Text, Document, Comment ...  Use this when you can instead of
    * checking the tag.
    *
    * @param aFlags what types you want to test for (see above)
    * @return whether the content matches ALL flags passed in
    */
   virtual bool IsNodeOfType(uint32_t aFlags) const = 0;
 
-  bool
-  IsContainerNode() const
+  bool IsContainerNode() const
   {
     return IsElement() || !IsCharacterData();
   }
 
-  bool
-  IsSlotable() const
+  bool IsSlotable() const
   {
     return IsElement() || IsText();
   }
 
+  /**
+   * Returns true if this is a document node.
+   */
+  bool IsDocument() const
+  {
+    // One less pointer-chase than checking NodeType().
+    return !GetParentNode() && IsInUncomposedDoc();
+  }
+
+  /**
+   * Return this node as a document. Asserts IsDocument().
+   *
+   * This is defined inline in nsIDocument.h.
+   */
+  inline nsIDocument* AsDocument();
+  inline const nsIDocument* AsDocument() const;
+
+  /**
+   * Returns true if this is a document fragment node.
+   */
+  bool IsDocumentFragment() const
+  {
+    return NodeType() == DOCUMENT_FRAGMENT_NODE;
+  }
+
+  /**
+   * Return this node as a document fragment. Asserts IsDocumentFragment().
+   *
+   * This is defined inline in DocumentFragment.h.
+   */
+  inline mozilla::dom::DocumentFragment* AsDocumentFragment();
+  inline const mozilla::dom::DocumentFragment* AsDocumentFragment() const;
+
   virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   /**
    * returns true if we are in priviliged code or
    * layout.css.getBoxQuads.enabled == true.
    */
   static bool HasBoxQuadsSupport(JSContext* aCx, JSObject* /* unused */);
 
@@ -485,60 +503,58 @@ public:
    * like event handler compilation.  Returning null means to use the
    * global object as the scope chain parent.
    */
   virtual nsINode* GetScopeChainParent() const;
 
   /**
    * Return whether the node is an Element node
    */
-  bool IsElement() const {
+  bool IsElement() const
+  {
     return GetBoolFlag(NodeIsElement);
   }
 
   /**
    * Return this node as an Element.  Should only be used for nodes
    * for which IsElement() is true.  This is defined inline in Element.h.
    */
-  mozilla::dom::Element* AsElement();
-  const mozilla::dom::Element* AsElement() const;
+  inline mozilla::dom::Element* AsElement();
+  inline const mozilla::dom::Element* AsElement() const;
 
   /**
    * Return this node as nsIContent.  Should only be used for nodes for which
    * IsContent() is true.  This is defined inline in nsIContent.h.
    */
-  nsIContent* AsContent();
-  const nsIContent* AsContent() const
-  {
-    return const_cast<nsINode*>(this)->AsContent();
-  }
+  inline nsIContent* AsContent();
+  inline const nsIContent* AsContent() const;
 
   /*
    * Return whether the node is a Text node (which might be an actual
    * textnode, or might be a CDATA section).
    */
   bool IsText() const
   {
     uint32_t nodeType = NodeType();
     return nodeType == TEXT_NODE || nodeType == CDATA_SECTION_NODE;
   }
 
   /**
    * Return this node as Text if it is one, otherwise null.  This is defined
    * inline in Text.h.
    */
-  mozilla::dom::Text* GetAsText();
-  const mozilla::dom::Text* GetAsText() const;
+  inline mozilla::dom::Text* GetAsText();
+  inline const mozilla::dom::Text* GetAsText() const;
 
   /**
    * Return this node as Text.  Asserts IsText().  This is defined inline in
    * Text.h.
    */
-  mozilla::dom::Text* AsText();
-  const mozilla::dom::Text* AsText() const;
+  inline mozilla::dom::Text* AsText();
+  inline const mozilla::dom::Text* AsText() const;
 
   /*
    * Return whether the node is a ProcessingInstruction node.
    */
   bool IsProcessingInstruction() const
   {
     return NodeType() == PROCESSING_INSTRUCTION_NODE;
   }
@@ -551,16 +567,32 @@ public:
   {
     uint32_t nodeType = NodeType();
     return nodeType == TEXT_NODE ||
            nodeType == CDATA_SECTION_NODE ||
            nodeType == PROCESSING_INSTRUCTION_NODE ||
            nodeType == COMMENT_NODE;
   }
 
+  /**
+   * Return whether the node is a Comment node.
+   */
+  bool IsComment() const
+  {
+    return NodeType() == COMMENT_NODE;
+  }
+
+  /**
+   * Return whether the node is an Attr node.
+   */
+  bool IsAttr() const
+  {
+    return NodeType() == ATTRIBUTE_NODE;
+  }
+
   virtual nsIDOMNode* AsDOMNode() = 0;
 
   /**
    * Return if this node has any children.
    */
   bool HasChildren() const { return !!mFirstChild; }
 
   /**
@@ -776,17 +808,17 @@ public:
   inline bool IsAnyOfMathMLElements(First aFirst, Args... aArgs) const
   {
     return IsMathMLElement() && IsNodeInternal(aFirst, aArgs...);
   }
 
   bool IsShadowRoot() const
   {
     const bool isShadowRoot = IsInShadowTree() && !GetParentNode();
-    MOZ_ASSERT_IF(isShadowRoot, NodeType() == DOCUMENT_FRAGMENT_NODE);
+    MOZ_ASSERT_IF(isShadowRoot, IsDocumentFragment());
     return isShadowRoot;
   }
 
   /**
    * Insert a content node before another or at the end.
    * This method handles calling BindToTree on the child appropriately.
    *
    * @param aKid the content to insert
@@ -1006,22 +1038,22 @@ public:
    */
   inline nsINode* GetFlattenedTreeParentNodeForStyle() const;
 
   inline mozilla::dom::Element* GetFlattenedTreeParentElement() const;
   inline mozilla::dom::Element* GetFlattenedTreeParentElementForStyle() const;
 
   /**
    * Get the parent nsINode for this node if it is an Element.
+   *
+   * Defined inline in Element.h
+   *
    * @return the parent node
    */
-  mozilla::dom::Element* GetParentElement() const
-  {
-    return mParent && mParent->IsElement() ? mParent->AsElement() : nullptr;
-  }
+  inline mozilla::dom::Element* GetParentElement() const;
 
   /**
    * Get the parent Element of this node, traversing over a ShadowRoot
    * to its host if necessary.
    */
   mozilla::dom::Element* GetParentElementCrossingShadowRoot() const;
 
   /**
@@ -1032,21 +1064,16 @@ public:
   nsINode* SubtreeRoot() const;
 
   /*
    * Get context object's shadow-including root if options's composed is true,
    * and context object's root otherwise.
    */
   nsINode* GetRootNode(const mozilla::dom::GetRootNodeOptions& aOptions);
 
-  /**
-   * See nsIDOMEventTarget
-   */
-  NS_DECL_NSIDOMEVENTTARGET
-
   virtual mozilla::EventListenerManager*
     GetExistingListenerManager() const override;
   virtual mozilla::EventListenerManager*
     GetOrCreateListenerManager() override;
 
   bool ComputeDefaultWantsUntrusted(mozilla::ErrorResult& aRv) final;
 
   virtual bool IsApzAware() const override;
--- a/dom/base/nsISlowScriptDebug.idl
+++ b/dom/base/nsISlowScriptDebug.idl
@@ -1,33 +1,34 @@
 /* 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 nsIDOMWindow;
-interface nsIDOMEventTarget;
+
+webidl EventTarget;
 
 [scriptable, function, uuid(f7dbb80c-5d1e-4fd9-b55c-a9ffda4a75b1)]
 interface nsISlowScriptDebugCallback : nsISupports
 {
   void handleSlowScriptDebug(in nsIDOMWindow aWindow);
 };
 
 [scriptable, function, uuid(b1c6ecd0-8fa4-11e4-b4a9-0800200c9a66)]
 interface nsISlowScriptDebuggerStartupCallback : nsISupports
 {
   void finishDebuggerStartup();
 };
 
 [scriptable, function, uuid(dbee14b0-8fa0-11e4-b4a9-0800200c9a66)]
 interface nsISlowScriptDebugRemoteCallback : nsISupports
 {
-  void handleSlowScriptDebug(in nsIDOMEventTarget aBrowser,
+  void handleSlowScriptDebug(in EventTarget aBrowser,
                              in nsISlowScriptDebuggerStartupCallback aCallback);
 };
 
 [scriptable, uuid(f75d4164-3aa7-4395-ba44-a5f95b2e8427)]
 interface nsISlowScriptDebug : nsISupports
 {
   attribute nsISlowScriptDebugCallback activationHandler;
   attribute nsISlowScriptDebugRemoteCallback remoteActivationHandler;
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -205,31 +205,29 @@ nsNodeUtils::NativeAnonymousChildListCha
                             (aContent, aIsRemove),
                             isRemove);
 }
 
 void
 nsNodeUtils::ContentInserted(nsINode* aContainer,
                              nsIContent* aChild)
 {
-  NS_PRECONDITION(aContainer->IsContent() ||
-                  aContainer->IsNodeOfType(nsINode::eDOCUMENT),
+  NS_PRECONDITION(aContainer->IsContent() || aContainer->IsDocument(),
                   "container must be an nsIContent or an nsIDocument");
   nsIDocument* doc = aContainer->OwnerDoc();
   IMPL_MUTATION_NOTIFICATION(ContentInserted, aContainer, (aChild),
                              IsRemoveNotification::No);
 }
 
 void
 nsNodeUtils::ContentRemoved(nsINode* aContainer,
                             nsIContent* aChild,
                             nsIContent* aPreviousSibling)
 {
-  NS_PRECONDITION(aContainer->IsContent() ||
-                  aContainer->IsNodeOfType(nsINode::eDOCUMENT),
+  NS_PRECONDITION(aContainer->IsContent() || aContainer->IsDocument(),
                   "container must be an nsIContent or an nsIDocument");
   nsIDocument* doc = aContainer->OwnerDoc();
   MOZ_ASSERT(aChild->GetParentNode() == aContainer,
              "We expect the parent link to be still around at this point");
   IMPL_MUTATION_NOTIFICATION(ContentRemoved, aContainer,
                              (aChild, aPreviousSibling),
                              IsRemoveNotification::Yes);
 }
@@ -304,21 +302,21 @@ nsNodeUtils::LastRelease(nsINode* aNode)
     }
 
     delete slots;
     aNode->mSlots = nullptr;
   }
 
   // Kill properties first since that may run external code, so we want to
   // be in as complete state as possible at that time.
-  if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {
+  if (aNode->IsDocument()) {
     // Delete all properties before tearing down the document. Some of the
     // properties are bound to nsINode objects and the destructor functions of
     // the properties may want to use the owner document of the nsINode.
-    static_cast<nsIDocument*>(aNode)->DeleteAllProperties();
+    aNode->AsDocument()->DeleteAllProperties();
   }
   else {
     if (aNode->HasProperties()) {
       // Strong reference to the document so that deleting properties can't
       // delete the document.
       nsCOMPtr<nsIDocument> document = aNode->OwnerDoc();
       document->DeleteAllPropertiesFor(aNode);
     }
@@ -484,17 +482,17 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
       // parent.
       rv = aParent->AppendChildTo(static_cast<nsIContent*>(clone.get()),
                                   false);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         aError.Throw(rv);
         return nullptr;
       }
     }
-    else if (aDeep && clone->IsNodeOfType(nsINode::eDOCUMENT)) {
+    else if (aDeep && clone->IsDocument()) {
       // After cloning the document itself, we want to clone the children into
       // the cloned document (somewhat like cloning and importing them into the
       // cloned document).
       nodeInfoManager = clone->mNodeInfo->NodeInfoManager();
     }
   }
   else if (nodeInfoManager) {
     nsIDocument* oldDoc = aNode->OwnerDoc();
@@ -610,17 +608,17 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
     bool ok = aNodesWithProperties->AppendObject(aNode);
     MOZ_RELEASE_ASSERT(ok, "Out of memory");
     if (aClone) {
       ok = aNodesWithProperties->AppendObject(clone);
       MOZ_RELEASE_ASSERT(ok, "Out of memory");
     }
   }
 
-  if (aDeep && (!aClone || !aNode->IsNodeOfType(nsINode::eATTRIBUTE))) {
+  if (aDeep && (!aClone || !aNode->IsAttr())) {
     // aNode's children.
     for (nsIContent* cloneChild = aNode->GetFirstChild();
          cloneChild;
          cloneChild = cloneChild->GetNextSibling()) {
       nsCOMPtr<nsINode> child =
         CloneAndAdopt(cloneChild, aClone, true, nodeInfoManager,
                       aReparentScope, aNodesWithProperties, clone,
                       aError);
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -976,19 +976,19 @@ nsRange::DoSetRange(const RawRangeBounda
   NS_PRECONDITION(!aRoot ||
                   (aStart.Container()->IsContent() &&
                    aEnd.Container()->IsContent() &&
                    aRoot ==
                     static_cast<nsIContent*>(aStart.Container())->GetBindingParent() &&
                    aRoot ==
                     static_cast<nsIContent*>(aEnd.Container())->GetBindingParent()) ||
                   (!aRoot->GetParentNode() &&
-                   (aRoot->IsNodeOfType(nsINode::eDOCUMENT) ||
-                    aRoot->IsNodeOfType(nsINode::eATTRIBUTE) ||
-                    aRoot->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT) ||
+                   (aRoot->IsDocument() ||
+                    aRoot->IsAttr() ||
+                    aRoot->IsDocumentFragment() ||
                      /*For backward compatibility*/
                     aRoot->IsContent())),
                   "Bad root");
   if (mRoot != aRoot) {
     if (mRoot) {
       mRoot->RemoveMutationObserver(this);
     }
     if (aRoot) {
@@ -1203,17 +1203,17 @@ nsRange::ComputeRootNode(nsINode* aNode,
   // text nodes in document, in document fragment or in attribute.
   nsINode* root = aNode->GetUncomposedDoc();
   if (root) {
     return root;
   }
 
   root = aNode->SubtreeRoot();
 
-  NS_ASSERTION(!root->IsNodeOfType(nsINode::eDOCUMENT),
+  NS_ASSERTION(!root->IsDocument(),
                "GetUncomposedDoc should have returned a doc");
 
   // We allow this because of backward compatibility.
   return root;
 }
 
 /* static */
 bool
--- a/dom/base/nsScreen.cpp
+++ b/dom/base/nsScreen.cpp
@@ -1,15 +1,14 @@
 /* -*- 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 "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
 #include "mozilla/dom/ScreenBinding.h"
 #include "nsContentUtils.h"
 #include "nsScreen.h"
 #include "nsIDocument.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsPresContext.h"
 #include "nsCOMPtr.h"
--- a/dom/base/nsTextNode.cpp
+++ b/dom/base/nsTextNode.cpp
@@ -105,17 +105,17 @@ JSObject*
 nsTextNode::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return TextBinding::Wrap(aCx, this, aGivenProto);
 }
 
 bool
 nsTextNode::IsNodeOfType(uint32_t aFlags) const
 {
-  return !(aFlags & ~eDATA_NODE);
+  return false;
 }
 
 already_AddRefed<CharacterData>
 nsTextNode::CloneDataNode(mozilla::dom::NodeInfo *aNodeInfo, bool aCloneText) const
 {
   already_AddRefed<mozilla::dom::NodeInfo> ni = RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();
   RefPtr<nsTextNode> it = new nsTextNode(ni);
   if (aCloneText) {
--- a/dom/base/nsTreeSanitizer.cpp
+++ b/dom/base/nsTreeSanitizer.cpp
@@ -9,16 +9,17 @@
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/BindingStyleRule.h"
 #include "mozilla/DeclarationBlock.h"
 #include "mozilla/DeclarationBlockInlines.h"
 #include "mozilla/ServoDeclarationBlock.h"
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/css/Rule.h"
 #include "mozilla/dom/CSSRuleList.h"
+#include "mozilla/dom/DocumentFragment.h"
 #include "mozilla/dom/SRIMetadata.h"
 #include "nsCSSParser.h"
 #include "nsCSSPropertyID.h"
 #include "nsUnicharInputStream.h"
 #include "nsAttrName.h"
 #include "nsIScriptError.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsNetUtil.h"
@@ -1345,23 +1346,21 @@ nsTreeSanitizer::SanitizeURL(mozilla::do
                  aElement->OwnerDoc(), aElement, aLocalName);
     }
     return true;
   }
   return false;
 }
 
 void
-nsTreeSanitizer::Sanitize(nsIContent* aFragment)
+nsTreeSanitizer::Sanitize(DocumentFragment* aFragment)
 {
   // If you want to relax these preconditions, be sure to check the code in
   // here that notifies / does not notify or that fires mutation events if
   // in tree.
-  NS_PRECONDITION(aFragment->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT),
-      "Argument was not DOM fragment.");
   NS_PRECONDITION(!aFragment->IsInUncomposedDoc(), "The fragment is in doc?");
 
   mFullDocument = false;
   SanitizeChildren(aFragment);
 }
 
 void
 nsTreeSanitizer::Sanitize(nsIDocument* aDocument)
@@ -1495,17 +1494,17 @@ nsTreeSanitizer::SanitizeChildren(nsINod
                            false,
                            false);
       }
       node = node->GetNextNode(aRoot);
       continue;
     }
     NS_ASSERTION(!node->GetFirstChild(), "How come non-element node had kids?");
     nsIContent* next = node->GetNextNonChildNode(aRoot);
-    if (!mAllowComments && node->IsNodeOfType(nsINode::eCOMMENT)) {
+    if (!mAllowComments && node->IsComment()) {
       node->RemoveFromParent();
     }
     node = next;
   }
 }
 
 void
 nsTreeSanitizer::RemoveAllAttributes(Element* aElement)
--- a/dom/base/nsTreeSanitizer.h
+++ b/dom/base/nsTreeSanitizer.h
@@ -25,22 +25,20 @@ class MOZ_STACK_CLASS nsTreeSanitizer {
      */
     explicit nsTreeSanitizer(uint32_t aFlags = 0);
 
     static void InitializeStatics();
     static void ReleaseStatics();
 
     /**
      * Sanitizes a disconnected DOM fragment freshly obtained from a parser.
-     * The argument must be of type nsINode::eDOCUMENT_FRAGMENT and,
-     * consequently, must not be in the document. Furthermore, the fragment
-     * must have just come from a parser so that it can't have mutation
-     * event listeners set on it.
+     * The fragment must have just come from a parser so that it can't have
+     * mutation event listeners set on it.
      */
-    void Sanitize(nsIContent* aFragment);
+    void Sanitize(mozilla::dom::DocumentFragment* aFragment);
 
     /**
      * Sanitizes a disconnected (not in a docshell) document freshly obtained
      * from a parser. The document must not be embedded in a docshell and must
      * not have had a chance to get mutation event listeners attached to it.
      * The root element must be <html>.
      */
     void Sanitize(nsIDocument* aDocument);
--- a/dom/base/nsWindowMemoryReporter.cpp
+++ b/dom/base/nsWindowMemoryReporter.cpp
@@ -730,17 +730,17 @@ nsWindowMemoryReporter::Observe(nsISuppo
   }
 
   return NS_OK;
 }
 
 void
 nsWindowMemoryReporter::ObserveDOMWindowDetached(nsGlobalWindowInner* aWindow)
 {
-  nsWeakPtr weakWindow = do_GetWeakReference(static_cast<nsIDOMEventTarget*>(aWindow));
+  nsWeakPtr weakWindow = do_GetWeakReference(aWindow);
   if (!weakWindow) {
     NS_WARNING("Couldn't take weak reference to a window?");
     return;
   }
 
   mDetachedWindows.Put(weakWindow, TimeStamp());
 
   AsyncCheckForGhostWindows();
--- a/dom/base/nsWindowRoot.cpp
+++ b/dom/base/nsWindowRoot.cpp
@@ -56,19 +56,18 @@ nsWindowRoot::~nsWindowRoot()
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsWindowRoot,
                                       mWindow,
                                       mListenerManager,
                                       mParent)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWindowRoot)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventTarget)
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_INTERFACE_MAP_ENTRY(nsPIWindowRoot)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
   NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsWindowRoot)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsWindowRoot)
 
 bool
 nsWindowRoot::DispatchEvent(Event& aEvent, CallerType aCallerType,
--- a/dom/base/nsWindowRoot.h
+++ b/dom/base/nsWindowRoot.h
@@ -2,35 +2,32 @@
 /* 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 nsWindowRoot_h__
 #define nsWindowRoot_h__
 
-class nsIDOMEvent;
 class nsIGlobalObject;
 
 #include "mozilla/Attributes.h"
 #include "mozilla/EventListenerManager.h"
-#include "nsIDOMEventTarget.h"
 #include "nsIWeakReferenceUtils.h"
 #include "nsPIWindowRoot.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsTHashtable.h"
 #include "nsHashKeys.h"
 
 class nsWindowRoot final : public nsPIWindowRoot
 {
 public:
   explicit nsWindowRoot(nsPIDOMWindowOuter* aWindow);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_NSIDOMEVENTTARGET
 
   virtual mozilla::EventListenerManager*
     GetExistingListenerManager() const override;
   virtual mozilla::EventListenerManager*
     GetOrCreateListenerManager() override;
 
   bool ComputeDefaultWantsUntrusted(mozilla::ErrorResult& aRv) final;
 
@@ -65,18 +62,17 @@ public:
   virtual mozilla::dom::EventTarget* GetParentTarget() override { return mParent; }
   virtual nsPIDOMWindowOuter* GetOwnerGlobalForBindings() override;
   virtual nsIGlobalObject* GetOwnerGlobal() const override;
 
   nsIGlobalObject* GetParentObject();
 
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsWindowRoot,
-                                                         nsIDOMEventTarget)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsWindowRoot)
 
   virtual void AddBrowser(mozilla::dom::TabParent* aBrowser) override;
   virtual void RemoveBrowser(mozilla::dom::TabParent* aBrowser) override;
   virtual void EnumerateBrowsers(BrowserEnumerator aEnumFunc, void *aArg) override;
 
   virtual bool ShowAccelerators() override
   {
     return mShowAccelerators;
--- a/dom/base/nsXMLContentSerializer.cpp
+++ b/dom/base/nsXMLContentSerializer.cpp
@@ -1267,17 +1267,17 @@ nsXMLContentSerializer::MaybeAddNewlineF
   return true;
 }
 
 void
 nsXMLContentSerializer::MaybeFlagNewlineForRootNode(nsINode* aNode)
 {
   nsINode* parent = aNode->GetParentNode();
   if (parent) {
-    mAddNewlineForRootNode = parent->IsNodeOfType(nsINode::eDOCUMENT);
+    mAddNewlineForRootNode = parent->IsDocument();
   }
 }
 
 void
 nsXMLContentSerializer::MaybeEnterInPreContent(nsIContent* aNode)
 {
   // support of the xml:space attribute
   nsAutoString space;
--- a/dom/base/test/chrome/window_swapFrameLoaders.xul
+++ b/dom/base/test/chrome/window_swapFrameLoaders.xul
@@ -2,17 +2,17 @@
 <?xml-stylesheet type="text/css" href="chrome://global/skin"?>
 <?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=1242644
 Test swapFrameLoaders with different frame types and remoteness
 -->
 <window title="Mozilla Bug 1242644"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/AddTask.js"></script>
 
   <script type="application/javascript"><![CDATA[
   ["SimpleTest", "SpecialPowers", "info", "is", "ok"].forEach(key => {
     window[key] = window.opener[key];
   })
 
   const NS = {
     xul: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
--- a/dom/base/test/test_blockParsing.html
+++ b/dom/base/test/test_blockParsing.html
@@ -1,14 +1,14 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>Test for document.blockParsing</title>
   <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
+  <script src="chrome://mochikit/content/tests/SimpleTest/AddTask.js"></script>
   <link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css">
 </head>
 <body>
 <script>
 ChromeUtils.import("resource://testing-common/TestUtils.jsm");
 
 async function runTest(url, initialHTML, finalHTML) {
   let iframe = document.createElement("iframe");
--- a/dom/base/test/test_bug1281963.html
+++ b/dom/base/test/test_bug1281963.html
@@ -2,17 +2,17 @@
 <html>
 <!--
 https://bugzilla.mozilla.org/1281963
 -->
 <head>
   <meta http-equiv="content-type" content="text/html; charset=utf-8">
   <title>Test for Bug 1281963</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <p id="display"></p>
 <div id="content"></div>
 
 <script class="testbody" type="application/javascript">
 
--- a/dom/base/test/test_bug352728.html
+++ b/dom/base/test/test_bug352728.html
@@ -46,17 +46,17 @@ function testCharacterData(aNode, aText)
 
 function testComment(aText)
 {
   try {
     var comment = document.createComment(aText);
     var types = [ Comment, CharacterData, Node ];
     checkTypes(comment, "comment", types);
 
-    var interfaces = [ "nsIDOMNode", "nsIDOMEventTarget" ];
+    var interfaces = [ "nsIDOMNode" ];
     checkInterfaces(comment, "comment", interfaces);
 
     testCharacterData(comment, aText);
     is(comment.nodeName, "#comment", "Check nodeName");
     is(comment.nodeType, Node.COMMENT_NODE, "Check nodeType");
   } catch (e) {
     ok(0, "Correct functioning of comment stuff", "something broke: " + e);
   }
@@ -76,17 +76,17 @@ function testCDATASection(aText, aShould
 
 function testPI(aTarget, aData, aShouldSucceed, aReason)
 {
   try {
     var pi = document.createProcessingInstruction(aTarget, aData);
     var types = [ ProcessingInstruction, Node ];
     checkTypes(pi, "processing instruction", types);
 
-    var interfaces = [ "nsIDOMNode", "nsIDOMEventTarget" ];
+    var interfaces = [ "nsIDOMNode" ];
     checkInterfaces(pi, "processing instruction", interfaces);
 
     is(pi.target, aTarget, "Check target");
     is(pi.data, aData, "Check data");
     is(pi.nodeName, aTarget, "Check nodeName");
     is(pi.nodeValue, aData, "Check nodeValue");
     is(pi.localName, undefined, "Check localName")
     is(pi.namespaceURI, undefined, "Check namespaceURI");
--- a/dom/base/test/test_bug352728.xhtml
+++ b/dom/base/test/test_bug352728.xhtml
@@ -70,17 +70,17 @@ function testCharacterData(aNode, aText)
 
 function testComment(aText)
 {
   try {
     var comment = document.createComment(aText);
     var types = [ Comment, CharacterData, Node ];
     checkTypes(comment, "comment", types);
 
-    var interfaces = [ "nsIDOMNode", "nsIDOMEventTarget" ];
+    var interfaces = [ "nsIDOMNode" ];
     checkInterfaces(comment, "comment", interfaces);
 
     testCharacterData(comment, aText);
     is(comment.nodeName, "#comment", "Check nodeName");
     is(comment.nodeType, Node.COMMENT_NODE, "Check nodeType");
   } catch (e) {
     ok(0, "Correct functioning of comment stuff", "something broke: " + e);
   }
@@ -88,17 +88,17 @@ function testComment(aText)
 
 function testCDATASection(aText, aShouldSucceed)
 {
   try {
     var cdataSection = document.createCDATASection(aText);
     var types = [ CDATASection, CharacterData, Node ];
     checkTypes(cdataSection, "CDATA section", types);
 
-    var interfaces = [ "nsIDOMNode", "nsIDOMEventTarget" ];
+    var interfaces = [ "nsIDOMNode" ];
     checkInterfaces(cdataSection, "CDATA section", interfaces);
 
     testCharacterData(cdataSection, aText);
     is(cdataSection.nodeName, "#cdata-section", "Check nodeName");
     is(cdataSection.nodeType, Node.CDATA_SECTION_NODE, "Check nodeType");
 
     if (!aShouldSucceed) {
       ok(0, "Invalid CDATA section creation",
@@ -119,17 +119,17 @@ function testCDATASection(aText, aShould
 
 function testPI(aTarget, aData, aShouldSucceed, aReason)
 {
   try {
     var pi = document.createProcessingInstruction(aTarget, aData);
     var types = [ ProcessingInstruction, Node ];
     checkTypes(pi, "processing instruction", types);
 
-    var interfaces = [ "nsIDOMNode", "nsIDOMEventTarget" ];
+    var interfaces = [ "nsIDOMNode" ];
     checkInterfaces(pi, "processing instruction", interfaces);
 
     is(pi.target, aTarget, "Check target");
     is(pi.data, aData, "Check data");
     is(pi.nodeName, aTarget, "Check nodeName");
     is(pi.nodeValue, aData, "Check nodeValue");
     is(pi.localName, undefined, "Check localName")
     is(pi.namespaceURI, undefined, "Check namespaceURI");
--- a/dom/base/test/test_copypaste.html
+++ b/dom/base/test/test_copypaste.html
@@ -1,17 +1,17 @@
 <!DOCTYPE HTML>
 <html>
 <!--
 -->
 <head>
   <title>Test for copy/paste</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <script type="text/javascript" src="copypaste.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=524975">Mozilla Bug </a>
 <p id="display"></p>
 <div id="content" style="display: none">
 </div>
--- a/dom/base/test/test_copypaste.xhtml
+++ b/dom/base/test/test_copypaste.xhtml
@@ -11,17 +11,17 @@ This test is different from test_copypas
      elements, and unlike HTML, neither does it produce text/_moz_htmlcontext
      and text/_moz_htmlinfo, which the clipboard converts to text/unicode.
 -->
 <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
 <head>
   <title>Test for copy/paste with XHTML</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="copypaste.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=888839">Mozilla Bug 888839</a>
 <p id="display"></p>
 <div id="content" style="display: none">
 </div>
 <pre id="test">
--- a/dom/base/test/test_explicit_user_agent.html
+++ b/dom/base/test/test_explicit_user_agent.html
@@ -1,14 +1,14 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>Test for XMLHttpRequest.GetResponseHeader(foo) byte-inflates the output</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <meta charset="utf-8">
 </head>
 <body>
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
--- a/dom/base/test/test_fragment_sanitization.xul
+++ b/dom/base/test/test_fragment_sanitization.xul
@@ -2,17 +2,17 @@
 <?xml-stylesheet type="text/css" href="chrome://global/skin"?>
 <?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=1432966
 -->
 <window title="Mozilla Bug 1432966"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"/>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/AddTask.js"/>
 
   <script type="application/javascript"><![CDATA[
 
 const NS_HTML = "http://www.w3.org/1999/xhtml";
 
 function awaitLoad(frame) {
   return new Promise(resolve => {
     frame.addEventListener("load", resolve, {once: true});
--- a/dom/base/test/test_mozbrowser_apis_allowed.html
+++ b/dom/base/test/test_mozbrowser_apis_allowed.html
@@ -1,14 +1,14 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>Verify mozbrowser APIs are allowed with browser permission</title>
   <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/AddTask.js"></script>
   <script type="text/javascript" src="mozbrowser_api_utils.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 </head>
 
 <body>
 <script type="application/javascript">
   add_task(async function() {
     await SpecialPowers.pushPrefEnv(
--- a/dom/base/test/test_mozbrowser_apis_blocked.html
+++ b/dom/base/test/test_mozbrowser_apis_blocked.html
@@ -1,14 +1,14 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>Verify mozbrowser APIs are blocked without browser permission</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <script type="text/javascript" src="mozbrowser_api_utils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 
 <body>
 <script type="application/javascript">
   add_task(async function() {
     await SpecialPowers.pushPrefEnv(
--- a/dom/base/test/test_postMessage_originAttributes.html
+++ b/dom/base/test/test_postMessage_originAttributes.html
@@ -1,14 +1,14 @@
 <!DOCTYPE html>
 <html>
 <head>
   <title>Test window.postMessages from system principal to window with non-default originAttributes</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 
 <body>
 <iframe id="target-iframe"></iframe>
 <script type="application/javascript">
 
 add_task(async function() {
--- a/dom/canvas/ImageBitmap.cpp
+++ b/dom/canvas/ImageBitmap.cpp
@@ -431,19 +431,17 @@ private:
   gfx::SurfaceFormat mFormat;
   gfx::IntSize mSize;
   const Maybe<IntRect>& mCropRect;
 };
 
 static bool
 CheckSecurityForHTMLElements(bool aIsWriteOnly, bool aCORSUsed, nsIPrincipal* aPrincipal)
 {
-  MOZ_ASSERT(aPrincipal);
-
-  if (aIsWriteOnly) {
+  if (aIsWriteOnly || !aPrincipal) {
     return false;
   }
 
   if (!aCORSUsed) {
     nsIGlobalObject* incumbentSettingsObject = GetIncumbentGlobal();
     if (NS_WARN_IF(!incumbentSettingsObject)) {
       return false;
     }
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -35,17 +35,16 @@
 #include "mozilla/ScopeExit.h"
 #include "mozilla/Services.h"
 #include "mozilla/Telemetry.h"
 #include "nsContentUtils.h"
 #include "nsDisplayList.h"
 #include "nsError.h"
 #include "nsIClassInfoImpl.h"
 #include "nsIConsoleService.h"
-#include "nsIDOMEvent.h"
 #include "nsIGfxInfo.h"
 #include "nsIObserverService.h"
 #include "nsIVariant.h"
 #include "nsIWidget.h"
 #include "nsIXPConnect.h"
 #include "nsServiceManagerUtils.h"
 #include "SVGObserverUtils.h"
 #include "prenv.h"
--- a/dom/canvas/WebGLContextUtils.cpp
+++ b/dom/canvas/WebGLContextUtils.cpp
@@ -7,17 +7,16 @@
 #include "WebGLContext.h"
 
 #include "GLContext.h"
 #include "jsapi.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/gfx/Logging.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Sprintf.h"
-#include "nsIDOMEvent.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIVariant.h"
 #include "nsPrintfCString.h"
 #include "nsServiceManagerUtils.h"
 #include <stdarg.h>
 #include "WebGLBuffer.h"
 #include "WebGLExtensions.h"
 #include "WebGLFramebuffer.h"
--- a/dom/credentialmanagement/tests/mochitest/test_credman_iframes.html
+++ b/dom/credentialmanagement/tests/mochitest/test_credman_iframes.html
@@ -1,13 +1,13 @@
 <!DOCTYPE html>
 <head>
   <title>Credential Management: Prohibit use in cross-origin iframes</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <meta charset=utf-8>
 </head>
 <body>
 <h1>Credential Management: Prohibit use in cross-origin iframes</h1>
 <ul>
   <li><a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1407789">Mozilla Bug 1407789</a></li>
 </ul>
--- a/dom/events/AsyncEventDispatcher.cpp
+++ b/dom/events/AsyncEventDispatcher.cpp
@@ -2,20 +2,19 @@
 /* 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 "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/BasicEvents.h"
 #include "mozilla/EventDispatcher.h"
-#include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
+#include "mozilla/dom/Event.h"
 #include "mozilla/dom/EventTarget.h"
 #include "nsContentUtils.h"
-#include "nsIDOMEvent.h"
 
 namespace mozilla {
 
 using namespace dom;
 
 /******************************************************************************
  * mozilla::AsyncEventDispatcher
  ******************************************************************************/
@@ -51,17 +50,17 @@ AsyncEventDispatcher::Run()
   }
   mTarget->AsyncEventRunning(this);
   if (mEventMessage != eUnidentifiedEvent) {
     return nsContentUtils::DispatchTrustedEvent<WidgetEvent>
       (node->OwnerDoc(), mTarget, mEventMessage, mBubbles,
        false /* aCancelable */, nullptr /* aDefaultAction */,
        mOnlyChromeDispatch);
   }
-  RefPtr<Event> event = mEvent ? mEvent->InternalDOMEvent() : nullptr;
+  RefPtr<Event> event = mEvent;
   if (!event) {
     event = NS_NewDOMEvent(mTarget, nullptr, nullptr);
     event->InitEvent(mEventType, mBubbles, false);
     event->SetTrusted(true);
   }
   if (mOnlyChromeDispatch) {
     MOZ_ASSERT(event->IsTrusted());
     event->WidgetEventPtr()->mFlags.mOnlyChromeDispatch = true;
--- a/dom/events/AsyncEventDispatcher.h
+++ b/dom/events/AsyncEventDispatcher.h
@@ -3,19 +3,20 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_AsyncEventDispatcher_h_
 #define mozilla_AsyncEventDispatcher_h_
 
 #include "mozilla/Attributes.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/dom/Event.h"
 #include "nsCOMPtr.h"
 #include "nsIDocument.h"
-#include "nsIDOMEvent.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 
 class nsINode;
 
 namespace mozilla {
 
 /**
@@ -83,17 +84,17 @@ public:
     , mTarget(aTarget)
     , mEventMessage(aEventMessage)
     , mBubbles(aBubbles)
   {
     mEventType.SetIsVoid(true);
     MOZ_ASSERT(mEventMessage != eUnidentifiedEvent);
   }
 
-  AsyncEventDispatcher(dom::EventTarget* aTarget, nsIDOMEvent* aEvent)
+  AsyncEventDispatcher(dom::EventTarget* aTarget, dom::Event* aEvent)
     : CancelableRunnable("AsyncEventDispatcher")
     , mTarget(aTarget)
     , mEvent(aEvent)
     , mEventMessage(eUnidentifiedEvent)
   {
   }
 
   AsyncEventDispatcher(dom::EventTarget* aTarget, WidgetEvent& aEvent);
@@ -104,17 +105,17 @@ public:
   void RunDOMEventWhenSafe();
 
   // Calling this causes the Run() method to check that
   // mTarget->IsInComposedDoc(). mTarget must be an nsINode or else we'll
   // assert.
   void RequireNodeInDocument();
 
   nsCOMPtr<dom::EventTarget> mTarget;
-  nsCOMPtr<nsIDOMEvent> mEvent;
+  RefPtr<dom::Event> mEvent;
   // If mEventType is set, mEventMessage will be eUnidentifiedEvent.
   // If mEventMessage is set, mEventType will be void.
   // They can never both be set at the same time.
   nsString              mEventType;
   mozilla::EventMessage mEventMessage;
   bool                  mBubbles = false;
   bool                  mOnlyChromeDispatch = false;
   bool                  mCanceled = false;
@@ -131,17 +132,17 @@ public:
                            aBubbles, aDispatchChromeOnly)
     , mBlockedDoc(aEventNode->OwnerDoc())
   {
     if (mBlockedDoc) {
       mBlockedDoc->BlockOnload();
     }
   }
 
-  LoadBlockingAsyncEventDispatcher(nsINode* aEventNode, nsIDOMEvent* aEvent)
+  LoadBlockingAsyncEventDispatcher(nsINode* aEventNode, dom::Event* aEvent)
     : AsyncEventDispatcher(aEventNode, aEvent)
     , mBlockedDoc(aEventNode->OwnerDoc())
   {
     if (mBlockedDoc) {
       mBlockedDoc->BlockOnload();
     }
   }
 
--- a/dom/events/DOMEventTargetHelper.cpp
+++ b/dom/events/DOMEventTargetHelper.cpp
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsContentUtils.h"
 #include "nsIDocument.h"
 #include "mozilla/Sprintf.h"
 #include "nsGlobalWindow.h"
+#include "mozilla/dom/Event.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/Likely.h"
 
 namespace mozilla {
 
@@ -71,17 +72,16 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(DOMEventTargetHelper)
   return tmp->HasKnownLiveWrapper();
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMEventTargetHelper)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
   NS_INTERFACE_MAP_ENTRY(dom::EventTarget)
   NS_INTERFACE_MAP_ENTRY(DOMEventTargetHelper)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMEventTargetHelper)
 NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE(DOMEventTargetHelper,
                                                    LastRelease())
 
@@ -195,22 +195,22 @@ DOMEventTargetHelper::DispatchTrustedEve
 {
   RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
   event->InitEvent(aEventName, false, false);
 
   return DispatchTrustedEvent(event);
 }
 
 nsresult
-DOMEventTargetHelper::DispatchTrustedEvent(nsIDOMEvent* event)
+DOMEventTargetHelper::DispatchTrustedEvent(Event* event)
 {
   event->SetTrusted(true);
 
   ErrorResult rv;
-  DispatchEvent(*event->InternalDOMEvent(), rv);
+  DispatchEvent(*event, rv);
   return rv.StealNSResult();
 }
 
 void
 DOMEventTargetHelper::GetEventTargetParent(EventChainPreVisitor& aVisitor)
 {
   aVisitor.mCanHandle = true;
   aVisitor.SetParentTarget(nullptr, false);
--- a/dom/events/DOMEventTargetHelper.h
+++ b/dom/events/DOMEventTargetHelper.h
@@ -21,16 +21,20 @@
 
 struct JSCompartment;
 class nsIDocument;
 
 namespace mozilla {
 
 class ErrorResult;
 
+namespace dom {
+class Event;
+} // namespace dom
+
 #define NS_DOMEVENTTARGETHELPER_IID \
 { 0xa28385c6, 0x9451, 0x4d7e, \
   { 0xa3, 0xdd, 0xf4, 0xb6, 0x87, 0x2f, 0xa4, 0x76 } }
 
 class DOMEventTargetHelper : public dom::EventTarget
 {
 public:
   DOMEventTargetHelper()
@@ -75,18 +79,16 @@ public:
     }
     BindToOwnerInternal(aOther->GetParentObject());
     mHasOrHasHadOwnerWindow = aOther->HasOrHasHadOwner();
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(DOMEventTargetHelper)
 
-  NS_DECL_NSIDOMEVENTTARGET
-
   virtual EventListenerManager* GetExistingListenerManager() const override;
   virtual EventListenerManager* GetOrCreateListenerManager() override;
 
   bool ComputeDefaultWantsUntrusted(ErrorResult& aRv) override;
 
   using EventTarget::DispatchEvent;
   bool DispatchEvent(dom::Event& aEvent, dom::CallerType aCallerType,
                      ErrorResult& aRv) override;
@@ -197,17 +199,17 @@ protected:
   // NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN macro.
   virtual bool IsCertainlyAliveForCC() const
   {
     return mIsKeptAlive;
   }
 
   RefPtr<EventListenerManager> mListenerManager;
   // Make |event| trusted and dispatch |aEvent| to |this|.
-  nsresult DispatchTrustedEvent(nsIDOMEvent* aEvent);
+  nsresult DispatchTrustedEvent(dom::Event* aEvent);
 
   virtual void LastRelease() {}
 
   void KeepAliveIfHasListenersFor(const nsAString& aType);
   void KeepAliveIfHasListenersFor(nsAtom* aType);
 
   void IgnoreKeepAliveIfHasListenersFor(const nsAString& aType);
   void IgnoreKeepAliveIfHasListenersFor(nsAtom* aType);
--- a/dom/events/DataTransferItem.cpp
+++ b/dom/events/DataTransferItem.cpp
@@ -321,20 +321,19 @@ DataTransferItem::GetAsEntry(nsIPrincipa
 
   nsCOMPtr<nsIGlobalObject> global;
   // This is annoying, but DataTransfer may have various things as parent.
   nsCOMPtr<EventTarget> target =
     do_QueryInterface(mDataTransfer->GetParentObject());
   if (target) {
     global = target->GetOwnerGlobal();
   } else {
-    nsCOMPtr<nsIDOMEvent> event =
-      do_QueryInterface(mDataTransfer->GetParentObject());
+    RefPtr<Event> event = do_QueryObject(mDataTransfer->GetParentObject());
     if (event) {
-      global = event->InternalDOMEvent()->GetParentObject();
+      global = event->GetParentObject();
     }
   }
 
   if (!global) {
     return nullptr;
   }
 
   RefPtr<FileSystem> fs = FileSystem::Create(global);
@@ -464,18 +463,18 @@ DataTransferItem::GetAsString(FunctionSt
 
   // DataTransfer.mParent might be EventTarget, nsIGlobalObject, ClipboardEvent
   // nsPIDOMWindowOuter, null
   nsISupports* parent = mDataTransfer->GetParentObject();
   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(parent);
   if (parent && !global) {
     if (nsCOMPtr<dom::EventTarget> target = do_QueryInterface(parent)) {
       global = target->GetOwnerGlobal();
-    } else if (nsCOMPtr<nsIDOMEvent> event = do_QueryInterface(parent)) {
-      global = event->InternalDOMEvent()->GetParentObject();
+    } else if (RefPtr<Event> event = do_QueryObject(parent)) {
+      global = event->GetParentObject();
     }
   }
   if (global) {
     rv = global->Dispatch(TaskCategory::Other, runnable.forget());
   } else {
     rv = NS_DispatchToMainThread(runnable);
   }
   if (NS_FAILED(rv)) {
--- a/dom/events/Event.cpp
+++ b/dom/events/Event.cpp
@@ -132,17 +132,17 @@ Event::~Event()
   if (mEventIsInternal && mEvent) {
     delete mEvent;
   }
 }
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Event)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMEvent)
+  NS_INTERFACE_MAP_ENTRY(Event)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(Event)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(Event)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(Event)
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Event)
@@ -217,41 +217,32 @@ Event::WrapObject(JSContext* aCx, JS::Ha
 }
 
 JSObject*
 Event::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return EventBinding::Wrap(aCx, this, aGivenProto);
 }
 
-// nsIDOMEventInterface
-NS_IMETHODIMP
-Event::GetType(nsAString& aType)
+void
+Event::GetType(nsAString& aType) const
 {
   if (!mIsMainThreadEvent) {
     aType = mEvent->mSpecifiedEventTypeString;
-    return NS_OK;
+    return;
   }
   GetWidgetEventType(mEvent, aType);
-  return NS_OK;
 }
 
 EventTarget*
 Event::GetTarget() const
 {
   return mEvent->GetDOMEventTarget();
 }
 
-NS_IMETHODIMP
-Event::GetTarget(nsIDOMEventTarget** aTarget)
-{
-  NS_IF_ADDREF(*aTarget = GetTarget());
-  return NS_OK;
-}
-
 bool
 Event::IsSrcElementEnabled(JSContext* /* unused */, JSObject* /* unused */)
 {
   // Not a pref, because that's a pain on workers.
 #ifdef NIGHTLY_BUILD
   return true;
 #else
   return false;
@@ -265,23 +256,16 @@ Event::GetCurrentTarget() const
 }
 
 void
 Event::ComposedPath(nsTArray<RefPtr<EventTarget>>& aPath)
 {
   EventDispatcher::GetComposedPathFor(mEvent, aPath);
 }
 
-NS_IMETHODIMP
-Event::GetCurrentTarget(nsIDOMEventTarget** aCurrentTarget)
-{
-  NS_IF_ADDREF(*aCurrentTarget = GetCurrentTarget());
-  return NS_OK;
-}
-
 //
 // Get the actual event target node (may have been retargeted for mouse events)
 //
 already_AddRefed<nsIContent>
 Event::GetTargetFromFrame()
 {
   if (!mPresContext) { return nullptr; }
 
@@ -299,51 +283,37 @@ EventTarget*
 Event::GetExplicitOriginalTarget() const
 {
   if (mExplicitOriginalTarget) {
     return mExplicitOriginalTarget;
   }
   return GetTarget();
 }
 
-NS_IMETHODIMP
-Event::GetExplicitOriginalTarget(nsIDOMEventTarget** aRealEventTarget)
-{
-  NS_IF_ADDREF(*aRealEventTarget = GetExplicitOriginalTarget());
-  return NS_OK;
-}
-
 EventTarget*
 Event::GetOriginalTarget() const
 {
   return mEvent->GetOriginalDOMEventTarget();
 }
 
-NS_IMETHODIMP
-Event::GetOriginalTarget(nsIDOMEventTarget** aOriginalTarget)
-{
-  NS_IF_ADDREF(*aOriginalTarget = GetOriginalTarget());
-  return NS_OK;
-}
-
 EventTarget*
 Event::GetComposedTarget() const
 {
   EventTarget* et = GetOriginalTarget();
   nsCOMPtr<nsIContent> content = do_QueryInterface(et);
   if (!content) {
     return et;
   }
   nsIContent* nonChrome = content->FindFirstNonChromeOnlyAccessContent();
   return nonChrome ?
     static_cast<EventTarget*>(nonChrome) :
     static_cast<EventTarget*>(content->GetComposedDoc());
 }
 
-NS_IMETHODIMP_(void)
+void
 Event::SetTrusted(bool aTrusted)
 {
   mEvent->mFlags.mIsTrusted = aTrusted;
 }
 
 bool
 Event::Init(mozilla::dom::EventTarget* aGlobal)
 {
@@ -393,90 +363,51 @@ Event::Constructor(EventTarget* aEventTa
 uint16_t
 Event::EventPhase() const
 {
   // Note, remember to check that this works also
   // if or when Bug 235441 is fixed.
   if ((mEvent->mCurrentTarget &&
        mEvent->mCurrentTarget == mEvent->mTarget) ||
        mEvent->mFlags.InTargetPhase()) {
-    return nsIDOMEvent::AT_TARGET;
+    return EventBinding::AT_TARGET;
   }
   if (mEvent->mFlags.mInCapturePhase) {
-    return nsIDOMEvent::CAPTURING_PHASE;
+    return EventBinding::CAPTURING_PHASE;
   }
   if (mEvent->mFlags.mInBubblingPhase) {
-    return nsIDOMEvent::BUBBLING_PHASE;
+    return EventBinding::BUBBLING_PHASE;
   }
-  return nsIDOMEvent::NONE;
-}
-
-NS_IMETHODIMP
-Event::GetEventPhase(uint16_t* aEventPhase)
-{
-  *aEventPhase = EventPhase();
-  return NS_OK;
+  return EventBinding::NONE;
 }
 
-NS_IMETHODIMP
-Event::GetBubbles(bool* aBubbles)
-{
-  *aBubbles = Bubbles();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-Event::GetCancelable(bool* aCancelable)
-{
-  *aCancelable = Cancelable();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-Event::GetTimeStamp(uint64_t* aTimeStamp)
-{
-  *aTimeStamp = mEvent->mTime;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
+void
 Event::StopPropagation()
 {
   mEvent->StopPropagation();
-  return NS_OK;
 }
 
-NS_IMETHODIMP
+void
 Event::StopImmediatePropagation()
 {
   mEvent->StopImmediatePropagation();
-  return NS_OK;
 }
 
-NS_IMETHODIMP
+void
 Event::StopCrossProcessForwarding()
 {
   mEvent->StopCrossProcessForwarding();
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-Event::GetIsTrusted(bool* aIsTrusted)
-{
-  *aIsTrusted = IsTrusted();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
+void
 Event::PreventDefault()
 {
   // This method is called only from C++ code which must handle default action
   // of this event.  So, pass true always.
   PreventDefaultInternal(true);
-  return NS_OK;
 }
 
 void
 Event::PreventDefault(JSContext* aCx, CallerType aCallerType)
 {
   // Note that at handling default action, another event may be dispatched.
   // Then, JS in content mey be call preventDefault()
   // even in the event is in system event group.  Therefore, don't refer
@@ -598,57 +529,48 @@ Event::InitEvent(const nsAString& aEvent
   mEvent->mFlags.mImmediatePropagationStopped = false;
 
   // Clearing the old targets, so that the event is targeted correctly when
   // re-dispatching it.
   mEvent->mTarget = nullptr;
   mEvent->mOriginalTarget = nullptr;
 }
 
-NS_IMETHODIMP
+void
 Event::DuplicatePrivateData()
 {
   NS_ASSERTION(mEvent, "No WidgetEvent for Event duplication!");
   if (mEventIsInternal) {
-    return NS_OK;
+    return;
   }
 
   mEvent = mEvent->Duplicate();
   mPresContext = nullptr;
   mEventIsInternal = true;
   mPrivateDataDuplicated = true;
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-Event::SetTarget(nsIDOMEventTarget* aTarget)
+void
+Event::SetTarget(EventTarget* aTarget)
 {
-  mEvent->mTarget = do_QueryInterface(aTarget);
-  return NS_OK;
+  mEvent->mTarget = aTarget;
 }
 
-NS_IMETHODIMP_(bool)
+bool
 Event::IsDispatchStopped()
 {
   return mEvent->PropagationStopped();
 }
 
-NS_IMETHODIMP_(WidgetEvent*)
+WidgetEvent*
 Event::WidgetEventPtr()
 {
   return mEvent;
 }
 
-NS_IMETHODIMP_(Event*)
-Event::InternalDOMEvent()
-{
-  return this;
-}
-
 // return true if eventName is contained within events, delimited by
 // spaces
 static bool
 PopupAllowedForEvent(const char *eventName)
 {
   if (!sPopupAllowedEvents) {
     Event::PopupAllowedEventsChanged();
 
@@ -681,23 +603,23 @@ PopupAllowedForEvent(const char *eventNa
     startiter = enditer;
   }
 
   return false;
 }
 
 // static
 PopupControlState
-Event::GetEventPopupControlState(WidgetEvent* aEvent, nsIDOMEvent* aDOMEvent)
+Event::GetEventPopupControlState(WidgetEvent* aEvent, Event* aDOMEvent)
 {
   // generally if an event handler is running, new windows are disallowed.
   // check for exceptions:
   PopupControlState abuse = openAbused;
 
-  if (aDOMEvent && aDOMEvent->InternalDOMEvent()->GetWantsPopupControlCheck()) {
+  if (aDOMEvent && aDOMEvent->GetWantsPopupControlCheck()) {
     nsAutoString type;
     aDOMEvent->GetType(type);
     if (PopupAllowedForEvent(NS_ConvertUTF16toUTF8(type).get())) {
       return openAllowed;
     }
   }
 
   switch(aEvent->mClass) {
@@ -1141,28 +1063,17 @@ Event::TimeStamp()
   double ret = workerPrivate->TimeStampToDOMHighRes(mEvent->mTimeStamp);
   if (workerPrivate->UsesSystemPrincipal())
     return ret;
 
   return nsRFPService::ReduceTimePrecisionAsMSecs(ret,
     workerPrivate->GetRandomTimelineSeed());
 }
 
-NS_IMETHODIMP
-Event::GetDefaultPrevented(bool* aReturn)
-{
-  NS_ENSURE_ARG_POINTER(aReturn);
-  // This method must be called by only event handlers implemented by C++.
-  // Then, the handlers must handle default action.  So, this method don't need
-  // to check if preventDefault() has been called by content or chrome.
-  *aReturn = DefaultPrevented();
-  return NS_OK;
-}
-
-NS_IMETHODIMP_(void)
+void
 Event::Serialize(IPC::Message* aMsg, bool aSerializeInterfaceType)
 {
   if (aSerializeInterfaceType) {
     IPC::WriteParam(aMsg, NS_LITERAL_STRING("event"));
   }
 
   nsString type;
   GetType(type);
@@ -1171,17 +1082,17 @@ Event::Serialize(IPC::Message* aMsg, boo
   IPC::WriteParam(aMsg, Bubbles());
   IPC::WriteParam(aMsg, Cancelable());
   IPC::WriteParam(aMsg, IsTrusted());
   IPC::WriteParam(aMsg, Composed());
 
   // No timestamp serialization for now!
 }
 
-NS_IMETHODIMP_(bool)
+bool
 Event::Deserialize(const IPC::Message* aMsg, PickleIterator* aIter)
 {
   nsString type;
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &type), false);
 
   bool bubbles = false;
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &bubbles), false);
 
@@ -1196,17 +1107,17 @@ Event::Deserialize(const IPC::Message* a
 
   InitEvent(type, bubbles, cancelable);
   SetTrusted(trusted);
   SetComposed(composed);
 
   return true;
 }
 
-NS_IMETHODIMP_(void)
+void
 Event::SetOwner(EventTarget* aOwner)
 {
   mOwner = nullptr;
 
   if (!aOwner) {
     return;
   }
 
@@ -1253,33 +1164,16 @@ Event::GetWidgetEventType(WidgetEvent* a
     aType = Substring(nsDependentAtomString(aEvent->mSpecifiedEventType), 2);
     aEvent->mSpecifiedEventTypeString = aType;
     return;
   }
 
   aType.Truncate();
 }
 
-NS_IMETHODIMP
-Event::GetCancelBubble(bool* aCancelBubble)
-{
-  NS_ENSURE_ARG_POINTER(aCancelBubble);
-  *aCancelBubble = CancelBubble();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-Event::SetCancelBubble(bool aCancelBubble)
-{
-  if (aCancelBubble) {
-    mEvent->StopPropagation();
-  }
-  return NS_OK;
-}
-
 } // namespace dom
 } // namespace mozilla
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 already_AddRefed<Event>
 NS_NewDOMEvent(EventTarget* aOwner,
--- a/dom/events/Event.h
+++ b/dom/events/Event.h
@@ -4,32 +4,35 @@
  * 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_Event_h_
 #define mozilla_dom_Event_h_
 
 #include "mozilla/Attributes.h"
 #include "mozilla/BasicEvents.h"
-#include "nsIDOMEvent.h"
 #include "nsISupports.h"
 #include "nsCOMPtr.h"
 #include "nsPIDOMWindow.h"
 #include "nsPoint.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/EventBinding.h"
 #include "nsIScriptGlobalObject.h"
 #include "Units.h"
 #include "js/TypeDecls.h"
 #include "nsIGlobalObject.h"
 
 class nsIContent;
-class nsIDOMEventTarget;
 class nsPresContext;
+class PickleIterator;
+
+namespace IPC {
+class Message;
+} // namespace IPC
 
 namespace mozilla {
 namespace dom {
 
 class BeforeUnloadEvent;
 class CustomEvent;
 class DragEvent;
 class EventTarget;
@@ -42,52 +45,41 @@ class MouseEvent;
 class TimeEvent;
 class UIEvent;
 class WantsPopupControlCheck;
 class XULCommandEvent;
 #define GENERATED_EVENT(EventClass_) class EventClass_;
 #include "mozilla/dom/GeneratedEventList.h"
 #undef GENERATED_EVENT
 
-class Event : public nsIDOMEvent,
-              public nsWrapperCache
+// IID for Event
+#define NS_EVENT_IID                                            \
+  { 0x71139716, 0x4d91, 0x4dee,                                 \
+      { 0xba, 0xf9, 0xe3, 0x3b, 0x80, 0xc1, 0x61, 0x61 } }
+
+class Event : public nsISupports
+            , public nsWrapperCache
 {
 public:
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_EVENT_IID)
+
   Event(EventTarget* aOwner,
         nsPresContext* aPresContext,
         WidgetEvent* aEvent);
   explicit Event(nsPIDOMWindowInner* aWindow);
 
 protected:
   virtual ~Event();
 
 private:
   void ConstructorInit(EventTarget* aOwner,
                        nsPresContext* aPresContext,
                        WidgetEvent* aEvent);
 
 public:
-  static Event* FromSupports(nsISupports* aSupports)
-  {
-    nsIDOMEvent* event =
-      static_cast<nsIDOMEvent*>(aSupports);
-#ifdef DEBUG
-    {
-      nsCOMPtr<nsIDOMEvent> target_qi =
-        do_QueryInterface(aSupports);
-
-      // If this assertion fires the QI implementation for the object in
-      // question doesn't use the nsIDOMEvent pointer as the
-      // nsISupports pointer. That must be fixed, or we'll crash...
-      MOZ_ASSERT(target_qi == event, "Uh, fix QI!");
-    }
-#endif
-    return static_cast<Event*>(event);
-  }
-
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Event)
 
   nsIGlobalObject* GetParentObject()
   {
     return mOwner;
   }
 
@@ -150,26 +142,36 @@ public:
   }
 
   // CustomEvent has a non-autogeneratable initCustomEvent.
   virtual CustomEvent* AsCustomEvent()
   {
     return nullptr;
   }
 
-  // nsIDOMEvent Interface
-  NS_DECL_NSIDOMEVENT
+  void InitEvent(const nsAString& aEventTypeArg,
+                 bool aCanBubbleArg,
+                 bool aCancelableArg);
+  void SetTarget(EventTarget* aTarget);
+  virtual void DuplicatePrivateData();
+  bool IsDispatchStopped();
+  WidgetEvent* WidgetEventPtr();
+  virtual void Serialize(IPC::Message* aMsg, bool aSerializeInterfaceType);
+  virtual bool Deserialize(const IPC::Message* aMsg, PickleIterator* aIter);
+  void SetOwner(EventTarget* aOwner);
+  void StopCrossProcessForwarding();
+  void SetTrusted(bool aTrusted);
 
   void InitPresContextData(nsPresContext* aPresContext);
 
   // Returns true if the event should be trusted.
   bool Init(EventTarget* aGlobal);
 
   static PopupControlState GetEventPopupControlState(WidgetEvent* aEvent,
-                                                     nsIDOMEvent* aDOMEvent = nullptr);
+                                                     Event* aDOMEvent = nullptr);
 
   static void PopupAllowedEventsChanged();
 
   static void Shutdown();
 
   static const char* GetEventName(EventMessage aEventType);
   static CSSIntPoint GetClientCoords(nsPresContext* aPresContext,
                                      WidgetEvent* aEvent,
@@ -191,32 +193,29 @@ public:
                                              const nsAString& aType,
                                              const EventInit& aParam);
 
   static already_AddRefed<Event> Constructor(const GlobalObject& aGlobal,
                                              const nsAString& aType,
                                              const EventInit& aParam,
                                              ErrorResult& aRv);
 
-  // Implemented as xpidl method
-  // void GetType(nsString& aRetval) {}
+  void GetType(nsAString& aType) const;
 
   EventTarget* GetTarget() const;
   static bool IsSrcElementEnabled(JSContext* /* unused */, JSObject* /* unused */);
   EventTarget* GetCurrentTarget() const;
 
   void ComposedPath(nsTArray<RefPtr<EventTarget>>& aPath);
 
   uint16_t EventPhase() const;
 
-  // xpidl implementation
-  // void StopPropagation();
+  void StopPropagation();
 
-  // xpidl implementation
-  // void StopImmediatePropagation();
+  void StopImmediatePropagation();
 
   bool Bubbles() const
   {
     return mEvent->mFlags.mBubbles;
   }
 
   bool Cancelable() const
   {
@@ -227,19 +226,25 @@ public:
   {
     return mEvent->mFlags.mComposed;
   }
 
   bool CancelBubble() const
   {
     return mEvent->PropagationStopped();
   }
+  void SetCancelBubble(bool aCancelBubble)
+  {
+    if (aCancelBubble)  {
+      mEvent->StopPropagation();
+    }
+  }
 
-  // xpidl implementation
-  // void PreventDefault();
+  // For C++ consumers only!
+  void PreventDefault();
 
   // You MUST NOT call PreventDefault(JSContext*, CallerType) from C++ code.  A
   // call of this method always sets Event.defaultPrevented true for web
   // contents.  If default action handler calls this, web applications see wrong
   // defaultPrevented value.
   virtual void PreventDefault(JSContext* aCx, CallerType aCallerType);
 
   // You MUST NOT call DefaultPrevented(CallerType) from C++ code.  This may
@@ -353,24 +358,24 @@ protected:
 /**
  * RAII helper-class to override an event's message (i.e. its DOM-exposed
  * type), for as long as the object is alive.  Restores the original
  * EventMessage when destructed.
  *
  * Notable requirements:
  *  - The original & overriding messages must be known (not eUnidentifiedEvent).
  *  - The original & overriding messages must be different.
- *  - The passed-in nsIDOMEvent must outlive this RAII helper.
+ *  - The passed-in Event must outlive this RAII helper.
  */
 class MOZ_RAII EventMessageAutoOverride
 {
 public:
-  explicit EventMessageAutoOverride(nsIDOMEvent* aEvent,
+  explicit EventMessageAutoOverride(Event* aEvent,
                                     EventMessage aOverridingMessage)
-    : mEvent(aEvent->InternalDOMEvent()),
+    : mEvent(aEvent),
       mOrigMessage(mEvent->mEvent->mMessage)
   {
     MOZ_ASSERT(aOverridingMessage != mOrigMessage,
                "Don't use this class if you're not actually overriding");
     MOZ_ASSERT(aOverridingMessage != eUnidentifiedEvent,
                "Only use this class with a valid overriding EventMessage");
     MOZ_ASSERT(mOrigMessage != eUnidentifiedEvent &&
                mEvent->mEvent->mSpecifiedEventTypeString.IsEmpty(),
@@ -390,46 +395,36 @@ protected:
   // with limited lifetime. Whoever creates us should keep mEvent alive.
   Event* const MOZ_NON_OWNING_REF mEvent;
   const EventMessage mOrigMessage;
 };
 
 class MOZ_STACK_CLASS WantsPopupControlCheck
 {
 public:
-  explicit WantsPopupControlCheck(nsIDOMEvent* aEvent) :
-    mEvent(aEvent->InternalDOMEvent())
+  explicit WantsPopupControlCheck(Event* aEvent) :
+    mEvent(aEvent)
   {
     mOriginalWantsPopupControlCheck = mEvent->GetWantsPopupControlCheck();
     mEvent->SetWantsPopupControlCheck(mEvent->IsTrusted());
   }
 
   ~WantsPopupControlCheck()
   {
     mEvent->SetWantsPopupControlCheck(mOriginalWantsPopupControlCheck);
   }
 
 private:
   Event* mEvent;
   bool mOriginalWantsPopupControlCheck;
 };
 
+NS_DEFINE_STATIC_IID_ACCESSOR(Event, NS_EVENT_IID)
+
 } // namespace dom
 } // namespace mozilla