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

Commit 8b36fe2

Browse files
committed
- handle markdown transformation when on list
- reset current inline style upon enter
1 parent 329e21a commit 8b36fe2

File tree

5 files changed

+111
-28
lines changed

5 files changed

+111
-28
lines changed

src/__test__/plugin.test.js

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,18 @@ describe("draft-js-markdown-plugin", () => {
9898
it("is loaded", () => {
9999
expect(typeof createMarkdownPlugin).toBe("function");
100100
});
101+
101102
it("initialize", () => {
102103
plugin.initialize(store);
103104
expect(plugin.store).toEqual(store);
104105
});
106+
105107
describe("handleReturn", () => {
106108
beforeEach(() => {
107109
subject = () =>
108110
plugin.handleReturn(event, store.getEditorState(), store);
109111
});
110-
it("does always handle", () => {
112+
it("does not handle", () => {
111113
currentRawContentState = {
112114
entityMap: {},
113115
blocks: [
@@ -122,10 +124,37 @@ describe("draft-js-markdown-plugin", () => {
122124
},
123125
],
124126
};
125-
expect(subject()).toBe("handled");
127+
expect(subject()).toBe("not-handled");
126128
expect(modifierSpy).not.toHaveBeenCalledTimes(1);
127129
expect(store.setEditorState).not.toHaveBeenCalled();
128130
});
131+
132+
it("resets curent inline style", () => {
133+
currentRawContentState = {
134+
entityMap: {},
135+
blocks: [
136+
{
137+
key: "item1",
138+
text: "item1",
139+
type: "unstyled",
140+
depth: 0,
141+
inlineStyleRanges: [{ offset: 0, length: 5, style: "BOLD" }],
142+
entityRanges: [],
143+
data: {},
144+
},
145+
],
146+
};
147+
currentSelectionState = currentSelectionState.merge({
148+
focusOffset: 5,
149+
anchorOffset: 5,
150+
});
151+
152+
expect(subject()).toBe("handled");
153+
expect(store.setEditorState).toHaveBeenCalled();
154+
newEditorState = store.setEditorState.mock.calls[0][0];
155+
expect(newEditorState.getCurrentInlineStyle().size).toBe(0);
156+
});
157+
129158
it("leaves from list", () => {
130159
createMarkdownPlugin.__Rewire__("leaveList", modifierSpy); // eslint-disable-line no-underscore-dangle
131160
currentRawContentState = {
@@ -146,6 +175,38 @@ describe("draft-js-markdown-plugin", () => {
146175
expect(modifierSpy).toHaveBeenCalledTimes(1);
147176
expect(store.setEditorState).toHaveBeenCalledWith(newEditorState);
148177
});
178+
179+
it("adds list item and transforms markdown", () => {
180+
// createMarkdownPlugin.__Rewire__("leaveList", modifierSpy); // eslint-disable-line no-underscore-dangle
181+
currentRawContentState = {
182+
entityMap: {},
183+
blocks: [
184+
{
185+
key: "item1",
186+
text: "**some bold text**",
187+
type: "unordered-list-item",
188+
depth: 0,
189+
inlineStyleRanges: [],
190+
entityRanges: [],
191+
data: {},
192+
},
193+
],
194+
};
195+
currentSelectionState = currentSelectionState.merge({
196+
focusOffset: 18,
197+
anchorOffset: 18,
198+
});
199+
expect(subject()).toBe("handled");
200+
// expect(modifierSpy).toHaveBeenCalledTimes(1);
201+
expect(store.setEditorState).toHaveBeenCalledTimes(1);
202+
newEditorState = store.setEditorState.mock.calls[0][0];
203+
const newRawContentState = Draft.convertToRaw(
204+
newEditorState.getCurrentContent()
205+
);
206+
expect(newRawContentState.blocks.length).toBe(2);
207+
expect(newEditorState.getCurrentInlineStyle().size).toBe(0);
208+
});
209+
149210
const testInsertNewBlock = type => () => {
150211
createMarkdownPlugin.__Rewire__("insertEmptyBlock", modifierSpy); // eslint-disable-line no-underscore-dangle
151212
currentRawContentState = {

src/index.js

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
CHECKABLE_LIST_ITEM,
77
} from "draft-js-checkable-list-item";
88

9-
import { Map, OrderedSet } from "immutable";
9+
import { Map, OrderedSet, is } from "immutable";
1010
import {
1111
getDefaultKeyBinding,
1212
Modifier,
@@ -67,9 +67,11 @@ function checkReturnForState(editorState, ev) {
6767
const currentBlock = contentState.getBlockForKey(key);
6868
const type = currentBlock.getType();
6969
const text = currentBlock.getText();
70+
7071
if (/-list-item$/.test(type) && text === "") {
7172
newEditorState = leaveList(editorState);
7273
}
74+
7375
if (
7476
newEditorState === editorState &&
7577
(ev.ctrlKey ||
@@ -163,20 +165,36 @@ const createMarkdownPlugin = (config = {}) => {
163165
let newEditorState = checkReturnForState(editorState, ev);
164166
let selection = newEditorState.getSelection();
165167

166-
newEditorState = checkCharacterForState(newEditorState, "");
168+
if (
169+
inCodeBlock(editorState) &&
170+
!is(editorState.getImmutable(), newEditorState.getImmutable())
171+
) {
172+
setEditorState(newEditorState);
173+
return "handled";
174+
}
175+
176+
newEditorState = checkCharacterForState(newEditorState, "\n");
167177
let content = newEditorState.getCurrentContent();
168178

169-
content = Modifier.splitBlock(content, selection);
179+
// if there are actually no changes but the editorState has a
180+
// current inline style we want to split the block
181+
if (
182+
is(editorState.getImmutable(), newEditorState.getImmutable()) &&
183+
editorState.getCurrentInlineStyle().size > 0
184+
) {
185+
content = Modifier.splitBlock(content, selection);
186+
}
170187

171-
setEditorState(
172-
EditorState.push(
173-
resetInlineStyle(newEditorState),
174-
content,
175-
"split-block"
176-
)
177-
);
188+
newEditorState = resetInlineStyle(newEditorState);
189+
190+
if (!is(editorState.getImmutable(), newEditorState.getImmutable())) {
191+
setEditorState(
192+
EditorState.push(newEditorState, content, "split-block")
193+
);
194+
return "handled";
195+
}
178196

179-
return "handled";
197+
return "not-handled";
180198
},
181199
handleBeforeInput(character, editorState, { setEditorState }) {
182200
if (character !== " ") {

src/modifiers/__test__/changeCurrentInlineStyle-test.js

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,12 @@ describe("changeCurrentInlineStyle", () => {
7070
"\n"
7171
);
7272
expect(newEditorState).not.toEqual(editorState);
73-
expect(Draft.convertToRaw(newEditorState.getCurrentContent())).toEqual(
74-
rawContentState(
75-
"foo bar\n baz",
76-
[
77-
{
78-
length: 3,
79-
offset: 4,
80-
style: "CODE",
81-
},
82-
],
83-
"CODE"
84-
)
85-
);
73+
const contentState = Draft.convertToRaw(newEditorState.getCurrentContent());
74+
expect(contentState.blocks.length).toBe(2);
75+
expect(contentState.blocks[0].text).toEqual("foo bar");
76+
expect(contentState.blocks[0].inlineStyleRanges).toEqual([
77+
{ offset: 4, length: 3, style: "CODE" },
78+
]);
79+
expect(contentState.blocks[1].text).toEqual(" baz");
8680
});
8781
});

src/modifiers/changeCurrentInlineStyle.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,16 @@ const changeCurrentInlineStyle = (editorState, matchArr, style, character) => {
2121

2222
let newContentState = currentContent;
2323

24+
let appendChar = character == null ? " " : character;
25+
if (character == "\n") appendChar = "";
26+
2427
// remove markdown delimiter at end
2528
newContentState = Modifier.replaceText(
2629
newContentState,
2730
wordSelection.merge({
2831
anchorOffset: wordSelection.getFocusOffset() - markdownCharacterLength,
2932
}),
30-
character == null ? " " : character
33+
appendChar
3134
);
3235

3336
let afterSelection = newContentState.getSelectionAfter();
@@ -56,6 +59,11 @@ const changeCurrentInlineStyle = (editorState, matchArr, style, character) => {
5659
style
5760
);
5861

62+
if (character == "\n") {
63+
newContentState = Modifier.splitBlock(newContentState, afterSelection);
64+
afterSelection = newContentState.getSelectionAfter();
65+
}
66+
5967
const newEditorState = EditorState.push(
6068
editorState,
6169
newContentState,

src/modifiers/resetInlineStyle.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@ import { OrderedSet } from "immutable";
22
import { EditorState } from "draft-js";
33

44
export default editorState =>
5-
EditorState.setInlineStyleOverride(editorState, OrderedSet());
5+
editorState.getCurrentInlineStyle().size === 0
6+
? editorState
7+
: EditorState.setInlineStyleOverride(editorState, OrderedSet());

0 commit comments

Comments
 (0)