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

Commit d8bc3e4

Browse files
committed
refactor inline style handlers to keep looking for delimiter matches until none are found
1 parent dc86d63 commit d8bc3e4

File tree

5 files changed

+119
-57
lines changed

5 files changed

+119
-57
lines changed

src/constants.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
export const CODE_BLOCK_REGEX = /^```([\w-]+)?\s*$/;
22

33
export const inlineMatchers = {
4-
BOLD: [/\*\*([^(?**)]+)\*\*$/g, /__([^(?:__)]+)__$/g],
5-
ITALIC: [/\*([^*]+)\*$/g, /_([^_]+)_$/g],
6-
CODE: [/`([^`]+)`$/g],
7-
STRIKETHROUGH: [/~~([^(?:~~)]+)~~$/g],
4+
BOLD: [/\*\*(.+)\*\*$/g, /__(.+)__$/g],
5+
ITALIC: [/\*(.+)\*$/g, /_(.+)_$/g],
6+
CODE: [/`(.+)`$/g],
7+
STRIKETHROUGH: [/~~(.+)~~$/g],
88
};
99

1010
export const CODE_BLOCK_TYPE = "code-block";

src/modifiers/__test__/changeCurrentInlineStyle-test.js

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe("changeCurrentInlineStyle", () => {
4545
expect(newEditorState).not.toEqual(editorState);
4646
expect(Draft.convertToRaw(newEditorState.getCurrentContent())).toEqual(
4747
rawContentState(
48-
"foo bar baz",
48+
"foo bar baz",
4949
[
5050
{
5151
length: 3,
@@ -57,25 +57,4 @@ describe("changeCurrentInlineStyle", () => {
5757
)
5858
);
5959
});
60-
it("inserts the character at the end", () => {
61-
const text = "foo `bar` baz";
62-
const editorState = createEditorState(text, []);
63-
const matchArr = ["`bar`", "bar"];
64-
matchArr.index = 4;
65-
matchArr.input = text;
66-
const newEditorState = changeCurrentInlineStyle(
67-
editorState,
68-
matchArr,
69-
"CODE",
70-
"\n"
71-
);
72-
expect(newEditorState).not.toEqual(editorState);
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");
80-
});
8160
});

src/modifiers/__test__/handleInlineStyle-test.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,66 @@ describe("handleInlineStyle", () => {
4242
});
4343

4444
const testCases = {
45+
"converts a mix of code, bold and italic and strikethrough in one go": {
46+
before: {
47+
entityMap: {},
48+
blocks: [
49+
{
50+
key: "item1",
51+
text: "`h~~el**lo *inline~~***` style",
52+
type: "unstyled",
53+
depth: 0,
54+
inlineStyleRanges: [],
55+
entityRanges: [],
56+
data: {},
57+
},
58+
],
59+
},
60+
after: {
61+
entityMap: {},
62+
blocks: [
63+
{
64+
key: "item1",
65+
text: "hello inline style",
66+
type: "unstyled",
67+
depth: 0,
68+
inlineStyleRanges: [
69+
{
70+
length: 12,
71+
offset: 0,
72+
style: "CODE",
73+
},
74+
{
75+
length: 11,
76+
offset: 1,
77+
style: "STRIKETHROUGH",
78+
},
79+
{
80+
length: 9,
81+
offset: 3,
82+
style: "BOLD",
83+
},
84+
{
85+
length: 6,
86+
offset: 6,
87+
style: "ITALIC",
88+
},
89+
],
90+
entityRanges: [],
91+
data: {},
92+
},
93+
],
94+
},
95+
selection: new SelectionState({
96+
anchorKey: "item1",
97+
anchorOffset: 24,
98+
focusKey: "item1",
99+
focusOffset: 24,
100+
isBackward: false,
101+
hasFocus: true,
102+
}),
103+
},
104+
45105
"converts to bold with astarisks": {
46106
before: {
47107
entityMap: {},

src/modifiers/changeCurrentInlineStyle.js

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { EditorState, SelectionState, Modifier } from "draft-js";
22

3-
const changeCurrentInlineStyle = (editorState, matchArr, style, character) => {
3+
const changeCurrentInlineStyle = (editorState, matchArr, style) => {
44
const currentContent = editorState.getCurrentContent();
55
const selection = editorState.getSelection();
66
const key = selection.getStartKey();
@@ -21,18 +21,12 @@ const changeCurrentInlineStyle = (editorState, matchArr, style, character) => {
2121

2222
let newContentState = currentContent;
2323

24-
// if appendChar isn't defined add a space
25-
// if character is a newline - add empty string and later on - split block
26-
let appendChar = character == null ? " " : character;
27-
if (character == "\n") appendChar = "";
28-
2924
// remove markdown delimiter at end
30-
newContentState = Modifier.replaceText(
25+
newContentState = Modifier.removeRange(
3126
newContentState,
3227
wordSelection.merge({
3328
anchorOffset: wordSelection.getFocusOffset() - markdownCharacterLength,
34-
}),
35-
appendChar
29+
})
3630
);
3731

3832
let afterSelection = newContentState.getSelectionAfter();
@@ -43,12 +37,11 @@ const changeCurrentInlineStyle = (editorState, matchArr, style, character) => {
4337
});
4438

4539
// remove markdown delimiter at start
46-
newContentState = Modifier.replaceText(
40+
newContentState = Modifier.removeRange(
4741
newContentState,
4842
wordSelection.merge({
4943
focusOffset: wordSelection.getAnchorOffset() + markdownCharacterLength,
50-
}),
51-
""
44+
})
5245
);
5346

5447
// apply style
@@ -61,11 +54,6 @@ const changeCurrentInlineStyle = (editorState, matchArr, style, character) => {
6154
style
6255
);
6356

64-
if (character == "\n") {
65-
newContentState = Modifier.splitBlock(newContentState, afterSelection);
66-
afterSelection = newContentState.getSelectionAfter();
67-
}
68-
6957
const newEditorState = EditorState.push(
7058
editorState,
7159
newContentState,

src/modifiers/handleInlineStyle.js

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,9 @@
11
import changeCurrentInlineStyle from "./changeCurrentInlineStyle";
2+
import { EditorState, Modifier } from "draft-js";
23
import { inlineMatchers } from "../constants";
34

4-
const handleInlineStyle = (editorState, character) => {
5-
const selection = editorState.getSelection();
6-
const key = editorState.getSelection().getStartKey();
7-
const text = editorState
8-
.getCurrentContent()
9-
.getBlockForKey(key)
10-
.getText()
11-
.slice(0, selection.getFocusOffset());
12-
13-
const line = `${text}`;
5+
const handleChange = (editorState, line, character) => {
146
let newEditorState = editorState;
15-
16-
var i = 0;
17-
187
Object.keys(inlineMatchers).some(k => {
198
inlineMatchers[k].some(re => {
209
let matchArr;
@@ -28,7 +17,6 @@ const handleInlineStyle = (editorState, character) => {
2817
character
2918
);
3019
}
31-
i++;
3220
} while (matchArr);
3321
return newEditorState !== editorState;
3422
});
@@ -37,4 +25,51 @@ const handleInlineStyle = (editorState, character) => {
3725
return newEditorState;
3826
};
3927

28+
const getLine = (editorState, anchorOffset) => {
29+
const selection = editorState.getSelection().merge({ anchorOffset });
30+
const key = editorState.getSelection().getStartKey();
31+
32+
return editorState
33+
.getCurrentContent()
34+
.getBlockForKey(key)
35+
.getText()
36+
.slice(0, selection.getFocusOffset());
37+
};
38+
39+
const handleInlineStyle = (editorState, character) => {
40+
let selection = editorState.getSelection();
41+
let line = getLine(editorState, selection.getAnchorOffset());
42+
let newEditorState = handleChange(editorState, line, "");
43+
let lastEditorState = editorState;
44+
45+
while (newEditorState !== lastEditorState) {
46+
lastEditorState = newEditorState;
47+
line = getLine(newEditorState, selection.getAnchorOffset());
48+
newEditorState = handleChange(newEditorState, line, "");
49+
}
50+
51+
if (newEditorState !== editorState) {
52+
let newContentState = newEditorState.getCurrentContent();
53+
selection = newEditorState.getSelection();
54+
55+
if (character === "\n") {
56+
newContentState = Modifier.splitBlock(newContentState, selection);
57+
} else {
58+
newContentState = Modifier.insertText(
59+
newContentState,
60+
selection,
61+
character
62+
);
63+
}
64+
65+
newEditorState = EditorState.push(
66+
newEditorState,
67+
newContentState,
68+
"change-inline-style"
69+
);
70+
}
71+
72+
return newEditorState;
73+
};
74+
4075
export default handleInlineStyle;

0 commit comments

Comments
 (0)