diff --git a/app/components/SimpleEditor/elements/note/note.scss b/app/components/SimpleEditor/elements/note/note.scss index 900d1f293cd29ba5c73d400f02515c62a8bda292..01a3748a232e95ebcac32b8ee34ca51fa035aeb8 100644 --- a/app/components/SimpleEditor/elements/note/note.scss +++ b/app/components/SimpleEditor/elements/note/note.scss @@ -29,7 +29,7 @@ $blue: #4990e2; .sc-note { cursor: pointer; - display: inherit; + display: block; height: 18px; position: relative; text-align: center; diff --git a/app/components/SimpleEditor/elements/track_change/TrackChangesProvider.js b/app/components/SimpleEditor/elements/track_change/TrackChangesProvider.js index bcebbae00f37ff39e788f67011c6980efcebe0fe..147f307eeb65b4393acd913263a7a3ba0494990c 100644 --- a/app/components/SimpleEditor/elements/track_change/TrackChangesProvider.js +++ b/app/components/SimpleEditor/elements/track_change/TrackChangesProvider.js @@ -312,6 +312,251 @@ class TrackChangesProvider extends TOCProvider { markSelectionAsDeleted(options) } + /* + HANDLER COMMON FUNCTIONS + */ + + createAdditionAnnotationOnLastChar () { + const selection = this.setSelectionPlusOne('left') + this.createAddAnnotation(selection) + this.moveCursorTo('end') + } + + deleteAllOwnAdditions (selection) { + const originalSelection = selection || this.getSelection() + let shortenBy = 0 + + const additions = this.getAllAnnotationsByStatus('add') + const ownAdditions = filter(additions, annotation => { + return this.isAnnotationFromTheSameUser(annotation) + }) + + each(ownAdditions, (annotation) => { + const selection = annotation.getSelection() + + // make sure only the part of the annotation that is selected is deleted + if (annotation.startOffset < originalSelection.startOffset) { + selection.startOffset = originalSelection.startOffset + } + + if (annotation.endOffset > originalSelection.endOffset) { + selection.endOffset = originalSelection.endOffset + } + + shortenBy += (selection.endOffset - selection.startOffset) + this.deleteSelection(selection) + }) + + return shortenBy // return how much shorter the selection should now be + } + + deleteOrMergeAllOwnDeletions (selection) { + const deletions = clone(this.getAllAnnotationsByStatus('delete')) + const ownDeletions = filter(deletions, annotation => { + return this.isAnnotationFromTheSameUser(annotation) + }) + + const selectionArray = [selection] + + each(ownDeletions, (annotation) => { + const annotationSelection = annotation.getSelection() + const contained = selection.contains(annotationSelection) + + if (!contained) { + selectionArray.push(annotationSelection) + } + + this.removeTrackAnnotation(annotation) + }) + + selection.start.offset = minBy(selectionArray, 'start.offset').start.offset + selection.end.offset = maxBy(selectionArray, 'end.offset').end.offset + + return selection + // TODO + // this.updateSelection(selection, startOffset, endOffset) + } + + deleteSelectedAndCreateAddition (options) { + let { selection } = options + + this.createDeleteAnnotation(selection) + this.moveCursorTo('end', selection) + + // selection is now collapsed, so handle it as collapsed + this.handleAddCollapsed(options) + } + + expandAnnotationToDirection (annotation, options) { + if (!options) options = {} + const move = options.move || 'left' + const cursorTo = options.cursorTo || 'end' + + const selection = this.setSelectionPlusOne(move) + this.expandTrackAnnotation(selection, annotation) + this.moveCursorTo(cursorTo) + } + + insertCharacterWithAddAnnotation (options) { + const { event } = options + this.insertText(event) + + // TODO -- watch it with additions by other users + this.createAdditionAnnotationOnLastChar() + } + + insertCharacterWithoutExpandingAnnotation (annotation, options) { + const { event } = options + let selection = options + + this.insertText(event) + selection = this.setSelectionPlusOne('left') + this.truncateTrackAnnotation(selection, annotation) + this.moveCursorTo('end') + + options.event = null + } + + markSelectionAsDeleted (options) { + const { direction, selection } = options + this.createDeleteAnnotation(selection) + this.moveCursorTo(direction.cursorTo) + } + + selectCharacterAndMarkDeleted (options) { + const { direction } = options + const selection = this.setSelectionPlusOne(direction.move) + + this.createDeleteAnnotation(selection) + this.moveCursorTo(direction.cursorTo) + } + + /* + + TRANSFORMATIONS + + */ + + createAddAnnotation (selection) { + this.createTrackAnnotation(selection, 'add') + } + + createDeleteAnnotation (selection) { + this.createTrackAnnotation(selection, 'delete') + } + + // TODO -- selection could default to current selection + createTrackAnnotation (selection, status) { + const surface = this.getSurface() + const info = this.getInfo() + const { user } = this.config + + if (selection.isContainerSelection()) { + return console.warn('Cannot delete a container') + } + + if (selection.isNodeSelection()) { + if (selection.isCollapsed()) return this.deleteCharacter('left') + return this.deleteSelection(selection) + } + + const transformation = (tx, args) => { + const newNode = { + selection: selection, + status: status, + type: 'track-change', + path: selection.path, + start: selection.start, + end: selection.end, + user: { + id: user.id, + roles: user.roles, + username: user.username + } + } + tx.create(newNode) + } + + surface.editorSession.transaction(transformation, info) + } + + deleteCharacter (direction) { + const surface = this.getSurface() + const info = { action: 'delete' } + + const transformation = (tx, args) => { + args.direction = direction + return tx.deleteCharacter(direction) + } + + surface.editorSession.transaction(transformation, info) + } + + deleteSelection (selection) { + const containerId = this.config.containerId + const surface = this.getSurface() + const info = { action: 'delete' } + const transformation = (tx, args) => { + tx.setSelection({ + type: 'property', + path: selection.path, + surfaceId: containerId, + startOffset: selection.start.offset, + endOffset: selection.end.offset + }) + return tx.deleteSelection() + } + + surface.editorSession.transaction(transformation, info) + } + + expandTrackAnnotation (selection, annotation) { + const surface = this.getSurface() + const info = this.getInfo() + + const transformation = (tx, args) => { + args.selection = selection + args.anno = annotation + + annotationHelpers.expandAnnotation(tx, args.anno, args.selection) + } + + surface.editorSession.transaction(transformation, info) + } + + insertText (event) { + if (!event) return + const surface = this.getSurface() + + surface.editorSession.transaction(function (tx, args) { + if (surface.domSelection) surface.domSelection.clear() + args.text = event.data || ' ' // if no data, it's a space key + return tx.insertText(args.text) + }, { action: 'type' }) + } + + removeTrackAnnotation (annotation) { + const surface = this.getSurface() + + const transformation = (tx, args) => { + tx.delete(annotation.id) + } + + surface.editorSession.transaction(transformation) + } + + truncateTrackAnnotation (selection, annotation) { + const surface = this.getSurface() + const info = this.getInfo() + const doc = this.getDocument() + + const transformation = (tx, args) => { + annotationHelpers.truncateAnnotation(doc, annotation, selection) + } + + surface.editorSession.transaction(transformation, info) + } + /* ACCEPT / REJECT @@ -359,8 +604,9 @@ class TrackChangesProvider extends TOCProvider { sortNodes (nodes) { const changes = clone(nodes) + const containerId = this.config.containerId const doc = this.getDocument() - const container = doc.get('body') + const container = doc.get(containerId) const changesArray = map(changes, annotation => { const blockId = annotation.path[0] diff --git a/app/components/SimpleEditor/notesEditor/NotesEditor.js b/app/components/SimpleEditor/notesEditor/NotesEditor.js index cfe2492b7a9d96d42b8dca6ecc02e65a2d7388a8..faf7b5d4f1bce9bd2c5701d4611b87b4e2fa9ad3 100644 --- a/app/components/SimpleEditor/notesEditor/NotesEditor.js +++ b/app/components/SimpleEditor/notesEditor/NotesEditor.js @@ -93,6 +93,7 @@ class NotesEditor extends ProseEditor { } findNote () { + console.log('find') const selection = this.editorSession.getSelection() if (!selection.end) return const isolatedNoteId = selection.end.path[0]