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/27] 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 000000000..7607d18a9 --- /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 000000000..bd89ace07 --- /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 bcc2e2461..c4c3b796f 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 aea0bad97..3102cc931 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 23fb1971a..15bdc6ca7 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 073741b9b..a50601f21 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/27] 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 7607d18a9..21dc7255f 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 bd89ace07..0d7620ebe 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/27] update eslint --- .eslintrc.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.eslintrc.js b/.eslintrc.js index b21e48fc2..9dd309888 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/27] 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 000000000..21dc7255f --- /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 000000000..1cedbe2f6 --- /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 c4c3b796f..e49ef25b3 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 3102cc931..22ea43971 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/27] 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 1cedbe2f6..c9b2bff96 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 e49ef25b3..1ff9f9057 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 22ea43971..cd1249367 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 5b530d5d0c6dbde70271a32373c27fb6bd596d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Fri, 3 May 2019 14:04:14 +0200 Subject: [PATCH 09/27] add oldstate to update event --- packages/tiptap/src/Editor.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/tiptap/src/Editor.js b/packages/tiptap/src/Editor.js index 741adc649..12fd34bbc 100644 --- a/packages/tiptap/src/Editor.js +++ b/packages/tiptap/src/Editor.js @@ -288,6 +288,8 @@ export default class Editor { return } + const oldState = this.state + this.state = this.state.apply(transaction) this.view.updateState(this.state) this.setActiveNodesAndMarks() @@ -296,14 +298,15 @@ export default class Editor { return } - this.emitUpdate(transaction) + this.emitUpdate(transaction, oldState) } - emitUpdate(transaction) { + emitUpdate(transaction, oldState) { this.options.onUpdate({ getHTML: this.getHTML.bind(this), getJSON: this.getJSON.bind(this), state: this.state, + oldState, transaction, }) } From 543387018388e56a7482e552aa6eb3fb7f4afae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Fri, 3 May 2019 14:04:37 +0200 Subject: [PATCH 10/27] add something broken --- .../Routes/Collaboration3/index.vue | 47 +++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/examples/Components/Routes/Collaboration3/index.vue b/examples/Components/Routes/Collaboration3/index.vue index cac658d83..471909ec2 100644 --- a/examples/Components/Routes/Collaboration3/index.vue +++ b/examples/Components/Routes/Collaboration3/index.vue @@ -47,15 +47,19 @@ export default { // this.editor.view.updateState(this.state.edit) // return false // }, - onUpdate: ({ state }) => { - this.getSendableSteps(state) + onUpdate: ({ state, oldState }) => { + this.getSendableSteps(state, oldState) }, }) }, - getSendableSteps: debounce(function (state) { + getSendableSteps: debounce(function (state, oldState) { const sendable = sendableSteps(state) + console.log('update editor', { sendable }) + + // console.log({ state, oldState }) + if (sendable) { this.socket.emit('update', sendable) @@ -63,7 +67,7 @@ export default { const clientIDs = this.repeat(sendable.clientID, steps.length) this.history.push({ - state, + state: oldState, version: getVersion(state), steps, clientIDs, @@ -116,7 +120,7 @@ export default { console.log('version in sync', version) // TODO remove steps older than version }) - .on('versionMismatch', ({ version, data }) => { + .on('versionMismatch', ({ version, data, doc }) => { console.log('version mismatch', version) // TODO: go back to `version`, apply `steps`, apply unmerged `steps` @@ -124,20 +128,47 @@ export default { const { state, view, schema } = this.editor - view.updateState(history.state) + // view.updateState(history.state) - view.dispatch(receiveTransaction( + console.log('other steps', { data }) + // console.log(getVersion(view.state)) + + const newstate = history.state.apply(receiveTransaction( history.state, data.map(item => Step.fromJSON(schema, item.step)), data.map(item => item.clientID), )) + view.updateState(newstate) + + // const newstate2 = newstate.apply(receiveTransaction( + // newstate, + // history.steps, + // history.clientIDs, + // )) + view.dispatch(receiveTransaction( - history.state, + state, history.steps, history.clientIDs, )) + // view.updateState(newstate2) + + // view.dispatch(receiveTransaction( + // view.state, + // data.map(item => Step.fromJSON(schema, item.step)), + // data.map(item => item.clientID), + // )) + + // console.log('own', { history }) + + // view.dispatch(receiveTransaction( + // history.state, + // history.steps, + // history.clientIDs, + // )) + // const transaction = receiveTransaction( // state, // steps, From ee12e0577daa663dce752e80ff427655f087ab29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Fri, 3 May 2019 16:05:30 +0200 Subject: [PATCH 11/27] add something broken --- .../Routes/Collaboration3/index.vue | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/examples/Components/Routes/Collaboration3/index.vue b/examples/Components/Routes/Collaboration3/index.vue index 471909ec2..7267a472a 100644 --- a/examples/Components/Routes/Collaboration3/index.vue +++ b/examples/Components/Routes/Collaboration3/index.vue @@ -9,7 +9,9 @@ import io from 'socket.io-client' import { debounce } from 'lodash-es' import { Editor, EditorContent } from 'tiptap' import { Step } from 'prosemirror-transform' -import { receiveTransaction, sendableSteps, getVersion } from 'prosemirror-collab' +import { + receiveTransaction, sendableSteps, getVersion, rebaseSteps, +} from 'prosemirror-collab' import Collab from './Collab' export default { @@ -71,6 +73,7 @@ export default { version: getVersion(state), steps, clientIDs, + sendable, }) const transaction = receiveTransaction( @@ -125,13 +128,9 @@ export default { // TODO: go back to `version`, apply `steps`, apply unmerged `steps` const history = this.history.find(item => item.version === version) - const { state, view, schema } = this.editor - // view.updateState(history.state) - - console.log('other steps', { data }) - // console.log(getVersion(view.state)) + // console.log('other steps', { data }) const newstate = history.state.apply(receiveTransaction( history.state, @@ -139,19 +138,30 @@ export default { data.map(item => item.clientID), )) + // this.editor.state = view.updateState(newstate) - // const newstate2 = newstate.apply(receiveTransaction( - // newstate, - // history.steps, - // history.clientIDs, - // )) + if (history.steps.length) { + view.dispatch(receiveTransaction( + state, + history.steps, + history.clientIDs, + )) + + // const sendable = sendableSteps(state) + // console.log({ sendable }) + + // this.socket.emit('update', { + // version: getVersion(state), + // steps: history.steps, + // }) + } + + + // const currentVersion = getVersion(view.state) + // const historySteps = history.steps + // console.log({ currentVersion, historySteps }) - view.dispatch(receiveTransaction( - state, - history.steps, - history.clientIDs, - )) // view.updateState(newstate2) From b5a5472171b476e79bb4fb10c79ef81a5635f078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Fri, 3 May 2019 17:50:30 +0200 Subject: [PATCH 12/27] refactoring --- .../Routes/Collaboration3/index.vue | 156 ++---------------- packages/tiptap/src/Editor.js | 5 - 2 files changed, 13 insertions(+), 148 deletions(-) diff --git a/examples/Components/Routes/Collaboration3/index.vue b/examples/Components/Routes/Collaboration3/index.vue index 7267a472a..6301f7566 100644 --- a/examples/Components/Routes/Collaboration3/index.vue +++ b/examples/Components/Routes/Collaboration3/index.vue @@ -9,9 +9,7 @@ import io from 'socket.io-client' import { debounce } from 'lodash-es' import { Editor, EditorContent } from 'tiptap' import { Step } from 'prosemirror-transform' -import { - receiveTransaction, sendableSteps, getVersion, rebaseSteps, -} from 'prosemirror-collab' +import { receiveTransaction, sendableSteps, getVersion } from 'prosemirror-collab' import Collab from './Collab' export default { @@ -21,10 +19,8 @@ export default { data() { return { - history: [], editor: null, socket: null, - newState: null, clientID: Math.floor(Math.random() * 0xFFFFFFFF), } }, @@ -43,171 +39,45 @@ export default { clientID: this.clientID, }), ], - // onTransaction: transaction => { - // console.log('onTransaction') - // this.newState = this.editor.state.apply(transaction) - // this.editor.view.updateState(this.state.edit) - // return false - // }, - onUpdate: ({ state, oldState }) => { - this.getSendableSteps(state, oldState) + onUpdate: ({ state }) => { + this.getSendableSteps(state) }, }) }, - getSendableSteps: debounce(function (state, oldState) { + getSendableSteps: debounce(function (state) { const sendable = sendableSteps(state) - console.log('update editor', { sendable }) - - // console.log({ state, oldState }) - if (sendable) { this.socket.emit('update', sendable) - - const { steps } = sendable - const clientIDs = this.repeat(sendable.clientID, steps.length) - - this.history.push({ - state: oldState, - version: getVersion(state), - steps, - clientIDs, - sendable, - }) - - const transaction = receiveTransaction( - state, - steps, - clientIDs, - ) - - this.editor.view.dispatch(transaction) } }, 250), - receiveData({ steps }) { + receiveData({ steps, version }) { const { state, view, schema } = this.editor + if (getVersion(state) > version) { + return + } + const transaction = receiveTransaction( state, - steps.map(step => Step.fromJSON(schema, step)), - steps.map(step => step.clientID), + steps.map(item => Step.fromJSON(schema, item.step)), + steps.map(item => item.clientID), ) view.dispatch(transaction) }, - - repeat(val, n) { - const result = [] - for (let i = 0; i < n; i++) result.push(val) - return result - }, }, mounted() { this.socket = io('wss://tiptap-sockets-2.glitch.me') - .on('connect', () => { - console.log('connected') - }) - .on('disconnect', () => { - console.log('disconnected') - }) .on('document', data => { this.initEditor(data) }) - .on('update', data => { - this.receiveData(data) + .on('update', ({ steps, version }) => { + this.receiveData({ steps, version }) }) - .on('versionInSync', version => { - console.log('version in sync', version) - // TODO remove steps older than version - }) - .on('versionMismatch', ({ version, data, doc }) => { - console.log('version mismatch', version) - // TODO: go back to `version`, apply `steps`, apply unmerged `steps` - - const history = this.history.find(item => item.version === version) - const { state, view, schema } = this.editor - - // console.log('other steps', { data }) - - const newstate = history.state.apply(receiveTransaction( - history.state, - data.map(item => Step.fromJSON(schema, item.step)), - data.map(item => item.clientID), - )) - - // this.editor.state = - view.updateState(newstate) - - if (history.steps.length) { - view.dispatch(receiveTransaction( - state, - history.steps, - history.clientIDs, - )) - - // const sendable = sendableSteps(state) - // console.log({ sendable }) - - // this.socket.emit('update', { - // version: getVersion(state), - // steps: history.steps, - // }) - } - - - // const currentVersion = getVersion(view.state) - // const historySteps = history.steps - // console.log({ currentVersion, historySteps }) - - - // view.updateState(newstate2) - - // view.dispatch(receiveTransaction( - // view.state, - // data.map(item => Step.fromJSON(schema, item.step)), - // data.map(item => item.clientID), - // )) - - // console.log('own', { history }) - - // view.dispatch(receiveTransaction( - // history.state, - // history.steps, - // history.clientIDs, - // )) - - // const transaction = receiveTransaction( - // state, - // steps, - // clientIDs, - // ) - - // this.editor.view.dispatch(transaction) - }) - // .on('versionMismatch', (version, steps) => { - // // set state to the latest synced version? - // // this.editor.view.updateState(this.prevState) - - // const currentVersion = getVersion(this.editor.state) - // console.log('should poll version', currentVersion) - - // this.socket.emit('getVersionSteps', currentVersion) - // }) - // .on('versionSteps', data => { - // console.log('versionSteps', data) - // const { state, view, schema } = this.editor - - // const transaction = receiveTransaction( - // state, - // data.map(item => Step.fromJSON(schema, item.step)), - // data.map(item => item.clientID), - // ) - - // view.dispatch(transaction) - // }) }, beforeDestroy() { diff --git a/packages/tiptap/src/Editor.js b/packages/tiptap/src/Editor.js index 12fd34bbc..6228524ff 100644 --- a/packages/tiptap/src/Editor.js +++ b/packages/tiptap/src/Editor.js @@ -39,7 +39,6 @@ export default class Editor { onBlur: () => {}, onPaste: () => {}, onDrop: () => {}, - onTransaction: () => true, } this.init(options) @@ -284,10 +283,6 @@ export default class Editor { } dispatchTransaction(transaction) { - if (!this.options.onTransaction(transaction)) { - return - } - const oldState = this.state this.state = this.state.apply(transaction) From e9e50a2e75e7853e5119143928655135a4fdfcf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Fri, 3 May 2019 18:05:05 +0200 Subject: [PATCH 13/27] refactoring --- .../Components/Routes/Collaboration/index.vue | 83 +++----- .../Routes/Collaboration2/Collab.js | 24 --- .../Routes/Collaboration2/index.vue | 183 ------------------ .../Routes/Collaboration3/Collab.js | 24 --- .../Routes/Collaboration3/index.vue | 87 --------- examples/Components/Subnavigation/index.vue | 6 - examples/main.js | 14 -- 7 files changed, 27 insertions(+), 394 deletions(-) delete mode 100644 examples/Components/Routes/Collaboration2/Collab.js delete mode 100644 examples/Components/Routes/Collaboration2/index.vue delete mode 100644 examples/Components/Routes/Collaboration3/Collab.js delete mode 100644 examples/Components/Routes/Collaboration3/index.vue diff --git a/examples/Components/Routes/Collaboration/index.vue b/examples/Components/Routes/Collaboration/index.vue index 0d7620ebe..c3d84fa01 100644 --- a/examples/Components/Routes/Collaboration/index.vue +++ b/examples/Components/Routes/Collaboration/index.vue @@ -5,6 +5,8 @@ diff --git a/examples/Components/Routes/Collaboration3/Collab.js b/examples/Components/Routes/Collaboration3/Collab.js deleted file mode 100644 index 21dc7255f..000000000 --- a/examples/Components/Routes/Collaboration3/Collab.js +++ /dev/null @@ -1,24 +0,0 @@ -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/Collaboration3/index.vue b/examples/Components/Routes/Collaboration3/index.vue deleted file mode 100644 index 6301f7566..000000000 --- a/examples/Components/Routes/Collaboration3/index.vue +++ /dev/null @@ -1,87 +0,0 @@ - - - diff --git a/examples/Components/Subnavigation/index.vue b/examples/Components/Subnavigation/index.vue index 1ff9f9057..c4c3b796f 100644 --- a/examples/Components/Subnavigation/index.vue +++ b/examples/Components/Subnavigation/index.vue @@ -51,12 +51,6 @@ Collaboration - - Collaboration 2 - - - Collaboration 3 - diff --git a/examples/main.js b/examples/main.js index cd1249367..3102cc931 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 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 14/27] 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 c3d84fa01..c65c19196 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 15/27] 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 c65c19196..6ac6073d2 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 16/27] 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 9f8a0a192..ebc1a2539 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 21dc7255f..a59328b25 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 6ac6073d2..f7adc7cb4 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 89a88025f..9c62a81e3 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 26/27] 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 e7420bc47..19f5ab068 100644 --- a/examples/Components/Routes/Collaboration/index.vue +++ b/examples/Components/Routes/Collaboration/index.vue @@ -18,7 +18,15 @@