decap-cms-widget-markdown 3.1.6 → 3.2.0
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/CHANGELOG.md +6 -0
- package/dist/decap-cms-widget-markdown.js +4 -4
- package/dist/decap-cms-widget-markdown.js.map +1 -1
- package/dist/esm/MarkdownControl/VisualEditor.js +4 -3
- package/dist/esm/MarkdownControl/plugins/html/withHtml.js +140 -0
- package/dist/esm/MarkdownControl/renderers.js +18 -18
- package/dist/esm/serializers/slateRemark.js +1 -1
- package/package.json +2 -2
- package/src/MarkdownControl/VisualEditor.js +4 -1
- package/src/MarkdownControl/plugins/html/withHtml.js +98 -0
- package/src/MarkdownControl/renderers.js +2 -2
- package/src/serializers/slateRemark.js +1 -1
- package/dist/esm/MarkdownControl/plugins/blocks/locations/isCursorAfterSoftBreak.js +0 -16
- package/dist/esm/MarkdownControl/plugins/blocks/locations/isCursorInNonDefaultBlock copy.js +0 -19
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "decap-cms-widget-markdown",
|
|
3
3
|
"description": "Widget for editing markdown in Decap CMS.",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.2.0",
|
|
5
5
|
"homepage": "https://www.decapcms.org/docs/widgets/#markdown",
|
|
6
6
|
"repository": "https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-widget-markdown",
|
|
7
7
|
"bugs": "https://github.com/decaporg/decap-cms/issues",
|
|
@@ -60,5 +60,5 @@
|
|
|
60
60
|
"commonmark-spec": "^0.30.0",
|
|
61
61
|
"slate-hyperscript": "^0.77.0"
|
|
62
62
|
},
|
|
63
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "022dbe523d07bb8bc74970460cc82b259fde4041"
|
|
64
64
|
}
|
|
@@ -26,6 +26,7 @@ import { markdownToSlate, slateToMarkdown } from '../serializers';
|
|
|
26
26
|
import withShortcodes from './plugins/shortcodes/withShortcodes';
|
|
27
27
|
import insertShortcode from './plugins/shortcodes/insertShortcode';
|
|
28
28
|
import defaultEmptyBlock from './plugins/blocks/defaultEmptyBlock';
|
|
29
|
+
import withHtml from './plugins/html/withHtml';
|
|
29
30
|
|
|
30
31
|
function visualEditorStyles({ minimal }) {
|
|
31
32
|
return `
|
|
@@ -97,7 +98,9 @@ function Editor(props) {
|
|
|
97
98
|
|
|
98
99
|
const editor = useMemo(
|
|
99
100
|
() =>
|
|
100
|
-
|
|
101
|
+
withHtml(
|
|
102
|
+
withReact(withHistory(withShortcodes(withBlocks(withLists(withInlines(createEditor())))))),
|
|
103
|
+
),
|
|
101
104
|
[],
|
|
102
105
|
);
|
|
103
106
|
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// source: https://github.com/ianstormtaylor/slate/blob/main/site/examples/ts/paste-html.tsx
|
|
2
|
+
import { jsx } from 'slate-hyperscript';
|
|
3
|
+
import { Transforms } from 'slate';
|
|
4
|
+
|
|
5
|
+
const ELEMENT_TAGS = {
|
|
6
|
+
A: el => ({ type: 'link', url: el.getAttribute('href') }),
|
|
7
|
+
BLOCKQUOTE: () => ({ type: 'quote' }),
|
|
8
|
+
H1: () => ({ type: 'heading-one' }),
|
|
9
|
+
H2: () => ({ type: 'heading-two' }),
|
|
10
|
+
H3: () => ({ type: 'heading-three' }),
|
|
11
|
+
H4: () => ({ type: 'heading-four' }),
|
|
12
|
+
H5: () => ({ type: 'heading-five' }),
|
|
13
|
+
H6: () => ({ type: 'heading-six' }),
|
|
14
|
+
IMG: el => ({ type: 'image', url: el.getAttribute('src') }),
|
|
15
|
+
LI: () => ({ type: 'list-item' }),
|
|
16
|
+
OL: () => ({ type: 'numbered-list' }),
|
|
17
|
+
P: () => ({ type: 'paragraph' }),
|
|
18
|
+
PRE: () => ({ type: 'code' }),
|
|
19
|
+
UL: () => ({ type: 'bulleted-list' }),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// COMPAT: `B` is omitted here because Google Docs uses `<b>` in weird ways.
|
|
23
|
+
const TEXT_TAGS = {
|
|
24
|
+
CODE: () => ({ code: true }),
|
|
25
|
+
DEL: () => ({ strikethrough: true }),
|
|
26
|
+
EM: () => ({ italic: true }),
|
|
27
|
+
I: () => ({ italic: true }),
|
|
28
|
+
S: () => ({ strikethrough: true }),
|
|
29
|
+
STRONG: () => ({ bold: true }),
|
|
30
|
+
U: () => ({ underline: true }),
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function deserialize(el) {
|
|
34
|
+
if (el.nodeType === 3) {
|
|
35
|
+
return el.textContent;
|
|
36
|
+
} else if (el.nodeType !== 1) {
|
|
37
|
+
return null;
|
|
38
|
+
} else if (el.nodeName === 'BR') {
|
|
39
|
+
return '\n';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const { nodeName } = el;
|
|
43
|
+
let parent = el;
|
|
44
|
+
|
|
45
|
+
if (nodeName === 'PRE' && el.childNodes[0] && el.childNodes[0].nodeName === 'CODE') {
|
|
46
|
+
parent = el.childNodes[0];
|
|
47
|
+
}
|
|
48
|
+
let children = Array.from(parent.childNodes).map(deserialize).flat();
|
|
49
|
+
|
|
50
|
+
if (children.length === 0) {
|
|
51
|
+
children = [{ text: '' }];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (el.nodeName === 'BODY') {
|
|
55
|
+
return jsx('fragment', {}, children);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (ELEMENT_TAGS[nodeName]) {
|
|
59
|
+
const attrs = ELEMENT_TAGS[nodeName](el);
|
|
60
|
+
return jsx('element', attrs, children);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (TEXT_TAGS[nodeName]) {
|
|
64
|
+
const attrs = TEXT_TAGS[nodeName](el);
|
|
65
|
+
return children.map(child => jsx('text', attrs, child));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return children;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function withHtml(editor) {
|
|
72
|
+
const { insertData, isInline, isVoid } = editor;
|
|
73
|
+
|
|
74
|
+
editor.isInline = element => {
|
|
75
|
+
return element.type === 'link' ? true : isInline(element);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
editor.isVoid = element => {
|
|
79
|
+
return element.type === 'image' ? true : isVoid(element);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
editor.insertData = data => {
|
|
83
|
+
const html = data.getData('text/html');
|
|
84
|
+
|
|
85
|
+
if (html) {
|
|
86
|
+
const parsed = new DOMParser().parseFromString(html, 'text/html');
|
|
87
|
+
const fragment = deserialize(parsed.body);
|
|
88
|
+
Transforms.insertFragment(editor, fragment);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
insertData(data);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
return editor;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export default withHtml;
|
|
@@ -226,8 +226,8 @@ function NumberedList(props) {
|
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
function Link(props) {
|
|
229
|
-
const url = props.url;
|
|
230
|
-
const title = props.title || url;
|
|
229
|
+
const url = props.element.url;
|
|
230
|
+
const title = props.element.title || url;
|
|
231
231
|
|
|
232
232
|
return (
|
|
233
233
|
<StyledA href={url} title={title} {...props.attributes}>
|
|
@@ -450,7 +450,7 @@ export default function slateToRemark(value, { voidCodeBlock }) {
|
|
|
450
450
|
*/
|
|
451
451
|
case 'link': {
|
|
452
452
|
const { title, data } = node;
|
|
453
|
-
return u(typeMap[node.type], { url:
|
|
453
|
+
return u(typeMap[node.type], { url: node.url, title, ...data }, children);
|
|
454
454
|
}
|
|
455
455
|
|
|
456
456
|
/**
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
var _slate = require("slate");
|
|
8
|
-
function isCursorAfterSoftBreak(editor) {
|
|
9
|
-
const {
|
|
10
|
-
selection
|
|
11
|
-
} = editor;
|
|
12
|
-
if (!selection) return false;
|
|
13
|
-
const [previous] = _slate.Editor.previous(editor);
|
|
14
|
-
return previous && previous.type == 'break';
|
|
15
|
-
}
|
|
16
|
-
var _default = exports.default = isCursorAfterSoftBreak;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
var _slate = require("slate");
|
|
8
|
-
function isCursorInNonDefaultBlock(editor) {
|
|
9
|
-
const {
|
|
10
|
-
selection
|
|
11
|
-
} = editor;
|
|
12
|
-
if (!selection) return false;
|
|
13
|
-
const [match] = Array.from(_slate.Editor.nodes(editor, {
|
|
14
|
-
match: n => _slate.Element.isElement(n) && _slate.Editor.isBlock(editor, n) && n.type !== 'paragraph',
|
|
15
|
-
mode: 'lowest'
|
|
16
|
-
}));
|
|
17
|
-
return !!match && !_slate.Editor.isEditor(match[0]);
|
|
18
|
-
}
|
|
19
|
-
var _default = exports.default = isCursorInNonDefaultBlock;
|