@atlaskit/editor-core
Version:
A package contains Atlassian editor core functionality
109 lines (94 loc) • 2.59 kB
text/typescript
import {
Plugin,
Schema,
EditorState,
EditorView,
baseKeymap,
keymap,
} from '../prosemirror';
import { default as defaultSchema } from './schema';
import { RefsNode, Refs } from './schema-builder';
import { setTextSelection } from '../utils';
import { reactNodeViewPlugins } from '../plugins';
/**
* Build a ProseMirror instance.
*
* Initial selection can be indicated using refs:
*
* - `<>` -- a collapsed text selection
* - `<` and `>` -- a range text selection (`<` is from, `>` is to).
*/
export default <T> (options: Options): EditorInstance<T> => {
const plugins: Plugin[] = [];
const schema = options.schema || defaultSchema;
const fixture = document.body.appendChild(document.createElement('div'));
if (options.plugin) {
plugins.push(options.plugin);
}
if (options.plugins) {
plugins.push(...options.plugins);
}
plugins.push(
...reactNodeViewPlugins(schema),
keymap(baseKeymap)
);
const editorState = EditorState.create({
plugins,
doc: options.doc,
schema: schema,
}) as ProseMirrorWithRefs;
const editorView = new EditorView(fixture, {
state: editorState,
nodeViews: options.nodeViews || {},
});
const { refs } = editorState.doc;
// Collapsed selection.
if ('<>' in refs) {
setTextSelection(editorView, refs['<>']);
// Expanded selection
} else if ('<' in refs || '>' in refs) {
if ('<' in refs === false) {
throw new Error('A `<` ref must complement a `>` ref.');
}
if ('>' in refs === false) {
throw new Error('A `>` ref must complement a `<` ref.');
}
setTextSelection(editorView, refs['<'], refs['>']);
}
const pluginStates = plugins.map((plugin) => plugin.getState(editorState));
afterEach(() => {
editorView.destroy();
plugins.forEach((plugin: any) => plugin.destroy! && plugin.destroy());
if (fixture && fixture.parentNode === document.body) {
document.body.removeChild(fixture);
}
});
return {
editorView,
plugins,
pluginStates: pluginStates,
refs,
plugin: plugins[0],
pluginState: plugins[0].getState(editorState) as T,
sel: refs['<>']
};
};
export interface ProseMirrorWithRefs extends EditorState<Schema<any, any>> {
doc: RefsNode;
}
export interface Options {
doc: RefsNode;
plugin?: Plugin;
plugins?: Plugin[];
nodeViews?: { [key: string]: any };
schema?: Schema<any, any>;
}
export interface EditorInstance<T> {
editorView: EditorView;
pluginState: T;
pluginStates: any[];
plugin: Plugin;
plugins: Plugin[];
refs: Refs;
sel: number;
}