From 6672536cde19c56ea0c5b5a4a99af8215b668b94 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Thu, 21 Sep 2023 00:15:54 -0400 Subject: [PATCH] fix: Retain image and video placeholders when document remotely edited --- package.json | 1 + shared/editor/lib/uploadPlaceholder.tsx | 14 ++++++++-- yarn.lock | 36 +++++++++++++++++++------ 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 8bac49f74..9a3c64767 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "@dnd-kit/sortable": "^7.0.1", "@emoji-mart/data": "^1.0.6", "@emoji-mart/react": "^1.1.1", + "@fellow/prosemirror-recreate-transform": "^1.2.3", "@getoutline/y-prosemirror": "^1.0.18", "@hocuspocus/extension-throttle": "1.1.2", "@hocuspocus/provider": "1.1.2", diff --git a/shared/editor/lib/uploadPlaceholder.tsx b/shared/editor/lib/uploadPlaceholder.tsx index 359d0d8bf..d49819f6f 100644 --- a/shared/editor/lib/uploadPlaceholder.tsx +++ b/shared/editor/lib/uploadPlaceholder.tsx @@ -1,3 +1,4 @@ +import { recreateTransform } from "@fellow/prosemirror-recreate-transform"; import { EditorState, Plugin } from "prosemirror-state"; import { Decoration, DecorationSet } from "prosemirror-view"; import * as React from "react"; @@ -11,8 +12,17 @@ const uploadPlaceholder = new Plugin({ return DecorationSet.empty; }, apply(tr, set: DecorationSet) { - // Adjust decoration positions to changes made by the transaction - set = set.map(tr.mapping, tr.doc); + const ySyncEdit = !!tr.getMeta("y-sync$"); + if (ySyncEdit) { + const mapping = recreateTransform(tr.before, tr.doc, { + complexSteps: true, + wordDiffs: false, + simplifyDiff: true, + }).mapping; + return set.map(mapping, tr.doc); + } else { + set = set.map(tr.mapping, tr.doc); + } // See if the transaction adds or removes any placeholders const action = tr.getMeta(this); diff --git a/yarn.lock b/yarn.lock index 243498280..dffed29df 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1600,6 +1600,16 @@ resolved "https://registry.yarnpkg.com/@faker-js/faker/-/faker-8.0.2.tgz#bab698c5d3da9c52744e966e0e3eedb6c8b05c37" integrity sha512-Uo3pGspElQW91PCvKSIAXoEgAUlRnH29sX2/p89kg7sP1m2PzCufHINd0FhTXQf6DYGiUlVncdSPa2F9wxed2A== +"@fellow/prosemirror-recreate-transform@^1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@fellow/prosemirror-recreate-transform/-/prosemirror-recreate-transform-1.2.3.tgz#078424dab58447145e1b93724216e8366553910f" + integrity sha512-LdvMirDXtZWNv2DSpUVh1L7OxV/8PopzCwL4XJdd8UW4MMXywlcnCUzOz2TuNTMoTNnbOPBQ2JJlaAG/hg6sdQ== + dependencies: + diff "^5.1.0" + prosemirror-model "^1.18.1" + prosemirror-transform "^1.7.0" + rfc6902 "^5.0.1" + "@formatjs/ecma402-abstract@1.12.0": version "1.12.0" resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.12.0.tgz#2fb5e8983d5fae2fad9ec6c77aec1803c2b88d8e" @@ -5752,6 +5762,11 @@ diff-sequences@^29.6.3: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== +diff@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" + integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== + dingbat-to-unicode@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/dingbat-to-unicode/-/dingbat-to-unicode-1.0.1.tgz#5091dd673241453e6b5865e26e5a4452cdef5c83" @@ -10821,10 +10836,10 @@ prosemirror-markdown@^1.11.0: markdown-it "^13.0.1" prosemirror-model "^1.0.0" -prosemirror-model@^1.0.0, prosemirror-model@^1.16.0, prosemirror-model@^1.19.2, prosemirror-model@^1.8.1: - version "1.19.2" - resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.19.2.tgz#297c9ecfb103154e605f0dbaf3cc72ee32ca0ad5" - integrity sha512-RXl0Waiss4YtJAUY3NzKH0xkJmsZupCIccqcIFoLTIKFlKNbIvFDRl27/kQy1FP8iUAxrjRRfIVvOebnnXJgqQ== +prosemirror-model@^1.0.0, prosemirror-model@^1.16.0, prosemirror-model@^1.18.1, prosemirror-model@^1.19.2, prosemirror-model@^1.8.1: + version "1.19.3" + resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.19.3.tgz#f0d55285487fefd962d0ac695f716f4ec6705006" + integrity sha512-tgSnwN7BS7/UM0sSARcW+IQryx2vODKX4MI7xpqY2X+iaepJdKBPc7I4aACIsDV/LTaTjt12Z56MhDr9LsyuZQ== dependencies: orderedmap "^2.0.0" @@ -10857,10 +10872,10 @@ prosemirror-tables@^1.3.2: prosemirror-transform "^1.2.1" prosemirror-view "^1.13.3" -prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.2.1, prosemirror-transform@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.7.3.tgz#cc2225cd1bf88a3c62404b9eb051ff73e9c716a6" - integrity sha512-qDapyx5lqYfxVeUWEw0xTGgeP2S8346QtE7DxkalsXlX89lpzkY6GZfulgfHyk1n4tf74sZ7CcXgcaCcGjsUtA== +prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.2.1, prosemirror-transform@^1.7.0, prosemirror-transform@^1.7.3: + version "1.7.5" + resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.7.5.tgz#c62aac8645bd4f8cf447d6d53dda80abe8489f03" + integrity sha512-U/fWB6frEzY7dzwJUo+ir8dU1JEanaI/RwL12Imy9js/527N0v/IRUKewocP1kTq998JNT18IGtThaDLwLOBxQ== dependencies: prosemirror-model "^1.0.0" @@ -11637,6 +11652,11 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +rfc6902@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/rfc6902/-/rfc6902-5.0.1.tgz#e16f18dc322c755d6dd948423ddf52bb451eca3d" + integrity sha512-tYGfLpKIq9X7lrt4o3IkD9w9bpeAtsejfAqWNR98AoxfTsZqCepKa8eDlRiX8QMiCOD9vMx0/YbKLx0G1nPi5w== + rfdc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b"