<!DOCTYPE html>
<html>
<head>
<title>Custom Elements: Upgrading custom elements should enqueue attributeChanged and connected callbacks</title>
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
<meta name="assert" content="Upgrading custom elements should enqueue attributeChanged and connected callbacksml">
<meta name="help" content="https://html.spec.whatwg.org/#upgrades">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/custom-elements-helpers.js"></script>
</head>
<body>
<div id="log"></div>
<script>
setup({allow_uncaught_exception:true});

test_with_window(function (contentWindow) {
    const contentDocument = contentWindow.document;
    contentDocument.write('<test-element id="some" title="This is a test">');

    const undefinedElement = contentDocument.querySelector('test-element');
    assert_equals(Object.getPrototypeOf(undefinedElement), contentWindow.HTMLElement.prototype);

    let log = [];
    class TestElement extends contentWindow.HTMLElement {
        constructor() {
            super();
            log.push(create_constructor_log(this));
        }
        attributeChangedCallback(...args) {
            log.push(create_attribute_changed_callback_log(this, ...args));
        }
        static get observedAttributes() { return ['id', 'title']; }
    }
    contentWindow.customElements.define('test-element', TestElement);
    assert_equals(Object.getPrototypeOf(undefinedElement), TestElement.prototype);

    assert_equals(log.length, 3);
    assert_constructor_log_entry(log[0], undefinedElement);
    assert_attribute_log_entry(log[1], {name: 'id', oldValue: null, newValue: 'some', namespace: null});
    assert_attribute_log_entry(log[2], {name: 'title', oldValue: null, newValue: 'This is a test', namespace: null});
}, 'Upgrading a custom element must enqueue attributeChangedCallback on each attribute');

test_with_window(function (contentWindow) {
    const contentDocument = contentWindow.document;
    contentDocument.write('<test-element id="some" title="This is a test" class="foo">');

    const undefinedElement = contentDocument.querySelector('test-element');
    assert_equals(Object.getPrototypeOf(undefinedElement), contentWindow.HTMLElement.prototype);

    let log = [];
    class TestElement extends contentWindow.HTMLElement {
        constructor() {
            super();
            log.push(create_constructor_log(this));
        }
        attributeChangedCallback(...args) {
            log.push(create_attribute_changed_callback_log(this, ...args));
        }
        static get observedAttributes() { return ['class', 'id']; }
    }
    contentWindow.customElements.define('test-element', TestElement);
    assert_equals(Object.getPrototypeOf(undefinedElement), TestElement.prototype);

    assert_equals(log.length, 3);
    assert_constructor_log_entry(log[0], undefinedElement);
    assert_attribute_log_entry(log[1], {name: 'id', oldValue: null, newValue: 'some', namespace: null});
    assert_attribute_log_entry(log[2], {name: 'class', oldValue: null, newValue: 'foo', namespace: null});
}, 'Upgrading a custom element not must enqueue attributeChangedCallback on unobserved attributes');

test_with_window(function (contentWindow) {
    const contentDocument = contentWindow.document;
    contentDocument.write('<test-element id="some" title="This is a test" class="foo">');

    const undefinedElement = contentDocument.querySelector('test-element');
    assert_equals(Object.getPrototypeOf(undefinedElement), contentWindow.HTMLElement.prototype);

    let log = [];
    class TestElement extends contentWindow.HTMLElement {
        constructor() {
            super();
            log.push(create_constructor_log(this));
        }
        connectedCallback(...args) {
            log.push(create_connected_callback_log(this, ...args));
        }
    }
    contentWindow.customElements.define('test-element', TestElement);
    assert_equals(Object.getPrototypeOf(undefinedElement), TestElement.prototype);

    assert_equals(log.length, 2);
    assert_constructor_log_entry(log[0], undefinedElement);
    assert_connected_log_entry(log[1], undefinedElement);
}, 'Upgrading a custom element must enqueue connectedCallback if the element in the document');

test_with_window(function (contentWindow) {
    const contentDocument = contentWindow.document;
    contentDocument.write('<test-element id="some" title="This is a test" class="foo">');

    const undefinedElement = contentDocument.querySelector('test-element');
    assert_equals(Object.getPrototypeOf(undefinedElement), contentWindow.HTMLElement.prototype);

    let log = [];
    class TestElement extends contentWindow.HTMLElement {
        constructor() {
            super();
            log.push(create_constructor_log(this));
        }
        connectedCallback(...args) {
            log.push(create_connected_callback_log(this, ...args));
        }
        attributeChangedCallback(...args) {
            log.push(create_attribute_changed_callback_log(this, ...args));
        }
        static get observedAttributes() { return ['class', 'id']; }
    }
    contentWindow.customElements.define('test-element', TestElement);
    assert_equals(Object.getPrototypeOf(undefinedElement), TestElement.prototype);

    assert_equals(log.length, 4);
    assert_constructor_log_entry(log[0], undefinedElement);
    assert_attribute_log_entry(log[1], {name: 'id', oldValue: null, newValue: 'some', namespace: null});
    assert_attribute_log_entry(log[2], {name: 'class', oldValue: null, newValue: 'foo', namespace: null});
    assert_connected_log_entry(log[3], undefinedElement);
}, 'Upgrading a custom element must enqueue attributeChangedCallback before connectedCallback');

test_with_window(function (contentWindow) {
    const contentDocument = contentWindow.document;
    contentDocument.write('<test-element id="some" title="This is a test" class="foo">');

    const undefinedElement = contentDocument.querySelector('test-element');
    assert_equals(Object.getPrototypeOf(undefinedElement), contentWindow.HTMLElement.prototype);

    let log = [];
    class TestElement extends contentWindow.HTMLElement {
        constructor() {
            super();
            log.push(create_constructor_log(this));
            throw 'Exception thrown as a part of test';
        }
        connectedCallback(...args) {
            log.push(create_connected_callback_log(this, ...args));
        }
        attributeChangedCallback(...args) {
            log.push(create_attribute_changed_callback_log(this, ...args));
        }
        static get observedAttributes() { return ['class', 'id']; }
    }
    contentWindow.customElements.define('test-element', TestElement);
    assert_equals(Object.getPrototypeOf(undefinedElement), TestElement.prototype);

    assert_equals(log.length, 1);
    assert_constructor_log_entry(log[0], undefinedElement);
}, 'Upgrading a custom element must not invoke attributeChangedCallback and connectedCallback when the element failed to upgrade');

</script>
</body>
</html>
