Skip to content

Commit

Permalink
Add do/undo/redo tests for list and blockquotes. Fix issues they unco…
Browse files Browse the repository at this point in the history
…vered.
  • Loading branch information
stevengharris committed Jun 25, 2024
1 parent b200b4a commit 320830d
Show file tree
Hide file tree
Showing 4 changed files with 384 additions and 11 deletions.
18 changes: 7 additions & 11 deletions MarkupEditor/Resources/markup.js
Original file line number Diff line number Diff line change
Expand Up @@ -2850,10 +2850,10 @@ const _undoPasteHTML = function(undoerData) {
if (_isEmptyPlaceholder(topLevelNode)) {
topLevelNode.replaceWith(newEmptyElement);
} else {
if (topLevelNode.nextSibling) { // We are at the end of the document
if (topLevelNode.nextSibling) {
topLevelNode.parentNode.insertBefore(newEmptyElement, topLevelNode);
} else {
topLevelNode.parentNode.insertBefore(newEmptyElement, null);
} else { // We are at the end of the document
_findContentEditable(topLevelNode).insertBefore(newEmptyElement, null);
};
};
newRange.setStart(newEmptyElement, 0);
Expand Down Expand Up @@ -2970,10 +2970,7 @@ const _deleteRange = function(range, rootName) {
endOffset = startOffset;
};
} else if (trailingWasDeleted) {
//WAS:
endLocation = _firstSelectableLocationBefore(trailingNode) ?? _firstSelectableLocationAfter(trailingNode);
//NOW:
//endLocation = _firstSelectableLocationAfter(trailingNode) ?? _firstSelectableLocationBefore(trailingNode);
if (endLocation) {
endContainer = endLocation.container;
endOffset = endLocation.offset;
Expand Down Expand Up @@ -3018,9 +3015,9 @@ const _deleteRange = function(range, rootName) {
const topLevelNode = _topLevelElementContaining(trailingNode);
if (topLevelNode && _isEmpty(topLevelNode)) {
// We are left with an empty top-level node (like a table or p), so delete it.
// If it's a table, then we treat it specially, because the selection was inside
// of the table and should be left before it.
if (_isTableElement(topLevelNode)) {
// If it's a table, list, or blockquote, then we treat it specially, because
// the selection was inside of the topLevelElement and should be left before it.
if (_isTableElement(topLevelNode) || _isListElement(topLevelNode) || _isBlockquoteElement(topLevelNode)) {
_deleteAndResetSelection(topLevelNode, 'BEFORE');
} else {
_deleteAndResetSelection(topLevelNode, 'AFTER');
Expand Down Expand Up @@ -7546,8 +7543,7 @@ const _monitorEnterTags = _listTags.concat(['TABLE', 'BLOCKQUOTE']);

const _monitorIndentTags = _listTags.concat(['BLOCKQUOTE']); // Tags we monitor for Tab or Ctrl+]

//TODO: Include BLOCKQUOTE?
const _topLevelTags = _paragraphStyleTags.concat(_listTags.concat(['TABLE', 'BLOCKQUOTE'])); // Allowed top-level tags within editor
const _topLevelTags = _paragraphStyleTags.concat(_listTags.concat(['TABLE', 'BLOCKQUOTE'])); // Allowed top-level tags w/in editor

const _voidTags = ['BR', 'IMG', 'AREA', 'COL', 'EMBED', 'HR', 'INPUT', 'LINK', 'META', 'PARAM'] // Tags that are self-closing

Expand Down
123 changes: 123 additions & 0 deletions MarkupEditorTests/BasicTests/BasicTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2916,6 +2916,7 @@ class BasicTests: XCTestCase, MarkupDelegate {
endOffset: 0,
pasteString: "<h1>A title</h1><h2>A subtitle</h2><p>A paragraph.</p>"
),
// Tables
HtmlTest(
description: "TABLE in P - Paste a table at a blank paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p><p id=\"blank\"><br></p>",
Expand Down Expand Up @@ -2976,6 +2977,128 @@ class BasicTests: XCTestCase, MarkupDelegate {
endOffset: 0,
pasteString: "<p>Hello world</p>"
),
// Lists
HtmlTest(
description: "OL in P - Paste a list at a blank paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p><p id=\"blank\"><br></p>",
endHtml: "<p id=\"p\">This is just a simple paragraph.</p><ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol>",
startId: "blank", // Select "|<br>"
startOffset: 0,
endId: "blank",
endOffset: 0,
pasteString: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol>"
),
HtmlTest(
description: "OL in P - Paste a list at beginning of a paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p>",
endHtml: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol><p id=\"p\">This is just a simple paragraph.</p>",
startId: "p", // Select "|This"
startOffset: 0,
endId: "p",
endOffset: 0,
pasteString: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol>"
),
HtmlTest(
description: "OL in P - Paste a list at end of a paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p>",
endHtml: "<p id=\"p\">This is just a simple paragraph.</p><ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol>",
startId: "p", // Select "paragraph.|"
startOffset: 32,
endId: "p",
endOffset: 32,
pasteString: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol>"
),
HtmlTest(
description: "OL in P - Paste a list in text of a paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p>",
endHtml: "<p id=\"p\">This is ju</p><ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol><p>st a simple paragraph.</p>",
startId: "p", // Select "ju|st"
startOffset: 10,
endId: "p",
endOffset: 10,
pasteString: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol>"
),
HtmlTest(
description: "OL in P - Paste a list in formatted text of a paragraph",
startHtml: "<p id=\"p\">This is <b id=\"b\">just</b> a simple paragraph.</p>",
endHtml: "<p id=\"p\">This is <b id=\"b\">ju</b></p><ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol><p><b>st</b> a simple paragraph.</p>",
startId: "b", // Select "ju|st"
startOffset: 2,
endId: "b",
endOffset: 2,
pasteString: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol>"
),
HtmlTest(
description: "P in P - Paste a simple paragraph at a blank line after a list",
startHtml: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol><p id=\"blank\"><br></p>",
endHtml: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol><p>Hello world</p>",
startId: "blank", // Select "|<br>"
startOffset: 0,
endId: "blank",
endOffset: 0,
pasteString: "<p>Hello world</p>"
),
// Blockquotes
HtmlTest(
description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE at a blank paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p><p id=\"blank\"><br></p>",
endHtml: "<p id=\"p\">This is just a simple paragraph.</p><blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote>",
startId: "blank", // Select "|<br>"
startOffset: 0,
endId: "blank",
endOffset: 0,
pasteString: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote>"
),
HtmlTest(
description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE at beginning of a paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p>",
endHtml: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote><p id=\"p\">This is just a simple paragraph.</p>",
startId: "p", // Select "|This"
startOffset: 0,
endId: "p",
endOffset: 0,
pasteString: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote>"
),
HtmlTest(
description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE at end of a paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p>",
endHtml: "<p id=\"p\">This is just a simple paragraph.</p><blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote>",
startId: "p", // Select "paragraph.|"
startOffset: 32,
endId: "p",
endOffset: 32,
pasteString: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote>"
),
HtmlTest(
description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE in text of a paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p>",
endHtml: "<p id=\"p\">This is ju</p><blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote><p>st a simple paragraph.</p>",
startId: "p", // Select "ju|st"
startOffset: 10,
endId: "p",
endOffset: 10,
pasteString: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote>"
),
HtmlTest(
description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE in formatted text of a paragraph",
startHtml: "<p id=\"p\">This is <b id=\"b\">just</b> a simple paragraph.</p>",
endHtml: "<p id=\"p\">This is <b id=\"b\">ju</b></p><blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote><p><b>st</b> a simple paragraph.</p>",
startId: "b", // Select "ju|st"
startOffset: 2,
endId: "b",
endOffset: 2,
pasteString: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote>"
),
HtmlTest(
description: "P in P - Paste a simple paragraph at a blank line after a BLOCKQUOTE",
startHtml: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote><p id=\"blank\"><br></p>",
endHtml: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote><p>Hello world</p>",
startId: "blank", // Select "|<br>"
startOffset: 0,
endId: "blank",
endOffset: 0,
pasteString: "<p>Hello world</p>"
),
]
for test in htmlTests {
test.printDescription()
Expand Down
127 changes: 127 additions & 0 deletions MarkupEditorTests/RedoTests/RedoTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2859,6 +2859,7 @@ class RedoTests: XCTestCase, MarkupDelegate {
endOffset: 0,
pasteString: "<h1>A title</h1><h2>A subtitle</h2><p>A paragraph.</p>"
),
// Tables
HtmlTest(
description: "TABLE in P - Paste a table at a blank paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p><p id=\"blank\"><br></p>",
Expand Down Expand Up @@ -2921,6 +2922,132 @@ class RedoTests: XCTestCase, MarkupDelegate {
endOffset: 0,
pasteString: "<p>Hello world</p>"
),
// Lists
HtmlTest(
description: "OL in P - Paste a list at a blank paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p><p id=\"blank\"><br></p>",
endHtml: "<p id=\"p\">This is just a simple paragraph.</p><ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol>",
undoHtml: "<p id=\"p\">This is just a simple paragraph.</p><p><br></p>",
startId: "blank", // Select "|<br>"
startOffset: 0,
endId: "blank",
endOffset: 0,
pasteString: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol>"
),
HtmlTest(
description: "OL in P - Paste a list at beginning of a paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p>",
endHtml: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol><p id=\"p\">This is just a simple paragraph.</p>",
startId: "p", // Select "|This"
startOffset: 0,
endId: "p",
endOffset: 0,
pasteString: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol>"
),
HtmlTest(
description: "OL in P - Paste a list at end of a paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p>",
endHtml: "<p id=\"p\">This is just a simple paragraph.</p><ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol>",
startId: "p", // Select "paragraph.|"
startOffset: 32,
endId: "p",
endOffset: 32,
pasteString: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol>"
),
HtmlTest(
description: "OL in P - Paste a list in text of a paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p>",
endHtml: "<p id=\"p\">This is ju</p><ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol><p>st a simple paragraph.</p>",
startId: "p", // Select "ju|st"
startOffset: 10,
endId: "p",
endOffset: 10,
pasteString: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol>"
),
HtmlTest(
description: "OL in P - Paste a list in formatted text of a paragraph",
startHtml: "<p id=\"p\">This is <b id=\"b\">just</b> a simple paragraph.</p>",
endHtml: "<p id=\"p\">This is <b id=\"b\">ju</b></p><ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol><p><b>st</b> a simple paragraph.</p>",
startId: "b", // Select "ju|st"
startOffset: 2,
endId: "b",
endOffset: 2,
pasteString: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol>"
),
HtmlTest(
description: "P in P - Paste a simple paragraph at a blank line after a list",
startHtml: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol><p id=\"blank\"><br></p>",
endHtml: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol><p>Hello world</p>",
undoHtml: "<ol><li><p>Item 1</p></li><li><p>Item 2</p></li></ol><p><br></p>",
startId: "blank", // Select "|<br>"
startOffset: 0,
endId: "blank",
endOffset: 0,
pasteString: "<p>Hello world</p>"
),
// Blockquotes
HtmlTest(
description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE at a blank paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p><p id=\"blank\"><br></p>",
endHtml: "<p id=\"p\">This is just a simple paragraph.</p><blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote>",
undoHtml: "<p id=\"p\">This is just a simple paragraph.</p><p><br></p>",
startId: "blank", // Select "|<br>"
startOffset: 0,
endId: "blank",
endOffset: 0,
pasteString: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote>"
),
HtmlTest(
description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE at beginning of a paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p>",
endHtml: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote><p id=\"p\">This is just a simple paragraph.</p>",
startId: "p", // Select "|This"
startOffset: 0,
endId: "p",
endOffset: 0,
pasteString: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote>"
),
HtmlTest(
description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE at end of a paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p>",
endHtml: "<p id=\"p\">This is just a simple paragraph.</p><blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote>",
startId: "p", // Select "paragraph.|"
startOffset: 32,
endId: "p",
endOffset: 32,
pasteString: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote>"
),
HtmlTest(
description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE in text of a paragraph",
startHtml: "<p id=\"p\">This is just a simple paragraph.</p>",
endHtml: "<p id=\"p\">This is ju</p><blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote><p>st a simple paragraph.</p>",
startId: "p", // Select "ju|st"
startOffset: 10,
endId: "p",
endOffset: 10,
pasteString: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote>"
),
HtmlTest(
description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE in formatted text of a paragraph",
startHtml: "<p id=\"p\">This is <b id=\"b\">just</b> a simple paragraph.</p>",
endHtml: "<p id=\"p\">This is <b id=\"b\">ju</b></p><blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote><p><b>st</b> a simple paragraph.</p>",
startId: "b", // Select "ju|st"
startOffset: 2,
endId: "b",
endOffset: 2,
pasteString: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote>"
),
HtmlTest(
description: "P in P - Paste a simple paragraph at a blank line after a BLOCKQUOTE",
startHtml: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote><p id=\"blank\"><br></p>",
endHtml: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote><p>Hello world</p>",
undoHtml: "<blockquote><blockquote><h5>Double-indented.</h5></blockquote></blockquote><p><br></p>",
startId: "blank", // Select "|<br>"
startOffset: 0,
endId: "blank",
endOffset: 0,
pasteString: "<p>Hello world</p>"
),
]
for test in htmlTests {
test.printDescription()
Expand Down
Loading

0 comments on commit 320830d

Please sign in to comment.