@kedao/editor
Version:
Rich Text Editor Based On Draft.js
147 lines • 6.89 kB
JavaScript
/**
* This extension is a transformation from draft-js-markdown-shortcuts-plugin (github repo: https://github.com/ngs/draft-js-markdown-shortcuts-plugin)
* Thanks very much for the contributors of draft-js-markdown-shortcuts-plugin!!!
*/
import handleBlockType from './modifiers/handleBlockType';
import handleInlineStyle from './modifiers/handleInlineStyle';
import handleNewCodeBlock from './modifiers/handleNewCodeBlock';
import insertEmptyBlock from './modifiers/insertEmptyBlock';
import handleLink from './modifiers/handleLink';
import handleImage from './modifiers/handleImage';
import leaveList from './modifiers/leaveList';
import insertText from './modifiers/insertText';
import changeCurrentBlockType from './modifiers/changeCurrentBlockType';
import { replaceText } from './utils';
function checkCharacterForState(editorState, character) {
let newEditorState = handleBlockType(editorState, character);
const contentState = editorState.getCurrentContent();
const selection = editorState.getSelection();
const key = selection.getStartKey();
const currentBlock = contentState.getBlockForKey(key);
const type = currentBlock.getType();
if (editorState === newEditorState) {
newEditorState = handleImage(editorState, character);
}
if (editorState === newEditorState) {
newEditorState = handleLink(editorState, character);
}
if (editorState === newEditorState && type !== 'code-block') {
newEditorState = handleInlineStyle(editorState, character);
}
return newEditorState;
}
function checkReturnForState(editorState, ev, insertEmptyBlockOnReturnWithModifierKey) {
let newEditorState = editorState;
const contentState = editorState.getCurrentContent();
const selection = editorState.getSelection();
const key = selection.getStartKey();
const currentBlock = contentState.getBlockForKey(key);
const type = currentBlock.getType();
const text = currentBlock.getText();
if (/-list-item$/.test(type) && text === '') {
newEditorState = leaveList(editorState);
}
if (newEditorState === editorState &&
insertEmptyBlockOnReturnWithModifierKey &&
(ev.ctrlKey ||
ev.shiftKey ||
ev.metaKey ||
ev.altKey ||
(/^header-/.test(type) &&
selection.isCollapsed() &&
selection.getEndOffset() === text.length))) {
newEditorState = insertEmptyBlock(editorState);
}
if (newEditorState === editorState &&
type !== 'code-block' &&
/^```([\w-]+)?$/.test(text)) {
newEditorState = handleNewCodeBlock(editorState);
}
if (newEditorState === editorState && type === 'code-block') {
if (/```\s*$/.test(text)) {
newEditorState = changeCurrentBlockType(newEditorState, type, text.replace(/\n```\s*$/, ''));
newEditorState = insertEmptyBlock(newEditorState);
}
else {
newEditorState = insertText(editorState, '\n');
}
}
if (editorState === newEditorState) {
newEditorState = handleInlineStyle(editorState, '\n');
}
return newEditorState;
}
export default (options) => {
options = Object.assign({ insertEmptyBlockOnReturnWithModifierKey: true }, options);
const { includeEditors, excludeEditors, insertEmptyBlockOnReturnWithModifierKey } = options;
return [
{
type: 'prop-interception',
includeEditors,
excludeEditors,
interceptor: (editorProps) => {
editorProps = Object.assign(Object.assign({}, editorProps), {
handleReturn(ev, editorState, editor) {
const newEditorState = checkReturnForState(editorState, ev, insertEmptyBlockOnReturnWithModifierKey);
if (editorState !== newEditorState) {
editor.setValue(newEditorState);
return 'handled';
}
return 'not-handled';
},
handleBeforeInput(character, editorState, editor) {
if (character.match(/[A-z0-9_*~`]/)) {
return 'not-handled';
}
const newEditorState = checkCharacterForState(editorState, character);
if (editorState !== newEditorState) {
editor.setValue(newEditorState);
return 'handled';
}
return 'not-handled';
},
handlePastedText(text, html, editorState, editor) {
if (html) {
return 'not-handled';
}
let newEditorState = editorState;
let buffer = [];
for (let i = 0; i < text.length; i++) {
// eslint-disable-line no-plusplus
if (text[i].match(/[^A-z0-9_*~`]/)) {
newEditorState = replaceText(newEditorState, buffer.join('') + text[i]);
newEditorState = checkCharacterForState(newEditorState, text[i]);
buffer = [];
}
else if (text[i].charCodeAt(0) === 10) {
newEditorState = replaceText(newEditorState, buffer.join(''));
const tmpEditorState = checkReturnForState(newEditorState, {}, insertEmptyBlockOnReturnWithModifierKey);
if (newEditorState === tmpEditorState) {
newEditorState = insertEmptyBlock(tmpEditorState);
}
else {
newEditorState = tmpEditorState;
}
buffer = [];
}
else if (i === text.length - 1) {
newEditorState = replaceText(newEditorState, buffer.join('') + text[i]);
buffer = [];
}
else {
buffer.push(text[i]);
}
}
if (editorState !== newEditorState) {
editor.setValue(newEditorState);
return 'handled';
}
return 'not-handled';
}
});
return editorProps;
}
}
];
};
//# sourceMappingURL=index.js.map