Backed out 6 changesets (bug 989198, bug 1082963) for causing bug 1083231.
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 16 Oct 2014 12:57:18 -0400
changeset 235078 3a53ee57c736e74a9a8d3f716ecc5aa2c062108f
parent 235077 f2409cd604c455345cd70c808b548c4feb906aba
child 235079 450728938eb2f9af60589bde6fabe4fbd87264c5
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs989198, 1082963, 1083231
milestone36.0a1
backs outa7c9724075780ad36da5fc35bf4d4d45d119f21b
94d1b30bde0022bc8c79e5b1b0128e121b579b1b
01e064ceb505c6b15251f846f719bb8e4ebf7487
f5a538109e367708626eccba5584f8ac2d87e88a
3ff227d79d74d1a0ce0d57a999f8395838d47db7
186743fc6f6d388ddbf02e2bdf9402dbd6acff77
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
Backed out 6 changesets (bug 989198, bug 1082963) for causing bug 1083231. Backed out changeset a7c972407578 (bug 1082963) Backed out changeset 94d1b30bde00 (bug 989198) Backed out changeset 01e064ceb505 (bug 989198) Backed out changeset f5a538109e36 (bug 989198) Backed out changeset 3ff227d79d74 (bug 989198) Backed out changeset 186743fc6f6d (bug 989198) CLOSED TREE
b2g/app/b2g.js
b2g/chrome/content/shell.js
content/base/src/nsGkAtomList.h
dom/apps/PermissionsTable.jsm
dom/events/BeforeAfterKeyboardEvent.cpp
dom/events/BeforeAfterKeyboardEvent.h
dom/events/EventDispatcher.cpp
dom/events/EventNameList.h
dom/events/EventStateManager.cpp
dom/events/KeyboardEvent.cpp
dom/events/KeyboardEvent.h
dom/events/moz.build
dom/events/test/bug989198_embedded.html
dom/events/test/bug989198_helper.js
dom/events/test/mochitest.ini
dom/events/test/test_all_synthetic_events.html
dom/events/test/test_dom_before_after_keyboard_event.html
dom/events/test/test_dom_before_after_keyboard_event_remote.html
dom/interfaces/events/nsIDOMEvent.idl
dom/ipc/PBrowser.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
dom/tests/mochitest/general/test_interfaces.html
dom/webidl/BeforeAfterKeyboardEvent.webidl
dom/webidl/moz.build
layout/base/nsIPresShell.h
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
modules/libpref/init/all.js
testing/mochitest/manifest.webapp
widget/BasicEvents.h
widget/EventClassList.h
widget/TextEvents.h
widget/nsGUIEventIPC.h
widget/shared/WidgetEventImpl.cpp
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -783,19 +783,16 @@ pref("dom.ipc.reuse_parent_app", false);
 // When a process receives a system message, we hold a CPU wake lock on its
 // behalf for this many seconds, or until it handles the system message,
 // whichever comes first.
 pref("dom.ipc.systemMessageCPULockTimeoutSec", 30);
 
 // Ignore the "dialog=1" feature in window.open.
 pref("dom.disable_window_open_dialog_feature", true);
 
-// Enable before keyboard events and after keyboard events.
-pref("dom.beforeAfterKeyboardEvent.enabled", true);
-
 // Screen reader support
 pref("accessibility.accessfu.activate", 2);
 pref("accessibility.accessfu.quicknav_modes", "Link,Heading,FormElement,Landmark,ListItem");
 // Active quicknav mode, index value of list from quicknav_modes
 pref("accessibility.accessfu.quicknav_index", 0);
 // Setting for an utterance order (0 - description first, 1 - description last).
 pref("accessibility.accessfu.utterance", 1);
 // Whether to skip images with empty alt text
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -319,18 +319,16 @@ var shell = {
     // Capture all key events so we can filter out hardware buttons
     // And send them to Gaia via mozChromeEvents.
     // Ideally, hardware buttons wouldn't generate key events at all, or
     // if they did, they would use keycodes that conform to DOM 3 Events.
     // See discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=762362
     chromeEventHandler.addEventListener('keydown', this, true);
     chromeEventHandler.addEventListener('keypress', this, true);
     chromeEventHandler.addEventListener('keyup', this, true);
-    chromeEventHandler.addEventListener('mozbrowserbeforekeydown', this, true);
-    chromeEventHandler.addEventListener('mozbrowserbeforekeyup', this, true);
 
     window.addEventListener('MozApplicationManifest', this);
     window.addEventListener('mozfullscreenchange', this);
     window.addEventListener('MozAfterPaint', this);
     window.addEventListener('sizemodechange', this);
     window.addEventListener('unload', this);
     this.contentBrowser.addEventListener('mozbrowserloadstart', this, true);
     this.contentBrowser.addEventListener('mozbrowserselectionchange', this, true);
@@ -353,18 +351,16 @@ var shell = {
     ppmm.addMessageListener("file-picker", this);
   },
 
   stop: function shell_stop() {
     window.removeEventListener('unload', this);
     window.removeEventListener('keydown', this, true);
     window.removeEventListener('keypress', this, true);
     window.removeEventListener('keyup', this, true);
-    window.removeEventListener('mozbrowserbeforekeydown', this, true);
-    window.removeEventListener('mozbrowserbeforekeyup', this, true);
     window.removeEventListener('MozApplicationManifest', this);
     window.removeEventListener('mozfullscreenchange', this);
     window.removeEventListener('sizemodechange', this);
     this.contentBrowser.removeEventListener('mozbrowserloadstart', this, true);
     this.contentBrowser.removeEventListener('mozbrowserselectionchange', this, true);
     this.contentBrowser.removeEventListener('mozbrowserscrollviewchange', this, true);
     this.contentBrowser.removeEventListener('mozbrowsertouchcarettap', this, true);
     ppmm.removeMessageListener("content-handler", this);
@@ -419,24 +415,27 @@ var shell = {
       isMediaKey = true;
       type = mediaKeys[evt.key];
     }
 
     if (!type) {
       return;
     }
 
+    // If we didn't return, then the key event represents a hardware key
+    // and we need to prevent it from propagating to Gaia
+    evt.stopImmediatePropagation();
+    evt.preventDefault(); // Prevent keypress events (when #501496 is fixed).
+
     // If it is a key down or key up event, we send a chrome event to Gaia.
     // If it is a keypress event we just ignore it.
     switch (evt.type) {
-      case 'mozbrowserbeforekeydown':
       case 'keydown':
         type = type + '-press';
         break;
-      case 'mozbrowserbeforekeyup':
       case 'keyup':
         type = type + '-release';
         break;
       case 'keypress':
         return;
     }
 
     // Let applications receive the headset button key press/release event.
@@ -469,18 +468,16 @@ var shell = {
   visibleNormalAudioActive: false,
 
   handleEvent: function shell_handleEvent(evt) {
     let content = this.contentBrowser.contentWindow;
     switch (evt.type) {
       case 'keydown':
       case 'keyup':
       case 'keypress':
-      case 'mozbrowserbeforekeydown':
-      case 'mozbrowserbeforekeyup':
         this.filterHardwareKeys(evt);
         break;
       case 'mozfullscreenchange':
         // When the screen goes fullscreen make sure to set the focus to the
         // main window so noboby can prevent the ESC key to get out fullscreen
         // mode
         if (document.mozFullScreen)
           Services.fm.focusedWindow = window;
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -789,20 +789,16 @@ GK_ATOM(onmousedown, "onmousedown")
 GK_ATOM(onmouseenter, "onmouseenter")
 GK_ATOM(onmouseleave, "onmouseleave")
 GK_ATOM(onmousemove, "onmousemove")
 GK_ATOM(onmouseout, "onmouseout")
 GK_ATOM(onmouseover, "onmouseover")
 GK_ATOM(onMozMouseHittest, "onMozMouseHittest")
 GK_ATOM(onmouseup, "onmouseup")
 GK_ATOM(onMozAfterPaint, "onMozAfterPaint")
-GK_ATOM(onmozbrowserafterkeydown, "onmozbrowserafterkeydown")
-GK_ATOM(onmozbrowserafterkeyup, "onmozbrowserafterkeyup")
-GK_ATOM(onmozbrowserbeforekeydown, "onmozbrowserbeforekeydown")
-GK_ATOM(onmozbrowserbeforekeyup, "onmozbrowserbeforekeyup")
 GK_ATOM(onmozfullscreenchange, "onmozfullscreenchange")
 GK_ATOM(onmozfullscreenerror, "onmozfullscreenerror")
 GK_ATOM(onmozpointerlockchange, "onmozpointerlockchange")
 GK_ATOM(onmozpointerlockerror, "onmozpointerlockerror")
 GK_ATOM(onmoztimechange, "onmoztimechange")
 GK_ATOM(onMozMousePixelScroll, "onMozMousePixelScroll")
 GK_ATOM(onMozScrolledAreaChanged, "onMozScrolledAreaChanged")
 GK_ATOM(onmoznetworkupload, "onmoznetworkupload")
--- a/dom/apps/PermissionsTable.jsm
+++ b/dom/apps/PermissionsTable.jsm
@@ -488,22 +488,16 @@ this.PermissionsTable =  { geolocation: 
                              access: ["read", "write"],
                              additional: ["settings-api"]
                            },
                            "engineering-mode": {
                              app: DENY_ACTION,
                              trusted: DENY_ACTION,
                              privileged: DENY_ACTION,
                              certified: ALLOW_ACTION
-                           },
-                           "before-after-keyboard-event": {
-                             app: DENY_ACTION,
-                             trusted: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
                            }
                          };
 
 /**
  * Append access modes to the permission name as suffixes.
  *   e.g. permission name 'contacts' with ['read', 'write'] =
  *   ['contacts-read', contacts-write']
  * @param string aPermName
deleted file mode 100644
--- a/dom/events/BeforeAfterKeyboardEvent.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/dom/BeforeAfterKeyboardEvent.h"
-#include "mozilla/TextEvents.h"
-#include "prtime.h"
-
-namespace mozilla {
-namespace dom {
-
-BeforeAfterKeyboardEvent::BeforeAfterKeyboardEvent(
-                                       EventTarget* aOwner,
-                                       nsPresContext* aPresContext,
-                                       InternalBeforeAfterKeyboardEvent* aEvent)
-  : KeyboardEvent(aOwner, aPresContext,
-                  aEvent ? aEvent :
-                           new InternalBeforeAfterKeyboardEvent(false, 0,
-                                                                nullptr))
-{
-  MOZ_ASSERT(mEvent->mClass == eBeforeAfterKeyboardEventClass,
-             "event type mismatch eBeforeAfterKeyboardEventClass");
-
-  if (!aEvent) {
-    mEventIsInternal = true;
-    mEvent->time = PR_Now();
-  }
-}
-
-// static
-already_AddRefed<BeforeAfterKeyboardEvent>
-BeforeAfterKeyboardEvent::Constructor(
-                            EventTarget* aOwner,
-                            const nsAString& aType,
-                            const BeforeAfterKeyboardEventInit& aParam)
-{
-  nsRefPtr<BeforeAfterKeyboardEvent> event =
-    new BeforeAfterKeyboardEvent(aOwner, nullptr, nullptr);
-  ErrorResult rv;
-  event->InitWithKeyboardEventInit(aOwner, aType, aParam, rv);
-  NS_WARN_IF(rv.Failed());
-
-  event->mEvent->AsBeforeAfterKeyboardEvent()->mEmbeddedCancelled =
-    aParam.mEmbeddedCancelled;
-
-  return event.forget();
-}
-
-// static
-already_AddRefed<BeforeAfterKeyboardEvent>
-BeforeAfterKeyboardEvent::Constructor(
-                            const GlobalObject& aGlobal,
-                            const nsAString& aType,
-                            const BeforeAfterKeyboardEventInit& aParam,
-                            ErrorResult& aRv)
-{
-  nsCOMPtr<EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
-  return Constructor(owner, aType, aParam);
-}
-
-Nullable<bool>
-BeforeAfterKeyboardEvent::GetEmbeddedCancelled()
-{
-  nsAutoString type;
-  GetType(type);
-  if (type.EqualsLiteral("mozbrowserafterkeydown") ||
-      type.EqualsLiteral("mozbrowserafterkeyup")) {
-    return mEvent->AsBeforeAfterKeyboardEvent()->mEmbeddedCancelled;
-  }
-  return Nullable<bool>();
-}
-
-} // namespace dom
-} // namespace mozilla
-
-using namespace mozilla;
-using namespace mozilla::dom;
-
-nsresult
-NS_NewDOMBeforeAfterKeyboardEvent(nsIDOMEvent** aInstancePtrResult,
-                                  EventTarget* aOwner,
-                                  nsPresContext* aPresContext,
-                                  InternalBeforeAfterKeyboardEvent* aEvent)
-{
-  BeforeAfterKeyboardEvent* it =
-    new BeforeAfterKeyboardEvent(aOwner, aPresContext, aEvent);
-
-  NS_ADDREF(it);
-  *aInstancePtrResult = static_cast<Event*>(it);
-  return NS_OK;
-}
deleted file mode 100644
--- a/dom/events/BeforeAfterKeyboardEvent.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_BeforeAfterKeyboardEvent_h_
-#define mozilla_dom_BeforeAfterKeyboardEvent_h_
-
-#include "mozilla/dom/KeyboardEvent.h"
-#include "mozilla/dom/BeforeAfterKeyboardEventBinding.h"
-
-namespace mozilla {
-namespace dom {
-
-class BeforeAfterKeyboardEvent : public KeyboardEvent
-{
-public:
-  BeforeAfterKeyboardEvent(EventTarget* aOwner,
-                           nsPresContext* aPresContext,
-                           InternalBeforeAfterKeyboardEvent* aEvent);
-
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
-  {
-    return BeforeAfterKeyboardEventBinding::Wrap(aCx, this);
-  }
-
-  static already_AddRefed<BeforeAfterKeyboardEvent>
-  Constructor(const GlobalObject& aGlobal,
-              const nsAString& aType,
-              const BeforeAfterKeyboardEventInit& aParam,
-              ErrorResult& aRv);
-
-  static already_AddRefed<BeforeAfterKeyboardEvent>
-  Constructor(EventTarget* aOwner, const nsAString& aType,
-              const BeforeAfterKeyboardEventInit& aEventInitDict);
-
-  // This function returns a boolean value when event typs is either
-  // "mozbrowserafterkeydown" or "mozbrowserafterkeyup".
-  Nullable<bool> GetEmbeddedCancelled();
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_BeforeAfterKeyboardEvent_h_
--- a/dom/events/EventDispatcher.cpp
+++ b/dom/events/EventDispatcher.cpp
@@ -696,19 +696,16 @@ EventDispatcher::CreateEvent(EventTarget
       return NS_NewDOMUIEvent(aDOMEvent, aOwner, aPresContext,
                               aEvent->AsGUIEvent());
     case eScrollAreaEventClass:
       return NS_NewDOMScrollAreaEvent(aDOMEvent, aOwner, aPresContext,
                                       aEvent->AsScrollAreaEvent());
     case eKeyboardEventClass:
       return NS_NewDOMKeyboardEvent(aDOMEvent, aOwner, aPresContext,
                                     aEvent->AsKeyboardEvent());
-    case eBeforeAfterKeyboardEventClass:
-      return NS_NewDOMBeforeAfterKeyboardEvent(aDOMEvent, aOwner, aPresContext,
-                                               aEvent->AsBeforeAfterKeyboardEvent());
     case eCompositionEventClass:
       return NS_NewDOMCompositionEvent(aDOMEvent, aOwner, aPresContext,
                                        aEvent->AsCompositionEvent());
     case eMouseEventClass:
       return NS_NewDOMMouseEvent(aDOMEvent, aOwner, aPresContext,
                                  aEvent->AsMouseEvent());
     case eFocusEventClass:
       return NS_NewDOMFocusEvent(aDOMEvent, aOwner, aPresContext,
--- a/dom/events/EventNameList.h
+++ b/dom/events/EventNameList.h
@@ -232,32 +232,16 @@ EVENT(keydown,
 EVENT(keypress,
       NS_KEY_PRESS,
       EventNameType_HTMLXUL,
       eKeyboardEventClass)
 EVENT(keyup,
       NS_KEY_UP,
       EventNameType_HTMLXUL,
       eKeyboardEventClass)
-NON_IDL_EVENT(mozbrowserbeforekeydown,
-              NS_KEY_BEFORE_DOWN,
-              EventNameType_None,
-              eBeforeAfterKeyboardEventClass)
-NON_IDL_EVENT(mozbrowserafterkeydown,
-              NS_KEY_AFTER_DOWN,
-              EventNameType_None,
-              eBeforeAfterKeyboardEventClass)
-NON_IDL_EVENT(mozbrowserbeforekeyup,
-              NS_KEY_BEFORE_UP,
-              EventNameType_None,
-              eBeforeAfterKeyboardEventClass)
-NON_IDL_EVENT(mozbrowserafterkeyup,
-              NS_KEY_AFTER_UP,
-              EventNameType_None,
-              eBeforeAfterKeyboardEventClass)
 EVENT(loadeddata,
       NS_LOADEDDATA,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(loadedmetadata,
       NS_LOADEDMETADATA,
       EventNameType_HTML,
       eBasicEventClass)
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -646,22 +646,18 @@ EventStateManager::PreHandleEvent(nsPres
       if (modifierMask &&
           (modifierMask == Prefs::ChromeAccessModifierMask() ||
            modifierMask == Prefs::ContentAccessModifierMask())) {
         HandleAccessKey(aPresContext, keyEvent, aStatus, nullptr,
                         eAccessKeyProcessingNormal, modifierMask);
       }
     }
     // then fall through...
-  case NS_KEY_BEFORE_DOWN:
   case NS_KEY_DOWN:
-  case NS_KEY_AFTER_DOWN:
-  case NS_KEY_BEFORE_UP:
   case NS_KEY_UP:
-  case NS_KEY_AFTER_UP:
     {
       nsIContent* content = GetFocusedContent();
       if (content)
         mCurrentTargetContent = content;
 
       // NOTE: Don't refer TextComposition::IsComposing() since DOM Level 3
       //       Events defines that KeyboardEvent.isComposing is true when it's
       //       dispatched after compositionstart and compositionend.
@@ -3162,19 +3158,17 @@ EventStateManager::PostHandleEvent(nsPre
       break;
     }
   case NS_DRAGDROP_EXIT:
      // make sure to fire the enter and exit_synth events after the
      // NS_DRAGDROP_EXIT event, otherwise we'll clean up too early
     GenerateDragDropEnterExit(presContext, aEvent->AsDragEvent());
     break;
 
-  case NS_KEY_BEFORE_UP:
   case NS_KEY_UP:
-  case NS_KEY_AFTER_UP:
     break;
 
   case NS_KEY_PRESS:
     if (nsEventStatus_eConsumeNoDefault != *aStatus) {
       WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
       //This is to prevent keyboard scrolling while alt modifier in use.
       if (!keyEvent->IsAlt()) {
         switch(keyEvent->keyCode) {
--- a/dom/events/KeyboardEvent.cpp
+++ b/dom/events/KeyboardEvent.cpp
@@ -12,18 +12,20 @@ namespace mozilla {
 namespace dom {
 
 KeyboardEvent::KeyboardEvent(EventTarget* aOwner,
                              nsPresContext* aPresContext,
                              WidgetKeyboardEvent* aEvent)
   : UIEvent(aOwner, aPresContext,
             aEvent ? aEvent : new WidgetKeyboardEvent(false, 0, nullptr))
   , mInitializedByCtor(false)
-  , mInitializedWhichValue(0)
+  , mInitialzedWhichValue(0)
 {
+  NS_ASSERTION(mEvent->mClass == eKeyboardEventClass, "event type mismatch");
+
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
     mEvent->AsKeyboardEvent()->mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
   }
@@ -250,22 +252,18 @@ uint32_t
 KeyboardEvent::CharCode()
 {
   // If this event is initialized with ctor, we shouldn't check event type.
   if (mInitializedByCtor) {
     return mEvent->AsKeyboardEvent()->charCode;
   }
 
   switch (mEvent->message) {
-  case NS_KEY_BEFORE_DOWN:
+  case NS_KEY_UP:
   case NS_KEY_DOWN:
-  case NS_KEY_AFTER_DOWN:
-  case NS_KEY_BEFORE_UP:
-  case NS_KEY_UP:
-  case NS_KEY_AFTER_UP:
     return 0;
   case NS_KEY_PRESS:
     return mEvent->AsKeyboardEvent()->charCode;
   }
   return 0;
 }
 
 NS_IMETHODIMP
@@ -279,37 +277,36 @@ KeyboardEvent::GetKeyCode(uint32_t* aKey
 uint32_t
 KeyboardEvent::KeyCode()
 {
   // If this event is initialized with ctor, we shouldn't check event type.
   if (mInitializedByCtor) {
     return mEvent->AsKeyboardEvent()->keyCode;
   }
 
-  if (mEvent->HasKeyEventMessage()) {
+  switch (mEvent->message) {
+  case NS_KEY_UP:
+  case NS_KEY_PRESS:
+  case NS_KEY_DOWN:
     return mEvent->AsKeyboardEvent()->keyCode;
   }
   return 0;
 }
 
 uint32_t
 KeyboardEvent::Which()
 {
   // If this event is initialized with ctor, which can have independent value.
   if (mInitializedByCtor) {
-    return mInitializedWhichValue;
+    return mInitialzedWhichValue;
   }
 
   switch (mEvent->message) {
-    case NS_KEY_BEFORE_DOWN:
+    case NS_KEY_UP:
     case NS_KEY_DOWN:
-    case NS_KEY_AFTER_DOWN:
-    case NS_KEY_BEFORE_UP:
-    case NS_KEY_UP:
-    case NS_KEY_AFTER_UP:
       return KeyCode();
     case NS_KEY_PRESS:
       //Special case for 4xp bug 62878.  Try to make value of which
       //more closely mirror the values that 4.x gave for RETURN and BACKSPACE
       {
         uint32_t keyCode = mEvent->AsKeyboardEvent()->keyCode;
         if (keyCode == NS_VK_RETURN || keyCode == NS_VK_BACK) {
           return keyCode;
@@ -341,45 +338,36 @@ already_AddRefed<KeyboardEvent>
 KeyboardEvent::Constructor(const GlobalObject& aGlobal,
                            const nsAString& aType,
                            const KeyboardEventInit& aParam,
                            ErrorResult& aRv)
 {
   nsCOMPtr<EventTarget> target = do_QueryInterface(aGlobal.GetAsSupports());
   nsRefPtr<KeyboardEvent> newEvent =
     new KeyboardEvent(target, nullptr, nullptr);
-  newEvent->InitWithKeyboardEventInit(target, aType, aParam, aRv);
-
-  return newEvent.forget();
-}
+  bool trusted = newEvent->Init(target);
+  aRv = newEvent->InitKeyEvent(aType, aParam.mBubbles, aParam.mCancelable,
+                               aParam.mView, aParam.mCtrlKey, aParam.mAltKey,
+                               aParam.mShiftKey, aParam.mMetaKey,
+                               aParam.mKeyCode, aParam.mCharCode);
+  newEvent->SetTrusted(trusted);
+  newEvent->mDetail = aParam.mDetail;
+  newEvent->mInitializedByCtor = true;
+  newEvent->mInitialzedWhichValue = aParam.mWhich;
 
-void
-KeyboardEvent::InitWithKeyboardEventInit(EventTarget* aOwner,
-                                         const nsAString& aType,
-                                         const KeyboardEventInit& aParam,
-                                         ErrorResult& aRv)
-{
-  bool trusted = Init(aOwner);
-  aRv = InitKeyEvent(aType, aParam.mBubbles, aParam.mCancelable,
-                     aParam.mView, aParam.mCtrlKey, aParam.mAltKey,
-                     aParam.mShiftKey, aParam.mMetaKey,
-                     aParam.mKeyCode, aParam.mCharCode);
-  SetTrusted(trusted);
-  mDetail = aParam.mDetail;
-  mInitializedByCtor = true;
-  mInitializedWhichValue = aParam.mWhich;
-
-  WidgetKeyboardEvent* internalEvent = mEvent->AsKeyboardEvent();
+  WidgetKeyboardEvent* internalEvent = newEvent->mEvent->AsKeyboardEvent();
   internalEvent->location = aParam.mLocation;
   internalEvent->mIsRepeat = aParam.mRepeat;
   internalEvent->mIsComposing = aParam.mIsComposing;
   internalEvent->mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
+  internalEvent->mKeyValue = aParam.mKey;
   internalEvent->mCodeNameIndex = CODE_NAME_INDEX_USE_STRING;
-  internalEvent->mKeyValue = aParam.mKey;
   internalEvent->mCodeValue = aParam.mCode;
+
+  return newEvent.forget();
 }
 
 NS_IMETHODIMP
 KeyboardEvent::InitKeyEvent(const nsAString& aType,
                             bool aCanBubble,
                             bool aCancelable,
                             nsIDOMWindow* aView,
                             bool aCtrlKey,
--- a/dom/events/KeyboardEvent.h
+++ b/dom/events/KeyboardEvent.h
@@ -69,27 +69,21 @@ public:
     aRv = InitKeyEvent(aType, aCanBubble, aCancelable, aView,
                        aCtrlKey, aAltKey, aShiftKey,aMetaKey,
                        aKeyCode, aCharCode);
   }
 
 protected:
   ~KeyboardEvent() {}
 
-  void InitWithKeyboardEventInit(EventTarget* aOwner,
-                                 const nsAString& aType,
-                                 const KeyboardEventInit& aParam,
-                                 ErrorResult& aRv);
-
 private:
   // True, if the instance is created with Constructor().
   bool mInitializedByCtor;
-
   // If the instance is created with Constructor(), which may have independent
   // value.  mInitializedWhichValue stores it.  I.e., this is invalid when
   // mInitializedByCtor is false.
-  uint32_t mInitializedWhichValue;
+  uint32_t mInitialzedWhichValue;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_KeyboardEvent_h_
--- a/dom/events/moz.build
+++ b/dom/events/moz.build
@@ -27,17 +27,16 @@ EXPORTS.mozilla += [
     'KeyNameList.h',
     'PhysicalKeyCodeNameList.h',
     'TextComposition.h',
     'VirtualKeyCodeList.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'AnimationEvent.h',
-    'BeforeAfterKeyboardEvent.h',
     'BeforeUnloadEvent.h',
     'ClipboardEvent.h',
     'CommandEvent.h',
     'CompositionEvent.h',
     'CustomEvent.h',
     'DataContainerEvent.h',
     'DataTransfer.h',
     'DeviceMotionEvent.h',
@@ -67,17 +66,16 @@ EXPORTS.mozilla.dom += [
 ]
 
 if CONFIG['MOZ_WEBSPEECH']:
     EXPORTS.mozilla.dom += ['SpeechRecognitionError.h']
 
 UNIFIED_SOURCES += [
     'AnimationEvent.cpp',
     'AsyncEventDispatcher.cpp',
-    'BeforeAfterKeyboardEvent.cpp',
     'BeforeUnloadEvent.cpp',
     'ClipboardEvent.cpp',
     'CommandEvent.cpp',
     'CompositionEvent.cpp',
     'ContentEventHandler.cpp',
     'DataContainerEvent.cpp',
     'DataTransfer.cpp',
     'DeviceMotionEvent.cpp',
deleted file mode 100644
--- a/dom/events/test/bug989198_embedded.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <title>Embedded iframe</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body onload="getFocus();">
-  <p id="display"></p>
-  <div id="content" style="display: none"></div>
-  <input id="input" style="display: block;">
-  <pre id="test">
-  <script type="application/javascript">
-    function getFocus() {
-      input = document.getElementById("input");
-      input.focus();
-    }
-  </script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/events/test/bug989198_helper.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Constants and helper functions for testing BeforeAfterKeyboardEvent.
- */
-
-const kUnknownEvent       = 0x000;
-const kKeyDownEvent       = 0x001;
-const kKeyUpEvent         = 0x002;
-const kBeforeEvent        = 0x010;
-const kAfterEvent         = 0x020;
-const kParent             = 0x100;
-const kChild              = 0x200;
-
-var gCurrentTest;
-
-function frameScript()
-{
-  function handler(e) {
-    var results = sendSyncMessage("forwardevent", { type: e.type });
-    if (results[0]) {
-      e.preventDefault();
-    }
-  }
-  addEventListener('keydown', handler);
-  addEventListener('keyup', handler);
-  addEventListener('mozbrowserbeforekeydown', handler);
-  addEventListener('mozbrowserbeforekeyup', handler);
-  addEventListener('mozbrowserafterkeydown', handler);
-  addEventListener('mozbrowserafterkeyup', handler);
-}
-
-function prepareTest(useRemote)
-{
-  setupHandlers(window, embedderHandler);
-
-  var iframe = document.createElement("iframe");
-  iframe.id = "embedded";
-  iframe.src = "bug989198_embedded.html";
-  iframe.setAttribute("remote", useRemote ? "true" : "false");
-  SpecialPowers.wrap(iframe).mozbrowser = true;
-
-  iframe.addEventListener("mozbrowserloadend", function onloadend() {
-    iframe.removeEventListener("mozbrowserloadend", onloadend);
-    iframe.focus();
-    var mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
-    mm.addMessageListener("forwardevent", function(msg) {
-      return embeddedHandler(msg.json);
-    });
-    mm.loadFrameScript("data:,(" + frameScript.toString() + ")();", false);
-    runTests();
-    return;
-  });
-
-  document.body.appendChild(iframe);
-}
-
-function cleanupTest()
-{
-  teardownHandlers(window, embedderHandler);
-  runTests();
-}
-
-function setupHandlers(element, handler)
-{
-  element.addEventListener('keydown', handler);
-  element.addEventListener('keyup', handler);
-  element.addEventListener('mozbrowserbeforekeydown', handler);
-  element.addEventListener('mozbrowserbeforekeyup', handler);
-  element.addEventListener('mozbrowserafterkeydown', handler);
-  element.addEventListener('mozbrowserafterkeyup', handler);
-}
-
-function teardownHandlers(element, handler)
-{
-  element.removeEventListener('keydown', handler);
-  element.removeEventListener('keyup', handler);
-  element.removeEventListener('mozbrowserbeforekeydown', handler);
-  element.removeEventListener('mozbrowserbeforekeyup', handler);
-  element.removeEventListener('mozbrowserafterkeydown', handler);
-  element.removeEventListener('mozbrowserafterkeyup', handler);
-}
-
-function convertNameToCode(name)
-{
-  switch (name) {
-    case "mozbrowserbeforekeydown":
-      return kBeforeEvent | kKeyDownEvent;
-    case "mozbrowserafterkeydown":
-      return kAfterEvent | kKeyDownEvent;
-    case "mozbrowserbeforekeyup":
-      return kBeforeEvent | kKeyUpEvent;
-    case "mozbrowserafterkeyup":
-      return kAfterEvent | kKeyUpEvent;
-    case "keydown":
-      return kKeyDownEvent;
-    case "keyup":
-      return kKeyUpEvent;
-    default:
-      return kUnknownEvent;
-  }
-}
-
-function classifyEvents(test)
-{
-  // Categorize resultEvents into KEYDOWN group and KEYUP group.
-  for (var i = 0; i < gCurrentTest.resultEvents.length ; i++) {
-    var code = test.resultEvents[i];
-    if ((code & 0xF) == 0x1) { // KEYDOWN
-      test.classifiedEvents[0].push(code);
-    } else if ((code & 0xF) == 0x2) { // KEYUP
-      test.classifiedEvents[1].push(code);
-    } else {
-      ok(false, "Invalid code for events");
-    }
-  }
-}
-
-function verifyResults(test)
-{
-  for (var i = 0; i < gCurrentTest.expectedEvents.length; i++) {
-    is(test.classifiedEvents[i].length,
-       test.expectedEvents[i].length,
-       test.description + ": Wrong number of events");
-
-    for (var j = 0; j < gCurrentTest.classifiedEvents[i].length; j++) {
-      var item = test.classifiedEvents[i][j];
-      is(item, test.expectedEvents[i][j],
-         test.description + ": Wrong order of events");
-     }
-  }
-}
-
-function embeddedHandler(e)
-{
-  return handler(e, kChild);
-}
-
-function embedderHandler(e)
-{
-  // Verify value of attribute embeddedCancelled
-  handler(e, kParent, function checkEmbeddedCancelled(code){
-    switch (code) {
-      case kBeforeEvent | kKeyDownEvent:
-      case kBeforeEvent | kKeyUpEvent:
-        is(e.embeddedCancelled, null,
-           gCurrentTest.description + ': embeddedCancelled should be null');
-        break;
-      case kAfterEvent | kKeyDownEvent:
-        if ((gCurrentTest.doPreventDefaultAt & 0xFF) == kKeyDownEvent) {
-          is(e.embeddedCancelled, true,
-             gCurrentTest.description + ': embeddedCancelled should be true');
-        } else {
-          is(e.embeddedCancelled, false,
-             gCurrentTest.description + ': embeddedCancelled should be false');
-        }
-        break;
-      case kAfterEvent | kKeyUpEvent:
-        if ((gCurrentTest.doPreventDefaultAt & 0xFF) == kKeyUpEvent) {
-          is(e.embeddedCancelled, true,
-             gCurrentTest.description + ': embeddedCancelled should be true');
-        } else {
-          is(e.embeddedCancelled, false,
-             gCurrentTest.description + ': embeddedCancelled should be false');
-        }
-        break;
-      default:
-        break;
-    }
-  });
-}
-
-function handler(e, highBit, callback)
-{
-  var code = convertNameToCode(e.type);
-  var newCode = highBit | code;
-  gCurrentTest.resultEvents.push(newCode);
-
-  if (callback) {
-    callback(code);
-  }
-
-  // Return and let frameScript to handle
-  if (highBit == kChild) {
-    return newCode == gCurrentTest.doPreventDefaultAt;
-  }
-
-  if (newCode == gCurrentTest.doPreventDefaultAt) {
-    e.preventDefault();
-  }
-}
-
-function runTests()
-{
-  if (!tests.length) {
-    SimpleTest.finish();
-    return;
-  }
-
-  var test = tests.shift();
-  test();
-}
--- a/dom/events/test/mochitest.ini
+++ b/dom/events/test/mochitest.ini
@@ -162,17 +162,8 @@ skip-if = toolkit == 'android' #CRASH_DU
 [test_focus_disabled.html]
 skip-if = buildapp == 'mulet'
 [test_messageEvent.html]
 [test_moz_mouse_pixel_scroll_event.html]
 skip-if = buildapp == 'mulet'
 [test_onerror_handler_args.html]
 [test_wheel_default_action.html]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || e10s
-[test_dom_before_after_keyboard_event.html]
-support-files =
-  bug989198_embedded.html
-  bug989198_helper.js
-[test_dom_before_after_keyboard_event_remote.html]
-support-files =
-  bug989198_embedded.html
-  bug989198_helper.js
-skip-if = buildapp == 'b2g' || e10s
--- a/dom/events/test/test_all_synthetic_events.html
+++ b/dom/events/test/test_all_synthetic_events.html
@@ -29,20 +29,16 @@ const kEventConstructors = {
                                                        },
                                              },
   AnimationEvent:                            { create: function (aName, aProps) {
                                                          return new AnimationEvent(aName, aProps);
                                                        },
                                              },
   AudioProcessingEvent:                      { create: null, // Cannot create untrusted event from JS.
                                              },
-  BeforeAfterKeyboardEvent:                  { create: function (aName, aProps) {
-                                                         return new BeforeAfterKeyboardEvent(aName, aProps);
-                                                       },
-                                             },
   BeforeUnloadEvent:                         { create: function (aName, aProps) {
                                                          var e = document.createEvent("beforeunloadevent");
                                                          e.initEvent(aName, aProps.bubbles, aProps.cancelable);
                                                          return e;
                                                        },
                                              },
   BlobEvent:                                 { create: function (aName, aProps) {
                                                          return new BlobEvent(aName, aProps);
deleted file mode 100644
--- a/dom/events/test/test_dom_before_after_keyboard_event.html
+++ /dev/null
@@ -1,117 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <title>Test for Bug 989198</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/NativeKeyCodes.js"></script>
-  <script type="text/javascript" src="bug989198_helper.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body onload="runTests();">
-<a target="_blank"
-   href="https://bugzilla.mozilla.org/show_bug.cgi?id=989198">Mozilla Bug 989198</a>
-<p id="display"></p>
-<pre id="test">
-<script type="application/javascript">
-
-SimpleTest.waitForExplicitFinish();
-
-function testEventOrderAndAttr()
-{
-  const mainDesc = 'Testing the order of the events';
-  const kTests = [
-    {
-      description: mainDesc,
-      expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
-                          kChild | kKeyDownEvent,
-                          kParent | kAfterEvent | kKeyDownEvent ],
-                        [ kParent | kBeforeEvent | kKeyUpEvent,
-                          kChild | kKeyUpEvent,
-                          kParent | kAfterEvent | kKeyUpEvent ] ],
-      resultEvents: [],
-      classifiedEvents: [ [], [] ],
-      doPreventDefaultAt: kUnknownEvent
-    },
-    {
-      description: mainDesc + ', calling preventDefault() at "mozbrowserbeforekeydown" event',
-      expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
-                          kParent | kAfterEvent | kKeyDownEvent ],
-                        [ kParent | kBeforeEvent | kKeyUpEvent,
-                          kChild | kKeyUpEvent,
-                          kParent | kAfterEvent | kKeyUpEvent ] ],
-      resultEvents: [],
-      classifiedEvents: [ [], [] ],
-      doPreventDefaultAt: kParent | kBeforeEvent | kKeyDownEvent
-    },
-    {
-      description: mainDesc + ', calling preventDefault() at "mozbrowserbeforekeyup" event',
-      expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
-                          kChild | kKeyDownEvent,
-                          kParent | kAfterEvent | kKeyDownEvent ],
-                        [ kParent | kBeforeEvent | kKeyUpEvent,
-                          kParent | kAfterEvent | kKeyUpEvent ] ],
-      resultEvents: [],
-      classifiedEvents: [ [], [] ],
-      doPreventDefaultAt: kParent | kBeforeEvent | kKeyUpEvent
-    },
-    {
-      description: mainDesc + ', calling preventDefault() at "keydown" event',
-      expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
-                          kChild | kKeyDownEvent,
-                          kParent | kAfterEvent | kKeyDownEvent ],
-                        [ kParent | kBeforeEvent | kKeyUpEvent,
-                          kChild | kKeyUpEvent,
-                          kParent | kAfterEvent | kKeyUpEvent ] ],
-      resultEvents: [],
-      classifiedEvents: [ [], [] ],
-      doPreventDefaultAt: kChild | kKeyDownEvent
-    },
-    {
-      description: mainDesc + ', calling preventDefault() at "keyup" event',
-      expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
-                          kChild | kKeyDownEvent,
-                          kParent | kAfterEvent | kKeyDownEvent ],
-                        [ kParent | kBeforeEvent | kKeyUpEvent,
-                          kChild | kKeyUpEvent,
-                          kParent | kAfterEvent | kKeyUpEvent ] ],
-      resultEvents: [],
-      classifiedEvents: [ [], [] ],
-      doPreventDefaultAt: kChild | kKeyUpEvent
-    }
-  ];
-
-  for (var k = 0; k < kTests.length; k++ ) {
-    gCurrentTest = kTests[k];
-    synthesizeKey('a', {}, document.getElementById("embedded").contentWindow);
-    classifyEvents(kTests[k]);
-    verifyResults(kTests[k]);
-  }
-
-  runTests();
-}
-
-var tests = [
-  function addPermissions() {
-    SpecialPowers.pushPermissions(
-      [{ type: "before-after-keyboard-event", allow: true, context: document },
-       { type: "browser", allow: true, context: document }],
-      runTests);
-  },
-  function addPreferences() {
-    SpecialPowers.pushPrefEnv(
-      { "set": [["dom.beforeAfterKeyboardEvent.enabled", true],
-                ["dom.mozBrowserFramesEnabled", true],
-                ["dom.ipc.tabs.disabled", false]] },
-      runTests);
-  },
-
-  // Tests for in-process iframe, i.e. <iframe mozbrowser>.
-  ()=>prepareTest(false),
-  testEventOrderAndAttr,
-  cleanupTest,
-];
-
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/events/test/test_dom_before_after_keyboard_event_remote.html
+++ /dev/null
@@ -1,142 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <title>Test for Bug 989198</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/NativeKeyCodes.js"></script>
-  <script type="text/javascript" src="bug989198_helper.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body onload="runTests();">
-<a target="_blank"
-   href="https://bugzilla.mozilla.org/show_bug.cgi?id=989198">Mozilla Bug 989198</a>
-<p id="display"></p>
-<div id="content">
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-SimpleTest.waitForExplicitFinish();
-
-const mainDesc = 'Testing the order of the events (OOP)';
-var testsForEventOrder = [
-  {
-    description: mainDesc,
-    expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
-                        kParent | kKeyDownEvent,
-                        kChild | kKeyDownEvent,
-                        kParent | kAfterEvent | kKeyDownEvent ],
-                      [ kParent | kBeforeEvent | kKeyUpEvent,
-                        kParent | kKeyUpEvent,
-                        kChild | kKeyUpEvent,
-                        kParent | kAfterEvent | kKeyUpEvent ] ],
-    resultEvents: [],
-    classifiedEvents: [ [], [] ],
-    doPreventDefaultAt: kUnknownEvent
-  },
-  {
-    description: mainDesc + ', calling preventDefault() at "mozbrowserbeforekeydown" event',
-    expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
-                        kParent | kAfterEvent | kKeyDownEvent ],
-                      [ kParent | kBeforeEvent | kKeyUpEvent,
-                        kParent | kKeyUpEvent,
-                        kChild | kKeyUpEvent,
-                        kParent | kAfterEvent | kKeyUpEvent ] ],
-    resultEvents: [],
-    classifiedEvents: [ [], [] ],
-    doPreventDefaultAt: kParent | kBeforeEvent | kKeyDownEvent
-  },
-  {
-    description: mainDesc + ', calling preventDefault() at "mozbrowserbeforekeyup" event',
-    expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
-                        kParent | kKeyDownEvent,
-                        kChild | kKeyDownEvent,
-                        kParent | kAfterEvent | kKeyDownEvent ],
-                      [ kParent | kBeforeEvent | kKeyUpEvent,
-                        kParent | kAfterEvent | kKeyUpEvent ] ],
-    resultEvents: [],
-    classifiedEvents: [ [], [] ],
-    doPreventDefaultAt: kParent | kBeforeEvent | kKeyUpEvent
-  },
-  {
-    description: mainDesc + ', calling preventDefault() at "keydown" event',
-    expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
-                        kParent | kKeyDownEvent,
-                        kChild | kKeyDownEvent,
-                        kParent | kAfterEvent | kKeyDownEvent ],
-                      [ kParent | kBeforeEvent | kKeyUpEvent,
-                        kParent | kKeyUpEvent,
-                        kChild | kKeyUpEvent,
-                        kParent | kAfterEvent | kKeyUpEvent ] ],
-    resultEvents: [],
-    classifiedEvents: [ [], [] ],
-    doPreventDefaultAt: kChild | kKeyDownEvent
-  },
-  {
-    description: mainDesc + ', calling preventDefault() at "keyup" event',
-    expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
-                        kParent | kKeyDownEvent,
-                        kChild | kKeyDownEvent,
-                        kParent | kAfterEvent | kKeyDownEvent ],
-                      [ kParent | kBeforeEvent | kKeyUpEvent,
-                        kParent | kKeyUpEvent,
-                        kChild | kKeyUpEvent,
-                        kParent | kAfterEvent | kKeyUpEvent ] ],
-    resultEvents: [],
-    classifiedEvents: [ [], [] ],
-    doPreventDefaultAt: kChild | kKeyUpEvent
-  }
-];
-
-function testEventOrder()
-{
-  if (!testsForEventOrder.length) {
-    runTests();
-    return;
-  }
-  gCurrentTest = testsForEventOrder.shift();
-
-  synthesizeKey('a', {}, document.getElementById("embedded").contentWindow);
-  // It take some time to propagate events to a remote iframe.
-
-  waitAndVerifyResult(0);
-}
-
-function waitAndVerifyResult(count) {
-  expectedEventLength = gCurrentTest.expectedEvents[0].length +
-                        gCurrentTest.expectedEvents[1].length;
-  if (gCurrentTest.resultEvents.length >= expectedEventLength || count > 10) {
-    classifyEvents(gCurrentTest);
-    verifyResults(gCurrentTest);
-    testEventOrder();
-  }
-  else {
-    setTimeout(()=>waitAndVerifyResult(count + 1), 100);
-  }
-}
-
-var tests = [
-  function addPermissions() {
-    SpecialPowers.pushPermissions(
-      [{ type: "before-after-keyboard-event", allow: true, context: document },
-       { type: "browser", allow: true, context: document }],
-      runTests);
-  },
-  function addPreferences() {
-    SpecialPowers.pushPrefEnv(
-      { "set": [["dom.beforeAfterKeyboardEvent.enabled", true],
-                ["dom.mozBrowserFramesEnabled", true],
-                ["dom.ipc.tabs.disabled", false]] },
-      runTests);
-  },
-
-  // Tests for out-of-process iframe, i.el. <iframe mozbrowser remote>
-  ()=>prepareTest(true),
-  testEventOrder,
-  cleanupTest
-];
-
-</script>
-</body>
-</html>
--- a/dom/interfaces/events/nsIDOMEvent.idl
+++ b/dom/interfaces/events/nsIDOMEvent.idl
@@ -267,23 +267,16 @@ NS_NewDOMInputEvent(nsIDOMEvent** aInsta
                     mozilla::dom::EventTarget* aOwner,
                     nsPresContext* aPresContext,
                     mozilla::InternalEditorInputEvent* aEvent);
 nsresult
 NS_NewDOMKeyboardEvent(nsIDOMEvent** aInstancePtrResult,
                        mozilla::dom::EventTarget* aOwner,
                        nsPresContext* aPresContext,
                        mozilla::WidgetKeyboardEvent* aEvent);
-
-nsresult
-NS_NewDOMBeforeAfterKeyboardEvent(nsIDOMEvent** aInstancePtrResult,
-                                  mozilla::dom::EventTarget* aOwner,
-                                  nsPresContext* aPresContext,
-                                  mozilla::InternalBeforeAfterKeyboardEvent* aEvent);
-
 nsresult
 NS_NewDOMCompositionEvent(nsIDOMEvent** aInstancePtrResult,
                           mozilla::dom::EventTarget* aOwner,
                           nsPresContext* aPresContext,
                           mozilla::WidgetCompositionEvent* aEvent);
 nsresult
 NS_NewDOMMutationEvent(nsIDOMEvent** aResult,
                        mozilla::dom::EventTarget* aOwner,
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -393,18 +393,16 @@ parent:
      * OnAuthAvailable or OnAuthCancelled message.
      */
     AsyncAuthPrompt(nsCString uri, nsString realm, uint64_t aCallbackId);
 
     __delete__();
 
     ReplyKeyEvent(WidgetKeyboardEvent event);
 
-    DispatchAfterKeyboardEvent(WidgetKeyboardEvent event);
-
     sync RequestNativeKeyBindings(WidgetKeyboardEvent event)
         returns (MaybeNativeKeyBinding bindings);
 
     /**
      * Child informs the parent that the graphics objects are ready for
      * compositing.  This is sent when all pending changes have been
      * sent to the compositor and are ready to be shown on the next composite.
      * @see PCompositor
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -76,18 +76,18 @@
 #include "JavaScriptChild.h"
 #include "nsILoadContext.h"
 #include "ipc/nsGUIEventIPC.h"
 #include "mozilla/gfx/Matrix.h"
 #include "UnitTransforms.h"
 #include "ClientLayerManager.h"
 #include "LayersLogging.h"
 #include "nsIOService.h"
+
 #include "nsColorPickerProxy.h"
-#include "nsPresShell.h"
 
 #define BROWSER_ELEMENT_CHILD_SCRIPT \
     NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js")
 
 #define TABC_LOG(...)
 // #define TABC_LOG(...) printf_stderr("TABC: " __VA_ARGS__)
 
 using namespace mozilla;
@@ -2357,20 +2357,16 @@ TabChild::RecvRealKeyEvent(const WidgetK
   if (event.message == NS_KEY_DOWN) {
     mIgnoreKeyPressEvent = status == nsEventStatus_eConsumeNoDefault;
   }
 
   if (localEvent.mFlags.mWantReplyFromContentProcess) {
     SendReplyKeyEvent(localEvent);
   }
 
-  if (PresShell::BeforeAfterKeyboardEventEnabled()) {
-    SendDispatchAfterKeyboardEvent(localEvent);
-  }
-
   return true;
 }
 
 bool
 TabChild::RecvKeyEvent(const nsString& aType,
                        const int32_t& aKeyCode,
                        const int32_t& aCharCode,
                        const int32_t& aModifiers,
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -47,17 +47,16 @@
 #include "nsIWindowCreator2.h"
 #include "nsIXULBrowserWindow.h"
 #include "nsIXULWindow.h"
 #include "nsViewManager.h"
 #include "nsIWidget.h"
 #include "nsIWindowWatcher.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowWatcher.h"
-#include "nsPresShell.h"
 #include "nsPrintfCString.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "nsWindowWatcher.h"
 #include "private/pprio.h"
 #include "PermissionMessageUtils.h"
 #include "StructuredCloneUtils.h"
 #include "ColorPickerParent.h"
@@ -1459,39 +1458,16 @@ TabParent::RecvReplyKeyEvent(const Widge
   NS_ENSURE_TRUE(presShell, true);
   nsPresContext* presContext = presShell->GetPresContext();
   NS_ENSURE_TRUE(presContext, true);
 
   EventDispatcher::Dispatch(mFrameElement, presContext, &localEvent);
   return true;
 }
 
-bool
-TabParent::RecvDispatchAfterKeyboardEvent(const WidgetKeyboardEvent& aEvent)
-{
-  NS_ENSURE_TRUE(mFrameElement, true);
-
-  WidgetKeyboardEvent localEvent(aEvent);
-  localEvent.widget = GetWidget();
-
-  nsIDocument* doc = mFrameElement->OwnerDoc();
-  nsCOMPtr<nsIPresShell> presShell = doc->GetShell();
-  NS_ENSURE_TRUE(presShell, true);
-
-  if (mFrameElement &&
-      PresShell::BeforeAfterKeyboardEventEnabled() &&
-      localEvent.message != NS_KEY_PRESS) {
-    nsCOMPtr<nsINode> node(do_QueryInterface(mFrameElement));
-    presShell->DispatchAfterKeyboardEvent(mFrameElement, localEvent,
-                                          aEvent.mFlags.mDefaultPrevented);
-  }
-
-  return true;
-}
-
 /**
  * Try to answer query event using cached text.
  *
  * For NS_QUERY_SELECTED_TEXT, fail if the cache doesn't contain the whole
  *  selected range. (This shouldn't happen because PuppetWidget should have
  *  already sent the whole selection.)
  *
  * For NS_QUERY_TEXT_CONTENT, fail only if the cache doesn't overlap with
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -117,17 +117,16 @@ public:
      */
     bool TryCapture(const WidgetGUIEvent& aEvent);
 
     void Destroy();
 
     virtual bool RecvMoveFocus(const bool& aForward) MOZ_OVERRIDE;
     virtual bool RecvEvent(const RemoteDOMEvent& aEvent) MOZ_OVERRIDE;
     virtual bool RecvReplyKeyEvent(const WidgetKeyboardEvent& event);
-    virtual bool RecvDispatchAfterKeyboardEvent(const WidgetKeyboardEvent& event);
     virtual bool RecvPRenderFrameConstructor(PRenderFrameParent* aActor,
                                              ScrollingBehavior* aScrolling,
                                              TextureFactoryIdentifier* aFactoryIdentifier,
                                              uint64_t* aLayersId,
                                              bool* aSuccess) MOZ_OVERRIDE;
     virtual bool RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
                                             const nsString& aURL,
                                             const nsString& aName,
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -167,40 +167,36 @@ var interfaceNamesInGlobalScope =
     "AudioProcessingEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "AudioStreamTrack",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "BarProp",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "BatteryManager",
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "BeforeAfterKeyboardEvent", b2g: true,
-     pref: "dom.beforeAfterKeyboardEvent.enabled",
-     permission: ["embed-apps", "before-after-keyboard-event"]},
-// IMPORTANT: Do not change this list without review from a DOM peer!
     "BeforeUnloadEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "BiquadFilterNode",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Blob",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "BlobEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "BluetoothAdapter", b2g: true, permission: ["bluetooth"]},
+    {name: "BluetoothAdapter", b2g: true, permission: "bluetooth"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "BluetoothDevice", b2g: true, permission: ["bluetooth"]},
+    {name: "BluetoothDevice", b2g: true, permission: "bluetooth"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "BluetoothDeviceEvent", b2g: true, permission: ["bluetooth"]},
+    {name: "BluetoothDeviceEvent", b2g: true, permission: "bluetooth"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "BluetoothDiscoveryStateChangedEvent", b2g: true,
-     permission: ["bluetooth"]},
+     permission: "bluetooth"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "BluetoothManager", b2g: true, permission: ["bluetooth"]},
+    {name: "BluetoothManager", b2g: true, permission: "bluetooth"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "BluetoothStatusChangedEvent", b2g: true, permission: ["bluetooth"]},
+    {name: "BluetoothStatusChangedEvent", b2g: true, permission: "bluetooth"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "BoxObject", xbl: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "CallEvent", b2g: true, pref: "dom.telephony.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "CallGroupErrorEvent", b2g: true, pref: "dom.telephony.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "CameraCapabilities", b2g: true},
@@ -752,17 +748,17 @@ var interfaceNamesInGlobalScope =
     {name: "mozRTCIceCandidate", pref: "media.peerconnection.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "mozRTCPeerConnection", pref: "media.peerconnection.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "mozRTCSessionDescription", pref: "media.peerconnection.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MozSettingsEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "MozSettingsTransactionEvent", permission: ["settings-api-read"]},
+    {name: "MozSettingsTransactionEvent", permission: "settings-api-read"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MozSmsEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MozSmsMessage",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "MozSpeakerManager", b2g: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "MozStkCommandEvent", b2g: true, pref: "dom.icc.enabled"},
@@ -772,33 +768,33 @@ var interfaceNamesInGlobalScope =
     {name: "MozVoicemail", b2g: true, pref: "dom.voicemail.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "MozVoicemailEvent", b2g: true, pref: "dom.voicemail.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "MozVoicemailStatus", b2g: true, pref: "dom.voicemail.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "MozWakeLock", b2g: true, pref: "dom.wakelock.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "MozWifiCapabilities", b2g: true, permission: ["wifi-manage"]},
+    {name: "MozWifiCapabilities", b2g: true, permission: "wifi-manage"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "MozWifiConnectionInfoEvent", b2g: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "MozWifiStationInfoEvent", b2g: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-   {name: "MozWifiManager", b2g: true, permission: ["wifi-manage"]},
+   {name: "MozWifiManager", b2g: true, permission: "wifi-manage"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "MozWifiNetwork", b2g: true, permission: ["wifi-manage"]},
+    {name: "MozWifiNetwork", b2g: true, permission: "wifi-manage"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "MozWifiStatusChangeEvent", b2g: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "MozWifiP2pGroupOwner", b2g: true, permission: ["wifi-manage"]},
+    {name: "MozWifiP2pGroupOwner", b2g: true, permission: "wifi-manage"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "MozWifiP2pManager", b2g: true, permission: ["wifi-manage"]},
+    {name: "MozWifiP2pManager", b2g: true, permission: "wifi-manage"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "MozWifiP2pStatusChangeEvent", b2g: true, permission: ["wifi-manage"]},
+    {name: "MozWifiP2pStatusChangeEvent", b2g: true, permission: "wifi-manage"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MutationEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MutationObserver",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MutationRecord",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "NamedNodeMap",
@@ -846,19 +842,19 @@ var interfaceNamesInGlobalScope =
     "PerformanceNavigation",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "PerformanceResourceTiming",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "PerformanceTiming",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "PeriodicWave",
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "PermissionSettings", b2g: true, permission: ["permissions"]},
+    {name: "PermissionSettings", b2g: true, permission: "permissions"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "PhoneNumberService", permission: ["phonenumberservice"]},
+    {name: "PhoneNumberService", permission: "phonenumberservice"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Plugin",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "PluginArray",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "PointerEvent", pref: "dom.w3c_pointer_events.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "PopStateEvent",
@@ -1230,21 +1226,19 @@ var interfaceNamesInGlobalScope =
     {name: "TreeColumns", xbl: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "TreeContentView", xbl: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "TreeSelection", xbl: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "TreeWalker",
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "UDPMessageEvent", pref: "dom.udpsocket.enabled",
-     permission: ["udp-socket"]},
+    {name: "UDPMessageEvent", pref: "dom.udpsocket.enabled", permission: "udp-socket"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "UDPSocket", pref: "dom.udpsocket.enabled",
-     permission: ["udp-socket"]},
+    {name: "UDPSocket", pref: "dom.udpsocket.enabled", permission: "udp-socket"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "UIEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "UndoManager",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "URL",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "URLSearchParams",
@@ -1344,22 +1338,18 @@ var interfaceNamesInGlobalScope =
 
 function createInterfaceMap(isXBLScope) {
   var prefs = SpecialPowers.Services.prefs;
   var version = SpecialPowers.Cc["@mozilla.org/xre/app-info;1"].getService(SpecialPowers.Ci.nsIXULAppInfo).version;
   var isNightly = version.endsWith("a1");
   var isRelease = !version.contains("a");
   var isDesktop = !/Mobile|Tablet/.test(navigator.userAgent);
   var isB2G = !isDesktop && !navigator.userAgent.contains("Android");
-  var hasPermission = function (aPermissions) {
-    var result = false;
-    for (var p of aPermissions) {
-      result = result || SpecialPowers.hasPermission(p, window.document);
-    }
-    return result;
+  var hasPermission = function (aPermission) {
+    return SpecialPowers.hasPermission(aPermission, window.document);
   };
 
   var interfaceMap = {};
 
   function addInterfaces(interfaces)
   {
     for (var entry of interfaces) {
       if (typeof(entry) === "string") {
deleted file mode 100644
--- a/dom/webidl/BeforeAfterKeyboardEvent.webidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-[Constructor(DOMString typeArg,
- optional BeforeAfterKeyboardEventInit eventInitDict),
- CheckPermissions="embed-apps before-after-keyboard-event",
- Pref="dom.beforeAfterKeyboardEvent.enabled"]
-interface BeforeAfterKeyboardEvent : KeyboardEvent
-{
-  // The valid value of embeddedCancelled is:
-  // - "mozbrowserbeforekeydown": null
-  // - "mozbrowserbeforekeyup": null
-  // - "mozbrowserafterkeydown": true/false
-  // - "mozbrowserafterkeyup": true/false
-  readonly attribute boolean? embeddedCancelled;
-};
-
-dictionary BeforeAfterKeyboardEventInit : KeyboardEventInit
-{
-  boolean? embeddedCancelled = null;
-};
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -44,17 +44,16 @@ WEBIDL_FILES = [
     'AudioParam.webidl',
     'AudioProcessingEvent.webidl',
     'AudioStreamTrack.webidl',
     'AudioTrack.webidl',
     'AudioTrackList.webidl',
     'AutocompleteInfo.webidl',
     'BarProp.webidl',
     'BatteryManager.webidl',
-    'BeforeAfterKeyboardEvent.webidl',
     'BeforeUnloadEvent.webidl',
     'BiquadFilterNode.webidl',
     'Blob.webidl',
     'BoxObject.webidl',
     'BrowserElementDictionaries.webidl',
     'CallsList.webidl',
     'CameraCapabilities.webidl',
     'CameraControl.webidl',
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -73,17 +73,16 @@ template<class E> class nsCOMArray;
 class nsWeakFrame;
 class nsIScrollableFrame;
 class gfxContext;
 class nsIDOMEvent;
 class nsDisplayList;
 class nsDisplayListBuilder;
 class nsPIDOMWindow;
 struct nsPoint;
-class nsINode;
 struct nsIntPoint;
 struct nsIntRect;
 struct nsRect;
 class nsRegion;
 class nsRefreshDriver;
 class nsARefreshObserver;
 class nsAPostRefreshObserver;
 #ifdef ACCESSIBILITY
@@ -135,18 +134,18 @@ typedef struct CapturingContentInfo {
   bool mAllowed;
   bool mPointerLock;
   bool mRetargetToElement;
   bool mPreventDrag;
   nsIContent* mContent;
 } CapturingContentInfo;
 
 #define NS_IPRESSHELL_IID \
-  { 0xa0a4b515, 0x0b91, 0x4f13, \
-    { 0xa0, 0x60, 0x4b, 0xfb, 0x35, 0x00, 0xdc, 0x00 } }
+		{ 0x42e9a352, 0x76f3, 0x4ba3, \
+		  { 0x94, 0x0b, 0x78, 0x9e, 0x58, 0x38, 0x73, 0x4f } }
 
 // debug VerifyReflow flags
 #define VERIFY_REFLOW_ON                    0x01
 #define VERIFY_REFLOW_NOISY                 0x02
 #define VERIFY_REFLOW_ALL                   0x04
 #define VERIFY_REFLOW_DUMP_COMMANDS         0x08
 #define VERIFY_REFLOW_NOISY_RC              0x10
 #define VERIFY_REFLOW_REALLY_NOISY_RC       0x20
@@ -852,23 +851,16 @@ public:
    * Dispatch event to content only (NOT full processing)
    * @note The caller must have a strong reference to the PresShell.
    */
   virtual nsresult HandleDOMEventWithTarget(nsIContent* aTargetContent,
                                                         nsIDOMEvent* aEvent,
                                                         nsEventStatus* aStatus) = 0;
 
   /**
-   * Dispatch AfterKeyboardEvent with specific target.
-   */
-  virtual void DispatchAfterKeyboardEvent(nsINode* aTarget,
-                                          const mozilla::WidgetKeyboardEvent& aEvent,
-                                          bool aEmbeddedCancelled) = 0;
-
-  /**
     * Gets the current target event frame from the PresShell
     */
   virtual nsIFrame* GetEventTargetFrame() = 0;
 
   /**
     * Gets the current target event frame from the PresShell
     */
   virtual already_AddRefed<nsIContent> GetEventTargetContent(
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -37,17 +37,16 @@
 
 #ifdef XP_WIN
 #include "winuser.h"
 #endif
 
 #include "nsPresShell.h"
 #include "nsPresContext.h"
 #include "nsIContent.h"
-#include "mozilla/dom/BeforeAfterKeyboardEvent.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h" // for Event::GetEventPopupControlState()
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/dom/PointerEvent.h"
 #include "nsIDocument.h"
 #include "nsAnimationManager.h"
 #include "nsNameSpaceManager.h"  // for Pref-related rule management (bugs 22963,20760,31816)
 #include "nsFrame.h"
@@ -68,28 +67,25 @@
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMElement.h"
 #include "nsRange.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsReadableUtils.h"
 #include "nsIPageSequenceFrame.h"
-#include "nsIPermissionManager.h"
-#include "nsIMozBrowserFrame.h"
 #include "nsCaret.h"
 #include "TouchCaret.h"
 #include "SelectionCarets.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsFrameManager.h"
 #include "nsXPCOM.h"
 #include "nsILayoutHistoryState.h"
 #include "nsILineIterator.h" // for ScrollContentIntoView
 #include "pldhash.h"
-#include "mozilla/dom/BeforeAfterKeyboardEventBinding.h"
 #include "mozilla/dom/Touch.h"
 #include "mozilla/dom/PointerEventBinding.h"
 #include "nsIObserverService.h"
 #include "nsDocShell.h"        // for reflow observation
 #include "nsIBaseWindow.h"
 #include "nsError.h"
 #include "nsLayoutUtils.h"
 #include "nsViewportInfo.h"
@@ -704,17 +700,16 @@ nsIPresShell::FrameSelection()
 
 //----------------------------------------------------------------------
 
 static bool sSynthMouseMove = true;
 static uint32_t sNextPresShellId;
 static bool sPointerEventEnabled = true;
 static bool sTouchCaretEnabled = false;
 static bool sSelectionCaretEnabled = false;
-static bool sBeforeAfterKeyboardEventEnabled = false;
 
 /* static */ bool
 PresShell::TouchCaretPrefEnabled()
 {
   static bool initialized = false;
   if (!initialized) {
     Preferences::AddBoolVarCache(&sTouchCaretEnabled, "touchcaret.enabled");
     initialized = true;
@@ -728,28 +723,16 @@ PresShell::SelectionCaretPrefEnabled()
   static bool initialized = false;
   if (!initialized) {
     Preferences::AddBoolVarCache(&sSelectionCaretEnabled, "selectioncaret.enabled");
     initialized = true;
   }
   return sSelectionCaretEnabled;
 }
 
-/* static */ bool
-PresShell::BeforeAfterKeyboardEventEnabled()
-{
-  static bool sInitialized = false;
-  if (!sInitialized) {
-    Preferences::AddBoolVarCache(&sBeforeAfterKeyboardEventEnabled,
-      "dom.beforeAfterKeyboardEvent.enabled");
-    sInitialized = true;
-  }
-  return sBeforeAfterKeyboardEventEnabled;
-}
-
 PresShell::PresShell()
   : mMouseLocation(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)
 {
   mSelection = nullptr;
 #ifdef MOZ_REFLOW_PERF
   mReflowCountMgr = new ReflowCountMgr();
   mReflowCountMgr->SetPresContext(mPresContext);
   mReflowCountMgr->SetPresShell(this);
@@ -6874,246 +6857,16 @@ public:
     mContent = aContent;
   }
 
 private:
   int32_t mPointerId;
   nsCOMPtr<nsIContent> mContent;
 };
 
-static bool
-CheckPermissionForBeforeAfterKeyboardEvent(Element* aElement)
-{
-  // An element which is chrome-privileged should be able to handle before
-  // events and after events.
-  nsIPrincipal* principal = aElement->NodePrincipal();
-  if (nsContentUtils::IsSystemPrincipal(principal)) {
-    return true;
-  }
-
-  // An element which has "before-after-keyboard-event" permission should be
-  // able to handle before events and after events.
-  nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
-  uint32_t permission = nsIPermissionManager::DENY_ACTION;
-  if (permMgr) {
-    permMgr->TestPermissionFromPrincipal(principal, "before-after-keyboard-event", &permission);
-    if (permission == nsIPermissionManager::ALLOW_ACTION) {
-      return true;
-    }
-
-    // Check "embed-apps" permission for later use.
-    permission = nsIPermissionManager::DENY_ACTION;
-    permMgr->TestPermissionFromPrincipal(principal, "embed-apps", &permission);
-  }
-
-  // An element can handle before events and after events if the following
-  // conditions are met:
-  // 1) <iframe mozbrowser mozapp>
-  // 2) it has "embed-apps" permission.
-  nsCOMPtr<nsIMozBrowserFrame> browserFrame(do_QueryInterface(aElement));
-  if ((permission == nsIPermissionManager::ALLOW_ACTION) &&
-      browserFrame && browserFrame->GetReallyIsApp()) {
-    return true;
-  }
-
-  return false;
-}
-
-static void
-BuildTargetChainForBeforeAfterKeyboardEvent(nsINode* aTarget,
-                                            nsTArray<nsCOMPtr<Element> >& aChain,
-                                            bool& aTargetIsIframe)
-{
-  nsCOMPtr<nsIContent> content(do_QueryInterface(aTarget));
-  nsCOMPtr<nsPIDOMWindow> window;
-  Element* frameElement;
-
-  // Initialize frameElement.
-  if (content && content->IsHTML(nsGkAtoms::iframe)) {
-    aTargetIsIframe = true;
-    frameElement = aTarget->AsElement();
-  } else {
-    // If event target is not an iframe, dispatch keydown/keyup event to its
-    // window after dispatching before events to its ancestors.
-    aTargetIsIframe = false;
-
-    // And skip the event target and get its parent frame.
-    window = aTarget->OwnerDoc()->GetWindow();
-    if (window) {
-      frameElement = window->GetFrameElementInternal();
-    }
-  }
-
-  // Check permission for all ancestors and add them into the target chain.
-  while (frameElement) {
-    if (CheckPermissionForBeforeAfterKeyboardEvent(frameElement)) {
-      aChain.AppendElement(frameElement);
-    }
-    window = frameElement->OwnerDoc()->GetWindow();
-    frameElement = window ? window->GetFrameElementInternal() : nullptr;
-  }
-}
-
-void
-PresShell::DispatchBeforeKeyboardEventInternal(const nsTArray<nsCOMPtr<Element> >& aChain,
-                                               const WidgetKeyboardEvent& aEvent,
-                                               size_t& aChainIndex,
-                                               bool& aDefaultPrevented)
-{
-  size_t length = aChain.Length();
-  if (!CanDispatchEvent(&aEvent) || !length) {
-    return;
-  }
-
-  uint32_t message =
-    (aEvent.message == NS_KEY_DOWN) ? NS_KEY_BEFORE_DOWN : NS_KEY_BEFORE_UP;
-  nsCOMPtr<EventTarget> eventTarget;
-  // Dispatch before events from the outermost element.
-  for (int32_t i = length - 1; i >= 0; i--) {
-    eventTarget = do_QueryInterface(aChain[i]->OwnerDoc()->GetWindow());
-    if (!eventTarget || !CanDispatchEvent(&aEvent)) {
-      return;
-    }
-
-    aChainIndex = i;
-    InternalBeforeAfterKeyboardEvent beforeEvent(aEvent.mFlags.mIsTrusted,
-                                                 message, aEvent.widget);
-    beforeEvent.AssignBeforeAfterKeyEventData(aEvent, false);
-    EventDispatcher::Dispatch(eventTarget, mPresContext, &beforeEvent);
-
-    if (beforeEvent.mFlags.mDefaultPrevented) {
-      aDefaultPrevented = true;
-      return;
-    }
-  }
-}
-
-void
-PresShell::DispatchAfterKeyboardEventInternal(const nsTArray<nsCOMPtr<Element> >& aChain,
-                                              const WidgetKeyboardEvent& aEvent,
-                                              bool aEmbeddedCancelled,
-                                              size_t aStartOffset)
-{
-  size_t length = aChain.Length();
-  if (!CanDispatchEvent(&aEvent) || !length) {
-    return;
-  }
-
-  uint32_t message =
-    (aEvent.message == NS_KEY_DOWN) ? NS_KEY_AFTER_DOWN : NS_KEY_AFTER_UP;
-  bool embeddedCancelled = aEmbeddedCancelled;
-  nsCOMPtr<EventTarget> eventTarget;
-  // Dispatch after events from the innermost element.
-  for (uint32_t i = aStartOffset; i < length; i++) {
-    eventTarget = do_QueryInterface(aChain[i]->OwnerDoc()->GetWindow());
-    if (!eventTarget || !CanDispatchEvent(&aEvent)) {
-      return;
-    }
-
-    InternalBeforeAfterKeyboardEvent afterEvent(aEvent.mFlags.mIsTrusted,
-                                                message, aEvent.widget);
-    afterEvent.AssignBeforeAfterKeyEventData(aEvent, false);
-    afterEvent.mEmbeddedCancelled.SetValue(embeddedCancelled);
-    EventDispatcher::Dispatch(eventTarget, mPresContext, &afterEvent);
-    embeddedCancelled = afterEvent.mFlags.mDefaultPrevented;
-  }
-}
-
-void
-PresShell::DispatchAfterKeyboardEvent(nsINode* aTarget,
-                                      const WidgetKeyboardEvent& aEvent,
-                                      bool aEmbeddedCancelled)
-{
-  MOZ_ASSERT(aTarget);
-  MOZ_ASSERT(BeforeAfterKeyboardEventEnabled());
-
-  if (NS_WARN_IF(aEvent.message != NS_KEY_DOWN &&
-                 aEvent.message != NS_KEY_UP)) {
-    return;
-  }
-
-  // Build up a target chain. Each item in the chain will receive an after event.
-  nsAutoTArray<nsCOMPtr<Element>, 5> chain;
-  bool targetIsIframe = false;
-  BuildTargetChainForBeforeAfterKeyboardEvent(aTarget, chain, targetIsIframe);
-  DispatchAfterKeyboardEventInternal(chain, aEvent, aEmbeddedCancelled);
-}
-
-bool
-PresShell::CanDispatchEvent(const WidgetGUIEvent* aEvent) const
-{
-  bool rv =
-    mPresContext && !mHaveShutDown && nsContentUtils::IsSafeToRunScript();
-  if (aEvent) {
-    rv &= (aEvent && aEvent->widget && !aEvent->widget->Destroyed());
-  }
-  return rv;
-}
-
-void
-PresShell::HandleKeyboardEvent(nsINode* aTarget,
-                               WidgetKeyboardEvent& aEvent,
-                               bool aEmbeddedCancelled,
-                               nsEventStatus* aStatus,
-                               EventDispatchingCallback* aEventCB)
-{
-  if (aEvent.message == NS_KEY_PRESS ||
-      !BeforeAfterKeyboardEventEnabled()) {
-    EventDispatcher::Dispatch(aTarget, mPresContext,
-                              &aEvent, nullptr, aStatus, aEventCB);
-    return;
-  }
-
-  MOZ_ASSERT(aTarget);
-  MOZ_ASSERT(aEvent.message == NS_KEY_DOWN || aEvent.message == NS_KEY_UP);
-
-  // Build up a target chain. Each item in the chain will receive a before event.
-  nsAutoTArray<nsCOMPtr<Element>, 5> chain;
-  bool targetIsIframe = false;
-  BuildTargetChainForBeforeAfterKeyboardEvent(aTarget, chain, targetIsIframe);
-
-  // Dispatch before events. If each item in the chain consumes the before
-  // event and doesn't prevent the default action, we will go further to
-  // dispatch the actual key event and after events in the reverse order.
-  // Otherwise, only items which has handled the before event will receive an
-  // after event.
-  size_t chainIndex;
-  bool defaultPrevented = false;
-  DispatchBeforeKeyboardEventInternal(chain, aEvent, chainIndex,
-                                      defaultPrevented);
-
-  // Dispatch after events to partial items.
-  if (defaultPrevented) {
-    DispatchAfterKeyboardEventInternal(chain, aEvent,
-                                       aEvent.mFlags.mDefaultPrevented, chainIndex);
-
-    // No need to forward the event to child process.
-    aEvent.mFlags.mNoCrossProcessBoundaryForwarding = true;
-    return;
-  }
-
-  // Event listeners may kill nsPresContext and nsPresShell.
-  if (!CanDispatchEvent()) {
-    return;
-  }
-
-  // Dispatch actual key event to event target.
-  EventDispatcher::Dispatch(aTarget, mPresContext,
-                            &aEvent, nullptr, aStatus, aEventCB);
-
-  // Event listeners may kill nsPresContext and nsPresShell.
-  if (targetIsIframe || !CanDispatchEvent()) {
-    return;
-  }
-
-  // Dispatch after events to all items in the chain.
-  DispatchAfterKeyboardEventInternal(chain, aEvent,
-                                     aEvent.mFlags.mDefaultPrevented);
-}
-
 nsresult
 PresShell::HandleEvent(nsIFrame* aFrame,
                        WidgetGUIEvent* aEvent,
                        bool aDontRetargetEvents,
                        nsEventStatus* aEventStatus)
 {
 #ifdef MOZ_TASK_TRACER
   // Make touch events, mouse events and hardware key events to be the source
@@ -8108,19 +7861,16 @@ PresShell::HandleEventInternal(WidgetEve
               eventCBPtr = nullptr;
             }
           }
           if (eventTarget) {
             if (aEvent->mClass == eCompositionEventClass) {
               IMEStateManager::DispatchCompositionEvent(eventTarget,
                 mPresContext, aEvent->AsCompositionEvent(), aStatus,
                 eventCBPtr);
-            } else if (aEvent->mClass == eKeyboardEventClass) {
-              HandleKeyboardEvent(eventTarget, *(aEvent->AsKeyboardEvent()),
-                                  false, aStatus, eventCBPtr);
             } else {
               EventDispatcher::Dispatch(eventTarget, mPresContext,
                                         aEvent, nullptr, aStatus, eventCBPtr);
             }
           }
         }
       }
 
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -45,17 +45,16 @@ struct nsCallbackEventRequest;
 class ReflowCountMgr;
 #endif
 
 class nsPresShellEventCB;
 class nsAutoCauseReflowNotifier;
 
 namespace mozilla {
 class CSSStyleSheet;
-class EventDispatchingCallback;
 } // namespace mozilla
 
 // 250ms.  This is actually pref-controlled, but we use this value if we fail
 // to get the pref for any reason.
 #define PAINTLOCK_EVENT_DELAY 250
 
 class PresShell MOZ_FINAL : public nsIPresShell,
                             public nsStubDocumentObserver,
@@ -71,19 +70,16 @@ public:
   NS_DECL_ISUPPORTS
 
   // Touch caret preference
   static bool TouchCaretPrefEnabled();
 
   // Selection caret preference
   static bool SelectionCaretPrefEnabled();
 
-  // BeforeAfterKeyboardEvent preference
-  static bool BeforeAfterKeyboardEventEnabled();
-
   void Init(nsIDocument* aDocument, nsPresContext* aPresContext,
             nsViewManager* aViewManager, nsStyleSet* aStyleSet,
             nsCompatibility aCompatMode);
   virtual void Destroy() MOZ_OVERRIDE;
   virtual void MakeZombie() MOZ_OVERRIDE;
 
   virtual nsresult SetPreferenceStyleRules(bool aForceReflow) MOZ_OVERRIDE;
 
@@ -368,20 +364,16 @@ public:
   virtual void EnsureImageInVisibleList(nsIImageLoadingContent* aImage) MOZ_OVERRIDE;
 
   virtual void RemoveImageFromVisibleList(nsIImageLoadingContent* aImage) MOZ_OVERRIDE;
 
   virtual bool AssumeAllImagesVisible() MOZ_OVERRIDE;
 
   virtual void RecordShadowStyleChange(mozilla::dom::ShadowRoot* aShadowRoot);
 
-  virtual void DispatchAfterKeyboardEvent(nsINode* aTarget,
-                                          const mozilla::WidgetKeyboardEvent& aEvent,
-                                          bool aEmbeddedCancelled) MOZ_OVERRIDE;
-
   void SetNextPaintCompressed() { mNextPaintCompressed = true; }
 
 protected:
   virtual ~PresShell();
 
   void HandlePostedReflowCallbacks(bool aInterruptible);
   void CancelPostedReflowCallbacks();
 
@@ -722,34 +714,16 @@ protected:
 
   void ClearVisibleImagesList();
   static void ClearImageVisibilityVisited(nsView* aView, bool aClear);
   static void MarkImagesInListVisible(const nsDisplayList& aList);
   void MarkImagesInSubtreeVisible(nsIFrame* aFrame, const nsRect& aRect);
 
   void EvictTouches();
 
-  // Methods for dispatching KeyboardEvent and BeforeAfterKeyboardEvent.
-  void HandleKeyboardEvent(nsINode* aTarget,
-                           mozilla::WidgetKeyboardEvent& aEvent,
-                           bool aEmbeddedCancelled,
-                           nsEventStatus* aStatus,
-                           mozilla::EventDispatchingCallback* aEventCB);
-  void DispatchBeforeKeyboardEventInternal(
-         const nsTArray<nsCOMPtr<mozilla::dom::Element> >& aChain,
-         const mozilla::WidgetKeyboardEvent& aEvent,
-         size_t& aChainIndex,
-         bool& aDefaultPrevented);
-  void DispatchAfterKeyboardEventInternal(
-         const nsTArray<nsCOMPtr<mozilla::dom::Element> >& aChain,
-         const mozilla::WidgetKeyboardEvent& aEvent,
-         bool aEmbeddedCancelled,
-         size_t aChainIndex = 0);
-  bool CanDispatchEvent(const mozilla::WidgetGUIEvent* aEvent = nullptr) const;
-
   // A list of images that are visible or almost visible.
   nsTHashtable< nsRefPtrHashKey<nsIImageLoadingContent> > mVisibleImages;
 
 #ifdef DEBUG
   // The reflow root under which we're currently reflowing.  Null when
   // not in reflow.
   nsIFrame*                 mCurrentReflowRoot;
   uint32_t                  mUpdateCount;
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -4344,19 +4344,16 @@ pref("dom.fetch.enabled", false);
 // supported will be disabled. This threshold can be adjusted to suit other
 // platforms; and set to 0 to disable the low-memory check altogether.
 pref("camera.control.low_memory_thresholdMB", 404);
 #endif
 
 // UDPSocket API
 pref("dom.udpsocket.enabled", false);
 
-// Disable before keyboard events and after keyboard events by default.
-pref("dom.beforeAfterKeyboardEvent.enabled", false);
-
 // Experiment: Get TTL from DNS records.
 //     Unset initially (0); Randomly chosen on first run; will remain unchanged
 //     unless adjusted by the user or experiment ends. Variants defined in
 //     nsHostResolver.cpp.
 pref("dns.ttl-experiment.variant", 0);
 pref("dns.ttl-experiment.enabled", true);
 
 // Use raw ICU instead of CoreServices API in Unicode collation
--- a/testing/mochitest/manifest.webapp
+++ b/testing/mochitest/manifest.webapp
@@ -22,18 +22,17 @@
     "camera":{},
     "geolocation":{},
     "wifi-manage":{},
     "desktop-notification":{},
     "idle":{},
     "network-events":{},
     "embed-apps":{},
     "audio-channel-content":{},
-    "audio-channel-alarm":{},
-    "before-after-keyboard-event":{}
+    "audio-channel-alarm":{}
   },
   "locales": {
     "en-US": {
       "name": "Mochitest",
       "description": "Mochitests"
     }
   },
   "datastores-access" : {
--- a/widget/BasicEvents.h
+++ b/widget/BasicEvents.h
@@ -36,21 +36,16 @@
 #define NS_XUL_CLOSE                    (NS_WINDOW_START + 1)
 // Key is pressed within a window
 #define NS_KEY_PRESS                    (NS_WINDOW_START + 31)
 // Key is released within a window
 #define NS_KEY_UP                       (NS_WINDOW_START + 32)
 // Key is pressed within a window
 #define NS_KEY_DOWN                     (NS_WINDOW_START + 33)
 
-#define NS_KEY_BEFORE_DOWN              (NS_WINDOW_START + 34)
-#define NS_KEY_AFTER_DOWN               (NS_WINDOW_START + 35)
-#define NS_KEY_BEFORE_UP                (NS_WINDOW_START + 36)
-#define NS_KEY_AFTER_UP                 (NS_WINDOW_START + 37)
-
 #define NS_RESIZE_EVENT                 (NS_WINDOW_START + 60)
 #define NS_SCROLL_EVENT                 (NS_WINDOW_START + 61)
 
 // A plugin was clicked or otherwise focused. NS_PLUGIN_ACTIVATE should be
 // used when the window is not active. NS_PLUGIN_FOCUS should be used when
 // the window is active. In the latter case, the dispatcher of the event
 // is expected to ensure that the plugin's widget is focused beforehand.
 #define NS_PLUGIN_ACTIVATE               (NS_WINDOW_START + 62)
--- a/widget/EventClassList.h
+++ b/widget/EventClassList.h
@@ -21,17 +21,16 @@ NS_EVENT_CLASS(Widget, InputEvent)
 NS_EVENT_CLASS(Internal, UIEvent)
 
 // TextEvents.h
 NS_EVENT_CLASS(Widget, KeyboardEvent)
 NS_EVENT_CLASS(Widget, CompositionEvent)
 NS_EVENT_CLASS(Widget, QueryContentEvent)
 NS_EVENT_CLASS(Widget, SelectionEvent)
 NS_EVENT_CLASS(Internal, EditorInputEvent)
-NS_EVENT_CLASS(Internal, BeforeAfterKeyboardEvent)
 
 // MouseEvents.h
 NS_EVENT_CLASS(Widget, MouseEventBase)
 NS_EVENT_CLASS(Widget, MouseEvent)
 NS_EVENT_CLASS(Widget, DragEvent)
 NS_EVENT_CLASS(Widget, MouseScrollEvent)
 NS_EVENT_CLASS(Widget, WheelEvent)
 NS_EVENT_CLASS(Widget, PointerEvent)
--- a/widget/TextEvents.h
+++ b/widget/TextEvents.h
@@ -70,27 +70,25 @@ struct AlternativeCharCode
  ******************************************************************************/
 
 class WidgetKeyboardEvent : public WidgetInputEvent
 {
 private:
   friend class dom::PBrowserParent;
   friend class dom::PBrowserChild;
 
-protected:
   WidgetKeyboardEvent()
   {
   }
 
 public:
   virtual WidgetKeyboardEvent* AsKeyboardEvent() MOZ_OVERRIDE { return this; }
 
-  WidgetKeyboardEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget,
-                      EventClassID aEventClassID = eKeyboardEventClass)
-    : WidgetInputEvent(aIsTrusted, aMessage, aWidget, aEventClassID)
+  WidgetKeyboardEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget)
+    : WidgetInputEvent(aIsTrusted, aMessage, aWidget, eKeyboardEventClass)
     , keyCode(0)
     , charCode(0)
     , location(nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD)
     , isChar(false)
     , mIsRepeat(false)
     , mIsComposing(false)
     , mKeyNameIndex(mozilla::KEY_NAME_INDEX_Unidentified)
     , mCodeNameIndex(CODE_NAME_INDEX_UNKNOWN)
@@ -191,82 +189,16 @@ public:
     mCodeValue = aEvent.mCodeValue;
     // Don't copy mNativeKeyEvent because it may be referred after its instance
     // is destroyed.
     mNativeKeyEvent = nullptr;
     mUniqueId = aEvent.mUniqueId;
   }
 };
 
-
-/******************************************************************************
- * mozilla::InternalBeforeAfterKeyboardEvent
- *
- * This is extended from WidgetKeyboardEvent and is mapped to DOM event
- * "BeforeAfterKeyboardEvent".
- *
- * Event message: NS_KEY_BEFORE_DOWN
- *                NS_KEY_BEFORE_UP
- *                NS_KEY_AFTER_DOWN
- *                NS_KEY_AFTER_UP
- ******************************************************************************/
-class InternalBeforeAfterKeyboardEvent : public WidgetKeyboardEvent
-{
-private:
-  friend class dom::PBrowserParent;
-  friend class dom::PBrowserChild;
-
-  InternalBeforeAfterKeyboardEvent()
-  {
-  }
-
-public:
-  // Extra member for InternalBeforeAfterKeyboardEvent. Indicates whether
-  // default actions of keydown/keyup event is prevented.
-  Nullable<bool> mEmbeddedCancelled;
-
-  virtual InternalBeforeAfterKeyboardEvent* AsBeforeAfterKeyboardEvent() MOZ_OVERRIDE
-  {
-    return this;
-  }
-
-  InternalBeforeAfterKeyboardEvent(bool aIsTrusted, uint32_t aMessage,
-                                   nsIWidget* aWidget)
-    : WidgetKeyboardEvent(aIsTrusted, aMessage, aWidget, eBeforeAfterKeyboardEventClass)
-  {
-  }
-
-  virtual WidgetEvent* Duplicate() const MOZ_OVERRIDE
-  {
-    MOZ_ASSERT(mClass == eBeforeAfterKeyboardEventClass,
-               "Duplicate() must be overridden by sub class");
-    // Not copying widget, it is a weak reference.
-    InternalBeforeAfterKeyboardEvent* result =
-      new InternalBeforeAfterKeyboardEvent(false, message, nullptr);
-    result->AssignBeforeAfterKeyEventData(*this, true);
-    result->mFlags = mFlags;
-    return result;
-  }
-
-  void AssignBeforeAfterKeyEventData(
-         const InternalBeforeAfterKeyboardEvent& aEvent,
-         bool aCopyTargets)
-  {
-    AssignKeyEventData(aEvent, aCopyTargets);
-    mEmbeddedCancelled = aEvent.mEmbeddedCancelled;
-  }
-
-  void AssignBeforeAfterKeyEventData(
-         const WidgetKeyboardEvent& aEvent,
-         bool aCopyTargets)
-  {
-    AssignKeyEventData(aEvent, aCopyTargets);
-  }
-};
-
 /******************************************************************************
  * mozilla::WidgetCompositionEvent
  ******************************************************************************/
 
 class WidgetCompositionEvent : public WidgetGUIEvent
 {
 private:
   friend class mozilla::dom::PBrowserParent;
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -358,47 +358,16 @@ struct ParamTraits<mozilla::WidgetKeyboa
       aResult->mNativeKeyEvent = nullptr;
       return true;
     }
     return false;
   }
 };
 
 template<>
-struct ParamTraits<mozilla::InternalBeforeAfterKeyboardEvent>
-{
-  typedef mozilla::InternalBeforeAfterKeyboardEvent paramType;
-
-  static void Write(Message* aMsg, const paramType& aParam)
-  {
-    WriteParam(aMsg, static_cast<mozilla::WidgetKeyboardEvent>(aParam));
-    WriteParam(aMsg, aParam.mEmbeddedCancelled.IsNull());
-    WriteParam(aMsg, aParam.mEmbeddedCancelled.Value());
-  }
-
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
-  {
-    bool isNull;
-    bool value;
-    bool rv =
-      ReadParam(aMsg, aIter,
-                static_cast<mozilla::WidgetKeyboardEvent*>(aResult)) &&
-      ReadParam(aMsg, aIter, &isNull) &&
-      ReadParam(aMsg, aIter, &value);
-
-    aResult->mEmbeddedCancelled = Nullable<bool>();
-    if (rv && !isNull) {
-      aResult->mEmbeddedCancelled.SetValue(value);
-    }
-
-    return rv;
-  }
-};
-
-template<>
 struct ParamTraits<mozilla::TextRangeStyle>
 {
   typedef mozilla::TextRangeStyle paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mDefinedStyles);
     WriteParam(aMsg, aParam.mLineStyle);
--- a/widget/shared/WidgetEventImpl.cpp
+++ b/widget/shared/WidgetEventImpl.cpp
@@ -117,20 +117,16 @@ WidgetEvent::HasDragEventMessage() const
 
 bool
 WidgetEvent::HasKeyEventMessage() const
 {
   switch (message) {
     case NS_KEY_DOWN:
     case NS_KEY_PRESS:
     case NS_KEY_UP:
-    case NS_KEY_BEFORE_DOWN:
-    case NS_KEY_BEFORE_UP:
-    case NS_KEY_AFTER_DOWN:
-    case NS_KEY_AFTER_UP:
       return true;
     default:
       return false;
   }
 }
 
 bool
 WidgetEvent::HasIMEEventMessage() const