// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/core/html/html_popup_element.h"

#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/events/keyboard_event.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"

namespace blink {

HTMLPopupElement::HTMLPopupElement(Document& document)
    : HTMLElement(html_names::kPopupTag, document), open_(false) {
  DCHECK(RuntimeEnabledFeatures::HTMLPopupElementEnabled());
  UseCounter::Count(document, WebFeature::kPopupElement);
}


void HTMLPopupElement::MarkStyleDirty() {
  SetNeedsStyleRecalc(kLocalStyleChange,
                      StyleChangeReasonForTracing::Create(
                          style_change_reason::kPopupVisibilityChange));
}

bool HTMLPopupElement::open() const {
  return open_;
}

void HTMLPopupElement::hide() {
  if (!open_)
    return;
  GetDocument().HideAllPopupsUntil(this);
  PopPopupElement(this);
  open_ = false;
  PseudoStateChanged(CSSSelector::kPseudoPopupOpen);
  MarkStyleDirty();
  ScheduleHideEvent();
}

void HTMLPopupElement::ScheduleHideEvent() {
  Event* event = Event::Create(event_type_names::kHide);
  event->SetTarget(this);
  GetDocument().EnqueueAnimationFrameEvent(event);
}

void HTMLPopupElement::show() {
  if (open_ || !isConnected())
    return;

  // Only hide popups up to the anchor element's nearest shadow-including
  // ancestor popup element.
  HTMLPopupElement* parent_popup = nullptr;
  if (Element* anchor = AnchorElement()) {
    for (Node* ancestor = anchor; ancestor;
         ancestor = ancestor->ParentOrShadowHostNode()) {
      if (HTMLPopupElement* ancestor_popup =
              DynamicTo<HTMLPopupElement>(ancestor)) {
        parent_popup = ancestor_popup;
        break;
      }
    }
  }
  GetDocument().HideAllPopupsUntil(parent_popup);
  open_ = true;
  PseudoStateChanged(CSSSelector::kPseudoPopupOpen);
  PushNewPopupElement(this);
  MarkStyleDirty();
}

void HTMLPopupElement::PushNewPopupElement(HTMLPopupElement* popup) {
  auto& stack = GetDocument().PopupElementStack();
  DCHECK(!stack.Contains(popup));
  stack.push_back(popup);
  GetDocument().AddToTopLayer(popup);
}

void HTMLPopupElement::PopPopupElement(HTMLPopupElement* popup) {
  auto& stack = GetDocument().PopupElementStack();
  DCHECK(stack.back() == popup);
  stack.pop_back();
  GetDocument().RemoveFromTopLayer(popup);
}

HTMLPopupElement* HTMLPopupElement::TopmostPopupElement() {
  auto& stack = GetDocument().PopupElementStack();
  return stack.IsEmpty() ? nullptr : stack.back();
}

Element* HTMLPopupElement::AnchorElement() const {
  const AtomicString& anchor_id = FastGetAttribute(html_names::kAnchorAttr);
  if (anchor_id.IsNull())
    return nullptr;
  if (!IsInTreeScope())
    return nullptr;
  if (Element* anchor = GetTreeScope().getElementById(anchor_id))
    return anchor;
  return nullptr;
}

void HTMLPopupElement::HandleLightDismiss(const Event& event) {
  auto* target_node = event.target()->ToNode();
  if (!target_node)
    return;
  auto& document = target_node->GetDocument();
  DCHECK(document.PopupShowing());
  const AtomicString& event_type = event.type();
  if (event_type == event_type_names::kClick) {
    // We need to walk up from the clicked element to see if there
    // is a parent popup, or the anchor for a popup. There can be
    // multiple popups for a single anchor element, but we will
    // stop on any of them. Therefore, just store the popup that
    // is highest (last) on the popup stack for each anchor.
    HeapHashMap<Member<const Element>, Member<const HTMLPopupElement>> anchors;
    for (auto popup : document.PopupElementStack()) {
      if (auto* anchor = popup->AnchorElement()) {
        anchors.Set(anchor, popup);
      }
    }
    const HTMLPopupElement* closest_popup_parent = nullptr;
    for (Node* current_node = target_node; current_node;
         current_node = current_node->parentNode()) {
      if (auto* popup = DynamicTo<HTMLPopupElement>(current_node)) {
        closest_popup_parent = popup;
        break;
      }
      Element* current_element = DynamicTo<Element>(current_node);
      if (current_element && anchors.Contains(current_element)) {
        closest_popup_parent = anchors.at(current_element);
        break;
      }
    }
    document.HideAllPopupsUntil(closest_popup_parent);
  } else if (event_type == event_type_names::kKeydown) {
    const KeyboardEvent* key_event = DynamicTo<KeyboardEvent>(event);
    if (key_event && key_event->key() == "Escape") {
      // Escape key just pops the topmost <popup> off the stack.
      document.HideTopmostPopupElement();
    }
  } else if (event_type == event_type_names::kScroll) {
    // Close all popups upon scroll.
    document.HideAllPopupsUntil(nullptr);
  }
}

}  // namespace blink
