From 5d25e8496c9b53efd2af8db8a391288e237032a2 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Mon, 20 Apr 2020 11:01:31 -0500 Subject: [PATCH] Switch to a method of re-applying HTML content to drafts that works reliably --- app/src/flux/stores/draft-editing-session.ts | 28 ++++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/app/src/flux/stores/draft-editing-session.ts b/app/src/flux/stores/draft-editing-session.ts index afcd25373..769d23d9a 100644 --- a/app/src/flux/stores/draft-editing-session.ts +++ b/app/src/flux/stores/draft-editing-session.ts @@ -69,19 +69,25 @@ function hotwireDraftBodyState(draft: any, session: DraftEditingSession): Messag const inHTMLEditorValue = convertFromHTML(inHTML); try { // try to apply the new value to the existing document to preserve undo history. - _bodyEditorValue = session._mountedEditor - .moveToRangeOfDocument() - .delete() - .insertFragment(inHTMLEditorValue.document) - .moveToRangeOfDocument() - .moveToStart().value; + let edits = session._mountedEditor.moveToStartOfDocument(); - // occasionally inserting the new document adds a new line at the beginning of the value. - // It's unclaer why this happens... - const firstBlock = _bodyEditorValue.document.getBlocks().first(); - if (firstBlock.text === '') { - _bodyEditorValue = session._mountedEditor.removeNodeByKey(firstBlock.key).value; + // remove all but the very first node in the document + const [first, ...rest] = edits.value.document.nodes.toArray(); + for (const item of rest) { + if (edits.value.document.getPath(item.key)) { + edits = edits.removeNodeByKey(item.key); + } } + + const [newFirst, ...newRest] = inHTMLEditorValue.document.nodes.toArray(); + + // replace the first node in the document with the first node of the new + // document, and then "insert" the remaining new nodes at the end. + edits = edits.replaceNodeByKey(first.key, newFirst).moveToEndOfDocument(); + for (const block of newRest) { + edits = edits.insertBlock(block); + } + _bodyEditorValue = edits.moveToStart().value; } catch (err) { // deleting and re-inserting the whole document seems to push Slate pretty hard and it // sometimes fails with odd schema issues (undefined node, invalid range.) Just fall