11cb0ef41Sopenharmony_ci// https://dom.spec.whatwg.org/#concept-event-dispatch
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst host = document.createElement("div"),
41cb0ef41Sopenharmony_ci      child = host.appendChild(document.createElement("p")),
51cb0ef41Sopenharmony_ci      shadow = host.attachShadow({ mode: "closed" }),
61cb0ef41Sopenharmony_ci      slot = shadow.appendChild(document.createElement("slot"));
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_citest(() => {
91cb0ef41Sopenharmony_ci  for (target of [shadow, slot]) {
101cb0ef41Sopenharmony_ci    for (relatedTarget of [new XMLHttpRequest(), self, host]) {
111cb0ef41Sopenharmony_ci      const event = new FocusEvent("demo", { relatedTarget: relatedTarget });
121cb0ef41Sopenharmony_ci      target.dispatchEvent(event);
131cb0ef41Sopenharmony_ci      assert_equals(event.target, null);
141cb0ef41Sopenharmony_ci      assert_equals(event.relatedTarget, null);
151cb0ef41Sopenharmony_ci    }
161cb0ef41Sopenharmony_ci  }
171cb0ef41Sopenharmony_ci}, "Reset if target pointed to a shadow tree");
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_citest(() => {
201cb0ef41Sopenharmony_ci  for (relatedTarget of [shadow, slot]) {
211cb0ef41Sopenharmony_ci    for (target of [new XMLHttpRequest(), self, host]) {
221cb0ef41Sopenharmony_ci      const event = new FocusEvent("demo", { relatedTarget: relatedTarget });
231cb0ef41Sopenharmony_ci      target.dispatchEvent(event);
241cb0ef41Sopenharmony_ci      assert_equals(event.target, target);
251cb0ef41Sopenharmony_ci      assert_equals(event.relatedTarget, host);
261cb0ef41Sopenharmony_ci    }
271cb0ef41Sopenharmony_ci  }
281cb0ef41Sopenharmony_ci}, "Retarget a shadow-tree relatedTarget");
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_citest(t => {
311cb0ef41Sopenharmony_ci  const shadowChild = shadow.appendChild(document.createElement("div"));
321cb0ef41Sopenharmony_ci  shadowChild.addEventListener("demo", t.step_func(() => document.body.appendChild(shadowChild)));
331cb0ef41Sopenharmony_ci  const event = new FocusEvent("demo", { relatedTarget: new XMLHttpRequest() });
341cb0ef41Sopenharmony_ci  shadowChild.dispatchEvent(event);
351cb0ef41Sopenharmony_ci  assert_equals(shadowChild.parentNode, document.body);
361cb0ef41Sopenharmony_ci  assert_equals(event.target, null);
371cb0ef41Sopenharmony_ci  assert_equals(event.relatedTarget, null);
381cb0ef41Sopenharmony_ci  shadowChild.remove();
391cb0ef41Sopenharmony_ci}, "Reset if target pointed to a shadow tree pre-dispatch");
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_citest(t => {
421cb0ef41Sopenharmony_ci  const shadowChild = shadow.appendChild(document.createElement("div"));
431cb0ef41Sopenharmony_ci  document.body.addEventListener("demo", t.step_func(() => document.body.appendChild(shadowChild)));
441cb0ef41Sopenharmony_ci  const event = new FocusEvent("demo", { relatedTarget: shadowChild });
451cb0ef41Sopenharmony_ci  document.body.dispatchEvent(event);
461cb0ef41Sopenharmony_ci  assert_equals(shadowChild.parentNode, document.body);
471cb0ef41Sopenharmony_ci  assert_equals(event.target, document.body);
481cb0ef41Sopenharmony_ci  assert_equals(event.relatedTarget, host);
491cb0ef41Sopenharmony_ci  shadowChild.remove();
501cb0ef41Sopenharmony_ci}, "Retarget a shadow-tree relatedTarget, part 2");
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_citest(t => {
531cb0ef41Sopenharmony_ci  const event = new FocusEvent("heya", { relatedTarget: shadow, cancelable: true }),
541cb0ef41Sopenharmony_ci        callback = t.unreached_func();
551cb0ef41Sopenharmony_ci  host.addEventListener("heya", callback);
561cb0ef41Sopenharmony_ci  t.add_cleanup(() => host.removeEventListener("heya", callback));
571cb0ef41Sopenharmony_ci  event.preventDefault();
581cb0ef41Sopenharmony_ci  assert_true(event.defaultPrevented);
591cb0ef41Sopenharmony_ci  assert_false(host.dispatchEvent(event));
601cb0ef41Sopenharmony_ci  assert_equals(event.target, null);
611cb0ef41Sopenharmony_ci  assert_equals(event.relatedTarget, null);
621cb0ef41Sopenharmony_ci  // Check that the dispatch flag is cleared
631cb0ef41Sopenharmony_ci  event.initEvent("x");
641cb0ef41Sopenharmony_ci  assert_equals(event.type, "x");
651cb0ef41Sopenharmony_ci}, "Reset targets on early return");
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_citest(t => {
681cb0ef41Sopenharmony_ci  const input = document.body.appendChild(document.createElement("input")),
691cb0ef41Sopenharmony_ci        event = new MouseEvent("click", { relatedTarget: shadow });
701cb0ef41Sopenharmony_ci  let seen = false;
711cb0ef41Sopenharmony_ci  t.add_cleanup(() => input.remove());
721cb0ef41Sopenharmony_ci  input.type = "checkbox";
731cb0ef41Sopenharmony_ci  input.oninput = t.step_func(() => {
741cb0ef41Sopenharmony_ci    assert_equals(event.target, null);
751cb0ef41Sopenharmony_ci    assert_equals(event.relatedTarget, null);
761cb0ef41Sopenharmony_ci    assert_equals(event.composedPath().length, 0);
771cb0ef41Sopenharmony_ci    seen = true;
781cb0ef41Sopenharmony_ci  });
791cb0ef41Sopenharmony_ci  assert_true(input.dispatchEvent(event));
801cb0ef41Sopenharmony_ci  assert_true(seen);
811cb0ef41Sopenharmony_ci}, "Reset targets before activation behavior");
82