Newer
Older
import { each, keys, includes } from 'lodash'
import {
ContainerEditor as SubstanceContainerEditor,
// deleteCharacter,
// deleteSelection,
} from 'substance'
class ContainerEditor extends SubstanceContainerEditor {
render ($$) {
// TODO -- better ways to write this in es6
var el = Surface.prototype.render.call(this, $$)
var doc = this.getDocument()
var containerId = this.getContainerId()
var containerNode = doc.get(containerId)
if (!containerNode) {
console.warn('No container node found for ', containerId)
}
el.addClass('sc-container-editor container-node ' + containerId)
.attr({
spellCheck: false,
'data-id': containerId
})
// if it IS empty, handle in didMount
if (!this.isEmpty()) {
containerNode.getNodes().forEach(function (node) {
el.append(this._renderNode($$, node).ref(node.id))
}.bind(this))
}
// TODO -- should maybe change to isEditable ?
// or maybe delete it? we never pass a disabled prop explicitly
if (!this.props.disabled) {
el.addClass('sm-enabled')
el.setAttribute('contenteditable', true)
}
return el
}
didMount () {
// TODO -- replace with super.didMount()
Surface.prototype.didMount.apply(this, arguments)
this.container.on('nodes:changed', this.onContainerChange, this)
// this.context.documentSession.on('didUpdate', (change, info) => {
// // console.log(this.getSelection())
// // 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)
//
// if (info.track) change.change.info.track = true
// }, this)
if (this.isEmpty()) this.createText()
if (this.isReadOnlyMode()) {
const documentSession = this.getDocumentSession()
documentSession.on('didUpdate', this.disableToolbar, this)
this.addTargetToLinks()
}
}
onTextInput (event) {
event.preventDefault()
event.stopPropagation()
if (!event.data) return
this._state.skipNextObservation = true
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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'
const trackChangesProvider = this.context.trackChangesProvider
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
var newSel
this.transaction(function (tx) {
var container = tx.get(this.props.containerId)
var textType = tx.getSchema().getDefaultTextType()
var node = tx.create({
id: uuid(textType),
type: textType,
content: ''
})
container.show(node.id)
newSel = tx.createSelection({
type: 'property',
path: [ node.id, 'content' ],
startOffset: 0,
endOffset: 0
})
}.bind(this))
this.rerender()
this.setSelection(newSel)
}
// only runs if editor is in read-only mode
// disables all tools, apart from comments
disableToolbar () {
const commandStates = this.getCommandStates()
each(keys(commandStates), key => {
const allowed = ['comment', 'note', 'save', 'undo', 'redo']
if (!includes(allowed, key)) commandStates[key].disabled = true
})
}
getCommandStates () {
const commandManager = this.context.commandManager
return commandManager.getCommandStates()
}
isReadOnlyMode () {
return !this.isEditable() && this.isSelectable()
}
const allLinks = this.el.findAll('a')
each(allLinks, link =>
link.attr('target', '_blank')
)
}