Skip to content

Commit

Permalink
fix: deserialization - wrap each resulting non-empty child text node …
Browse files Browse the repository at this point in the history
…with a paragraph (#2236)
  • Loading branch information
kark authored Jul 21, 2022
1 parent 63131b5 commit a7ae18d
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/slow-bags-cheer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@commercetools-uikit/rich-text-utils': patch
---

Fix `deserializeElement` function by wrapping each resulting non-empty child text node with a paragraph
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ const initialValue = {
es: lorem,
};

const complexMarkup =
'<ol><li><span style="font-weight: bold; font-family: &quot;Comic Sans MS&quot;;">Computermouse for <span style="text-decoration-line: underline;">controlling</span></span></li></ol><span><table class="table table-bordered"><tbody><tr><td>hello</td></tr><tr><td><p>world<img src="https://www.rollingstone.com/wp-content/uploads/2019/01/shutterstock_10010937aj.jpg" style="width: 100%; float: right;" class="pull-right img-circle"></p></td></tr></tbody></table></span><ol><li><span style="font-weight: bold; font-family: &quot;Comic Sans MS&quot;;">';

const initialValueWithComplexMarkup = {
en: complexMarkup,
de: complexMarkup,
es: complexMarkup,
};

const emptyValue = '';

export const routePath = '/localized-rich-text-input';
Expand Down Expand Up @@ -267,6 +276,15 @@ const DefaultRoute = () => (
onClickExpand={() => {}}
/>
</Spec>
<Spec label="with complex markup" omitPropsList>
<LocalizedRichTextInput
onChange={() => {}}
value={initialValueWithComplexMarkup}
selectedLanguage="en"
horizontalConstraint={7}
defaultExpandMultilineText={true}
/>
</Spec>
</Suite>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ describe('html', () => {
'<ol><li><span style="font-weight: bold; font-family: &quot;Comic Sans MS&quot;;">Computermouse for <span style="text-decoration-line: underline;">controlling</span></span></li></ol><table class="table table-bordered"><tbody><tr><td>hello</td></tr><tr><td><p>world<img src="https://www.rollingstone.com/wp-content/uploads/2019/01/shutterstock_10010937aj.jpg" style="width: 100%; float: right;" class="pull-right img-circle"></p></td></tr></tbody></table><ol><li><span style="font-weight: bold; font-family: &quot;Comic Sans MS&quot;;"><span style="text-decoration-line: underline;"><br></span></span></li></ol>';

expect(html.serialize(html.deserialize(htmlValue))).toEqual(
'<ol><li><strong>Computermouse for </strong><u><strong>controlling</strong></u></li></ol>hello<p>world</p><ol><li><u><strong></strong></u></li></ol>'
'<ol><li><strong>Computermouse for </strong><u><strong>controlling</strong></u></li></ol><p>hello</p><p>world</p><ol><li><u><strong></strong></u></li></ol>'
);
});
});
Expand Down
11 changes: 9 additions & 2 deletions packages/components/inputs/rich-text-utils/src/html/html.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,16 @@ const mapper: TMapper = {
},
};

const wrapWithParagraph = (
textContent: TElement | TText | (TElement | TText)[]
) => jsx('element', { type: 'paragraph' }, textContent);

const wrapWithParagraphIfRootElement = (
el: HTMLElement | ChildNode,
textContent: TElement | TText | (TElement | TText)[]
) =>
el.parentNode?.nodeName === 'BODY' // root element, because body is eventually turned to React fragment
? jsx('element', { type: 'paragraph' }, textContent)
? wrapWithParagraph(textContent)
: textContent;

export type Deserialized = Descendant | null;
Expand Down Expand Up @@ -275,7 +279,10 @@ const deserializeElement = (
return children.map((child) => jsx('text', attrs, child));
}

return children;
// each non-empty text node must be wrapped with a paragraph
return children.map((child) =>
Text.isText(child) && child.text ? wrapWithParagraph(child) : child
);
};
const deserialize = (html: Html) => {
const document = new DOMParser().parseFromString(
Expand Down

1 comment on commit a7ae18d

@vercel
Copy link

@vercel vercel bot commented on a7ae18d Jul 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.