• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!doctype html>
2<title>Synthetic click event "magic"</title>
3<script src="/resources/testharness.js"></script>
4<script src="/resources/testharnessreport.js"></script>
5<div id=log></div>
6<div id=dump style=display:none></div>
7<script>
8var dump = document.getElementById("dump")
9
10async_test(function(t) {
11  var input = document.createElement("input")
12  input.type = "checkbox"
13  dump.appendChild(input)
14  input.onclick = t.step_func_done(function() {
15    assert_true(input.checked)
16  })
17  input.click()
18}, "basic with click()")
19
20async_test(function(t) {
21  var input = document.createElement("input")
22  input.type = "checkbox"
23  dump.appendChild(input)
24  input.onclick = t.step_func_done(function() {
25    assert_true(input.checked)
26  })
27  input.dispatchEvent(new MouseEvent("click", {bubbles:true})) // equivalent to the above
28}, "basic with dispatchEvent()")
29
30async_test(function(t) {
31  var input = document.createElement("input")
32  input.type = "checkbox"
33  dump.appendChild(input)
34  input.onclick = t.step_func_done(function() {
35    assert_false(input.checked)
36  })
37  input.dispatchEvent(new Event("click", {bubbles:true})) // no MouseEvent
38}, "basic with wrong event class")
39
40async_test(function(t) {
41  var input = document.createElement("input")
42  input.type = "checkbox"
43  dump.appendChild(input)
44  var child = input.appendChild(new Text("does not matter"))
45  child.dispatchEvent(new MouseEvent("click")) // does not bubble
46  assert_false(input.checked)
47  t.done()
48}, "look at parents only when event bubbles")
49
50async_test(function(t) {
51  var input = document.createElement("input")
52  input.type = "checkbox"
53  dump.appendChild(input)
54  input.onclick = t.step_func_done(function() {
55    assert_true(input.checked)
56  })
57  var child = input.appendChild(new Text("does not matter"))
58  child.dispatchEvent(new MouseEvent("click", {bubbles:true}))
59}, "look at parents when event bubbles")
60
61async_test(function(t) {
62  var input = document.createElement("input")
63  input.type = "checkbox"
64  dump.appendChild(input)
65  input.onclick = t.step_func(function() {
66    assert_false(input.checked, "input pre-click must not be triggered")
67  })
68  var child = input.appendChild(document.createElement("input"))
69  child.type = "checkbox"
70  child.onclick = t.step_func(function() {
71    assert_true(child.checked, "child pre-click must be triggered")
72  })
73  child.dispatchEvent(new MouseEvent("click", {bubbles:true}))
74  t.done()
75}, "pick the first with activation behavior <input type=checkbox>")
76
77async_test(function(t) { // as above with <a>
78  window.hrefComplete = t.step_func(function(a) {
79    assert_equals(a, 'child');
80    t.done();
81  });
82  var link = document.createElement("a")
83  link.href = "javascript:hrefComplete('link')" // must not be triggered
84  dump.appendChild(link)
85  var child = link.appendChild(document.createElement("a"))
86  child.href = "javascript:hrefComplete('child')"
87  child.dispatchEvent(new MouseEvent("click", {bubbles:true}))
88}, "pick the first with activation behavior <a href>")
89
90async_test(function(t) {
91  var input = document.createElement("input")
92  input.type = "checkbox"
93  dump.appendChild(input)
94  var clickEvent = new MouseEvent("click")
95  input.onchange = t.step_func_done(function() {
96    assert_false(clickEvent.defaultPrevented)
97    assert_true(clickEvent.returnValue)
98    assert_equals(clickEvent.eventPhase, 0)
99    assert_equals(clickEvent.currentTarget, null)
100    assert_equals(clickEvent.target, input)
101    assert_equals(clickEvent.srcElement, input)
102    assert_equals(clickEvent.composedPath().length, 0)
103  })
104  input.dispatchEvent(clickEvent)
105}, "event state during post-click handling")
106
107async_test(function(t) {
108  var input = document.createElement("input")
109  input.type = "checkbox"
110  dump.appendChild(input)
111  var clickEvent = new MouseEvent("click")
112  var finalTarget = document.createElement("doesnotmatter")
113  finalTarget.onclick = t.step_func_done(function() {
114    assert_equals(clickEvent.target, finalTarget)
115    assert_equals(clickEvent.srcElement, finalTarget)
116  })
117  input.onchange = t.step_func(function() {
118    finalTarget.dispatchEvent(clickEvent)
119  })
120  input.dispatchEvent(clickEvent)
121}, "redispatch during post-click handling")
122
123async_test(function(t) {
124  var input = document.createElement("input")
125  input.type = "checkbox"
126  dump.appendChild(input)
127  var child = input.appendChild(document.createElement("input"))
128  child.type = "checkbox"
129  child.disabled = true
130  child.click()
131  assert_false(input.checked)
132  assert_false(child.checked)
133  t.done()
134}, "disabled checkbox still has activation behavior")
135
136async_test(function(t) {
137  var state = "start"
138
139  var form = document.createElement("form")
140  form.onsubmit = t.step_func(() => {
141    if(state == "start" || state == "checkbox") {
142      state = "failure"
143    } else if(state == "form") {
144      state = "done"
145    }
146    return false
147  })
148  dump.appendChild(form)
149  var button = form.appendChild(document.createElement("button"))
150  button.type = "submit"
151  var checkbox = button.appendChild(document.createElement("input"))
152  checkbox.type = "checkbox"
153  checkbox.onclick = t.step_func(() => {
154    if(state == "start") {
155      assert_unreached()
156    } else if(state == "checkbox") {
157      assert_true(checkbox.checked)
158    }
159  })
160  checkbox.disabled = true
161  checkbox.click()
162  assert_equals(state, "start")
163
164  state = "checkbox"
165  checkbox.disabled = false
166  checkbox.click()
167  assert_equals(state, "checkbox")
168
169  state = "form"
170  button.click()
171  assert_equals(state, "done")
172
173  t.done()
174}, "disabled checkbox still has activation behavior, part 2")
175
176async_test(function(t) {
177  var input = document.createElement("input")
178  input.type = "checkbox"
179  input.onclick = t.step_func_done(function() {
180    assert_true(input.checked)
181  })
182  input.click()
183}, "disconnected checkbox should be checked")
184
185async_test(function(t) {
186  var input = document.createElement("input")
187  input.type = "radio"
188  input.onclick = t.step_func_done(function() {
189    assert_true(input.checked)
190  })
191  input.click()
192}, "disconnected radio should be checked")
193
194async_test(t => {
195  const input = document.createElement('input');
196  input.type = 'checkbox';
197  input.onclick = t.step_func_done(() => {
198    assert_true(input.checked);
199  });
200  input.dispatchEvent(new MouseEvent('click'));
201}, `disconnected checkbox should be checked from dispatchEvent(new MouseEvent('click'))`);
202
203async_test(t => {
204  const input = document.createElement('input');
205  input.type = 'radio';
206  input.onclick = t.step_func_done(() => {
207    assert_true(input.checked);
208  });
209  input.dispatchEvent(new MouseEvent('click'));
210}, `disconnected radio should be checked from dispatchEvent(new MouseEvent('click'))`);
211
212test(() => {
213  const input = document.createElement("input");
214  input.type = "checkbox";
215  input.disabled = true;
216  input.dispatchEvent(new MouseEvent("click"));
217  assert_true(input.checked);
218}, `disabled checkbox should be checked from dispatchEvent(new MouseEvent("click"))`);
219
220test(() => {
221  const input = document.createElement("input");
222  input.type = "radio";
223  input.disabled = true;
224  input.dispatchEvent(new MouseEvent("click"));
225  assert_true(input.checked);
226}, `disabled radio should be checked from dispatchEvent(new MouseEvent("click"))`);
227
228async_test(t => {
229  const input = document.createElement("input");
230  input.type = "checkbox";
231  input.disabled = true;
232  input.onclick = t.step_func_done();
233  input.dispatchEvent(new MouseEvent("click"));
234}, `disabled checkbox should fire onclick`);
235
236async_test(t => {
237  const input = document.createElement("input");
238  input.type = "radio";
239  input.disabled = true;
240  input.onclick = t.step_func_done();
241  input.dispatchEvent(new MouseEvent("click"));
242}, `disabled radio should fire onclick`);
243
244async_test(t => {
245  const input = document.createElement("input");
246  input.type = "checkbox";
247  input.disabled = true;
248  input.onclick = t.step_func(ev => {
249    assert_true(input.checked);
250    ev.preventDefault();
251    queueMicrotask(t.step_func_done(() => {
252      assert_false(input.checked);
253    }));
254  });
255  input.dispatchEvent(new MouseEvent("click", { cancelable: true }));
256}, `disabled checkbox should get legacy-canceled-activation behavior`);
257
258async_test(t => {
259  const input = document.createElement("input");
260  input.type = "radio";
261  input.disabled = true;
262  input.onclick = t.step_func(ev => {
263    assert_true(input.checked);
264    ev.preventDefault();
265    queueMicrotask(t.step_func_done(() => {
266      assert_false(input.checked);
267    }));
268  });
269  input.dispatchEvent(new MouseEvent("click", { cancelable: true }));
270}, `disabled radio should get legacy-canceled-activation behavior`);
271
272test(t => {
273  const input = document.createElement("input");
274  input.type = "checkbox";
275  input.disabled = true;
276  const ev = new MouseEvent("click", { cancelable: true });
277  ev.preventDefault();
278  input.dispatchEvent(ev);
279  assert_false(input.checked);
280}, `disabled checkbox should get legacy-canceled-activation behavior 2`);
281
282test(t => {
283  const input = document.createElement("input");
284  input.type = "radio";
285  input.disabled = true;
286  const ev = new MouseEvent("click", { cancelable: true });
287  ev.preventDefault();
288  input.dispatchEvent(ev);
289  assert_false(input.checked);
290}, `disabled radio should get legacy-canceled-activation behavior 2`);
291
292for (const type of ["checkbox", "radio"]) {
293  for (const handler of ["oninput", "onchange"]) {
294    async_test(t => {
295      const input = document.createElement("input");
296      input.type = type;
297      input.onclick = t.step_func(ev => {
298        input.disabled = true;
299      });
300      input[handler] = t.step_func(ev => {
301        assert_equals(input.checked, true);
302        t.done();
303      });
304      dump.append(input);
305      input.click();
306    }, `disabling ${type} in onclick listener shouldn't suppress ${handler}`);
307  }
308}
309
310async_test(function(t) {
311  var form = document.createElement("form")
312  var didSubmit = false
313  form.onsubmit = t.step_func(() => {
314    didSubmit = true
315    return false
316  })
317  var input = form.appendChild(document.createElement("input"))
318  input.type = "submit"
319  input.click()
320  assert_false(didSubmit)
321  t.done()
322}, "disconnected form should not submit")
323
324async_test(t => {
325  const form = document.createElement("form");
326  form.onsubmit = t.step_func(ev => {
327    ev.preventDefault();
328    assert_unreached("The form is unexpectedly submitted.");
329  });
330  dump.append(form);
331  const input = form.appendChild(document.createElement("input"));
332  input.type = "submit"
333  input.disabled = true;
334  input.dispatchEvent(new MouseEvent("click", { cancelable: true }));
335  t.done();
336}, "disabled submit button should not activate");
337
338async_test(t => {
339  const form = document.createElement("form");
340  form.onsubmit = t.step_func(ev => {
341    ev.preventDefault();
342    assert_unreached("The form is unexpectedly submitted.");
343  });
344  dump.append(form);
345  const input = form.appendChild(document.createElement("input"));
346  input.onclick = t.step_func(() => {
347    input.disabled = true;
348  });
349  input.type = "submit"
350  input.dispatchEvent(new MouseEvent("click", { cancelable: true }));
351  t.done();
352}, "submit button should not activate if the event listener disables it");
353
354async_test(t => {
355  const form = document.createElement("form");
356  form.onsubmit = t.step_func(ev => {
357    ev.preventDefault();
358    assert_unreached("The form is unexpectedly submitted.");
359  });
360  dump.append(form);
361  const input = form.appendChild(document.createElement("input"));
362  input.onclick = t.step_func(() => {
363    input.type = "submit"
364    input.disabled = true;
365  });
366  input.click();
367  t.done();
368}, "submit button that morphed from checkbox should not activate");
369</script>
370