@uiw/react-md-editor 4.1.5 → 4.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -1
- package/dist/mdeditor.css +5 -0
- package/dist/mdeditor.js +2382 -1031
- package/dist/mdeditor.min.css +1 -1
- package/dist/mdeditor.min.js +1 -1
- package/esm/Editor.factory.js +85 -11
- package/esm/Types.d.ts +6 -0
- package/esm/commands/index.cn.d.ts +2 -1
- package/esm/commands/index.cn.js +2 -2
- package/esm/commands/index.d.ts +2 -2
- package/esm/commands/index.js +2 -2
- package/esm/commands/list.d.ts +1 -1
- package/esm/commands/list.js +9 -3
- package/esm/components/TextArea/Markdown.common.d.ts +3 -5
- package/esm/components/TextArea/Markdown.common.js +2 -56
- package/esm/components/TextArea/Markdown.d.ts +3 -5
- package/esm/components/TextArea/Markdown.factory.d.ts +6 -0
- package/esm/components/TextArea/Markdown.factory.js +138 -0
- package/esm/components/TextArea/Markdown.js +2 -63
- package/esm/components/TextArea/factory.js +6 -2
- package/esm/components/TextArea/index.css +5 -0
- package/esm/components/TextArea/index.less +5 -0
- package/esm/components/TextArea/splitBlocks.d.ts +13 -0
- package/esm/components/TextArea/splitBlocks.js +111 -0
- package/esm/package.json +1 -0
- package/lib/Editor.factory.js +93 -12
- package/lib/Types.d.ts +6 -0
- package/lib/commands/index.cn.d.ts +2 -1
- package/lib/commands/index.cn.js +8 -1
- package/lib/commands/index.d.ts +2 -2
- package/lib/commands/index.js +6 -0
- package/lib/commands/list.d.ts +1 -1
- package/lib/commands/list.js +5 -1
- package/lib/components/TextArea/Markdown.common.d.ts +3 -5
- package/lib/components/TextArea/Markdown.common.js +3 -60
- package/lib/components/TextArea/Markdown.d.ts +3 -5
- package/lib/components/TextArea/Markdown.factory.d.ts +6 -0
- package/lib/components/TextArea/Markdown.factory.js +148 -0
- package/lib/components/TextArea/Markdown.js +3 -67
- package/lib/components/TextArea/factory.js +6 -2
- package/lib/components/TextArea/index.less +5 -0
- package/lib/components/TextArea/splitBlocks.d.ts +13 -0
- package/lib/components/TextArea/splitBlocks.js +117 -0
- package/markdown-editor.css +5 -0
- package/package.json +18 -12
- package/src/Editor.factory.tsx +83 -4
- package/src/Types.ts +6 -0
- package/src/commands/index.cn.ts +2 -0
- package/src/commands/index.ts +2 -1
- package/src/commands/list.tsx +11 -2
- package/src/components/TextArea/Markdown.common.tsx +3 -46
- package/src/components/TextArea/Markdown.factory.tsx +132 -0
- package/src/components/TextArea/Markdown.tsx +3 -55
- package/src/components/TextArea/factory.tsx +7 -4
- package/src/components/TextArea/index.less +5 -0
- package/src/components/TextArea/splitBlocks.ts +114 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
var FENCE_OPEN = /^```/;
|
|
2
|
+
var FENCE_CLOSE = /^```\r?\n?$/;
|
|
3
|
+
var BLANK_LINE = /^[ \t]*\r?\n?$/;
|
|
4
|
+
var FRONT_MATTER_FENCE = /^---\r?\n?$/;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Splits markdown into blocks that Prism's markdown grammar highlights the same way
|
|
8
|
+
* on their own as it does in the full document, so unchanged blocks can be cached.
|
|
9
|
+
* Joining the returned blocks always yields the original string.
|
|
10
|
+
*
|
|
11
|
+
* A block ends where a run of blank lines starts, so each block keeps its leading blank
|
|
12
|
+
* lines (indented code needs them). No split happens inside a ``` fence, front matter or
|
|
13
|
+
* multiline markup or link references, or right before a `---` line, which Prism
|
|
14
|
+
* would read as front matter. Whitespace-only lines stay in their block because
|
|
15
|
+
* Prism's inline emphasis can span them.
|
|
16
|
+
* Fences follow Prism's rule, not CommonMark's, so the split matches what Prism sees.
|
|
17
|
+
*/
|
|
18
|
+
export function splitBlocks(markdown) {
|
|
19
|
+
var lines = markdown.match(/[^\n]*\n|[^\n]+$/g) || [];
|
|
20
|
+
var blocks = [];
|
|
21
|
+
var current = '';
|
|
22
|
+
var pendingSplit = -1;
|
|
23
|
+
var inFence = false;
|
|
24
|
+
var inFrontMatter = /^(?:\s*[\r\n])?---(?:\r?\n|$)/.test(markdown);
|
|
25
|
+
var frontMatterStarted = false;
|
|
26
|
+
var syntax = {
|
|
27
|
+
end: '',
|
|
28
|
+
quote: '',
|
|
29
|
+
brackets: 0,
|
|
30
|
+
subset: 0
|
|
31
|
+
};
|
|
32
|
+
var previousIsBlank = true;
|
|
33
|
+
lines.forEach(line => {
|
|
34
|
+
var isBlank = BLANK_LINE.test(line);
|
|
35
|
+
var canSplit = !inFence && !inFrontMatter && !syntax.end && !syntax.brackets;
|
|
36
|
+
if (/^\r?\n$/.test(line) && !previousIsBlank && canSplit) {
|
|
37
|
+
pendingSplit = current.length;
|
|
38
|
+
}
|
|
39
|
+
if (!isBlank && pendingSplit > 0) {
|
|
40
|
+
if (!FRONT_MATTER_FENCE.test(line)) {
|
|
41
|
+
blocks.push(current.slice(0, pendingSplit));
|
|
42
|
+
current = current.slice(pendingSplit);
|
|
43
|
+
}
|
|
44
|
+
pendingSplit = -1;
|
|
45
|
+
}
|
|
46
|
+
current += line;
|
|
47
|
+
previousIsBlank = isBlank;
|
|
48
|
+
if (inFrontMatter) {
|
|
49
|
+
if (FRONT_MATTER_FENCE.test(line)) {
|
|
50
|
+
inFrontMatter = !frontMatterStarted;
|
|
51
|
+
frontMatterStarted = true;
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (inFence) {
|
|
56
|
+
inFence = !FENCE_CLOSE.test(line);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (!syntax.end && FENCE_OPEN.test(line)) {
|
|
60
|
+
inFence = true;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
updateSyntax(line, syntax);
|
|
64
|
+
});
|
|
65
|
+
if (current) {
|
|
66
|
+
blocks.push(current);
|
|
67
|
+
}
|
|
68
|
+
return blocks;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Keep potential multiline Prism tokens together. Unclosed syntax conservatively
|
|
72
|
+
// keeps the rest of the document in one block until the user closes it.
|
|
73
|
+
function updateSyntax(line, state) {
|
|
74
|
+
var reference = false;
|
|
75
|
+
for (var i = 0; i < line.length; i++) {
|
|
76
|
+
var char = line[i];
|
|
77
|
+
if (state.end && state.end !== '>') {
|
|
78
|
+
var end = line.indexOf(state.end, i);
|
|
79
|
+
if (end === -1) return;
|
|
80
|
+
i = end + state.end.length - 1;
|
|
81
|
+
state.end = '';
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (state.end === '>') {
|
|
85
|
+
if (state.quote) {
|
|
86
|
+
if (char === state.quote) state.quote = '';
|
|
87
|
+
} else if (char === '"' || char === "'") {
|
|
88
|
+
state.quote = char;
|
|
89
|
+
} else if (char === '[') {
|
|
90
|
+
state.subset++;
|
|
91
|
+
} else if (char === ']' && state.subset) {
|
|
92
|
+
state.subset--;
|
|
93
|
+
} else if (char === '>' && !state.subset) {
|
|
94
|
+
state.end = '';
|
|
95
|
+
}
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (char === '\\') {
|
|
99
|
+
i++;
|
|
100
|
+
} else if (char === '<' && /[a-z!?/]/i.test(line[i + 1] || '')) {
|
|
101
|
+
state.end = line.startsWith('<!--', i) ? '-->' : line.startsWith('<![CDATA[', i) ? ']]>' : line.startsWith('<?', i) ? '?>' : '>';
|
|
102
|
+
} else if (char === '[') {
|
|
103
|
+
state.brackets++;
|
|
104
|
+
} else if (char === ']') {
|
|
105
|
+
state.brackets = Math.max(0, state.brackets - 1);
|
|
106
|
+
reference = line[i + 1] === ':';
|
|
107
|
+
} else if (reference && (char === '"' || char === "'" || char === '(')) {
|
|
108
|
+
state.end = char === '(' ? ')' : char;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
package/esm/package.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
package/lib/Editor.factory.js
CHANGED
|
@@ -7,15 +7,16 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
});
|
|
8
8
|
exports.createMDEditor = createMDEditor;
|
|
9
9
|
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
|
|
10
|
-
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
11
10
|
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
11
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
12
12
|
var _react = _interopRequireWildcard(require("react"));
|
|
13
13
|
var _Toolbar = require("./components/Toolbar/");
|
|
14
14
|
var _DragBar = _interopRequireDefault(require("./components/DragBar/"));
|
|
15
15
|
var _commands = require("./commands/");
|
|
16
16
|
var _Context = require("./Context");
|
|
17
17
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
18
|
-
var _excluded = ["
|
|
18
|
+
var _excluded = ["renderMsRef"],
|
|
19
|
+
_excluded2 = ["prefixCls", "className", "value", "commands", "commandsFilter", "direction", "extraCommands", "height", "enableScroll", "visibleDragbar", "highlightEnable", "preview", "fullscreen", "overflow", "previewOptions", "textareaProps", "id", "name", "required", "disabled", "readOnly", "placeholder", "aria-label", "aria-labelledby", "aria-describedby", "aria-invalid", "aria-required", "aria-errormessage", "maxHeight", "minHeight", "autoFocus", "autoFocusEnd", "tabSize", "defaultTabEnable", "onChange", "onStatistics", "onHeightChange", "hideToolbar", "toolbarBottom", "components", "renderTextarea"];
|
|
19
20
|
function setGroupPopFalse() {
|
|
20
21
|
var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
21
22
|
Object.keys(data).forEach(function (keyname) {
|
|
@@ -23,11 +24,64 @@ function setGroupPopFalse() {
|
|
|
23
24
|
});
|
|
24
25
|
return data;
|
|
25
26
|
}
|
|
27
|
+
var DEFAULT_PREVIEW_OPTIONS = {};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Lets the preview render after the textarea on React 18+, so typing in a large
|
|
31
|
+
* document stays responsive. Older React versions render it right away, as before.
|
|
32
|
+
*/
|
|
33
|
+
var useDeferredValue = _react["default"].useDeferredValue || function (value) {
|
|
34
|
+
return value;
|
|
35
|
+
};
|
|
36
|
+
var useIsomorphicLayoutEffect = typeof window === 'undefined' ? _react.useEffect : _react.useLayoutEffect;
|
|
37
|
+
var SLOW_PREVIEW_MS = 50;
|
|
38
|
+
var MAX_PREVIEW_DELAY_MS = 500;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Keeps the preview in step with every keystroke while it renders fast. Once a preview
|
|
42
|
+
* render takes longer than SLOW_PREVIEW_MS, it waits for a pause in typing as long as
|
|
43
|
+
* that render (at most MAX_PREVIEW_DELAY_MS) before updating.
|
|
44
|
+
* https://github.com/uiwjs/react-md-editor/issues/620
|
|
45
|
+
*/
|
|
46
|
+
function usePreviewSource(markdown, previewRenderMs) {
|
|
47
|
+
var _useReducer = (0, _react.useReducer)(function (count) {
|
|
48
|
+
return count + 1;
|
|
49
|
+
}, 0),
|
|
50
|
+
_useReducer2 = (0, _slicedToArray2["default"])(_useReducer, 2),
|
|
51
|
+
rerender = _useReducer2[1];
|
|
52
|
+
var shownRef = (0, _react.useRef)(markdown);
|
|
53
|
+
if (previewRenderMs.current < SLOW_PREVIEW_MS) {
|
|
54
|
+
shownRef.current = markdown;
|
|
55
|
+
}
|
|
56
|
+
(0, _react.useEffect)(function () {
|
|
57
|
+
if (shownRef.current === markdown) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
var delay = Math.min(previewRenderMs.current, MAX_PREVIEW_DELAY_MS);
|
|
61
|
+
var timer = setTimeout(function () {
|
|
62
|
+
shownRef.current = markdown;
|
|
63
|
+
rerender();
|
|
64
|
+
}, delay);
|
|
65
|
+
return function () {
|
|
66
|
+
return clearTimeout(timer);
|
|
67
|
+
};
|
|
68
|
+
}, [markdown, previewRenderMs]);
|
|
69
|
+
return shownRef.current;
|
|
70
|
+
}
|
|
26
71
|
function createMDEditor(options) {
|
|
27
72
|
var MarkdownPreview = options.MarkdownPreview,
|
|
28
73
|
TextArea = options.TextArea;
|
|
29
74
|
var PreviewComponent = MarkdownPreview;
|
|
30
75
|
var TextAreaComponent = TextArea;
|
|
76
|
+
function TimedPreview(props) {
|
|
77
|
+
var renderMsRef = props.renderMsRef,
|
|
78
|
+
previewProps = (0, _objectWithoutProperties2["default"])(props, _excluded);
|
|
79
|
+
var renderStart = performance.now();
|
|
80
|
+
useIsomorphicLayoutEffect(function () {
|
|
81
|
+
renderMsRef.current = performance.now() - renderStart;
|
|
82
|
+
});
|
|
83
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(PreviewComponent, (0, _objectSpread2["default"])({}, previewProps));
|
|
84
|
+
}
|
|
31
85
|
var InternalMDEditor = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
|
|
32
86
|
var _ref = props || {},
|
|
33
87
|
_ref$prefixCls = _ref.prefixCls,
|
|
@@ -55,8 +109,20 @@ function createMDEditor(options) {
|
|
|
55
109
|
_ref$overflow = _ref.overflow,
|
|
56
110
|
overflow = _ref$overflow === void 0 ? true : _ref$overflow,
|
|
57
111
|
_ref$previewOptions = _ref.previewOptions,
|
|
58
|
-
previewOptions = _ref$previewOptions === void 0 ?
|
|
112
|
+
previewOptions = _ref$previewOptions === void 0 ? DEFAULT_PREVIEW_OPTIONS : _ref$previewOptions,
|
|
59
113
|
textareaProps = _ref.textareaProps,
|
|
114
|
+
id = _ref.id,
|
|
115
|
+
name = _ref.name,
|
|
116
|
+
required = _ref.required,
|
|
117
|
+
disabled = _ref.disabled,
|
|
118
|
+
readOnly = _ref.readOnly,
|
|
119
|
+
placeholder = _ref.placeholder,
|
|
120
|
+
ariaLabel = _ref['aria-label'],
|
|
121
|
+
ariaLabelledBy = _ref['aria-labelledby'],
|
|
122
|
+
ariaDescribedBy = _ref['aria-describedby'],
|
|
123
|
+
ariaInvalid = _ref['aria-invalid'],
|
|
124
|
+
ariaRequired = _ref['aria-required'],
|
|
125
|
+
ariaErrorMessage = _ref['aria-errormessage'],
|
|
60
126
|
_ref$maxHeight = _ref.maxHeight,
|
|
61
127
|
maxHeight = _ref$maxHeight === void 0 ? 1200 : _ref$maxHeight,
|
|
62
128
|
_ref$minHeight = _ref.minHeight,
|
|
@@ -76,14 +142,14 @@ function createMDEditor(options) {
|
|
|
76
142
|
toolbarBottom = _ref$toolbarBottom === void 0 ? false : _ref$toolbarBottom,
|
|
77
143
|
components = _ref.components,
|
|
78
144
|
renderTextarea = _ref.renderTextarea,
|
|
79
|
-
other = (0, _objectWithoutProperties2["default"])(_ref,
|
|
145
|
+
other = (0, _objectWithoutProperties2["default"])(_ref, _excluded2);
|
|
80
146
|
var cmds = commands.map(function (item) {
|
|
81
147
|
return commandsFilter ? commandsFilter(item, false) : item;
|
|
82
148
|
}).filter(Boolean);
|
|
83
149
|
var extraCmds = extraCommands.map(function (item) {
|
|
84
150
|
return commandsFilter ? commandsFilter(item, true) : item;
|
|
85
151
|
}).filter(Boolean);
|
|
86
|
-
var
|
|
152
|
+
var _useReducer3 = (0, _react.useReducer)(_Context.reducer, {
|
|
87
153
|
markdown: propsValue,
|
|
88
154
|
preview: previewType,
|
|
89
155
|
components: components,
|
|
@@ -99,9 +165,9 @@ function createMDEditor(options) {
|
|
|
99
165
|
fullscreen: fullscreen,
|
|
100
166
|
barPopup: {}
|
|
101
167
|
}),
|
|
102
|
-
|
|
103
|
-
state =
|
|
104
|
-
dispatch =
|
|
168
|
+
_useReducer4 = (0, _slicedToArray2["default"])(_useReducer3, 2),
|
|
169
|
+
state = _useReducer4[0],
|
|
170
|
+
dispatch = _useReducer4[1];
|
|
105
171
|
var container = (0, _react.useRef)(null);
|
|
106
172
|
var previewRef = (0, _react.useRef)(null);
|
|
107
173
|
var enableScrollRef = (0, _react.useRef)(enableScroll);
|
|
@@ -235,16 +301,19 @@ function createMDEditor(options) {
|
|
|
235
301
|
var handlePreviewScroll = function handlePreviewScroll(e) {
|
|
236
302
|
return handleScroll(e, 'preview');
|
|
237
303
|
};
|
|
304
|
+
var previewRenderMs = (0, _react.useRef)(0);
|
|
305
|
+
var previewMarkdown = useDeferredValue(usePreviewSource(state.markdown || '', previewRenderMs));
|
|
238
306
|
var mdPreview = (0, _react.useMemo)(function () {
|
|
239
307
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
240
308
|
ref: previewRef,
|
|
241
309
|
className: previewClassName,
|
|
242
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
310
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(TimedPreview, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, previewOptions), {}, {
|
|
311
|
+
renderMsRef: previewRenderMs,
|
|
243
312
|
onScroll: handlePreviewScroll,
|
|
244
|
-
source:
|
|
313
|
+
source: previewMarkdown
|
|
245
314
|
}))
|
|
246
315
|
});
|
|
247
|
-
}, [previewClassName, previewOptions,
|
|
316
|
+
}, [previewClassName, previewOptions, previewMarkdown]);
|
|
248
317
|
var preview = (components === null || components === void 0 ? void 0 : components.preview) && (components === null || components === void 0 ? void 0 : components.preview(state.markdown || '', state, dispatch));
|
|
249
318
|
if (preview && /*#__PURE__*/_react["default"].isValidElement(preview)) {
|
|
250
319
|
mdPreview = /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
@@ -302,7 +371,19 @@ function createMDEditor(options) {
|
|
|
302
371
|
children: [/(edit|live)/.test(state.preview || '') && /*#__PURE__*/(0, _jsxRuntime.jsx)(TextAreaComponent, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({
|
|
303
372
|
className: "".concat(prefixCls, "-input"),
|
|
304
373
|
prefixCls: prefixCls,
|
|
305
|
-
autoFocus: autoFocus
|
|
374
|
+
autoFocus: autoFocus,
|
|
375
|
+
id: id,
|
|
376
|
+
name: name,
|
|
377
|
+
required: required,
|
|
378
|
+
disabled: disabled,
|
|
379
|
+
readOnly: readOnly,
|
|
380
|
+
placeholder: placeholder,
|
|
381
|
+
"aria-label": ariaLabel,
|
|
382
|
+
"aria-labelledby": ariaLabelledBy,
|
|
383
|
+
"aria-describedby": ariaDescribedBy,
|
|
384
|
+
"aria-invalid": ariaInvalid,
|
|
385
|
+
"aria-required": ariaRequired,
|
|
386
|
+
"aria-errormessage": ariaErrorMessage
|
|
306
387
|
}, textareaProps), {}, {
|
|
307
388
|
onChange: changeHandle,
|
|
308
389
|
renderTextarea: (components === null || components === void 0 ? void 0 : components.textarea) || renderTextarea,
|
package/lib/Types.d.ts
CHANGED
|
@@ -18,6 +18,12 @@ export interface MDEditorProps extends Omit<React.HTMLAttributes<HTMLDivElement>
|
|
|
18
18
|
* The Markdown value.
|
|
19
19
|
*/
|
|
20
20
|
value?: string;
|
|
21
|
+
/** Native textarea form attributes. */
|
|
22
|
+
name?: React.TextareaHTMLAttributes<HTMLTextAreaElement>['name'];
|
|
23
|
+
required?: React.TextareaHTMLAttributes<HTMLTextAreaElement>['required'];
|
|
24
|
+
disabled?: React.TextareaHTMLAttributes<HTMLTextAreaElement>['disabled'];
|
|
25
|
+
readOnly?: React.TextareaHTMLAttributes<HTMLTextAreaElement>['readOnly'];
|
|
26
|
+
placeholder?: React.TextareaHTMLAttributes<HTMLTextAreaElement>['placeholder'];
|
|
21
27
|
/**
|
|
22
28
|
* Event handler for the `onChange` event.
|
|
23
29
|
*/
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type ICommand } from './';
|
|
2
2
|
import { divider } from './divider';
|
|
3
3
|
import { group } from './group';
|
|
4
|
+
import { makeList } from './list';
|
|
4
5
|
declare let bold: ICommand;
|
|
5
6
|
declare let code: ICommand;
|
|
6
7
|
declare let codeBlock: ICommand;
|
|
@@ -30,4 +31,4 @@ declare let table: ICommand;
|
|
|
30
31
|
declare let help: ICommand;
|
|
31
32
|
export declare const getCommands: () => ICommand[];
|
|
32
33
|
export declare const getExtraCommands: () => ICommand[];
|
|
33
|
-
export { title, title1, title2, title3, title4, title5, title6, bold, codeBlock, comment, italic, strikethrough, hr, group, divider, link, quote, code, image, unorderedListCommand, orderedListCommand, checkedListCommand, table, issue, help, codeEdit, codeLive, codePreview, fullscreen, };
|
|
34
|
+
export { title, title1, title2, title3, title4, title5, title6, bold, codeBlock, comment, italic, strikethrough, hr, group, divider, link, quote, code, image, unorderedListCommand, orderedListCommand, checkedListCommand, makeList, table, issue, help, codeEdit, codeLive, codePreview, fullscreen, };
|
package/lib/commands/index.cn.js
CHANGED
|
@@ -18,7 +18,14 @@ Object.defineProperty(exports, "group", {
|
|
|
18
18
|
return _group.group;
|
|
19
19
|
}
|
|
20
20
|
});
|
|
21
|
-
exports.
|
|
21
|
+
exports.link = exports.italic = exports.issue = exports.image = exports.hr = exports.help = void 0;
|
|
22
|
+
Object.defineProperty(exports, "makeList", {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
get: function get() {
|
|
25
|
+
return _list.makeList;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
exports.unorderedListCommand = exports.title6 = exports.title5 = exports.title4 = exports.title3 = exports.title2 = exports.title1 = exports.title = exports.table = exports.strikethrough = exports.quote = exports.orderedListCommand = void 0;
|
|
22
29
|
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
|
|
23
30
|
var _divider = require("./divider");
|
|
24
31
|
var _group = require("./group");
|
package/lib/commands/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { hr } from './hr';
|
|
|
10
10
|
import { image } from './image';
|
|
11
11
|
import { italic } from './italic';
|
|
12
12
|
import { link } from './link';
|
|
13
|
-
import { checkedListCommand, orderedListCommand, unorderedListCommand } from './list';
|
|
13
|
+
import { checkedListCommand, makeList, orderedListCommand, unorderedListCommand } from './list';
|
|
14
14
|
import { codeEdit, codeLive, codePreview } from './preview';
|
|
15
15
|
import { quote } from './quote';
|
|
16
16
|
import { strikethrough } from './strikeThrough';
|
|
@@ -93,4 +93,4 @@ declare class TextAreaCommandOrchestrator implements CommandOrchestrator {
|
|
|
93
93
|
getState(): false | TextState;
|
|
94
94
|
executeCommand(command: ICommand<string>, dispatch?: React.Dispatch<ContextStore>, state?: ExecuteCommandState, shortcuts?: string[]): void;
|
|
95
95
|
}
|
|
96
|
-
export { title, title1, title2, title3, title4, title5, title6, heading, heading1, heading2, heading3, heading4, heading5, heading6, bold, codeBlock, comment, italic, strikethrough, hr, group, divider, link, quote, code, image, unorderedListCommand, orderedListCommand, checkedListCommand, table, issue, help, codeEdit, codeLive, codePreview, fullscreen, getCommands, getExtraCommands, getStateFromTextArea, TextAreaCommandOrchestrator, TextAreaTextApi, };
|
|
96
|
+
export { title, title1, title2, title3, title4, title5, title6, heading, heading1, heading2, heading3, heading4, heading5, heading6, bold, codeBlock, comment, italic, strikethrough, hr, group, divider, link, quote, code, image, unorderedListCommand, orderedListCommand, checkedListCommand, makeList, table, issue, help, codeEdit, codeLive, codePreview, fullscreen, getCommands, getExtraCommands, getStateFromTextArea, TextAreaCommandOrchestrator, TextAreaTextApi, };
|
package/lib/commands/index.js
CHANGED
|
@@ -151,6 +151,12 @@ Object.defineProperty(exports, "link", {
|
|
|
151
151
|
return _link.link;
|
|
152
152
|
}
|
|
153
153
|
});
|
|
154
|
+
Object.defineProperty(exports, "makeList", {
|
|
155
|
+
enumerable: true,
|
|
156
|
+
get: function get() {
|
|
157
|
+
return _list.makeList;
|
|
158
|
+
}
|
|
159
|
+
});
|
|
154
160
|
Object.defineProperty(exports, "orderedListCommand", {
|
|
155
161
|
enumerable: true,
|
|
156
162
|
get: function get() {
|
package/lib/commands/list.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ICommand, type ExecuteState, TextAreaTextApi } from './';
|
|
2
2
|
import { AlterLineFunction } from '../utils/markdownUtils';
|
|
3
|
-
export declare const makeList: (state: ExecuteState, api: TextAreaTextApi, insertBefore: string | AlterLineFunction) => void;
|
|
3
|
+
export declare const makeList: (state: ExecuteState, api: TextAreaTextApi, insertBefore: string | AlterLineFunction, selectionStrategy?: "word" | "line") => void;
|
|
4
4
|
export declare const unorderedListCommand: ICommand;
|
|
5
5
|
export declare const orderedListCommand: ICommand;
|
|
6
6
|
export declare const checkedListCommand: ICommand;
|
package/lib/commands/list.js
CHANGED
|
@@ -9,7 +9,11 @@ var _react = _interopRequireDefault(require("react"));
|
|
|
9
9
|
var _markdownUtils = require("../utils/markdownUtils");
|
|
10
10
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
11
11
|
var makeList = exports.makeList = function makeList(state, api, insertBefore) {
|
|
12
|
-
var
|
|
12
|
+
var selectionStrategy = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'word';
|
|
13
|
+
var newSelectionRange = selectionStrategy === 'line' ? (0, _markdownUtils.selectLine)({
|
|
14
|
+
text: state.text,
|
|
15
|
+
selection: state.selection
|
|
16
|
+
}) : (0, _markdownUtils.selectWord)({
|
|
13
17
|
text: state.text,
|
|
14
18
|
selection: state.selection,
|
|
15
19
|
prefix: state.command.prefix
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
}
|
|
5
|
-
export default function Markdown(props: MarkdownProps): import("react/jsx-runtime").JSX.Element;
|
|
1
|
+
export type { MarkdownProps } from './Markdown.factory';
|
|
2
|
+
declare const _default: (props: import("./Markdown.factory").MarkdownProps) => import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export default _default;
|
|
@@ -1,68 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
|
|
4
|
-
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard")["default"];
|
|
5
4
|
Object.defineProperty(exports, "__esModule", {
|
|
6
5
|
value: true
|
|
7
6
|
});
|
|
8
|
-
exports["default"] =
|
|
9
|
-
var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
|
|
10
|
-
var _react = _interopRequireWildcard(require("react"));
|
|
11
|
-
var _rehype = require("rehype");
|
|
7
|
+
exports["default"] = void 0;
|
|
12
8
|
var _common = _interopRequireDefault(require("rehype-prism-plus/common"));
|
|
13
|
-
var
|
|
14
|
-
var
|
|
15
|
-
var _templateObject;
|
|
16
|
-
function html2Escape(sHtml) {
|
|
17
|
-
return sHtml.replace(/[<&"]/g, function (c) {
|
|
18
|
-
return {
|
|
19
|
-
'<': '<',
|
|
20
|
-
'>': '>',
|
|
21
|
-
'&': '&',
|
|
22
|
-
'"': '"'
|
|
23
|
-
}[c];
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
function Markdown(props) {
|
|
27
|
-
var prefixCls = props.prefixCls;
|
|
28
|
-
var _useContext = (0, _react.useContext)(_Context.EditorContext),
|
|
29
|
-
_useContext$markdown = _useContext.markdown,
|
|
30
|
-
markdown = _useContext$markdown === void 0 ? '' : _useContext$markdown,
|
|
31
|
-
highlightEnable = _useContext.highlightEnable,
|
|
32
|
-
dispatch = _useContext.dispatch;
|
|
33
|
-
var preRef = /*#__PURE__*/_react["default"].createRef();
|
|
34
|
-
(0, _react.useEffect)(function () {
|
|
35
|
-
if (preRef.current && dispatch) {
|
|
36
|
-
dispatch({
|
|
37
|
-
textareaPre: preRef.current
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
41
|
-
}, []);
|
|
42
|
-
if (!markdown) {
|
|
43
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)("pre", {
|
|
44
|
-
ref: preRef,
|
|
45
|
-
className: "".concat(prefixCls, "-text-pre wmde-markdown-color")
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
var mdStr = "<pre class=\"language-markdown ".concat(prefixCls, "-text-pre wmde-markdown-color\"><code class=\"language-markdown\">").concat(html2Escape(String.raw(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["", ""])), markdown)), "\n</code></pre>");
|
|
49
|
-
if (highlightEnable) {
|
|
50
|
-
try {
|
|
51
|
-
mdStr = (0, _rehype.rehype)().data('settings', {
|
|
52
|
-
fragment: true
|
|
53
|
-
})
|
|
54
|
-
// https://github.com/uiwjs/react-md-editor/issues/593
|
|
55
|
-
// @ts-ignore
|
|
56
|
-
.use(_common["default"], {
|
|
57
|
-
ignoreMissing: true
|
|
58
|
-
}).processSync(mdStr).toString();
|
|
59
|
-
} catch (error) {}
|
|
60
|
-
}
|
|
61
|
-
return /*#__PURE__*/_react["default"].createElement('div', {
|
|
62
|
-
className: 'wmde-markdown-color',
|
|
63
|
-
dangerouslySetInnerHTML: {
|
|
64
|
-
__html: mdStr || ''
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
}
|
|
9
|
+
var _Markdown = require("./Markdown.factory");
|
|
10
|
+
var _default = exports["default"] = (0, _Markdown.createMarkdown)(_common["default"]);
|
|
68
11
|
module.exports = exports.default;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
}
|
|
5
|
-
export default function Markdown(props: MarkdownProps): import("react/jsx-runtime").JSX.Element;
|
|
1
|
+
export type { MarkdownProps } from './Markdown.factory';
|
|
2
|
+
declare const _default: (props: import("./Markdown.factory").MarkdownProps) => import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export default _default;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type rehypePrismPlus from 'rehype-prism-plus';
|
|
3
|
+
import { type IProps } from '../../Types';
|
|
4
|
+
export interface MarkdownProps extends IProps, React.HTMLAttributes<HTMLPreElement> {
|
|
5
|
+
}
|
|
6
|
+
export declare function createMarkdown(rehypePrism: typeof rehypePrismPlus): (props: MarkdownProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard")["default"];
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.createMarkdown = createMarkdown;
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
+
var _rehype = require("rehype");
|
|
10
|
+
var _Context = require("../../Context");
|
|
11
|
+
var _splitBlocks = require("./splitBlocks");
|
|
12
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
|
+
/**
|
|
14
|
+
* Prism's markdown grammar takes quadratic time on long lines, so a single base64 image
|
|
15
|
+
* line can block the editor for minutes. Blocks with such a line are shown uncoloured.
|
|
16
|
+
*/var MAX_HIGHLIGHT_LINE_LENGTH = 1000;
|
|
17
|
+
function html2Escape(sHtml) {
|
|
18
|
+
return sHtml.replace(/[<&"]/g, function (c) {
|
|
19
|
+
return {
|
|
20
|
+
'<': '<',
|
|
21
|
+
'>': '>',
|
|
22
|
+
'&': '&',
|
|
23
|
+
'"': '"'
|
|
24
|
+
}[c];
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function hasLongLine(text) {
|
|
28
|
+
var lineStart = 0;
|
|
29
|
+
while (lineStart <= text.length) {
|
|
30
|
+
var lineEnd = text.indexOf('\n', lineStart);
|
|
31
|
+
var end = lineEnd === -1 ? text.length : lineEnd;
|
|
32
|
+
if (end - lineStart > MAX_HIGHLIGHT_LINE_LENGTH) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
lineStart = end + 1;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
function getCodeInnerHtml(html) {
|
|
40
|
+
var codeStart = html.indexOf('<code');
|
|
41
|
+
var contentStart = html.indexOf('>', codeStart) + 1;
|
|
42
|
+
var contentEnd = html.lastIndexOf('</code>');
|
|
43
|
+
return html.slice(contentStart, contentEnd);
|
|
44
|
+
}
|
|
45
|
+
var MarkdownBlock = /*#__PURE__*/_react["default"].memo(function MarkdownBlock(props) {
|
|
46
|
+
return /*#__PURE__*/_react["default"].createElement('span', {
|
|
47
|
+
dangerouslySetInnerHTML: {
|
|
48
|
+
__html: props.html
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
function createMarkdown(rehypePrism) {
|
|
53
|
+
var processor = (0, _rehype.rehype)().data('settings', {
|
|
54
|
+
fragment: true
|
|
55
|
+
})
|
|
56
|
+
// https://github.com/uiwjs/react-md-editor/issues/593
|
|
57
|
+
// @ts-ignore
|
|
58
|
+
.use(rehypePrism, {
|
|
59
|
+
ignoreMissing: true
|
|
60
|
+
});
|
|
61
|
+
function highlightBlock(block) {
|
|
62
|
+
var escaped = html2Escape(block);
|
|
63
|
+
if (hasLongLine(block)) {
|
|
64
|
+
return escaped;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
var html = processor.processSync("<pre><code class=\"language-markdown\">".concat(escaped, "</code></pre>")).toString();
|
|
68
|
+
return getCodeInnerHtml(html);
|
|
69
|
+
} catch (error) {
|
|
70
|
+
return escaped;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Highlighting runs per block, and blocks whose text did not change reuse their cached
|
|
76
|
+
* HTML and DOM, so typing in a large document only re-highlights the edited block.
|
|
77
|
+
* https://github.com/uiwjs/react-md-editor/issues/620
|
|
78
|
+
*/
|
|
79
|
+
return function Markdown(props) {
|
|
80
|
+
var prefixCls = props.prefixCls;
|
|
81
|
+
var _useContext = (0, _react.useContext)(_Context.EditorContext),
|
|
82
|
+
_useContext$markdown = _useContext.markdown,
|
|
83
|
+
markdown = _useContext$markdown === void 0 ? '' : _useContext$markdown,
|
|
84
|
+
highlightEnable = _useContext.highlightEnable,
|
|
85
|
+
dispatch = _useContext.dispatch;
|
|
86
|
+
var preRef = (0, _react.useRef)(null);
|
|
87
|
+
var cacheRef = (0, _react.useRef)(new Map());
|
|
88
|
+
var nextIdRef = (0, _react.useRef)(0);
|
|
89
|
+
(0, _react.useEffect)(function () {
|
|
90
|
+
if (preRef.current && dispatch) {
|
|
91
|
+
dispatch({
|
|
92
|
+
textareaPre: preRef.current
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
96
|
+
}, []);
|
|
97
|
+
var blocks = (0, _react.useMemo)(function () {
|
|
98
|
+
if (!highlightEnable) {
|
|
99
|
+
cacheRef.current = new Map();
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
var cache = new Map();
|
|
103
|
+
var occurrences = new Map();
|
|
104
|
+
var result = (0, _splitBlocks.splitBlocks)(markdown).map(function (block) {
|
|
105
|
+
var highlighted = cacheRef.current.get(block) || cache.get(block);
|
|
106
|
+
if (!highlighted) {
|
|
107
|
+
highlighted = {
|
|
108
|
+
id: nextIdRef.current++,
|
|
109
|
+
html: highlightBlock(block)
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
cache.set(block, highlighted);
|
|
113
|
+
var occurrence = occurrences.get(block) || 0;
|
|
114
|
+
occurrences.set(block, occurrence + 1);
|
|
115
|
+
return {
|
|
116
|
+
key: "".concat(highlighted.id, "-").concat(occurrence),
|
|
117
|
+
html: highlighted.html
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
cacheRef.current = cache;
|
|
121
|
+
return result;
|
|
122
|
+
}, [markdown, highlightEnable]);
|
|
123
|
+
if (!markdown) {
|
|
124
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("pre", {
|
|
125
|
+
ref: preRef,
|
|
126
|
+
className: "".concat(prefixCls, "-text-pre wmde-markdown-color")
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
130
|
+
className: "wmde-markdown-color",
|
|
131
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("pre", {
|
|
132
|
+
ref: preRef,
|
|
133
|
+
className: "language-markdown ".concat(prefixCls, "-text-pre wmde-markdown-color"),
|
|
134
|
+
children: highlightEnable ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("code", {
|
|
135
|
+
className: "language-markdown code-highlight",
|
|
136
|
+
children: [blocks.map(function (block) {
|
|
137
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(MarkdownBlock, {
|
|
138
|
+
html: block.html
|
|
139
|
+
}, block.key);
|
|
140
|
+
}), '\n']
|
|
141
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)("code", {
|
|
142
|
+
className: "language-markdown",
|
|
143
|
+
children: "".concat(markdown, "\n")
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
}
|