nsresult
nsEventListenerManager::SetEventHandlerInternal(nsIScriptContext *aContext,
                                                JS::Handle<JSObject*> aScopeObject,
                                                nsIAtom* aName,
                                                const nsEventHandler& aHandler,
                                                bool aPermitUntrustedEvents,
                                                nsListenerStruct **aListenerStruct)
{
  NS_ASSERTION((aContext && aScopeObject) || aHandler.HasEventHandler(),
               "Must have one or the other!");

  nsresult rv = NS_OK;
  uint32_t eventType = nsContentUtils::GetEventId(aName);
  nsListenerStruct* ls = FindEventHandler(eventType, aName);

  if (!ls) {
    // If we didn't find a script listener or no listeners existed
    // create and add a new one.
    EventListenerFlags flags;
    flags.mListenerIsJSListener = true;

    nsCOMPtr<nsIJSEventListener> scriptListener;
    rv = NS_NewJSEventListener(aContext, aScopeObject, mTarget, aName,
                               aHandler, getter_AddRefs(scriptListener));

    if (NS_SUCCEEDED(rv)) {
      EventListenerHolder holder(scriptListener);
      AddEventListenerInternal(holder, eventType, aName, flags, true);

      ls = FindEventHandler(eventType, aName);
    }
  } else {
    nsIJSEventListener* scriptListener = ls->GetJSListener();
    MOZ_ASSERT(scriptListener,
               "How can we have an event handler with no nsIJSEventListener?");

    bool same = scriptListener->GetHandler() == aHandler;
    // Possibly the same listener, but update still the context and scope.
    scriptListener->SetHandler(aHandler, aContext, aScopeObject);
    if (mTarget && !same) {
      mTarget->EventListenerRemoved(aName);
      mTarget->EventListenerAdded(aName);
    }
  }

  if (NS_SUCCEEDED(rv) && ls) {
    // Set flag to indicate possible need for compilation later
    ls->mHandlerIsString = !aHandler.HasEventHandler();
    if (aPermitUntrustedEvents) {
      ls->mFlags.mAllowUntrustedEvents = true;
    }

    *aListenerStruct = ls;
  } else {
    *aListenerStruct = nullptr;
  }

  return rv;
}
nsresult
nsEventListenerManager::SetEventHandlerInternal(nsIScriptContext *aContext,
                                                JSObject* aScopeObject,
                                                nsIAtom* aName,
                                                const nsEventHandler& aHandler,
                                                bool aPermitUntrustedEvents,
                                                nsListenerStruct **aListenerStruct)
{
  NS_ASSERTION((aContext && aScopeObject) || aHandler.HasEventHandler(),
               "Must have one or the other!");

  nsresult rv = NS_OK;
  uint32_t eventType = nsContentUtils::GetEventId(aName);
  nsListenerStruct* ls = FindEventHandler(eventType, aName);

  if (!ls) {
    // If we didn't find a script listener or no listeners existed
    // create and add a new one.
    const uint32_t flags = NS_EVENT_FLAG_BUBBLE | NS_PRIV_EVENT_FLAG_SCRIPT;

    nsCOMPtr<nsIJSEventListener> scriptListener;
    rv = NS_NewJSEventListener(aContext, aScopeObject, mTarget, aName,
                               aHandler, getter_AddRefs(scriptListener));

    if (NS_SUCCEEDED(rv)) {
      AddEventListener(scriptListener, eventType, aName, flags, true);

      ls = FindEventHandler(eventType, aName);
    }
  } else {
    nsIJSEventListener* scriptListener = ls->GetJSListener();
    MOZ_ASSERT(scriptListener,
               "How can we have an event handler with no nsIJSEventListener?");

    scriptListener->SetHandler(aHandler, aContext, aScopeObject);
  }

  if (NS_SUCCEEDED(rv) && ls) {
    // Set flag to indicate possible need for compilation later
    ls->mHandlerIsString = !aHandler.HasEventHandler();
    if (aPermitUntrustedEvents) {
      ls->mFlags |= NS_PRIV_EVENT_UNTRUSTED_PERMITTED;
    }

    *aListenerStruct = ls;
  } else {
    *aListenerStruct = nullptr;
  }

  return rv;
}