Skip to content
This repository was archived by the owner on Oct 11, 2022. It is now read-only.

Commit 2fa7df1

Browse files
committed
Fix paste behavior for code block
1 parent ba70187 commit 2fa7df1

File tree

2 files changed

+82
-10
lines changed

2 files changed

+82
-10
lines changed

src/__test__/plugin-test.js

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,20 @@ describe('draft-js-markdown-shortcuts-plugin', () => {
1717
createMarkdownShortcutsPlugin.__ResetDependency__('handleLink');
1818
createMarkdownShortcutsPlugin.__ResetDependency__('handleImage');
1919
createMarkdownShortcutsPlugin.__ResetDependency__('leaveList');
20+
createMarkdownShortcutsPlugin.__ResetDependency__('changeCurrentBlockType');
21+
createMarkdownShortcutsPlugin.__ResetDependency__('replaceText');
22+
createMarkdownShortcutsPlugin.__ResetDependency__('checkReturnForState');
2023
/* eslint-enable no-underscore-dangle */
2124
});
2225

26+
const createEditorState = (rawContent, rawSelection) => {
27+
const contentState = Draft.convertFromRaw(rawContent);
28+
return EditorState.forceSelection(
29+
EditorState.createWithContent(contentState),
30+
rawSelection
31+
);
32+
};
33+
2334
let plugin;
2435
let store;
2536
let currentEditorState;
@@ -67,10 +78,7 @@ describe('draft-js-markdown-shortcuts-plugin', () => {
6778
store = {
6879
setEditorState: sinon.spy(),
6980
getEditorState: sinon.spy(() => {
70-
const contentState = Draft.convertFromRaw(currentRawContentState);
71-
currentEditorState = EditorState.forceSelection(
72-
EditorState.createWithContent(contentState),
73-
currentSelectionState);
81+
currentEditorState = createEditorState(currentRawContentState, currentSelectionState);
7482
return currentEditorState;
7583
})
7684
};
@@ -179,6 +187,23 @@ describe('draft-js-markdown-shortcuts-plugin', () => {
179187
expect(modifierSpy).to.have.been.calledOnce();
180188
expect(store.setEditorState).to.have.been.calledWith(newEditorState);
181189
});
190+
it('handle code block closing', () => {
191+
createMarkdownShortcutsPlugin.__Rewire__('changeCurrentBlockType', modifierSpy); // eslint-disable-line no-underscore-dangle
192+
currentRawContentState = {
193+
entityMap: {},
194+
blocks: [{
195+
key: 'item1',
196+
text: 'foo\n```',
197+
type: 'code-block',
198+
depth: 0,
199+
inlineStyleRanges: [],
200+
entityRanges: [],
201+
data: {}
202+
}]
203+
};
204+
expect(subject()).to.equal('handled');
205+
expect(modifierSpy).to.have.been.calledOnce();
206+
});
182207
it('insert new line char from code-block', () => {
183208
createMarkdownShortcutsPlugin.__Rewire__('insertText', modifierSpy); // eslint-disable-line no-underscore-dangle
184209
currentRawContentState = {
@@ -311,6 +336,7 @@ describe('draft-js-markdown-shortcuts-plugin', () => {
311336
beforeEach(() => {
312337
pastedText = `_hello world_
313338
Hello`;
339+
html = undefined;
314340
subject = () => plugin.handlePastedText(pastedText, html, store);
315341
});
316342
[
@@ -349,6 +375,42 @@ describe('draft-js-markdown-shortcuts-plugin', () => {
349375
expect(modifierSpy).to.have.been.calledWith(currentEditorState, 'hello');
350376
});
351377
});
378+
describe('pasted just text with new line code', () => {
379+
beforeEach(() => {
380+
pastedText = 'hello\nworld';
381+
const rawContentState = {
382+
entityMap: {},
383+
blocks: [{
384+
key: 'item1',
385+
text: '',
386+
type: 'unstyled',
387+
depth: 0,
388+
inlineStyleRanges: [],
389+
entityRanges: [],
390+
data: {}
391+
}]
392+
};
393+
const otherRawContentState = {
394+
entityMap: {},
395+
blocks: [{
396+
key: 'item2',
397+
text: 'H1',
398+
type: 'header-one',
399+
depth: 0,
400+
inlineStyleRanges: [],
401+
entityRanges: [],
402+
data: {}
403+
}]
404+
};
405+
/* eslint-disable no-underscore-dangle */
406+
createMarkdownShortcutsPlugin.__Rewire__('replaceText', () => createEditorState(rawContentState, currentSelectionState));
407+
createMarkdownShortcutsPlugin.__Rewire__('checkReturnForState', () => createEditorState(otherRawContentState, currentSelectionState));
408+
/* eslint-enable no-underscore-dangle */
409+
});
410+
it('return handled', () => {
411+
expect(subject()).to.equal('handled');
412+
});
413+
});
352414
describe('passed `html` argument', () => {
353415
beforeEach(() => {
354416
pastedText = '# hello';

src/index.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import handleLink from './modifiers/handleLink';
1414
import handleImage from './modifiers/handleImage';
1515
import leaveList from './modifiers/leaveList';
1616
import insertText from './modifiers/insertText';
17+
import changeCurrentBlockType from './modifiers/changeCurrentBlockType';
1718
import createLinkDecorator from './decorators/link';
1819
import createImageDecorator from './decorators/image';
1920
import { replaceText } from './utils';
@@ -49,12 +50,17 @@ function checkReturnForState(editorState, ev) {
4950
(ev.ctrlKey || ev.shiftKey || ev.metaKey || ev.altKey || /^header-/.test(type))) {
5051
newEditorState = insertEmptyBlock(editorState);
5152
}
52-
if (newEditorState === editorState && type === 'code-block') {
53-
newEditorState = insertText(editorState, '\n');
54-
}
55-
if (newEditorState === editorState) {
53+
if (newEditorState === editorState && type !== 'code-block' && /^```([\w-]+)?$/.test(text)) {
5654
newEditorState = handleNewCodeBlock(editorState);
5755
}
56+
if (newEditorState === editorState && type === 'code-block') {
57+
if (/```\s*$/.test(text)) {
58+
newEditorState = changeCurrentBlockType(newEditorState, type, text.replace(/\n```\s*$/, ''));
59+
newEditorState = insertEmptyBlock(newEditorState);
60+
} else {
61+
newEditorState = insertText(editorState, '\n');
62+
}
63+
}
5864

5965
return newEditorState;
6066
}
@@ -148,8 +154,12 @@ const createMarkdownShortcutsPlugin = (config = {}) => {
148154
buffer = [];
149155
} else if (text[i].charCodeAt(0) === 10) {
150156
newEditorState = replaceText(newEditorState, buffer.join(''));
151-
newEditorState = insertEmptyBlock(newEditorState);
152-
newEditorState = checkReturnForState(newEditorState, {});
157+
const tmpEditorState = checkReturnForState(newEditorState, {});
158+
if (newEditorState === tmpEditorState) {
159+
newEditorState = insertEmptyBlock(tmpEditorState);
160+
} else {
161+
newEditorState = tmpEditorState;
162+
}
153163
buffer = [];
154164
} else if (i === text.length - 1) {
155165
newEditorState = replaceText(newEditorState, buffer.join('') + text[i]);

0 commit comments

Comments
 (0)