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

Commit b9e11d7

Browse files
authored
Merge pull request #71 from cusxio/entity
custom entity
2 parents b0d2e8b + b75ef88 commit b9e11d7

File tree

18 files changed

+116
-31
lines changed

18 files changed

+116
-31
lines changed

README.md

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ const markdownPlugin = createMarkdownPlugin({ renderLanguageSelect })
5757
```
5858

5959
### `languages`
60+
6061
Dictionary for languages available to code block switcher
6162

6263
#### Example:
@@ -70,6 +71,7 @@ const markdownPlugin = createMarkdownPlugin({ languages })
7071
```
7172

7273
### `features`
74+
7375
A list of enabled features, by default all features are turned on.
7476

7577
```js
@@ -79,7 +81,7 @@ features = {
7981
}
8082
```
8183

82-
#### Example
84+
#### Example:
8385

8486
```
8587
// this will only enable BOLD for inline and CODE
@@ -125,6 +127,30 @@ import { CHECKABLE_LIST_ITEM } from "draft-js-checkable-list-item"
125127
]
126128
```
127129

130+
### `entityType`
131+
132+
To interoperate this plugin with other DraftJS plugins, i.e. [`draft-js-plugins`](https://github.com/draft-js-plugins/draft-js-plugins), you might need to customize the `LINK` and `IMAGE` entity type created by `draft-js-markdown-plugin`.
133+
134+
#### Example:
135+
136+
```js
137+
import createMarkdownPlugin from "draft-js-markdown-plugin";
138+
import createFocusPlugin from "draft-js-focus-plugin";
139+
import createImagePlugin from "draft-js-image-plugin";
140+
141+
const entityType = {
142+
IMAGE: "IMAGE",
143+
};
144+
145+
const focusPlugin = createFocusPlugin();
146+
const imagePlugin = createImagePlugin({
147+
decorator: focusPlugin.decorator,
148+
});
149+
// For `draft-js-image-plugin` to work, the entity type of an image must be `IMAGE`.
150+
const markdownPlugin = createMarkdownPlugin({ entityType });
151+
152+
const editorPlugins = [focusPlugin, imagePlugin, markdownPlugin];
153+
```
128154

129155
## Usage
130156

src/__test__/plugin.test.js

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import {
44
CheckableListItemUtils,
55
} from "draft-js-checkable-list-item";
66

7-
import { defaultInlineWhitelist, defaultBlockWhitelist } from "../constants";
7+
import {
8+
defaultInlineWhitelist,
9+
defaultBlockWhitelist,
10+
ENTITY_TYPE,
11+
} from "../constants";
812

913
import { Map, List } from "immutable";
1014
import createMarkdownPlugin from "../";
@@ -514,14 +518,33 @@ describe("draft-js-markdown-plugin", () => {
514518
],
515519
};
516520
});
517-
["handleImage", "handleLink"].forEach(modifier => {
521+
["handleImage"].forEach(modifier => {
522+
describe(modifier, () => {
523+
beforeEach(() => {
524+
createMarkdownPlugin.__Rewire__(modifier, modifierSpy); // eslint-disable-line no-underscore-dangle
525+
});
526+
it("returns handled", () => {
527+
expect(subject()).toBe("handled");
528+
expect(modifierSpy).toHaveBeenCalledWith(
529+
currentEditorState,
530+
" ",
531+
ENTITY_TYPE.IMAGE
532+
);
533+
});
534+
});
535+
});
536+
["handleLink"].forEach(modifier => {
518537
describe(modifier, () => {
519538
beforeEach(() => {
520539
createMarkdownPlugin.__Rewire__(modifier, modifierSpy); // eslint-disable-line no-underscore-dangle
521540
});
522541
it("returns handled", () => {
523542
expect(subject()).toBe("handled");
524-
expect(modifierSpy).toHaveBeenCalledWith(currentEditorState, " ");
543+
expect(modifierSpy).toHaveBeenCalledWith(
544+
currentEditorState,
545+
" ",
546+
ENTITY_TYPE.LINK
547+
);
525548
});
526549
});
527550
});

src/constants.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ export const inlineMatchers = {
1111

1212
export const CODE_BLOCK_TYPE = "code-block";
1313

14+
export const ENTITY_TYPE = {
15+
IMAGE: "IMG",
16+
LINK: "LINK",
17+
};
18+
1419
export const defaultInlineWhitelist = [
1520
"BOLD",
1621
"ITALIC",

src/decorators/image/__test__/imageStrategy-test.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Draft from "draft-js";
2+
import { ENTITY_TYPE } from "../../../constants";
23
import createImageStrategy from "../imageStrategy";
34

45
describe("imageStrategy", () => {
@@ -34,7 +35,9 @@ describe("imageStrategy", () => {
3435
});
3536
it("callbacks range", () => {
3637
const block = contentState.getBlockForKey("dtehj");
37-
const strategy = createImageStrategy();
38+
const strategy = createImageStrategy({
39+
entityType: ENTITY_TYPE.IMAGE,
40+
});
3841
const cb = jest.fn();
3942
expect(typeof block).toBe("object");
4043
strategy(block, cb, contentState);

src/decorators/image/imageStrategy.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
const createImageStrategy = () => {
1+
const createImageStrategy = ({ entityType }) => {
22
const findImageEntities = (contentBlock, callback, contentState) => {
33
contentBlock.findEntityRanges(character => {
44
const entityKey = character.getEntity();
55
return (
66
entityKey !== null &&
7-
contentState.getEntity(entityKey).getType() === "IMG"
7+
contentState.getEntity(entityKey).getType() === entityType
88
);
99
}, callback);
1010
};

src/decorators/image/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import createImageStrategy from "./imageStrategy";
22
import Image from "../../components/Image";
33

4-
const createImageDecorator = () => ({
5-
strategy: createImageStrategy(),
4+
const createImageDecorator = ({ entityType }) => ({
5+
strategy: createImageStrategy({ entityType }),
66
component: Image,
77
});
88

src/decorators/link/__test__/linkStrategy-test.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Draft from "draft-js";
2+
import { ENTITY_TYPE } from "../../../constants";
23
import createLinkStrategy from "../linkStrategy";
34

45
describe("linkStrategy", () => {
@@ -33,7 +34,9 @@ describe("linkStrategy", () => {
3334
});
3435
it("callbacks range", () => {
3536
const block = contentState.getBlockForKey("dtehj");
36-
const strategy = createLinkStrategy();
37+
const strategy = createLinkStrategy({
38+
entityType: ENTITY_TYPE.LINK,
39+
});
3740
const cb = jest.fn();
3841
expect(typeof block).toBe("object");
3942
strategy(block, cb, contentState);

src/decorators/link/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import createLinkStrategy from "./linkStrategy";
22
import Link from "../../components/Link";
33

4-
const createLinkDecorator = () => ({
5-
strategy: createLinkStrategy(),
4+
const createLinkDecorator = ({ entityType }) => ({
5+
strategy: createLinkStrategy({ entityType }),
66
component: Link,
77
});
88

src/decorators/link/linkStrategy.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
const createLinkStrategy = () => {
1+
const createLinkStrategy = ({ entityType }) => {
22
const findLinkEntities = (contentBlock, callback, contentState) => {
33
contentBlock.findEntityRanges(character => {
44
const entityKey = character.getEntity();
55
return (
66
entityKey !== null &&
7-
contentState.getEntity(entityKey).getType() === "LINK"
7+
contentState.getEntity(entityKey).getType() === entityType
88
);
99
}, callback);
1010
};

src/index.js

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { replaceText } from "./utils";
3333
import {
3434
CODE_BLOCK_REGEX,
3535
CODE_BLOCK_TYPE,
36+
ENTITY_TYPE,
3637
defaultInlineWhitelist,
3738
defaultBlockWhitelist,
3839
} from "./constants";
@@ -101,13 +102,17 @@ function checkCharacterForState(config, editorState, character) {
101102
editorState === newEditorState &&
102103
config.features.inline.includes("IMAGE")
103104
) {
104-
newEditorState = handleImage(editorState, character);
105+
newEditorState = handleImage(
106+
editorState,
107+
character,
108+
config.entityType.IMAGE
109+
);
105110
}
106111
if (
107112
editorState === newEditorState &&
108113
config.features.inline.includes("LINK")
109114
) {
110-
newEditorState = handleLink(editorState, character);
115+
newEditorState = handleLink(editorState, character, config.entityType.LINK);
111116
}
112117
if (
113118
newEditorState === editorState &&
@@ -204,6 +209,7 @@ const defaultConfig = {
204209
inline: defaultInlineWhitelist,
205210
block: defaultBlockWhitelist,
206211
},
212+
entityType: ENTITY_TYPE,
207213
};
208214

209215
const createMarkdownPlugin = (_config = {}) => {
@@ -216,6 +222,10 @@ const createMarkdownPlugin = (_config = {}) => {
216222
...defaultConfig.features,
217223
..._config.features,
218224
},
225+
entityType: {
226+
...defaultConfig.entityType,
227+
..._config.entityType,
228+
},
219229
};
220230

221231
return {
@@ -226,7 +236,14 @@ const createMarkdownPlugin = (_config = {}) => {
226236
wrapper: <pre spellCheck="false" />,
227237
},
228238
}).merge(checkboxBlockRenderMap),
229-
decorators: [createLinkDecorator(), createImageDecorator()],
239+
decorators: [
240+
createLinkDecorator({
241+
entityType: config.entityType.LINK,
242+
}),
243+
createImageDecorator({
244+
entityType: config.entityType.IMAGE,
245+
}),
246+
],
230247
initialize({ setEditorState, getEditorState }) {
231248
store.setEditorState = setEditorState;
232249
store.getEditorState = getEditorState;

0 commit comments

Comments
 (0)