/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 *           (C) 2001 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All
 * rights reserved.
 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved.
 * (http://www.torchmobile.com/)
 * Copyright (C) 2011 Google Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"

#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/dom/container_node.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
#include "third_party/blink/renderer/core/dom/events/event_path.h"
#include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h"
#include "third_party/blink/renderer/core/dom/events/window_event_context.h"
#include "third_party/blink/renderer/core/events/mouse_event.h"
#include "third_party/blink/renderer/core/frame/ad_tracker.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
#include "third_party/blink/renderer/core/timing/event_timing.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"

namespace blink {

DispatchEventResult EventDispatcher::DispatchEvent(Node& node, Event& event) {
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("blink.debug"),
               "EventDispatcher::dispatchEvent");
#if DCHECK_IS_ON()
  DCHECK(!EventDispatchForbiddenScope::IsEventDispatchForbidden());
#endif
  EventDispatcher dispatcher(node, event);
  return event.DispatchEvent(dispatcher);
}

EventDispatcher::EventDispatcher(Node& node, Event& event)
    : node_(node), event_(event) {
  view_ = node.GetDocument().View();
  event_->InitEventPath(*node_);
}

void EventDispatcher::DispatchScopedEvent(Node& node, Event& event) {
  // We need to set the target here because it can go away by the time we
  // actually fire the event.
  event.SetTarget(&EventPath::EventTargetRespectingTargetRules(node));
  ScopedEventQueue::Instance()->EnqueueEvent(event);
}

void EventDispatcher::DispatchSimulatedClick(
    Node& node,
    Event* underlying_event,
    SimulatedClickMouseEventOptions mouse_event_options,
    SimulatedClickCreationScope creation_scope) {
  // This persistent vector doesn't cause leaks, because added Nodes are removed
  // before dispatchSimulatedClick() returns. This vector is here just to
  // prevent the code from running into an infinite recursion of
  // dispatchSimulatedClick().
  DEFINE_STATIC_LOCAL(Persistent<HeapHashSet<Member<Node>>>,
                      nodes_dispatching_simulated_clicks,
                      (MakeGarbageCollected<HeapHashSet<Member<Node>>>()));

  if (IsDisabledFormControl(&node))
    return;

  if (nodes_dispatching_simulated_clicks->Contains(&node))
    return;

  nodes_dispatching_simulated_clicks->insert(&node);

  if (mouse_event_options == kSendMouseOverUpDownEvents)
    EventDispatcher(node, *MouseEvent::Create(event_type_names::kMouseover,
                                              node.GetDocument().domWindow(),
                                              underlying_event, creation_scope))
        .Dispatch();

  if (mouse_event_options != kSendNoEvents) {
    EventDispatcher(node, *MouseEvent::Create(event_type_names::kMousedown,
                                              node.GetDocument().domWindow(),
                                              underlying_event, creation_scope))
        .Dispatch();
    node.SetActive(true);
    EventDispatcher(node, *MouseEvent::Create(event_type_names::kMouseup,
                                              node.GetDocument().domWindow(),
                                              underlying_event, creation_scope))
        .Dispatch();
  }
  // Some elements (e.g. the color picker) may set active state to true before
  // calling this method and expect the state to be reset during the call.
  node.SetActive(false);

  // always send click
  EventDispatcher(node, *MouseEvent::Create(event_type_names::kClick,
                                            node.GetDocument().domWindow(),
                                            underlying_event, creation_scope))
      .Dispatch();

  nodes_dispatching_simulated_clicks->erase(&node);
}

// https://dom.spec.whatwg.org/#dispatching-events
DispatchEventResult EventDispatcher::Dispatch() {
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("blink.debug"),
               "EventDispatcher::dispatch");

#if DCHECK_IS_ON()
  DCHECK(!event_dispatched_);
  event_dispatched_ = true;
#endif
  if (GetEvent().GetEventPath().IsEmpty()) {
    // eventPath() can be empty if event path is shrinked by relataedTarget
    // retargeting.
    return DispatchEventResult::kNotCanceled;
  }
  std::unique_ptr<EventTiming> eventTiming;
  if (origin_trials::EventTimingEnabled(&node_->GetDocument())) {
    LocalFrame* frame = node_->GetDocument().GetFrame();
    if (frame && frame->DomWindow()) {
      UseCounter::Count(node_->GetDocument(),
                        WebFeature::kPerformanceEventTimingConstructor);
      eventTiming = std::make_unique<EventTiming>(frame->DomWindow());
      eventTiming->WillDispatchEvent(*event_);
    }
  }
  event_->GetEventPath().EnsureWindowEventContext();

  const bool is_click =
      event_->IsMouseEvent() && event_->type() == event_type_names::kClick;

  if (is_click && event_->isTrusted()) {
    Document& document = node_->GetDocument();
    LocalFrame* frame = document.GetFrame();
    if (frame) {
      // A genuine mouse click cannot be triggered by script so we don't expect
      // there are any script in the stack.
      DCHECK(!frame->GetAdTracker() ||
             !frame->GetAdTracker()->IsAdScriptInStack());
      if (frame->IsAdSubframe()) {
        UseCounter::Count(document, WebFeature::kAdClick);
      }
    }
  }

  // 6. Let isActivationEvent be true, if event is a MouseEvent object and
  // event's type attribute is "click", and false otherwise.
  //
  // We need to include non-standard textInput event for HTMLInputElement.
  const bool is_activation_event =
      is_click || event_->type() == event_type_names::kTextInput;

  // 7. Let activationTarget be target, if isActivationEvent is true and target
  // has activation behavior, and null otherwise.
  Node* activation_target =
      is_activation_event && node_->HasActivationBehavior() ? node_ : nullptr;

  // A part of step 9 loop.
  if (is_activation_event && !activation_target && event_->bubbles()) {
    wtf_size_t size = event_->GetEventPath().size();
    for (wtf_size_t i = 1; i < size; ++i) {
      Node& target = event_->GetEventPath()[i].GetNode();
      if (target.HasActivationBehavior()) {
        activation_target = &target;
        break;
      }
    }
  }

  event_->SetTarget(&EventPath::EventTargetRespectingTargetRules(*node_));
#if DCHECK_IS_ON()
  DCHECK(!EventDispatchForbiddenScope::IsEventDispatchForbidden());
#endif
  DCHECK(event_->target());
  TRACE_EVENT1("devtools.timeline", "EventDispatch", "data",
               inspector_event_dispatch_event::Data(*event_));
  EventDispatchHandlingState* pre_dispatch_event_handler_result = nullptr;
  if (DispatchEventPreProcess(activation_target,
                              pre_dispatch_event_handler_result) ==
      kContinueDispatching) {
    if (DispatchEventAtCapturing() == kContinueDispatching) {
      // TODO(crbug/882574): Remove these.
      CHECK(event_->HasEventPath());
      CHECK(!event_->GetEventPath().IsEmpty());
      if (DispatchEventAtTarget() == kContinueDispatching)
        DispatchEventAtBubbling();
    }
  }
  DispatchEventPostProcess(activation_target,
                           pre_dispatch_event_handler_result);
  if (eventTiming)
    eventTiming->DidDispatchEvent(*event_);

  return EventTarget::GetDispatchEventResult(*event_);
}

inline EventDispatchContinuation EventDispatcher::DispatchEventPreProcess(
    Node* activation_target,
    EventDispatchHandlingState*& pre_dispatch_event_handler_result) {
  // 11. If activationTarget is non-null and activationTarget has
  // legacy-pre-activation behavior, then run activationTarget's
  // legacy-pre-activation behavior.
  if (activation_target) {
    pre_dispatch_event_handler_result =
        activation_target->PreDispatchEventHandler(*event_);
  }
  return (event_->GetEventPath().IsEmpty() || event_->PropagationStopped())
             ? kDoneDispatching
             : kContinueDispatching;
}

inline EventDispatchContinuation EventDispatcher::DispatchEventAtCapturing() {
  // Trigger capturing event handlers, starting at the top and working our way
  // down.
  event_->SetEventPhase(Event::kCapturingPhase);

  if (event_->GetEventPath().GetWindowEventContext().HandleLocalEvents(
          *event_) &&
      event_->PropagationStopped())
    return kDoneDispatching;

  for (wtf_size_t i = event_->GetEventPath().size() - 1; i > 0; --i) {
    const NodeEventContext& event_context = event_->GetEventPath()[i];
    if (event_context.CurrentTargetSameAsTarget()) {
      if (!RuntimeEnabledFeatures::
              CallCaptureListenersAtCapturePhaseAtShadowHostsEnabled())
        continue;
      event_->SetEventPhase(Event::kAtTarget);
      event_->SetFireOnlyCaptureListenersAtTarget(true);
      event_context.HandleLocalEvents(*event_);
      event_->SetFireOnlyCaptureListenersAtTarget(false);
    } else {
      event_->SetEventPhase(Event::kCapturingPhase);
      event_context.HandleLocalEvents(*event_);
    }
    if (event_->PropagationStopped())
      return kDoneDispatching;
  }

  return kContinueDispatching;
}

inline EventDispatchContinuation EventDispatcher::DispatchEventAtTarget() {
  event_->SetEventPhase(Event::kAtTarget);
  event_->GetEventPath()[0].HandleLocalEvents(*event_);
  return event_->PropagationStopped() ? kDoneDispatching : kContinueDispatching;
}

inline void EventDispatcher::DispatchEventAtBubbling() {
  // Trigger bubbling event handlers, starting at the bottom and working our way
  // up.
  wtf_size_t size = event_->GetEventPath().size();
  for (wtf_size_t i = 1; i < size; ++i) {
    const NodeEventContext& event_context = event_->GetEventPath()[i];
    if (event_context.CurrentTargetSameAsTarget()) {
      // TODO(hayato): Need to check cancelBubble() also here?
      event_->SetEventPhase(Event::kAtTarget);
      if (RuntimeEnabledFeatures::
              CallCaptureListenersAtCapturePhaseAtShadowHostsEnabled()) {
        event_->SetFireOnlyNonCaptureListenersAtTarget(true);
        event_context.HandleLocalEvents(*event_);
        event_->SetFireOnlyNonCaptureListenersAtTarget(false);
      } else {
        event_context.HandleLocalEvents(*event_);
      }
    } else if (event_->bubbles() && !event_->cancelBubble()) {
      event_->SetEventPhase(Event::kBubblingPhase);
      event_context.HandleLocalEvents(*event_);
    } else {
      continue;
    }
    if (event_->PropagationStopped())
      return;
  }
  if (event_->bubbles() && !event_->cancelBubble()) {
    event_->SetEventPhase(Event::kBubblingPhase);
    event_->GetEventPath().GetWindowEventContext().HandleLocalEvents(*event_);
  }
}

inline void EventDispatcher::DispatchEventPostProcess(
    Node* activation_target,
    EventDispatchHandlingState* pre_dispatch_event_handler_result) {
  event_->SetTarget(&EventPath::EventTargetRespectingTargetRules(*node_));
  // https://dom.spec.whatwg.org/#concept-event-dispatch
  // 14. Unset event’s dispatch flag, stop propagation flag, and stop immediate
  // propagation flag.
  event_->SetStopPropagation(false);
  event_->SetStopImmediatePropagation(false);
  // 15. Set event’s eventPhase attribute to NONE.
  event_->SetEventPhase(0);
  // TODO(rakina): investigate this and move it to the bottom of step 16
  // 17. Set event’s currentTarget attribute to null.
  event_->SetCurrentTarget(nullptr);

  bool is_click = event_->IsMouseEvent() &&
                  ToMouseEvent(*event_).type() == event_type_names::kClick;
  if (is_click) {
    // Fire an accessibility event indicating a node was clicked on.  This is
    // safe if event_->target()->ToNode() returns null.
    if (AXObjectCache* cache = node_->GetDocument().ExistingAXObjectCache())
      cache->HandleClicked(event_->target()->ToNode());

    // Pass the data from the PreDispatchEventHandler to the
    // PostDispatchEventHandler.
    // This may dispatch an event, and node_ and event_ might be altered.
    if (activation_target) {
      activation_target->PostDispatchEventHandler(
          *event_, pre_dispatch_event_handler_result);
    }
    // TODO(tkent): Is it safe to kick DefaultEventHandler() with such altered
    // event_?
  }

  // The DOM Events spec says that events dispatched by JS (other than "click")
  // should not have their default handlers invoked.
  bool is_trusted_or_click =
      !RuntimeEnabledFeatures::TrustedEventsDefaultActionEnabled() ||
      event_->isTrusted() || is_click;

  // For Android WebView (distinguished by wideViewportQuirkEnabled)
  // enable untrusted events for mouse down on select elements because
  // fastclick.js seems to generate these. crbug.com/642698
  // TODO(dtapuska): Change this to a target SDK quirk crbug.com/643705
  if (!is_trusted_or_click && event_->IsMouseEvent() &&
      event_->type() == event_type_names::kMousedown &&
      IsHTMLSelectElement(*node_)) {
    if (Settings* settings = node_->GetDocument().GetSettings()) {
      is_trusted_or_click = settings->GetWideViewportQuirkEnabled();
    }
  }

  // Call default event handlers. While the DOM does have a concept of
  // preventing default handling, the detail of which handlers are called is an
  // internal implementation detail and not part of the DOM.
  if (!event_->defaultPrevented() && !event_->DefaultHandled() &&
      is_trusted_or_click) {
    // Non-bubbling events call only one default event handler, the one for the
    // target.
    node_->WillCallDefaultEventHandler(*event_);
    node_->DefaultEventHandler(*event_);
    DCHECK(!event_->defaultPrevented());
    // For bubbling events, call default event handlers on the same targets in
    // the same order as the bubbling phase.
    if (!event_->DefaultHandled() && event_->bubbles()) {
      wtf_size_t size = event_->GetEventPath().size();
      for (wtf_size_t i = 1; i < size; ++i) {
        event_->GetEventPath()[i].GetNode().WillCallDefaultEventHandler(
            *event_);
        event_->GetEventPath()[i].GetNode().DefaultEventHandler(*event_);
        DCHECK(!event_->defaultPrevented());
        if (event_->DefaultHandled())
          break;
      }
    }
  }

  // Track the usage of sending a mousedown event to a select element to force
  // it to open. This measures a possible breakage of not allowing untrusted
  // events to open select boxes.
  if (!event_->isTrusted() && event_->IsMouseEvent() &&
      event_->type() == event_type_names::kMousedown &&
      IsHTMLSelectElement(*node_)) {
    UseCounter::Count(node_->GetDocument(),
                      WebFeature::kUntrustedMouseDownEventDispatchedToSelect);
  }
  // 16. If target's root is a shadow root, then set event's target attribute
  // and event's relatedTarget to null.
  event_->SetTarget(event_->GetEventPath().GetWindowEventContext().Target());
  if (!event_->target())
    event_->SetRelatedTargetIfExists(nullptr);
}

}  // namespace blink
