@frontkom/block-react-parser 0.1.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/.nvmrc +1 -0
- package/dist/components/Block.js +49 -0
- package/dist/components/Context.js +31 -0
- package/dist/components/Tree.js +47 -0
- package/dist/elements/index.js +180 -0
- package/dist/elements/tags/img.js +25 -0
- package/dist/elements/tags/selfClosing.js +17 -0
- package/dist/index.js +61 -0
- package/dist/utils/attribsProps.js +22 -0
- package/dist/utils/innerNode.js +20 -0
- package/dist/utils/parseBlocks.js +20 -0
- package/package.json +43 -0
- package/src/components/Block.jsx +37 -0
- package/src/components/Context.js +20 -0
- package/src/components/Tree.jsx +37 -0
- package/src/elements/index.js +135 -0
- package/src/elements/tags/img.js +13 -0
- package/src/elements/tags/selfClosing.js +8 -0
- package/src/index.js +7 -0
- package/src/utils/attribsProps.js +21 -0
- package/src/utils/innerNode.jsx +19 -0
- package/src/utils/parseBlocks.jsx +13 -0
package/.nvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
16.16.0
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = Block;
|
|
7
|
+
var _Tree = _interopRequireDefault(require("./Tree"));
|
|
8
|
+
var _innerNode = _interopRequireDefault(require("../utils/innerNode"));
|
|
9
|
+
var _Context = require("./Context");
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
+
/**
|
|
12
|
+
* Block element.
|
|
13
|
+
*
|
|
14
|
+
* @param {object} componentProps - properties that includes the block object.
|
|
15
|
+
* @returns {JSX.Element | null | undefined}
|
|
16
|
+
*/
|
|
17
|
+
function Block(_ref) {
|
|
18
|
+
let {
|
|
19
|
+
block
|
|
20
|
+
} = _ref;
|
|
21
|
+
const {
|
|
22
|
+
blockName = null,
|
|
23
|
+
innerContent,
|
|
24
|
+
innerBlocks
|
|
25
|
+
} = block;
|
|
26
|
+
const CustomBlock = (0, _Context.useBlockComponent)(blockName);
|
|
27
|
+
if (CustomBlock) {
|
|
28
|
+
return /*#__PURE__*/React.createElement(CustomBlock, {
|
|
29
|
+
block: block
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Filter out empty blocks.
|
|
34
|
+
if (!blockName && innerContent.length === 0) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
// Filter out empty lines and orphaned closing tags.
|
|
38
|
+
if (innerContent.length === 1 && (innerContent[0] === "\n" || innerContent[0].substring(0, 2) === "</")) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const node = (0, _innerNode.default)(innerBlocks, innerContent);
|
|
42
|
+
if (node) {
|
|
43
|
+
return /*#__PURE__*/React.createElement(_Tree.default, {
|
|
44
|
+
node: node,
|
|
45
|
+
block: block
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Provider = void 0;
|
|
7
|
+
exports.useBlockComponent = useBlockComponent;
|
|
8
|
+
exports.useComponentContext = useComponentContext;
|
|
9
|
+
exports.useTagComponent = useTagComponent;
|
|
10
|
+
var _react = require("react");
|
|
11
|
+
var _elements = require("../elements");
|
|
12
|
+
const TxContext = /*#__PURE__*/(0, _react.createContext)();
|
|
13
|
+
const {
|
|
14
|
+
Provider
|
|
15
|
+
} = TxContext;
|
|
16
|
+
exports.Provider = Provider;
|
|
17
|
+
function useComponentContext() {
|
|
18
|
+
return (0, _react.useContext)(TxContext);
|
|
19
|
+
}
|
|
20
|
+
function useBlockComponent(name) {
|
|
21
|
+
const {
|
|
22
|
+
CustomBlocks = _elements.coreBlocks
|
|
23
|
+
} = (0, _react.useContext)(TxContext);
|
|
24
|
+
return name && CustomBlocks[name];
|
|
25
|
+
}
|
|
26
|
+
function useTagComponent(tag) {
|
|
27
|
+
const {
|
|
28
|
+
CustomTags = _elements.coreTags
|
|
29
|
+
} = (0, _react.useContext)(TxContext);
|
|
30
|
+
return tag && CustomTags[tag];
|
|
31
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = Tree;
|
|
7
|
+
var _Context = require("./Context");
|
|
8
|
+
var _Block = _interopRequireDefault(require("./Block"));
|
|
9
|
+
var _attribsProps = _interopRequireDefault(require("../utils/attribsProps"));
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
+
function Tree(_ref) {
|
|
12
|
+
var _node$children;
|
|
13
|
+
let {
|
|
14
|
+
node,
|
|
15
|
+
block
|
|
16
|
+
} = _ref;
|
|
17
|
+
const CustomTag = (0, _Context.useTagComponent)(node.name);
|
|
18
|
+
(0, _attribsProps.default)(node.attribs);
|
|
19
|
+
if (node.type === "text") {
|
|
20
|
+
if (node.data === "[innerBlocks]") {
|
|
21
|
+
var _block$innerBlocks;
|
|
22
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
23
|
+
return (_block$innerBlocks = block.innerBlocks) === null || _block$innerBlocks === void 0 ? void 0 : _block$innerBlocks.map((inner, index) => /*#__PURE__*/React.createElement(_Block.default, {
|
|
24
|
+
block: inner,
|
|
25
|
+
key: index
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
return node.data;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Handle selfclosed elements (???)
|
|
32
|
+
if (CustomTag) {
|
|
33
|
+
return /*#__PURE__*/React.createElement(CustomTag, {
|
|
34
|
+
attribs: node.attribs
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
const Component = node.name;
|
|
38
|
+
const attrs = (0, _attribsProps.default)(node.attribs);
|
|
39
|
+
return /*#__PURE__*/React.createElement(Component, attrs, (_node$children = node.children) === null || _node$children === void 0 ? void 0 : _node$children.map((child, index) =>
|
|
40
|
+
/*#__PURE__*/
|
|
41
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
42
|
+
React.createElement(Tree, {
|
|
43
|
+
node: child,
|
|
44
|
+
block: block,
|
|
45
|
+
key: index
|
|
46
|
+
})));
|
|
47
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.customTags = exports.customBlocks = exports.coreTags = exports.coreBlocks = void 0;
|
|
7
|
+
var _img = _interopRequireDefault(require("./tags/img"));
|
|
8
|
+
var _selfClosing = _interopRequireDefault(require("./tags/selfClosing"));
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
const coreTags = exports.coreTags = {
|
|
11
|
+
img: _ref => {
|
|
12
|
+
let {
|
|
13
|
+
attribs
|
|
14
|
+
} = _ref;
|
|
15
|
+
return /*#__PURE__*/React.createElement(_img.default, {
|
|
16
|
+
attribs: attribs
|
|
17
|
+
});
|
|
18
|
+
},
|
|
19
|
+
br: _ref2 => {
|
|
20
|
+
let {
|
|
21
|
+
attribs
|
|
22
|
+
} = _ref2;
|
|
23
|
+
return /*#__PURE__*/React.createElement(_selfClosing.default, {
|
|
24
|
+
attribs: attribs,
|
|
25
|
+
tag: "br"
|
|
26
|
+
});
|
|
27
|
+
},
|
|
28
|
+
hr: _ref3 => {
|
|
29
|
+
let {
|
|
30
|
+
attribs
|
|
31
|
+
} = _ref3;
|
|
32
|
+
return /*#__PURE__*/React.createElement(_selfClosing.default, {
|
|
33
|
+
attribs: attribs,
|
|
34
|
+
tag: "hr"
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
meta: _ref4 => {
|
|
38
|
+
let {
|
|
39
|
+
attribs
|
|
40
|
+
} = _ref4;
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
// area: ({attribs}) => <SelfClosing attribs={attribs} tag="area" />,
|
|
44
|
+
// base: ({attribs}) => <SelfClosing attribs={attribs} tag="base" />,
|
|
45
|
+
// col: ({attribs}) => <SelfClosing attribs={attribs} tag="col" />,
|
|
46
|
+
// embed: ({attribs}) => <SelfClosing attribs={attribs} tag="embed" />,
|
|
47
|
+
// input: ({attribs}) => <SelfClosing attribs={attribs} tag="input" />,
|
|
48
|
+
// link: ({attribs}) => <SelfClosing attribs={attribs} tag="link" />,
|
|
49
|
+
// meta: ({attribs}) => <SelfClosing attribs={attribs} tag="meta" />,
|
|
50
|
+
// param: ({attribs}) => <SelfClosing attribs={attribs} tag="param" />,
|
|
51
|
+
// source: ({attribs}) => <SelfClosing attribs={attribs} tag="source" />,
|
|
52
|
+
// track: ({attribs}) => <SelfClosing attribs={attribs} tag="track" />,
|
|
53
|
+
// wbr: ({attribs}) => <SelfClosing attribs={attribs} tag="wbr" />,
|
|
54
|
+
};
|
|
55
|
+
const coreBlocks = exports.coreBlocks = {
|
|
56
|
+
// 'core/archives': ({ block }) => doSomething(),
|
|
57
|
+
// 'core/audio': ({ block }) => doSomething(),
|
|
58
|
+
// 'core/avatar': ({ block }) => doSomething(),
|
|
59
|
+
// 'core/block': ({ block }) => doSomething(),
|
|
60
|
+
// 'core/button': ({ block }) => doSomething(),
|
|
61
|
+
// 'core/buttons': ({ block }) => doSomething(),
|
|
62
|
+
// 'core/calendar': ({ block }) => doSomething(),
|
|
63
|
+
// 'core/categories': ({ block }) => doSomething(),
|
|
64
|
+
// 'core/code': ({ block }) => doSomething(),
|
|
65
|
+
// 'core/column': ({ block }) => <p>Column</p>,
|
|
66
|
+
// 'core/columns': ({ block }) => doSomething(),
|
|
67
|
+
// 'core/comment-author-avatar': ({ block }) => doSomething(),
|
|
68
|
+
// 'core/comment-author-name': ({ block }) => doSomething(),
|
|
69
|
+
// 'core/comment-content': ({ block }) => doSomething(),
|
|
70
|
+
// 'core/comment-date': ({ block }) => doSomething(),
|
|
71
|
+
// 'core/comment-edit-link': ({ block }) => doSomething(),
|
|
72
|
+
// 'core/comment-reply-link': ({ block }) => doSomething(),
|
|
73
|
+
// 'core/comment-template': ({ block }) => doSomething(),
|
|
74
|
+
// 'core/comments': ({ block }) => doSomething(),
|
|
75
|
+
// 'core/comments-pagination': ({ block }) => doSomething(),
|
|
76
|
+
// 'core/comments-pagination-next': ({ block }) => doSomething(),
|
|
77
|
+
// 'core/comments-pagination-numbers': ({ block }) => doSomething(),
|
|
78
|
+
// 'core/comments-pagination-previous': ({ block }) => doSomething(),
|
|
79
|
+
// 'core/comments-title': ({ block }) => doSomething(),
|
|
80
|
+
// 'core/cover': ({ block }) => doSomething(),
|
|
81
|
+
// 'core/embed': ({ block }) => doSomething(),
|
|
82
|
+
// 'core/file': ({ block }) => doSomething(),
|
|
83
|
+
// 'core/freeform': ({ block }) => doSomething(),
|
|
84
|
+
// 'core/gallery': ({ block }) => doSomething(),
|
|
85
|
+
// 'core/group': ({ block }) => doSomething(),
|
|
86
|
+
// 'core/heading': ({ block }) => doSomething(),
|
|
87
|
+
// 'core/home-link': ({ block }) => doSomething(),
|
|
88
|
+
// 'core/html': ({ block }) => doSomething(),
|
|
89
|
+
// 'core/image': ({ block }) => doSomething(),
|
|
90
|
+
// 'core/latest-comments': ({ block }) => doSomething(),
|
|
91
|
+
// 'core/latest-posts': ({ block }) => doSomething(),
|
|
92
|
+
// 'core/list': ({ block }) => doSomething(),
|
|
93
|
+
// 'core/list-item': ({ block }) => doSomething(),
|
|
94
|
+
// 'core/loginout': ({ block }) => doSomething(),
|
|
95
|
+
// 'core/media-text': ({ block }) => doSomething(),
|
|
96
|
+
// 'core/missing': ({ block }) => doSomething(),
|
|
97
|
+
// 'core/more': ({ block }) => doSomething(),
|
|
98
|
+
// 'core/navigation': ({ block }) => doSomething(),
|
|
99
|
+
// 'core/navigation-link': ({ block }) => doSomething(),
|
|
100
|
+
// 'core/navigation-submenu': ({ block }) => doSomething(),
|
|
101
|
+
// 'core/nextpage': ({ block }) => doSomething(),
|
|
102
|
+
// 'core/page-list': ({ block }) => doSomething(),
|
|
103
|
+
// 'core/paragraph': ({ block }) => doSomething(),
|
|
104
|
+
// 'core/pattern': ({ block }) => doSomething(),
|
|
105
|
+
// 'core/post-author': ({ block }) => doSomething(),
|
|
106
|
+
// 'core/post-author-biography': ({ block }) => doSomething(),
|
|
107
|
+
// 'core/post-author-name': ({ block }) => doSomething(),
|
|
108
|
+
// 'core/post-comment': ({ block }) => doSomething(),
|
|
109
|
+
// 'core/post-comments-count': ({ block }) => doSomething(),
|
|
110
|
+
// 'core/post-comments-form': ({ block }) => doSomething(),
|
|
111
|
+
// 'core/post-comments-link': ({ block }) => doSomething(),
|
|
112
|
+
// 'core/post-content': ({ block }) => doSomething(),
|
|
113
|
+
// 'core/post-date': ({ block }) => doSomething(),
|
|
114
|
+
// 'core/post-excerpt': ({ block }) => doSomething(),
|
|
115
|
+
// 'core/post-featured-image': ({ block }) => doSomething(),
|
|
116
|
+
// 'core/post-navigation-link': ({ block }) => doSomething(),
|
|
117
|
+
// 'core/post-template': ({ block }) => doSomething(),
|
|
118
|
+
// 'core/post-terms': ({ block }) => doSomething(),
|
|
119
|
+
// 'core/post-title': ({ block }) => doSomething(),
|
|
120
|
+
// 'core/preformatted': ({ block }) => doSomething(),
|
|
121
|
+
// 'core/pullquote': ({ block }) => doSomething(),
|
|
122
|
+
// 'core/query': ({ block }) => doSomething(),
|
|
123
|
+
// 'core/query-no-results': ({ block }) => doSomething(),
|
|
124
|
+
// 'core/query-pagination': ({ block }) => doSomething(),
|
|
125
|
+
// 'core/query-pagination-next': ({ block }) => doSomething(),
|
|
126
|
+
// 'core/query-pagination-numbers': ({ block }) => doSomething(),
|
|
127
|
+
// 'core/query-pagination-previous': ({ block }) => doSomething(),
|
|
128
|
+
// 'core/query-title': ({ block }) => doSomething(),
|
|
129
|
+
// 'core/quote': ({ block }) => doSomething(),
|
|
130
|
+
// 'core/read-more': ({ block }) => doSomething(),
|
|
131
|
+
// 'core/rss': ({ block }) => doSomething(),
|
|
132
|
+
// 'core/search': ({ block }) => doSomething(),
|
|
133
|
+
// 'core/separator': ({ block }) => doSomething(),
|
|
134
|
+
// 'core/shortcode': ({ block }) => doSomething(),
|
|
135
|
+
// 'core/site-logo': ({ block }) => doSomething(),
|
|
136
|
+
// 'core/site-tagline': ({ block }) => doSomething(),
|
|
137
|
+
// 'core/site-title': ({ block }) => doSomething(),
|
|
138
|
+
// 'core/social-link': ({ block }) => doSomething(),
|
|
139
|
+
// 'core/social-links': ({ block }) => doSomething(),
|
|
140
|
+
// 'core/spacer': ({ block }) => doSomething(),
|
|
141
|
+
// 'core/table': ({ block }) => doSomething(),
|
|
142
|
+
// 'core/table-of-contents': ({ block }) => doSomething(),
|
|
143
|
+
// 'core/tag-cloud': ({ block }) => doSomething(),
|
|
144
|
+
// 'core/template-part': ({ block }) => doSomething(),
|
|
145
|
+
// 'core/term-description': ({ block }) => doSomething(),
|
|
146
|
+
// 'core/text-columns': ({ block }) => doSomething(),
|
|
147
|
+
// 'core/verse': ({ block }) => doSomething(),
|
|
148
|
+
// 'core/video': ({ block }) => doSomething(),
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Helper function to setup custom tags definitions.
|
|
153
|
+
*
|
|
154
|
+
* @param {object} tags - Optional object with custom blocks definitions. Empty by default.
|
|
155
|
+
* @returns {object} Object with blocks definitions
|
|
156
|
+
*/
|
|
157
|
+
const customTags = function () {
|
|
158
|
+
let tags = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
159
|
+
return {
|
|
160
|
+
...coreTags,
|
|
161
|
+
...tags
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Helper function to setup custom blocks definitions.
|
|
167
|
+
*
|
|
168
|
+
* @param {object} blocks - Optional object with custom blocks definitions. Empty by default.
|
|
169
|
+
* @param {boolean} useDefaultBlocks - Optional boolean to use core blocks defaults. True by default.
|
|
170
|
+
* @returns {object} Object with blocks definitions
|
|
171
|
+
*/
|
|
172
|
+
exports.customTags = customTags;
|
|
173
|
+
const customBlocks = function () {
|
|
174
|
+
let blocks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
175
|
+
return {
|
|
176
|
+
...coreBlocks,
|
|
177
|
+
...blocks
|
|
178
|
+
};
|
|
179
|
+
};
|
|
180
|
+
exports.customBlocks = customBlocks;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = Image;
|
|
7
|
+
function Image(_ref) {
|
|
8
|
+
let {
|
|
9
|
+
attribs
|
|
10
|
+
} = _ref;
|
|
11
|
+
const {
|
|
12
|
+
alt = '',
|
|
13
|
+
class: className = '',
|
|
14
|
+
src,
|
|
15
|
+
height,
|
|
16
|
+
width
|
|
17
|
+
} = attribs;
|
|
18
|
+
return /*#__PURE__*/React.createElement("img", {
|
|
19
|
+
alt: alt,
|
|
20
|
+
className: className,
|
|
21
|
+
src: src,
|
|
22
|
+
width: width,
|
|
23
|
+
height: height
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = SelfClosing;
|
|
7
|
+
var _attribsProps = _interopRequireDefault(require("../../utils/attribsProps"));
|
|
8
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
9
|
+
function SelfClosing(_ref) {
|
|
10
|
+
let {
|
|
11
|
+
attribs,
|
|
12
|
+
tag
|
|
13
|
+
} = _ref;
|
|
14
|
+
const Component = tag;
|
|
15
|
+
const attributes = (0, _attribsProps.default)(attribs);
|
|
16
|
+
return /*#__PURE__*/React.createElement(Component, attributes);
|
|
17
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "Block", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _Block.default;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "Provider", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _Context.Provider;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "Tree", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _Tree.default;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "attribsProps", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _attribsProps.default;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(exports, "customBlocks", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return _elements.customBlocks;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(exports, "customTags", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return _elements.customTags;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(exports, "innerNode", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function () {
|
|
45
|
+
return _innerNode.default;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(exports, "parseBlocks", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function () {
|
|
51
|
+
return _parseBlocks.default;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
var _Block = _interopRequireDefault(require("./components/Block"));
|
|
55
|
+
var _Tree = _interopRequireDefault(require("./components/Tree"));
|
|
56
|
+
var _Context = require("./components/Context");
|
|
57
|
+
var _elements = require("./elements");
|
|
58
|
+
var _attribsProps = _interopRequireDefault(require("./utils/attribsProps"));
|
|
59
|
+
var _innerNode = _interopRequireDefault(require("./utils/innerNode"));
|
|
60
|
+
var _parseBlocks = _interopRequireDefault(require("./utils/parseBlocks"));
|
|
61
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _reactAttrConverter = _interopRequireDefault(require("react-attr-converter"));
|
|
8
|
+
var _styleToJs = _interopRequireDefault(require("style-to-js"));
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
const attribsProps = attribs => {
|
|
11
|
+
if (attribs === undefined) {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
const props = Object.fromEntries(Object.entries(attribs).map(attribute => {
|
|
15
|
+
if (attribute[0] === 'style') {
|
|
16
|
+
return [(0, _reactAttrConverter.default)(attribute[0]), (0, _styleToJs.default)(attribute[1])];
|
|
17
|
+
}
|
|
18
|
+
return [(0, _reactAttrConverter.default)(attribute[0]), attribute[1]];
|
|
19
|
+
}));
|
|
20
|
+
return props;
|
|
21
|
+
};
|
|
22
|
+
var _default = exports.default = attribsProps;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _htmlparser = require("htmlparser2");
|
|
8
|
+
const innerNode = (innerBlocks, innerContent) => {
|
|
9
|
+
var _tree$children$;
|
|
10
|
+
// If no inner blocks, return the block markup.
|
|
11
|
+
// If inner blocks, return the wrapping markup.
|
|
12
|
+
const innerHtml = !innerBlocks.length ? innerContent[0] : "".concat(innerContent[0], "[innerBlocks]").concat(innerContent[innerContent.length - 1]);
|
|
13
|
+
const html = innerHtml ? innerHtml.trim() : "";
|
|
14
|
+
const tree = (0, _htmlparser.parseDocument)(html, {
|
|
15
|
+
lowerCaseTags: true,
|
|
16
|
+
recognizeSelfClosing: true
|
|
17
|
+
});
|
|
18
|
+
return (_tree$children$ = tree.children[0]) !== null && _tree$children$ !== void 0 ? _tree$children$ : null;
|
|
19
|
+
};
|
|
20
|
+
var _default = exports.default = innerNode;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _blockSerializationDefaultParser = require("@wordpress/block-serialization-default-parser");
|
|
8
|
+
var _Block = _interopRequireDefault(require("../components/Block"));
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
/**
|
|
11
|
+
* Parse Gutenberg blocks from HTML markup.
|
|
12
|
+
*
|
|
13
|
+
* @param {string} html - markup rendered by Gutenberg editor.
|
|
14
|
+
* @returns {JSX.Element[]}
|
|
15
|
+
*/
|
|
16
|
+
const parseBlocks = html => (0, _blockSerializationDefaultParser.parse)(html.trim()).map((block, key) => /*#__PURE__*/React.createElement(_Block.default, {
|
|
17
|
+
block: block,
|
|
18
|
+
key: key
|
|
19
|
+
}));
|
|
20
|
+
var _default = exports.default = parseBlocks;
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@frontkom/block-react-parser",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Gutenberg-generated HTML to React parser.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "rm -rf dist && NODE_ENV=production babel src --out-dir dist --copy-files"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"html",
|
|
12
|
+
"react",
|
|
13
|
+
"parser",
|
|
14
|
+
"gutenberg"
|
|
15
|
+
],
|
|
16
|
+
"author": "Roberto Ornelas <rob@frontkom.com>",
|
|
17
|
+
"license": "ISC",
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@wordpress/block-serialization-default-parser": "^4.21.0",
|
|
20
|
+
"htmlparser2": "^8.0.1",
|
|
21
|
+
"react-attr-converter": "^0.3.1",
|
|
22
|
+
"style-to-js": "^1.1.1"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@babel/cli": "^7.19.3",
|
|
26
|
+
"@babel/core": "^7.20.2",
|
|
27
|
+
"@babel/preset-env": "^7.20.2",
|
|
28
|
+
"@babel/preset-react": "^7.18.6",
|
|
29
|
+
"react": "^17.0.2",
|
|
30
|
+
"react-dom": "^17.0.2"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"react": "^17.0.2",
|
|
34
|
+
"react-dom": "^17.0.2"
|
|
35
|
+
},
|
|
36
|
+
"babel": {
|
|
37
|
+
"presets": [
|
|
38
|
+
"@babel/preset-env",
|
|
39
|
+
"@babel/preset-react"
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"browserslist": "> 0.25%, not dead"
|
|
43
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import Tree from "./Tree";
|
|
2
|
+
import innerNode from "../utils/innerNode";
|
|
3
|
+
import { useBlockComponent } from "./Context";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Block element.
|
|
7
|
+
*
|
|
8
|
+
* @param {object} componentProps - properties that includes the block object.
|
|
9
|
+
* @returns {JSX.Element | null | undefined}
|
|
10
|
+
*/
|
|
11
|
+
export default function Block({ block }) {
|
|
12
|
+
const { blockName = null, innerContent, innerBlocks } = block;
|
|
13
|
+
const CustomBlock = useBlockComponent(blockName);
|
|
14
|
+
|
|
15
|
+
if (CustomBlock) {
|
|
16
|
+
return <CustomBlock block={block} />;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Filter out empty blocks.
|
|
20
|
+
if (!blockName && innerContent.length === 0) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
// Filter out empty lines and orphaned closing tags.
|
|
24
|
+
if (
|
|
25
|
+
innerContent.length === 1 &&
|
|
26
|
+
(innerContent[0] === "\n" || innerContent[0].substring(0, 2) === "</")
|
|
27
|
+
) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const node = innerNode(innerBlocks, innerContent);
|
|
32
|
+
if (node) {
|
|
33
|
+
return <Tree node={node} block={block} />;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
import { coreTags, coreBlocks } from '../elements';
|
|
3
|
+
|
|
4
|
+
const TxContext = createContext();
|
|
5
|
+
|
|
6
|
+
export const { Provider } = TxContext;
|
|
7
|
+
|
|
8
|
+
export function useComponentContext() {
|
|
9
|
+
return useContext(TxContext);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function useBlockComponent(name) {
|
|
13
|
+
const { CustomBlocks = coreBlocks } = useContext(TxContext);
|
|
14
|
+
return name && CustomBlocks[name];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function useTagComponent(tag) {
|
|
18
|
+
const { CustomTags = coreTags } = useContext(TxContext);
|
|
19
|
+
return tag && CustomTags[tag];
|
|
20
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useTagComponent } from "./Context";
|
|
2
|
+
import Block from "./Block";
|
|
3
|
+
import attribsProps from "../utils/attribsProps";
|
|
4
|
+
|
|
5
|
+
export default function Tree({ node, block }) {
|
|
6
|
+
const CustomTag = useTagComponent(node.name);
|
|
7
|
+
|
|
8
|
+
attribsProps(node.attribs);
|
|
9
|
+
|
|
10
|
+
if (node.type === "text") {
|
|
11
|
+
if (node.data === "[innerBlocks]") {
|
|
12
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
13
|
+
return block.innerBlocks?.map((inner, index) => (
|
|
14
|
+
<Block block={inner} key={index} />
|
|
15
|
+
));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return node.data;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Handle selfclosed elements (???)
|
|
22
|
+
if (CustomTag) {
|
|
23
|
+
return <CustomTag attribs={node.attribs} />;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const Component = node.name;
|
|
27
|
+
const attrs = attribsProps(node.attribs);
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<Component {...attrs}>
|
|
31
|
+
{node.children?.map((child, index) => (
|
|
32
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
33
|
+
<Tree node={child} block={block} key={index} />
|
|
34
|
+
))}
|
|
35
|
+
</Component>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import Image from './tags/img';
|
|
2
|
+
import SelfClosing from './tags/selfClosing';
|
|
3
|
+
|
|
4
|
+
export const coreTags = {
|
|
5
|
+
img: ({ attribs }) => <Image attribs={attribs} />,
|
|
6
|
+
br: ({ attribs }) => <SelfClosing attribs={attribs} tag="br" />,
|
|
7
|
+
hr: ({ attribs }) => <SelfClosing attribs={attribs} tag="hr" />,
|
|
8
|
+
meta: ({ attribs }) => {
|
|
9
|
+
return null;
|
|
10
|
+
},
|
|
11
|
+
// area: ({attribs}) => <SelfClosing attribs={attribs} tag="area" />,
|
|
12
|
+
// base: ({attribs}) => <SelfClosing attribs={attribs} tag="base" />,
|
|
13
|
+
// col: ({attribs}) => <SelfClosing attribs={attribs} tag="col" />,
|
|
14
|
+
// embed: ({attribs}) => <SelfClosing attribs={attribs} tag="embed" />,
|
|
15
|
+
// input: ({attribs}) => <SelfClosing attribs={attribs} tag="input" />,
|
|
16
|
+
// link: ({attribs}) => <SelfClosing attribs={attribs} tag="link" />,
|
|
17
|
+
// meta: ({attribs}) => <SelfClosing attribs={attribs} tag="meta" />,
|
|
18
|
+
// param: ({attribs}) => <SelfClosing attribs={attribs} tag="param" />,
|
|
19
|
+
// source: ({attribs}) => <SelfClosing attribs={attribs} tag="source" />,
|
|
20
|
+
// track: ({attribs}) => <SelfClosing attribs={attribs} tag="track" />,
|
|
21
|
+
// wbr: ({attribs}) => <SelfClosing attribs={attribs} tag="wbr" />,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const coreBlocks = {
|
|
25
|
+
// 'core/archives': ({ block }) => doSomething(),
|
|
26
|
+
// 'core/audio': ({ block }) => doSomething(),
|
|
27
|
+
// 'core/avatar': ({ block }) => doSomething(),
|
|
28
|
+
// 'core/block': ({ block }) => doSomething(),
|
|
29
|
+
// 'core/button': ({ block }) => doSomething(),
|
|
30
|
+
// 'core/buttons': ({ block }) => doSomething(),
|
|
31
|
+
// 'core/calendar': ({ block }) => doSomething(),
|
|
32
|
+
// 'core/categories': ({ block }) => doSomething(),
|
|
33
|
+
// 'core/code': ({ block }) => doSomething(),
|
|
34
|
+
// 'core/column': ({ block }) => <p>Column</p>,
|
|
35
|
+
// 'core/columns': ({ block }) => doSomething(),
|
|
36
|
+
// 'core/comment-author-avatar': ({ block }) => doSomething(),
|
|
37
|
+
// 'core/comment-author-name': ({ block }) => doSomething(),
|
|
38
|
+
// 'core/comment-content': ({ block }) => doSomething(),
|
|
39
|
+
// 'core/comment-date': ({ block }) => doSomething(),
|
|
40
|
+
// 'core/comment-edit-link': ({ block }) => doSomething(),
|
|
41
|
+
// 'core/comment-reply-link': ({ block }) => doSomething(),
|
|
42
|
+
// 'core/comment-template': ({ block }) => doSomething(),
|
|
43
|
+
// 'core/comments': ({ block }) => doSomething(),
|
|
44
|
+
// 'core/comments-pagination': ({ block }) => doSomething(),
|
|
45
|
+
// 'core/comments-pagination-next': ({ block }) => doSomething(),
|
|
46
|
+
// 'core/comments-pagination-numbers': ({ block }) => doSomething(),
|
|
47
|
+
// 'core/comments-pagination-previous': ({ block }) => doSomething(),
|
|
48
|
+
// 'core/comments-title': ({ block }) => doSomething(),
|
|
49
|
+
// 'core/cover': ({ block }) => doSomething(),
|
|
50
|
+
// 'core/embed': ({ block }) => doSomething(),
|
|
51
|
+
// 'core/file': ({ block }) => doSomething(),
|
|
52
|
+
// 'core/freeform': ({ block }) => doSomething(),
|
|
53
|
+
// 'core/gallery': ({ block }) => doSomething(),
|
|
54
|
+
// 'core/group': ({ block }) => doSomething(),
|
|
55
|
+
// 'core/heading': ({ block }) => doSomething(),
|
|
56
|
+
// 'core/home-link': ({ block }) => doSomething(),
|
|
57
|
+
// 'core/html': ({ block }) => doSomething(),
|
|
58
|
+
// 'core/image': ({ block }) => doSomething(),
|
|
59
|
+
// 'core/latest-comments': ({ block }) => doSomething(),
|
|
60
|
+
// 'core/latest-posts': ({ block }) => doSomething(),
|
|
61
|
+
// 'core/list': ({ block }) => doSomething(),
|
|
62
|
+
// 'core/list-item': ({ block }) => doSomething(),
|
|
63
|
+
// 'core/loginout': ({ block }) => doSomething(),
|
|
64
|
+
// 'core/media-text': ({ block }) => doSomething(),
|
|
65
|
+
// 'core/missing': ({ block }) => doSomething(),
|
|
66
|
+
// 'core/more': ({ block }) => doSomething(),
|
|
67
|
+
// 'core/navigation': ({ block }) => doSomething(),
|
|
68
|
+
// 'core/navigation-link': ({ block }) => doSomething(),
|
|
69
|
+
// 'core/navigation-submenu': ({ block }) => doSomething(),
|
|
70
|
+
// 'core/nextpage': ({ block }) => doSomething(),
|
|
71
|
+
// 'core/page-list': ({ block }) => doSomething(),
|
|
72
|
+
// 'core/paragraph': ({ block }) => doSomething(),
|
|
73
|
+
// 'core/pattern': ({ block }) => doSomething(),
|
|
74
|
+
// 'core/post-author': ({ block }) => doSomething(),
|
|
75
|
+
// 'core/post-author-biography': ({ block }) => doSomething(),
|
|
76
|
+
// 'core/post-author-name': ({ block }) => doSomething(),
|
|
77
|
+
// 'core/post-comment': ({ block }) => doSomething(),
|
|
78
|
+
// 'core/post-comments-count': ({ block }) => doSomething(),
|
|
79
|
+
// 'core/post-comments-form': ({ block }) => doSomething(),
|
|
80
|
+
// 'core/post-comments-link': ({ block }) => doSomething(),
|
|
81
|
+
// 'core/post-content': ({ block }) => doSomething(),
|
|
82
|
+
// 'core/post-date': ({ block }) => doSomething(),
|
|
83
|
+
// 'core/post-excerpt': ({ block }) => doSomething(),
|
|
84
|
+
// 'core/post-featured-image': ({ block }) => doSomething(),
|
|
85
|
+
// 'core/post-navigation-link': ({ block }) => doSomething(),
|
|
86
|
+
// 'core/post-template': ({ block }) => doSomething(),
|
|
87
|
+
// 'core/post-terms': ({ block }) => doSomething(),
|
|
88
|
+
// 'core/post-title': ({ block }) => doSomething(),
|
|
89
|
+
// 'core/preformatted': ({ block }) => doSomething(),
|
|
90
|
+
// 'core/pullquote': ({ block }) => doSomething(),
|
|
91
|
+
// 'core/query': ({ block }) => doSomething(),
|
|
92
|
+
// 'core/query-no-results': ({ block }) => doSomething(),
|
|
93
|
+
// 'core/query-pagination': ({ block }) => doSomething(),
|
|
94
|
+
// 'core/query-pagination-next': ({ block }) => doSomething(),
|
|
95
|
+
// 'core/query-pagination-numbers': ({ block }) => doSomething(),
|
|
96
|
+
// 'core/query-pagination-previous': ({ block }) => doSomething(),
|
|
97
|
+
// 'core/query-title': ({ block }) => doSomething(),
|
|
98
|
+
// 'core/quote': ({ block }) => doSomething(),
|
|
99
|
+
// 'core/read-more': ({ block }) => doSomething(),
|
|
100
|
+
// 'core/rss': ({ block }) => doSomething(),
|
|
101
|
+
// 'core/search': ({ block }) => doSomething(),
|
|
102
|
+
// 'core/separator': ({ block }) => doSomething(),
|
|
103
|
+
// 'core/shortcode': ({ block }) => doSomething(),
|
|
104
|
+
// 'core/site-logo': ({ block }) => doSomething(),
|
|
105
|
+
// 'core/site-tagline': ({ block }) => doSomething(),
|
|
106
|
+
// 'core/site-title': ({ block }) => doSomething(),
|
|
107
|
+
// 'core/social-link': ({ block }) => doSomething(),
|
|
108
|
+
// 'core/social-links': ({ block }) => doSomething(),
|
|
109
|
+
// 'core/spacer': ({ block }) => doSomething(),
|
|
110
|
+
// 'core/table': ({ block }) => doSomething(),
|
|
111
|
+
// 'core/table-of-contents': ({ block }) => doSomething(),
|
|
112
|
+
// 'core/tag-cloud': ({ block }) => doSomething(),
|
|
113
|
+
// 'core/template-part': ({ block }) => doSomething(),
|
|
114
|
+
// 'core/term-description': ({ block }) => doSomething(),
|
|
115
|
+
// 'core/text-columns': ({ block }) => doSomething(),
|
|
116
|
+
// 'core/verse': ({ block }) => doSomething(),
|
|
117
|
+
// 'core/video': ({ block }) => doSomething(),
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Helper function to setup custom tags definitions.
|
|
122
|
+
*
|
|
123
|
+
* @param {object} tags - Optional object with custom blocks definitions. Empty by default.
|
|
124
|
+
* @returns {object} Object with blocks definitions
|
|
125
|
+
*/
|
|
126
|
+
export const customTags = (tags = {}) => ({ ...coreTags, ...tags });
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Helper function to setup custom blocks definitions.
|
|
130
|
+
*
|
|
131
|
+
* @param {object} blocks - Optional object with custom blocks definitions. Empty by default.
|
|
132
|
+
* @param {boolean} useDefaultBlocks - Optional boolean to use core blocks defaults. True by default.
|
|
133
|
+
* @returns {object} Object with blocks definitions
|
|
134
|
+
*/
|
|
135
|
+
export const customBlocks = (blocks = {}) => ({ ...coreBlocks, ...blocks });
|
package/src/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { default as Block } from './components/Block';
|
|
2
|
+
export { default as Tree } from './components/Tree';
|
|
3
|
+
export { Provider } from './components/Context';
|
|
4
|
+
export { customBlocks, customTags } from './elements';
|
|
5
|
+
export { default as attribsProps } from './utils/attribsProps';
|
|
6
|
+
export { default as innerNode } from './utils/innerNode';
|
|
7
|
+
export { default as parseBlocks } from './utils/parseBlocks';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import convert from 'react-attr-converter';
|
|
2
|
+
import parseStyle from 'style-to-js';
|
|
3
|
+
|
|
4
|
+
const attribsProps = (attribs) => {
|
|
5
|
+
if (attribs === undefined) {
|
|
6
|
+
return {};
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const props = Object.fromEntries(
|
|
10
|
+
Object.entries(attribs).map((attribute) => {
|
|
11
|
+
if (attribute[0] === 'style') {
|
|
12
|
+
return [convert(attribute[0]), parseStyle(attribute[1])];
|
|
13
|
+
}
|
|
14
|
+
return [convert(attribute[0]), attribute[1]];
|
|
15
|
+
})
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
return props;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default attribsProps;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { parseDocument } from "htmlparser2";
|
|
2
|
+
|
|
3
|
+
const innerNode = (innerBlocks, innerContent) => {
|
|
4
|
+
// If no inner blocks, return the block markup.
|
|
5
|
+
// If inner blocks, return the wrapping markup.
|
|
6
|
+
const innerHtml = !innerBlocks.length
|
|
7
|
+
? innerContent[0]
|
|
8
|
+
: `${innerContent[0]}[innerBlocks]${innerContent[innerContent.length - 1]}`;
|
|
9
|
+
const html = innerHtml ? innerHtml.trim() : "";
|
|
10
|
+
|
|
11
|
+
const tree = parseDocument(html, {
|
|
12
|
+
lowerCaseTags: true,
|
|
13
|
+
recognizeSelfClosing: true,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
return tree.children[0] ?? null;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default innerNode;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { parse } from "@wordpress/block-serialization-default-parser";
|
|
2
|
+
import Block from "../components/Block";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Parse Gutenberg blocks from HTML markup.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} html - markup rendered by Gutenberg editor.
|
|
8
|
+
* @returns {JSX.Element[]}
|
|
9
|
+
*/
|
|
10
|
+
const parseBlocks = (html) =>
|
|
11
|
+
parse(html.trim()).map((block, key) => <Block block={block} key={key} />);
|
|
12
|
+
|
|
13
|
+
export default parseBlocks;
|