tor-browser

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

test_paste_no_formatting.html (7202B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <meta charset="utf-8">
      5  <title>Test pasting formatted test into various fields</title>
      6  <script src="/tests/SimpleTest/SimpleTest.js"></script>
      7  <script src="/tests/SimpleTest/EventUtils.js"></script>
      8  <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
      9 </head>
     10 <body>
     11 
     12 <input id="input">
     13 <textarea id="textarea"></textarea>
     14 <div id="editable" contenteditable="true"></div>
     15 <div id="noneditable">Text</div>
     16 
     17 <div id="source">Some <b>Bold</b> Text</div>
     18 <script>
     19 
     20 const includeCommonAncestor = SpecialPowers.getBoolPref(
     21  "dom.serializer.includeCommonAncestor.enabled"
     22 );
     23 const expectedText = "Some Bold Text";
     24 const expectedHTML = `${includeCommonAncestor ? "<div id=\"source\">" : ""}` +
     25                     `Some <b>Bold</b> Text` +
     26                     `${includeCommonAncestor ? "</div>" : ""}`;
     27 
     28 const htmlPrefix = navigator.platform.includes("Win")
     29  ? "<html><body>\n<!--StartFragment-->"
     30  : "";
     31 const htmlPostfix = navigator.platform.includes("Win")
     32  ? "<!--EndFragment-->\n</body>\n</html>"
     33  : "";
     34 
     35 add_task(async function test_paste_formatted() {
     36  window.getSelection().selectAllChildren(document.getElementById("source"));
     37  synthesizeKey("c", { accelKey: true });
     38 
     39  function doKey(element, withShiftKey)
     40  {
     41    let inputEventPromise = new Promise(resolve => {
     42      element.addEventListener("input", event => {
     43        is(event.inputType, "insertFromPaste", "correct inputType");
     44        resolve();
     45      }, { once: true });
     46    });
     47    synthesizeKey("v", { accelKey: true, shiftKey: withShiftKey });
     48    return inputEventPromise;
     49  }
     50 
     51  function cancelEvent(event) {
     52    event.preventDefault();
     53  }
     54 
     55  // Paste into input and textarea
     56  for (let fieldid of ["input", "textarea"]) {
     57    const field = document.getElementById(fieldid);
     58    field.focus();
     59 
     60    field.addEventListener("paste", cancelEvent);
     61    doKey(field, false);
     62    is(
     63      field.value,
     64      "",
     65      `Nothing should be pasted into <${field.tagName.toLowerCase()}> when paste event is canceled (shift key is not pressed)`
     66    );
     67 
     68    doKey(field, true);
     69    is(
     70      field.value,
     71      "",
     72      `Nothing should be pasted into <${field.tagName.toLowerCase()}> when paste event is canceled (shift key is pressed)`
     73    );
     74    field.removeEventListener("paste", cancelEvent);
     75 
     76    doKey(field, false);
     77    is(field.value, expectedText, "paste into " + fieldid);
     78 
     79    doKey(field, true);
     80    is(field.value, expectedText + expectedText, "paste unformatted into " + field);
     81  }
     82 
     83  const selection = window.getSelection();
     84 
     85  const editable = document.getElementById("editable");
     86  const innerHTMLBeforeTest = editable.innerHTML;
     87 
     88  (function test_pasteWithFormatIntoEditableArea() {
     89    selection.selectAllChildren(editable);
     90    selection.collapseToStart();
     91    editable.addEventListener("paste", cancelEvent);
     92    doKey(editable, false);
     93    is(
     94      editable.innerHTML,
     95      "",
     96      "test_pasteWithFormatIntoEditableArea: Nothing should be pasted when paste event is canceled"
     97    );
     98    editable.removeEventListener("paste", cancelEvent);
     99 
    100    doKey(editable, false);
    101    is(
    102      editable.innerHTML,
    103      expectedHTML,
    104      "test_pasteWithFormatIntoEditableArea: Pasting with format should work as expected"
    105    );
    106    editable.innerHTML = innerHTMLBeforeTest;
    107  }());
    108 
    109  (function test_pasteWithoutFormatIntoEditableArea() {
    110    selection.selectAllChildren(editable);
    111    selection.collapseToEnd();
    112    doKey(editable, true);
    113    is(
    114      editable.innerHTML,
    115      expectedText,
    116      "test_pasteWithoutFormatIntoEditableArea: Pasting without format should work as expected",
    117    );
    118    editable.innerHTML = innerHTMLBeforeTest;
    119  })();
    120 
    121  (function test_pasteWithFormatIntoEditableAreaWhenHTMLEditorIsInReadonlyMode() {
    122    getEditor().flags |= SpecialPowers.Ci.nsIEditor.eEditorReadonlyMask;
    123    selection.selectAllChildren(editable);
    124    selection.collapseToStart();
    125    let beforeInputEvents = [];
    126    function onBeforeInput(aEvent) {
    127      beforeInputEvents.push(aEvent);
    128    }
    129    editable.addEventListener("beforeinput", onBeforeInput);
    130    doKey(editable, false);
    131    const description = "test_pasteWithFormatIntoEditableAreaWhenHTMLEditorIsInReadonlyMode";
    132    is(
    133      editable.innerHTML,
    134      innerHTMLBeforeTest,
    135      `${description}: Pasting with format should not work`
    136    );
    137    is(
    138      beforeInputEvents.length,
    139      0,
    140      `${description}: Pasting with format should not cause "beforeinput", but fired "${
    141        beforeInputEvents[0]?.inputType
    142      }"`
    143    );
    144    editable.removeEventListener("beforeinput", onBeforeInput);
    145    editable.innerHTML = innerHTMLBeforeTest;
    146    getEditor().flags &= ~SpecialPowers.Ci.nsIEditor.eEditorReadonlyMask;
    147  })();
    148 
    149  (function test_pasteWithoutFormatIntoEditableAreaWhenHTMLEditorIsInReadonlyMode() {
    150    getEditor().flags |= SpecialPowers.Ci.nsIEditor.eEditorReadonlyMask;
    151    selection.selectAllChildren(editable);
    152    selection.collapseToStart();
    153    let beforeInputEvents = [];
    154    function onBeforeInput(aEvent) {
    155      beforeInputEvents.push(aEvent);
    156    }
    157    editable.addEventListener("beforeinput", onBeforeInput);
    158    doKey(editable, false);
    159    const description = "test_pasteWithoutFormatIntoEditableAreaWhenHTMLEditorIsInReadonlyMode";
    160    is(
    161      editable.innerHTML,
    162      innerHTMLBeforeTest,
    163      `${description}: Pasting with format should not work`
    164    );
    165    is(
    166      beforeInputEvents.length,
    167      0,
    168      `${description}: Pasting with format should not cause "beforeinput", but fired "${
    169        beforeInputEvents[0]?.inputType
    170      }"`
    171    );
    172    editable.removeEventListener("beforeinput", onBeforeInput);
    173    editable.innerHTML = innerHTMLBeforeTest;
    174    getEditor().flags &= ~SpecialPowers.Ci.nsIEditor.eEditorReadonlyMask;
    175  })();
    176 
    177  let noneditable = document.getElementById("noneditable");
    178  selection.selectAllChildren(noneditable);
    179  selection.collapseToStart();
    180 
    181  function getPasteResult() {
    182    return new Promise(resolve => {
    183      noneditable.addEventListener("paste", event => {
    184        resolve({
    185          text: event.clipboardData.getData("text/plain"),
    186          html: event.clipboardData.getData("text/html"),
    187        });
    188      }, { once: true});
    189    });
    190  }
    191 
    192  // Normal paste into non-editable area
    193  let pastePromise = getPasteResult();
    194  doKey(noneditable, false);
    195  is(noneditable.innerHTML, "Text", "paste into non-editable");
    196 
    197  let result = await pastePromise;
    198  is(result.text, expectedText, "paste text into non-editable");
    199  is(result.html,
    200     htmlPrefix + expectedHTML + htmlPostfix,
    201     "paste html into non-editable");
    202 
    203  // Unformatted paste into non-editable area
    204  pastePromise = getPasteResult();
    205  doKey(noneditable, true);
    206  is(noneditable.innerHTML, "Text", "paste unformatted into non-editable");
    207 
    208  result = await pastePromise;
    209  is(result.text, expectedText, "paste unformatted text into non-editable");
    210  // Formatted HTML text should not exist when pasting unformatted.
    211  is(result.html, "", "paste unformatted html into non-editable");
    212 });
    213 
    214 function getEditor() {
    215  const editingSession = SpecialPowers.wrap(window).docShell.editingSession;
    216  return editingSession.getEditorForWindow(window);
    217 }
    218 </script>
    219 </body>