Skip to content

Commit

Permalink
part 0: Add automated tests of preserving selection while handling so…
Browse files Browse the repository at this point in the history
…me commands

The following patches touch the logic to restore selection after handling
commands.  However, it seems that they are not tested because I found some
regressions by manual testing, but didn't cause orange on tryserver.

`outdent-preserving-selection.tentative.html` causes a crash due to the
`MOZ_ASSERTION` in `HTMLEditor::HandleOutdentAtSelectionInternal`.  It means
that I misunderstand the logic and had put the assertion.  I should fix it
later with reading the complicated code again.  For now, I just change it
to `NS_WARNING_ASSERTION` instead.

And also `test_cmd_absPos.html` is the first test to check toggling `position`
between `static` and `absolute`.  Therefore, it detects wrong `MOZ_ASSERT`s
which test whether `EditActionData` or `TopLevelEditSubActionData` is created
or not **before** they create them by themselves.  So, this patch removes the
wrong assertions.

Differential Revision: https://phabricator.services.mozilla.com/D152962

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1774704
gecko-commit: d554ca7850eb362a0482c9f4c19caf288e65efb1
gecko-reviewers: m_kato
  • Loading branch information
masayuki-nakano authored and moz-wptsync-bot committed Aug 4, 2022
1 parent d9abd65 commit 44d0967
Show file tree
Hide file tree
Showing 5 changed files with 734 additions and 0 deletions.
136 changes: 136 additions & 0 deletions editing/other/formatblock-preserving-selection.tentative.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<!doctype html>
<html>
<head>
<meta chareset="utf-8">
<meta name="timeout" content="long">
<meta name="variant" content="?styleWithCSS=false&block=address">
<meta name="variant" content="?styleWithCSS=false&block=article">
<meta name="variant" content="?styleWithCSS=false&block=blockquote">
<meta name="variant" content="?styleWithCSS=false&block=dd">
<meta name="variant" content="?styleWithCSS=false&block=div">
<meta name="variant" content="?styleWithCSS=false&block=dt">
<meta name="variant" content="?styleWithCSS=false&block=h1">
<meta name="variant" content="?styleWithCSS=false&block=li">
<meta name="variant" content="?styleWithCSS=false&block=pre">
<meta name="variant" content="?styleWithCSS=true&block=address">
<meta name="variant" content="?styleWithCSS=true&block=article">
<meta name="variant" content="?styleWithCSS=true&block=blockquote">
<meta name="variant" content="?styleWithCSS=true&block=dd">
<meta name="variant" content="?styleWithCSS=true&block=div">
<meta name="variant" content="?styleWithCSS=true&block=dt">
<meta name="variant" content="?styleWithCSS=true&block=h1">
<meta name="variant" content="?styleWithCSS=true&block=li">
<meta name="variant" content="?styleWithCSS=true&block=pre">
<title>Test preserving selection after formatBlock</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="../include/editor-test-utils.js"></script>
</head>
<body>
<div contenteditable></div>
<script>
"use strict";

const editor = document.querySelector("div[contenteditable]");
const utils = new EditorTestUtils(editor);
const searchParams = new URLSearchParams(document.location.search);
const styleWithCSS = searchParams.get("styleWithCSS");
const block = searchParams.get("block");
document.execCommand("styleWithCSS", false, styleWithCSS);

// Note that it's not scope of this test how browsers to convert the selected
// content to a block.

// html: Initial HTML which will be set editor.innerHTML, it should contain
// selection range with a pair of "[" or "{" and "]" or "}".
// expectedSelectedString: After executing "outdent", compared with
// getSelection().toString().replace(/[ \n\r\t]+/g, "")
const tests = [
{
html: "a[b]c",
expectedSelectedString: "b",
},
{
html: "a[bc<br>de]f",
expectedSelectedString: "bcde",
},
{
html: "<div>a[b]c</div>",
expectedSelectedString: "b",
},
{
html: "<div>a[bc</div><div>de]f</div>",
expectedSelectedString: "bcde",
},
{
html: "<div>a[bc<br>de]f</div>",
expectedSelectedString: "bcde",
},
{
html: "<ul><li>a[b]c</li></ul>",
expectedSelectedString: "b",
},
{
html: "<ul><li>a[bc</li><li>de]f</li></ul>",
expectedSelectedString: "bcde",
},
{
html: "<ul><li>a[bc</li><li>de]f</li><li>ghi</li></ul>",
expectedSelectedString: "bcde",
},
{
html: "<ul><li>abc</li><li>d[ef</li><li>gh]i</li></ul>",
expectedSelectedString: "efgh",
},
{
html: "<ul><li>abc</li><li>d[ef</li></ul>" +
"<div>gh]i</div>",
expectedSelectedString: "efgh",
},
{
html: "<div>a[bc</div>" +
"<ul><li>de]f</li><li>ghi</li></ul>",
expectedSelectedString: "bcde",
},
{
html: "<table><tr><td>a[b]c</td></tr></table>",
expectedSelectedString: "b",
},
{
html: "<table><tr><td>a[bc</td><td>de]f</td></tr></table>",
expectedSelectedString: "bcde",
},
{
html: "<table><tr><td>a[bc</td></tr><tr><td>de]f</td></tr></table>",
expectedSelectedString: "bcde",
},
{
html: "<div>a[bc</div>" +
"<table><tr><td>de]f</td></tr></table>",
expectedSelectedString: "bcde",
},
{
html: "<table><tr><td>a[bc</td></tr></table>" +
"<div>de]f</div>",
expectedSelectedString: "bcde",
},
];

for (const t of tests) {
test(() => {
utils.setupEditingHost(t.html);
document.execCommand("formatblock", false, block);
assert_equals(
getSelection().toString().replace(/[ \n\r\t]+/g, ""),
t.expectedSelectedString,
`Result: ${editor.innerHTML}`
);
}, `Preserve selection after formatBlock with ${block} at ${t.html}`);
}

</script>
</body>
</html>
103 changes: 103 additions & 0 deletions editing/other/indent-preserving-selection.tentative.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<!doctype html>
<html>
<head>
<meta chareset="utf-8">
<meta name="timeout" content="long">
<meta name="variant" content="?styleWithCSS=false">
<meta name="variant" content="?styleWithCSS=true">
<title>Test preserving selection after indent</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="../include/editor-test-utils.js"></script>
</head>
<body>
<div contenteditable></div>
<script>
"use strict";

const editor = document.querySelector("div[contenteditable]");
const utils = new EditorTestUtils(editor);
const styleWithCSS =
new URLSearchParams(document.location.search).get("styleWithCSS");
document.execCommand("styleWithCSS", false, styleWithCSS);

// Note that it's not scope of this test how browsers to indent the selected
// content.

// html: Initial HTML which will be set editor.innerHTML, it should contain
// selection range with a pair of "[" or "{" and "]" or "}".
// expectedSelectedString: After executing "indent", compared with
// getSelection().toString().replace(/[ \n\r]+/g, "")
const tests = [
{
html: "<div>a[b]c</div>",
expectedSelectedString: "b",
},
{
html: "<div>a[bc</div><div>de]f</div>",
expectedSelectedString: "bcde",
},
{
html: "<ul><li>a[b]c</li></ul>",
expectedSelectedString: "b",
},
{
html: "<ul><li>a[bc</li><li>de]f</li></ul>",
expectedSelectedString: "bcde",
},
{
html: "<div>a[bc</div>" +
"<ul><li>de]f</li></ul>",
expectedSelectedString: "bcde",
},
{
html: "<ul><li>a[bc</li></ul>" +
"<ul><li>de]f</li></ul>",
expectedSelectedString: "bcde",
},
{
html: "<ul><li>abc</li><li>d[ef</li></ul>" +
"<ul><li>gh]i</li></ul>",
expectedSelectedString: "efgh",
},
{
html: "<ul><li>abc</li><li>d[ef</li></ul>" +
"<ul><li>gh]i</li><li>jkl</li></ul>",
expectedSelectedString: "efgh",
},
{
html: "<ul><ul><li>a[bc</li></ul><li>de]f</li></ul>",
expectedSelectedString: "bcde",
},
{
html: "<ol><ul><li>a[bc</li></ul><li>de]f</li></ol>",
expectedSelectedString: "bcde",
},
{
html: "<ul><li>a[bc</li><ul><li>de]f</li></ul></ul>",
expectedSelectedString: "bcde",
},
{
html: "<ol><li>a[bc</li><ul><li>de]f</li></ul></ol>",
expectedSelectedString: "bcde",
},
];

for (const t of tests) {
test(() => {
utils.setupEditingHost(t.html);
document.execCommand("indent");
assert_equals(
getSelection().toString().replace(/[ \n\r]+/g, ""),
t.expectedSelectedString,
`Result: ${editor.innerHTML}`
);
}, `Preserve selection after indent at ${t.html}`);
}

</script>
</body>
</html>
155 changes: 155 additions & 0 deletions editing/other/insert-list-preserving-selection.tentative.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<!doctype html>
<html>
<head>
<meta chareset="utf-8">
<meta name="timeout" content="long">
<meta name="variant" content="?styleWithCSS=false&command=insertOrderedList">
<meta name="variant" content="?styleWithCSS=false&command=insertUnorderedList">
<meta name="variant" content="?styleWithCSS=true&command=insertOrderedList">
<meta name="variant" content="?styleWithCSS=true&command=insertUnorderedList">
<title>Test preserving selection after insert*List</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="../include/editor-test-utils.js"></script>
</head>
<body>
<div contenteditable></div>
<script>
"use strict";

const editor = document.querySelector("div[contenteditable]");
const utils = new EditorTestUtils(editor);
const searchParams = new URLSearchParams(document.location.search);
const styleWithCSS = searchParams.get("styleWithCSS");
const command = searchParams.get("command");
document.execCommand("styleWithCSS", false, styleWithCSS);

// Note that it's not scope of this test how browsers to convert the selected
// content to a list.

// html: Initial HTML which will be set editor.innerHTML, it should contain
// selection range with a pair of "[" or "{" and "]" or "}".
// expectedSelectedString: After executing "outdent", compared with
// getSelection().toString().replace(/[ \n\r\t]+/g, "")
const tests = [
{
html: "<div>a[b]c</div>",
expectedSelectedString: "b",
},
{
html: "<div>a[bc</div><div>de]f</div>",
expectedSelectedString: "bcde",
},
{
html: "<div>a[bc<br>de]f</div>",
expectedSelectedString: "bcde",
},
{
html: "<ul><li>a[b]c</li></ul>",
expectedSelectedString: "b",
},
{
html: "<ul><li>a[bc</li><li>de]f</li></ul>",
expectedSelectedString: "bcde",
},
{
html: "<ul><li>a[bc</li><li>de]f</li><li>ghi</li></ul>",
expectedSelectedString: "bcde",
},
{
html: "<ul><li>abc</li><li>d[ef</li><li>gh]i</li></ul>",
expectedSelectedString: "efgh",
},
{
html: "<ol><li>a[b]c</li></ol>",
expectedSelectedString: "b",
},
{
html: "<ol><li>a[bc</li><li>de]f</li></ol>",
expectedSelectedString: "bcde",
},
{
html: "<ol><li>a[bc</li><li>de]f</li><li>ghi</li></ol>",
expectedSelectedString: "bcde",
},
{
html: "<ol><li>abc</li><li>d[ef</li><li>gh]i</li></ol>",
expectedSelectedString: "efgh",
},
{
html: "<ul><li>a[bc</li></ul>" +
"<ul><li>de]f</li></ul>",
expectedSelectedString: "bcde",
},
{
html: "<ol><li>a[bc</li></ol>" +
"<ul><li>de]f</li></ul>",
expectedSelectedString: "bcde",
},
{
html: "<ul><li>a[bc</li></ul>" +
"<ol><li>de]f</li></ol>",
expectedSelectedString: "bcde",
},
{
html: "<div>a[bc</div>" +
"<ul><li>de]f</li><li>ghi</li></ul>",
expectedSelectedString: "bcde",
},
{
html: "<ul><li>abc</li><li>d[ef</li></ul>" +
"<div>gh]i</div>",
expectedSelectedString: "efgh",
},
{
html: "<div>a[bc</div>" +
"<ol><li>de]f</li><li>ghi</li></ol>",
expectedSelectedString: "bcde",
},
{
html: "<ol><li>abc</li><li>d[ef</li></ol>" +
"<div>gh]i</div>",
expectedSelectedString: "efgh",
},
{
html: "<table><tr><td>a[b]c</td></tr></table>",
expectedSelectedString: "b",
},
{
html: "<table><tr><td>a[bc</td><td>de]f</td></tr></table>",
expectedSelectedString: "bcde",
},
{
html: "<table><tr><td>a[bc</td></tr><tr><td>de]f</td></tr></table>",
expectedSelectedString: "bcde",
},
{
html: "<div>a[bc</div>" +
"<table><tr><td>de]f</td></tr></table>",
expectedSelectedString: "bcde",
},
{
html: "<table><tr><td>a[bc</td></tr></table>" +
"<div>de]f</div>",
expectedSelectedString: "bcde",
},
];

for (const t of tests) {
test(() => {
utils.setupEditingHost(t.html);
document.execCommand(command);
assert_equals(
getSelection().toString().replace(/[ \n\r\t]+/g, ""),
t.expectedSelectedString,
`Result: ${editor.innerHTML}`
);
}, `Preserve selection after ${command} at ${t.html}`);
}

</script>
</body>
</html>
Loading

0 comments on commit 44d0967

Please sign in to comment.