Skip to content
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

Feat/eb 579 merge cells #30

Merged
merged 5 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
11 changes: 5 additions & 6 deletions src/fromRedactor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -213,22 +213,21 @@ export const fromRedactor = (el: any, options?:IHtmlToJsonOptions) : IAnyObject
const thead = el.querySelector('thead')

if (!tbody && !thead) {
el.append(document.createElement('tbody'))
el.innerHTML += "<tbody></tbody>"
}
}
else if (['TBODY', 'THEAD'].includes(el.nodeName)) {
const row = el.querySelector('tr')
if (!row) {
const tr = document.createElement('tr')
el.append(tr)
el.innerHTML += "<tr></tr>"
}
}
else if (el.nodeName === 'TR') {
const cell = el.querySelector('th, td')
if (!cell) {
const cellType = el.parentElement.nodeName === 'THEAD' ? 'th' : 'td'
const cell = document.createElement(cellType)
el.append(cell)
el.innerHTML += `<${cellType}></${cellType}>`

}
}
const { nodeName } = el
Expand Down Expand Up @@ -726,7 +725,7 @@ export const fromRedactor = (el: any, options?:IHtmlToJsonOptions) : IAnyObject
return Array(colSpan).fill(0).map((_, i) => cellIndex + i)
})

if (disabledCols.length)
if (disabledCols?.length)
elementAttrs.attrs['disabledCols'] = disabledCols


Expand Down
105 changes: 104 additions & 1 deletion test/expectedJson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1755,5 +1755,108 @@ export default {
json: {"type":"doc","uid":"uid","attrs":{},"children":[{"type":"hangout-module","attrs":{},"children":[{"type":"hangout-chat","attrs":{"from":"Paul, Addy","nested-json":{"to":"Hello World","more-nesting":{"from":"Beautiful World"}}},"children":[{"type":"hangout-discussion","attrs":{},"children":[{"type":"hangout-message","attrs":{"from":"Paul","profile":"profile.png","datetime":"2013-07-17T12:02"},"children":[{"type":"p","uid":"uid","attrs":{},"children":[{"text":"Feelin' this Web Components thing."}]},{"type":"p","uid":"uid","attrs":{},"children":[{"text":"Heard of it?"}]}]}]}]},{"type":"hangout-chat","attrs":{},"children":[{"text":"Hi There!"}]}]}]},
html : `<hangout-module><hangout-chat from="Paul, Addy" nested-json='{"to":"Hello World","more-nesting":{"from":"Beautiful World"}}'><hangout-discussion><hangout-message from="Paul" profile="profile.png" datetime="2013-07-17T12:02"><p>Feelin' this Web Components thing.</p><p>Heard of it?</p></hangout-message></hangout-discussion></hangout-chat><hangout-chat>Hi There!</hangout-chat></hangout-module>`
},
]
],
'table-rowspan-colspan': {
html: `<p></p>
<table style="text-align: center;">
<colgroup data-width='444.99982'>
<col style="width:26.2921%" />
<col style="width:24.494399999999995%" />
<col style="width:25.617999999999995%" />
<col style="width:23.5955%" />
</colgroup>
<thead style="text-align: center;">
<tr style="text-align: center;">
<th colspan="4" style="text-align: center;">h1</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="2" colspan="2">1</td>
<td colspan="2">2</td>
</tr>
<tr>
<td>3</td>
<td rowspan="4">4</td>
</tr>
<tr>
<td rowspan="3">5</td>
<td>6</td>
<td>7</td>
</tr>
<tr>
<td colspan="2">8</td>
</tr>
<tr>
<td>9</td>
<td>10</td>
</tr>
<tr>
<td>11</td>
<td>12</td>
<td>13</td>
<td>14</td>
</tr>
</tbody>
</table>
<p></p>`,
expectedJson: {"type":"doc","uid":"uid","attrs":{},"children":[{"type":"p","attrs":{},"uid":"uid","children":[{"text":""}]},{"type":"table","attrs":{"style":{"text-align":"center"},"redactor-attributes":{"style":"text-align: center;"},"rows":7,"cols":4,"colWidths":[116.99979767422,109.00003591007999,114.00005388759998,104.9999325281],"disabledCols":[0,1,2,3]},"uid":"uid","children":[{"type":"thead","attrs":{"style":{"text-align":"center"},"redactor-attributes":{"style":"text-align: center;"}},"uid":"uid","children":[{"type":"tr","attrs":{"style":{"text-align":"center"},"redactor-attributes":{"style":"text-align: center;"}},"uid":"uid","children":[{"type":"th","attrs":{"colSpan":4,"style":{"text-align":"center"},"redactor-attributes":{"colspan":"4","style":"text-align: center;"}},"uid":"uid","children":[{"text":"h1"}]},{"type":"th","attrs":{"void":true},"children":[{"text":""}]},{"type":"th","attrs":{"void":true},"children":[{"text":""}]},{"type":"th","attrs":{"void":true},"children":[{"text":""}]}]}]},{"type":"tbody","attrs":{},"uid":"uid","children":[{"type":"trgrp","children":[{"type":"tr","attrs":{},"uid":"uid","children":[{"type":"td","attrs":{"rowSpan":2,"colSpan":2,"style":{},"redactor-attributes":{"rowspan":"2","colspan":"2"}},"uid":"uid","children":[{"text":"1"}]},{"type":"td","attrs":{"void":true},"children":[{"text":""}]},{"type":"td","attrs":{"colSpan":2,"style":{},"redactor-attributes":{"colspan":"2"}},"uid":"uid","children":[{"text":"2"}]},{"type":"td","attrs":{"void":true},"children":[{"text":""}]}]},{"type":"tr","attrs":{},"uid":"uid","children":[{"type":"td","attrs":{"void":true},"children":[{"text":""}]},{"type":"td","attrs":{"void":true},"children":[{"text":""}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":"3"}]},{"type":"td","attrs":{"rowSpan":4,"style":{},"redactor-attributes":{"rowspan":"4"}},"uid":"uid","children":[{"text":"4"}]}]},{"type":"tr","attrs":{},"uid":"uid","children":[{"type":"td","attrs":{"rowSpan":3,"style":{},"redactor-attributes":{"rowspan":"3"}},"uid":"uid","children":[{"text":"5"}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":"6"}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":"7"}]},{"type":"td","attrs":{"void":true},"children":[{"text":""}]}]},{"type":"tr","attrs":{},"uid":"uid","children":[{"type":"td","attrs":{"void":true},"children":[{"text":""}]},{"type":"td","attrs":{"colSpan":2,"style":{},"redactor-attributes":{"colspan":"2"}},"uid":"uid","children":[{"text":"8"}]},{"type":"td","attrs":{"void":true},"children":[{"text":""}]},{"type":"td","attrs":{"void":true},"children":[{"text":""}]}]},{"type":"tr","attrs":{},"uid":"uid","children":[{"type":"td","attrs":{"void":true},"children":[{"text":""}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":"9"}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":"10"}]},{"type":"td","attrs":{"void":true},"children":[{"text":""}]}]}]},{"type":"tr","attrs":{},"uid":"uid","children":[{"type":"td","attrs":{},"uid":"uid","children":[{"text":"11"}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":"12"}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":"13"}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":"14"}]}]}]}]},{"type":"p","attrs":{},"uid":"uid","children":[{"text":""}]}]}
},
'table-rowspan-colspan-2': {
html: `<p></p>
<table>
<tbody>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td rowspan="4"></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<p></p>`,
expectedJson: {"type":"doc","uid":"uid","attrs":{},"children":[{"type":"p","attrs":{},"uid":"uid","children":[{"text":""}]},{"type":"table","attrs":{"rows":3,"cols":2,"colWidths":[250,250]},"uid":"uid","children":[{"type":"tbody","attrs":{},"uid":"uid","children":[{"type":"tr","attrs":{},"uid":"uid","children":[{"type":"td","attrs":{},"uid":"uid","children":[{"text":""}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":""}]}]},{"type":"trgrp","children":[{"type":"tr","attrs":{},"uid":"uid","children":[{"type":"td","attrs":{"rowSpan":4,"style":{},"redactor-attributes":{"rowspan":"4"}},"uid":"uid","children":[{"text":""}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":""}]}]},{"type":"tr","attrs":{},"uid":"uid","children":[{"type":"td","attrs":{"void":true},"children":[{"text":""}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":""}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":""}]}]}]}]}]},{"type":"p","attrs":{},"uid":"uid","children":[{"text":""}]}]}
},
'table-rowspan-colspan-3': {
html: `<table border="1">
<thead>
<tr>
<th>Header 1</th>
<th colspan="3">Header 2</th>
<th>Header 3</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="2">Row 1, Col 1</td>
<td colspan="2">Row 1, Col 2</td>
<td>Row 1, Col 3</td>
<td rowspan="2">Row 1, Col 4</td>
</tr>
<tr>
<td>Row 2, Col 2</td>
<td>Row 2, Col 3</td>
<td>Row 2, Col 4</td>
</tr>
<tr>
<td>Row 3, Col 1</td>
<td colspan="3" rowspan="2">Row 3, Col 2</td>
<td>Row 3, Col 5</td>
</tr>
<tr>
<td>Row 4, Col 1</td>
<td>Row 4, Col 5</td>
</tr>
</tbody>
</table>
`,
expectedJson: {"type":"doc","uid":"uid","attrs":{},"children":[{"type":"table","attrs":{"style":{},"redactor-attributes":{"border":"1"},"rows":5,"cols":4,"colWidths":[250,250,250,250],"disabledCols":[1,2,3]},"uid":"uid","children":[{"type":"thead","attrs":{},"uid":"uid","children":[{"type":"tr","attrs":{},"uid":"uid","children":[{"type":"th","attrs":{},"uid":"uid","children":[{"text":"Header 1"}]},{"type":"th","attrs":{"colSpan":3,"style":{},"redactor-attributes":{"colspan":"3"}},"uid":"uid","children":[{"text":"Header 2"}]},{"type":"th","attrs":{"void":true},"children":[{"text":""}]},{"type":"th","attrs":{"void":true},"children":[{"text":""}]},{"type":"th","attrs":{},"uid":"uid","children":[{"text":"Header 3"}]}]}]},{"type":"tbody","attrs":{},"uid":"uid","children":[{"type":"trgrp","children":[{"type":"tr","attrs":{},"uid":"uid","children":[{"type":"td","attrs":{"rowSpan":2,"style":{},"redactor-attributes":{"rowspan":"2"}},"uid":"uid","children":[{"text":"Row 1, Col 1"}]},{"type":"td","attrs":{"colSpan":2,"style":{},"redactor-attributes":{"colspan":"2"}},"uid":"uid","children":[{"text":"Row 1, Col 2"}]},{"type":"td","attrs":{"void":true},"children":[{"text":""}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":"Row 1, Col 3"}]},{"type":"td","attrs":{"rowSpan":2,"style":{},"redactor-attributes":{"rowspan":"2"}},"uid":"uid","children":[{"text":"Row 1, Col 4"}]}]},{"type":"tr","attrs":{},"uid":"uid","children":[{"type":"td","attrs":{"void":true},"children":[{"text":""}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":"Row 2, Col 2"}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":"Row 2, Col 3"}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":"Row 2, Col 4"}]},{"type":"td","attrs":{"void":true},"children":[{"text":""}]}]}]},{"type":"trgrp","children":[{"type":"tr","attrs":{},"uid":"uid","children":[{"type":"td","attrs":{},"uid":"uid","children":[{"text":"Row 3, Col 1"}]},{"type":"td","attrs":{"rowSpan":2,"colSpan":3,"style":{},"redactor-attributes":{"colspan":"3","rowspan":"2"}},"uid":"uid","children":[{"text":"Row 3, Col 2"}]},{"type":"td","attrs":{"void":true},"children":[{"text":""}]},{"type":"td","attrs":{"void":true},"children":[{"text":""}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":"Row 3, Col 5"}]}]},{"type":"tr","attrs":{},"uid":"uid","children":[{"type":"td","attrs":{},"uid":"uid","children":[{"text":"Row 4, Col 1"}]},{"type":"td","attrs":{"void":true},"children":[{"text":""}]},{"type":"td","attrs":{"void":true},"children":[{"text":""}]},{"type":"td","attrs":{"void":true},"children":[{"text":""}]},{"type":"td","attrs":{},"uid":"uid","children":[{"text":"Row 4, Col 5"}]}]}]}]}]}]}
},

}
27 changes: 27 additions & 0 deletions test/fromRedactor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,5 +303,32 @@ describe("CS-41001", () =>{
const jsonValue = fromRedactor(body);
expect(jsonValue).toStrictEqual({"type":"doc","uid":"uid","attrs":{},"children":[{"type":"p","attrs":{},"uid":"uid","children":[{"text":"Hello"}]},{"type":"fragment","attrs":{},"uid":"uid","children":[{"text":" beautiful "}]},{"type":"p","attrs":{},"uid":"uid","children":[{"text":"World"}]}]})
})

test('table JSON should have proper structure with rowspan and colspan', () => {
const testCases = ['table-rowspan-colspan', 'table-rowspan-colspan-2', 'table-rowspan-colspan-3']
testCases.forEach(testCase => {
try {
const { html, expectedJson } = expectedValue[testCase]
const json = htmlToJson(html)
expect(json).toStrictEqual(expectedJson)
}
catch (e) {
throw new Error(`Test failed for ${testCase} - ${e}`)
}
})
})
})

function htmlToJson (html, options) {
const dom = new JSDOM(html);
let htmlDoc = dom.window.document.querySelector("body");
return fromRedactor(htmlDoc, options);

}


test.only('test', () => {
const html = `<table><tbody></tbody></table>`
const json = htmlToJson(html)
console.log(JSON.stringify(json))
Jayesh2812 marked this conversation as resolved.
Show resolved Hide resolved
})
14 changes: 14 additions & 0 deletions test/toRedactor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,18 @@ describe("Testing json to html conversion", () => {
});
});
});

test("should convert rowspan and colspan tables to proper html", () => {

const { html: expectedHtml, expectedJson: json } = {
html: `<p></p><table style="text-align: center;"><colgroup data-width='444.99982'><col style="width:26.2921%"/><col style="width:24.494399999999995%"/><col style="width:25.617999999999995%"/><col style="width:23.5955%"/></colgroup><thead style="text-align: center;"><tr style="text-align: center;"><th colspan="4" style="text-align: center;">h1</th></tr></thead><tbody><tr><td rowspan="2" colspan="2">1</td><td colspan="2">2</td></tr><tr><td>3</td><td rowspan="4">4</td></tr><tr><td rowspan="3">5</td><td>6</td><td>7</td></tr><tr><td colspan="2">8</td></tr><tr><td>9</td><td>10</td></tr><tr><td>11</td><td>12</td><td>13</td><td>14</td></tr></tbody></table><p></p>`,
expectedJson: [{ "type": "p", "attrs": {}, "uid": "uid", "children": [{ "text": "" }] }, { "type": "table", "attrs": { "style": { "text-align": "center" }, "redactor-attributes": { "style": "text-align: center;" }, "rows": 7, "cols": 4, "colWidths": [116.99979767422, 109.00003591007999, 114.00005388759998, 104.9999325281], "disabledCols": [0, 1, 2, 3] }, "uid": "uid", "children": [{ "type": "thead", "attrs": { "style": { "text-align": "center" }, "redactor-attributes": { "style": "text-align: center;" } }, "uid": "uid", "children": [{ "type": "tr", "attrs": { "style": { "text-align": "center" }, "redactor-attributes": { "style": "text-align: center;" } }, "uid": "uid", "children": [{ "type": "th", "attrs": { "colSpan": 4, "style": { "text-align": "center" }, "redactor-attributes": { "colspan": "4", "style": "text-align: center;" } }, "uid": "uid", "children": [{ "text": "h1" }] }, { "type": "th", "attrs": { "void": true }, "children": [{ "text": "" }] }, { "type": "th", "attrs": { "void": true }, "children": [{ "text": "" }] }, { "type": "th", "attrs": { "void": true }, "children": [{ "text": "" }] }] }] }, { "type": "tbody", "attrs": {}, "uid": "uid", "children": [{ "type": "trgrp", "children": [{ "type": "tr", "attrs": {}, "uid": "uid", "children": [{ "type": "td", "attrs": { "rowSpan": 2, "colSpan": 2, "redactor-attributes": { "rowspan": "2", "colspan": "2" } }, "uid": "uid", "children": [{ "text": "1" }] }, { "type": "td", "attrs": { "void": true }, "children": [{ "text": "" }] }, { "type": "td", "attrs": { "colSpan": 2, "redactor-attributes": { "colspan": "2" } }, "uid": "uid", "children": [{ "text": "2" }] }, { "type": "td", "attrs": { "void": true }, "children": [{ "text": "" }] }] }, { "type": "tr", "attrs": {}, "uid": "uid", "children": [{ "type": "td", "attrs": { "void": true }, "children": [{ "text": "" }] }, { "type": "td", "attrs": { "void": true }, "children": [{ "text": "" }] }, { "type": "td", "attrs": {}, "uid": "uid", "children": [{ "text": "3" }] }, { "type": "td", "attrs": { "rowSpan": 4, "redactor-attributes": { "rowspan": "4" } }, "uid": "uid", "children": [{ "text": "4" }] }] }, { "type": "tr", "attrs": {}, "uid": "uid", "children": [{ "type": "td", "attrs": { "rowSpan": 3, "redactor-attributes": { "rowspan": "3" } }, "uid": "uid", "children": [{ "text": "5" }] }, { "type": "td", "attrs": {}, "uid": "uid", "children": [{ "text": "6" }] }, { "type": "td", "attrs": {}, "uid": "uid", "children": [{ "text": "7" }] }, { "type": "td", "attrs": { "void": true }, "children": [{ "text": "" }] }] }, { "type": "tr", "attrs": {}, "uid": "uid", "children": [{ "type": "td", "attrs": { "void": true }, "children": [{ "text": "" }] }, { "type": "td", "attrs": { "colSpan": 2, "redactor-attributes": { "colspan": "2" } }, "uid": "uid", "children": [{ "text": "8" }] }, { "type": "td", "attrs": { "void": true }, "children": [{ "text": "" }] }, { "type": "td", "attrs": { "void": true }, "children": [{ "text": "" }] }] }, { "type": "tr", "attrs": {}, "uid": "uid", "children": [{ "type": "td", "attrs": { "void": true }, "children": [{ "text": "" }] }, { "type": "td", "attrs": {}, "uid": "uid", "children": [{ "text": "9" }] }, { "type": "td", "attrs": {}, "uid": "uid", "children": [{ "text": "10" }] }, { "type": "td", "attrs": { "void": true }, "children": [{ "text": "" }] }] }] }, { "type": "tr", "attrs": {}, "uid": "uid", "children": [{ "type": "td", "attrs": {}, "uid": "uid", "children": [{ "text": "11" }] }, { "type": "td", "attrs": {}, "uid": "uid", "children": [{ "text": "12" }] }, { "type": "td", "attrs": {}, "uid": "uid", "children": [{ "text": "13" }] }, { "type": "td", "attrs": {}, "uid": "uid", "children": [{ "text": "14" }] }] }] }] }, { "type": "p", "attrs": {}, "uid": "uid", "children": [{ "text": "" }] }]
}
const html = toRedactor({
type: 'docs',
children: json
})
expect(html).toStrictEqual(expectedHtml)
})

})
Loading