tor-browser

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

radio.html (15924B)


      1 <!DOCTYPE html>
      2 <meta charset=utf-8>
      3 <title>input type radio</title>
      4 <link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
      5 <link rel=help href="https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio)">
      6 <script src="/resources/testharness.js"></script>
      7 <script src="/resources/testharnessreport.js"></script>
      8 <div id="log"></div>
      9 <input type=radio name=group1 id=radio1>
     10 <input type=radio name=group1 id=radio2>
     11 
     12 <input type=radio name=groüp2 id=radio3>
     13 <input type=radio name=groüp2 id=radio4>
     14 
     15 <input type=radio id=radio5>
     16 <input type=radio id=radio6 disabled>
     17 
     18 <input type=radio name="group5" id=radio71 checked>
     19 <input type=radio name="group5" id=radio72>
     20 
     21 <input type=radio name=group3 id=radio8 checked>
     22 <input type=radio name=group3 id=radio9>
     23 <input type=radio name=group4 id=radio10>
     24 <input type=radio name=group4 id=radio11 checked>
     25 
     26 <form id="testform"></form>
     27 <input type=radio form=testform name=group6 id=radio12 checked>
     28 <input type=radio form=testform name=group6 id=radio13>
     29 <input type=radio form=testform name=group6 id=radio14>
     30 
     31 <script>
     32  var radio1 = document.getElementById('radio1'),
     33      radio2 = document.getElementById('radio2'),
     34      radio3 = document.getElementById('radio3'),
     35      radio4 = document.getElementById('radio4'),
     36      radio5 = document.getElementById('radio5'),
     37      radio6 = document.getElementById('radio6'),
     38      radio71 = document.getElementById('radio71'),
     39      radio72 = document.getElementById('radio72'),
     40      radio8 = document.getElementById('radio8'),
     41      radio9 = document.getElementById('radio9'),
     42      radio10 = document.getElementById('radio10'),
     43      radio11 = document.getElementById('radio11'),
     44      radio12 = document.getElementById('radio12'),
     45      radio13 = document.getElementById('radio13'),
     46      radio14 = document.getElementById('radio14'),
     47      testform = document.getElementById('testform'),
     48      t1 = async_test("click on mutable radio fires click event, then input event, then change event"),
     49      t3 = async_test("click on non-mutable radio doesn't fire the input event"),
     50      t4 = async_test("click on non-mutable radio doesn't fire the change event"),
     51      t5 = async_test("canceled activation steps on unchecked radio"),
     52      input_fired = false,
     53      change_fired = false;
     54 
     55  test(function(){
     56    assert_false(radio1.checked);
     57    assert_false(radio2.checked);
     58    radio1.checked = true;
     59    assert_true(radio1.checked);
     60    assert_false(radio2.checked);
     61    radio2.checked = true;
     62    assert_false(radio1.checked);
     63    assert_true(radio2.checked);
     64  }, "only one control of a radio button group can have its checkedness set to true");
     65 
     66  test(function(){
     67    assert_false(radio3.checked);
     68    assert_false(radio4.checked);
     69    radio3.checked = true;
     70    assert_true(radio3.checked);
     71    assert_false(radio4.checked);
     72    radio4.checked = true;
     73    assert_false(radio3.checked);
     74    assert_true(radio4.checked);
     75  }, "radio inputs with non-ASCII name attributes belong to the same radio button group");
     76 
     77  test(function(){
     78    assert_true(radio8.checked);
     79    assert_false(radio9.checked);
     80    assert_false(radio10.checked);
     81    assert_true(radio11.checked);
     82    radio9.name="group4";
     83    radio9.checked = true;
     84    assert_true(radio8.checked);
     85    assert_true(radio9.checked);
     86    assert_false(radio10.checked);
     87    assert_false(radio11.checked);
     88  }, "changing the name of a radio input element and setting its checkedness to true makes all the other elements' checkedness in the same radio button group be set to false");
     89 
     90  test(function(){
     91    radio12.remove();
     92    assert_true(radio12.checked);
     93    assert_false(radio13.checked);
     94    assert_false(radio14.checked);
     95    radio13.checked = true;
     96    assert_true(radio13.checked);
     97    assert_false(radio14.checked);
     98    radio13.removeAttribute("form");
     99    radio14.removeAttribute("form");
    100    assert_true(radio13.checked);
    101    assert_false(radio14.checked);
    102    radio14.checked = true;
    103    assert_false(radio13.checked);
    104    assert_true(radio14.checked);
    105    radio13.setAttribute("form", "testform");
    106    radio14.setAttribute("form", "testform");
    107    radio13.checked = true;
    108    assert_true(radio13.checked);
    109    assert_false(radio14.checked);
    110    testform.remove();
    111    assert_true(radio13.checked);
    112    assert_false(radio14.checked);
    113  }, "moving radio input element out of or into a form should still work as expected");
    114 
    115  radio5.onclick = t1.step_func(function(e) {
    116    click_fired = true;
    117    assert_false(input_fired, "click event should fire before input event");
    118    assert_false(change_fired, "click event should fire before change event");
    119    assert_false(e.isTrusted, "click()-initiated click event shouldn't be trusted");
    120  });
    121 
    122  radio5.oninput = t1.step_func(function(e) {
    123    input_fired = true;
    124    assert_true(click_fired, "input event should fire after click event");
    125    assert_false(change_fired, "input event should fire before change event");
    126    assert_true(e.bubbles, "input event should bubble")
    127    assert_true(e.isTrusted, "input event should be trusted");
    128    assert_false(e.cancelable, "input event should not be cancelable");
    129  });
    130 
    131  radio5.onchange = t1.step_func(function(e) {
    132    change_fired = true;
    133    assert_true(click_fired, "change event should fire after click event");
    134    assert_true(input_fired, "change event should fire after input event");
    135    assert_true(e.bubbles, "change event should bubble")
    136    assert_true(e.isTrusted, "change event should be trusted");
    137    assert_false(e.cancelable, "change event should not be cancelable");
    138  });
    139 
    140  radio6.oninput= t3.step_func_done(function(e) {
    141    assert_unreached("event input fired");
    142  });
    143 
    144  radio6.onchange = t4.step_func_done(function(e) {
    145    assert_unreached("event change fired");
    146  });
    147 
    148  t1.step(function() {
    149    radio5.click();
    150    assert_true(input_fired);
    151    t1.done();
    152  });
    153 
    154  t3.step(function(){
    155    radio6.click();
    156    t3.done();
    157    t4.done();
    158  });
    159 
    160  radio72.onclick = t5.step_func_done(function(e){
    161    assert_false(radio71.checked, "click on radio should uncheck other radio in same group");
    162    assert_true(radio72.checked, "click on radio should check that radio");
    163    e.preventDefault();
    164    // The cancelation of the click doesn't have an effect until after all the click event handlers have been run.
    165    assert_false(radio71.checked, "radio remains unchecked immediately after click event on other radio in same group is canceled");
    166    assert_true(radio72.checked, "clicked radio remains checked immediately after click event is canceled");
    167  });
    168 
    169  t5.step(function(){
    170    assert_true(radio71.checked, "initially checked radio should be checked");
    171    assert_false(radio72.checked, "other radios in same group as initially-checked radio should be unchecked");
    172    radio72.click();
    173    // Now that the click event has been fully dispatched, its cancelation has taken effect.
    174    assert_true(radio71.checked, "canceled click event on radio should leave the previously-checked radio checked");
    175    assert_false(radio72.checked, "canceled click event on previously-unchecked radio should leave that radio unchecked");
    176  });
    177 
    178  test(() => {
    179    const container = document.createElement('div');
    180    container.innerHTML =
    181        '<input type=radio name=n1><span><input type=radio name=n1 checked></span>' +
    182        '<form><input type=radio name=n1 checked></form>';
    183    const radios = container.querySelectorAll('input');
    184    assert_false(radios[0].checked, 'Sanity check: The first radio should be unchecked');
    185    assert_true(radios[1].checked, 'Sanity check: The second radio should be checked');
    186    assert_true(radios[2].checked, 'Sanity check: The third radio should be checked');
    187 
    188    radios[0].checked = true;
    189    assert_true(radios[0].checked, 'The first radio should be checked after setting checked');
    190    assert_false(radios[1].checked, 'The second radio should be unchecked after setting checked');
    191    assert_true(radios[2].checked, 'The third radio should be checked after setting checked');
    192 
    193    radios[1].required = true;
    194    assert_false(radios[0].validity.valueMissing, 'The first radio should be valid');
    195    assert_false(radios[1].validity.valueMissing, 'The second radio should be valid');
    196    assert_false(radios[2].validity.valueMissing, 'The third radio should be valid');
    197 
    198    radios[0].remove();
    199    assert_false(radios[0].validity.valueMissing, 'The first radio should be valid because of no required');
    200    assert_true(radios[1].validity.valueMissing, 'The second radio should be invalid***');
    201    assert_false(radios[2].validity.valueMissing, 'The third radio should be valid');
    202 
    203    radios[0].required = true;
    204    radios[0].checked = false;
    205    assert_true(radios[0].validity.valueMissing, 'The first radio should be invalid because of required');
    206  }, 'Radio buttons in an orphan tree should make a group');
    207 
    208  test(() => {
    209    const container = document.createElement('div');
    210    container.innerHTML =
    211        '<form>' +
    212          '<input type=radio name=group1 id=radio1 checked>' +
    213          '<input type=radio name=group1 id=radio2>' +
    214        '</form>' +
    215        '<form>' +
    216          '<input type=radio name=group1 id=radio3 checked>' +
    217          '<input type=radio name=group1 id=radio4>' +
    218        '</form>' +
    219        '<input type=radio name=group1 id=radio5 checked>' +
    220        '<input type=radio name=group1 id=radio6>';
    221    const radio1 = container.querySelector('#radio1');
    222    const radio2 = container.querySelector('#radio2');
    223    const radio3 = container.querySelector('#radio3');
    224    const radio4 = container.querySelector('#radio4');
    225    const radio5 = container.querySelector('#radio5');
    226    const radio6 = container.querySelector('#radio6');
    227 
    228    // initial conditions
    229    assert_true(radio1.checked, 'radio1 should be checked');
    230    assert_false(radio2.checked, 'radio2 should be unchecked');
    231    assert_true(radio3.checked, 'radio3 should be checked');
    232    assert_false(radio4.checked, 'radio4 should be unchecked');
    233    assert_true(radio5.checked, 'radio5 should be checked');
    234    assert_false(radio6.checked, 'radio6 should be unchecked');
    235 
    236    radio2.checked = true;
    237    assert_false(radio1.checked, 'radio1 should be unchecked');
    238    assert_true(radio2.checked, 'radio2 should be checked');
    239    assert_true(radio3.checked, 'radio3 should remain checked');
    240    assert_true(radio5.checked, 'radio5 should remain checked');
    241 
    242    radio4.checked = true;
    243    assert_false(radio1.checked, 'radio1 should remain unchecked');
    244    assert_true(radio2.checked, 'radio2 should remain checked');
    245    assert_false(radio3.checked, 'radio3 should be unchecked');
    246    assert_true(radio4.checked, 'radio4 should be checked');
    247    assert_true(radio5.checked, 'radio5 should remain checked');
    248 
    249    radio6.checked = true;
    250    assert_false(radio1.checked, 'radio1 should remain unchecked');
    251    assert_true(radio2.checked, 'radio2 should remain checked');
    252    assert_false(radio3.checked, 'radio3 should remain unchecked');
    253    assert_true(radio4.checked, 'radio4 should remain checked');
    254    assert_false(radio5.checked, 'radio5 should be unchecked');
    255    assert_true(radio6.checked, 'radio6 should be checked');
    256  }, "Radio buttons in different groups (because they have different form owners or no form owner) do not affect each other's checkedness");
    257 
    258  test(() => {
    259    const container = document.createElement('div');
    260    container.innerHTML =
    261        '<form>' +
    262          '<input type=radio name=group1 id=radio1 checked>' +
    263          '<input type=radio name=group1 id=radio2>' +
    264          '<input type=radio name=group1 id=radio3>' +
    265          '<input type=radio name=group1 id=radio4>' +
    266        '</form>';
    267    const radio1 = container.querySelector('#radio1');
    268    const radio2 = container.querySelector('#radio2');
    269    const radio3 = container.querySelector('#radio3');
    270    const radio4 = container.querySelector('#radio4');
    271 
    272    // initial conditions
    273    assert_true(radio1.checked, 'radio1 should be checked');
    274    assert_false(radio2.checked, 'radio2 should be unchecked');
    275    assert_false(radio3.checked, 'radio3 should be unchecked');
    276    assert_false(radio4.checked, 'radio4 should be unchecked');
    277 
    278    radio3.remove();
    279    radio4.remove();
    280    radio3.checked = true;
    281    radio4.checked = true;
    282    assert_true(radio1.checked, 'radio1 should remain checked');
    283    assert_false(radio2.checked, 'radio2 should remain unchecked');
    284    assert_true(radio3.checked, 'radio3 should be checked');
    285    assert_true(radio4.checked, 'radio4 should be checked');
    286  }, "Radio buttons in different groups (because they are not in the same tree) do not affect each other's checkedness");
    287 
    288  test(() => {
    289    const container = document.createElement('div');
    290    container.innerHTML =
    291        '<form>' +
    292          '<input type=radio name=group1 id=radio1 checked>' +
    293          '<input type=radio name=group1 id=radio2>' +
    294          '<input type=radio name=group2 id=radio3 checked>' +
    295          '<input type=radio name=group2 id=radio4>' +
    296          '<input type=radio name="" id=radio5 checked>' +
    297          '<input type=radio name="" id=radio6>' +
    298          '<input type=radio id=radio7 checked>' +
    299          '<input type=radio id=radio8>' +
    300        '</form>';
    301    const radio1 = container.querySelector('#radio1');
    302    const radio2 = container.querySelector('#radio2');
    303    const radio3 = container.querySelector('#radio3');
    304    const radio4 = container.querySelector('#radio4');
    305    const radio5 = container.querySelector('#radio5');
    306    const radio6 = container.querySelector('#radio6');
    307    const radio7 = container.querySelector('#radio7');
    308    const radio8 = container.querySelector('#radio8');
    309 
    310    // initial conditions
    311    assert_true(radio1.checked, 'radio1 should be checked');
    312    assert_false(radio2.checked, 'radio2 should be unchecked');
    313    assert_true(radio3.checked, 'radio3 should be checked');
    314    assert_false(radio4.checked, 'radio4 should be unchecked');
    315    assert_true(radio5.checked, 'radio5 should be checked');
    316    assert_false(radio6.checked, 'radio6 should be unchecked');
    317    assert_true(radio7.checked, 'radio7 should be checked');
    318    assert_false(radio8.checked, 'radio8 should be unchecked');
    319 
    320    radio2.checked = true;
    321    assert_false(radio1.checked, 'radio1 should be unchecked');
    322    assert_true(radio2.checked, 'radio2 should be checked');
    323    assert_true(radio3.checked, 'radio3 should remain checked');
    324    assert_false(radio4.checked, 'radio4 should remain unchecked');
    325    assert_true(radio5.checked, 'radio5 should remain checked');
    326    assert_false(radio6.checked, 'radio6 should remain unchecked');
    327    assert_true(radio7.checked, 'radio7 should remain checked');
    328    assert_false(radio8.checked, 'radio8 should remain unchecked');
    329 
    330    radio6.checked = true;
    331    assert_false(radio1.checked, 'radio1 should remain unchecked');
    332    assert_true(radio2.checked, 'radio2 should remain checked');
    333    assert_true(radio3.checked, 'radio3 should remain checked');
    334    assert_false(radio4.checked, 'radio4 should remain unchecked');
    335    assert_true(radio5.checked, 'radio5 should remain checked');
    336    assert_true(radio6.checked, 'radio6 should be checked');
    337    assert_true(radio7.checked, 'radio7 should remain checked');
    338 
    339    radio8.checked = true;
    340    assert_false(radio1.checked, 'radio1 should remain unchecked');
    341    assert_true(radio2.checked, 'radio2 should remain checked');
    342    assert_true(radio3.checked, 'radio3 should remain checked');
    343    assert_false(radio4.checked, 'radio4 should remain unchecked');
    344    assert_true(radio5.checked, 'radio5 should remain checked');
    345    assert_true(radio6.checked, 'radio6 should remain checked');
    346    assert_true(radio7.checked, 'radio7 should remain checked');
    347    assert_true(radio8.checked, 'radio8 should be checked');
    348 
    349  }, "Radio buttons in different groups (because they have different name attribute values, or no name attribute) do not affect each other's checkedness");
    350 
    351 </script>