import { each, includes, keys } from 'lodash' import { documentHelpers, EditorSession, ProseEditorConfigurator as Configurator, Tool } from 'substance' import MiniEditor from '../../miniEditor/miniEditor' import config from '../../miniEditor/config' import Importer from '../../SimpleEditorImporter' import SimpleExporter from '../../SimpleEditorExporter' class EditNoteTool extends Tool { constructor (props) { super(props) this.saveNote = this.saveNote.bind(this) } render ($$) { const miniEditorSession = this._initMiniEditor() const selected = this.getSelection() const provider = this.getProvider() let el = $$('div').addClass('sc-edit-note-tool') if (!selected.node) return el el.append($$(MiniEditor, { editorSession: miniEditorSession })) provider.config.miniEditorContext.editor.emit('noteSelected', 'paragraph-71bf75436a5f9b56700064c6ee2116ab') return el } didMount () { this.context.editorSession.onUpdate('', this.disableTools, this) } _initMiniEditor () { const selected = this.getSelection() if (!selected.node) return const configurator = new Configurator().import(config) configurator.addImporter('html', Importer) const importer = configurator.createImporter('html') const doc = importer.importDocument(selected.node['note-content']) const editorSession = new EditorSession(doc, { configurator: configurator }) editorSession.setSaveHandler({ saveDocument: this.saveNote }) return editorSession } disableTools () { const selected = this.getSelection() if (!selected.node) return const commandStates = this.context.commandManager.commandStates each(keys(commandStates), (key) => { const allowed = ['comment', 'redo', 'save', 'switch-text-type', 'undo', 'note'] if (!includes(allowed, key)) commandStates[key].disabled = true }) this.rerender() } saveNote (source) { const selected = this.getSelection() const config = this.context.editorSession.configurator.config const exporter = new SimpleExporter(config) const convertedSource = exporter.exportDocument(source) const editorSession = this.context.editorSession editorSession.transaction(function (tx, args) { const path = [selected.node.id, 'note-content'] tx.set(path, convertedSource) }) // Return dummy Promise needed in saveDocument return new Promise(function (resolve, reject) { resolve() }) } getSelection () { // TODO -- write cleaner const surface = this.context.surfaceManager.getFocusedSurface() if (!surface) return {} const session = this.context.editorSession const sel = session.getSelection() const notes = documentHelpers.getPropertyAnnotationsForSelection( session.getDocument(), sel, { type: 'note' } ) const note = notes[0] let show = false if (typeof note !== 'undefined') { if ((sel.start.offset === note.start.offset && sel.end.offset === note.end.offset)) { show = true } } // disable when larger selection that just includes a note as well // const selectionLength = (sel.end.offset - sel.start.offset === 1) // if (sel.end.offset - sel.) if (show) { return { node: note } } else { return { node: null } } } getProvider () { return this.context.notesProvider } getSurface () { const surfaceManager = this.context.surfaceManager return surfaceManager.getFocusedSurface() } isEditorReadOnly () { const surface = this.getSurface() return surface.isReadOnlyMode() } } EditNoteTool.type = 'edit-note' export default EditNoteTool