Skip to content

Commit b37c515

Browse files
committed
[FIX] web_editor: properly convert cards to tables
Cards need to be double wrapped in tables to be displayed properly because of a bizarre hack by bootstrap that uses background-color rather to give the effect of a border, and because we can have card-body be a sibling of a list-group. Incidentally this also prevents the introduction of a new row for each whitespace text node. Part-of: odoo#82233
1 parent 8697f35 commit b37c515

File tree

2 files changed

+45
-18
lines changed

2 files changed

+45
-18
lines changed

addons/web_editor/static/src/js/backend/convert_inline.js

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { isBlock, rgbToHex } from '../../../lib/odoo-editor/src/utils/utils';
1111
const RE_COL_MATCH = /(^| )col(-[\w\d]+)*( |$)/;
1212
const RE_OFFSET_MATCH = /(^| )offset(-[\w\d]+)*( |$)/;
1313
const RE_PADDING = /([\d.]+)/;
14+
const RE_WHITESPACE = /[\s\u200b]*/;
1415
const SELECTORS_IGNORE = /(^\*$|:hover|:before|:after|:active|:link|::|'|\([^(),]+[,(])/;
1516
// Attributes all tables should have in a mailing.
1617
const TABLE_ATTRIBUTES = {
@@ -248,25 +249,33 @@ function cardToTable($editable) {
248249
const $card = $(card);
249250
const $table = _createTable(card.attributes);
250251
for (const child of [...card.childNodes]) {
251-
if (child.nodeType === Node.TEXT_NODE) {
252-
$table.append(child);
253-
} else {
254-
const $row = $('<tr/>');
255-
const $col = $('<td/>');
256-
if (child.nodeName === 'IMG') {
252+
const $row = $('<tr/>');
253+
const $col = $('<td/>');
254+
if (child.nodeName === 'IMG') {
255+
$col.append(child);
256+
} else if (child.nodeType === Node.TEXT_NODE) {
257+
if (child.textContent.replace(RE_WHITESPACE, '').length) {
257258
$col.append(child);
258259
} else {
259-
for (const attr of child.attributes) {
260-
$col.attr(attr.name, attr.value);
261-
}
262-
for (const descendant of [...child.childNodes]) {
263-
$col.append(descendant);
264-
}
265-
$(child).remove();
260+
continue;
266261
}
267-
$row.append($col);
268-
$table.append($row);
262+
} else {
263+
for (const attr of child.attributes) {
264+
$col.attr(attr.name, attr.value);
265+
}
266+
for (const descendant of [...child.childNodes]) {
267+
$col.append(descendant);
268+
}
269+
$(child).remove();
269270
}
271+
const $subTable = _createTable();
272+
const $superRow = $('<tr/>');
273+
const $superCol = $('<td/>');
274+
$row.append($col);
275+
$subTable.append($row);
276+
$superCol.append($subTable);
277+
$superRow.append($superCol);
278+
$table.append($superRow);
270279
}
271280
$card.before($table);
272281
$card.remove();

addons/web_editor/static/tests/convert_inline_tests.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,27 @@ QUnit.module('convert_inline', {}, function () {
251251
assert.strictEqual($editable.html(),
252252
getRegularTableHtml(3, 1, 12, 100)
253253
.split('style="').join('class="card" style="')
254-
.replace(/<td[^>]*>\(0, 0\)<\/td>/, '<td class="card-header"><span>HEADER</span></td>')
255-
.replace(/<td[^>]*>\(1, 0\)<\/td>/, '<td class="card-body"><h2 class="card-title">TITLE</h2><small>BODY <img></small></td>')
256-
.replace(/<td[^>]*>\(2, 0\)<\/td>/, '<td class="card-footer"><a href="#" class="btn">FOOTER</a></td>'),
254+
.replace(/<td[^>]*>\(0, 0\)<\/td>/,
255+
`<td>` +
256+
`<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%\" align=\"center\" ` +
257+
`role=\"presentation\" style=\"width: 100% !important; border-collapse: collapse; text-align: inherit; ` +
258+
`font-size: unset; line-height: unset;\"><tr>` +
259+
`<td class="card-header"><span>HEADER</span></td>` +
260+
`</tr></table></td>`)
261+
.replace(/<td[^>]*>\(1, 0\)<\/td>/,
262+
`<td>` +
263+
`<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%\" align=\"center\" ` +
264+
`role=\"presentation\" style=\"width: 100% !important; border-collapse: collapse; text-align: inherit; ` +
265+
`font-size: unset; line-height: unset;\"><tr>` +
266+
`<td class="card-body"><h2 class="card-title">TITLE</h2><small>BODY <img></small></td>` +
267+
`</tr></table></td>`)
268+
.replace(/<td[^>]*>\(2, 0\)<\/td>/,
269+
`<td>` +
270+
`<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%\" align=\"center\" ` +
271+
`role=\"presentation\" style=\"width: 100% !important; border-collapse: collapse; text-align: inherit; ` +
272+
`font-size: unset; line-height: unset;\"><tr>` +
273+
`<td class="card-footer"><a href="#" class="btn">FOOTER</a></td>` +
274+
`</tr></table></td>`),
257275
"should have converted a card structure into a table");
258276
});
259277
QUnit.test('convert a list group to a table', async function (assert) {

0 commit comments

Comments
 (0)