Skip to content

Commit

Permalink
fix: Table cell parsing (Fixes #31)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericof committed Jul 3, 2023
1 parent 3d81492 commit 0500c3d
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 20 deletions.
4 changes: 1 addition & 3 deletions src/converters/fromHtml.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { draftTableBlock, draftTextBlock } from './draftjs.js';
import { slateTableBlock, slateTextBlock } from './slate.js';
import {
groupInlineNodes,
isInline,
isWhitespace,
isGlobalInline,
} from '../helpers/dom.js';
Expand Down Expand Up @@ -89,9 +90,6 @@ const skipCommentsAndWhitespace = (elements) => {
);
};

const isInline = (n) =>
n.nodeType === TEXT_NODE || isGlobalInline(n.tagName.toLowerCase());

const extractElementsWithConverters = (el, defaultTextBlock, href) => {
const result = [];
if (el.tagName === 'A') {
Expand Down
7 changes: 6 additions & 1 deletion src/converters/slate.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,12 @@ const slateTableBlock = (elem) => {
for (const cell of tchild.children) {
const cellType = cell.tagName === 'TD' ? 'data' : 'header';
const cellValue = deserializeChildren(cell);
cells.push(createCell(cellType, cellValue));
const elements = cellValue.map((element) =>
isInline(element)
? jsx('element', { type: 'span' }, [element])
: element,
);
cells.push(createCell(cellType, elements));
}
rows.push({ key: getId(), cells });
}
Expand Down
85 changes: 70 additions & 15 deletions src/converters/slate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,9 @@ describe('slateTableBlock processing a simple table', () => {
expect(rows[0].cells[0].key).toBeDefined();
expect(rows[0].cells[0].type).toBe('data');
expect(rows[0].cells[0].value).toHaveLength(1);
const value = rows[0].cells[0].value[0];
const parentValue = rows[0].cells[0].value[0];
expect(parentValue['type']).toBe('span');
const value = parentValue['children'][0];
expect(value['text']).toBe('A value');
});
});
Expand All @@ -657,7 +659,10 @@ describe('slateTableBlock processing a table with whitespace', () => {
const cells = rows[0].cells;
expect(cells).toHaveLength(1);
const cell = cells[0];
expect(cell.value).toEqual([{ text: 'A value\n\xa0' }]);
const parentValue = cell.value[0];
expect(parentValue['type']).toBe('span');
const value = parentValue['children'][0];
expect(value).toEqual({ text: 'A value' });
});
});

Expand All @@ -678,7 +683,9 @@ describe('slateTableBlock processing a table with a link', () => {
expect(rows[0].cells).toHaveLength(1);
expect(rows[0].cells[0].type).toBe('data');
expect(rows[0].cells[0].value).toHaveLength(1);
const value = rows[0].cells[0].value[0];
const parentValue = rows[0].cells[0].value[0];
expect(parentValue['type']).toBe('span');
const value = parentValue['children'][0];
expect(value['type']).toBe('link');
expect(value['data']['url']).toBe('https://plone.org');
expect(value['children'][0]['text']).toBe('Plone');
Expand Down Expand Up @@ -707,14 +714,18 @@ describe('slateTableBlock processing a table with a link', () => {
test('first value is a text', () => {
const result = slateTableBlock(elem);
const rows = result.table.rows;
let value = rows[0].cells[0].value[0];
const parentValue = rows[0].cells[0].value[0];
expect(parentValue['type']).toBe('span');
const value = parentValue['children'][0];
expect(value['text']).toBe('Plone ');
});

test('second value is the link', () => {
test('second value is the span with the link', () => {
const result = slateTableBlock(elem);
const rows = result.table.rows;
let value = rows[0].cells[0].value[1];
const parentValue = rows[0].cells[0].value[1];
expect(parentValue['type']).toBe('span');
const value = parentValue['children'][0];
expect(value['type']).toBe('link');
expect(value['data']['url']).toBe('https://plone.org');
expect(value['children'][0]['text']).toBe('site');
Expand All @@ -729,13 +740,20 @@ describe('slateTableBlock processing a table with text + sup', () => {
test('will keep sup inline', () => {
const result = slateTableBlock(elem);
const cell = result.table.rows[0].cells[0];
expect(cell.value).toEqual([
{ text: '10' },
{
type: 'sup',
children: [{ text: '2' }],
},
]);
expect(cell.value).toHaveLength(2);
expect(cell.value[0]).toEqual({
type: 'span',
children: [{ text: '10' }],
});
expect(cell.value[1]).toEqual({
type: 'span',
children: [
{
type: 'sup',
children: [{ text: '2' }],
},
],
});
});
});

Expand All @@ -744,11 +762,48 @@ describe('slateTableBlock processing a table with a div', () => {
'<table><tr><td><div><strong>text</strong></div></td></tr></table>',
);

test('will remove the div', () => {
test('will replace the div with a paragraph', () => {
const result = slateTableBlock(elem);
const cell = result.table.rows[0].cells[0];
expect(cell.value).toEqual([
{ type: 'strong', children: [{ text: 'text' }] },
{
type: 'span',
children: [{ type: 'strong', children: [{ text: 'text' }] }],
},
]);
});
});

describe('slateTableBlock parsing table with bold text', () => {
const elem = elementFromString(
'<table class="plain">\n<tbody>\n<tr><td><b>Text1</b></td></tr>\n</tbody>\n</table>',
);
test('returns valid result with the correct children', () => {
const block = slateTableBlock(elem);
expect(block['@type']).toEqual('slateTable');
const rows = block['table']['rows'];
expect(rows).toHaveLength(1);
const cells = rows[0]['cells'];
expect(cells).toHaveLength(1);
const value = cells[0]['value'][0];
expect(value['type']).toEqual('span');
expect(value['children'][0]['type']).toEqual('strong');
});
});

describe('slateTableBlock parsing table with line break', () => {
const elem = elementFromString(
'<table class="plain">\n<tbody>\n<tr><td><br/>Text</td></tr>\n</tbody>\n</table>',
);
test('returns valid result with the correct children', () => {
const block = slateTableBlock(elem);
expect(block['@type']).toEqual('slateTable');
const rows = block['table']['rows'];
expect(rows).toHaveLength(1);
const cells = rows[0]['cells'];
expect(cells).toHaveLength(1);
const value = cells[0]['value'][0];
expect(value['type']).toEqual('span');
expect(value['children'][0]['text']).toEqual('\n');
});
});
13 changes: 12 additions & 1 deletion src/helpers/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ const { JSDOM } = jsdom;
const DOMParser = new JSDOM().window.DOMParser;
const parser = new DOMParser();

const TEXT_NODE = 3;

const elementFromString = (value) => {
const elem = parser.parseFromString(value, 'text/html').body.firstChild;
return elem;
Expand Down Expand Up @@ -51,4 +53,13 @@ const inlineElements = [

const isGlobalInline = (tagName) => inlineElements.includes(tagName);

export { elementFromString, isWhitespace, isGlobalInline, groupInlineNodes };
const isInline = (n) =>
n.nodeType === TEXT_NODE || isGlobalInline(n.tagName.toLowerCase());

export {
elementFromString,
isInline,
isWhitespace,
isGlobalInline,
groupInlineNodes,
};

0 comments on commit 0500c3d

Please sign in to comment.