// https://html.spec.whatwg.org/multipage/scripting.html#upgrades
bool ScriptCustomElementDefinition::runConstructor(Element* element) {
  if (!m_scriptState->contextIsValid())
    return false;
  ScriptState::Scope scope(m_scriptState.get());
  v8::Isolate* isolate = m_scriptState->isolate();

  // Step 5 says to rethrow the exception; but there is no one to
  // catch it. The side effect is to report the error.
  v8::TryCatch tryCatch(isolate);
  tryCatch.SetVerbose(true);

  Element* result = runConstructor();

  // To report exception thrown from runConstructor()
  if (tryCatch.HasCaught())
    return false;

  // To report InvalidStateError Exception, when the constructor returns some
  // different object
  if (result != element) {
    const String& message =
        "custom element constructors must call super() first and must "
        "not return a different object";
    v8::Local<v8::Value> exception = V8ThrowException::createDOMException(
        m_scriptState->isolate(), InvalidStateError, message);
    dispatchErrorEvent(isolate, exception, constructor());
    return false;
  }

  return true;
}
// https://html.spec.whatwg.org/multipage/scripting.html#concept-upgrade-an-element
void CustomElementDefinition::upgrade(Element* element)
{
    DCHECK_EQ(element->getCustomElementState(), CustomElementState::Undefined);

    if (!m_observedAttributes.isEmpty())
        enqueueAttributeChangedCallbackForAllAttributes(element);

    if (element->inShadowIncludingDocument() && hasConnectedCallback())
        enqueueConnectedCallback(element);

    m_constructionStack.append(element);
    size_t depth = m_constructionStack.size();

    bool succeeded = runConstructor(element);

    // Pop the construction stack.
    if (m_constructionStack.last().get())
        DCHECK_EQ(m_constructionStack.last(), element);
    DCHECK_EQ(m_constructionStack.size(), depth); // It's a *stack*.
    m_constructionStack.removeLast();

    if (!succeeded)
        return;

    CHECK(element->getCustomElementState() == CustomElementState::Custom);
}
HTMLElement* ScriptCustomElementDefinition::createElementSync(
    Document& document,
    const QualifiedName& tagName,
    ExceptionState& exceptionState) {
  DCHECK(ScriptState::current(m_scriptState->isolate()) == m_scriptState);

  // Create an element
  // https://dom.spec.whatwg.org/#concept-create-element
  // 6. If definition is non-null
  // 6.1. If the synchronous custom elements flag is set:
  // 6.1.2. Set result to Construct(C). Rethrow any exceptions.

  // Create an element and push to the construction stack.
  // V8HTMLElement::constructorCustom() can only refer to
  // window.document(), but it is different from the document here
  // when it is an import document.  This is not exactly what the
  // spec defines, but the public behavior matches to the spec.
  Element* element = createElementForConstructor(document);
  {
    ConstructionStackScope constructionStackScope(this, element);
    v8::TryCatch tryCatch(m_scriptState->isolate());
    element = runConstructor();
    if (tryCatch.HasCaught()) {
      exceptionState.rethrowV8Exception(tryCatch.Exception());
      return nullptr;
    }
  }

  // 6.1.3. through 6.1.9.
  checkConstructorResult(element, document, tagName, exceptionState);
  if (exceptionState.hadException())
    return nullptr;

  DCHECK_EQ(element->getCustomElementState(), CustomElementState::Custom);
  return toHTMLElement(element);
}