diff --git a/packages/text-editor/src/components/Collaboration.svelte b/packages/text-editor/src/components/Collaboration.svelte index 4923fc888c..133a2b5e54 100644 --- a/packages/text-editor/src/components/Collaboration.svelte +++ b/packages/text-editor/src/components/Collaboration.svelte @@ -16,9 +16,8 @@ -->
- {#if comparedVersion !== undefined && !noButton} -
-
-
- { - showDiff = !showDiff - editor.chain().focus() - }} - /> -
-
- {/if}
diff --git a/packages/text-editor/src/components/CollaboratorEditor.svelte b/packages/text-editor/src/components/CollaboratorEditor.svelte index 942ec71d7d..5e63825fba 100644 --- a/packages/text-editor/src/components/CollaboratorEditor.svelte +++ b/packages/text-editor/src/components/CollaboratorEditor.svelte @@ -15,15 +15,14 @@ // --> + +
+
+
+
+
diff --git a/packages/text-editor/src/components/diff/decorations.ts b/packages/text-editor/src/components/diff/decorations.ts index 50a01ef133..11b6f57e68 100644 --- a/packages/text-editor/src/components/diff/decorations.ts +++ b/packages/text-editor/src/components/diff/decorations.ts @@ -19,13 +19,26 @@ import { ChangeSet } from '@tiptap/pm/changeset' import { DOMParser, type Node, type Schema } from '@tiptap/pm/model' import { Decoration, DecorationSet } from '@tiptap/pm/view' import { yDocToProsemirrorJSON } from 'y-prosemirror' -import { Doc, applyUpdate } from 'yjs' +import { Doc as Ydoc, applyUpdate } from 'yjs' import { recreateTransform } from './recreate' /** * @public */ -export function createDocument (schema: Schema, content: Markup | ArrayBuffer, field?: string): Node { +export function createYdocDocument (schema: Schema, ydoc: Ydoc, field?: string): Node { + try { + const body = yDocToProsemirrorJSON(ydoc, field) + return schema.nodeFromJSON(body) + } catch (err: any) { + console.error(err) + return schema.node(schema.topNodeType) + } +} + +/** + * @public + */ +export function createMarkupDocument (schema: Schema, content: Markup | ArrayBuffer, field?: string): Node { if (typeof content === 'string') { const wrappedValue = `${content}` @@ -34,7 +47,7 @@ export function createDocument (schema: Schema, content: Markup | ArrayBuffer, f return DOMParser.fromSchema(schema).parse(body) } else { try { - const ydoc = new Doc() + const ydoc = new Ydoc() const uint8arr = new Uint8Array(content) applyUpdate(ydoc, uint8arr) @@ -53,8 +66,7 @@ export function createDocument (schema: Schema, content: Markup | ArrayBuffer, f export function calculateDecorations ( editor?: Editor, oldContent?: string, - field?: string, - comparedVersion?: Markup | ArrayBuffer + comparedDoc?: Node ): | { decorations: DecorationSet @@ -65,11 +77,9 @@ export function calculateDecorations ( if (editor?.schema === undefined) { return } - if (comparedVersion === undefined) { + if (comparedDoc === undefined) { return } - const schema = editor.schema - const docOld = createDocument(schema, comparedVersion, field) const docNew = editor.state.doc const c = editor.getHTML() @@ -77,8 +87,8 @@ export function calculateDecorations ( return } - const tr = recreateTransform(docOld, docNew) - const changeSet = ChangeSet.create(docOld).addSteps(tr.doc, tr.mapping.maps, undefined) + const tr = recreateTransform(comparedDoc, docNew) + const changeSet = ChangeSet.create(comparedDoc).addSteps(tr.doc, tr.mapping.maps, undefined) const changes = changeSet.changes const decorations: Decoration[] = [] @@ -91,18 +101,18 @@ export function calculateDecorations ( function deleted (prob: any): any { const icon = document.createElement('span') - icon.className = 'deletion' + icon.className = 'text-editor-highlighted-node-delete' icon.innerText = prob return icon } changes.forEach((change) => { if (change.inserted.length > 0) { - decorations.push(Decoration.inline(change.fromB, change.toB, { class: 'diff insertion' }, {})) + decorations.push(Decoration.inline(change.fromB, change.toB, { class: 'text-editor-highlighted-node-add' }, {})) decorations.push(Decoration.widget(change.fromB, lintIcon('add'))) } if (change.deleted.length > 0) { - const cont = docOld.textBetween(change.fromA, change.toA) + const cont = comparedDoc.textBetween(change.fromA, change.toA) decorations.push(Decoration.widget(change.fromB, deleted(cont))) decorations.push(Decoration.widget(change.fromB, lintIcon('delete'))) } diff --git a/packages/text-editor/src/index.ts b/packages/text-editor/src/index.ts index 8160185065..168f7715dc 100644 --- a/packages/text-editor/src/index.ts +++ b/packages/text-editor/src/index.ts @@ -21,6 +21,7 @@ export { default as Collaboration } from './components/Collaboration.svelte' export { default as CollaborationDiffViewer } from './components/CollaborationDiffViewer.svelte' export { default as CollaboratorEditor } from './components/CollaboratorEditor.svelte' export { default as FullDescriptionBox } from './components/FullDescriptionBox.svelte' +export { default as MarkupDiffViewer } from './components/MarkupDiffViewer.svelte' export { default as ReferenceInput } from './components/ReferenceInput.svelte' export { default as StyleButton } from './components/StyleButton.svelte' export { default as StyledTextArea } from './components/StyledTextArea.svelte' @@ -65,4 +66,7 @@ export { export { ImageExtension, type ImageOptions } from './components/extension/imageExt' export { TodoItemExtension, TodoListExtension } from './components/extension/todo' +export { TiptapCollabProvider, type TiptapCollabProviderConfiguration, createTiptapCollaborationData } from './provider' +export { CollaborationIds } from './types' + export { textEditorId } diff --git a/packages/text-editor/src/provider.ts b/packages/text-editor/src/provider.ts index 19ec13c8de..8a2c30f94e 100644 --- a/packages/text-editor/src/provider.ts +++ b/packages/text-editor/src/provider.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // - +import { Doc as Ydoc } from 'yjs' import { HocuspocusProvider, type HocuspocusProviderConfiguration } from '@hocuspocus/provider' export type TiptapCollabProviderConfiguration = HocuspocusProviderConfiguration & @@ -50,3 +50,24 @@ export class TiptapCollabProvider extends HocuspocusProvider { super.destroy() } } + +export const createTiptapCollaborationData = (params: { + collaboratorURL: string + documentId: string + initialContentId: string | undefined + token: string +}): { provider: TiptapCollabProvider, ydoc: Ydoc } => { + const ydoc: Ydoc = new Ydoc() + return { + ydoc, + provider: new TiptapCollabProvider({ + url: params.collaboratorURL, + name: params.documentId, + document: ydoc, + token: params.token, + parameters: { + initialContentId: params.initialContentId ?? '' + } + }) + } +} diff --git a/plugins/view-resources/src/components/MarkupDiffPresenter.svelte b/plugins/view-resources/src/components/MarkupDiffPresenter.svelte index 377b654369..1cea8211ae 100644 --- a/plugins/view-resources/src/components/MarkupDiffPresenter.svelte +++ b/plugins/view-resources/src/components/MarkupDiffPresenter.svelte @@ -14,7 +14,7 @@ // limitations under the License. -->