tor-browser

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

exec-command-with-text-editor.tentative.html (26265B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <title>Test that execCommand with &lt;input&gt; or &lt;textarea&gt;</title>
      4 <meta name="variant" content="?type=text">
      5 <meta name="variant" content="?type=textarea">
      6 <meta name="variant" content="?type=password">
      7 <script src=/resources/testharness.js></script>
      8 <script src=/resources/testharnessreport.js></script>
      9 <script src="/resources/testdriver.js"></script>
     10 <script src='/resources/testdriver-vendor.js'></script>
     11 <div id="container"></div>
     12 <script>
     13 "use strict";
     14 
     15 setup({explicit_done: true});
     16 const testingType = new URLSearchParams(document.location.search).get("type");
     17 
     18 /**
     19 * This test checks whether document.execCommand() does something expected or
     20 * not in <input> and <textarea> with/without contenteditable parent.  Although
     21 * this is not standardized even by any drafts.  So, this test uses expected
     22 * values which may be expected by web developers.
     23 */
     24 async function runTests() {
     25  let container = document.getElementById("container");
     26  switch (testingType) {
     27    case "text":
     28    case "password":
     29      container.innerHTML = `Here <b>is</b> Text: <input id="target" type="${testingType}">`;
     30      await runTest(document.getElementById("target"), `In <input type="${testingType}">`);
     31      container.setAttribute("contenteditable", "true");
     32      container.innerHTML = `Here <b>is</b> Text: <input id="target" type="${testingType}">`;
     33      await runTest(document.getElementById("target"), `In <input type="${testingType}"> in contenteditable`);
     34      break;
     35    case "textarea":
     36      container.innerHTML = "Here <b>is</b> Text: <textarea id=\"target\"></textarea>";
     37      await runTest(document.getElementById("target"), "In <textarea>");
     38      container.setAttribute("contenteditable", "true");
     39      container.innerHTML = "Here <b>is</b> Text: <textarea id=\"target\"></textarea>";
     40      await runTest(document.getElementById("target"), "In <textarea> in contenteditable");
     41      break;
     42  }
     43  done();
     44 }
     45 
     46 async function runTest(aTarget, aDescription) {
     47  const kIsTextArea = testingType == "textarea";
     48  const kTests = [
     49    /**
     50     * command: command name of execCommand().
     51     * param: param for the command.  i.e., the 3rd param of execCommand().
     52     * value: initial value of <input> or <textarea>.  must have a pair of
     53     *        "[" and "]" for specifying selection range.
     54     * expectedValue: expected value of <input> or <textarea> after calling
     55     *                execCommand() with command and param.  must have a
     56     *                pair of "[" and "]" for specifying selection range.
     57     * expectedExecCommandResult: expected bool result of execCommand().
     58     * expectedCommandSupported: expected bool result of queryCommandSupported().
     59     * expectedCommandEnabled: expected bool result of queryCommandEnabled().
     60     * beforeinputExpected: if "beforeinput" event shouldn't be fired, set
     61     *                      null.  otherwise, expected inputType value and
     62     *                      target element.
     63     * inputExpected: if "input" event shouldn't be fired, set null.
     64     *                otherwise, expected inputType value and target element.
     65     */
     66    {command: "getHTML", param: null,
     67     value: "a[b]c", expectedValue: "a[b]c",
     68     expectedExecCommandResult: false,
     69     expectedCommandSupported: false,
     70     expectedCommandEnabled: false,
     71     beforeinputExpected: null, inputExpected: null,
     72    },
     73    {command: "bold", param: "bold",
     74     value: "a[b]c", expectedValue: "a[b]c",
     75     expectedExecCommandResult: false,
     76     expectedCommandSupported: true,
     77     expectedCommandEnabled: false,
     78     beforeinputExpected: null, inputExpected: null,
     79    },
     80    {command: "italic", param: null,
     81     value: "a[b]c", expectedValue: "a[b]c",
     82     expectedExecCommandResult: false,
     83     expectedCommandSupported: true,
     84     expectedCommandEnabled: false,
     85     beforeinputExpected: null, inputExpected: null,
     86    },
     87    {command: "underline", param: null,
     88     value: "a[b]c", expectedValue: "a[b]c",
     89     expectedExecCommandResult: false,
     90     expectedCommandSupported: true,
     91     expectedCommandEnabled: false,
     92     beforeinputExpected: null, inputExpected: null,
     93    },
     94    {command: "strikethrough", param: null,
     95     value: "a[b]c", expectedValue: "a[b]c",
     96     expectedExecCommandResult: false,
     97     expectedCommandSupported: true,
     98     expectedCommandEnabled: false,
     99     beforeinputExpected: null, inputExpected: null,
    100    },
    101    {command: "superscript", param: null,
    102     value: "a[b]c", expectedValue: "a[b]c",
    103     expectedExecCommandResult: false,
    104     expectedCommandSupported: true,
    105     expectedCommandEnabled: false,
    106     beforeinputExpected: null, inputExpected: null,
    107    },
    108    // Should return true for web apps implementing custom editor.
    109    {command: "cut", param: null,
    110     value: "ab[]c", expectedValue: "ab[]c",
    111     expectedExecCommandResult: false,
    112     expectedCommandSupported: true,
    113     expectedCommandEnabled: false,
    114     beforeinputExpected: null, inputExpected: null,
    115    },
    116    {command: "cut", param: null,
    117     value: "a[b]c", expectedValue: "a[]c",
    118     expectedExecCommandResult: true,
    119     expectedCommandSupported: true,
    120     expectedCommandEnabled: true,
    121     beforeinputExpected: null,
    122     inputExpected: { inputType: "deleteByCut", target: aTarget },
    123    },
    124    // Should return true for web apps implementing custom editor.
    125    {command: "copy", param: null,
    126     value: "abc[]d", expectedValue: "abc[]d",
    127     expectedExecCommandResult: false,
    128     expectedCommandSupported: true,
    129     expectedCommandEnabled: false,
    130     beforeinputExpected: null, inputExpected: null,
    131    },
    132    {command: "copy", param: null,
    133     value: "a[bc]d", expectedValue: "a[bc]d",
    134     expectedExecCommandResult: true,
    135     expectedCommandSupported: true,
    136     expectedCommandEnabled: true,
    137     beforeinputExpected: null, inputExpected: null,
    138    },
    139    {command: "paste", param: null,
    140     value: "a[]c", expectedValue: "abc[]c",
    141     expectedExecCommandResult: true,
    142     expectedCommandSupported: true,
    143     expectedCommandEnabled: true,
    144     beforeinputExpected: null,
    145     inputExpected: { inputType: "insertFromPaste", target: aTarget },
    146    },
    147    {command: "delete", param: null,
    148     value: "ab[]c", expectedValue: "a[]c",
    149     expectedExecCommandResult: true,
    150     expectedCommandSupported: true,
    151     expectedCommandEnabled: true,
    152     beforeinputExpected: null,
    153     inputExpected: { inputType: "deleteContentBackward", target: aTarget },
    154    },
    155    {command: "delete", param: null,
    156     value: "a[b]c", expectedValue: "a[]c",
    157     expectedExecCommandResult: true,
    158     expectedCommandSupported: true,
    159     expectedCommandEnabled: true,
    160     beforeinputExpected: null,
    161     inputExpected: { inputType: "deleteContentBackward", target: aTarget },
    162    },
    163    {command: "forwarddelete", param: null,
    164     value: "a[b]c", expectedValue: "a[]c",
    165     expectedExecCommandResult: true,
    166     expectedCommandSupported: true,
    167     expectedCommandEnabled: true,
    168     beforeinputExpected: null,
    169     inputExpected: { inputType: "deleteContentForward", target: aTarget },
    170    },
    171    {command: "forwarddelete", param: null,
    172     value: "a[]bc", expectedValue: "a[]c",
    173     expectedExecCommandResult: true,
    174     expectedCommandSupported: true,
    175     expectedCommandEnabled: true,
    176     beforeinputExpected: null,
    177     inputExpected: { inputType: "deleteContentForward", target: aTarget },
    178    },
    179    {command: "selectall", param: null,
    180     value: "a[b]c", expectedValue: "[abc]",
    181     expectedExecCommandResult: true,
    182     expectedCommandSupported: true,
    183     expectedCommandEnabled: true,
    184     beforeinputExpected: null, inputExpected: null,
    185    },
    186    // Setting value should forget any transactions.
    187    {command: "undo", param: null,
    188     value: "[a]bc", expectedValue: "[a]bc",
    189     expectedExecCommandResult: false,
    190     expectedCommandSupported: true,
    191     expectedCommandEnabled: false,
    192     beforeinputExpected: null, inputExpected: null,
    193    },
    194    {command: "undo", param: null,
    195     value: "a[b]c", expectedValue: "a[b]c",
    196     initFunc: () => {
    197       document.execCommand("delete", false, null);
    198     },
    199     expectedExecCommandResult: true,
    200     expectedCommandSupported: true,
    201     expectedCommandEnabled: true,
    202     beforeinputExpected: null,
    203     inputExpected: { inputType: "historyUndo", target: aTarget },
    204    },
    205    // Setting value should forget any transactions.
    206    {command: "redo", param: null,
    207     value: "[a]bc", expectedValue: "[a]bc",
    208     expectedExecCommandResult: false,
    209     expectedCommandSupported: true,
    210     expectedCommandEnabled: false,
    211     beforeinputExpected: null, inputExpected: null,
    212    },
    213    {command: "redo", param: null,
    214     value: "a[b]c", expectedValue: "a[]c",
    215     initFunc: () => {
    216       document.execCommand("delete", false, null);
    217       document.execCommand("undo", false, null);
    218     },
    219     expectedExecCommandResult: true,
    220     expectedCommandSupported: true,
    221     expectedCommandEnabled: true,
    222     beforeinputExpected: null,
    223     inputExpected: { inputType: "historyRedo", target: aTarget },
    224    },
    225    {command: "indent", param: null,
    226     value: "a[b]c", expectedValue: "a[b]c",
    227     expectedExecCommandResult: false,
    228     expectedCommandSupported: true,
    229     expectedCommandEnabled: false,
    230     beforeinputExpected: null, inputExpected: null,
    231    },
    232    {command: "outdent", param: null,
    233     value: "a[b]c", expectedValue: "a[b]c",
    234     expectedExecCommandResult: false,
    235     expectedCommandSupported: true,
    236     expectedCommandEnabled: false,
    237     beforeinputExpected: null, inputExpected: null,
    238    },
    239    {command: "backcolor", param: "#000000",
    240     value: "a[b]c", expectedValue: "a[b]c",
    241     expectedExecCommandResult: false,
    242     expectedCommandSupported: true,
    243     expectedCommandEnabled: false,
    244     beforeinputExpected: null, inputExpected: null,
    245    },
    246    {command: "forecolor", param: "#000000",
    247     value: "a[b]c", expectedValue: "a[b]c",
    248     expectedExecCommandResult: false,
    249     expectedCommandSupported: true,
    250     expectedCommandEnabled: false,
    251     beforeinputExpected: null, inputExpected: null,
    252    },
    253    {command: "hilitecolor", param: "#000000",
    254     value: "a[b]c", expectedValue: "a[b]c",
    255     expectedExecCommandResult: false,
    256     expectedCommandSupported: true,
    257     expectedCommandEnabled: false,
    258     beforeinputExpected: null, inputExpected: null,
    259    },
    260    {command: "fontname", param: "DummyFont",
    261     value: "a[b]c", expectedValue: "a[b]c",
    262     expectedExecCommandResult: false,
    263     expectedCommandSupported: true,
    264     expectedCommandEnabled: false,
    265     beforeinputExpected: null, inputExpected: null,
    266    },
    267    {command: "fontsize", param: "5",
    268     value: "a[b]c", expectedValue: "a[b]c",
    269     expectedExecCommandResult: false,
    270     expectedCommandSupported: true,
    271     expectedCommandEnabled: false,
    272     beforeinputExpected: null, inputExpected: null,
    273    },
    274    {command: "increasefontsize", param: null,
    275     value: "a[b]c", expectedValue: "a[b]c",
    276     expectedExecCommandResult: false,
    277     expectedCommandSupported: false,
    278     expectedCommandEnabled: false,
    279     beforeinputExpected: null, inputExpected: null,
    280    },
    281    {command: "decreasefontsize", param: null,
    282     value: "a[b]c", expectedValue: "a[b]c",
    283     expectedExecCommandResult: false,
    284     expectedCommandSupported: false,
    285     expectedCommandEnabled: false,
    286     beforeinputExpected: null, inputExpected: null,
    287    },
    288    {command: "inserthorizontalrule", param: null,
    289     value: "a[b]c", expectedValue: "a[b]c",
    290     expectedExecCommandResult: false,
    291     expectedCommandSupported: true,
    292     expectedCommandEnabled: false,
    293     beforeinputExpected: null, inputExpected: null,
    294    },
    295    {command: "createlink", param: "foo.html",
    296     value: "a[b]c", expectedValue: "a[b]c",
    297     expectedExecCommandResult: false,
    298     expectedCommandSupported: true,
    299     expectedCommandEnabled: false,
    300     beforeinputExpected: null, inputExpected: null,
    301    },
    302    {command: "insertimage", param: "no-image.png",
    303     value: "a[b]c", expectedValue: "a[b]c",
    304     expectedExecCommandResult: false,
    305     expectedCommandSupported: true,
    306     expectedCommandEnabled: false,
    307     beforeinputExpected: null, inputExpected: null,
    308    },
    309    {command: "inserthtml", param: "<b>inserted</b>",
    310     value: "a[b]c", expectedValue: "ainserted[]c",
    311     expectedExecCommandResult: true,
    312     expectedCommandSupported: true,
    313     expectedCommandEnabled: true,
    314     beforeinputExpected: null,
    315     inputExpected: { inputType: "insertText", target: aTarget },
    316    },
    317    {command: "inserttext", param: "**inserted**",
    318     value: "a[b]c", expectedValue: "a**inserted**[]c",
    319     expectedExecCommandResult: true,
    320     expectedCommandSupported: true,
    321     expectedCommandEnabled: true,
    322     beforeinputExpected: null,
    323     inputExpected: { inputType: "insertText", target: aTarget },
    324    },
    325    {command: "inserttext", param: "",
    326     value: "a[b]c", expectedValue: "a[]c",
    327     expectedExecCommandResult: true,
    328     expectedCommandSupported: true,
    329     expectedCommandEnabled: true,
    330     beforeinputExpected: null,
    331     inputExpected: { inputType: "insertText", target: aTarget },
    332    },
    333    {command: "justifyleft", param: null,
    334     value: "a[b]c", expectedValue: "a[b]c",
    335     expectedExecCommandResult: false,
    336     expectedCommandSupported: true,
    337     expectedCommandEnabled: false,
    338     beforeinputExpected: null, inputExpected: null,
    339    },
    340    {command: "justifyright", param: null,
    341     value: "a[b]c", expectedValue: "a[b]c",
    342     expectedExecCommandResult: false,
    343     expectedCommandSupported: true,
    344     expectedCommandEnabled: false,
    345     beforeinputExpected: null, inputExpected: null,
    346    },
    347    {command: "justifycenter", param: null,
    348     value: "a[b]c", expectedValue: "a[b]c",
    349     expectedExecCommandResult: false,
    350     expectedCommandSupported: true,
    351     expectedCommandEnabled: false,
    352     beforeinputExpected: null, inputExpected: null,
    353    },
    354    {command: "justifyfull", param: null,
    355     value: "a[b]c", expectedValue: "a[b]c",
    356     expectedExecCommandResult: false,
    357     expectedCommandSupported: true,
    358     expectedCommandEnabled: false,
    359     beforeinputExpected: null, inputExpected: null,
    360    },
    361    {command: "removeformat", param: null,
    362     value: "a[b]c", expectedValue: "a[b]c",
    363     expectedExecCommandResult: false,
    364     expectedCommandSupported: true,
    365     expectedCommandEnabled: false,
    366     beforeinputExpected: null, inputExpected: null,
    367    },
    368    {command: "unlink", param: null,
    369     value: "a[b]c", expectedValue: "a[b]c",
    370     expectedExecCommandResult: false,
    371     expectedCommandSupported: true,
    372     expectedCommandEnabled: false,
    373     beforeinputExpected: null, inputExpected: null,
    374    },
    375    {command: "insertorderedlist", param: null,
    376     value: "a[b]c", expectedValue: "a[b]c",
    377     expectedExecCommandResult: false,
    378     expectedCommandSupported: true,
    379     expectedCommandEnabled: false,
    380     beforeinputExpected: null, inputExpected: null,
    381    },
    382    {command: "insertunorderedlist", param: null,
    383     value: "a[b]c", expectedValue: "a[b]c",
    384     expectedExecCommandResult: false,
    385     expectedCommandSupported: true,
    386     expectedCommandEnabled: false,
    387     beforeinputExpected: null, inputExpected: null,
    388    },
    389    {command: "insertparagraph", param: null,
    390     value: "a[b]c", expectedValue: kIsTextArea ? "a\n[]c" : "a[b]c",
    391     expectedExecCommandResult: kIsTextArea,
    392     expectedCommandSupported: true,
    393     expectedCommandEnabled: kIsTextArea,
    394     beforeinputExpected: null,
    395     inputExpected: kIsTextArea ? { inputType: "insertParagraph", target: aTarget } : null,
    396    },
    397    {command: "insertlinebreak", param: null,
    398     value: "a[b]c", expectedValue: kIsTextArea ? "a\n[]c" : "a[b]c",
    399     expectedExecCommandResult: kIsTextArea,
    400     expectedCommandSupported: true,
    401     expectedCommandEnabled: kIsTextArea,
    402     beforeinputExpected: null,
    403     inputExpected: kIsTextArea ? { inputType: "insertLineBreak", target: aTarget } : null,
    404    },
    405    {command: "formatblock", param: "div",
    406     value: "a[b]c", expectedValue: "a[b]c",
    407     expectedExecCommandResult: false,
    408     expectedCommandSupported: true,
    409     expectedCommandEnabled: false,
    410     beforeinputExpected: null, inputExpected: null,
    411    },
    412    {command: "heading", param: "h1",
    413     value: "a[b]c", expectedValue: "a[b]c",
    414     expectedExecCommandResult: false,
    415     expectedCommandSupported: false,
    416     expectedCommandEnabled: false,
    417     beforeinputExpected: null, inputExpected: null,
    418    },
    419    {command: "styleWithCSS", param: "true",
    420     value: "a[b]c", expectedValue: "a[b]c",
    421     expectedExecCommandResult: container.isContentEditable,
    422     expectedCommandSupported: true,
    423     expectedCommandEnabled: container.isContentEditable,
    424     beforeinputExpected: null, inputExpected: null,
    425     additionalCheckFunc: aDescription => {
    426       test(
    427         () => assert_equals(document.queryCommandState("styleWithCSS"), container.isContentEditable),
    428         `${aDescription}: styleWithCSS state should be ${container.isContentEditable} when ${
    429           kIsTextArea ? "<textarea>" : "<input>"
    430         } has focus`
    431       );
    432       aTarget.blur();
    433       container.focus();
    434       getSelection().collapse(container, 0);
    435       test(
    436         () => assert_equals(document.queryCommandState("styleWithCSS"), container.isContentEditable),
    437         `${aDescription}: styleWithCSS state should be ${container.isContentEditable} when ${
    438           kIsTextArea ? "<textarea>" : "<input>"
    439         } does not have focus`
    440        );
    441      },
    442    },
    443    {command: "styleWithCSS", param: "false",
    444     value: "a[b]c", expectedValue: "a[b]c",
    445     expectedExecCommandResult: container.isContentEditable,
    446     expectedCommandSupported: true,
    447     expectedCommandEnabled: container.isContentEditable,
    448     beforeinputExpected: null, inputExpected: null,
    449     additionalCheckFunc: aDescription => {
    450       test(
    451         () => assert_equals(document.queryCommandState("styleWithCSS"), false),
    452         `${aDescription}: styleWithCSS state should be false when ${
    453           kIsTextArea ? "<textarea>" : "<input>"
    454         } has focus`
    455       );
    456       aTarget.blur();
    457       container.focus();
    458       getSelection().collapse(container, 0);
    459       test(
    460         () => assert_equals(document.queryCommandState("styleWithCSS"), false),
    461         `${aDescription}: styleWithCSS state should be false when ${
    462           kIsTextArea ? "<textarea>" : "<input>"
    463         } does not have focus`
    464        );
    465      },
    466    },
    467    {command: "contentReadOnly", param: "true",
    468     value: "a[b]c", expectedValue: "a[b]c",
    469     expectedExecCommandResult: false,
    470     expectedCommandSupported: false,
    471     expectedCommandEnabled: false,
    472     beforeinputExpected: null, inputExpected: null,
    473     additionalCheckFunc: aDescription => {
    474       test(
    475         () => assert_equals(document.queryCommandState("contentReadOnly"), false),
    476         `${aDescription}: contentReadOnly state should be true when ${
    477           kIsTextArea ? "<textarea>" : "<input>"
    478         } has focus`
    479       );
    480       test(
    481         () => assert_equals(aTarget.readOnly, false),
    482         `${aDescription}: readonly property should be true`
    483       );
    484       aTarget.blur();
    485       container.focus();
    486       getSelection().collapse(container, 0);
    487       test(
    488         () => assert_equals(document.queryCommandState("contentReadOnly"), false),
    489         `${aDescription}: contentReadOnly state should be false when ${
    490           kIsTextArea ? "<textarea>" : "<input>"
    491         } does not have focus`
    492        );
    493      },
    494    },
    495    {command: "contentReadOnly", param: "false",
    496     value: "a[b]c", expectedValue: "a[b]c",
    497     expectedExecCommandResult: false,
    498     expectedCommandSupported: false,
    499     expectedCommandEnabled: false,
    500     beforeinputExpected: null, inputExpected: null,
    501     additionalCheckFunc: aDescription => {
    502       test(
    503         () => assert_equals(document.queryCommandState("contentReadOnly"), false),
    504         `${aDescription}: contentReadOnly state should be false when ${
    505           kIsTextArea ? "<textarea>" : "<input>"
    506         } has focus`
    507       );
    508       test(
    509         () => assert_equals(aTarget.readOnly, false),
    510         `${aDescription}: readonly property should be false`
    511       );
    512       aTarget.blur();
    513       container.focus();
    514       getSelection().collapse(container, 0);
    515       test(
    516         () => assert_equals(document.queryCommandState("contentReadOnly"), false),
    517         `${aDescription}: contentReadOnly state should be false when ${
    518           kIsTextArea ? "<textarea>" : "<input>"
    519         } does not have focus`
    520        );
    521      },
    522    },
    523    {command: "defaultParagraphSeparator", param: "p",
    524     value: "a[b]c", expectedValue: "a[b]c",
    525     expectedExecCommandResult: container.isContentEditable,
    526     expectedCommandSupported: true,
    527     expectedCommandEnabled: container.isContentEditable,
    528     beforeinputExpected: null, inputExpected: null,
    529     additionalCheckFunc: aDescription => {
    530       test(
    531         () =>
    532           assert_equals(
    533             document.queryCommandValue("defaultParagraphSeparator"),
    534             container.isContentEditable ? "p" : "div"
    535           )
    536         ,
    537         `${aDescription}: defaultParagraphSeparator value should be "p" when ${
    538           kIsTextArea ? "<textarea>" : "<input>"
    539         } has focus`
    540       );
    541       aTarget.blur();
    542       container.focus();
    543       getSelection().collapse(container, 0);
    544       test(
    545         () =>
    546           assert_equals(
    547             document.queryCommandValue("defaultParagraphSeparator"),
    548             container.isContentEditable ? "p" : "div"
    549           ),
    550         `${aDescription}: defaultParagraphSeparator value should be "p" when ${
    551           kIsTextArea ? "<textarea>" : "<input>"
    552         } does not have focus`
    553        );
    554      },
    555    },
    556    {command: "defaultParagraphSeparator", param: "div",
    557     value: "a[b]c", expectedValue: "a[b]c",
    558     expectedExecCommandResult: container.isContentEditable,
    559     expectedCommandSupported: true,
    560     expectedCommandEnabled: container.isContentEditable,
    561     beforeinputExpected: null, inputExpected: null,
    562     additionalCheckFunc: aDescription => {
    563       test(
    564         () => assert_equals(document.queryCommandValue("defaultParagraphSeparator"), "div"),
    565         `${aDescription}: defaultParagraphSeparator value should be "div" when ${
    566           kIsTextArea ? "<textarea>" : "<input>"
    567         } has focus`
    568       );
    569       aTarget.blur();
    570       container.focus();
    571       getSelection().collapse(container, 0);
    572       test(
    573         () => assert_equals(document.queryCommandValue("defaultParagraphSeparator"), "div"),
    574         `${aDescription}: defaultParagraphSeparator value should be "div" when ${
    575           kIsTextArea ? "<textarea>" : "<input>"
    576         } does not have focus`
    577        );
    578      },
    579    },
    580  ];
    581 
    582  for (const kTest of kTests) {
    583    const kDescription =
    584        `${aDescription}, execCommand("${kTest.command}", false, ${kTest.param}), ${kTest.value})`;
    585    if (kTest.command === "paste" || kTest.command === "copy" || kTest.command === "cut") {
    586      await test_driver.click(document.body);
    587    }
    588    aTarget.value = "dummy value to ensure the following value setting clear the undo history";
    589    let value = kTest.value.replace(/[\[\]]/g, "");
    590    aTarget.value = value;
    591    aTarget.focus();
    592    aTarget.selectionStart = kTest.value.indexOf("[");
    593    aTarget.selectionEnd = kTest.value.indexOf("]") - 1;
    594 
    595    test(
    596      () => assert_equals(document.queryCommandSupported(kTest.command), kTest.expectedCommandSupported),
    597      `${kDescription}: The command should ${
    598        kTest.expectedCommandSupported ? "be" : "not be"
    599      } supported`
    600    );
    601    test(
    602      () => assert_equals(document.queryCommandEnabled(kTest.command), kTest.expectedCommandEnabled),
    603      `${kDescription}: The command should ${
    604        kTest.expectedCommandEnabled ? "be" : "not be"
    605      } enabled`
    606    );
    607 
    608    if (!document.queryCommandSupported(kTest.command) || !kTest.expectedCommandSupported) {
    609      continue;
    610    }
    611 
    612    if (kTest.initFunc) {
    613      kTest.initFunc();
    614    }
    615 
    616    let beforeinput = null;
    617    function onBeforeinput(event) {
    618      beforeinput = event;
    619    }
    620    window.addEventListener("beforeinput", onBeforeinput, {capture: true});
    621    let input = null;
    622    function onInput(event) {
    623      input = event;
    624    }
    625    window.addEventListener("input", onInput, {capture: true});
    626    let ret;
    627    test(function () {
    628      ret = document.execCommand(kTest.command, false, kTest.param);
    629      assert_equals(ret, kTest.expectedExecCommandResult);
    630    }, `${kDescription}: execCommand() should return ${kTest.expectedExecCommandResult}`);
    631    test(function () {
    632      let value = aTarget.value.substring(0, aTarget.selectionStart) +
    633                      "[" +
    634                      aTarget.value.substring(aTarget.selectionStart, aTarget.selectionEnd) +
    635                      "]" +
    636                      aTarget.value.substring(aTarget.selectionEnd);
    637      assert_equals(value, kTest.expectedValue);
    638    }, `${kDescription}: ${kIsTextArea ? "<textarea>" : "<input>"}.value should be "${kTest.expectedValue}"`);
    639    test(function () {
    640      assert_equals(beforeinput?.inputType, kTest.beforeinputExpected?.inputType);
    641    }, `${kDescription}: beforeinput.inputType should be ${kTest.beforeinputExpected?.inputType}`);
    642    test(function () {
    643      assert_equals(beforeinput?.target, kTest.beforeinputExpected?.target);
    644    }, `${kDescription}: beforeinput.target should be ${kTest.beforeinputExpected?.target}`);
    645    test(function () {
    646      assert_equals(input?.inputType, kTest.inputExpected?.inputType);
    647    }, `${kDescription}: input.inputType should be ${kTest.inputExpected?.inputType}`);
    648    test(function () {
    649      assert_equals(input?.target, kTest.inputExpected?.target);
    650    }, `${kDescription}: input.target should be ${kTest.inputExpected?.target}`);
    651    if (kTest.additionalCheckFunc) {
    652      kTest.additionalCheckFunc(kDescription);
    653    }
    654    window.removeEventListener("beforeinput", onBeforeinput, {capture: true});
    655    window.removeEventListener("input", onInput, {capture: true});
    656  }
    657 }
    658 
    659 window.addEventListener("load", runTests, {once: true});
    660 </script>