<!doctype html>
<meta charset="utf8">
<meta name="timeout" content="long">
<title>Events must dispatch on disabled elements</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<style>
  @keyframes fade {
    0% {
      opacity: 1;
    }
    100% {
      opacity: 0;
    }
  }
</style>
<body>
<script>
// HTML elements that can be disabled
const formElements = ["button", "fieldset", "input", "select", "textarea"];

test(() => {
  for (const localName of formElements) {
    const elem = document.createElement(localName);
    elem.disabled = true;
    // pass becomes true if the event is called and it's the right type.
    let pass = false;
    const listener = ({ type }) => {
      pass = type === "click";
    };
    elem.addEventListener("click", listener, { once: true });
    elem.dispatchEvent(new Event("click"));
    assert_true(
      pass,
      `Untrusted "click" Event didn't dispatch on ${elem.constructor.name}.`
    );
  }
}, "Can dispatch untrusted 'click' Events at disabled HTML elements.");

test(() => {
  for (const localName of formElements) {
    const elem = document.createElement(localName);
    elem.disabled = true;
    // pass becomes true if the event is called and it's the right type.
    let pass = false;
    const listener = ({ type }) => {
      pass = type === "pass";
    };
    elem.addEventListener("pass", listener, { once: true });
    elem.dispatchEvent(new Event("pass"));
    assert_true(
      pass,
      `Untrusted "pass" Event didn't dispatch on ${elem.constructor.name}`
    );
  }
}, "Can dispatch untrusted Events at disabled HTML elements.");

test(() => {
  for (const localName of formElements) {
    const elem = document.createElement(localName);
    elem.disabled = true;
    // pass becomes true if the event is called and it's the right type.
    let pass = false;
    const listener = ({ type }) => {
      pass = type === "custom-pass";
    };
    elem.addEventListener("custom-pass", listener, { once: true });
    elem.dispatchEvent(new CustomEvent("custom-pass"));
    assert_true(
      pass,
      `CustomEvent "custom-pass" didn't dispatch on ${elem.constructor.name}`
    );
  }
}, "Can dispatch CustomEvents at disabled HTML elements.");

test(() => {
  for (const localName of formElements) {
    const elem = document.createElement(localName);

    // Element is disabled... so this click() MUST NOT fire an event.
    elem.disabled = true;
    let pass = true;
    elem.onclick = e => {
      pass = false;
    };
    elem.click();
    assert_true(
      pass,
      `.click() must not dispatch "click" event on disabled ${
        elem.constructor.name
      }.`
    );

    // Element is (re)enabled... so this click() fires an event.
    elem.disabled = false;
    pass = false;
    elem.onclick = e => {
      pass = true;
    };
    elem.click();
    assert_true(
      pass,
      `.click() must dispatch "click" event on enabled ${
        elem.constructor.name
      }.`
    );
  }
}, "Calling click() on disabled elements must not dispatch events.");

promise_test(async () => {
  // For each form element type, set up transition event handlers.
  for (const localName of formElements) {
    const elem = document.createElement(localName);
    elem.disabled = true;
    document.body.appendChild(elem);
    const eventPromises = [
      "transitionrun",
      "transitionstart",
      "transitionend",
    ].map(eventType => {
      return new Promise(r => {
        elem.addEventListener(eventType, r);
      });
    });
    // Flushing style triggers transition.
    getComputedStyle(elem).opacity;
    elem.style.transition = "opacity .1s";
    elem.style.opacity = 0;
    getComputedStyle(elem).opacity;
    // All the events fire...
    await Promise.all(eventPromises);
    elem.remove();
  }
}, "CSS Transitions transitionrun, transitionstart, transitionend events fire on disabled form elements");

promise_test(async () => {
  // For each form element type, set up transition event handlers.
  for (const localName of formElements) {
    const elem = document.createElement(localName);
    elem.disabled = true;
    document.body.appendChild(elem);
    getComputedStyle(elem).opacity;
    elem.style.transition = "opacity 100s";
    // We use ontransitionstart to cancel the event.
    elem.ontransitionstart = () => {
      elem.style.display = "none";
    };
    const promiseToCancel = new Promise(r => {
      elem.ontransitioncancel = r;
    });
    // Flushing style triggers the transition.
    elem.style.opacity = 0;
    getComputedStyle(elem).opacity;
    await promiseToCancel;
    // And we are done with this element.
    elem.remove();
  }
}, "CSS Transitions transitioncancel event fires on disabled form elements");

promise_test(async () => {
  // For each form element type, set up transition event handlers.
  for (const localName of formElements) {
    const elem = document.createElement(localName);
    document.body.appendChild(elem);
    elem.disabled = true;
    const animationStartPromise = new Promise(r => {
      elem.addEventListener("animationstart", () => {
        // Seek to the second iteration to trigger the animationiteration event
        elem.style.animationDelay = "-100s"
        r();
      });
    });
    const animationIterationPromise = new Promise(r => {
      elem.addEventListener("animationiteration", ()=>{
        elem.style.animationDelay = "-200s"
        r();
      });
    });
    const animationEndPromise = new Promise(r => {
      elem.addEventListener("animationend", r);
    });
    elem.style.animation = "fade 100s 2";
    elem.classList.add("animate");
    // All the events fire...
    await Promise.all([
      animationStartPromise,
      animationIterationPromise,
      animationEndPromise,
    ]);
    elem.remove();
  }
}, "CSS Animation animationstart, animationiteration, animationend fire on disabled form elements");

promise_test(async () => {
  // For each form element type, set up transition event handlers.
  for (const localName of formElements) {
    const elem = document.createElement(localName);
    document.body.appendChild(elem);
    elem.disabled = true;

    const promiseToCancel = new Promise(r => {
      elem.addEventListener("animationcancel", r);
    });

    elem.addEventListener("animationstart", () => {
      // Cancel the animation by hiding it.
      elem.style.display = "none";
    });

    // Trigger the animation
    elem.style.animation = "fade 100s";
    elem.classList.add("animate");
    await promiseToCancel;
    // And we are done with this element.
    elem.remove();
  }
}, "CSS Animation's animationcancel event fires on disabled form elements");

promise_test(async () => {
  for (const localName of formElements) {
    const elem = document.createElement(localName);
    elem.disabled = true;
    document.body.appendChild(elem);
    // Element is disabled, so clicking must not fire events
    let pass = true;
    elem.onclick = e => {
      pass = false;
    };
    // Disabled elements are not clickable.
    await test_driver.click(elem);
    assert_true(
      pass,
      `${elem.constructor.name} is disabled, so onclick must not fire.`
    );
    // Element is (re)enabled... so this click() will fire an event.
    pass = false;
    elem.disabled = false;
    elem.onclick = () => {
      pass = true;
    };
    await test_driver.click(elem);
    assert_true(
      pass,
      `${elem.constructor.name} is enabled, so onclick must fire.`
    );
    elem.remove();
  }
}, "Real clicks on disabled elements must not dispatch events.");
</script>
