diff --git a/MarkupEditor/Resources/markup.js b/MarkupEditor/Resources/markup.js index 6124793..4940e62 100644 --- a/MarkupEditor/Resources/markup.js +++ b/MarkupEditor/Resources/markup.js @@ -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); @@ -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; @@ -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'); @@ -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 diff --git a/MarkupEditorTests/BasicTests/BasicTests.swift b/MarkupEditorTests/BasicTests/BasicTests.swift index 206e735..64d7fc6 100644 --- a/MarkupEditorTests/BasicTests/BasicTests.swift +++ b/MarkupEditorTests/BasicTests/BasicTests.swift @@ -2916,6 +2916,7 @@ class BasicTests: XCTestCase, MarkupDelegate { endOffset: 0, pasteString: "
A paragraph.
" ), + // Tables HtmlTest( description: "TABLE in P - Paste a table at a blank paragraph", startHtml: "This is just a simple paragraph.
Hello world
" ), + // Lists + HtmlTest( + description: "OL in P - Paste a list at a blank paragraph", + startHtml: "This is just a simple paragraph.
This is just a simple paragraph.
Item 1
Item 2
Item 1
Item 2
This is just a simple paragraph.
", + endHtml: "Item 1
Item 2
This is just a simple paragraph.
", + startId: "p", // Select "|This" + startOffset: 0, + endId: "p", + endOffset: 0, + pasteString: "Item 1
Item 2
This is just a simple paragraph.
", + endHtml: "This is just a simple paragraph.
Item 1
Item 2
Item 1
Item 2
This is just a simple paragraph.
", + endHtml: "This is ju
Item 1
Item 2
st a simple paragraph.
", + startId: "p", // Select "ju|st" + startOffset: 10, + endId: "p", + endOffset: 10, + pasteString: "Item 1
Item 2
This is just a simple paragraph.
", + endHtml: "This is ju
Item 1
Item 2
st a simple paragraph.
", + startId: "b", // Select "ju|st" + startOffset: 2, + endId: "b", + endOffset: 2, + pasteString: "Item 1
Item 2
Item 1
Item 2
Item 1
Item 2
Hello world
", + startId: "blank", // Select "|Hello world
" + ), + // Blockquotes + HtmlTest( + description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE at a blank paragraph", + startHtml: "This is just a simple paragraph.
This is just a simple paragraph.
", + startId: "blank", // Select "|Double-indented.
" + ), + HtmlTest( + description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE at beginning of a paragraph", + startHtml: "Double-indented.
This is just a simple paragraph.
", + endHtml: "Double-indented.
This is just a simple paragraph.
", + startId: "p", // Select "|This" + startOffset: 0, + endId: "p", + endOffset: 0, + pasteString: "" + ), + HtmlTest( + description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE at end of a paragraph", + startHtml: "Double-indented.
This is just a simple paragraph.
", + endHtml: "This is just a simple paragraph.
", + startId: "p", // Select "paragraph.|" + startOffset: 32, + endId: "p", + endOffset: 32, + pasteString: "Double-indented.
" + ), + HtmlTest( + description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE in text of a paragraph", + startHtml: "Double-indented.
This is just a simple paragraph.
", + endHtml: "This is ju
Double-indented.
st a simple paragraph.
", + startId: "p", // Select "ju|st" + startOffset: 10, + endId: "p", + endOffset: 10, + pasteString: "" + ), + HtmlTest( + description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE in formatted text of a paragraph", + startHtml: "Double-indented.
This is just a simple paragraph.
", + endHtml: "This is ju
Double-indented.
st a simple paragraph.
", + startId: "b", // Select "ju|st" + startOffset: 2, + endId: "b", + endOffset: 2, + pasteString: "" + ), + HtmlTest( + description: "P in P - Paste a simple paragraph at a blank line after a BLOCKQUOTE", + startHtml: "Double-indented.
Double-indented.
Double-indented.
Hello world
", + startId: "blank", // Select "|Hello world
" + ), ] for test in htmlTests { test.printDescription() diff --git a/MarkupEditorTests/RedoTests/RedoTests.swift b/MarkupEditorTests/RedoTests/RedoTests.swift index 041a14a..2488f1e 100644 --- a/MarkupEditorTests/RedoTests/RedoTests.swift +++ b/MarkupEditorTests/RedoTests/RedoTests.swift @@ -2859,6 +2859,7 @@ class RedoTests: XCTestCase, MarkupDelegate { endOffset: 0, pasteString: "A paragraph.
" ), + // Tables HtmlTest( description: "TABLE in P - Paste a table at a blank paragraph", startHtml: "This is just a simple paragraph.
Hello world
" ), + // Lists + HtmlTest( + description: "OL in P - Paste a list at a blank paragraph", + startHtml: "This is just a simple paragraph.
This is just a simple paragraph.
Item 1
Item 2
This is just a simple paragraph.
Item 1
Item 2
This is just a simple paragraph.
", + endHtml: "Item 1
Item 2
This is just a simple paragraph.
", + startId: "p", // Select "|This" + startOffset: 0, + endId: "p", + endOffset: 0, + pasteString: "Item 1
Item 2
This is just a simple paragraph.
", + endHtml: "This is just a simple paragraph.
Item 1
Item 2
Item 1
Item 2
This is just a simple paragraph.
", + endHtml: "This is ju
Item 1
Item 2
st a simple paragraph.
", + startId: "p", // Select "ju|st" + startOffset: 10, + endId: "p", + endOffset: 10, + pasteString: "Item 1
Item 2
This is just a simple paragraph.
", + endHtml: "This is ju
Item 1
Item 2
st a simple paragraph.
", + startId: "b", // Select "ju|st" + startOffset: 2, + endId: "b", + endOffset: 2, + pasteString: "Item 1
Item 2
Item 1
Item 2
Item 1
Item 2
Hello world
", + undoHtml: "Item 1
Item 2
Hello world
" + ), + // Blockquotes + HtmlTest( + description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE at a blank paragraph", + startHtml: "This is just a simple paragraph.
This is just a simple paragraph.
", + undoHtml: "Double-indented.
This is just a simple paragraph.
" + ), + HtmlTest( + description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE at beginning of a paragraph", + startHtml: "Double-indented.
This is just a simple paragraph.
", + endHtml: "Double-indented.
This is just a simple paragraph.
", + startId: "p", // Select "|This" + startOffset: 0, + endId: "p", + endOffset: 0, + pasteString: "" + ), + HtmlTest( + description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE at end of a paragraph", + startHtml: "Double-indented.
This is just a simple paragraph.
", + endHtml: "This is just a simple paragraph.
", + startId: "p", // Select "paragraph.|" + startOffset: 32, + endId: "p", + endOffset: 32, + pasteString: "Double-indented.
" + ), + HtmlTest( + description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE in text of a paragraph", + startHtml: "Double-indented.
This is just a simple paragraph.
", + endHtml: "This is ju
Double-indented.
st a simple paragraph.
", + startId: "p", // Select "ju|st" + startOffset: 10, + endId: "p", + endOffset: 10, + pasteString: "" + ), + HtmlTest( + description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE in formatted text of a paragraph", + startHtml: "Double-indented.
This is just a simple paragraph.
", + endHtml: "This is ju
Double-indented.
st a simple paragraph.
", + startId: "b", // Select "ju|st" + startOffset: 2, + endId: "b", + endOffset: 2, + pasteString: "" + ), + HtmlTest( + description: "P in P - Paste a simple paragraph at a blank line after a BLOCKQUOTE", + startHtml: "Double-indented.
Double-indented.
Double-indented.
Hello world
", + undoHtml: "Double-indented.
Hello world
" + ), ] for test in htmlTests { test.printDescription() diff --git a/MarkupEditorTests/UndoTests/UndoTests.swift b/MarkupEditorTests/UndoTests/UndoTests.swift index 80f157e..90181bb 100644 --- a/MarkupEditorTests/UndoTests/UndoTests.swift +++ b/MarkupEditorTests/UndoTests/UndoTests.swift @@ -2625,6 +2625,7 @@ class UndoTests: XCTestCase, MarkupDelegate { endOffset: 0, pasteString: "A paragraph.
" ), + // Tables HtmlTest( description: "TABLE in P - Paste a table at a blank paragraph", startHtml: "This is just a simple paragraph.
Hello world
" ), + // Lists + HtmlTest( + description: "OL in P - Paste a list at a blank paragraph", + startHtml: "This is just a simple paragraph.
This is just a simple paragraph.
Item 1
Item 2
This is just a simple paragraph.
Item 1
Item 2
This is just a simple paragraph.
", + endHtml: "Item 1
Item 2
This is just a simple paragraph.
", + startId: "p", // Select "|This" + startOffset: 0, + endId: "p", + endOffset: 0, + pasteString: "Item 1
Item 2
This is just a simple paragraph.
", + endHtml: "This is just a simple paragraph.
Item 1
Item 2
Item 1
Item 2
This is just a simple paragraph.
", + endHtml: "This is ju
Item 1
Item 2
st a simple paragraph.
", + startId: "p", // Select "ju|st" + startOffset: 10, + endId: "p", + endOffset: 10, + pasteString: "Item 1
Item 2
This is just a simple paragraph.
", + endHtml: "This is ju
Item 1
Item 2
st a simple paragraph.
", + startId: "b", // Select "ju|st" + startOffset: 2, + endId: "b", + endOffset: 2, + pasteString: "Item 1
Item 2
Item 1
Item 2
Item 1
Item 2
Hello world
", + undoHtml: "Item 1
Item 2
Hello world
" + ), + // Blockquotes + HtmlTest( + description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE at a blank paragraph", + startHtml: "This is just a simple paragraph.
This is just a simple paragraph.
", + undoHtml: "Double-indented.
This is just a simple paragraph.
" + ), + HtmlTest( + description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE at beginning of a paragraph", + startHtml: "Double-indented.
This is just a simple paragraph.
", + endHtml: "Double-indented.
This is just a simple paragraph.
", + startId: "p", // Select "|This" + startOffset: 0, + endId: "p", + endOffset: 0, + pasteString: "" + ), + HtmlTest( + description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE at end of a paragraph", + startHtml: "Double-indented.
This is just a simple paragraph.
", + endHtml: "This is just a simple paragraph.
", + startId: "p", // Select "paragraph.|" + startOffset: 32, + endId: "p", + endOffset: 32, + pasteString: "Double-indented.
" + ), + HtmlTest( + description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE in text of a paragraph", + startHtml: "Double-indented.
This is just a simple paragraph.
", + endHtml: "This is ju
Double-indented.
st a simple paragraph.
", + startId: "p", // Select "ju|st" + startOffset: 10, + endId: "p", + endOffset: 10, + pasteString: "" + ), + HtmlTest( + description: "BLOCKQUOTE in P - Paste a BLOCKQUOTE in formatted text of a paragraph", + startHtml: "Double-indented.
This is just a simple paragraph.
", + endHtml: "This is ju
Double-indented.
st a simple paragraph.
", + startId: "b", // Select "ju|st" + startOffset: 2, + endId: "b", + endOffset: 2, + pasteString: "" + ), + HtmlTest( + description: "P in P - Paste a simple paragraph at a blank line after a BLOCKQUOTE", + startHtml: "Double-indented.
Double-indented.
Double-indented.
Hello world
", + undoHtml: "Double-indented.
Hello world
" + ), ] for test in htmlTests { test.printDescription()