From 6abd1665f28dbbfe6bd63958e3e8653f2dd03c16 Mon Sep 17 00:00:00 2001 From: barlas <yannisbarlas@gmail.com> Date: Wed, 28 Dec 2016 14:44:58 +0200 Subject: [PATCH] basic deletion track changes funcionality --- .../SimpleEditor/ContainerEditor.js | 64 +++++++- .../elements/track_change/TrackChange.js | 4 + .../track_change/TrackChangeComponent.js | 6 +- .../track_change/TrackChangesProvider.js | 149 ++++++++++++++++-- .../elements/track_change/trackChange.scss | 13 ++ 5 files changed, 215 insertions(+), 21 deletions(-) diff --git a/app/components/SimpleEditor/ContainerEditor.js b/app/components/SimpleEditor/ContainerEditor.js index 05d6892..8d5ccc2 100644 --- a/app/components/SimpleEditor/ContainerEditor.js +++ b/app/components/SimpleEditor/ContainerEditor.js @@ -1,6 +1,8 @@ import { each, keys, includes } from 'lodash' import { ContainerEditor as SubstanceContainerEditor, + // deleteCharacter, + // deleteSelection, Surface, uuid } from 'substance' @@ -53,6 +55,7 @@ class ContainerEditor extends SubstanceContainerEditor { // // console.log(this.context.commandManager.getCommandStates().strong.mode) // // console.log(this.context.commandManager.getCommandStates()['track-change'].mode) // console.log('\n did update') + // console.log(this.getCommandStates()) // console.log('change', change) // console.log('info', info) // @@ -70,25 +73,72 @@ class ContainerEditor extends SubstanceContainerEditor { } onTextInput (event) { + // console.log(this.context) event.preventDefault() event.stopPropagation() if (!event.data) return this._state.skipNextObservation = true - this.transaction(function (tx, args) { - if (this.domSelection) this.domSelection.clear() - args.text = event.data - return this.insertText(tx, args) - }.bind(this), { action: 'type' }) + if (!this.props.trackChanges) { + this.transaction(function (tx, args) { + if (this.domSelection) this.domSelection.clear() + args.text = event.data + return this.insertText(tx, args) + }.bind(this), { action: 'type' }) + return + } + + const trackChangesProvider = this.context.trackChangesProvider + const status = 'add' + trackChangesProvider.handleTransaction(event, status) + + // const isSelCollapsed = this.getSelection().isCollapsed() + // if (!isSelCollapsed) { + // const trackChangesProvider = this.context.trackChangesProvider + // const status = 'delete' + // trackChangesProvider.handleTransaction(status) + // } + // + // this.transaction(function (tx, args) { + // if (this.domSelection) this.domSelection.clear() + // args.text = event.data + // return this.insertText(tx, args) + // }.bind(this), { action: 'type' }) + // + // // don't rewrite the above, call it with super + // if (this.props.trackChanges) { + // const status = 'add' + // trackChangesProvider.handleTransaction(status) + // } + } + + _handleDeleteKey (event) { + event.preventDefault() + event.stopPropagation() + let direction = (event.keyCode === keys.BACKSPACE) ? 'left' : 'right' - // don't rewrite the above, call it with super if (this.props.trackChanges) { const trackChangesProvider = this.context.trackChangesProvider - trackChangesProvider.handleTransaction() + const status = 'delete' + trackChangesProvider.handleTransaction(event, status, direction) + } else { + this.transaction(function (tx, args) { + args.direction = direction + return this.delete(tx, args) + }.bind(this), { action: 'delete' }) } } + // delete (tx, args) { + // let sel = args.selection + // if (!sel.isCollapsed()) { + // return deleteSelection(tx, args) + // } else if (sel.isPropertySelection() || sel.isNodeSelection()) { + // return deleteCharacter(tx, args) + // } + // } + // create an empty paragraph with an empty node // then select it for cursor focus createText () { diff --git a/app/components/SimpleEditor/elements/track_change/TrackChange.js b/app/components/SimpleEditor/elements/track_change/TrackChange.js index 2de7707..d768fa7 100644 --- a/app/components/SimpleEditor/elements/track_change/TrackChange.js +++ b/app/components/SimpleEditor/elements/track_change/TrackChange.js @@ -2,6 +2,10 @@ import { PropertyAnnotation } from 'substance' class TrackChange extends PropertyAnnotation {} +TrackChange.define({ + status: { type: 'string' } +}) + TrackChange.type = 'track-change' export default TrackChange diff --git a/app/components/SimpleEditor/elements/track_change/TrackChangeComponent.js b/app/components/SimpleEditor/elements/track_change/TrackChangeComponent.js index 0373ac2..fb744b2 100644 --- a/app/components/SimpleEditor/elements/track_change/TrackChangeComponent.js +++ b/app/components/SimpleEditor/elements/track_change/TrackChangeComponent.js @@ -3,14 +3,18 @@ import { AnnotationComponent } from 'substance' class TrackChangeComponent extends AnnotationComponent { render ($$) { const user = this.context.controller.props.user + const status = this.props.node.status var el = $$('span') .attr('data-id', this.props.node.id) .attr('data-user', user.username) .attr('data-role', user.teams[0].name) .addClass(this.getClassNames()) + .append(this.props.children) + + const className = 'sc-track-change-' + status + el.addClass(className) - el.append(this.props.children) return el } diff --git a/app/components/SimpleEditor/elements/track_change/TrackChangesProvider.js b/app/components/SimpleEditor/elements/track_change/TrackChangesProvider.js index 059e282..4325616 100644 --- a/app/components/SimpleEditor/elements/track_change/TrackChangesProvider.js +++ b/app/components/SimpleEditor/elements/track_change/TrackChangesProvider.js @@ -1,5 +1,5 @@ import { keys, last } from 'lodash' -import { createAnnotation } from 'substance' +import { createAnnotation, expandAnnotation } from 'substance' class TrackChangesProvider { constructor (config) { @@ -7,9 +7,43 @@ class TrackChangesProvider { this.config.documentSession.on('didUpdate', this.handleUndoRedo, this) } - handleTransaction () { + handleTransaction (event, status) { + if (status === 'add') { + const isSelCollapsed = this.isSelectionCollapsed() + if (!isSelCollapsed) { + const options = { 'deleteCollapsed': true } + this.createDeletionAnnotation(options) + } + this.insertText(event) + this.createAdditionAnnotation() + return + } + + if (status === 'delete') { + this.createDeletionAnnotation() + return + } + } + + insertText (event) { + const surface = this.getSurface() + surface.transaction(function (tx, args) { + if (surface.domSelection) surface.domSelection.clear() + args.text = event.data + return surface.insertText(tx, args) + }, { action: 'type' }) + } + + onDeleteAnnotation () { + const anno = this.getExistingAnnotation() + const isDelete = (anno.status === 'delete') + return isDelete + } + + createAdditionAnnotation () { const mode = this.getMode() - if (mode) return + const onDelete = this.onDeleteAnnotation() + if (mode && !onDelete) return const surface = this.getSurface() @@ -18,27 +52,109 @@ class TrackChangesProvider { const newNode = { selection: selection, - node: { 'type': 'track-change' } + node: { + 'status': 'add', + 'type': 'track-change' + } } createAnnotation(tx, newNode) - this.clearSelection(args) - // this.removeAnnotationFromHistory() + this.clearSelection(args, 'add') } - const info = { - track: true + const info = {} + surface.transaction(transformation, info) + + surface.transaction((tx, args) => { + if (onDelete) { + // console.log(this.getAllExistingAnnotations()) + const annos = this.getAllExistingAnnotations() + const deleteAnno = annos.find((obj) => { + // console.log(obj) + return obj.type === 'track-change' && obj.status === 'delete' + }) + const addAnno = annos.find((obj) => { + // console.log(obj) + return obj.type === 'track-change' && obj.status === 'add' + }) + // console.log(deleteAnno) + deleteAnno.updateRange(tx, { + start: { + startPath: deleteAnno.startPath, + offset: deleteAnno.startOffset + }, + end: { + offset: addAnno.startOffset + } + }) + // deleteAnno.endOffset = addAnno.startOffset + // console.log(deleteAnno) + } + }) + } + + getExistingAnnotation () { + const documentSession = this.getDocumentSession() + const selectionState = documentSession.getSelectionState() + const annotations = selectionState.getAnnotationsForType('track-change') + return annotations[0] + } + + getAllExistingAnnotations () { + const documentSession = this.getDocumentSession() + const selectionState = documentSession.getSelectionState() + const annotations = selectionState.getAnnotationsForType('track-change') + return annotations + } + + createDeletionAnnotation (options) { + let deleteCollapsed + if (options && options.deleteCollapsed) deleteCollapsed = true + + const surface = this.getSurface() + const mode = this.getMode() + + const transformation = (tx, args) => { + let selection = args.selection + if (!deleteCollapsed) selection = this.createSelection(args) + + if (mode === 'delete') { + args.anno = this.getExistingAnnotation() + expandAnnotation(tx, args) + } else { + const newNode = { + selection: selection, + node: { + 'status': 'delete', + 'type': 'track-change' + } + } + + createAnnotation(tx, newNode) + } + + args.deleteCollapsed = deleteCollapsed + this.clearSelection(args, 'delete') } + const info = {} surface.transaction(transformation, info) } + isSelectionCollapsed () { + const surface = this.getSurface() + const selection = surface.getSelection() + const isCollapsed = selection.isCollapsed() + return isCollapsed + } + + // TODO -- shouldn't run both all the time handleUndoRedo (update, info) { if (!info.replay) return - console.log(update) - console.log(info) + // console.log(update) + // console.log(info) this.handleUndo(update) - this.handleRedo(update) + // this.handleRedo(update) } handleUndo (update) { @@ -78,9 +194,16 @@ class TrackChangesProvider { // }) // ensure that text insertion has finished // } - clearSelection (args) { + clearSelection (args, status) { const selection = args.selection - selection.startOffset = selection.endOffset + if ( + status === 'add' || + (status === 'delete' && args.deleteCollapsed) + ) { + selection.startOffset = selection.endOffset + } else if (status === 'delete') { + selection.endOffset = selection.startOffset + } return selection } diff --git a/app/components/SimpleEditor/elements/track_change/trackChange.scss b/app/components/SimpleEditor/elements/track_change/trackChange.scss index d995404..bd8eb65 100644 --- a/app/components/SimpleEditor/elements/track_change/trackChange.scss +++ b/app/components/SimpleEditor/elements/track_change/trackChange.scss @@ -1,3 +1,16 @@ .sc-track-change { + // background-color: #f7f70c; +} + +.sc-track-change-add { background-color: #f7f70c; } + +.sc-track-change-delete { + background-color: red; + text-decoration: line-through; + + .sc-track-change-add { + text-decoration: none !important; + } +} -- GitLab