Skip to content
Snippets Groups Projects
Commit a787e3f8 authored by john's avatar john
Browse files

move all track changes selection helpers to their own file

parent 0420448e
No related branches found
No related tags found
No related merge requests found
import {
clone,
// each,
// filter,
// find,
findIndex,
includes,
keys,
// last,
map,
// maxBy,
// minBy,
pickBy,
some,
sortBy
} from 'lodash'
import {
// annotationHelpers,
TOCProvider
} from 'substance'
import { TOCProvider } from 'substance'
import {
// getAllAnnotationsByStatus,
getAnnotationByStatus,
isAnnotationFromTheSameUser,
isNotOnTrackAnnotation,
......@@ -42,20 +31,26 @@ import {
selectCharacterAndMarkDeleted
} from './utils/handlerHelpers'
// import { handleUndoRedo } from './utils/historyHandlers'
import {
isSelectionCollapsed,
isSelectionContainedWithin,
moveCursorTo,
updateSelection
} from './utils/selectionHelpers'
import {
// createTrackAnnotation,
deleteCharacter,
deleteSelection,
// expandTrackAnnotation,
insertText,
removeTrackAnnotation
// truncateTrackAnnotation
} from './utils/transformations'
class TrackChangesProvider extends TOCProvider {
constructor (document, config) {
super(document, config)
// config.documentSession.on('didUpdate', this.handleUndoRedo, this)
// config.documentSession.on('didUpdate', handleUndoRedo, this)
// handle button actions
const editor = this.config.controller
......@@ -75,7 +70,8 @@ class TrackChangesProvider extends TOCProvider {
*/
handleTransaction (options) {
options.editorSession = this.getEditorSession()
// options.editor = this.config.controller
options.editorSession = this.config.editorSession
options.selection = this.getSelection()
options.surface = this.getSurface()
options.user = this.config.user
......@@ -89,15 +85,13 @@ class TrackChangesProvider extends TOCProvider {
}
handleAdd (options) {
const isSelectionCollapsed = this.isSelectionCollapsed()
const isCollapsed = isSelectionCollapsed(options)
if (isSelectionCollapsed) return this.handleAddCollapsed(options)
if (!isSelectionCollapsed) return this.handleAddNonCollapsed(options)
if (isCollapsed) return this.handleAddCollapsed(options)
if (!isCollapsed) return this.handleAddNonCollapsed(options)
}
handleAddCollapsed (options) {
// const { event } = options
const notOnTrack = isNotOnTrackAnnotation(options)
const isOnAdd = isOnAnnotation(options, 'add')
const isOnDelete = isOnAnnotation(options, 'delete')
......@@ -135,13 +129,13 @@ class TrackChangesProvider extends TOCProvider {
const isOnLeftEdge = isSelectionOnLeftEdge(options, annotation)
const isOnRightEdge = isSelectionOnRightEdge(options, annotation)
const withinAnnotation = this.isSelectionContainedWithin(annotation, true)
const withinAnnotation = isSelectionContainedWithin(options, annotation, true)
// if contained within the delete annotation, move it to the edge,
// insert character, set event to null so that the character does
// not get inserted twice, and handle again
if (withinAnnotation) {
this.moveCursorTo(annotation.endOffset)
moveCursorTo(options, annotation.end.offset)
insertCharacterWithoutExpandingAnnotation(options, annotation)
options.selection = this.getSelection()
return this.handleAdd(options)
......@@ -169,18 +163,17 @@ class TrackChangesProvider extends TOCProvider {
const shortenBy = deleteAllOwnAdditions(options, selection)
const startOffset = selection.start.offset
const endOffset = selection.end.offset - shortenBy
selection = this.updateSelection(selection, startOffset, endOffset)
selection = updateSelection(options, selection, startOffset, endOffset)
options.selection = selection
if (isOnDelete) {
// console.log('on delete')
const annotation = getAnnotationByStatus(options, 'delete')
const withinAnnotation = this.isSelectionContainedWithin(annotation)
const withinAnnotation = isSelectionContainedWithin(options, annotation)
if (withinAnnotation) {
// if selection is wholly contained within a delete annotation,
// move to the end of the annotation and handle again
this.moveCursorTo(annotation.endOffset)
moveCursorTo(options, annotation.end.offset)
options.selection = this.getSelection()
return this.handleAddCollapsed(options)
}
......@@ -203,7 +196,7 @@ class TrackChangesProvider extends TOCProvider {
handleDelete (options) {
const { key, move } = options
const isSelectionCollapsed = this.isSelectionCollapsed()
const isCollapsed = isSelectionCollapsed(options)
options.direction = {
cursorTo: (move === 'left') ? 'start' : 'end',
......@@ -211,8 +204,8 @@ class TrackChangesProvider extends TOCProvider {
move: move
}
if (isSelectionCollapsed) return this.handleDeleteCollapsed(options)
if (!isSelectionCollapsed) return this.handleDeleteNonCollapsed(options)
if (isCollapsed) return this.handleDeleteCollapsed(options)
if (!isCollapsed) return this.handleDeleteNonCollapsed(options)
}
handleDeleteCollapsed (options) {
......@@ -273,7 +266,7 @@ class TrackChangesProvider extends TOCProvider {
}
if (moveOnly) {
return this.moveCursorTo(point)
return moveCursorTo(options, point)
}
if (isFromSameUser) {
......@@ -298,35 +291,23 @@ class TrackChangesProvider extends TOCProvider {
const startOffset = selection.start.offset
const endOffset = selection.end.offset - shortenBy
this.updateSelection(selection, startOffset, endOffset)
updateSelection(options, selection, startOffset, endOffset)
// TODO -- validate that this is not needed
// if (selection.isCollapsed()) return this.handleDeleteCollapsed(options)
if (selection.isCollapsed()) return
if (isOnDelete) {
// console.log
const annotation = getAnnotationByStatus(options, 'delete')
const containedWithin = this.isSelectionContainedWithin(annotation)
const containedWithin = isSelectionContainedWithin(options, annotation)
if (containedWithin) {
const point = annotation[direction.cursorTo + 'Offset']
return this.moveCursorTo(point)
return moveCursorTo(options, point)
}
// const selection = this.getSelection()
// this.expandTrackAnnotation(selection, annotation)
//
// const key = direction.key
//
// let point
// if (key === 'BACKSPACE') point = selection.startOffset
// if (key === 'DELETE') point = selection.endOffset
// this.moveCursorTo(point)
}
options.selection = deleteOrMergeAllOwnDeletions(options, selection)
// console.log(this.getSelection())
// options.selection = this.getSelection()
markSelectionAsDeleted(options)
}
......@@ -422,7 +403,7 @@ class TrackChangesProvider extends TOCProvider {
const selection = annotation.getSelection()
surface.editorSession.setSelection(selection)
this.moveCursorTo('start')
moveCursorTo({ surface }, 'start')
}
canAct () {
......@@ -431,121 +412,6 @@ class TrackChangesProvider extends TOCProvider {
return some(accepted, (role) => includes(user.roles, role))
}
/**
HISTORY HANDLERS
*/
// TODO -- shouldn't run both all the time
handleUndoRedo (update, info) {
if (!info.replay) return
// console.log('update', update)
// console.log('info', info)
// this.handleUndo(update)
// this.handleRedo(update)
}
handleUndo (update) {
const deleted = update.change.deleted
const deletedLength = keys(deleted).length
// console.log(keys(deleted))
if (deletedLength === 0) return
if (deletedLength > 1) {
return console.warn('FIXME: Multiple operations in track changes replay!')
}
const deletedOp = deleted[keys(deleted)[0]]
if (!deletedOp.type === 'track-change') return
const documentSession = this.getEditorSession()
documentSession.undo()
}
handleRedo () {
// const documentSession = this.getEditorSession()
// const undoneChanges = documentSession.undoneChanges
// const lastChange = last(undoneChanges)
// const op = last(lastChange.ops)
//
// const isTrack = op.path[0].split('-').slice(0, -1).join('-') === 'track-change
}
/*
SELECTION HANDLERS
*/
// isAnnotationContainedWithinSelection (annotation, strict) {
// const selection = this.getSelection()
// const annotationSelection = annotation.getSelection()
//
// return selection.contains(annotationSelection, strict)
// }
isSelectionCollapsed () {
const selection = this.getSelection()
const isCollapsed = selection.isCollapsed()
return isCollapsed
}
// TODO -- refactor this and isAnnotationContainedWithinSelection into one
isSelectionContainedWithin (annotation, strict) {
const selection = this.getSelection()
// console.trace()
const annotationSelection = annotation.getSelection()
return annotationSelection.contains(selection, strict)
// const leftSide = (selection.startOffset < annotation.startOffset)
// const rightSide = (selection.endOffset > annotation.endOffset)
//
// if (leftSide || rightSide) return false
// return true
}
moveCursorTo (point, sel) {
const selection = sel || this.getSelection()
const surface = this.getSurface()
// TODO -- use substance's selection.collapse(direction)
if (point === 'start') {
selection.end.offset = selection.start.offset
} else if (point === 'end') {
selection.start.offset = selection.end.offset
} else {
selection.start.offset = point
selection.end.offset = point
}
surface.editorSession.setSelection(selection)
}
// setSelectionPlusOne (direction) {
// const selection = this.getSelection()
// const surface = this.getSurface()
//
// if (direction === 'left') selection.start.offset -= 1
// if (direction === 'right') selection.end.offset += 1
//
// surface.editorSession.setSelection(selection)
//
// return selection
// }
updateSelection (selection, startOffset, endOffset) {
const surface = this.getSurface()
selection.start.offset = startOffset
selection.end.offset = endOffset
surface.editorSession.setSelection(selection)
return selection
}
/*
GETTERS
......@@ -556,14 +422,6 @@ class TrackChangesProvider extends TOCProvider {
return this.config.commandManager
}
getCurrentUser () {
return this.config.user.id
}
getEditorSession () {
return this.config.editorSession
}
getMode () {
const trackState = this.getTrackState()
return trackState.mode
......
......@@ -101,6 +101,8 @@ const deleteSelectedAndCreateAddition = (options) => {
// selection is now collapsed, so handle it as collapsed
options.status = 'add'
options.selection = getSelection(options.surface)
const provider = getProvider(options)
provider.handleAddCollapsed(options)
}
......@@ -132,18 +134,24 @@ const insertCharacterWithAddAnnotation = (options) => {
}
const insertCharacterWithoutExpandingAnnotation = (options, annotation) => {
// After text has been inserted, set the event to null to make sure it does
// not get added twice by a second iteration of the handlers.
// eg. if at the end of the logic path, handleAddCollapsed gets called
// that will assume that there is text still to be inserted
insertText(options)
options.event = null
options.selection = getSelection(options.surface)
options.selection = setSelectionPlusOne(options, 'left')
// options.selection = selection
options.annotation = annotation
options.doc = options.editorSession.getDocument()
// Clone the options, to make sure that the annotation or the selection
// does not change while the truncate operation is in progress.
const opts = clone(options)
truncateTrackAnnotation(options)
moveCursorTo(options, 'end')
opts.selection = getSelection(opts.surface)
opts.selection = setSelectionPlusOne(opts, 'left')
opts.annotation = annotation
opts.doc = opts.editorSession.getDocument() // TODO -- should get from handler
options.event = null // ?
truncateTrackAnnotation(opts)
moveCursorTo(opts, 'end')
}
const markSelectionAsDeleted = (options) => {
......
// TODO -- shouldn't run both all the time
const handleUndoRedo = (update, info) => {
if (!info.replay) return
// console.log('update', update)
// console.log('info', info)
// this.handleUndo(update)
// this.handleRedo(update)
}
// const handleUndo = (update) => {
// const deleted = update.change.deleted
// const deletedLength = keys(deleted).length
//
// // console.log(keys(deleted))
//
// if (deletedLength === 0) return
// if (deletedLength > 1) {
// return console.warn('FIXME: Multiple operations in track changes replay!')
// }
//
// const deletedOp = deleted[keys(deleted)[0]]
// if (!deletedOp.type === 'track-change') return
//
// const documentSession = this.getEditorSession()
// documentSession.undo()
// }
// const handleRedo = () => {
// // const documentSession = this.getEditorSession()
// // const undoneChanges = documentSession.undoneChanges
// // const lastChange = last(undoneChanges)
// // const op = last(lastChange.ops)
// //
// // const isTrack = op.path[0].split('-').slice(0, -1).join('-') === 'track-change
// }
export {
handleUndoRedo
}
......@@ -2,9 +2,34 @@ const getSelection = (surface) => {
return surface.domSelection.getSelection()
}
const isSelectionCollapsed = (options) => {
// const selection = this.getSelection()
const { selection } = options
const isCollapsed = selection.isCollapsed()
return isCollapsed
}
// TODO -- refactor this and isAnnotationContainedWithinSelection into one
const isSelectionContainedWithin = (options, annotation, strict) => {
// const selection = this.getSelection()
const selection = getSelection(options.surface)
const annotationSelection = annotation.getSelection()
return annotationSelection.contains(selection, strict)
// const leftSide = (selection.startOffset < annotation.startOffset)
// const rightSide = (selection.endOffset > annotation.endOffset)
//
// if (leftSide || rightSide) return false
// return true
}
const moveCursorTo = (options, point) => {
// const selection = sel || this.getSelection()
const { selection, surface } = options
// const { selection, surface } = options
const { surface } = options
const selection = getSelection(surface)
// const surface = this.getSurface()
// TODO -- use substance's selection.collapse(direction)
......@@ -32,8 +57,21 @@ const setSelectionPlusOne = (options, direction) => {
return selection
}
const updateSelection = (options, selection, startOffset, endOffset) => {
const { surface } = options
selection.start.offset = startOffset
selection.end.offset = endOffset
surface.editorSession.setSelection(selection)
return selection
}
export {
getSelection,
isSelectionCollapsed,
isSelectionContainedWithin,
moveCursorTo,
setSelectionPlusOne
setSelectionPlusOne,
updateSelection
}
......@@ -125,6 +125,7 @@ const truncateTrackAnnotation = options => {
const info = getInfo()
const transformation = (tx, args) => {
// console.log(selection)
annotationHelpers.truncateAnnotation(doc, annotation, selection)
}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment