Skip to content
This repository was archived by the owner on Oct 11, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/constants.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export const CODE_BLOCK_REGEX = /^```([\w-]+)?\s*$/;

export const inlineMatchers = {
BOLD: [/\*\*([^(?**)]+)\*\*$/g, /__([^(?:__)]+)__$/g],
ITALIC: [/\*([^*]+)\*$/g, /_([^_]+)_$/g],
CODE: [/`([^`]+)`$/g],
STRIKETHROUGH: [/~~([^(?:~~)]+)~~$/g],
BOLD: [/\*\*(.+)\*\*$/g, /__(.+)__$/g],
ITALIC: [/\*(.+)\*$/g, /_(.+)_$/g],
CODE: [/`(.+)`$/g],
STRIKETHROUGH: [/~~(.+)~~$/g],
};

export const CODE_BLOCK_TYPE = "code-block";
23 changes: 1 addition & 22 deletions src/modifiers/__test__/changeCurrentInlineStyle-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe("changeCurrentInlineStyle", () => {
expect(newEditorState).not.toEqual(editorState);
expect(Draft.convertToRaw(newEditorState.getCurrentContent())).toEqual(
rawContentState(
"foo bar baz",
"foo bar baz",
[
{
length: 3,
Expand All @@ -57,25 +57,4 @@ describe("changeCurrentInlineStyle", () => {
)
);
});
it("inserts the character at the end", () => {
const text = "foo `bar` baz";
const editorState = createEditorState(text, []);
const matchArr = ["`bar`", "bar"];
matchArr.index = 4;
matchArr.input = text;
const newEditorState = changeCurrentInlineStyle(
editorState,
matchArr,
"CODE",
"\n"
);
expect(newEditorState).not.toEqual(editorState);
const contentState = Draft.convertToRaw(newEditorState.getCurrentContent());
expect(contentState.blocks.length).toBe(2);
expect(contentState.blocks[0].text).toEqual("foo bar");
expect(contentState.blocks[0].inlineStyleRanges).toEqual([
{ offset: 4, length: 3, style: "CODE" },
]);
expect(contentState.blocks[1].text).toEqual(" baz");
});
});
60 changes: 60 additions & 0 deletions src/modifiers/__test__/handleInlineStyle-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,66 @@ describe("handleInlineStyle", () => {
});

const testCases = {
"converts a mix of code, bold and italic and strikethrough in one go": {
before: {
entityMap: {},
blocks: [
{
key: "item1",
text: "`h~~el**lo *inline~~***` style",
type: "unstyled",
depth: 0,
inlineStyleRanges: [],
entityRanges: [],
data: {},
},
],
},
after: {
entityMap: {},
blocks: [
{
key: "item1",
text: "hello inline style",
type: "unstyled",
depth: 0,
inlineStyleRanges: [
{
length: 12,
offset: 0,
style: "CODE",
},
{
length: 11,
offset: 1,
style: "STRIKETHROUGH",
},
{
length: 9,
offset: 3,
style: "BOLD",
},
{
length: 6,
offset: 6,
style: "ITALIC",
},
],
entityRanges: [],
data: {},
},
],
},
selection: new SelectionState({
anchorKey: "item1",
anchorOffset: 24,
focusKey: "item1",
focusOffset: 24,
isBackward: false,
hasFocus: true,
}),
},

"converts to bold with astarisks": {
before: {
entityMap: {},
Expand Down
22 changes: 5 additions & 17 deletions src/modifiers/changeCurrentInlineStyle.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { EditorState, SelectionState, Modifier } from "draft-js";

const changeCurrentInlineStyle = (editorState, matchArr, style, character) => {
const changeCurrentInlineStyle = (editorState, matchArr, style) => {
const currentContent = editorState.getCurrentContent();
const selection = editorState.getSelection();
const key = selection.getStartKey();
Expand All @@ -21,18 +21,12 @@ const changeCurrentInlineStyle = (editorState, matchArr, style, character) => {

let newContentState = currentContent;

// if appendChar isn't defined add a space
// if character is a newline - add empty string and later on - split block
let appendChar = character == null ? " " : character;
if (character == "\n") appendChar = "";

// remove markdown delimiter at end
newContentState = Modifier.replaceText(
newContentState = Modifier.removeRange(
newContentState,
wordSelection.merge({
anchorOffset: wordSelection.getFocusOffset() - markdownCharacterLength,
}),
appendChar
})
);

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

// remove markdown delimiter at start
newContentState = Modifier.replaceText(
newContentState = Modifier.removeRange(
newContentState,
wordSelection.merge({
focusOffset: wordSelection.getAnchorOffset() + markdownCharacterLength,
}),
""
})
);

// apply style
Expand All @@ -61,11 +54,6 @@ const changeCurrentInlineStyle = (editorState, matchArr, style, character) => {
style
);

if (character == "\n") {
newContentState = Modifier.splitBlock(newContentState, afterSelection);
afterSelection = newContentState.getSelectionAfter();
}

const newEditorState = EditorState.push(
editorState,
newContentState,
Expand Down
63 changes: 49 additions & 14 deletions src/modifiers/handleInlineStyle.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
import changeCurrentInlineStyle from "./changeCurrentInlineStyle";
import { EditorState, Modifier } from "draft-js";
import { inlineMatchers } from "../constants";

const handleInlineStyle = (editorState, character) => {
const selection = editorState.getSelection();
const key = editorState.getSelection().getStartKey();
const text = editorState
.getCurrentContent()
.getBlockForKey(key)
.getText()
.slice(0, selection.getFocusOffset());

const line = `${text}`;
const handleChange = (editorState, line, character) => {
let newEditorState = editorState;

var i = 0;

Object.keys(inlineMatchers).some(k => {
inlineMatchers[k].some(re => {
let matchArr;
Expand All @@ -28,7 +17,6 @@ const handleInlineStyle = (editorState, character) => {
character
);
}
i++;
} while (matchArr);
return newEditorState !== editorState;
});
Expand All @@ -37,4 +25,51 @@ const handleInlineStyle = (editorState, character) => {
return newEditorState;
};

const getLine = (editorState, anchorOffset) => {
const selection = editorState.getSelection().merge({ anchorOffset });
const key = editorState.getSelection().getStartKey();

return editorState
.getCurrentContent()
.getBlockForKey(key)
.getText()
.slice(0, selection.getFocusOffset());
};

const handleInlineStyle = (editorState, character) => {
let selection = editorState.getSelection();
let line = getLine(editorState, selection.getAnchorOffset());
let newEditorState = handleChange(editorState, line, "");
let lastEditorState = editorState;

while (newEditorState !== lastEditorState) {
lastEditorState = newEditorState;
line = getLine(newEditorState, selection.getAnchorOffset());
newEditorState = handleChange(newEditorState, line, "");
}

if (newEditorState !== editorState) {
let newContentState = newEditorState.getCurrentContent();
selection = newEditorState.getSelection();

if (character === "\n") {
newContentState = Modifier.splitBlock(newContentState, selection);
} else {
newContentState = Modifier.insertText(
newContentState,
selection,
character
);
}

newEditorState = EditorState.push(
newEditorState,
newContentState,
"change-inline-style"
);
}

return newEditorState;
};

export default handleInlineStyle;