From b23cdcba6b42de6234929c725b56e5c4d457eed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Sun, 3 Feb 2019 14:06:17 +0100 Subject: [PATCH 01/64] add basic collab implementation --- .../Components/Routes/Collaboration/Collab.js | 12 +++ .../Components/Routes/Collaboration/index.vue | 88 +++++++++++++++++++ examples/Components/Subnavigation/index.vue | 3 + examples/main.js | 7 ++ package.json | 4 +- yarn.lock | 7 ++ 6 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 examples/Components/Routes/Collaboration/Collab.js create mode 100644 examples/Components/Routes/Collaboration/index.vue diff --git a/examples/Components/Routes/Collaboration/Collab.js b/examples/Components/Routes/Collaboration/Collab.js new file mode 100644 index 00000000..7607d18a --- /dev/null +++ b/examples/Components/Routes/Collaboration/Collab.js @@ -0,0 +1,12 @@ +import { Extension } from 'tiptap' +import { collab } from 'prosemirror-collab' + +export default class CollabExtension extends Extension { + get name() { + return 'collab' + } + + get plugins() { + return [collab()] + } +} diff --git a/examples/Components/Routes/Collaboration/index.vue b/examples/Components/Routes/Collaboration/index.vue new file mode 100644 index 00000000..bd89ace0 --- /dev/null +++ b/examples/Components/Routes/Collaboration/index.vue @@ -0,0 +1,88 @@ + + + diff --git a/examples/Components/Subnavigation/index.vue b/examples/Components/Subnavigation/index.vue index bcc2e246..c4c3b796 100644 --- a/examples/Components/Subnavigation/index.vue +++ b/examples/Components/Subnavigation/index.vue @@ -48,6 +48,9 @@ Export HTML or JSON + + Collaboration + diff --git a/examples/main.js b/examples/main.js index aea0bad9..3102cc93 100644 --- a/examples/main.js +++ b/examples/main.js @@ -124,6 +124,13 @@ const routes = [ githubUrl: 'https://github.com/scrumpy/tiptap/tree/master/examples/Components/Routes/Export', }, }, + { + path: '/collaboration', + component: () => import('Components/Routes/Collaboration'), + meta: { + githubUrl: 'https://github.com/scrumpy/tiptap/tree/master/examples/Components/Routes/Collaboration', + }, + }, ] const router = new VueRouter({ diff --git a/package.json b/package.json index 23fb1971..15bdc6ca 100644 --- a/package.json +++ b/package.json @@ -86,5 +86,7 @@ "webpack-svgstore-plugin": "^4.1.0", "zlib": "^1.0.5" }, - "dependencies": {} + "dependencies": { + "prosemirror-collab": "^1.1.1" + } } diff --git a/yarn.lock b/yarn.lock index 073741b9..a50601f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9572,6 +9572,13 @@ promzard@^0.3.0: dependencies: read "1" +prosemirror-collab@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/prosemirror-collab/-/prosemirror-collab-1.1.1.tgz#c8f5d951abaeac8a80818b6bd960f5a392b35b3f" + integrity sha512-BpXIB3WBD7UvgxuiasKOxlAZ78TTOdW+SQN4bbJan995tVx/wM/OZXtRJebS+tSWWAbRisHaO3ciFo732vuvdA== + dependencies: + prosemirror-state "^1.0.0" + prosemirror-commands@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.0.7.tgz#e5a2ba821e29ea7065c88277fe2c3d7f6b0b9d37" From bf21ebd719c942a4a766360d343f0e787d8d36d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Sun, 3 Feb 2019 21:18:03 +0100 Subject: [PATCH 02/64] improve collab demo --- .../Components/Routes/Collaboration/Collab.js | 14 ++++- .../Components/Routes/Collaboration/index.vue | 52 +++++++++++++------ 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/examples/Components/Routes/Collaboration/Collab.js b/examples/Components/Routes/Collaboration/Collab.js index 7607d18a..21dc7255 100644 --- a/examples/Components/Routes/Collaboration/Collab.js +++ b/examples/Components/Routes/Collaboration/Collab.js @@ -6,7 +6,19 @@ export default class CollabExtension extends Extension { return 'collab' } + get defaultOptions() { + return { + version: 0, + clientID: Math.floor(Math.random() * 0xFFFFFFFF), + } + } + get plugins() { - return [collab()] + return [ + collab({ + version: this.options.version, + clientID: this.options.clientID, + }), + ] } } diff --git a/examples/Components/Routes/Collaboration/index.vue b/examples/Components/Routes/Collaboration/index.vue index bd89ace0..0d7620eb 100644 --- a/examples/Components/Routes/Collaboration/index.vue +++ b/examples/Components/Routes/Collaboration/index.vue @@ -1,6 +1,6 @@ @@ -17,16 +17,29 @@ export default { data() { return { + editor: null, ws: null, - - authority: { + clientID: Math.floor(Math.random() * 0xFFFFFFFF), + collabStartVersion: 0, + collabHistory: { steps: [], - stepClientIDs: [], + clientIDs: [], }, + } + }, - editor: new Editor({ - content: 'Collaboration!', - extensions: [new Collab()], + methods: { + initEditor({ doc, version }) { + this.collabStartVersion = version + 1 + + this.editor = new Editor({ + content: doc, + extensions: [ + new Collab({ + version: this.collabStartVersion, + clientID: this.clientID, + }), + ], onUpdate: ({ state }) => { const sendable = sendableSteps(state) @@ -34,19 +47,17 @@ export default { this.ws.send(JSON.stringify(sendable)) } }, - }), - } - }, + }) + }, - methods: { receiveData({ version, steps, clientID }) { - if (version !== this.authority.steps.length) { + if (version !== this.collabHistory.steps.length + this.collabStartVersion) { return } steps.forEach(step => { - this.authority.steps.push(step) - this.authority.stepClientIDs.push(clientID) + this.collabHistory.steps.push(step) + this.collabHistory.clientIDs.push(clientID) }) this.updateDoc() @@ -66,9 +77,10 @@ export default { }, stepsSince(version) { + const count = version - this.collabStartVersion return { - steps: this.authority.steps.slice(version), - clientIDs: this.authority.stepClientIDs.slice(version), + steps: this.collabHistory.steps.slice(count), + clientIDs: this.collabHistory.clientIDs.slice(count), } }, }, @@ -77,7 +89,13 @@ export default { this.ws = new WebSocket('wss://tiptap-sockets.glitch.me') this.ws.onmessage = event => { - this.receiveData(JSON.parse(event.data)) + const payload = JSON.parse(event.data) + + if (payload.doc) { + this.initEditor(payload) + } else { + this.receiveData(payload) + } } }, From 9b0c35d34ccc9fdfa8106eda7cb9d1fc7dc3ec41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Tue, 5 Feb 2019 00:03:27 +0100 Subject: [PATCH 03/64] update eslint --- .eslintrc.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.eslintrc.js b/.eslintrc.js index b21e48fc..9dd30988 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -56,5 +56,7 @@ module.exports = { 'class-methods-use-this': 'off', 'global-require': 'off', + + 'func-names': ['error', 'never'], } } From aba26c7e74d12cb7041a31c3cb74e5f783b11745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Tue, 5 Feb 2019 02:20:49 +0100 Subject: [PATCH 04/64] started adding a better collab demo --- .../Routes/Collaboration2/Collab.js | 24 +++ .../Routes/Collaboration2/index.vue | 150 ++++++++++++++++++ examples/Components/Subnavigation/index.vue | 3 + examples/main.js | 7 + 4 files changed, 184 insertions(+) create mode 100644 examples/Components/Routes/Collaboration2/Collab.js create mode 100644 examples/Components/Routes/Collaboration2/index.vue diff --git a/examples/Components/Routes/Collaboration2/Collab.js b/examples/Components/Routes/Collaboration2/Collab.js new file mode 100644 index 00000000..21dc7255 --- /dev/null +++ b/examples/Components/Routes/Collaboration2/Collab.js @@ -0,0 +1,24 @@ +import { Extension } from 'tiptap' +import { collab } from 'prosemirror-collab' + +export default class CollabExtension extends Extension { + get name() { + return 'collab' + } + + get defaultOptions() { + return { + version: 0, + clientID: Math.floor(Math.random() * 0xFFFFFFFF), + } + } + + get plugins() { + return [ + collab({ + version: this.options.version, + clientID: this.options.clientID, + }), + ] + } +} diff --git a/examples/Components/Routes/Collaboration2/index.vue b/examples/Components/Routes/Collaboration2/index.vue new file mode 100644 index 00000000..1cedbe2f --- /dev/null +++ b/examples/Components/Routes/Collaboration2/index.vue @@ -0,0 +1,150 @@ + + + diff --git a/examples/Components/Subnavigation/index.vue b/examples/Components/Subnavigation/index.vue index c4c3b796..e49ef25b 100644 --- a/examples/Components/Subnavigation/index.vue +++ b/examples/Components/Subnavigation/index.vue @@ -51,6 +51,9 @@ Collaboration + + Collaboration 2 + diff --git a/examples/main.js b/examples/main.js index 3102cc93..22ea4397 100644 --- a/examples/main.js +++ b/examples/main.js @@ -131,6 +131,13 @@ const routes = [ githubUrl: 'https://github.com/scrumpy/tiptap/tree/master/examples/Components/Routes/Collaboration', }, }, + { + path: '/collaboration2', + component: () => import('Components/Routes/Collaboration2'), + meta: { + githubUrl: 'https://github.com/scrumpy/tiptap/tree/master/examples/Components/Routes/Collaboration2', + }, + }, ] const router = new VueRouter({ From bdcd5c967f3d0b614eaa92b05be07f35417234af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Tue, 5 Feb 2019 03:07:43 +0100 Subject: [PATCH 05/64] add socket.io to collab demo --- .../Routes/Collaboration2/index.vue | 88 +++++-------------- package.json | 4 +- yarn.lock | 58 ++++++++++++ 3 files changed, 83 insertions(+), 67 deletions(-) diff --git a/examples/Components/Routes/Collaboration2/index.vue b/examples/Components/Routes/Collaboration2/index.vue index 1cedbe2f..c9b2bff9 100644 --- a/examples/Components/Routes/Collaboration2/index.vue +++ b/examples/Components/Routes/Collaboration2/index.vue @@ -5,6 +5,7 @@ diff --git a/examples/Components/Subnavigation/index.vue b/examples/Components/Subnavigation/index.vue index e49ef25b..1ff9f905 100644 --- a/examples/Components/Subnavigation/index.vue +++ b/examples/Components/Subnavigation/index.vue @@ -54,6 +54,9 @@ Collaboration 2 + + Collaboration 3 + diff --git a/examples/main.js b/examples/main.js index 22ea4397..cd124936 100644 --- a/examples/main.js +++ b/examples/main.js @@ -138,6 +138,13 @@ const routes = [ githubUrl: 'https://github.com/scrumpy/tiptap/tree/master/examples/Components/Routes/Collaboration2', }, }, + { + path: '/collaboration3', + component: () => import('Components/Routes/Collaboration3'), + meta: { + githubUrl: 'https://github.com/scrumpy/tiptap/tree/master/examples/Components/Routes/Collaboration3', + }, + }, ] const router = new VueRouter({ From f490ca1469c8d8b972cf148b9a6be494a592e7b3 Mon Sep 17 00:00:00 2001 From: Chrissi2812 Date: Thu, 7 Mar 2019 18:13:19 +0100 Subject: [PATCH 09/64] fix menububble position --- packages/tiptap/src/Plugins/MenuBubble.js | 49 ++++++++++++++++++++++- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/packages/tiptap/src/Plugins/MenuBubble.js b/packages/tiptap/src/Plugins/MenuBubble.js index 95510b77..2c80c4f4 100644 --- a/packages/tiptap/src/Plugins/MenuBubble.js +++ b/packages/tiptap/src/Plugins/MenuBubble.js @@ -1,4 +1,49 @@ import { Plugin } from 'prosemirror-state' +import { textRange } from 'prosemirror-view/src/dom' + +function singleRect(object, bias) { + const rects = object.getClientRects() + return !rects.length ? object.getBoundingClientRect() : rects[bias < 0 ? 0 : rects.length - 1] +} + +function coordsAtPos(view, pos, end = false) { + const { node, offset } = view.docView.domFromPos(pos) + let side + let rect + if (node.nodeType === 3) { + if (end && offset < node.nodeValue.length) { + rect = singleRect(textRange(node, offset - 1, offset), -1) + side = 'right' + } else if (offset < node.nodeValue.length) { + rect = singleRect(textRange(node, offset, offset + 1), -1) + side = 'left' + } + } else if (node.firstChild) { + if (offset < node.childNodes.length) { + const child = node.childNodes[offset] + rect = singleRect(child.nodeType === 3 ? textRange(child) : child, -1) + side = 'left' + } + if ((!rect || rect.top === rect.bottom) && offset) { + const child = node.childNodes[offset - 1] + rect = singleRect(child.nodeType === 3 ? textRange(child) : child, 1) + side = 'right' + } + } else { + rect = node.getBoundingClientRect() + side = 'left' + } + + const x = rect[side] + + return { + top: rect.top, + bottom: rect.bottom, + left: x, + right: x, + } +} + class Menu { @@ -36,8 +81,8 @@ class Menu { const { from, to } = state.selection // These are in screen coordinates - const start = view.coordsAtPos(from) - const end = view.coordsAtPos(to) + const start = coordsAtPos(view, from) + const end = coordsAtPos(view, to, true) // The box in which the tooltip is positioned, to use as base const box = this.options.element.offsetParent.getBoundingClientRect() From 8ddc0c016af9ccbda487e460a60202d864524c7a Mon Sep 17 00:00:00 2001 From: Chrissi2812 Date: Thu, 7 Mar 2019 18:15:45 +0100 Subject: [PATCH 10/64] add note why we had to use our own cordsAtPos implementation --- packages/tiptap/src/Plugins/MenuBubble.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/tiptap/src/Plugins/MenuBubble.js b/packages/tiptap/src/Plugins/MenuBubble.js index 2c80c4f4..e003d37d 100644 --- a/packages/tiptap/src/Plugins/MenuBubble.js +++ b/packages/tiptap/src/Plugins/MenuBubble.js @@ -81,6 +81,8 @@ class Menu { const { from, to } = state.selection // These are in screen coordinates + // We can't use EditorView.cordsAtPos here because it can't handle linebreaks correctly + // See: https://github.com/ProseMirror/prosemirror-view/pull/47 const start = coordsAtPos(view, from) const end = coordsAtPos(view, to, true) From e441041860da82ebc4bc5e7554a7f7735b54cedd Mon Sep 17 00:00:00 2001 From: Chrissi2812 Date: Thu, 7 Mar 2019 18:28:27 +0100 Subject: [PATCH 11/64] fix travis-ci: copied textRange function from prosemirror-view --- packages/tiptap/src/Plugins/MenuBubble.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/tiptap/src/Plugins/MenuBubble.js b/packages/tiptap/src/Plugins/MenuBubble.js index e003d37d..0a0235d3 100644 --- a/packages/tiptap/src/Plugins/MenuBubble.js +++ b/packages/tiptap/src/Plugins/MenuBubble.js @@ -1,5 +1,11 @@ import { Plugin } from 'prosemirror-state' -import { textRange } from 'prosemirror-view/src/dom' + +function textRange(node, from, to) { + const range = document.createRange() + range.setEnd(node, to == null ? node.nodeValue.length : to) + range.setStart(node, from || 0) + return range +} function singleRect(object, bias) { const rects = object.getClientRects() From cf7a442edd3b668e077d3b4c46e452b416ec0fd3 Mon Sep 17 00:00:00 2001 From: Chrissi2812 Date: Wed, 24 Apr 2019 18:33:59 +0200 Subject: [PATCH 12/64] add link to documentation --- examples/Components/Navigation/index.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/Components/Navigation/index.vue b/examples/Components/Navigation/index.vue index 4a94ef61..89f41a0d 100644 --- a/examples/Components/Navigation/index.vue +++ b/examples/Components/Navigation/index.vue @@ -6,6 +6,9 @@
+ + Documentation + Contribute From 2f0acf2f91e9569e8a192210b196b25093a4a023 Mon Sep 17 00:00:00 2001 From: Chrissi2812 Date: Thu, 25 Apr 2019 16:01:27 +0200 Subject: [PATCH 13/64] keep menuBubble in bounding box of editor --- examples/Components/Routes/MenuBubble/index.vue | 3 ++- packages/tiptap/src/Components/EditorMenuBubble.js | 5 +++++ packages/tiptap/src/Plugins/MenuBubble.js | 10 +++++++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/examples/Components/Routes/MenuBubble/index.vue b/examples/Components/Routes/MenuBubble/index.vue index 6a7780b5..30601375 100644 --- a/examples/Components/Routes/MenuBubble/index.vue +++ b/examples/Components/Routes/MenuBubble/index.vue @@ -1,6 +1,6 @@ diff --git a/examples/main.js b/examples/main.js index cd124936..3102cc93 100644 --- a/examples/main.js +++ b/examples/main.js @@ -131,20 +131,6 @@ const routes = [ githubUrl: 'https://github.com/scrumpy/tiptap/tree/master/examples/Components/Routes/Collaboration', }, }, - { - path: '/collaboration2', - component: () => import('Components/Routes/Collaboration2'), - meta: { - githubUrl: 'https://github.com/scrumpy/tiptap/tree/master/examples/Components/Routes/Collaboration2', - }, - }, - { - path: '/collaboration3', - component: () => import('Components/Routes/Collaboration3'), - meta: { - githubUrl: 'https://github.com/scrumpy/tiptap/tree/master/examples/Components/Routes/Collaboration3', - }, - }, ] const router = new VueRouter({ From 392f8a20b3fa08e3875053719683dc885cb138e0 Mon Sep 17 00:00:00 2001 From: Marius Tolzmann Date: Fri, 3 May 2019 19:06:18 +0200 Subject: [PATCH 28/64] Revert "fix eslint warning" This reverts commit c4e0bbeaf41ce8bb8f56ef1e4060c6a551982c21. --- packages/tiptap-utils/src/utils/getMarkRange.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tiptap-utils/src/utils/getMarkRange.js b/packages/tiptap-utils/src/utils/getMarkRange.js index ce563ab7..b7026156 100644 --- a/packages/tiptap-utils/src/utils/getMarkRange.js +++ b/packages/tiptap-utils/src/utils/getMarkRange.js @@ -22,7 +22,7 @@ export default function ($pos = null, type = null) { startPos -= $pos.parent.child(startIndex).nodeSize } - // const endIndex = $pos.indexAfter() + const endIndex = $pos.indexAfter() const endPos = startPos + start.node.nodeSize // disable for now. see #156 From d057d5d7d9490b41220fdbf703c57eb7e4b89833 Mon Sep 17 00:00:00 2001 From: Marius Tolzmann Date: Fri, 3 May 2019 19:06:19 +0200 Subject: [PATCH 29/64] Revert "fix a bug for getting mark range, fix #156" This reverts commit 0cf905abb9f9546fb379b7f539428d9ff655fa02. --- packages/tiptap-utils/src/utils/getMarkRange.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/tiptap-utils/src/utils/getMarkRange.js b/packages/tiptap-utils/src/utils/getMarkRange.js index b7026156..115f8b6b 100644 --- a/packages/tiptap-utils/src/utils/getMarkRange.js +++ b/packages/tiptap-utils/src/utils/getMarkRange.js @@ -22,14 +22,12 @@ export default function ($pos = null, type = null) { startPos -= $pos.parent.child(startIndex).nodeSize } - const endIndex = $pos.indexAfter() - const endPos = startPos + start.node.nodeSize - - // disable for now. see #156 - // while (endIndex < $pos.parent.childCount && link.isInSet($pos.parent.child(endIndex).marks)) { - // endPos += $pos.parent.child(endIndex).nodeSize - // endIndex += 1 - // } + let endIndex = $pos.indexAfter() + let endPos = startPos + start.node.nodeSize + while (endIndex < $pos.parent.childCount && link.isInSet($pos.parent.child(endIndex).marks)) { + endPos += $pos.parent.child(endIndex).nodeSize + endIndex += 1 + } return { from: startPos, to: endPos } From 9787b876fe270d66ff6c3080bb2a800167309189 Mon Sep 17 00:00:00 2001 From: Marius Tolzmann Date: Fri, 3 May 2019 19:08:50 +0200 Subject: [PATCH 30/64] fix endPosition in getMarkRange getMarkRange() will not return the actual end position of the current mark. might reintroduce bug from #156 (i cannot reproduce #156 so i cannot check) fixes in this commit: A) work around a possible bug in indexAfter()?: $pos.indexAfter() seems to return the same index as $pos.index() at some point -> fixed by increasing startIndex by 1 instead of using indexAfter() B) endPos needs to be initialized with initial startPos + nodeSize and not with resulting startPos: -> moved initialization right after setting startPos --- packages/tiptap-utils/src/utils/getMarkRange.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/tiptap-utils/src/utils/getMarkRange.js b/packages/tiptap-utils/src/utils/getMarkRange.js index 115f8b6b..b3b02977 100644 --- a/packages/tiptap-utils/src/utils/getMarkRange.js +++ b/packages/tiptap-utils/src/utils/getMarkRange.js @@ -17,13 +17,14 @@ export default function ($pos = null, type = null) { let startIndex = $pos.index() let startPos = $pos.start() + start.offset + let endIndex = startIndex + 1 + let endPos = startPos + start.node.nodeSize + while (startIndex > 0 && link.isInSet($pos.parent.child(startIndex - 1).marks)) { startIndex -= 1 startPos -= $pos.parent.child(startIndex).nodeSize } - let endIndex = $pos.indexAfter() - let endPos = startPos + start.node.nodeSize while (endIndex < $pos.parent.childCount && link.isInSet($pos.parent.child(endIndex).marks)) { endPos += $pos.parent.child(endIndex).nodeSize endIndex += 1 From fd404f5c1fd350331160669161ff6010d39865d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Fri, 3 May 2019 21:50:17 +0200 Subject: [PATCH 31/64] change socket url --- examples/Components/Routes/Collaboration/index.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/Components/Routes/Collaboration/index.vue b/examples/Components/Routes/Collaboration/index.vue index c3d84fa0..c65c1919 100644 --- a/examples/Components/Routes/Collaboration/index.vue +++ b/examples/Components/Routes/Collaboration/index.vue @@ -65,8 +65,8 @@ export default { }, mounted() { - this.socket = io('wss://tiptap-sockets-2.glitch.me') - .on('document', data => this.initEditor(data)) + this.socket = io('wss://tiptap-sockets.glitch.me') + .on('init', data => this.initEditor(data)) .on('update', data => this.receiveData(data)) }, From 2475bf6123f97d57269756d27ea8935ed69cb04f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Fri, 3 May 2019 22:14:18 +0200 Subject: [PATCH 32/64] add loading state --- examples/Components/Routes/Collaboration/index.vue | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/Components/Routes/Collaboration/index.vue b/examples/Components/Routes/Collaboration/index.vue index c65c1919..6ac6073d 100644 --- a/examples/Components/Routes/Collaboration/index.vue +++ b/examples/Components/Routes/Collaboration/index.vue @@ -1,6 +1,9 @@ @@ -19,6 +22,7 @@ export default { data() { return { + loading: true, editor: null, socket: null, } @@ -26,6 +30,8 @@ export default { methods: { initEditor({ doc, version }) { + this.loading = false + if (this.editor) { this.editor.destroy() } From cd46b163d059260a5643bdd253bb1a3d82fdc020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Sat, 4 May 2019 00:05:39 +0200 Subject: [PATCH 33/64] add emitter, move some collab logic to extension --- babel.config.js | 1 + .../Components/Routes/Collaboration/Collab.js | 21 ++++++- .../Components/Routes/Collaboration/index.vue | 32 +++++----- package.json | 1 + packages/tiptap/src/Editor.js | 42 ++++++++----- packages/tiptap/src/Utils/Emitter.js | 59 +++++++++++++++++++ packages/tiptap/src/Utils/Extension.js | 8 +++ packages/tiptap/src/Utils/ExtensionManager.js | 6 +- packages/tiptap/src/Utils/camelCase.js | 3 + packages/tiptap/src/Utils/index.js | 2 + yarn.lock | 51 ++++++++++------ 11 files changed, 173 insertions(+), 53 deletions(-) create mode 100644 packages/tiptap/src/Utils/Emitter.js create mode 100644 packages/tiptap/src/Utils/camelCase.js diff --git a/babel.config.js b/babel.config.js index 9f8a0a19..ebc1a253 100644 --- a/babel.config.js +++ b/babel.config.js @@ -4,5 +4,6 @@ module.exports = { ], plugins: [ '@babel/plugin-syntax-dynamic-import', + '@babel/plugin-proposal-class-properties', ], } diff --git a/examples/Components/Routes/Collaboration/Collab.js b/examples/Components/Routes/Collaboration/Collab.js index 21dc7255..a59328b2 100644 --- a/examples/Components/Routes/Collaboration/Collab.js +++ b/examples/Components/Routes/Collaboration/Collab.js @@ -1,15 +1,25 @@ import { Extension } from 'tiptap' -import { collab } from 'prosemirror-collab' +import { collab, sendableSteps } from 'prosemirror-collab' +import { debounce } from 'lodash-es' export default class CollabExtension extends Extension { + get name() { return 'collab' } + init() { + this.editor.on('update', ({ state }) => { + this.getSendableSteps(state) + }) + } + get defaultOptions() { return { version: 0, clientID: Math.floor(Math.random() * 0xFFFFFFFF), + debounce: 250, + onSend: () => {}, } } @@ -21,4 +31,13 @@ export default class CollabExtension extends Extension { }), ] } + + getSendableSteps = debounce(state => { + const sendable = sendableSteps(state) + + if (sendable) { + this.options.onSend(sendable) + } + }, this.options.debounce) + } diff --git a/examples/Components/Routes/Collaboration/index.vue b/examples/Components/Routes/Collaboration/index.vue index 6ac6073d..f7adc7cb 100644 --- a/examples/Components/Routes/Collaboration/index.vue +++ b/examples/Components/Routes/Collaboration/index.vue @@ -9,10 +9,9 @@ + + diff --git a/examples/assets/sass/main.scss b/examples/assets/sass/main.scss index 89a88025..9c62a81e 100644 --- a/examples/assets/sass/main.scss +++ b/examples/assets/sass/main.scss @@ -74,6 +74,15 @@ h3 { background-color: rgba($color-black, 0.1); } +.message { + background-color: rgba($color-black, 0.05); + color: rgba($color-black, 0.7); + padding: 1rem; + border-radius: 6px; + margin-bottom: 1rem; + font-style: italic; +} + @import "./editor"; @import "./menubar"; @import "./menububble"; From 76dca53d806c06d4ae74d90b85a2505cd75df561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Sun, 5 May 2019 21:47:52 +0200 Subject: [PATCH 44/64] send only json steps --- .../Components/Routes/Collaboration/index.vue | 15 ++++++++++++++- .../src/extensions/Collaboration.js | 6 +++++- packages/tiptap/src/Editor.js | 7 +++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/examples/Components/Routes/Collaboration/index.vue b/examples/Components/Routes/Collaboration/index.vue index e7420bc4..19f5ab06 100644 --- a/examples/Components/Routes/Collaboration/index.vue +++ b/examples/Components/Routes/Collaboration/index.vue @@ -18,7 +18,15 @@