Skip to content

feat: preserve empty blocks while converting to html #87

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .talismanrc
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ fileignoreconfig:
checksum: 3d014702628ad538065c970d988a695af003c61663596a8f6b9267b4e57ef6ea
- filename: test/expectedJson.json
checksum: 9979f84be3e5aa27f24381a0c49e0e6696388d19615c4f3b09082780968236ee
- filename: README.md
checksum: cccb3cd93c499acc87593eca5cc032e256c11cf530d4de67ece09e57fc430215
34 changes: 30 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,27 @@ On the other hand, the `customTextWrapper` parser function provides the followin
- `child`: The HTML string that specifies the child element
- `value`: The value passed against the child element

___

You can pass an object to `allowedEmptyAttributes` to retain empty attribute values for specific element types during HTML conversion.
`allowedEmptyAttributes`

**Note:**
By default, if nothing is passed to `allowedEmptyAttributes`, we retain the `alt` attribute for `<img>` and `reference` (asset) element types, even when its value is empty, during HTML conversion.
- Type: `object`
- Default: `{ img: ['alt'], reference: ['alt'] }`

Specifies which empty attributes should be retained for specific HTML elements during the jsonToHtml conversion.
By default, the converter preserves the alt attribute for <img> and reference (asset) elements, even when their values are empty.
This is particularly useful for ensuring semantic correctness and accessibility.

Use this option when you want to retain specific attributes with empty values during the conversion process.

___

`addNbspForEmptyBlocks`

- Type: `boolean`
- Default:`false`

When set to true, this option adds a non-breaking space (nbsp;) to empty blocks during the jsonToHtml conversion. This helps maintain the visual structure of the HTML output—especially useful for preserving spacing in editable content or content editors.

You can use the following customized JSON RTE Serializer code to convert your JSON RTE field data into HTML format.

Expand Down Expand Up @@ -196,6 +211,16 @@ const jsonValue = {
},
],
},
{
"type": "p",
"uid": "28c837c127504d3c85b9cb6d7099cb0b",
"attrs": {},
"children": [
{
"text": ""
}
]
},
{
type: "p",
attrs: {},
Expand Down Expand Up @@ -225,7 +250,8 @@ const htmlValue = jsonToHtml(
allowedEmptyAttributes : {
"p": ["dir"],
"img" : ["width"]
}
},
addNbspForEmptyBlocks : true
}
);

Expand Down
12 changes: 11 additions & 1 deletion src/toRedactor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,13 @@ const ALLOWED_EMPTY_ATTRIBUTES: IJsonToHtmlAllowedEmptyAttributes = {
reference: ['alt']
}

let ADD_NBSP_FOR_EMPTY_BLOCKS : boolean = false

export const toRedactor = (jsonValue: any,options?:IJsonToHtmlOptions) : string => {
//TODO: optimize assign once per function call
if(options?.addNbspForEmptyBlocks){
ADD_NBSP_FOR_EMPTY_BLOCKS = options?.addNbspForEmptyBlocks
}
if(options?.customTextWrapper && !isEmpty(options.customTextWrapper)){
Object.assign(TEXT_WRAPPERS,options.customTextWrapper)
}
Expand Down Expand Up @@ -590,7 +595,12 @@ export const toRedactor = (jsonValue: any,options?:IJsonToHtmlOptions) : string

attrs = (attrs.trim() ? ' ' : '') + attrs.trim()

return ELEMENT_TYPES[orgType || jsonValue['type']](attrs, children,jsonValue, figureStyles)
return ELEMENT_TYPES[orgType || jsonValue['type']](
attrs,
ADD_NBSP_FOR_EMPTY_BLOCKS && !children ? '&nbsp;' : children,
jsonValue,
figureStyles
)
}

return children
Expand Down
4 changes: 3 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ export interface IAnyObject {[key:string]:any}
export interface IHtmlToJsonOptions {
allowNonStandardTags?: boolean,
customElementTags?: IHtmlToJsonElementTags,
customTextTags?: IHtmlToJsonTextTags
customTextTags?: IHtmlToJsonTextTags,
addNbspForEmptyBlocks?: boolean
}
export interface IHtmlToJsonElementTagsAttributes {
type:string,
Expand All @@ -22,4 +23,5 @@ export interface IJsonToHtmlOptions {
customTextWrapper?: IJsonToHtmlTextTags,
allowNonStandardTypes?: boolean,
allowedEmptyAttributes?: IJsonToHtmlAllowedEmptyAttributes,
addNbspForEmptyBlocks?: boolean
}
6 changes: 6 additions & 0 deletions test/toRedactor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,3 +331,9 @@ describe("Testing json to html conversion", () => {

})

test("should add nbsp for empty blocks", () => {
const json = {"type":"doc","uid":"uid","attrs":{},"children":[{"type":"p","attrs":{},"uid":"uid","children":[{"text":"Hi"}]},{"type":"p","attrs":{},"uid":"uid","children":[{"text":""}]},{"type":"p","attrs":{},"uid":"uid","children":[{"text":""}]},{"type":"p","attrs":{},"uid":"uid","children":[{"text":"Hello"}]}]};
const html = toRedactor(json, {addNbspForEmptyBlocks: true});
expect(html).toBe(`<p>Hi</p><p>&nbsp;</p><p>&nbsp;</p><p>Hello</p>`);
});

Loading