Newer
Older
import React, { useContext, useRef, useEffect } from 'react';
import styled from 'styled-components';
import { EditorView } from 'prosemirror-view';
import { EditorState, TextSelection, NodeSelection } from 'prosemirror-state';
import { dropCursor } from 'prosemirror-dropcursor';
import { gapCursor } from 'prosemirror-gapcursor';
import { StepMap } from 'prosemirror-transform';
import { keymap } from 'prosemirror-keymap';
import { baseKeymap, chainCommands } from 'prosemirror-commands';
import {
splitListItem,
liftListItem,
sinkListItem,
} from 'prosemirror-schema-list';
import Placeholder from '../plugins/placeholder';
import FakeCursorPlugin from '../../MultipleDropDownService/plugins/FakeCursorPlugin';
const EditorWrapper = styled.div`
border: none;
display: flex;
flex: 2 1 auto;
justify-content: left;
.ProseMirror {
white-space: break-spaces;
width: 100%;
word-wrap: break-word;
&:focus {
outline: none;
}
color: #aaa;
float: left;
font-style: italic;
pointer-events: none;
}
p.empty-node:first-child::before {
content: attr(data-content);
}
.empty-node::before {
color: rgb(170, 170, 170);
float: left;
font-style: italic;
height: 0px;
pointer-events: none;
}
}
`;
const QuestionEditorComponent = ({
node,
view,
getPos,
const editorRef = useRef();
const context = useContext(WaxContext);
let questionView;
const questionId = node.attrs.id;
let finalPlugins = [FakeCursorPlugin(), gapCursor(), dropCursor()];
const createKeyBindings = () => {
const keys = getKeys();
Object.keys(baseKeymap).forEach(key => {
if (keys[key]) {
keys[key] = chainCommands(keys[key], baseKeymap[key]);
} else {
keys[key] = baseKeymap[key];
}
const pressEnter = (state, dispatch) => {
if (state.selection.node && state.selection.node.type.name === 'image') {
const { $from, to } = state.selection;
const same = $from.sharedDepth(to);
const pos = $from.before(same);
dispatch(state.tr.setSelection(NodeSelection.create(state.doc, pos)));
return true;
}
// LISTS
if (splitListItem(state.schema.nodes.list_item)(state)) {
splitListItem(state.schema.nodes.list_item)(state, dispatch);
return true;
}
return false;
};
const getKeys = () => {
return {
'Mod-z': () => undo(view.state, view.dispatch),
'Mod-y': () => redo(view.state, view.dispatch),
'Mod-[': liftListItem(view.state.schema.nodes.list_item),
'Mod-]': sinkListItem(view.state.schema.nodes.list_item),
// Enter: () =>
// splitListItem(questionView.state.schema.nodes.list_item)(
// questionView.state,
// questionView.dispatch,
// ),
Enter: pressEnter,
const plugins = [keymap(createKeyBindings()), ...app.getPlugins()];
const createPlaceholder = placeholder => {
return Placeholder({
content: placeholder,
});
};
finalPlugins = finalPlugins.concat([
getPos() +
1 +
context.pmViews[questionId].state.selection.to,
// context.pmViews[activeViewId].dispatch(
// context.pmViews[activeViewId].state.tr.setSelection(
// context.pmViews[activeViewId].state.selection.$anchor,
// context.pmViews[activeViewId].state.selection.$head,
if (questionView.hasFocus()) questionView.focus();
},
blur: (editorView, event) => {
if (questionView && event.relatedTarget === null) {
questionView.focus();
}
},
attributes: {
spellcheck: 'false',
},
},
);
context.updateView(
{
[questionId]: questionView,
},
questionId,
);
}, []);
const dispatchTransaction = tr => {
const addToHistory = !tr.getMeta('exludeToHistoryFromOutside');
const { state, transactions } = questionView.state.applyTransaction(tr);
questionView.updateState(state);
context.updateView({}, questionId);
if (!tr.getMeta('fromOutside')) {
const outerTr = view.state.tr;
const offsetMap = StepMap.offset(getPos() + 1);
for (let j = 0; j < steps.length; j++)
outerTr.step(steps[j].map(offsetMap));
}
view.dispatch(
outerTr
.setMeta('outsideView', questionId)
.setMeta('addToHistory', addToHistory),
);
return (
<EditorWrapper>
<div ref={editorRef} />