diff --git a/dist/components/Block.js b/dist/components/Block.js
index 2ec30c8..9460da7 100644
--- a/dist/components/Block.js
+++ b/dist/components/Block.js
@@ -1,16 +1,22 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = Block;
+var _Tree = _interopRequireDefault(require("./Tree.js"));
+var _innerNode = _interopRequireDefault(require("../utils/innerNode.js"));
+var _Context = require("./Context.js");
+var _jsxRuntime = require("react/jsx-runtime");
+function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
// eslint-disable-next-line no-unused-vars
-import Tree from "./Tree.js";
-import innerNode from "../utils/innerNode.js";
-import { useBlockComponent } from "./Context.js";
/**
* Block element.
*
* @param {object} componentProps - properties that includes the block object.
* @returns {JSX.Element | null | undefined}
- */
-import { jsx as _jsx } from "react/jsx-runtime";
-export default function Block(_ref) {
+ */function Block(_ref) {
let {
block
} = _ref;
@@ -19,9 +25,9 @@ export default function Block(_ref) {
innerContent,
innerBlocks
} = block;
- const CustomBlock = useBlockComponent(blockName);
+ const CustomBlock = (0, _Context.useBlockComponent)(blockName);
if (CustomBlock) {
- return /*#__PURE__*/_jsx(CustomBlock, {
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(CustomBlock, {
block: block
});
}
@@ -34,9 +40,9 @@ export default function Block(_ref) {
if (innerContent.length === 1 && (innerContent[0] === "\n" || innerContent[0].substring(0, 2) === "")) {
return null;
}
- const node = innerNode(innerBlocks, innerContent);
+ const node = (0, _innerNode.default)(innerBlocks, innerContent);
if (node) {
- return /*#__PURE__*/_jsx(Tree, {
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tree.default, {
node: node,
block: block
});
diff --git a/dist/components/Context.js b/dist/components/Context.js
index d783d2b..8fd10fc 100644
--- a/dist/components/Context.js
+++ b/dist/components/Context.js
@@ -1,21 +1,31 @@
-import { createContext, useContext } from 'react';
-import { coreTags, coreBlocks } from '../elements/index.js';
-const TxContext = /*#__PURE__*/createContext();
-export const {
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.Provider = void 0;
+exports.useBlockComponent = useBlockComponent;
+exports.useComponentContext = useComponentContext;
+exports.useTagComponent = useTagComponent;
+var _react = require("react");
+var _index = require("../elements/index.js");
+const TxContext = /*#__PURE__*/(0, _react.createContext)();
+const {
Provider
} = TxContext;
-export function useComponentContext() {
- return useContext(TxContext);
+exports.Provider = Provider;
+function useComponentContext() {
+ return (0, _react.useContext)(TxContext);
}
-export function useBlockComponent(name) {
+function useBlockComponent(name) {
const {
- CustomBlocks = coreBlocks
- } = useContext(TxContext);
+ CustomBlocks = _index.coreBlocks
+ } = (0, _react.useContext)(TxContext);
return name && CustomBlocks[name];
}
-export function useTagComponent(tag) {
+function useTagComponent(tag) {
const {
- CustomTags = coreTags
- } = useContext(TxContext);
+ CustomTags = _index.coreTags
+ } = (0, _react.useContext)(TxContext);
return tag && CustomTags[tag];
}
\ No newline at end of file
diff --git a/dist/components/Tree.js b/dist/components/Tree.js
index 2d0ebcb..9d6f96e 100644
--- a/dist/components/Tree.js
+++ b/dist/components/Tree.js
@@ -1,29 +1,37 @@
-import { useTagComponent } from "./Context.js";
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = Tree;
+var _Context = require("./Context.js");
+var _Block = _interopRequireDefault(require("./Block.js"));
+var _attribsProps = _interopRequireDefault(require("../utils/attribsProps.js"));
+var _jsxRuntime = require("react/jsx-runtime");
+function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
// eslint-disable-next-line no-unused-vars
-import Block from "./Block.js";
-import attribsProps from "../utils/attribsProps.js";
-import { jsx as _jsx } from "react/jsx-runtime";
-export default function Tree(_ref) {
+
+function Tree(_ref) {
let {
node,
block
} = _ref;
- const CustomTag = useTagComponent(node.name);
- attribsProps(node.attribs);
+ const CustomTag = (0, _Context.useTagComponent)(node.name);
+ (0, _attribsProps.default)(node.attribs);
if (node.type === "text") {
if (node.data.trim() === "[innerBlocks]") {
- return block.innerBlocks?.map((inner, index) => /*#__PURE__*/_jsx(Block, {
+ return block.innerBlocks?.map((inner, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_Block.default, {
block: inner
}, index));
}
return node.data;
}
if (CustomTag) {
- const children = node.children?.map((child, index) => /*#__PURE__*/_jsx(Tree, {
+ const children = node.children?.map((child, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(Tree, {
node: child,
block: block
}, index));
- return /*#__PURE__*/_jsx(CustomTag, {
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(CustomTag, {
attribs: node.attribs,
node: children,
block: block
@@ -33,10 +41,10 @@ export default function Tree(_ref) {
// Component is used as a dynamic tag name in JSX
// eslint-disable-next-line no-unused-vars
const Component = node.name;
- const attrs = attribsProps(node.attribs);
- return /*#__PURE__*/_jsx(Component, {
+ const attrs = (0, _attribsProps.default)(node.attribs);
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(Component, {
...attrs,
- children: node.children?.map((child, index) => /*#__PURE__*/_jsx(Tree, {
+ children: node.children?.map((child, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(Tree, {
node: child,
block: block
}, index))
diff --git a/dist/elements/index.js b/dist/elements/index.js
index 623042a..070b263 100644
--- a/dist/elements/index.js
+++ b/dist/elements/index.js
@@ -1,14 +1,23 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.customTags = exports.customBlocks = exports.coreTags = exports.coreBlocks = void 0;
+var _img = _interopRequireDefault(require("./tags/img.js"));
+var _selfClosing = _interopRequireDefault(require("./tags/selfClosing.js"));
+var _jsxRuntime = require("react/jsx-runtime");
+function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
// eslint-disable-next-line no-unused-vars
-import Image from './tags/img.js';
+
// eslint-disable-next-line no-unused-vars
-import SelfClosing from './tags/selfClosing.js';
-import { jsx as _jsx } from "react/jsx-runtime";
-export const coreTags = {
+
+const coreTags = exports.coreTags = {
img: _ref => {
let {
attribs
} = _ref;
- return /*#__PURE__*/_jsx(Image, {
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_img.default, {
attribs: attribs
});
},
@@ -16,7 +25,7 @@ export const coreTags = {
let {
attribs
} = _ref2;
- return /*#__PURE__*/_jsx(SelfClosing, {
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_selfClosing.default, {
attribs: attribs,
tag: "br"
});
@@ -25,7 +34,7 @@ export const coreTags = {
let {
attribs
} = _ref3;
- return /*#__PURE__*/_jsx(SelfClosing, {
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_selfClosing.default, {
attribs: attribs,
tag: "hr"
});
@@ -48,7 +57,7 @@ export const coreTags = {
// track: ({attribs}) => ,
// wbr: ({attribs}) => ,
};
-export const coreBlocks = {
+const coreBlocks = exports.coreBlocks = {
// 'core/archives': ({ block }) => doSomething(),
// 'core/audio': ({ block }) => doSomething(),
// 'core/avatar': ({ block }) => doSomething(),
@@ -150,7 +159,7 @@ export const coreBlocks = {
* @param {object} tags - Optional object with custom blocks definitions. Empty by default.
* @returns {object} Object with blocks definitions
*/
-export const customTags = function () {
+const customTags = function () {
let tags = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
return {
...coreTags,
@@ -165,10 +174,12 @@ export const customTags = function () {
* @param {boolean} useDefaultBlocks - Optional boolean to use core blocks defaults. True by default.
* @returns {object} Object with blocks definitions
*/
-export const customBlocks = function () {
+exports.customTags = customTags;
+const customBlocks = function () {
let blocks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
return {
...coreBlocks,
...blocks
};
-};
\ No newline at end of file
+};
+exports.customBlocks = customBlocks;
\ No newline at end of file
diff --git a/dist/elements/tags/img.js b/dist/elements/tags/img.js
index 6dca87e..ecc79de 100644
--- a/dist/elements/tags/img.js
+++ b/dist/elements/tags/img.js
@@ -1,5 +1,11 @@
-import { jsx as _jsx } from "react/jsx-runtime";
-export default function Image(_ref) {
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = Image;
+var _jsxRuntime = require("react/jsx-runtime");
+function Image(_ref) {
let {
attribs
} = _ref;
@@ -10,7 +16,7 @@ export default function Image(_ref) {
height,
width
} = attribs;
- return /*#__PURE__*/_jsx("img", {
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("img", {
alt: alt,
className: className,
src: src,
diff --git a/dist/elements/tags/selfClosing.js b/dist/elements/tags/selfClosing.js
index a69312a..3ed28f1 100644
--- a/dist/elements/tags/selfClosing.js
+++ b/dist/elements/tags/selfClosing.js
@@ -1,14 +1,21 @@
-import attribsProps from '../../utils/attribsProps.js';
-import { jsx as _jsx } from "react/jsx-runtime";
-export default function SelfClosing(_ref) {
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = SelfClosing;
+var _attribsProps = _interopRequireDefault(require("../../utils/attribsProps.js"));
+var _jsxRuntime = require("react/jsx-runtime");
+function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
+function SelfClosing(_ref) {
let {
attribs,
tag
} = _ref;
// eslint-disable-next-line no-unused-vars
const Component = tag;
- const attributes = attribsProps(attribs);
- return /*#__PURE__*/_jsx(Component, {
+ const attributes = (0, _attribsProps.default)(attribs);
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(Component, {
...attributes
});
}
\ No newline at end of file
diff --git a/dist/index.js b/dist/index.js
index b4bd59d..28f1c1c 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -1,7 +1,61 @@
-export { default as Block } from './components/Block.js';
-export { default as Tree } from './components/Tree.js';
-export { Provider } from './components/Context.js';
-export { customBlocks, customTags } from './elements/index.js';
-export { default as attribsProps } from './utils/attribsProps.js';
-export { default as innerNode } from './utils/innerNode.js';
-export { default as parseBlocks } from './utils/parseBlocks.js';
\ No newline at end of file
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+Object.defineProperty(exports, "Block", {
+ enumerable: true,
+ get: function () {
+ return _Block.default;
+ }
+});
+Object.defineProperty(exports, "Provider", {
+ enumerable: true,
+ get: function () {
+ return _Context.Provider;
+ }
+});
+Object.defineProperty(exports, "Tree", {
+ enumerable: true,
+ get: function () {
+ return _Tree.default;
+ }
+});
+Object.defineProperty(exports, "attribsProps", {
+ enumerable: true,
+ get: function () {
+ return _attribsProps.default;
+ }
+});
+Object.defineProperty(exports, "customBlocks", {
+ enumerable: true,
+ get: function () {
+ return _index.customBlocks;
+ }
+});
+Object.defineProperty(exports, "customTags", {
+ enumerable: true,
+ get: function () {
+ return _index.customTags;
+ }
+});
+Object.defineProperty(exports, "innerNode", {
+ enumerable: true,
+ get: function () {
+ return _innerNode.default;
+ }
+});
+Object.defineProperty(exports, "parseBlocks", {
+ enumerable: true,
+ get: function () {
+ return _parseBlocks.default;
+ }
+});
+var _Block = _interopRequireDefault(require("./components/Block"));
+var _Tree = _interopRequireDefault(require("./components/Tree"));
+var _Context = require("./components/Context");
+var _index = require("./elements/index");
+var _attribsProps = _interopRequireDefault(require("./utils/attribsProps"));
+var _innerNode = _interopRequireDefault(require("./utils/innerNode"));
+var _parseBlocks = _interopRequireDefault(require("./utils/parseBlocks"));
+function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
\ No newline at end of file
diff --git a/dist/utils/attribsProps.js b/dist/utils/attribsProps.js
index 7967c90..38cbf12 100644
--- a/dist/utils/attribsProps.js
+++ b/dist/utils/attribsProps.js
@@ -1,15 +1,22 @@
-import convert from 'react-attr-converter';
-import parseStyle from 'style-to-js';
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+var _reactAttrConverter = _interopRequireDefault(require("react-attr-converter"));
+var _styleToJs = _interopRequireDefault(require("style-to-js"));
+function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const attribsProps = attribs => {
if (attribs === undefined) {
return {};
}
const props = Object.fromEntries(Object.entries(attribs).map(attribute => {
if (attribute[0] === 'style') {
- return [convert(attribute[0]), parseStyle(attribute[1])];
+ return [(0, _reactAttrConverter.default)(attribute[0]), (0, _styleToJs.default)(attribute[1])];
}
- return [convert(attribute[0]), attribute[1]];
+ return [(0, _reactAttrConverter.default)(attribute[0]), attribute[1]];
}));
return props;
};
-export default attribsProps;
\ No newline at end of file
+var _default = exports.default = attribsProps;
\ No newline at end of file
diff --git a/dist/utils/innerNode.js b/dist/utils/innerNode.js
index 0cf2465..5f8d120 100644
--- a/dist/utils/innerNode.js
+++ b/dist/utils/innerNode.js
@@ -1,13 +1,19 @@
-import { parseDocument } from "htmlparser2";
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+var _htmlparser = require("htmlparser2");
const innerNode = (innerBlocks, innerContent) => {
// If no inner blocks, return the block markup.
// If inner blocks, return the wrapping markup.
- const innerHtml = !innerBlocks.length ? innerContent[0] : `${innerContent[0]}[innerBlocks]${innerContent[innerContent.length - 1]}`;
+ const innerHtml = !innerBlocks.length ? innerContent[0] : `${innerContent[0] ?? ""}[innerBlocks]${innerContent[innerContent.length - 1] ?? ""}`;
const html = innerHtml ? innerHtml.trim() : "";
- const tree = parseDocument(html, {
+ const tree = (0, _htmlparser.parseDocument)(html, {
lowerCaseTags: true,
recognizeSelfClosing: true
});
return tree.children[0] ?? null;
};
-export default innerNode;
\ No newline at end of file
+var _default = exports.default = innerNode;
\ No newline at end of file
diff --git a/dist/utils/parseBlocks.js b/dist/utils/parseBlocks.js
index 3247c33..37e7704 100644
--- a/dist/utils/parseBlocks.js
+++ b/dist/utils/parseBlocks.js
@@ -1,15 +1,21 @@
-import { parse } from "@wordpress/block-serialization-default-parser";
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+var _blockSerializationDefaultParser = require("@wordpress/block-serialization-default-parser");
+var _Block = _interopRequireDefault(require("../components/Block.js"));
+var _jsxRuntime = require("react/jsx-runtime");
+function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
// eslint-disable-next-line no-unused-vars
-import Block from "../components/Block.js";
/**
* Parse Gutenberg blocks from HTML markup.
*
* @param {string} html - markup rendered by Gutenberg editor.
* @returns {JSX.Element[]}
- */
-import { jsx as _jsx } from "react/jsx-runtime";
-const parseBlocks = html => parse(html.trim()).map((block, key) => /*#__PURE__*/_jsx(Block, {
+ */const parseBlocks = html => (0, _blockSerializationDefaultParser.parse)(html.trim()).map((block, key) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_Block.default, {
block: block
}, key));
-export default parseBlocks;
\ No newline at end of file
+var _default = exports.default = parseBlocks;
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index d1faf2e..cfbcf04 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@frontkom/block-react-parser",
- "version": "1.3.0",
+ "version": "1.4.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@frontkom/block-react-parser",
- "version": "1.3.0",
+ "version": "1.4.3",
"license": "ISC",
"dependencies": {
"@wordpress/block-serialization-default-parser": "^5.38.0",
diff --git a/package.json b/package.json
index 5be2aee..fe66186 100644
--- a/package.json
+++ b/package.json
@@ -1,8 +1,7 @@
{
"name": "@frontkom/block-react-parser",
- "version": "1.4.0",
+ "version": "1.4.3",
"description": "Gutenberg-generated HTML to React parser.",
- "type": "module",
"main": "dist/index.js",
"module": "dist/index.js",
"scripts": {
@@ -47,10 +46,7 @@
"babel": {
"presets": [
[
- "@babel/preset-env",
- {
- "modules": false
- }
+ "@babel/preset-env"
],
[
"@babel/preset-react",
diff --git a/src/index.js b/src/index.js
index 8579e8c..d651c03 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,7 +1,7 @@
-export { default as Block } from './components/Block.js';
-export { default as Tree } from './components/Tree.js';
-export { Provider } from './components/Context.js';
-export { customBlocks, customTags } from './elements/index.js';
-export { default as attribsProps } from './utils/attribsProps.js';
-export { default as innerNode } from './utils/innerNode.js';
-export { default as parseBlocks } from './utils/parseBlocks.js';
+export { default as Block } from './components/Block';
+export { default as Tree } from './components/Tree';
+export { Provider } from './components/Context';
+export { customBlocks, customTags } from './elements/index';
+export { default as attribsProps } from './utils/attribsProps';
+export { default as innerNode } from './utils/innerNode';
+export { default as parseBlocks } from './utils/parseBlocks';
diff --git a/src/utils/innerNode.jsx b/src/utils/innerNode.jsx
index b380b2f..8bf8701 100644
--- a/src/utils/innerNode.jsx
+++ b/src/utils/innerNode.jsx
@@ -5,7 +5,9 @@ const innerNode = (innerBlocks, innerContent) => {
// If inner blocks, return the wrapping markup.
const innerHtml = !innerBlocks.length
? innerContent[0]
- : `${innerContent[0]}[innerBlocks]${innerContent[innerContent.length - 1]}`;
+ : `${innerContent[0] ?? ""}[innerBlocks]${
+ innerContent[innerContent.length - 1] ?? ""
+ }`;
const html = innerHtml ? innerHtml.trim() : "";
const tree = parseDocument(html, {
diff --git a/test/block.test.mjs b/test/block.test.mjs
index 241473e..798a8cc 100644
--- a/test/block.test.mjs
+++ b/test/block.test.mjs
@@ -570,6 +570,34 @@ test('Block component renders media-text block', () => {
assert.ok(rendered.includes('Text beside media.'), 'Should render text content');
});
+// ============ Null Wrapper Markup Tests ============
+test('Block component renders inner blocks when wrapper markup is null', () => {
+ // A block that only contains inner blocks with no surrounding HTML markup
+ // serializes to innerContent === [null, null]. The wrapping markup must not
+ // leak the string "null" into the output.
+ const block = {
+ blockName: 'core/group',
+ attrs: {},
+ innerBlocks: [
+ {
+ blockName: 'core/paragraph',
+ attrs: {},
+ innerBlocks: [],
+ innerHTML: '
Inner content
',
+ innerContent: ['Inner content
'],
+ },
+ ],
+ innerHTML: '',
+ innerContent: [null, null],
+ };
+
+ const rendered = renderBlock(block);
+
+ assert.ok(rendered.includes('Inner content'), 'Should render inner block content');
+ assert.ok(!rendered.includes('null'), 'Should not leak literal "null" text');
+ assert.ok(!rendered.includes('[innerBlocks]'), 'Should not leak the [innerBlocks] marker');
+});
+
// ============ Custom Block Handler Tests ============
test('Block component uses custom handler for paragraph', () => {
const html = `