<!DOCTYPE html>
<html>
<head>
<title>Custom Elements: Each element must have its own custom element reaction queue</title>
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
<meta name="assert" content="Each element must have its own custom element reaction queue">
<meta name="help" content="https://html.spec.whatwg.org/multipage/scripting.html#custom-element-reaction-queue">
<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>

test_with_window(function (contentWindow) {
    const contentDocument = contentWindow.document;
    contentDocument.write('<test-element id="first-element">');
    contentDocument.write('<test-element id="second-element">');

    const element1 = contentDocument.getElementById('first-element');
    const element2 = contentDocument.getElementById('second-element');
    assert_equals(Object.getPrototypeOf(element1), contentWindow.HTMLElement.prototype);
    assert_equals(Object.getPrototypeOf(element2), 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 ['id']; }
    }
    contentWindow.customElements.define('test-element', TestElement);
    assert_equals(Object.getPrototypeOf(element1), TestElement.prototype);
    assert_equals(Object.getPrototypeOf(element2), TestElement.prototype);

    assert_equals(log.length, 6);
    assert_constructor_log_entry(log[0], element1);
    assert_attribute_log_entry(log[1], {name: 'id', oldValue: null, newValue: 'first-element', namespace: null});
    assert_connected_log_entry(log[2], element1);
    assert_constructor_log_entry(log[3], element2);
    assert_attribute_log_entry(log[4], {name: 'id', oldValue: null, newValue: 'second-element', namespace: null});
    assert_connected_log_entry(log[5], element2);
}, 'Upgrading a custom element must invoke attributeChangedCallback and connectedCallback before start upgrading another element');

test_with_window(function (contentWindow) {
    const contentDocument = contentWindow.document;
    contentDocument.write('<test-element id="first-element">');
    contentDocument.write('<test-element id="second-element">');

    const element1 = contentDocument.getElementById('first-element');
    const element2 = contentDocument.getElementById('second-element');
    assert_equals(Object.getPrototypeOf(element1), contentWindow.HTMLElement.prototype);
    assert_equals(Object.getPrototypeOf(element2), contentWindow.HTMLElement.prototype);

    let log = [];
    class TestElement extends contentWindow.HTMLElement {
        constructor() {
            super();
            log.push(create_constructor_log(this));
            if (this == element1) {
                element2.setAttribute('title', 'hi');
                element2.removeAttribute('title');
                element2.setAttribute('class', 'foo');
            }
        }
        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 ['id', 'class', 'title']; }
    }
    contentWindow.customElements.define('test-element', TestElement);
    assert_equals(Object.getPrototypeOf(element1), TestElement.prototype);
    assert_equals(Object.getPrototypeOf(element2), TestElement.prototype);

    assert_equals(log.length, 7);
    assert_constructor_log_entry(log[0], element1);
    assert_attribute_log_entry(log[1], {name: 'id', oldValue: null, newValue: 'first-element', namespace: null});
    assert_connected_log_entry(log[2], element1);
    assert_constructor_log_entry(log[3], element2);
    assert_attribute_log_entry(log[4], {name: 'id', oldValue: null, newValue: 'second-element', namespace: null});
    assert_attribute_log_entry(log[5], {name: 'class', oldValue: null, newValue: 'foo', namespace: null});
    assert_connected_log_entry(log[6], element2);
}, 'Mutating a undefined custom element while upgrading a custom element must not enqueue or invoke reactions on the mutated element');

test_with_window(function (contentWindow) {
    let log = [];
    let element1;
    let element2;
    class TestElement extends contentWindow.HTMLElement {
        constructor() {
            super();
            log.push(create_constructor_log(this));
        }
        adoptedCallback(...args) {
            log.push(create_adopted_callback_log(this, ...args));
            if (this == element1)
                element3.setAttribute('id', 'foo');
        }
        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 ['id', 'class']; }
    }

    contentWindow.customElements.define('test-element', TestElement);

    let contentDocument = contentWindow.document;
    element1 = contentDocument.createElement('test-element');
    element2 = contentDocument.createElement('test-element');
    element3 = contentDocument.createElement('test-element');
    assert_equals(Object.getPrototypeOf(element1), TestElement.prototype);
    assert_equals(Object.getPrototypeOf(element2), TestElement.prototype);
    assert_equals(Object.getPrototypeOf(element3), TestElement.prototype);

    assert_equals(log.length, 3);
    assert_constructor_log_entry(log[0], element1);
    assert_constructor_log_entry(log[1], element2);
    assert_constructor_log_entry(log[2], element3);
    log = [];

    const container = contentDocument.createElement('div');
    container.appendChild(element1);
    container.appendChild(element2);
    container.appendChild(element3);

    const anotherDocument = document.implementation.createHTMLDocument();
    anotherDocument.documentElement.appendChild(container);

    assert_equals(log.length, 7);
    assert_adopted_log_entry(log[0], element1);
    assert_adopted_log_entry(log[1], element3);
    assert_connected_log_entry(log[2], element3);
    assert_attribute_log_entry(log[3], {name: 'id', oldValue: null, newValue: 'foo', namespace: null});
    assert_connected_log_entry(log[4], element1);
    assert_adopted_log_entry(log[5], element2);
    assert_connected_log_entry(log[6], element2);

}, 'Mutating another custom element inside adopted callback must invoke all pending callbacks on the mutated element');


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