Bug 1478564 - part 0: Add automated tests for TextEditRules::HandleNewLines() r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 26 Jul 2018 22:27:47 +0900
changeset 823373 5999f07ff608964c784c18709af9f02b0e0d777a
parent 823333 8f2f847b2f9dc5643eeb9935d603a3b30686f972
child 823374 6adcf225044307e30da5ddaf43f1d7a2e71680df
child 823400 d9eab725ecf0c3261a8da35d2bcc3b5d84f95b49
push id117649
push usermasayuki@d-toybox.com
push dateFri, 27 Jul 2018 04:13:22 +0000
reviewersm_kato
bugs1478564
milestone63.0a1
Bug 1478564 - part 0: Add automated tests for TextEditRules::HandleNewLines() r?m_kato MozReview-Commit-ID: L55zBuflDBP
editor/libeditor/tests/mochitest.ini
editor/libeditor/tests/test_handle_new_lines.html
--- a/editor/libeditor/tests/mochitest.ini
+++ b/editor/libeditor/tests/mochitest.ini
@@ -266,16 +266,18 @@ subsuite = clipboard
 [test_composition_event_created_in_chrome.html]
 [test_contenteditable_focus.html]
 [test_documentCharacterSet.html]
 [test_dom_input_event_on_htmleditor.html]
 skip-if = toolkit == 'android' # bug 1054087
 [test_dom_input_event_on_texteditor.html]
 [test_dragdrop.html]
 skip-if = os == 'android'
+[test_handle_new_lines.html]
+subsuite = clipboard
 [test_inline_style_cache.html]
 [test_inlineTableEditing.html]
 [test_insertParagraph_in_inline_editing_host.html]
 [test_keypress_untrusted_event.html]
 [test_middle_click_paste.html]
 subsuite = clipboard
 [test_objectResizing.html]
 [test_root_element_replacement.html]
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/tests/test_handle_new_lines.html
@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Test for TextEditRules::HandlingNewLines()</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none;">
+
+</div>
+
+<div id="container"></div>
+
+<textarea id="toCopyPlaintext" style="display: none;"></textarea>
+
+<pre id="test">
+
+<script class="testbody" type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+async function copyPlaintext(aText) {
+  return new Promise(resolve => {
+    SimpleTest.waitForClipboard(
+      () => { return true; }, // because of mismatch of linebreakers
+      () => {
+        let element = document.getElementById("toCopyPlaintext");
+        element.style.display = "block";
+        element.focus();
+        element.value = aText;
+        synthesizeKey("a", {accelKey: true});
+        synthesizeKey("c", {accelKey: true});
+      },
+      () => {
+        ok(true, `Succeeded to copy "${aText.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/ /g, "\u00A0")}" to clipboard`);
+        let element = document.getElementById("toCopyPlaintext");
+        element.style.display = "none";
+        resolve();
+      },
+      () => {
+        SimpleTest.finish();
+      });
+  });
+}
+
+async function doTests() {
+  // nsIPlaintextEditor::eNewlinesPasteIntact (0):
+  //   only remove the leading and trailing newlines.
+  // nsIPlaintextEditor::eNewlinesPasteToFirst (1) or any other value:
+  //   remove the first newline and all characters following it.
+  // nsIPlaintextEditor::eNewlinesReplaceWithSpaces (2, Firefox default):
+  //   replace newlines with spaces.
+  // nsIPlaintextEditor::eNewlinesStrip (3):
+  //   remove newlines from the string.
+  // nsIPlaintextEditor::eNewlinesReplaceWithCommas (4, Thunderbird default):
+  //   replace newlines with commas.
+  // nsIPlaintextEditor::eNewlinesStripSurroundingWhitespace (5):
+  //   collapse newlines and surrounding whitespace characters and
+  //   remove them from the string.
+
+  // value: setting or pasting text.
+  // expected: array of final values for each above pref value.
+  //   setValue: expected result when HTMLInputElement.value is set to the value.
+  //   pasteValue: expected result when pasting the value from clipboard.
+  //
+  // Note that HTMLInputElement strips both \r and \n.  Therefore, each expected
+  // result is different from pasting the value.
+  const kTests = [
+    { value: "\nabc\ndef\n",
+      expected: [{ setValue: "abcdef", pasteValue: "abc\ndef" },
+                 { setValue: "abcdef", pasteValue: "abc" },
+                 { setValue: "abcdef", pasteValue: " abc def" },
+                 { setValue: "abcdef", pasteValue: "abcdef" },
+                 { setValue: "abcdef", pasteValue: "abc,def" },
+                 { setValue: "abcdef", pasteValue: "abcdef" }],
+    },
+    { value: "\n   abc   \n   def   \n",
+      expected: [{ setValue: "   abc      def   ", pasteValue: "   abc   \n   def   " },
+                 { setValue: "   abc      def   ", pasteValue: "   abc   " },
+                 { setValue: "   abc      def   ", pasteValue: "    abc       def   " },
+                 { setValue: "   abc      def   ", pasteValue: "   abc      def   " },
+                 { setValue: "   abc      def   ", pasteValue: "   abc   ,   def   " },
+                 { setValue: "   abc      def   ", pasteValue: "abcdef" }],
+    },
+    { value: "   abc   \n   def   ",
+      expected: [{ setValue: "   abc      def   ", pasteValue: "   abc   \n   def   " },
+                 { setValue: "   abc      def   ", pasteValue: "   abc   " },
+                 { setValue: "   abc      def   ", pasteValue: "   abc       def   " },
+                 { setValue: "   abc      def   ", pasteValue: "   abc      def   " },
+                 { setValue: "   abc      def   ", pasteValue: "   abc   ,   def   " },
+                 { setValue: "   abc      def   ", pasteValue: "   abcdef   " }],
+    },
+  ];
+
+  let container = document.getElementById("container");
+  for (let i = 0; i <= 5; i++) {
+    await SpecialPowers.pushPrefEnv({"set": [["editor.singleLine.pasteNewlines", i]]});
+    container.innerHTML = `<input id="input${i}" type="text">`;
+    let input = document.getElementById(`input${i}`);
+    input.focus();
+    let editor = SpecialPowers.wrap(input).editor;
+    for (const kLineBreaker of ["\n", "\r", "\r\n"]) {
+      for (let kTest of kTests) {
+        let value = kTest.value.replace(/\n/g, kLineBreaker);
+        input.value = value;
+        is(editor.rootElement.firstChild.wholeText, kTest.expected[i].setValue,
+           `Setting value to "${value.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/ /g, "\u00A0")}" when pref is ${i}`);
+        input.value = "";
+
+        await copyPlaintext(value);
+        input.focus();
+        synthesizeKey("v", {accelKey: true});
+        is(editor.rootElement.firstChild.wholeText, kTest.expected[i].pasteValue,
+           `Pasting "${value.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/ /g, "\u00A0")}" when pref is ${i}`);
+        input.value = "";
+      }
+    }
+  }
+
+  SimpleTest.finish();
+}
+
+SimpleTest.waitForFocus(doTests);
+</script>
+</pre>
+</body>
+</html>