tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Event-dispatch-click.html (13174B)


      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>
      8 var dump = document.getElementById("dump")
      9 
     10 async_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 
     20 async_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 
     30 async_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 
     40 async_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 
     50 async_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 
     61 async_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 
     77 async_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 
     90 async_test(function(t) {
     91  var input = document.createElement("input")
     92  input.type = "radio"
     93  dump.appendChild(input)
     94  input.onclick = t.step_func(function() {
     95    assert_false(input.checked, "input pre-click must not be triggered")
     96  })
     97  var child = input.appendChild(document.createElement("input"))
     98  child.type = "radio"
     99  child.onclick = t.step_func(function() {
    100    assert_true(child.checked, "child pre-click must be triggered")
    101  })
    102  child.dispatchEvent(new MouseEvent("click", {bubbles:true}))
    103  t.done()
    104 }, "pick the first with activation behavior <input type=radio>")
    105 
    106 async_test(function(t) {
    107  var input = document.createElement("input")
    108  input.type = "checkbox"
    109  dump.appendChild(input)
    110  var clickEvent = new MouseEvent("click")
    111  input.onchange = t.step_func_done(function() {
    112    assert_false(clickEvent.defaultPrevented)
    113    assert_true(clickEvent.returnValue)
    114    assert_equals(clickEvent.eventPhase, 0)
    115    assert_equals(clickEvent.currentTarget, null)
    116    assert_equals(clickEvent.target, input)
    117    assert_equals(clickEvent.srcElement, input)
    118    assert_equals(clickEvent.composedPath().length, 0)
    119  })
    120  input.dispatchEvent(clickEvent)
    121 }, "event state during post-click handling")
    122 
    123 async_test(function(t) {
    124  var input = document.createElement("input")
    125  input.type = "checkbox"
    126  dump.appendChild(input)
    127  var clickEvent = new MouseEvent("click")
    128  var finalTarget = document.createElement("doesnotmatter")
    129  finalTarget.onclick = t.step_func_done(function() {
    130    assert_equals(clickEvent.target, finalTarget)
    131    assert_equals(clickEvent.srcElement, finalTarget)
    132  })
    133  input.onchange = t.step_func(function() {
    134    finalTarget.dispatchEvent(clickEvent)
    135  })
    136  input.dispatchEvent(clickEvent)
    137 }, "redispatch during post-click handling")
    138 
    139 async_test(function(t) {
    140  var input = document.createElement("input")
    141  input.type = "checkbox"
    142  dump.appendChild(input)
    143  var child = input.appendChild(document.createElement("input"))
    144  child.type = "checkbox"
    145  child.disabled = true
    146  child.click()
    147  assert_false(input.checked)
    148  assert_false(child.checked)
    149  t.done()
    150 }, "disabled checkbox still has activation behavior")
    151 
    152 async_test(function(t) {
    153  var state = "start"
    154 
    155  var form = document.createElement("form")
    156  form.onsubmit = t.step_func(() => {
    157    if(state == "start" || state == "checkbox") {
    158      state = "failure"
    159    } else if(state == "form") {
    160      state = "done"
    161    }
    162    return false
    163  })
    164  dump.appendChild(form)
    165  var button = form.appendChild(document.createElement("button"))
    166  button.type = "submit"
    167  var checkbox = button.appendChild(document.createElement("input"))
    168  checkbox.type = "checkbox"
    169  checkbox.onclick = t.step_func(() => {
    170    if(state == "start") {
    171      assert_unreached()
    172    } else if(state == "checkbox") {
    173      assert_true(checkbox.checked)
    174    }
    175  })
    176  checkbox.disabled = true
    177  checkbox.click()
    178  assert_equals(state, "start")
    179 
    180  state = "checkbox"
    181  checkbox.disabled = false
    182  checkbox.click()
    183  assert_equals(state, "checkbox")
    184 
    185  state = "form"
    186  button.click()
    187  assert_equals(state, "done")
    188 
    189  t.done()
    190 }, "disabled checkbox still has activation behavior, part 2")
    191 
    192 async_test(function(t) {
    193  var state = "start"
    194 
    195  var form = document.createElement("form")
    196  form.onsubmit = t.step_func(() => {
    197    if(state == "start" || state == "radio") {
    198      state = "failure"
    199    } else if(state == "form") {
    200      state = "done"
    201    }
    202    return false
    203  })
    204  dump.appendChild(form)
    205  var button = form.appendChild(document.createElement("button"))
    206  button.type = "submit"
    207  var radio = button.appendChild(document.createElement("input"))
    208  radio.type = "radio"
    209  radio.onclick = t.step_func(() => {
    210    if(state == "start") {
    211      assert_unreached()
    212    } else if(state == "radio") {
    213      assert_true(radio.checked)
    214    }
    215  })
    216  radio.disabled = true
    217  radio.click()
    218  assert_equals(state, "start")
    219 
    220  state = "radio"
    221  radio.disabled = false
    222  radio.click()
    223  assert_equals(state, "radio")
    224 
    225  state = "form"
    226  button.click()
    227  assert_equals(state, "done")
    228 
    229  t.done()
    230 }, "disabled radio still has activation behavior")
    231 
    232 async_test(function(t) {
    233  var input = document.createElement("input")
    234  input.type = "checkbox"
    235  input.onclick = t.step_func_done(function() {
    236    assert_true(input.checked)
    237  })
    238  input.click()
    239 }, "disconnected checkbox should be checked")
    240 
    241 async_test(function(t) {
    242  var input = document.createElement("input")
    243  input.type = "radio"
    244  input.onclick = t.step_func_done(function() {
    245    assert_true(input.checked)
    246  })
    247  input.click()
    248 }, "disconnected radio should be checked")
    249 
    250 async_test(t => {
    251  const input = document.createElement('input');
    252  input.type = 'checkbox';
    253  input.onclick = t.step_func_done(() => {
    254    assert_true(input.checked);
    255  });
    256  input.dispatchEvent(new MouseEvent('click'));
    257 }, `disconnected checkbox should be checked from dispatchEvent(new MouseEvent('click'))`);
    258 
    259 async_test(t => {
    260  const input = document.createElement('input');
    261  input.type = 'radio';
    262  input.onclick = t.step_func_done(() => {
    263    assert_true(input.checked);
    264  });
    265  input.dispatchEvent(new MouseEvent('click'));
    266 }, `disconnected radio should be checked from dispatchEvent(new MouseEvent('click'))`);
    267 
    268 test(() => {
    269  const input = document.createElement("input");
    270  input.type = "checkbox";
    271  input.disabled = true;
    272  input.dispatchEvent(new MouseEvent("click"));
    273  assert_true(input.checked);
    274 }, `disabled checkbox should be checked from dispatchEvent(new MouseEvent("click"))`);
    275 
    276 test(() => {
    277  const input = document.createElement("input");
    278  input.type = "radio";
    279  input.disabled = true;
    280  input.dispatchEvent(new MouseEvent("click"));
    281  assert_true(input.checked);
    282 }, `disabled radio should be checked from dispatchEvent(new MouseEvent("click"))`);
    283 
    284 async_test(t => {
    285  const input = document.createElement("input");
    286  input.type = "checkbox";
    287  input.disabled = true;
    288  input.onclick = t.step_func_done();
    289  input.dispatchEvent(new MouseEvent("click"));
    290 }, `disabled checkbox should fire onclick`);
    291 
    292 async_test(t => {
    293  const input = document.createElement("input");
    294  input.type = "radio";
    295  input.disabled = true;
    296  input.onclick = t.step_func_done();
    297  input.dispatchEvent(new MouseEvent("click"));
    298 }, `disabled radio should fire onclick`);
    299 
    300 async_test(t => {
    301  const input = document.createElement("input");
    302  input.type = "checkbox";
    303  input.disabled = true;
    304  input.onclick = t.step_func(ev => {
    305    assert_true(input.checked);
    306    ev.preventDefault();
    307    queueMicrotask(t.step_func_done(() => {
    308      assert_false(input.checked);
    309    }));
    310  });
    311  input.dispatchEvent(new MouseEvent("click", { cancelable: true }));
    312 }, `disabled checkbox should get legacy-canceled-activation behavior`);
    313 
    314 async_test(t => {
    315  const input = document.createElement("input");
    316  input.type = "radio";
    317  input.disabled = true;
    318  input.onclick = t.step_func(ev => {
    319    assert_true(input.checked);
    320    ev.preventDefault();
    321    queueMicrotask(t.step_func_done(() => {
    322      assert_false(input.checked);
    323    }));
    324  });
    325  input.dispatchEvent(new MouseEvent("click", { cancelable: true }));
    326 }, `disabled radio should get legacy-canceled-activation behavior`);
    327 
    328 test(t => {
    329  const input = document.createElement("input");
    330  input.type = "checkbox";
    331  input.disabled = true;
    332  const ev = new MouseEvent("click", { cancelable: true });
    333  ev.preventDefault();
    334  input.dispatchEvent(ev);
    335  assert_false(input.checked);
    336 }, `disabled checkbox should get legacy-canceled-activation behavior 2`);
    337 
    338 test(t => {
    339  const input = document.createElement("input");
    340  input.type = "radio";
    341  input.disabled = true;
    342  const ev = new MouseEvent("click", { cancelable: true });
    343  ev.preventDefault();
    344  input.dispatchEvent(ev);
    345  assert_false(input.checked);
    346 }, `disabled radio should get legacy-canceled-activation behavior 2`);
    347 
    348 for (const type of ["checkbox", "radio"]) {
    349  for (const handler of ["oninput", "onchange"]) {
    350    async_test(t => {
    351      const input = document.createElement("input");
    352      input.type = type;
    353      input.onclick = t.step_func(ev => {
    354        input.disabled = true;
    355      });
    356      input[handler] = t.step_func(ev => {
    357        assert_equals(input.checked, true);
    358        t.done();
    359      });
    360      dump.append(input);
    361      input.click();
    362    }, `disabling ${type} in onclick listener shouldn't suppress ${handler}`);
    363  }
    364 }
    365 
    366 async_test(function(t) {
    367  var form = document.createElement("form")
    368  var didSubmit = false
    369  form.onsubmit = t.step_func(() => {
    370    didSubmit = true
    371    return false
    372  })
    373  var input = form.appendChild(document.createElement("input"))
    374  input.type = "submit"
    375  input.click()
    376  assert_false(didSubmit)
    377  t.done()
    378 }, "disconnected form should not submit")
    379 
    380 async_test(t => {
    381  const form = document.createElement("form");
    382  form.onsubmit = t.step_func(ev => {
    383    ev.preventDefault();
    384    assert_unreached("The form is unexpectedly submitted.");
    385  });
    386  dump.append(form);
    387  const input = form.appendChild(document.createElement("input"));
    388  input.type = "submit"
    389  input.disabled = true;
    390  input.dispatchEvent(new MouseEvent("click", { cancelable: true }));
    391  t.done();
    392 }, "disabled submit button should not activate");
    393 
    394 async_test(t => {
    395  const form = document.createElement("form");
    396  form.onsubmit = t.step_func(ev => {
    397    ev.preventDefault();
    398    assert_unreached("The form is unexpectedly submitted.");
    399  });
    400  dump.append(form);
    401  const input = form.appendChild(document.createElement("input"));
    402  input.onclick = t.step_func(() => {
    403    input.disabled = true;
    404  });
    405  input.type = "submit"
    406  input.dispatchEvent(new MouseEvent("click", { cancelable: true }));
    407  t.done();
    408 }, "submit button should not activate if the event listener disables it");
    409 
    410 async_test(t => {
    411  const form = document.createElement("form");
    412  form.onsubmit = t.step_func(ev => {
    413    ev.preventDefault();
    414    assert_unreached("The form is unexpectedly submitted.");
    415  });
    416  dump.append(form);
    417  const input = form.appendChild(document.createElement("input"));
    418  input.onclick = t.step_func(() => {
    419    input.type = "submit"
    420    input.disabled = true;
    421  });
    422  input.click();
    423  t.done();
    424 }, "submit button that morphed from checkbox should not activate");
    425 </script>