tor-browser

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

editing-div-outside-body.html (4531B)


      1 <!doctype html>
      2 <html>
      3 <meta charset=utf-8>
      4 <meta name="variant" content="?designMode">
      5 <meta name="variant" content="?body">
      6 <meta name="variant" content="?html">
      7 <meta name="variant" content="?div-in-body">
      8 <meta name="variant" content="?nothing">
      9 <title>Test editing outside of body element</title>
     10 <script src=/resources/testharness.js></script>
     11 <script src=/resources/testharnessreport.js></script>
     12 <script src="/resources/testdriver.js"></script>
     13 <script src="/resources/testdriver-vendor.js"></script>
     14 <script src="/resources/testdriver-actions.js"></script>
     15 <script src="../include/editor-test-utils.js"></script>
     16 <script>
     17 "use strict";
     18 
     19 // This test creates an editable <div> element, append it to the <html>,
     20 // i.e., after the <body>, and do something in it.
     21 
     22 const tests = [
     23  {
     24    command: "insertText",
     25    arg: "abc",
     26    initial: "<div>[]<br></div>",
     27    expected: ["<div>abc</div>", "<div>abc<br></div>"],
     28  },
     29  {
     30    command: "delete",
     31    initial: "<div>abc[]</div>",
     32    expected: ["<div>ab</div>", "<div>ab<br></div>"],
     33  },
     34  {
     35    command: "forwardDelete",
     36    initial: "<div>[]abc</div>",
     37    expected: ["<div>bc</div>", "<div>bc<br></div>"],
     38  },
     39  {
     40    command: "insertParagraph",
     41    initial: "<div>ab[]c</div>",
     42    expected: [
     43      "<div>ab</div><div>c</div>",
     44      "<div>ab<br></div><div>c</div>",
     45      "<div>ab</div><div>c<br></div>",
     46      "<div>ab<br></div><div>c<br></div>",
     47    ],
     48  },
     49  {
     50    command: "insertLineBreak",
     51    initial: "<div>ab[]c</div>",
     52    expected: ["<div>ab<br>c</div>", "<div>ab<br>c<br></div>"],
     53  },
     54  {
     55    command: "bold",
     56    initial: "<div>a[b]c</div>",
     57    expected: ["<div>a<b>b</b>c</div>", "<div>a<b>b</b>c<br></div>"],
     58  },
     59  {
     60    command: "italic",
     61    initial: "<div>a[b]c</div>",
     62    expected: ["<div>a<i>b</i>c</div>", "<div>a<i>b</i>c<br></div>"],
     63  },
     64  {
     65    command: "createLink",
     66    arg: "another.html",
     67    initial: "<div>a[b]c</div>",
     68    expected: [
     69      "<div>a<a href=\"another.html\">b</a>c</div>",
     70      "<div>a<a href=\"another.html\">b</a>c<br></div>",
     71    ],
     72  },
     73  {
     74    command: "unlink",
     75    initial: "<div>a[<a href=\"another.html\">b</a>]c</div>",
     76    expected: ["<div>abc</div>", "<div>abc<br></div>"],
     77  },
     78  {
     79    command: "insertHTML",
     80    arg: "<hr>",
     81    initial: "<div>a[b]c</div>",
     82    expected: [
     83      "<div>a<hr>c</div>",
     84      "<div>a<br><hr>c</div>",
     85      "<div>a<hr>c<br></div>",
     86      "<div>a<br><hr>c<br></div>",
     87    ],
     88  },
     89  // TODO: Add more commands.
     90 ];
     91 
     92 let editingHost = () => {
     93  switch (document.location.search) {
     94    case "?designMode":
     95      document.designMode = "on";
     96      return document.documentElement;
     97    case "?body":
     98      document.body.setAttribute("contenteditable", "true");
     99      return document.body;
    100    case "?html":
    101      document.documentElement.setAttribute("contenteditable", "true");
    102      return document.documentElement;
    103    case "?div-in-body":
    104      return document.querySelector("div[contenteditable]");
    105    case "?nothing":
    106      return null;
    107  }
    108 };
    109 
    110 let div;
    111 
    112 promise_test(async () => {
    113  await new Promise(resolve => {
    114    addEventListener(
    115      "load",
    116      () => {
    117        assert_true(true, "load event is fired");
    118        resolve();
    119      },
    120      { once: true }
    121    );
    122  });
    123 
    124  div = document.createElement("div");
    125  if (editingHost != document.documentElement) {
    126    div.setAttribute("contenteditable", "true");
    127    editingHost = div;
    128  }
    129  document.documentElement.appendChild(div);
    130  assert_equals(document.documentElement.lastChild, div,
    131    "The test target should be last child of the <html>");
    132 }, "Waiting for load event");
    133 
    134 function addPromiseTest(testName, testFunc) {
    135  promise_test(async () => {
    136    editingHost.focus();
    137    await testFunc(new EditorTestUtils(div));
    138  }, testName);
    139 }
    140 
    141 for (const test of tests) {
    142  addPromiseTest(
    143    `Test for execCommand("${test.command}", false, ${
    144      typeof test.arg == "string" ? `"${test.arg}"` : test.arg
    145    }) in "${test.initial}"`,
    146    async (utils) => {
    147      utils.setupEditingHost(test.initial);
    148      await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
    149      document.execCommand(test.command, false, test.arg);
    150      if (Array.isArray(test.expected)) {
    151        assert_in_array(div.innerHTML, test.expected,
    152          "The editing result is different from expected one");
    153      } else {
    154        assert_equals(div.innerHTML, test.expected,
    155          "The editing result is different from expected one");
    156      }
    157    }
    158  );
    159 }
    160 </script>
    161 </head>
    162 <body></body>
    163 </html>