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

Commit 39d265b

Browse files
committed
Trigger markdown on any character
This makes it so typing `*` after `*some text` immediately makes it bold without having to press space after!
1 parent cc8537c commit 39d265b

File tree

4 files changed

+49
-67
lines changed

4 files changed

+49
-67
lines changed

src/__test__/plugin.test.js

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -228,37 +228,6 @@ describe("draft-js-markdown-plugin", () => {
228228
expect(store.setEditorState).toHaveBeenCalledWith(newEditorState);
229229
});
230230

231-
it("adds list item and transforms markdown", () => {
232-
// createMarkdownPlugin.__Rewire__("leaveList", modifierSpy); // eslint-disable-line no-underscore-dangle
233-
currentRawContentState = {
234-
entityMap: {},
235-
blocks: [
236-
{
237-
key: "item1",
238-
text: "**some bold text**",
239-
type: "unordered-list-item",
240-
depth: 0,
241-
inlineStyleRanges: [],
242-
entityRanges: [],
243-
data: {},
244-
},
245-
],
246-
};
247-
currentSelectionState = currentSelectionState.merge({
248-
focusOffset: 18,
249-
anchorOffset: 18,
250-
});
251-
expect(subject()).toBe("handled");
252-
// expect(modifierSpy).toHaveBeenCalledTimes(1);
253-
expect(store.setEditorState).toHaveBeenCalledTimes(1);
254-
newEditorState = store.setEditorState.mock.calls[0][0];
255-
const newRawContentState = Draft.convertToRaw(
256-
newEditorState.getCurrentContent()
257-
);
258-
expect(newRawContentState.blocks.length).toBe(2);
259-
expect(newEditorState.getCurrentInlineStyle().size).toBe(0);
260-
});
261-
262231
const emptyBlockTypes = [
263232
"blockquote",
264233
"header-one",

src/index.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -341,10 +341,6 @@ const createMarkdownPlugin = (_config = {}) => {
341341
return "not-handled";
342342
},
343343
handleBeforeInput(character, editorState, { setEditorState }) {
344-
if (character !== " ") {
345-
return "not-handled";
346-
}
347-
348344
// If we're in a code block - don't transform markdown
349345
if (inCodeBlock(editorState)) return "not-handled";
350346

src/modifiers/__test__/handleInlineStyle-test.js

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,13 @@ describe("handleInlineStyle", () => {
4848

4949
const testCases = {
5050
"converts a mix of code, bold and italic and strikethrough in one go": {
51+
character: "`",
5152
before: {
5253
entityMap: {},
5354
blocks: [
5455
{
5556
key: "item1",
56-
text: "`h~~el*lo _inline~~_*` style",
57+
text: "`h~~el*lo _inline~~_* style",
5758
type: "unstyled",
5859
depth: 0,
5960
inlineStyleRanges: [],
@@ -99,21 +100,22 @@ describe("handleInlineStyle", () => {
99100
},
100101
selection: new SelectionState({
101102
anchorKey: "item1",
102-
anchorOffset: 22,
103+
anchorOffset: 21,
103104
focusKey: "item1",
104-
focusOffset: 22,
105+
focusOffset: 21,
105106
isBackward: false,
106107
hasFocus: true,
107108
}),
108109
},
109110

110111
"converts to bold with astarisks": {
112+
character: "*",
111113
before: {
112114
entityMap: {},
113115
blocks: [
114116
{
115117
key: "item1",
116-
text: "hello *inline* style",
118+
text: "hello *inline style",
117119
type: "unstyled",
118120
depth: 0,
119121
inlineStyleRanges: [],
@@ -144,20 +146,21 @@ describe("handleInlineStyle", () => {
144146
},
145147
selection: new SelectionState({
146148
anchorKey: "item1",
147-
anchorOffset: 14,
149+
anchorOffset: 13,
148150
focusKey: "item1",
149-
focusOffset: 14,
151+
focusOffset: 13,
150152
isBackward: false,
151153
hasFocus: true,
152154
}),
153155
},
154156
"converts semicolons to bold with astarisks": {
157+
character: "*",
155158
before: {
156159
entityMap: {},
157160
blocks: [
158161
{
159162
key: "item1",
160-
text: "hello **TL;DR:** style",
163+
text: "hello *TL;DR: style",
161164
type: "unstyled",
162165
depth: 0,
163166
inlineStyleRanges: [],
@@ -188,20 +191,21 @@ describe("handleInlineStyle", () => {
188191
},
189192
selection: new SelectionState({
190193
anchorKey: "item1",
191-
anchorOffset: 16,
194+
anchorOffset: 13,
192195
focusKey: "item1",
193-
focusOffset: 16,
196+
focusOffset: 13,
194197
isBackward: false,
195198
hasFocus: true,
196199
}),
197200
},
198201
"converts to italic with underscore": {
202+
character: "_",
199203
before: {
200204
entityMap: {},
201205
blocks: [
202206
{
203207
key: "item1",
204-
text: "hello _inline_ style",
208+
text: "hello _inline style",
205209
type: "unstyled",
206210
depth: 0,
207211
inlineStyleRanges: [],
@@ -232,20 +236,21 @@ describe("handleInlineStyle", () => {
232236
},
233237
selection: new SelectionState({
234238
anchorKey: "item1",
235-
anchorOffset: 14,
239+
anchorOffset: 13,
236240
focusKey: "item1",
237-
focusOffset: 14,
241+
focusOffset: 13,
238242
isBackward: false,
239243
hasFocus: true,
240244
}),
241245
},
242246
"combines to italic and bold with astarisks": {
247+
character: "*",
243248
before: {
244249
entityMap: {},
245250
blocks: [
246251
{
247252
key: "item1",
248-
text: "hello *inline* style",
253+
text: "hello *inline style",
249254
type: "unstyled",
250255
depth: 0,
251256
inlineStyleRanges: [
@@ -287,20 +292,21 @@ describe("handleInlineStyle", () => {
287292
},
288293
selection: new SelectionState({
289294
anchorKey: "item1",
290-
anchorOffset: 14,
295+
anchorOffset: 13,
291296
focusKey: "item1",
292-
focusOffset: 14,
297+
focusOffset: 13,
293298
isBackward: false,
294299
hasFocus: true,
295300
}),
296301
},
297302
"converts to code with backquote": {
303+
character: "`",
298304
before: {
299305
entityMap: {},
300306
blocks: [
301307
{
302308
key: "item1",
303-
text: "hello `inline` style",
309+
text: "hello `inline style",
304310
type: "unstyled",
305311
depth: 0,
306312
inlineStyleRanges: [],
@@ -331,20 +337,21 @@ describe("handleInlineStyle", () => {
331337
},
332338
selection: new SelectionState({
333339
anchorKey: "item1",
334-
anchorOffset: 14,
340+
anchorOffset: 13,
335341
focusKey: "item1",
336-
focusOffset: 14,
342+
focusOffset: 13,
337343
isBackward: false,
338344
hasFocus: true,
339345
}),
340346
},
341347
"converts to strikethrough with tildes": {
348+
character: "~",
342349
before: {
343350
entityMap: {},
344351
blocks: [
345352
{
346353
key: "item1",
347-
text: "hello ~~inline~~ style",
354+
text: "hello ~~inline~ style",
348355
type: "unstyled",
349356
depth: 0,
350357
inlineStyleRanges: [],
@@ -375,9 +382,9 @@ describe("handleInlineStyle", () => {
375382
},
376383
selection: new SelectionState({
377384
anchorKey: "item1",
378-
anchorOffset: 16,
385+
anchorOffset: 15,
379386
focusKey: "item1",
380-
focusOffset: 16,
387+
focusOffset: 15,
381388
isBackward: false,
382389
hasFocus: true,
383390
}),
@@ -386,12 +393,13 @@ describe("handleInlineStyle", () => {
386393
// combine tests
387394

388395
"combines to bold and italic with underscores": {
396+
character: "_",
389397
before: {
390398
entityMap: {},
391399
blocks: [
392400
{
393401
key: "item1",
394-
text: "hello _inline_ style",
402+
text: "hello _inline style",
395403
type: "unstyled",
396404
depth: 0,
397405
inlineStyleRanges: [
@@ -433,9 +441,9 @@ describe("handleInlineStyle", () => {
433441
},
434442
selection: new SelectionState({
435443
anchorKey: "item1",
436-
anchorOffset: 14,
444+
anchorOffset: 13,
437445
focusKey: "item1",
438-
focusOffset: 14,
446+
focusOffset: 13,
439447
isBackward: false,
440448
hasFocus: true,
441449
}),
@@ -444,7 +452,11 @@ describe("handleInlineStyle", () => {
444452
Object.keys(testCases).forEach(k => {
445453
describe(k, () => {
446454
const testCase = testCases[k];
447-
const { before, after, selection, character = " " } = testCase;
455+
const { before, after, selection, character } = testCase;
456+
if (!character)
457+
throw new Error(
458+
"Invalid test case, needs to provide character option."
459+
);
448460
const contentState = Draft.convertFromRaw(before);
449461
const editorState = EditorState.forceSelection(
450462
EditorState.createWithContent(contentState),

src/modifiers/handleInlineStyle.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import changeCurrentInlineStyle from "./changeCurrentInlineStyle";
22
import { EditorState, Modifier } from "draft-js";
33
import { inlineMatchers } from "../constants";
4+
import insertText from "./insertText";
45

56
const handleChange = (editorState, line, whitelist) => {
67
let newEditorState = editorState;
@@ -37,12 +38,18 @@ const getLine = (editorState, anchorOffset) => {
3738
.slice(0, selection.getFocusOffset());
3839
};
3940

40-
const handleInlineStyle = (whitelist, editorState, character) => {
41+
const handleInlineStyle = (
42+
whitelist,
43+
editorStateWithoutCharacter,
44+
character
45+
) => {
46+
const editorState = insertText(editorStateWithoutCharacter, character);
4147
let selection = editorState.getSelection();
4248
let line = getLine(editorState, selection.getAnchorOffset());
4349
let newEditorState = handleChange(editorState, line, whitelist);
4450
let lastEditorState = editorState;
4551

52+
// Recursively resolve markdown, e.g. _*text*_ should turn into both italic and bold
4653
while (newEditorState !== lastEditorState) {
4754
lastEditorState = newEditorState;
4855
line = getLine(newEditorState, selection.getAnchorOffset());
@@ -56,21 +63,19 @@ const handleInlineStyle = (whitelist, editorState, character) => {
5663
if (character === "\n") {
5764
newContentState = Modifier.splitBlock(newContentState, selection);
5865
} else {
59-
newContentState = Modifier.insertText(
60-
newContentState,
61-
selection,
62-
character
63-
);
66+
newContentState = Modifier.insertText(newContentState, selection, " ");
6467
}
6568

6669
newEditorState = EditorState.push(
6770
newEditorState,
6871
newContentState,
6972
"change-inline-style"
7073
);
74+
75+
return newEditorState;
7176
}
7277

73-
return newEditorState;
78+
return editorStateWithoutCharacter;
7479
};
7580

7681
export default handleInlineStyle;

0 commit comments

Comments
 (0)