Bug 915757: Split GetListenerManager into two functions for more const-correctness. r=smaug
☠☠ backed out by 2a4109a72ff7 ☠ ☠
authorKyle Huey <khuey@kylehuey.com>
Mon, 16 Sep 2013 09:06:02 +0800
changeset 161177 e385645fb787a4666ecf79f45fe5bfb8a5034234
parent 161176 39d11ad40510628e40e8f694c2d3d97563f1f910
child 161178 c00c7a77c130de81e05f7e45936668475ebc43e0
push id407
push userlsblakk@mozilla.com
push dateTue, 03 Dec 2013 03:32:50 +0000
treeherdermozilla-release@babf8c9ebc52 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs915757
milestone26.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
Bug 915757: Split GetListenerManager into two functions for more const-correctness. r=smaug
accessible/src/base/DocManager.cpp
accessible/src/base/nsCoreUtils.cpp
content/base/public/nsContentUtils.h
content/base/public/nsINode.h
content/base/src/Element.cpp
content/base/src/FragmentOrElement.cpp
content/base/src/nsCCUncollectableMarker.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
content/base/src/nsINode.cpp
content/base/src/nsNodeUtils.cpp
content/base/src/nsXMLHttpRequest.cpp
content/events/src/EventTarget.cpp
content/events/src/nsDOMEventTargetHelper.cpp
content/events/src/nsDOMEventTargetHelper.h
content/events/src/nsEventDispatcher.cpp
content/events/src/nsEventListenerManager.h
content/events/src/nsEventListenerService.cpp
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsTextEditorState.cpp
content/smil/nsSMILTimeValueSpec.cpp
content/svg/content/src/nsSVGElement.cpp
content/xbl/src/nsXBLBinding.cpp
content/xbl/src/nsXBLService.cpp
content/xul/content/src/nsXULElement.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsWindowRoot.cpp
dom/base/nsWindowRoot.h
dom/devicestorage/DeviceStorage.h
dom/devicestorage/nsDeviceStorage.cpp
dom/interfaces/events/nsIDOMEventTarget.idl
dom/ipc/TabChild.cpp
editor/libeditor/base/nsEditorEventListener.cpp
embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
layout/base/PositionedEventTargeting.cpp
layout/base/nsPresContext.cpp
--- a/accessible/src/base/DocManager.cpp
+++ b/accessible/src/base/DocManager.cpp
@@ -324,17 +324,17 @@ DocManager::HandleDOMDocumentLoad(nsIDoc
 }
 
 void
 DocManager::AddListeners(nsIDocument* aDocument,
                          bool aAddDOMContentLoadedListener)
 {
   nsPIDOMWindow* window = aDocument->GetWindow();
   EventTarget* target = window->GetChromeEventHandler();
-  nsEventListenerManager* elm = target->GetListenerManager(true);
+  nsEventListenerManager* elm = target->ListenerManager();
   elm->AddEventListenerByType(this, NS_LITERAL_STRING("pagehide"),
                               dom::TrustedEventsAtCapture());
 
 #ifdef A11Y_LOG
   if (logging::IsEnabled(logging::eDocCreate))
     logging::Text("added 'pagehide' listener");
 #endif
 
@@ -354,17 +354,17 @@ DocManager::RemoveListeners(nsIDocument*
   nsPIDOMWindow* window = aDocument->GetWindow();
   if (!window)
     return;
 
   EventTarget* target = window->GetChromeEventHandler();
   if (!target)
     return;
 
-  nsEventListenerManager* elm = target->GetListenerManager(true);
+  nsEventListenerManager* elm = target->ListenerManager();
   elm->RemoveEventListenerByType(this, NS_LITERAL_STRING("pagehide"),
                                  dom::TrustedEventsAtCapture());
 
   elm->RemoveEventListenerByType(this, NS_LITERAL_STRING("DOMContentLoaded"),
                                  dom::TrustedEventsAtCapture());
 }
 
 DocAccessible*
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -40,17 +40,17 @@ using namespace mozilla;
 // nsCoreUtils
 ////////////////////////////////////////////////////////////////////////////////
 
 bool
 nsCoreUtils::HasClickListener(nsIContent *aContent)
 {
   NS_ENSURE_TRUE(aContent, false);
   nsEventListenerManager* listenerManager =
-    aContent->GetListenerManager(false);
+    aContent->GetExistingListenerManager();
 
   return listenerManager &&
     (listenerManager->HasListenersFor(nsGkAtoms::onclick) ||
      listenerManager->HasListenersFor(nsGkAtoms::onmousedown) ||
      listenerManager->HasListenersFor(nsGkAtoms::onmouseup));
 }
 
 void
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1049,25 +1049,29 @@ public:
    *
    * @param aNode The node to traverse.
    * @param children The buffer to push a listener manager pointer into.
    */
   static void TraverseListenerManager(nsINode *aNode,
                                       nsCycleCollectionTraversalCallback &cb);
 
   /**
-   * Get the eventlistener manager for aNode. If a new eventlistener manager
-   * was created, aCreated is set to true.
+   * Get the eventlistener manager for aNode, creating it if it does not
+   * already exist.
    *
    * @param aNode The node for which to get the eventlistener manager.
-   * @param aCreateIfNotFound If false, returns a listener manager only if
-   *                          one already exists.
    */
-  static nsEventListenerManager* GetListenerManager(nsINode* aNode,
-                                                    bool aCreateIfNotFound);
+  static nsEventListenerManager* ListenerManagerForNode(nsINode* aNode);
+  /**
+   * Get the eventlistener manager for aNode, returning null if it does not
+   * already exist.
+   *
+   * @param aNode The node for which to get the eventlistener manager.
+   */
+  static nsEventListenerManager* GetExistingListenerManagerForNode(const nsINode* aNode);
 
   static void UnmarkGrayJSListenersInCCGenerationDocuments(uint32_t aGeneration);
 
   /**
    * Remove the eventlistener manager for aNode.
    *
    * @param aNode The node for which to remove the eventlistener manager.
    */
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -793,17 +793,17 @@ public:
     }
 #endif
     return node;
   }
 
   /**
    * See nsIDOMEventTarget
    */
-  NS_DECL_NSIDOMEVENTTARGET
+  NS_REALLY_DECL_NSIDOMEVENTTARGET
   using mozilla::dom::EventTarget::RemoveEventListener;
   using nsIDOMEventTarget::AddEventListener;
   virtual void AddEventListener(const nsAString& aType,
                                 nsIDOMEventListener* aListener,
                                 bool aUseCapture,
                                 const mozilla::dom::Nullable<bool>& aWantsUntrusted,
                                 mozilla::ErrorResult& aRv) MOZ_OVERRIDE;
   using nsIDOMEventTarget::AddSystemEventListener;
--- a/content/base/src/Element.cpp
+++ b/content/base/src/Element.cpp
@@ -1772,17 +1772,17 @@ Element::SetMappedAttribute(nsIDocument*
   return false;
 }
 
 nsEventListenerManager*
 Element::GetEventListenerManagerForAttr(nsIAtom* aAttrName,
                                         bool* aDefer)
 {
   *aDefer = true;
-  return GetListenerManager(true);
+  return ListenerManager();
 }
 
 Element::nsAttrInfo
 Element::GetAttrInfo(int32_t aNamespaceID, nsIAtom* aName) const
 {
   NS_ASSERTION(nullptr != aName, "must have attribute name");
   NS_ASSERTION(aNamespaceID != kNameSpaceID_Unknown,
                "must have a real namespace ID!");
--- a/content/base/src/FragmentOrElement.cpp
+++ b/content/base/src/FragmentOrElement.cpp
@@ -1220,17 +1220,17 @@ FragmentOrElement::MarkUserDataHandler(v
 void
 FragmentOrElement::MarkNodeChildren(nsINode* aNode)
 {
   JSObject* o = GetJSObjectChild(aNode);
   if (o) {
     JS::ExposeObjectToActiveJS(o);
   }
 
-  nsEventListenerManager* elm = aNode->GetListenerManager(false);
+  nsEventListenerManager* elm = aNode->GetExistingListenerManager();
   if (elm) {
     elm->MarkForCC();
   }
 
   if (aNode->HasProperties()) {
     nsIDocument* ownerDoc = aNode->OwnerDoc();
     ownerDoc->PropertyTable(DOM_USER_DATA)->
       Enumerate(aNode, FragmentOrElement::MarkUserData,
--- a/content/base/src/nsCCUncollectableMarker.cpp
+++ b/content/base/src/nsCCUncollectableMarker.cpp
@@ -139,17 +139,17 @@ MarkMessageManagers()
         static_cast<nsFrameMessageManager*>(tabMM)->GetCallback();
       if (cb) {
         nsFrameLoader* fl = static_cast<nsFrameLoader*>(cb);
         EventTarget* et = fl->GetTabChildGlobalAsEventTarget();
         if (!et) {
           continue;
         }
         static_cast<nsInProcessTabChildGlobal*>(et)->MarkForCC();
-        nsEventListenerManager* elm = et->GetListenerManager(false);
+        nsEventListenerManager* elm = et->GetExistingListenerManager();
         if (elm) {
           elm->MarkForCC();
         }
       }
     }
   }
   if (nsFrameMessageManager::sParentProcessManager) {
     nsFrameMessageManager::sParentProcessManager->MarkForCC();
@@ -183,23 +183,23 @@ MarkContentViewer(nsIContentViewer* aVie
     return;
   }
 
   nsIDocument *doc = aViewer->GetDocument();
   if (doc &&
       doc->GetMarkedCCGeneration() != nsCCUncollectableMarker::sGeneration) {
     doc->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration);
     if (aCleanupJS) {
-      nsEventListenerManager* elm = doc->GetListenerManager(false);
+      nsEventListenerManager* elm = doc->GetExistingListenerManager();
       if (elm) {
         elm->MarkForCC();
       }
       nsCOMPtr<EventTarget> win = do_QueryInterface(doc->GetInnerWindow());
       if (win) {
-        elm = win->GetListenerManager(false);
+        elm = win->GetExistingListenerManager();
         if (elm) {
           elm->MarkForCC();
         }
         static_cast<nsGlobalWindow*>(win.get())->UnmarkGrayTimers();
       }
 
       doc->PropertyTable(DOM_USER_DATA_HANDLER)->
         EnumerateAll(MarkUserDataHandler, &nsCCUncollectableMarker::sGeneration);
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -3612,28 +3612,28 @@ nsContentUtils::HasMutationListeners(nsI
   }
 
   doc->MayDispatchMutationEvent(aTargetForSubtreeModified);
 
   // If we have a window, we can check it for mutation listeners now.
   if (aNode->IsInDoc()) {
     nsCOMPtr<EventTarget> piTarget(do_QueryInterface(window));
     if (piTarget) {
-      nsEventListenerManager* manager = piTarget->GetListenerManager(false);
+      nsEventListenerManager* manager = piTarget->GetExistingListenerManager();
       if (manager && manager->HasMutationListeners()) {
         return true;
       }
     }
   }
 
   // If we have a window, we know a mutation listener is registered, but it
   // might not be in our chain.  If we don't have a window, we might have a
   // mutation listener.  Check quickly to see.
   while (aNode) {
-    nsEventListenerManager* manager = aNode->GetListenerManager(false);
+    nsEventListenerManager* manager = aNode->GetExistingListenerManager();
     if (manager && manager->HasMutationListeners()) {
       return true;
     }
 
     if (aNode->IsNodeOfType(nsINode::eCONTENT)) {
       nsIContent* content = static_cast<nsIContent*>(aNode);
       nsIContent* insertionParent = content->GetXBLInsertionParent();
       if (insertionParent) {
@@ -3745,41 +3745,25 @@ nsContentUtils::TraverseListenerManager(
                                         PL_DHASH_LOOKUP));
   if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
     CycleCollectionNoteChild(cb, entry->mListenerManager.get(),
                              "[via hash] mListenerManager");
   }
 }
 
 nsEventListenerManager*
-nsContentUtils::GetListenerManager(nsINode *aNode,
-                                   bool aCreateIfNotFound)
-{
-  if (!aCreateIfNotFound && !aNode->HasFlag(NODE_HAS_LISTENERMANAGER)) {
-    return nullptr;
-  }
-  
+nsContentUtils::ListenerManagerForNode(nsINode *aNode)
+{
   if (!sEventListenerManagersHash.ops) {
     // We're already shut down, don't bother creating an event listener
     // manager.
 
     return nullptr;
   }
 
-  if (!aCreateIfNotFound) {
-    EventListenerManagerMapEntry *entry =
-      static_cast<EventListenerManagerMapEntry *>
-                 (PL_DHashTableOperate(&sEventListenerManagersHash, aNode,
-                                          PL_DHASH_LOOKUP));
-    if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
-      return entry->mListenerManager;
-    }
-    return nullptr;
-  }
-
   EventListenerManagerMapEntry *entry =
     static_cast<EventListenerManagerMapEntry *>
                (PL_DHashTableOperate(&sEventListenerManagersHash, aNode,
                                         PL_DHASH_ADD));
 
   if (!entry) {
     return nullptr;
   }
@@ -3788,16 +3772,41 @@ nsContentUtils::GetListenerManager(nsINo
     entry->mListenerManager = new nsEventListenerManager(aNode);
 
     aNode->SetFlags(NODE_HAS_LISTENERMANAGER);
   }
 
   return entry->mListenerManager;
 }
 
+nsEventListenerManager*
+nsContentUtils::GetExistingListenerManagerForNode(const nsINode *aNode)
+{
+  if (!aNode->HasFlag(NODE_HAS_LISTENERMANAGER)) {
+    return nullptr;
+  }
+  
+  if (!sEventListenerManagersHash.ops) {
+    // We're already shut down, don't bother creating an event listener
+    // manager.
+
+    return nullptr;
+  }
+
+  EventListenerManagerMapEntry *entry =
+    static_cast<EventListenerManagerMapEntry *>
+               (PL_DHashTableOperate(&sEventListenerManagersHash, aNode,
+                                        PL_DHASH_LOOKUP));
+  if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
+    return entry->mListenerManager;
+  }
+
+  return nullptr;
+}
+
 /* static */
 void
 nsContentUtils::RemoveListenerManager(nsINode *aNode)
 {
   if (sEventListenerManagersHash.ops) {
     EventListenerManagerMapEntry *entry =
       static_cast<EventListenerManagerMapEntry *>
                  (PL_DHashTableOperate(&sEventListenerManagersHash, aNode,
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1609,17 +1609,17 @@ nsDocument::Release()
 NS_IMETHODIMP_(void)
 nsDocument::DeleteCycleCollectable()
 {
   delete this;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsDocument)
   if (Element::CanSkip(tmp, aRemovingAllowed)) {
-    nsEventListenerManager* elm = tmp->GetListenerManager(false);
+    nsEventListenerManager* elm = tmp->GetExistingListenerManager();
     if (elm) {
       elm->MarkForCC();
     }
     return true;
   }
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsDocument)
@@ -6921,27 +6921,33 @@ nsDocument::GetViewportInfo(const Screen
     }
 
     return nsViewportInfo(scaleFloat, scaleMinFloat, scaleMaxFloat, size,
                           mAutoSize, mAllowZoom);
   }
 }
 
 nsEventListenerManager*
-nsDocument::GetListenerManager(bool aCreateIfNotFound)
-{
-  if (!mListenerManager && aCreateIfNotFound) {
+nsDocument::ListenerManager()
+{
+  if (!mListenerManager) {
     mListenerManager =
       new nsEventListenerManager(static_cast<EventTarget*>(this));
     SetFlags(NODE_HAS_LISTENERMANAGER);
   }
 
   return mListenerManager;
 }
 
+nsEventListenerManager*
+nsDocument::GetExistingListenerManager() const
+{
+  return mListenerManager;
+}
+
 nsresult
 nsDocument::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   aVisitor.mCanHandle = true;
    // FIXME! This is a hack to make middle mouse paste working also in Editor.
    // Bug 329119
   aVisitor.mForceContentDispatch = true;
 
@@ -7625,18 +7631,17 @@ nsDocument::CanSavePresentation(nsIReque
   nsPIDOMWindow* win = GetInnerWindow();
   if (win && win->TimeoutSuspendCount()) {
     return false;
   }
 
   // Check our event listener manager for unload/beforeunload listeners.
   nsCOMPtr<EventTarget> piTarget = do_QueryInterface(mScriptGlobalObject);
   if (piTarget) {
-    nsEventListenerManager* manager =
-      piTarget->GetListenerManager(false);
+    nsEventListenerManager* manager = piTarget->GetExistingListenerManager();
     if (manager && manager->HasUnloadListeners()) {
       return false;
     }
   }
 
   // Check if we have pending network requests
   nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
   if (loadGroup) {
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -769,18 +769,18 @@ public:
   // nsIDOMXMLDocument
   NS_DECL_NSIDOMXMLDOCUMENT
 
   // nsIDOMDocumentXBL
   NS_DECL_NSIDOMDOCUMENTXBL
 
   // nsIDOMEventTarget
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
-  virtual nsEventListenerManager*
-    GetListenerManager(bool aCreateIfNotFound) MOZ_OVERRIDE;
+  virtual nsEventListenerManager* ListenerManager() MOZ_OVERRIDE;
+  virtual nsEventListenerManager* GetExistingListenerManager() const MOZ_OVERRIDE;
 
   // nsIScriptObjectPrincipal
   virtual nsIPrincipal* GetPrincipal() MOZ_OVERRIDE;
 
   // nsIApplicationCacheContainer
   NS_DECL_NSIAPPLICATIONCACHECONTAINER
 
   // nsIObserver
--- a/content/base/src/nsINode.cpp
+++ b/content/base/src/nsINode.cpp
@@ -1034,17 +1034,17 @@ nsINode::AddEventListener(const nsAStrin
                "explicit by making aOptionalArgc non-zero.");
 
   if (!aWantsUntrusted &&
       (aOptionalArgc < 2 &&
        !nsContentUtils::IsChromeDoc(OwnerDoc()))) {
     aWantsUntrusted = true;
   }
 
-  nsEventListenerManager* listener_manager = GetListenerManager(true);
+  nsEventListenerManager* listener_manager = ListenerManager();
   NS_ENSURE_STATE(listener_manager);
   listener_manager->AddEventListener(aType, aListener, aUseCapture,
                                      aWantsUntrusted);
   return NS_OK;
 }
 
 void
 nsINode::AddEventListener(const nsAString& aType,
@@ -1055,17 +1055,17 @@ nsINode::AddEventListener(const nsAStrin
 {
   bool wantsUntrusted;
   if (aWantsUntrusted.IsNull()) {
     wantsUntrusted = !nsContentUtils::IsChromeDoc(OwnerDoc());
   } else {
     wantsUntrusted = aWantsUntrusted.Value();
   }
 
-  nsEventListenerManager* listener_manager = GetListenerManager(true);
+  nsEventListenerManager* listener_manager = ListenerManager();
   if (!listener_manager) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return;
   }
   listener_manager->AddEventListener(aType, aListener, aUseCapture,
                                      wantsUntrusted);
 }
 
@@ -1091,17 +1091,17 @@ nsINode::AddSystemEventListener(const ns
                                    aWantsUntrusted);
 }
 
 NS_IMETHODIMP
 nsINode::RemoveEventListener(const nsAString& aType,
                              nsIDOMEventListener* aListener,
                              bool aUseCapture)
 {
-  nsEventListenerManager* elm = GetListenerManager(false);
+  nsEventListenerManager* elm = GetExistingListenerManager();
   if (elm) {
     elm->RemoveEventListener(aType, aListener, aUseCapture);
   }
   return NS_OK;
 }
 
 NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsINode)
 
@@ -1153,19 +1153,25 @@ nsINode::DispatchDOMEvent(nsEvent* aEven
                           nsPresContext* aPresContext,
                           nsEventStatus* aEventStatus)
 {
   return nsEventDispatcher::DispatchDOMEvent(this, aEvent, aDOMEvent,
                                              aPresContext, aEventStatus);
 }
 
 nsEventListenerManager*
-nsINode::GetListenerManager(bool aCreateIfNotFound)
+nsINode::ListenerManager()
 {
-  return nsContentUtils::GetListenerManager(this, aCreateIfNotFound);
+  return nsContentUtils::ListenerManagerForNode(this);
+}
+
+nsEventListenerManager*
+nsINode::GetExistingListenerManager() const
+{
+  return nsContentUtils::GetExistingListenerManagerForNode(this);
 }
 
 nsIScriptContext*
 nsINode::GetContextForEventHandlers(nsresult* aRv)
 {
   return nsContentUtils::GetContextForEventHandlers(this, aRv);
 }
 
@@ -2160,18 +2166,17 @@ nsINode::GetBoundMutationObservers(nsTAr
     }
   }
 }
 
 size_t
 nsINode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
 {
   size_t n = 0;
-  nsEventListenerManager* elm =
-    const_cast<nsINode*>(this)->GetListenerManager(false);
+  nsEventListenerManager* elm = GetExistingListenerManager();
   if (elm) {
     n += elm->SizeOfIncludingThis(aMallocSizeOf);
   }
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mNodeInfo
   // - mSlots
@@ -2179,23 +2184,23 @@ nsINode::SizeOfExcludingThis(MallocSizeO
   // The following members are not measured:
   // - mParent, mNextSibling, mPreviousSibling, mFirstChild: because they're
   //   non-owning
   return n;
 }
 
 #define EVENT(name_, id_, type_, struct_)                                    \
   EventHandlerNonNull* nsINode::GetOn##name_() {                             \
-    nsEventListenerManager *elm = GetListenerManager(false);                 \
+    nsEventListenerManager *elm = GetExistingListenerManager();              \
     return elm ? elm->GetEventHandler(nsGkAtoms::on##name_, EmptyString())   \
                : nullptr;                                                    \
   }                                                                          \
   void nsINode::SetOn##name_(EventHandlerNonNull* handler,                   \
                              ErrorResult& error) {                           \
-    nsEventListenerManager *elm = GetListenerManager(true);                  \
+    nsEventListenerManager *elm = ListenerManager();                         \
     if (elm) {                                                               \
       error = elm->SetEventHandler(nsGkAtoms::on##name_,                     \
                                    EmptyString(), handler);                  \
     } else {                                                                 \
       error.Throw(NS_ERROR_OUT_OF_MEMORY);                                   \
     }                                                                        \
   }                                                                          \
   NS_IMETHODIMP nsINode::GetOn##name_(JSContext *cx, JS::Value *vp) {        \
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -226,17 +226,17 @@ nsNodeUtils::LastRelease(nsINode* aNode)
   }
   aNode->UnsetFlags(NODE_HAS_PROPERTIES);
 
   if (aNode->NodeType() != nsIDOMNode::DOCUMENT_NODE &&
       aNode->HasFlag(NODE_HAS_LISTENERMANAGER)) {
 #ifdef DEBUG
     if (nsContentUtils::IsInitialized()) {
       nsEventListenerManager* manager =
-        nsContentUtils::GetListenerManager(aNode, false);
+        nsContentUtils::GetExistingListenerManagerForNode(aNode);
       if (!manager) {
         NS_ERROR("Huh, our bit says we have a listener manager list, "
                  "but there's nothing in the hash!?!!");
       }
     }
 #endif
 
     nsContentUtils::RemoveListenerManager(aNode);
@@ -475,17 +475,17 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
       // XXX what if oldDoc is null, we don't know if this should be
       // registered or not! Can that really happen?
       if (wasRegistered) {
         newDoc->RegisterFreezableElement(aNode->AsElement());
       }
 
       nsPIDOMWindow* window = newDoc->GetInnerWindow();
       if (window) {
-        nsEventListenerManager* elm = aNode->GetListenerManager(false);
+        nsEventListenerManager* elm = aNode->GetExistingListenerManager();
         if (elm) {
           window->SetMutationListeners(elm->MutationListenerBits());
           if (elm->MayHavePaintEventListener()) {
             window->SetHasPaintEventListeners();
           }
           if (elm->MayHaveAudioAvailableEventListener()) {
             window->SetHasAudioAvailableEventListeners();
           }
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -2168,17 +2168,17 @@ nsXMLHttpRequest::OnStopRequest(nsIReque
   if (!mResponseXML) {
     ChangeStateToDone();
     return NS_OK;
   }
   if (mIsHtml) {
     NS_ASSERTION(!(mState & XML_HTTP_REQUEST_SYNCLOOPING),
       "We weren't supposed to support HTML parsing with XHR!");
     nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(mResponseXML);
-    nsEventListenerManager* manager = eventTarget->GetListenerManager(true);
+    nsEventListenerManager* manager = eventTarget->ListenerManager();
     manager->AddEventListenerByType(new nsXHRParseEndListener(this),
                                     NS_LITERAL_STRING("DOMContentLoaded"),
                                     dom::TrustedEventsAtSystemGroupBubble());
     return NS_OK;
   }
   // We might have been sent non-XML data. If that was the case,
   // we should null out the document member. The idea in this
   // check here is that if there is no document element it is not
--- a/content/events/src/EventTarget.cpp
+++ b/content/events/src/EventTarget.cpp
@@ -11,26 +11,26 @@ namespace mozilla {
 namespace dom {
 
 void
 EventTarget::RemoveEventListener(const nsAString& aType,
                                  nsIDOMEventListener* aListener,
                                  bool aUseCapture,
                                  ErrorResult& aRv)
 {
-  nsEventListenerManager* elm = GetListenerManager(false);
+  nsEventListenerManager* elm = GetExistingListenerManager();
   if (elm) {
     elm->RemoveEventListener(aType, aListener, aUseCapture);
   }
 }
 
 EventHandlerNonNull*
 EventTarget::GetEventHandler(nsIAtom* aType, const nsAString& aTypeString)
 {
-  nsEventListenerManager* elm = GetListenerManager(false);
+  nsEventListenerManager* elm = GetExistingListenerManager();
   return elm ? elm->GetEventHandler(aType, aTypeString) : nullptr;
 }
 
 void
 EventTarget::SetEventHandler(const nsAString& aType,
                              EventHandlerNonNull* aHandler,
                              ErrorResult& rv)
 {
@@ -43,15 +43,13 @@ EventTarget::SetEventHandler(const nsASt
                          aHandler, rv);
 }
 
 void
 EventTarget::SetEventHandler(nsIAtom* aType, const nsAString& aTypeString,
                              EventHandlerNonNull* aHandler,
                              ErrorResult& rv)
 {
-  rv = GetListenerManager(true)->SetEventHandler(aType,
-                                                 aTypeString,
-                                                 aHandler);
+  rv = ListenerManager()->SetEventHandler(aType, aTypeString, aHandler);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/content/events/src/nsDOMEventTargetHelper.cpp
+++ b/content/events/src/nsDOMEventTargetHelper.cpp
@@ -149,17 +149,17 @@ nsDOMEventTargetHelper::DisconnectFromOw
   }
 }
 
 NS_IMETHODIMP
 nsDOMEventTargetHelper::RemoveEventListener(const nsAString& aType,
                                             nsIDOMEventListener* aListener,
                                             bool aUseCapture)
 {
-  nsEventListenerManager* elm = GetListenerManager(false);
+  nsEventListenerManager* elm = GetExistingListenerManager();
   if (elm) {
     elm->RemoveEventListener(aType, aListener, aUseCapture);
   }
 
   return NS_OK;
 }
 
 NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsDOMEventTargetHelper)
@@ -176,17 +176,17 @@ nsDOMEventTargetHelper::AddEventListener
                "aWantsUntrusted to false or make the aWantsUntrusted "
                "explicit by making aOptionalArgc non-zero.");
 
   if (aOptionalArgc < 2) {
     nsresult rv = WantsUntrusted(&aWantsUntrusted);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  nsEventListenerManager* elm = GetListenerManager(true);
+  nsEventListenerManager* elm = ListenerManager();
   NS_ENSURE_STATE(elm);
   elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
   return NS_OK;
 }
 
 void
 nsDOMEventTargetHelper::AddEventListener(const nsAString& aType,
                                          nsIDOMEventListener* aListener,
@@ -200,17 +200,17 @@ nsDOMEventTargetHelper::AddEventListener
     if (NS_FAILED(rv)) {
       aRv.Throw(rv);
       return;
     }
   } else {
     wantsUntrusted = aWantsUntrusted.Value();
   }
 
-  nsEventListenerManager* elm = GetListenerManager(true);
+  nsEventListenerManager* elm = ListenerManager();
   if (!elm) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return;
   }
   elm->AddEventListener(aType, aListener, aUseCapture, wantsUntrusted);
 }
 
 NS_IMETHODIMP
@@ -315,25 +315,31 @@ nsDOMEventTargetHelper::DispatchDOMEvent
                                          nsEventStatus* aEventStatus)
 {
   return
     nsEventDispatcher::DispatchDOMEvent(this, aEvent, aDOMEvent, aPresContext,
                                         aEventStatus);
 }
 
 nsEventListenerManager*
-nsDOMEventTargetHelper::GetListenerManager(bool aCreateIfNotFound)
+nsDOMEventTargetHelper::ListenerManager()
 {
-  if (!mListenerManager && aCreateIfNotFound) {
+  if (!mListenerManager) {
     mListenerManager = new nsEventListenerManager(this);
   }
 
   return mListenerManager;
 }
 
+nsEventListenerManager*
+nsDOMEventTargetHelper::GetExistingListenerManager() const
+{
+  return mListenerManager;
+}
+
 nsIScriptContext*
 nsDOMEventTargetHelper::GetContextForEventHandlers(nsresult* aRv)
 {
   *aRv = CheckInnerWindowCorrectness();
   if (NS_FAILED(*aRv)) {
     return nullptr;
   }
   nsPIDOMWindow* owner = GetOwner();
--- a/content/events/src/nsDOMEventTargetHelper.h
+++ b/content/events/src/nsDOMEventTargetHelper.h
@@ -38,17 +38,17 @@ public:
     // All objects coming through here are WebIDL objects
     SetIsDOMBinding();
   }
 
   virtual ~nsDOMEventTargetHelper();
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsDOMEventTargetHelper)
 
-  NS_DECL_NSIDOMEVENTTARGET
+  NS_REALLY_DECL_NSIDOMEVENTTARGET
   using mozilla::dom::EventTarget::RemoveEventListener;
   virtual void AddEventListener(const nsAString& aType,
                                 nsIDOMEventListener* aListener,
                                 bool aCapture,
                                 const mozilla::dom::Nullable<bool>& aWantsUntrusted,
                                 mozilla::ErrorResult& aRv) MOZ_OVERRIDE;
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOMEVENTTARGETHELPER_IID)
@@ -217,24 +217,35 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsDOMEvent
     return _to WillHandleEvent(aVisitor); \
   } \
   virtual nsresult PostHandleEvent(nsEventChainPostVisitor & aVisitor) { \
     return _to PostHandleEvent(aVisitor); \
   } \
   virtual nsresult DispatchDOMEvent(nsEvent *aEvent, nsIDOMEvent *aDOMEvent, nsPresContext *aPresContext, nsEventStatus *aEventStatus) { \
     return _to DispatchDOMEvent(aEvent, aDOMEvent, aPresContext, aEventStatus); \
   } \
-  virtual nsEventListenerManager * GetListenerManager(bool aMayCreate) { \
-    return _to GetListenerManager(aMayCreate); \
+  virtual nsEventListenerManager * ListenerManager() { \
+    return _to ListenerManager(); \
+  } \
+  virtual nsEventListenerManager * GetExistingListenerManager() const { \
+    return _to GetExistingListenerManager(); \
   } \
   virtual nsIScriptContext * GetContextForEventHandlers(nsresult *aRv) { \
     return _to GetContextForEventHandlers(aRv); \
   } \
   virtual JSContext * GetJSContextForEventHandlers(void) { \
     return _to GetJSContextForEventHandlers(); \
   }
 
 #define NS_REALLY_FORWARD_NSIDOMEVENTTARGET(_class) \
   using _class::AddEventListener;                   \
   using _class::RemoveEventListener;                \
-  NS_FORWARD_NSIDOMEVENTTARGET(_class::)
+  NS_FORWARD_NSIDOMEVENTTARGET(_class::)            \
+  virtual nsEventListenerManager*                   \
+  ListenerManager() {                               \
+    return _class::ListenerManager();               \
+  }                                                 \
+  virtual nsEventListenerManager*                   \
+  GetExistingListenerManager() const {              \
+    return _class::GetExistingListenerManager();    \
+  }
 
 #endif // nsDOMEventTargetHelper_h_
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -173,18 +173,17 @@ public:
     }
     if (aVisitor.mEvent->mFlags.mPropagationStopped) {
       return NS_OK;
     }
     if (!mManager) {
       if (!MayHaveListenerManager() && !aCd.MayHaveNewListenerManager()) {
         return NS_OK;
       }
-      mManager =
-        static_cast<nsEventListenerManager*>(mTarget->GetListenerManager(false));
+      mManager = mTarget->GetExistingListenerManager();
     }
     if (mManager) {
       NS_ASSERTION(aVisitor.mEvent->currentTarget == nullptr,
                    "CurrentTarget should be null!");
       mManager->HandleEvent(aVisitor.mPresContext, aVisitor.mEvent,
                             &aVisitor.mDOMEvent,
                             CurrentTarget(),
                             &aVisitor.mEventStatus,
--- a/content/events/src/nsEventListenerManager.h
+++ b/content/events/src/nsEventListenerManager.h
@@ -556,17 +556,17 @@ protected:
  */
 inline nsresult
 NS_AddSystemEventListener(mozilla::dom::EventTarget* aTarget,
                           const nsAString& aType,
                           nsIDOMEventListener *aListener,
                           bool aUseCapture,
                           bool aWantsUntrusted)
 {
-  nsEventListenerManager* listenerManager = aTarget->GetListenerManager(true);
+  nsEventListenerManager* listenerManager = aTarget->ListenerManager();
   NS_ENSURE_STATE(listenerManager);
   mozilla::dom::EventListenerFlags flags;
   flags.mInSystemGroup = true;
   flags.mCapture = aUseCapture;
   flags.mAllowUntrustedEvents = aWantsUntrusted;
   listenerManager->AddEventListenerByType(aListener, aType, flags);
   return NS_OK;
 }
--- a/content/events/src/nsEventListenerService.cpp
+++ b/content/events/src/nsEventListenerService.cpp
@@ -156,18 +156,17 @@ NS_IMETHODIMP
 nsEventListenerService::GetListenerInfoFor(nsIDOMEventTarget* aEventTarget,
                                            uint32_t* aCount,
                                            nsIEventListenerInfo*** aOutArray)
 {
   NS_ENSURE_ARG_POINTER(aEventTarget);
   *aCount = 0;
   *aOutArray = nullptr;
   nsCOMArray<nsIEventListenerInfo> listenerInfos;
-  nsEventListenerManager* elm =
-    aEventTarget->GetListenerManager(false);
+  nsEventListenerManager* elm = aEventTarget->GetExistingListenerManager();
   if (elm) {
     elm->GetListenerInfo(&listenerInfos);
   }
 
   int32_t count = listenerInfos.Count();
   if (count == 0) {
     return NS_OK;
   }
@@ -215,31 +214,31 @@ nsEventListenerService::GetEventTargetCh
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsEventListenerService::HasListenersFor(nsIDOMEventTarget* aEventTarget,
                                         const nsAString& aType,
                                         bool* aRetVal)
 {
-  nsEventListenerManager* elm = aEventTarget->GetListenerManager(false);
+  nsEventListenerManager* elm = aEventTarget->GetExistingListenerManager();
   *aRetVal = elm && elm->HasListenersFor(aType);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsEventListenerService::AddSystemEventListener(nsIDOMEventTarget *aTarget,
                                                const nsAString& aType,
                                                nsIDOMEventListener* aListener,
                                                bool aUseCapture)
 {
   NS_PRECONDITION(aTarget, "Missing target");
   NS_PRECONDITION(aListener, "Missing listener");
 
-  nsEventListenerManager* manager = aTarget->GetListenerManager(true);
+  nsEventListenerManager* manager = aTarget->ListenerManager();
   NS_ENSURE_STATE(manager);
 
   EventListenerFlags flags =
     aUseCapture ? TrustedEventsAtSystemGroupCapture() :
                   TrustedEventsAtSystemGroupBubble();
   manager->AddEventListenerByType(aListener, aType, flags);
   return NS_OK;
 }
@@ -248,17 +247,17 @@ NS_IMETHODIMP
 nsEventListenerService::RemoveSystemEventListener(nsIDOMEventTarget *aTarget,
                                                   const nsAString& aType,
                                                   nsIDOMEventListener* aListener,
                                                   bool aUseCapture)
 {
   NS_PRECONDITION(aTarget, "Missing target");
   NS_PRECONDITION(aListener, "Missing listener");
 
-  nsEventListenerManager* manager = aTarget->GetListenerManager(false);
+  nsEventListenerManager* manager = aTarget->GetExistingListenerManager();
   if (manager) {
     EventListenerFlags flags =
       aUseCapture ? TrustedEventsAtSystemGroupCapture() :
                     TrustedEventsAtSystemGroupBubble();
     manager->RemoveEventListenerByType(aListener, aType, flags);
   }
 
   return NS_OK;
@@ -267,31 +266,31 @@ nsEventListenerService::RemoveSystemEven
 NS_IMETHODIMP
 nsEventListenerService::AddListenerForAllEvents(nsIDOMEventTarget* aTarget,
                                                 nsIDOMEventListener* aListener,
                                                 bool aUseCapture,
                                                 bool aWantsUntrusted,
                                                 bool aSystemEventGroup)
 {
   NS_ENSURE_STATE(aTarget && aListener);
-  nsEventListenerManager* manager = aTarget->GetListenerManager(true);
+  nsEventListenerManager* manager = aTarget->ListenerManager();
   NS_ENSURE_STATE(manager);
   manager->AddListenerForAllEvents(aListener, aUseCapture, aWantsUntrusted,
                                aSystemEventGroup);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsEventListenerService::RemoveListenerForAllEvents(nsIDOMEventTarget* aTarget,
                                                    nsIDOMEventListener* aListener,
                                                    bool aUseCapture,
                                                    bool aSystemEventGroup)
 {
   NS_ENSURE_STATE(aTarget && aListener);
-  nsEventListenerManager* manager = aTarget->GetListenerManager(false);
+  nsEventListenerManager* manager = aTarget->GetExistingListenerManager();
   if (manager) {
     manager->RemoveListenerForAllEvents(aListener, aUseCapture, aSystemEventGroup);
   }
   return NS_OK;
 }
 
 nsresult
 NS_NewEventListenerService(nsIEventListenerService** aResult)
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -834,17 +834,17 @@ nsGenericHTMLElement::GetEventListenerMa
     // XXXbz sXBL/XBL2 issue: should we instead use GetCurrentDoc() here,
     // override BindToTree for those classes and munge event listeners there?
     nsIDocument *document = OwnerDoc();
 
     *aDefer = false;
     if ((win = document->GetInnerWindow())) {
       nsCOMPtr<EventTarget> piTarget(do_QueryInterface(win));
 
-      return piTarget->GetListenerManager(true);
+      return piTarget->ListenerManager();
     }
 
     return nullptr;
   }
 
   return nsGenericHTMLElementBase::GetEventListenerManagerForAttr(aAttrName,
                                                                   aDefer);
 }
@@ -1003,18 +1003,17 @@ nsGenericHTMLElement::UnsetAttr(int32_t 
       NS_ENSURE_SUCCESS(rv, rv);
     }
     else if (aAttribute == nsGkAtoms::accesskey) {
       // Have to unregister before clearing flag. See UnregAccessKey
       UnregAccessKey();
       UnsetFlags(NODE_HAS_ACCESSKEY);
     }
     else if (IsEventAttributeName(aAttribute)) {
-      nsEventListenerManager* manager = GetListenerManager(false);
-      if (manager) {
+      if (nsEventListenerManager* manager = GetExistingListenerManager()) {
         manager->RemoveEventHandler(aAttribute, EmptyString());
       }
     }
   }
 
   nsresult rv = nsGenericHTMLElementBase::UnsetAttr(aNameSpaceID, aAttribute,
                                                     aNotify);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -1555,18 +1555,17 @@ nsTextEditorState::UnbindFromFrame(nsTex
     mSelCon = nullptr;
   }
 
   if (mTextListener)
   {
     mTextListener->SetFrame(nullptr);
 
     nsCOMPtr<EventTarget> target = do_QueryInterface(mTextCtrlElement);
-    nsEventListenerManager* manager =
-      target->GetListenerManager(false);
+    nsEventListenerManager* manager = target->GetExistingListenerManager();
     if (manager) {
       manager->RemoveEventListenerByType(mTextListener,
         NS_LITERAL_STRING("keydown"),
         dom::TrustedEventsAtSystemGroupBubble());
       manager->RemoveEventListenerByType(mTextListener,
         NS_LITERAL_STRING("keypress"),
         dom::TrustedEventsAtSystemGroupBubble());
       manager->RemoveEventListenerByType(mTextListener,
@@ -1963,17 +1962,17 @@ nsTextEditorState::SetValue(const nsAStr
   mTextCtrlElement->OnValueChanged(!!mRootNode);
 }
 
 void
 nsTextEditorState::InitializeKeyboardEventListeners()
 {
   //register key listeners
   nsCOMPtr<EventTarget> target = do_QueryInterface(mTextCtrlElement);
-  nsEventListenerManager* manager = target->GetListenerManager(true);
+  nsEventListenerManager* manager = target->ListenerManager();
   if (manager) {
     manager->AddEventListenerByType(mTextListener,
                                     NS_LITERAL_STRING("keydown"),
                                     dom::TrustedEventsAtSystemGroupBubble());
     manager->AddEventListenerByType(mTextListener,
                                     NS_LITERAL_STRING("keypress"),
                                     dom::TrustedEventsAtSystemGroupBubble());
     manager->AddEventListenerByType(mTextListener,
--- a/content/smil/nsSMILTimeValueSpec.cpp
+++ b/content/smil/nsSMILTimeValueSpec.cpp
@@ -367,17 +367,17 @@ nsSMILTimeValueSpec::GetEventListenerMan
       return nullptr;
     target = do_QueryInterface(win);
   } else {
     target = aTarget;
   }
   if (!target)
     return nullptr;
 
-  return target->GetListenerManager(true);
+  return target->ListenerManager();
 }
 
 void
 nsSMILTimeValueSpec::HandleEvent(nsIDOMEvent* aEvent)
 {
   NS_ABORT_IF_FALSE(mEventListener, "Got event without an event listener");
   NS_ABORT_IF_FALSE(IsEventBased(),
                     "Got event for non-event nsSMILTimeValueSpec");
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -659,17 +659,17 @@ nsSVGElement::UnsetAttrInternal(int32_t 
   // Maybe consolidate?
 
   if (aNamespaceID == kNameSpaceID_None) {
     // If this is an svg presentation attribute, remove rule to force an update
     if (IsAttributeMapped(aName))
       mContentStyleRule = nullptr;
 
     if (IsEventAttributeName(aName)) {
-      nsEventListenerManager* manager = GetListenerManager(false);
+      nsEventListenerManager* manager = GetExistingListenerManager();
       if (manager) {
         nsIAtom* eventName = GetEventNameForAttr(aName);
         manager->RemoveEventHandler(eventName, EmptyString());
       }
       return;
     }
     
     // Check if this is a length attribute going away
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -494,18 +494,17 @@ void
 nsXBLBinding::InstallEventHandlers()
 {
   // Don't install handlers if scripts aren't allowed.
   if (AllowScripts()) {
     // Fetch the handlers prototypes for this binding.
     nsXBLPrototypeHandler* handlerChain = mPrototypeBinding->GetPrototypeHandlers();
 
     if (handlerChain) {
-      nsEventListenerManager* manager =
-        mBoundElement->GetListenerManager(true);
+      nsEventListenerManager* manager = mBoundElement->ListenerManager();
       if (!manager)
         return;
 
       bool isChromeDoc =
         nsContentUtils::IsChromeDoc(mBoundElement->OwnerDoc());
       bool isChromeBinding = mPrototypeBinding->IsChrome();
       nsXBLPrototypeHandler* curr;
       for (curr = handlerChain; curr; curr = curr->GetNextHandler()) {
@@ -644,17 +643,17 @@ nsXBLBinding::ExecuteDetachedHandler()
 
 void
 nsXBLBinding::UnhookEventHandlers()
 {
   nsXBLPrototypeHandler* handlerChain = mPrototypeBinding->GetPrototypeHandlers();
 
   if (handlerChain) {
     nsEventListenerManager* manager =
-      mBoundElement->GetListenerManager(false);
+      mBoundElement->GetExistingListenerManager();
     if (!manager) {
       return;
     }
                                       
     bool isChromeBinding = mPrototypeBinding->IsChrome();
     nsXBLPrototypeHandler* curr;
     for (curr = handlerChain; curr; curr = curr->GetNextHandler()) {
       nsXBLEventHandler* handler = curr->GetCachedEventHandler();
--- a/content/xbl/src/nsXBLService.cpp
+++ b/content/xbl/src/nsXBLService.cpp
@@ -556,17 +556,17 @@ nsXBLService::AttachGlobalKeyHandler(Eve
   nsCOMPtr<nsIContent> contentNode(do_QueryInterface(aTarget));
   if (contentNode) {
     // Only attach if we're really in a document
     nsCOMPtr<nsIDocument> doc = contentNode->GetCurrentDoc();
     if (doc)
       piTarget = doc; // We're a XUL keyset. Attach to our document.
   }
 
-  nsEventListenerManager* manager = piTarget->GetListenerManager(true);
+  nsEventListenerManager* manager = piTarget->ListenerManager();
 
   if (!piTarget || !manager)
     return NS_ERROR_FAILURE;
 
   // the listener already exists, so skip this
   if (contentNode && contentNode->GetProperty(nsGkAtoms::listener))
     return NS_OK;
 
@@ -606,17 +606,17 @@ nsXBLService::DetachGlobalKeyHandler(Eve
   if (!contentNode) // detaching is only supported for content nodes
     return NS_ERROR_FAILURE;
 
   // Only attach if we're really in a document
   nsCOMPtr<nsIDocument> doc = contentNode->GetCurrentDoc();
   if (doc)
     piTarget = do_QueryInterface(doc);
 
-  nsEventListenerManager* manager = piTarget->GetListenerManager(true);
+  nsEventListenerManager* manager = piTarget->ListenerManager();
 
   if (!piTarget || !manager)
     return NS_ERROR_FAILURE;
 
   nsIDOMEventListener* handler =
     static_cast<nsIDOMEventListener*>(contentNode->GetProperty(nsGkAtoms::listener));
   if (!handler)
     return NS_ERROR_FAILURE;
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -495,17 +495,17 @@ nsXULElement::GetEventListenerManagerFor
     nsPIDOMWindow *window;
     Element *root = doc->GetRootElement();
     if ((!root || root == this) && !mNodeInfo->Equals(nsGkAtoms::overlay) &&
         (window = doc->GetInnerWindow())) {
 
         nsCOMPtr<EventTarget> piTarget = do_QueryInterface(window);
 
         *aDefer = false;
-        return piTarget->GetListenerManager(true);
+        return piTarget->ListenerManager();
     }
 
     return nsStyledElement::GetEventListenerManagerForAttr(aAttrName, aDefer);
 }
 
 // returns true if the element is not a list
 static bool IsNonList(nsINodeInfo* aNodeInfo)
 {
@@ -1670,17 +1670,17 @@ nsXULElement::AddPopupListener(nsIAtom* 
     if (HasFlag(listenerFlag)) {
         return NS_OK;
     }
 
     nsCOMPtr<nsIDOMEventListener> listener =
       new nsXULPopupListener(this, isContext);
 
     // Add the popup as a listener on this element.
-    nsEventListenerManager* manager = GetListenerManager(true);
+    nsEventListenerManager* manager = ListenerManager();
     SetFlags(listenerFlag);
 
     if (isContext) {
       manager->AddEventListenerByType(listener,
                                       NS_LITERAL_STRING("contextmenu"),
                                       dom::TrustedEventsAtSystemGroupBubble());
     } else {
       manager->AddEventListenerByType(listener,
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1568,18 +1568,17 @@ MarkXBLHandlers(nsXBLPrototypeHandler* a
   return PL_DHASH_NEXT;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsGlobalWindow)
   if (tmp->IsBlackForCC()) {
     if (tmp->mCachedXBLPrototypeHandlers) {
       tmp->mCachedXBLPrototypeHandlers->Enumerate(MarkXBLHandlers, nullptr);
     }
-    nsEventListenerManager* elm = tmp->GetListenerManager(false);
-    if (elm) {
+    if (nsEventListenerManager* elm = tmp->GetExistingListenerManager()) {
       elm->MarkForCC();
     }
     tmp->UnmarkGrayTimers();
     return true;
   }
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsGlobalWindow)
@@ -8032,18 +8031,17 @@ nsGlobalWindow::Btoa(const nsAString& aB
 // nsGlobalWindow::nsIDOMEventTarget
 //*****************************************************************************
 
 NS_IMETHODIMP
 nsGlobalWindow::RemoveEventListener(const nsAString& aType,
                                     nsIDOMEventListener* aListener,
                                     bool aUseCapture)
 {
-  nsRefPtr<nsEventListenerManager> elm = GetListenerManager(false);
-  if (elm) {
+  if (nsRefPtr<nsEventListenerManager> elm = GetExistingListenerManager()) {
     elm->RemoveEventListener(aType, aListener, aUseCapture);
   }
   return NS_OK;
 }
 
 NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsGlobalWindow)
 
 NS_IMETHODIMP
@@ -8088,17 +8086,17 @@ nsGlobalWindow::AddEventListener(const n
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   if (!aWantsUntrusted &&
       (aOptionalArgc < 2 && !nsContentUtils::IsChromeDoc(mDoc))) {
     aWantsUntrusted = true;
   }
 
-  nsEventListenerManager* manager = GetListenerManager(true);
+  nsEventListenerManager* manager = ListenerManager();
   NS_ENSURE_STATE(manager);
   manager->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
   return NS_OK;
 }
 
 void
 nsGlobalWindow::AddEventListener(const nsAString& aType,
                                  nsIDOMEventListener* aListener,
@@ -8114,17 +8112,17 @@ nsGlobalWindow::AddEventListener(const n
 
   bool wantsUntrusted;
   if (aWantsUntrusted.IsNull()) {
     wantsUntrusted = !nsContentUtils::IsChromeDoc(mDoc);
   } else {
     wantsUntrusted = aWantsUntrusted.Value();
   }
 
-  nsEventListenerManager* manager = GetListenerManager(true);
+  nsEventListenerManager* manager = ListenerManager();
   if (!manager) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return;
   }
   manager->AddEventListener(aType, aListener, aUseCapture, wantsUntrusted);
 }
 
 NS_IMETHODIMP
@@ -8149,28 +8147,36 @@ nsGlobalWindow::AddSystemEventListener(c
     aWantsUntrusted = true;
   }
 
   return NS_AddSystemEventListener(this, aType, aListener, aUseCapture,
                                    aWantsUntrusted);
 }
 
 nsEventListenerManager*
-nsGlobalWindow::GetListenerManager(bool aCreateIfNotFound)
-{
-  FORWARD_TO_INNER_CREATE(GetListenerManager, (aCreateIfNotFound), nullptr);
-
-  if (!mListenerManager && aCreateIfNotFound) {
+nsGlobalWindow::ListenerManager()
+{
+  FORWARD_TO_INNER_CREATE(ListenerManager, (), nullptr);
+
+  if (!mListenerManager) {
     mListenerManager =
       new nsEventListenerManager(static_cast<EventTarget*>(this));
   }
 
   return mListenerManager;
 }
 
+nsEventListenerManager*
+nsGlobalWindow::GetExistingListenerManager() const
+{
+  FORWARD_TO_INNER(GetExistingListenerManager, (), nullptr);
+
+  return mListenerManager;
+}
+
 nsIScriptContext*
 nsGlobalWindow::GetContextForEventHandlers(nsresult* aRv)
 {
   *aRv = NS_ERROR_UNEXPECTED;
   if (IsInnerWindow()) {
     nsPIDOMWindow* outer = GetOuterWindow();
     NS_ENSURE_TRUE(outer && outer->GetCurrentInnerWindow() == this, nullptr);
   }
@@ -11516,19 +11522,17 @@ SizeOfEventTargetObjectsEntryExcludingTh
 }
 
 void
 nsGlobalWindow::SizeOfIncludingThis(nsWindowSizes* aWindowSizes) const
 {
   aWindowSizes->mDOMOther += aWindowSizes->mMallocSizeOf(this);
 
   if (IsInnerWindow()) {
-    nsEventListenerManager* elm =
-      const_cast<nsGlobalWindow*>(this)->GetListenerManager(false);
-    if (elm) {
+    if (nsEventListenerManager* elm = GetExistingListenerManager()) {
       aWindowSizes->mDOMOther +=
         elm->SizeOfIncludingThis(aWindowSizes->mMallocSizeOf);
     }
     if (mDoc) {
       mDoc->DocSizeOfIncludingThis(aWindowSizes);
     }
   }
 
@@ -12058,60 +12062,58 @@ nsGlobalWindow::DisableNetworkEvent(uint
     }                                                                        \
     ErrorResult rv;                                                          \
     SetOn##name_(handler, rv);                                               \
     return rv.ErrorCode();                                                   \
   }
 #define ERROR_EVENT(name_, id_, type_, struct_)                              \
   NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx,                  \
                                              JS::Value *vp) {                \
-    nsEventListenerManager *elm = GetListenerManager(false);                 \
-    if (elm) {                                                               \
+    if (nsEventListenerManager *elm = GetExistingListenerManager()) {        \
       OnErrorEventHandlerNonNull* h = elm->GetOnErrorEventHandler();         \
       if (h) {                                                               \
         *vp = JS::ObjectValue(*h->Callable());                               \
         return NS_OK;                                                        \
       }                                                                      \
     }                                                                        \
     *vp = JSVAL_NULL;                                                        \
     return NS_OK;                                                            \
   }                                                                          \
   NS_IMETHODIMP nsGlobalWindow::SetOn##name_(JSContext *cx,                  \
                                              const JS::Value &v) {           \
-    nsEventListenerManager *elm = GetListenerManager(true);                  \
+    nsEventListenerManager *elm = ListenerManager();                         \
     if (!elm) {                                                              \
       return NS_ERROR_OUT_OF_MEMORY;                                         \
     }                                                                        \
                                                                              \
     nsRefPtr<OnErrorEventHandlerNonNull> handler;                            \
     JSObject *callable;                                                      \
     if (v.isObject() &&                                                      \
         JS_ObjectIsCallable(cx, callable = &v.toObject())) {                 \
       handler = new OnErrorEventHandlerNonNull(callable);                    \
     }                                                                        \
     return elm->SetEventHandler(handler);                                    \
   }
 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                       \
   NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx,                  \
                                              JS::Value *vp) {                \
-    nsEventListenerManager *elm = GetListenerManager(false);                 \
-    if (elm) {                                                               \
+    if (nsEventListenerManager *elm = GetExistingListenerManager()) {        \
       BeforeUnloadEventHandlerNonNull* h =                                   \
         elm->GetOnBeforeUnloadEventHandler();                                \
       if (h) {                                                               \
         *vp = JS::ObjectValue(*h->Callable());                               \
         return NS_OK;                                                        \
       }                                                                      \
     }                                                                        \
     *vp = JSVAL_NULL;                                                        \
     return NS_OK;                                                            \
   }                                                                          \
   NS_IMETHODIMP nsGlobalWindow::SetOn##name_(JSContext *cx,                  \
                                              const JS::Value &v) {           \
-    nsEventListenerManager *elm = GetListenerManager(true);                  \
+    nsEventListenerManager *elm = ListenerManager();                         \
     if (!elm) {                                                              \
       return NS_ERROR_OUT_OF_MEMORY;                                         \
     }                                                                        \
                                                                              \
     nsRefPtr<BeforeUnloadEventHandlerNonNull> handler;                       \
     JSObject *callable;                                                      \
     if (v.isObject() &&                                                      \
         JS_ObjectIsCallable(cx, callable = &v.toObject())) {                 \
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -365,17 +365,17 @@ public:
 
   // nsIDOMWindowPerformance
   NS_DECL_NSIDOMWINDOWPERFORMANCE
 
   // nsIDOMJSWindow
   NS_DECL_NSIDOMJSWINDOW
 
   // nsIDOMEventTarget
-  NS_DECL_NSIDOMEVENTTARGET
+  NS_REALLY_DECL_NSIDOMEVENTTARGET
   using mozilla::dom::EventTarget::RemoveEventListener;
   virtual void AddEventListener(const nsAString& aType,
                                 nsIDOMEventListener* aListener,
                                 bool aUseCapture,
                                 const mozilla::dom::Nullable<bool>& aWantsUntrusted,
                                 mozilla::ErrorResult& aRv) MOZ_OVERRIDE;
   virtual nsIDOMWindow* GetOwnerGlobal() MOZ_OVERRIDE
   {
@@ -542,17 +542,17 @@ public:
     return mContext;
   }
 
   nsGlobalWindow *GetOuterWindowInternal()
   {
     return static_cast<nsGlobalWindow *>(GetOuterWindow());
   }
 
-  nsGlobalWindow *GetCurrentInnerWindowInternal()
+  nsGlobalWindow *GetCurrentInnerWindowInternal() const
   {
     return static_cast<nsGlobalWindow *>(mInnerWindow);
   }
 
   nsGlobalWindow *EnsureInnerWindowInternal()
   {
     return static_cast<nsGlobalWindow *>(EnsureInnerWindow());
   }
@@ -698,58 +698,55 @@ public:
   // Enable/disable updates for gamepad input.
   void EnableGamepadUpdates();
   void DisableGamepadUpdates();
 
 
 #define EVENT(name_, id_, type_, struct_)                                     \
   mozilla::dom::EventHandlerNonNull* GetOn##name_()                           \
   {                                                                           \
-    nsEventListenerManager *elm = GetListenerManager(false);                  \
+    nsEventListenerManager *elm = GetExistingListenerManager();               \
     return elm ? elm->GetEventHandler(nsGkAtoms::on##name_, EmptyString())    \
                : nullptr;                                                     \
   }                                                                           \
   void SetOn##name_(mozilla::dom::EventHandlerNonNull* handler,               \
                     mozilla::ErrorResult& error)                              \
   {                                                                           \
-    nsEventListenerManager *elm = GetListenerManager(true);                   \
-    if (elm) {                                                                \
+    if (nsEventListenerManager *elm = ListenerManager()) {                    \
       error = elm->SetEventHandler(nsGkAtoms::on##name_, EmptyString(),       \
                                    handler);                                  \
     } else {                                                                  \
       error.Throw(NS_ERROR_OUT_OF_MEMORY);                                    \
     }                                                                         \
   }
 #define ERROR_EVENT(name_, id_, type_, struct_)                               \
   mozilla::dom::OnErrorEventHandlerNonNull* GetOn##name_()                    \
   {                                                                           \
-    nsEventListenerManager *elm = GetListenerManager(false);                  \
+    nsEventListenerManager *elm = GetExistingListenerManager();               \
     return elm ? elm->GetOnErrorEventHandler() : nullptr;                     \
   }                                                                           \
   void SetOn##name_(mozilla::dom::OnErrorEventHandlerNonNull* handler,        \
                     mozilla::ErrorResult& error)                              \
   {                                                                           \
-    nsEventListenerManager *elm = GetListenerManager(true);                   \
-    if (elm) {                                                                \
+    if (nsEventListenerManager *elm = ListenerManager()) {                    \
       error = elm->SetEventHandler(handler);                                  \
     } else {                                                                  \
       error.Throw(NS_ERROR_OUT_OF_MEMORY);                                    \
     }                                                                         \
   }
 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                        \
   mozilla::dom::BeforeUnloadEventHandlerNonNull* GetOn##name_()               \
   {                                                                           \
-    nsEventListenerManager *elm = GetListenerManager(false);                  \
+    nsEventListenerManager *elm = GetExistingListenerManager();               \
     return elm ? elm->GetOnBeforeUnloadEventHandler() : nullptr;              \
   }                                                                           \
   void SetOn##name_(mozilla::dom::BeforeUnloadEventHandlerNonNull* handler,   \
                     mozilla::ErrorResult& error)                              \
   {                                                                           \
-    nsEventListenerManager *elm = GetListenerManager(true);                   \
-    if (elm) {                                                                \
+    if (nsEventListenerManager *elm = ListenerManager()) {                    \
       error = elm->SetEventHandler(handler);                                  \
     } else {                                                                  \
       error.Throw(NS_ERROR_OUT_OF_MEMORY);                                    \
     }                                                                         \
   }
 #define WINDOW_ONLY_EVENT EVENT
 #define TOUCH_EVENT EVENT
 #include "nsEventNameList.h"
--- a/dom/base/nsWindowRoot.cpp
+++ b/dom/base/nsWindowRoot.cpp
@@ -60,18 +60,17 @@ NS_INTERFACE_MAP_END
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsWindowRoot)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsWindowRoot)
 
 NS_IMPL_DOMTARGET_DEFAULTS(nsWindowRoot)
 
 NS_IMETHODIMP
 nsWindowRoot::RemoveEventListener(const nsAString& aType, nsIDOMEventListener* aListener, bool aUseCapture)
 {
-  nsRefPtr<nsEventListenerManager> elm = GetListenerManager(false);
-  if (elm) {
+  if (nsRefPtr<nsEventListenerManager> elm = GetExistingListenerManager()) {
     elm->RemoveEventListener(aType, aListener, aUseCapture);
   }
   return NS_OK;
 }
 
 NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsWindowRoot)
 
 NS_IMETHODIMP
@@ -101,31 +100,31 @@ nsWindowRoot::AddEventListener(const nsA
                                bool aUseCapture, bool aWantsUntrusted,
                                uint8_t aOptionalArgc)
 {
   NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
                "Won't check if this is chrome, you want to set "
                "aWantsUntrusted to false or make the aWantsUntrusted "
                "explicit by making optional_argc non-zero.");
 
-  nsEventListenerManager* elm = GetListenerManager(true);
+  nsEventListenerManager* elm = ListenerManager();
   NS_ENSURE_STATE(elm);
   elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
   return NS_OK;
 }
 
 void
 nsWindowRoot::AddEventListener(const nsAString& aType,
                                 nsIDOMEventListener* aListener,
                                 bool aUseCapture,
                                 const Nullable<bool>& aWantsUntrusted,
                                 ErrorResult& aRv)
 {
   bool wantsUntrusted = !aWantsUntrusted.IsNull() && aWantsUntrusted.Value();
-  nsEventListenerManager* elm = GetListenerManager(true);
+  nsEventListenerManager* elm = ListenerManager();
   if (!elm) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return;
   }
   elm->AddEventListener(aType, aListener, aUseCapture, wantsUntrusted);
 }
 
 
@@ -141,26 +140,32 @@ nsWindowRoot::AddSystemEventListener(con
                "aWantsUntrusted to false or make the aWantsUntrusted "
                "explicit by making optional_argc non-zero.");
 
   return NS_AddSystemEventListener(this, aType, aListener, aUseCapture,
                                    aWantsUntrusted);
 }
 
 nsEventListenerManager*
-nsWindowRoot::GetListenerManager(bool aCreateIfNotFound)
+nsWindowRoot::ListenerManager()
 {
-  if (!mListenerManager && aCreateIfNotFound) {
+  if (!mListenerManager) {
     mListenerManager =
       new nsEventListenerManager(static_cast<EventTarget*>(this));
   }
 
   return mListenerManager;
 }
 
+nsEventListenerManager*
+nsWindowRoot::GetExistingListenerManager() const
+{
+  return mListenerManager;
+}
+
 nsIScriptContext*
 nsWindowRoot::GetContextForEventHandlers(nsresult* aRv)
 {
   *aRv = NS_OK;
   return nullptr;
 }
 
 nsresult
--- a/dom/base/nsWindowRoot.h
+++ b/dom/base/nsWindowRoot.h
@@ -22,17 +22,17 @@ class nsEventChainPostVisitor;
 
 class nsWindowRoot : public nsPIWindowRoot
 {
 public:
   nsWindowRoot(nsPIDOMWindow* aWindow);
   virtual ~nsWindowRoot();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_NSIDOMEVENTTARGET
+  NS_REALLY_DECL_NSIDOMEVENTTARGET
   using mozilla::dom::EventTarget::RemoveEventListener;
   virtual void AddEventListener(const nsAString& aType,
                                 nsIDOMEventListener* aListener,
                                 bool aUseCapture,
                                 const mozilla::dom::Nullable<bool>& aWantsUntrusted,
                                 mozilla::ErrorResult& aRv) MOZ_OVERRIDE;
 
   // nsPIWindowRoot
--- a/dom/devicestorage/DeviceStorage.h
+++ b/dom/devicestorage/DeviceStorage.h
@@ -150,17 +150,17 @@ class nsDOMDeviceStorage MOZ_FINAL
   typedef mozilla::dom::DOMRequest DOMRequest;
 public:
   typedef nsTArray<nsString> VolumeNameArray;
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDEVICESTORAGE
 
   NS_DECL_NSIOBSERVER
-  NS_DECL_NSIDOMEVENTTARGET
+  NS_REALLY_DECL_NSIDOMEVENTTARGET
 
   virtual void
   AddEventListener(const nsAString& aType,
                    nsIDOMEventListener* aListener,
                    bool aUseCapture,
                    const mozilla::dom::Nullable<bool>& aWantsUntrusted,
                    ErrorResult& aRv) MOZ_OVERRIDE;
 
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -3473,19 +3473,25 @@ nsDOMDeviceStorage::DispatchDOMEvent(nsE
 {
   return nsDOMEventTargetHelper::DispatchDOMEvent(aEvent,
                                                   aDOMEvent,
                                                   aPresContext,
                                                   aEventStatus);
 }
 
 nsEventListenerManager *
-nsDOMDeviceStorage::GetListenerManager(bool aMayCreate)
+nsDOMDeviceStorage::ListenerManager()
 {
-  return nsDOMEventTargetHelper::GetListenerManager(aMayCreate);
+  return nsDOMEventTargetHelper::ListenerManager();
+}
+
+nsEventListenerManager *
+nsDOMDeviceStorage::GetExistingListenerManager() const
+{
+  return nsDOMEventTargetHelper::GetExistingListenerManager();
 }
 
 nsIScriptContext *
 nsDOMDeviceStorage::GetContextForEventHandlers(nsresult *aRv)
 {
   return nsDOMEventTargetHelper::GetContextForEventHandlers(aRv);
 }
 
--- a/dom/interfaces/events/nsIDOMEventTarget.idl
+++ b/dom/interfaces/events/nsIDOMEventTarget.idl
@@ -40,17 +40,17 @@ class nsEventListenerManager;
 [ptr] native JSContextPtr(JSContext);
 [ptr] native nsEventListenerManagerPtr(nsEventListenerManager);
 [ptr] native EventTargetPtr(mozilla::dom::EventTarget);
 
 interface nsIScriptContext;
 interface nsIDOMEventListener;
 interface nsIDOMEvent;
 
-[scriptable, builtinclass, uuid(31e92e56-4d23-4a4a-9cfe-a6d12cf434bc)]
+[scriptable, builtinclass, uuid(b128448c-7b53-4769-92cb-cd6eafee676c)]
 interface nsIDOMEventTarget : nsISupports
 {
   /**
    * This method allows the registration of event listeners on the event target.
    * If an EventListener is added to an EventTarget while it is processing an
    * event, it will not be triggered by the current actions but may be 
    * triggered during a later stage of event flow, such as the bubbling phase.
    * 
@@ -262,24 +262,31 @@ interface nsIDOMEventTarget : nsISupport
    *             have been converted to use nsIDOMEventTarget::dispatchEvent.
    */
   [noscript, nostdcall]
   void DispatchDOMEvent(in nsEventPtr aEvent,
                         in nsIDOMEvent aDOMEvent,
                         in nsPresContextPtr aPresContext,
                         in nsEventStatusPtr aEventStatus);
 
+%{C++
+  // These are virtual, but everything after this is not accessible to JS so
+  // xpidl not understanding the vtable here doesn't matter.
+
   /**
-   * Get the event listener manager, the guy you talk to to register for events
-   * on this node.
-   * @param aMayCreate If PR_FALSE, returns a listener manager only if
-   *                   one already exists.
+   * Get the event listener manager, creating it if it does not already exist.
    */
-  [notxpcom, nostdcall]
-  nsEventListenerManagerPtr GetListenerManager(in boolean aMayCreate);
+  virtual nsEventListenerManager* ListenerManager() = 0;
+
+  /**
+   * Get the event listener manager, returning null if it does not already
+   * exist.
+   */
+  virtual nsEventListenerManager* GetExistingListenerManager() const = 0;
+%}
 
   /**
    * Get the script context in which the event handlers should be run.
    * May return null.
    * @note Caller *must* check the value of aRv.
    */
   [notxpcom, nostdcall]
   nsIScriptContext GetContextForEventHandlers(out nsresult aRv);
@@ -288,29 +295,34 @@ interface nsIDOMEventTarget : nsISupport
    * If the method above returns null, but a success code, this method
    * is called.
    */
   [notxpcom, nostdcall] JSContextPtr GetJSContextForEventHandlers();
 };
 
 %{C++
 
+#define NS_REALLY_DECL_NSIDOMEVENTTARGET \
+  NS_DECL_NSIDOMEVENTTARGET \
+  virtual nsEventListenerManager* ListenerManager() MOZ_OVERRIDE; \
+  virtual nsEventListenerManager* GetExistingListenerManager() const MOZ_OVERRIDE;
+
 #define NS_IMPL_DOMTARGET_DEFAULTS(_class) \
 mozilla::dom::EventTarget* _class::GetTargetForDOMEvent() { return this; } \
 mozilla::dom::EventTarget* _class::GetTargetForEventTargetChain() { return this; } \
 nsresult _class::WillHandleEvent(nsEventChainPostVisitor& aVisitor) { return NS_OK; } \
 JSContext* _class::GetJSContextForEventHandlers() { return nullptr; }
 
 #define NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(aClass) \
 NS_IMETHODIMP \
 aClass::RemoveSystemEventListener(const nsAString& aType, \
                                   nsIDOMEventListener *aListener, \
                                   bool aUseCapture) \
 { \
-  nsEventListenerManager* listenerManager = GetListenerManager(false); \
+  nsEventListenerManager* listenerManager = GetExistingListenerManager(); \
   if (!listenerManager) { \
     return NS_OK; \
   } \
   mozilla::dom::EventListenerFlags flags; \
   flags.mInSystemGroup = true; \
   flags.mCapture = aUseCapture; \
   listenerManager->RemoveEventListenerByType(aListener, aType, flags); \
   return NS_OK; \
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -1230,17 +1230,17 @@ TabChild::~TabChild()
 
     nsCOMPtr<nsIWebBrowser> webBrowser = do_QueryInterface(mWebNav);
     if (webBrowser) {
       webBrowser->SetContainerWindow(nullptr);
     }
     mGlobal = nullptr;
 
     if (mTabChildGlobal) {
-      nsEventListenerManager* elm = mTabChildGlobal->GetListenerManager(false);
+      nsEventListenerManager* elm = mTabChildGlobal->GetExistingListenerManager();
       if (elm) {
         elm->Disconnect();
       }
       mTabChildGlobal->mTabChild = nullptr;
     }
 }
 
 void
--- a/editor/libeditor/base/nsEditorEventListener.cpp
+++ b/editor/libeditor/base/nsEditorEventListener.cpp
@@ -103,17 +103,17 @@ nsresult
 nsEditorEventListener::InstallToEditor()
 {
   NS_PRECONDITION(mEditor, "The caller must set mEditor");
 
   nsCOMPtr<nsIDOMEventTarget> piTarget = mEditor->GetDOMEventTarget();
   NS_ENSURE_TRUE(piTarget, NS_ERROR_FAILURE);
 
   // register the event listeners with the listener manager
-  nsEventListenerManager* elmP = piTarget->GetListenerManager(true);
+  nsEventListenerManager* elmP = piTarget->ListenerManager();
   NS_ENSURE_STATE(elmP);
 
 #ifdef HANDLE_NATIVE_TEXT_DIRECTION_SWITCH
   elmP->AddEventListenerByType(this,
                                NS_LITERAL_STRING("keydown"),
                                dom::TrustedEventsAtSystemGroupBubble());
   elmP->AddEventListenerByType(this,
                                NS_LITERAL_STRING("keyup"),
@@ -182,18 +182,17 @@ nsEditorEventListener::Disconnect()
 void
 nsEditorEventListener::UninstallFromEditor()
 {
   nsCOMPtr<nsIDOMEventTarget> piTarget = mEditor->GetDOMEventTarget();
   if (!piTarget) {
     return;
   }
 
-  nsEventListenerManager* elmP =
-    piTarget->GetListenerManager(true);
+  nsEventListenerManager* elmP = piTarget->ListenerManager();
   if (!elmP) {
     return;
   }
 
 #ifdef HANDLE_NATIVE_TEXT_DIRECTION_SWITCH
   elmP->RemoveEventListenerByType(this,
                                   NS_LITERAL_STRING("keydown"),
                                   dom::TrustedEventsAtSystemGroupBubble());
--- a/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
+++ b/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
@@ -861,17 +861,17 @@ nsDocShellTreeOwner::AddChromeListeners(
         rv = NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   // register dragover and drop event listeners with the listener manager
   nsCOMPtr<EventTarget> target;
   GetDOMEventTarget(mWebBrowser, getter_AddRefs(target));
 
-  nsEventListenerManager* elmP = target->GetListenerManager(true);
+  nsEventListenerManager* elmP = target->ListenerManager();
   if (elmP) {
     elmP->AddEventListenerByType(this, NS_LITERAL_STRING("dragover"),
                                  dom::TrustedEventsAtSystemGroupBubble());
     elmP->AddEventListenerByType(this, NS_LITERAL_STRING("drop"),
                                  dom::TrustedEventsAtSystemGroupBubble());
   }
 
   return rv;
@@ -891,17 +891,17 @@ nsDocShellTreeOwner::RemoveChromeListene
     NS_RELEASE(mChromeContextMenuListener);
   }
 
   nsCOMPtr<EventTarget> piTarget;
   GetDOMEventTarget(mWebBrowser, getter_AddRefs(piTarget));
   if (!piTarget)
     return NS_OK;
 
-  nsEventListenerManager* elmP = piTarget->GetListenerManager(true);
+  nsEventListenerManager* elmP = piTarget->ListenerManager();
   if (elmP)
   {
     elmP->RemoveEventListenerByType(this, NS_LITERAL_STRING("dragover"),
                                     dom::TrustedEventsAtSystemGroupBubble());
     elmP->RemoveEventListenerByType(this, NS_LITERAL_STRING("drop"),
                                     dom::TrustedEventsAtSystemGroupBubble());
   }
 
--- a/layout/base/PositionedEventTargeting.cpp
+++ b/layout/base/PositionedEventTargeting.cpp
@@ -111,23 +111,23 @@ GetPrefsFor(nsEventStructType aEventStru
   }
 
   return prefs;
 }
 
 static bool
 HasMouseListener(nsIContent* aContent)
 {
-  nsEventListenerManager* elm = aContent->GetListenerManager(false);
-  if (!elm) {
-    return false;
+  if (nsEventListenerManager* elm = aContent->GetExistingListenerManager()) {
+    return elm->HasListenersFor(nsGkAtoms::onclick) ||
+           elm->HasListenersFor(nsGkAtoms::onmousedown) ||
+           elm->HasListenersFor(nsGkAtoms::onmouseup);
   }
-  return elm->HasListenersFor(nsGkAtoms::onclick) ||
-         elm->HasListenersFor(nsGkAtoms::onmousedown) ||
-         elm->HasListenersFor(nsGkAtoms::onmouseup);
+
+  return false;
 }
 
 static bool
 IsElementClickable(nsIFrame* aFrame, nsIAtom* stopAt = nullptr)
 {
   // Input events propagate up the content tree so we'll follow the content
   // ancestors to look for elements accepting the click.
   for (nsIContent* content = aFrame->GetContent(); content;
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2201,17 +2201,17 @@ MayHavePaintEventListener(nsPIDOMWindow*
   if (aInnerWindow->HasPaintEventListeners())
     return true;
 
   EventTarget* parentTarget = aInnerWindow->GetParentTarget();
   if (!parentTarget)
     return false;
 
   nsEventListenerManager* manager = nullptr;
-  if ((manager = parentTarget->GetListenerManager(false)) &&
+  if ((manager = parentTarget->GetExistingListenerManager()) &&
       manager->MayHavePaintEventListener()) {
     return true;
   }
 
   nsCOMPtr<nsINode> node;
   if (parentTarget != aInnerWindow->GetChromeEventHandler()) {
     nsCOMPtr<nsIInProcessContentFrameMessageManager> mm =
       do_QueryInterface(parentTarget);
@@ -2229,17 +2229,17 @@ MayHavePaintEventListener(nsPIDOMWindow*
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(parentTarget);
   if (window)
     return MayHavePaintEventListener(window);
 
   nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(parentTarget);
   EventTarget* tabChildGlobal;
   return root &&
          (tabChildGlobal = root->GetParentTarget()) &&
-         (manager = tabChildGlobal->GetListenerManager(false)) &&
+         (manager = tabChildGlobal->GetExistingListenerManager()) &&
          manager->MayHavePaintEventListener();
 }
 
 bool
 nsPresContext::MayHavePaintEventListener()
 {
   return ::MayHavePaintEventListener(mDocument->GetInnerWindow());
 }