Skip to content

Commit f29425d

Browse files
committed
fixup! feat(markdown): add removeEmptyParagraphs prop
1 parent aa43b06 commit f29425d

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

src/components/markdown/examples/markdown-remove-empty-paragraphs.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import { Component, h, Host } from '@stencil/core';
22

3+
const zeroWidthHexCodes = ['200B', '200C', '200D', 'FEFF'];
4+
const zeroWidthSequence = zeroWidthHexCodes
5+
.map((hexCode) => String.fromCodePoint(Number.parseInt(hexCode, 16)))
6+
.join('');
7+
const zeroWidthCharacter = zeroWidthSequence.charAt(0);
8+
39
const markdownWithEmptyParagraphs = `
410
<p>In some use cases, empty paragraphs may be desired to keep certain spacing
511
in the content, while in other cases they may be unwanted and just add
@@ -17,6 +23,8 @@ by pressing the <kbd>Enter</kbd> key multiple times, while typing an email.</p>
1723
<p><span style="font-size:10.5pt; color:#333333">&nbsp;</span></p>
1824
<p><span></span></p>
1925
<p> </p>
26+
<p>${zeroWidthSequence}</p>
27+
<p><span>${zeroWidthCharacter}</span></p>
2028
<p>Rendering all the empty paragraphs that you see in this example would just add lots
2129
of vertical scrolling to large content.</p>
2230
`;

src/components/markdown/remove-empty-paragraphs-plugin.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,31 @@ describe('remove empty paragraphs plugin', () => {
3636
expect(tree.children[0]).toBe(paragraph);
3737
});
3838

39+
it('removes paragraphs containing only line breaks', () => {
40+
const tree = createRoot([
41+
createParagraph([createElement('br')]),
42+
createParagraph([createElement('span', [createElement('br')])]),
43+
]);
44+
45+
runPlugin(tree, true);
46+
47+
expect(tree.children).toHaveLength(0);
48+
});
49+
50+
it('removes paragraphs containing only zero-width whitespace characters', () => {
51+
const zeroWidthText = '\u200B\u200C\u200D\uFEFF';
52+
const tree = createRoot([
53+
createParagraph([createText(zeroWidthText)]),
54+
createParagraph([
55+
createElement('span', [createText(zeroWidthText)]),
56+
]),
57+
]);
58+
59+
runPlugin(tree, true);
60+
61+
expect(tree.children).toHaveLength(0);
62+
});
63+
3964
it('keeps text content inside paragraphs', () => {
4065
const paragraph = createParagraph([
4166
createElement('span', [createText('Meaningful text')]),

src/components/markdown/remove-empty-paragraphs-plugin.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const createRemoveEmptyParagraphsPlugin = (enabled = false): Plugin => {
1616
};
1717

1818
const NBSP_REGEX = /\u00A0/g;
19+
const ZERO_WIDTH_HEX_CODES = ['200B', '200C', '200D', 'FEFF'];
1920
const MEANINGFUL_VOID_ELEMENTS = new Set([
2021
'audio',
2122
'canvas',
@@ -30,6 +31,17 @@ const MEANINGFUL_VOID_ELEMENTS = new Set([
3031

3132
const TREAT_AS_EMPTY_ELEMENTS = new Set(['br']);
3233

34+
const stripZeroWidthCharacters = (text: string): string => {
35+
let cleaned = text;
36+
37+
for (const hexCode of ZERO_WIDTH_HEX_CODES) {
38+
const character = String.fromCodePoint(Number.parseInt(hexCode, 16));
39+
cleaned = cleaned.split(character).join('');
40+
}
41+
42+
return cleaned;
43+
};
44+
3345
const pruneEmptyParagraphs = (node: any, parent: any) => {
3446
if (!node || typeof node !== 'object') {
3547
return;
@@ -115,5 +127,9 @@ const isWhitespace = (value: string): boolean => {
115127
return true;
116128
}
117129

118-
return value.replaceAll(NBSP_REGEX, ' ').trim() === '';
130+
const normalized = stripZeroWidthCharacters(
131+
value.replaceAll(NBSP_REGEX, ' ')
132+
);
133+
134+
return normalized.trim() === '';
119135
};

0 commit comments

Comments
 (0)