UNPKG

@atlaskit/editor-core

Version:

A package contains Atlassian editor core functionality

137 lines (110 loc) 3.62 kB
import { EditorView, TextSelection, Node } from '../../prosemirror'; import { getEditorValueWithMedia, insertFileFromDataUrl } from '../utils'; import { Transformer } from '../../transformers'; export default class EditorActions { private editorView?: EditorView; private contentTransformer?: Transformer<string>; // This method needs to be public for context based helper components. _privateGetEditorView(): EditorView | undefined { return this.editorView; } // This method needs to be public for EditorContext component. _privateRegisterEditor(editorView: EditorView, contentTransformer?: Transformer<string>): void { if (!this.editorView && editorView) { this.editorView = editorView; } else if (this.editorView !== editorView) { throw new Error('Editor has already been registered! It\'s not allowed to re-register editor with the new Editor instance.'); } this.contentTransformer = contentTransformer; } // This method needs to be public for EditorContext component. _privateUnregisterEditor(): void { this.editorView = undefined; } focus(): boolean { if (!this.editorView || this.editorView.hasFocus()) { return false; } this.editorView.focus(); return true; } blur(): boolean { if (!this.editorView || !this.editorView.hasFocus()) { return false; } this.editorView.dom.blur(); return true; } clear(): boolean { if (!this.editorView) { return false; } const editorView = this.editorView; const { state } = editorView; const tr = editorView.state.tr .setSelection(TextSelection.create(state.doc, 0, state.doc.nodeSize - 2)) .deleteSelection(); editorView.dispatch(tr); return true; } getValue(): Promise<string | Node | undefined> { return getEditorValueWithMedia(this.editorView && this.editorView.state).then(doc => { if (this.contentTransformer && doc) { return this.contentTransformer.encode(doc); } return doc; }); } replaceDocument(rawValue: Node | string | Object): boolean { if (!this.editorView || !rawValue) { return false; } const state = this.editorView.state; const schema = state.schema; let value; if (typeof rawValue === 'string') { try { value = JSON.parse(rawValue); } catch (e) { return false; } } else if (rawValue instanceof Node) { // If rawValue is instance of Node we convert it to JSON and re-create children, // so we get completely new document instead of changing the one that was passed to us value = rawValue.toJSON(); } else { value = rawValue; } const content = (value.content || []).map(child => schema.nodeFromJSON(child)); if (!content.length) { return false; } const tr = state.tr .replaceWith(0, state.doc.nodeSize - 2, content) .scrollIntoView(); this.editorView.dispatch(tr); return true; } appendText(text: string): boolean { if (!this.editorView || !text) { return false; } const { state } = this.editorView; const lastChild = state.doc.lastChild; if (lastChild && lastChild.type !== state.schema.nodes.paragraph) { return false; } const tr = state.tr .insertText(text) .scrollIntoView(); this.editorView.dispatch(tr); return true; } insertFileFromDataUrl(url: string, filename: string): boolean { if (!this.editorView) { return false; } insertFileFromDataUrl(this.editorView.state, url, filename); return true; } }