<!DOCTYPE html>
<title>Custom Elements: Create an element when definition is non-null and synchronous flag set</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="resources/custom-elements-helpers.js"></script>
<body>
<script>
'use strict';

setup({
  allow_uncaught_exception: true,
});

const expectTypeError = TypeError.prototype;
const expectNotSupportedError = 'NOT_SUPPORTED_ERR';

// https://dom.spec.whatwg.org/#concept-create-element
// 5. If definition is non-null and the definition represents a customized built-in element:
// 5.3. If the synchronous custom elements flag is set:
// 6. If definition is non-null, then:
// 6.1. If the synchronous custom elements flag is set:

test_create_element_synchronous(
  'createElement(): ',
  (w, constructor, opt_tag) => {
    if (!opt_tag) {
      w.customElements.define('a-a', constructor);
      return w.document.createElement('a-a');
    } else {
      let extend_options = { extends: opt_tag };
      w.customElements.define('a-a', constructor, extend_options);
      return w.document.createElement(opt_tag, { is: 'a-a' });
    }
  });

test_create_element_synchronous(
  'createElementNS(): ',
  (w, constructor, opt_tag) => {
    if (!opt_tag) {
      w.customElements.define('a-a', constructor);
      return w.document.createElementNS('http://www.w3.org/1999/xhtml', 'a-a');
    } else {
      let extend_options = { extends: opt_tag };
      w.customElements.define('a-a', constructor, extend_options);
      return w.document.createElementNS('http://www.w3.org/1999/xhtml', opt_tag, { is: 'a-a' });
    }
  });

function test_create_element_synchronous(description, define_and_create_element) {
  test_with_window((w) => {
    let is_constructed = false;
    class A extends w.HTMLElement {
      constructor() { super(); is_constructed = true; }
    }
    let o = define_and_create_element(w, A);
    assert_true(is_constructed, 'custom constructor ran');
    assert_equals(o.constructor, A);
  }, `${description}Pre-flight check should succeed`);

  test_with_window((w) => {
    let is_constructed = false;
    class A extends w.HTMLDivElement {
      constructor() { super(); is_constructed = true; }
    }
    let o = define_and_create_element(w, A, 'div');
    assert_true(is_constructed, 'custom constructor ran');
    assert_equals(o.constructor, A);
  }, `${description}5. Create a customized built-in element`);

  test_with_window((w) => {
    let is_constructed = false;
    class A extends w.HTMLElement {
      constructor() { super(); is_constructed = true; }
    }
    define_and_create_element(w, A);
    assert_true(is_constructed, 'custom constructor ran');
  }, `${description}6. Create an autonomous custom element`);

  test_with_window((w) => {
    const err = new Error('check this is reported');
    err.name = 'reported';
    assert_reports(w, err, () => {
      define_and_create_element(w, class extends w.HTMLElement {
        constructor() { super(); throw err; }
      });
    });
  }, `${description}6.1.2. Errors in Construct(C) should be reported`);

  test_with_window((w) => {
    assert_reports(w, expectTypeError, () => {
      define_and_create_element(w, class {
        constructor() {}
      });
    });
  }, `${description}6.1.3. If result does not implement the HTMLElement interface, throw a TypeError`);

  test_with_window((w) => {
    assert_reports(w, expectNotSupportedError, () => {
      define_and_create_element(w, class extends w.HTMLElement {
        constructor() { super(); this.setAttribute('a', 'a'); }
      });
    });
  }, `${description}6.1.4. If result\'s attribute list is not empty, then throw a NotSupportedError`);

  test_with_window((w) => {
    assert_reports(w, expectNotSupportedError, () => {
      define_and_create_element(w, class extends w.HTMLElement {
        constructor() { super(); this.appendChild(w.document.createElement('a')); }
      });
    }, 'should throw if it has a child element');
  }, `${description}6.1.5. If result has children, then throw a NotSupportedError`);

  test_with_window((w) => {
    assert_reports(w, expectNotSupportedError, () => {
      define_and_create_element(w, class extends w.HTMLElement {
        constructor() { super(); this.append('a'); }
      });
    }, 'should throw if it has a child text node');
  }, `${description}6.1.5. If result has children, then throw a NotSupportedError`);

  test_with_window((w) => {
    assert_reports(w, expectNotSupportedError, () => {
      define_and_create_element(w, class extends w.HTMLElement {
        constructor() { super(); w.document.createElement('div').appendChild(this); }
      });
    });
  }, `${description}6.1.6. If result\'s parent is not null, then throw a NotSupportedError`);

  test_with_window((w) => {
    assert_reports(w, expectNotSupportedError, () => {
      define_and_create_element(w, class extends w.HTMLElement {
        constructor() { super(); return w.document.implementation.createHTMLDocument().createElement('div'); }
      });
    });
  }, `${description}6.1.7. If result\'s node document is not document, then throw a NotSupportedError`);

  // See the note in step 6.1.8. In future, it may be possible to throw
  // NotSupportedError for some elements.
  test_with_window((w) => {
    assert_reports(w, expectTypeError, () => {
      define_and_create_element(w, class extends w.HTMLElement {
        constructor() { super(); return w.document.createElementNS('http://www.w3.org/2000/svg', 'g'); }
      });
    });
  }, `${description}6.1.8. If result\'s namespace is not the HTML namespace, then throw (a NotSupportedError, currently TypeError)`);

  test_with_window((w) => {
    assert_reports(w, expectNotSupportedError, () => {
      define_and_create_element(w, class extends w.HTMLElement {
        constructor() { super(); return document.createElement('div'); }
      });
    });
  }, `${description}6.1.9. If result\'s local name is not equal to localName, then throw a NotSupportedError`);
}
</script>
</body>
