// Copyright 2016 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/custom/custom_element.h"

#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/qualified_name.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/html/custom/ce_reactions_scope.h"
#include "third_party/blink/renderer/core/html/custom/custom_element_definition.h"
#include "third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.h"
#include "third_party/blink/renderer/core/html/custom/custom_element_registry.h"
#include "third_party/blink/renderer/core/html/custom/v0_custom_element.h"
#include "third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html/html_unknown_element.h"
#include "third_party/blink/renderer/core/html_element_factory.h"
#include "third_party/blink/renderer/core/html_element_type_helpers.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h"

namespace blink {

CustomElementRegistry* CustomElement::Registry(const Element& element) {
  return Registry(element.GetDocument());
}

CustomElementRegistry* CustomElement::Registry(const Document& document) {
  if (LocalDOMWindow* window = document.ExecutingWindow())
    return window->customElements();
  return nullptr;
}

static CustomElementDefinition* DefinitionForElementWithoutCheck(
    const Element& element) {
  DCHECK_EQ(element.GetCustomElementState(), CustomElementState::kCustom);
  return element.GetCustomElementDefinition();
}

CustomElementDefinition* CustomElement::DefinitionForElement(
    const Element* element) {
  if (!element ||
      element->GetCustomElementState() != CustomElementState::kCustom)
    return nullptr;
  return DefinitionForElementWithoutCheck(*element);
}

bool CustomElement::IsHyphenatedSpecElementName(const AtomicString& name) {
  // Even if Blink does not implement one of the related specs, (for
  // example annotation-xml is from MathML, which Blink does not
  // implement) we must prohibit using the name because that is
  // required by the HTML spec which we *do* implement. Don't remove
  // names from this list without removing them from the HTML spec
  // first.
  DEFINE_STATIC_LOCAL(HashSet<AtomicString>, hyphenated_spec_element_names,
                      ({
                          "annotation-xml", "color-profile", "font-face",
                          "font-face-src", "font-face-uri", "font-face-format",
                          "font-face-name", "missing-glyph",
                      }));
  return hyphenated_spec_element_names.Contains(name);
}

bool CustomElement::ShouldCreateCustomElement(const AtomicString& name) {
  return IsValidName(name);
}

bool CustomElement::ShouldCreateCustomElement(const QualifiedName& tag_name) {
  return ShouldCreateCustomElement(tag_name.LocalName()) &&
         tag_name.NamespaceURI() == HTMLNames::xhtmlNamespaceURI;
}

bool CustomElement::ShouldCreateCustomizedBuiltinElement(
    const AtomicString& local_name) {
  return htmlElementTypeForTag(local_name) !=
         HTMLElementType::kHTMLUnknownElement;
}

bool CustomElement::ShouldCreateCustomizedBuiltinElement(
    const QualifiedName& tag_name) {
  return ShouldCreateCustomizedBuiltinElement(tag_name.LocalName()) &&
         tag_name.NamespaceURI() == HTMLNames::xhtmlNamespaceURI;
}

static CustomElementDefinition* DefinitionFor(
    const Document& document,
    const CustomElementDescriptor desc) {
  if (CustomElementRegistry* registry = CustomElement::Registry(document))
    return registry->DefinitionFor(desc);
  return nullptr;
}

// https://dom.spec.whatwg.org/#concept-create-element
HTMLElement* CustomElement::CreateCustomElement(Document& document,
                                                const QualifiedName& tag_name,
                                                CreateElementFlags flags) {
  DCHECK(ShouldCreateCustomElement(tag_name)) << tag_name;
  // 4. Let definition be the result of looking up a custom element
  // definition given document, namespace, localName, and is.
  if (auto* definition = DefinitionFor(
          document, CustomElementDescriptor(tag_name.LocalName(),
                                            tag_name.LocalName()))) {
    DCHECK(definition->Descriptor().IsAutonomous());
    // 6. Otherwise, if definition is non-null, then:
    return definition->CreateElement(document, tag_name, flags);
  }
  // 7. Otherwise:
  return ToHTMLElement(
      CreateUncustomizedOrUndefinedElementTemplate<kQNameIsValid>(
          document, tag_name, flags, g_null_atom));
}

// Step 7 of https://dom.spec.whatwg.org/#concept-create-element in
// addition to Custom Element V0 handling.
template <CustomElement::CreateUUCheckLevel level>
Element* CustomElement::CreateUncustomizedOrUndefinedElementTemplate(
    Document& document,
    const QualifiedName& tag_name,
    const CreateElementFlags flags,
    const AtomicString& is_value) {
  if (level == kQNameIsValid) {
    DCHECK(is_value.IsNull());
    DCHECK(ShouldCreateCustomElement(tag_name)) << tag_name;
  }

  Element* element;
  if (V0CustomElement::IsValidName(tag_name.LocalName()) &&
      document.RegistrationContext()) {
    element = document.RegistrationContext()->CreateCustomTagElement(document,
                                                                     tag_name);
  } else {
    // 7.1. Let interface be the element interface for localName and namespace.
    // 7.2. Set result to a new element that implements interface, with ...
    element = document.CreateRawElement(tag_name, flags);
    if (level == kCheckAll && !is_value.IsNull()) {
      element->SetIsValue(is_value);
      if (flags.IsCustomElementsV0())
        V0CustomElementRegistrationContext::SetTypeExtension(element, is_value);
    }
  }

  // 7.3. If namespace is the HTML namespace, and either localName is a
  // valid custom element name or is is non-null, then set result’s
  // custom element state to "undefined".
  if (level == kQNameIsValid)
    element->SetCustomElementState(CustomElementState::kUndefined);
  else if (tag_name.NamespaceURI() == HTMLNames::xhtmlNamespaceURI &&
           (CustomElement::IsValidName(tag_name.LocalName()) ||
            !is_value.IsNull()))
    element->SetCustomElementState(CustomElementState::kUndefined);

  return element;
}

Element* CustomElement::CreateUncustomizedOrUndefinedElement(
    Document& document,
    const QualifiedName& tag_name,
    const CreateElementFlags flags,
    const AtomicString& is_value) {
  return CreateUncustomizedOrUndefinedElementTemplate<kCheckAll>(
      document, tag_name, flags, is_value);
}

HTMLElement* CustomElement::CreateFailedElement(Document& document,
                                                const QualifiedName& tag_name) {
  DCHECK(ShouldCreateCustomElement(tag_name));

  // "create an element for a token":
  // https://html.spec.whatwg.org/multipage/syntax.html#create-an-element-for-the-token

  // 7. If this step throws an exception, let element be instead a new element
  // that implements HTMLUnknownElement, with no attributes, namespace set to
  // given namespace, namespace prefix set to null, custom element state set
  // to "failed", and node document set to document.

  HTMLElement* element = HTMLUnknownElement::Create(tag_name, document);
  element->SetCustomElementState(CustomElementState::kFailed);
  return element;
}

void CustomElement::Enqueue(Element* element, CustomElementReaction* reaction) {
  // To enqueue an element on the appropriate element queue
  // https://html.spec.whatwg.org/multipage/scripting.html#enqueue-an-element-on-the-appropriate-element-queue

  // If the custom element reactions stack is not empty, then
  // Add element to the current element queue.
  if (CEReactionsScope* current = CEReactionsScope::Current()) {
    current->EnqueueToCurrentQueue(element, reaction);
    return;
  }

  // If the custom element reactions stack is empty, then
  // Add element to the backup element queue.
  CustomElementReactionStack::Current().EnqueueToBackupQueue(element, reaction);
}

void CustomElement::EnqueueConnectedCallback(Element* element) {
  CustomElementDefinition* definition =
      DefinitionForElementWithoutCheck(*element);
  if (definition->HasConnectedCallback())
    definition->EnqueueConnectedCallback(element);
}

void CustomElement::EnqueueDisconnectedCallback(Element* element) {
  CustomElementDefinition* definition =
      DefinitionForElementWithoutCheck(*element);
  if (definition->HasDisconnectedCallback())
    definition->EnqueueDisconnectedCallback(element);
}

void CustomElement::EnqueueAdoptedCallback(Element* element,
                                           Document* old_owner,
                                           Document* new_owner) {
  DCHECK_EQ(element->GetCustomElementState(), CustomElementState::kCustom);
  CustomElementDefinition* definition =
      DefinitionForElementWithoutCheck(*element);
  if (definition->HasAdoptedCallback())
    definition->EnqueueAdoptedCallback(element, old_owner, new_owner);
}

void CustomElement::EnqueueAttributeChangedCallback(
    Element* element,
    const QualifiedName& name,
    const AtomicString& old_value,
    const AtomicString& new_value) {
  CustomElementDefinition* definition =
      DefinitionForElementWithoutCheck(*element);
  if (definition->HasAttributeChangedCallback(name))
    definition->EnqueueAttributeChangedCallback(element, name, old_value,
                                                new_value);
}

void CustomElement::TryToUpgrade(Element* element,
                                 bool upgrade_invisible_elements) {
  // Try to upgrade an element
  // https://html.spec.whatwg.org/multipage/scripting.html#concept-try-upgrade

  DCHECK_EQ(element->GetCustomElementState(), CustomElementState::kUndefined);

  CustomElementRegistry* registry = CustomElement::Registry(*element);
  if (!registry)
    return;
  const AtomicString& is_value = element->IsValue();
  if (CustomElementDefinition* definition =
          registry->DefinitionFor(CustomElementDescriptor(
              is_value.IsNull() ? element->localName() : is_value,
              element->localName())))
    definition->EnqueueUpgradeReaction(element, upgrade_invisible_elements);
  else
    registry->AddCandidate(element);
}

}  // namespace blink
