<!DOCTYPE html>
<title>Custom Elements: [HTMLConstructor] derives prototype from NewTarget</title>
<meta name="author" title="Domenic Denicola" href="mailto:d@domenic.me">
<meta name="help" content="https://html.spec.whatwg.org/multipage/dom.html#htmlconstructor">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/custom-elements-helpers.js"></script>
<body>
<script>
"use strict";

test_with_window(w => {
  let beforeDefinition = true;
  const proto1 = { "proto": "number one" };
  const proto2 = { "proto": "number two" };

  function TestElement() {
    const o = Reflect.construct(w.HTMLElement, [], new.target);
    assert_equals(Object.getPrototypeOf(o), proto2,
      "Must use the value returned from new.target.prototype");
    assert_not_equals(Object.getPrototypeOf(o), proto1,
      "Must not use the prototype stored at definition time");
  }

  const ElementWithDynamicPrototype = new Proxy(TestElement, {
      get: function (target, name) {
        if (name == "prototype")
          return beforeDefinition ? proto1 : proto2;
        return target[name];
      }
  });

  w.customElements.define("test-element", ElementWithDynamicPrototype);

  beforeDefinition = false;
  new ElementWithDynamicPrototype();
}, "Use NewTarget's prototype, not the one stored at definition time");

test_with_window(w => {
  // We have to not throw during define(), but throw during super()
  let throws = false;

  function TestElement() {
    throws = true;
    assert_throws({ name: "prototype throws" }, () => {
      Reflect.construct(w.HTMLElement, [], new.target);
    });
  }

  const ElementWithDynamicPrototype = new Proxy(TestElement, {
    get: function (target, name) {
      if (throws && name == "prototype")
        throw { name: "prototype throws" };
      return target[name];
    }
  });

  w.customElements.define("test-element", ElementWithDynamicPrototype);

  new ElementWithDynamicPrototype();

}, "Rethrow any exceptions thrown while getting the prototype");

[null, undefined, 5, "string"].forEach(function (notAnObject) {
  test_with_window(w => {
    // We have to return an object during define(), but not during super()
    let returnNotAnObject = false;

    function TestElement() {
      const o = Reflect.construct(w.HTMLElement, [], new.target);

      assert_equals(Object.getPrototypeOf(new.target), window.Function.prototype);
      assert_equals(Object.getPrototypeOf(o), window.HTMLElement.prototype,
        "Must use the HTMLElement from the realm of NewTarget");
      assert_not_equals(Object.getPrototypeOf(o), w.HTMLElement.prototype,
        "Must not use the HTMLElement from the realm of the active function object (w.HTMLElement)");

      return o;
    }

    const ElementWithDynamicPrototype = new Proxy(TestElement, {
      get: function (target, name) {
        if (name == "prototype")
          return returnNotAnObject ? notAnObject : {};
        return target[name];
      }
    });

    w.customElements.define("test-element", ElementWithDynamicPrototype);

    returnNotAnObject = true;
    new ElementWithDynamicPrototype();
  }, "If prototype is not object (" + notAnObject + "), derives the fallback from NewTarget's realm (autonomous custom elements)");
});

[null, undefined, 5, "string"].forEach(function (notAnObject) {
  test_with_window(w => {
    // We have to return an object during define(), but not during super()
    let returnNotAnObject = false;

    function TestElement() {
      const o = Reflect.construct(w.HTMLParagraphElement, [], new.target);

      assert_equals(Object.getPrototypeOf(o), window.HTMLParagraphElement.prototype,
        "Must use the HTMLParagraphElement from the realm of NewTarget");
      assert_not_equals(Object.getPrototypeOf(o), w.HTMLParagraphElement.prototype,
        "Must not use the HTMLParagraphElement from the realm of the active function object (w.HTMLParagraphElement)");

      return o;
    }

    const ElementWithDynamicPrototype = new Proxy(TestElement, {
      get: function (target, name) {
        if (name == "prototype")
          return returnNotAnObject ? notAnObject : {};
        return target[name];
      }
    });

    w.customElements.define("test-element", ElementWithDynamicPrototype, { extends: "p" });

    returnNotAnObject = true;
    new ElementWithDynamicPrototype();
  }, "If prototype is not object (" + notAnObject + "), derives the fallback from NewTarget's realm (customized built-in elements)");
});

test_with_window(w => {
    class SomeCustomElement extends HTMLParagraphElement {};
    var getCount = 0;
    var countingProxy = new Proxy(SomeCustomElement, {
        get: function(target, prop, receiver) {
            if (prop == "prototype") {
                ++getCount;
            }
            return Reflect.get(target, prop, receiver);
        }
    });
    w.customElements.define("failure-counting-element", countingProxy);
    // define() gets the prototype of the constructor it's passed, so
    // reset the counter.
    getCount = 0;
    assert_throws({'name': 'TypeError'},
                  function () { new countingProxy() },
                  "Should not be able to construct an HTMLParagraphElement not named 'p'");
    assert_equals(getCount, 0, "Should never have gotten .prototype");
}, 'HTMLParagraphElement constructor must not get .prototype until it finishes its extends sanity checks, calling proxy constructor directly');

test_with_window(w => {
    class SomeCustomElement extends HTMLParagraphElement {};
    var getCount = 0;
    var countingProxy = new Proxy(SomeCustomElement, {
        get: function(target, prop, receiver) {
            if (prop == "prototype") {
                ++getCount;
            }
            return Reflect.get(target, prop, receiver);
        }
    });
    w.customElements.define("failure-counting-element", countingProxy);
    // define() gets the prototype of the constructor it's passed, so
    // reset the counter.
    getCount = 0;
    assert_throws({'name': 'TypeError'},
                  function () { Reflect.construct(HTMLParagraphElement, [], countingProxy) },
                  "Should not be able to construct an HTMLParagraphElement not named 'p'");
    assert_equals(getCount, 0, "Should never have gotten .prototype");
}, 'HTMLParagraphElement constructor must not get .prototype until it finishes its extends sanity checks, calling via Reflect');
</script>
</body>
