[FIX] web_editor, mass_mailing: support responsive columns in mailings

Since flexbox is not well supported across e-mail clients, columns were
until now not responsive. This adds support for responsive columns and
a special rendering of them for Outlook so they don't break there.

task-2761098

Part-of: odoo/odoo#87962
This commit is contained in:
Antoine Guenet
2022-05-31 11:06:47 +02:00
parent 756243ecd3
commit d6cc70ec72
4 changed files with 146 additions and 63 deletions
+8
View File
@@ -60,6 +60,14 @@
width: 100% !important;
}
}
@media screen and (max-width: 1135px) {
td {
max-width: inherit !important;
}
td > img:only-child {
min-width: 100% !important;
}
}
</style>
</template>
@@ -128,6 +128,8 @@ function bootstrapToTable($editable) {
// Now convert all containers with rows to tables.
for (const container of [...editable.querySelectorAll('.container, .container-fluid, .o_fake_table')].filter(n => [...n.children].some(c => c.classList.contains('row')))) {
const containerWidth = _getWidth(container);
// TABLE
const table = _createTable(container.attributes);
for (const child of [...container.childNodes]) {
@@ -188,7 +190,7 @@ function bootstrapToTable($editable) {
const columnSize = _getColumnSize(bootstrapColumn);
if (gridIndex + columnSize < 12) {
currentCol = grid[gridIndex];
_applyColspan(currentCol, columnSize);
_applyColspan(currentCol, columnSize, containerWidth);
if (columnIndex === bootstrapColumns.length - 1) {
// We handled all the columns but there is still space
// in the row. Insert the columns and fill the row.
@@ -199,7 +201,7 @@ function bootstrapToTable($editable) {
} else if (gridIndex + columnSize === 12) {
// Finish the row.
currentCol = grid[gridIndex];
_applyColspan(currentCol, columnSize);
_applyColspan(currentCol, columnSize, containerWidth);
currentRow.append(...grid.filter(td => td.getAttribute('colspan')));
if (columnIndex !== bootstrapColumns.length - 1) {
// The row was filled before we handled all of its
@@ -213,7 +215,7 @@ function bootstrapToTable($editable) {
} else {
// Fill the row with what was in the grid before it
// overflowed.
_applyColspan(grid[gridIndex], 12 - gridIndex);
_applyColspan(grid[gridIndex], 12 - gridIndex, containerWidth);
currentRow.append(...grid.filter(td => td.getAttribute('colspan')));
// Start a new row that starts with the current col.
const previousRow = currentRow;
@@ -221,7 +223,7 @@ function bootstrapToTable($editable) {
previousRow.after(currentRow);
grid = _createColumnGrid();
currentCol = grid[0];
_applyColspan(currentCol, columnSize);
_applyColspan(currentCol, columnSize, containerWidth);
gridIndex = columnSize;
if (columnIndex === bootstrapColumns.length - 1 && gridIndex < 12) {
// We handled all the columns but there is still space
@@ -229,7 +231,7 @@ function bootstrapToTable($editable) {
grid[gridIndex].setAttribute('colspan', 12 - gridIndex);
currentRow.append(...grid.filter(td => td.getAttribute('colspan')));
// Adapt width to colspan.
_applyColspan(grid[gridIndex], 12 - gridIndex);
_applyColspan(grid[gridIndex], 12 - gridIndex, containerWidth);
}
}
if (currentCol) {
@@ -247,7 +249,7 @@ function bootstrapToTable($editable) {
currentCol.append(child);
}
// Adapt width to colspan.
_applyColspan(currentCol, +currentCol.getAttribute('colspan'));
_applyColspan(currentCol, +currentCol.getAttribute('colspan'), containerWidth);
}
columnIndex++;
}
@@ -391,6 +393,23 @@ function classToStyle($editable, cssRules) {
};
writes.forEach(fn => fn());
}
/**
* Add styles to all table rows and columns, that are necessary for them to be
* responsive. This only works if columns have a max-width so the styles are
* only applied to columns where that is the case.
*
* @param {Element} editable
*/
function enforceTablesResponsivity(editable) {
for (const tr of editable.querySelectorAll('tr')) {
tr.style.setProperty('width', '100%');
}
for (const td of editable.querySelectorAll('td[style*="max-width"]')) {
td.setAttribute('width', '100%');
td.style.setProperty('width', '100%');
td.style.setProperty('display', 'inline-block');
}
}
/**
* Convert the contents of an editable area (as a JQuery element) into content
* that is widely compatible with email clients. If no CSS Rules are given, they
@@ -456,11 +475,13 @@ async function toInline($editable, cssRules, $iframe) {
cardToTable($editable);
listGroupToTable($editable);
addTables($editable);
formatTables($editable);
normalizeColors($editable);
const rootFontSizeProperty = getComputedStyle(editable.ownerDocument.documentElement).fontSize;
const rootFontSize = parseFloat(rootFontSizeProperty.replace(/[^\d\.]/g, ''));
normalizeRem($editable, rootFontSize);
responsiveToStaticForOutlook(editable);
enforceTablesResponsivity(editable);
formatTables($editable);
await flattenBackgroundImages(editable);
// Styles were applied inline, we don't need a style element anymore.
@@ -668,14 +689,14 @@ function formatTables($editable) {
}
}
// Align items doesn't work on table rows.
for (const cell of editable.querySelectorAll('tr')) {
const alignItems = cell.style.alignItems;
for (const row of editable.querySelectorAll('tr')) {
const alignItems = row.style.alignItems;
if (alignItems === 'flex-start') {
cell.style.verticalAlign = 'top';
row.style.verticalAlign = 'top';
} else if (alignItems === 'center') {
cell.style.verticalAlign = 'middle';
row.style.verticalAlign = 'middle';
} else if (alignItems === 'flex-end' || alignItems === 'baseline') {
cell.style.verticalAlign = 'bottom';
row.style.verticalAlign = 'bottom';
}
}
// Tables don't properly inherit alignments from their ancestors in Outlook.
@@ -690,6 +711,11 @@ function formatTables($editable) {
}
}
}
// Hide replaced cells on Outlook
for (const toHide of editable.querySelectorAll('.mso-hide')) {
const style = toHide.getAttribute('style') || '';
toHide.setAttribute('style', `${style} mso-hide: all;`.trim());
}
}
/**
* Parse through the given document's stylesheets, preprocess(*) them and return
@@ -839,6 +865,36 @@ function normalizeRem($editable, rootFontSize=16) {
}
}
/**
* This replaces column html with a dumbed down, Outlook-compliant version of
* them just for Outlook so while not responsive, these columns still display OK
* on Outlook.
*
* @param {Element} editable
*/
function responsiveToStaticForOutlook(editable) {
// Replace the responsive tables with static ones for Outlook
for (const td of editable.querySelectorAll('td')) {
const tdStyle = td.getAttribute('style') || '';
const msoAttributes = [...td.attributes].filter(attr => attr.name !== 'style' && attr.name !== 'width');
const msoWidth = td.style.getPropertyValue('max-width');
const msoStyles = tdStyle.replace(/(^| |max-)width:[^;]*;\s*/g, '');
const outlookTd = document.createElement('td');
for (const attribute of msoAttributes) {
outlookTd.setAttribute(attribute.name, td.getAttribute(attribute.name));
}
if (msoWidth) {
outlookTd.setAttribute('width', ('' + msoWidth).replace('px', '').trim());
outlookTd.setAttribute('style', `${msoStyles}width: ${msoWidth};`);
} else {
outlookTd.setAttribute('style', msoStyles);
}
td.before(document.createComment(`[if mso]>${outlookTd.outerHTML.replace('</td>', '')}<![endif]`));
td.before(document.createComment('[if !mso]><!--'));
td.prepend(document.createComment('<![endif]'));
td.after(document.createComment(`[if mso]></td><![endif]`));
}
}
/**
* Convert images of type svg to png.
*
@@ -885,13 +941,14 @@ async function svgToPng($editable) {
*
* @param {Element} element
* @param {number} colspan
* @param {number} tableWidth
*/
function _applyColspan(element, colspan) {
function _applyColspan(element, colspan, tableWidth) {
element.setAttribute('colspan', colspan);
const widthPercentage = +element.getAttribute('colspan') / 12;
// Round to 2 decimal places.
const width = (Math.round(+element.getAttribute('colspan') * 10000 / 12) / 100) + '%';
element.setAttribute('width', width);
element.style.setProperty('width', width);
const width = Math.round(tableWidth * widthPercentage * 100) / 100;
element.style.setProperty('max-width', width + 'px');
}
/**
* Take a selector and return its specificity according to the w3 specification.
@@ -1,6 +1,6 @@
/** @odoo-module **/
import convertInline from '@web_editor/js/backend/convert_inline';
import {getGridHtml, getTableHtml, getRegularGridHtml, getRegularTableHtml} from 'web_editor.test_utils';
import {getGridHtml, getTableHtml, getRegularGridHtml, getRegularTableHtml, removeComments} from 'web_editor.test_utils';
QUnit.module('web_editor', {}, function () {
QUnit.module('convert_inline', {}, function () {
@@ -13,25 +13,25 @@ QUnit.module('convert_inline', {}, function () {
// 1x1
let $editable = $(`<div>${getRegularGridHtml(1, 1)}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(), getRegularTableHtml(1, 1, 12, 100),
assert.strictEqual(removeComments($editable.html()), getRegularTableHtml(1, 1, 12, 100),
"should have converted a 1x1 grid to an equivalent table");
// 1x2
$editable = $(`<div>${getRegularGridHtml(1, 2)}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(), getRegularTableHtml(1, 2, 6, 50),
assert.strictEqual(removeComments($editable.html()), getRegularTableHtml(1, 2, 6, 50),
"should have converted a 1x2 grid to an equivalent table");
// 1x3
$editable = $(`<div>${getRegularGridHtml(1, 3)}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(), getRegularTableHtml(1, 3, 4, 33.33),
assert.strictEqual(removeComments($editable.html()), getRegularTableHtml(1, 3, 4, 33.33),
"should have converted a 1x3 grid to an equivalent table");
// 1x12
$editable = $(`<div>${getRegularGridHtml(1, 12)}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(), getRegularTableHtml(1, 12, 1, 8.33),
assert.strictEqual(removeComments($editable.html()), getRegularTableHtml(1, 12, 1, 8.33),
"should have converted a 1x12 grid to an equivalent table");
});
QUnit.test('convert a single-row regular overflowing grid', async function (assert) {
@@ -40,39 +40,39 @@ QUnit.module('convert_inline', {}, function () {
// 1x13
let $editable = $(`<div>${getRegularGridHtml(1, 13)}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(),
assert.strictEqual(removeComments($editable.html()),
getRegularTableHtml(1, 12, 1, 8.33).slice(0, -8) +
`<tr><td colspan="12" width="100%" style="width: 100%;">(0, 12)</td></tr></table>`,
`<tr><td colspan="12">(0, 12)</td></tr></table>`,
"should have converted a 1x13 grid to an equivalent table (overflowing)");
// 1x14
$editable = $(`<div>${getRegularGridHtml(1, 14)}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(),
assert.strictEqual(removeComments($editable.html()),
getRegularTableHtml(1, 12, 1, 8.33).slice(0, -8) +
`<tr><td colspan="1" width="8.33%" style="width: 8.33%;">(0, 12)</td>` +
`<td colspan="11" width="91.67%" style="width: 91.67%;">(0, 13)</td></tr></table>`,
`<tr><td colspan="1">(0, 12)</td>` +
`<td colspan="11">(0, 13)</td></tr></table>`,
"should have converted a 1x14 grid to an equivalent table (overflowing)");
// 1x25
$editable = $(`<div>${getRegularGridHtml(1, 25)}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(),
assert.strictEqual(removeComments($editable.html()),
getRegularTableHtml(1, 12, 1, 8.33).slice(0, -8) +
getRegularTableHtml(1, 12, 1, 8.33).replace(/\(0, (\d+)\)/g, (s, c) => `(0, ${+c + 12})`)
.replace(/^<table[^<]*>/, '').slice(0, -8) +
`<tr><td colspan="12" width="100%" style="width: 100%;">(0, 24)</td></tr></table>`,
`<tr><td colspan="12">(0, 24)</td></tr></table>`,
"should have converted a 1x25 grid to an equivalent table (overflowing)");
// 1x26
$editable = $(`<div>${getRegularGridHtml(1, 26)}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(),
assert.strictEqual(removeComments($editable.html()),
getRegularTableHtml(1, 12, 1, 8.33).slice(0, -8) +
getRegularTableHtml(1, 12, 1, 8.33).replace(/\(0, (\d+)\)/g, (s, c) => `(0, ${+c + 12})`)
.replace(/^<table[^<]*>/, '').slice(0, -8) +
`<tr><td colspan="1" width="8.33%" style="width: 8.33%;">(0, 24)</td>` +
`<td colspan="11" width="91.67%" style="width: 91.67%;">(0, 25)</td></tr></table>`,
`<tr><td colspan="1">(0, 24)</td>` +
`<td colspan="11">(0, 25)</td></tr></table>`,
"should have converted a 1x26 grid to an equivalent table (overflowing)");
});
QUnit.test('convert a multi-row regular grid', async function (assert) {
@@ -81,25 +81,25 @@ QUnit.module('convert_inline', {}, function () {
// 2x1
let $editable = $(`<div>${getRegularGridHtml(2, 1)}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(), getRegularTableHtml(2, 1, 12, 100),
assert.strictEqual(removeComments($editable.html()), getRegularTableHtml(2, 1, 12, 100),
"should have converted a 2x1 grid to an equivalent table");
// 2x[1,2]
$editable = $(`<div>${getRegularGridHtml(2, [1, 2])}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(), getRegularTableHtml(2, [1, 2], [12, 6], [100, 50]),
assert.strictEqual(removeComments($editable.html()), getRegularTableHtml(2, [1, 2], [12, 6], [100, 50], true),
"should have converted a 2x[1,2] grid to an equivalent table");
// 3x3
$editable = $(`<div>${getRegularGridHtml(3, 3)}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(), getRegularTableHtml(3, 3, 4, 33.33),
assert.strictEqual(removeComments($editable.html()), getRegularTableHtml(3, 3, 4, 33.33),
"should have converted a 3x3 grid to an equivalent table");
// 3x[3,2,1]
$editable = $(`<div>${getRegularGridHtml(3, [3,2,1])}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(), getRegularTableHtml(3, [3, 2, 1], [4, 6, 12], [33.33, 50, 100]),
assert.strictEqual(removeComments($editable.html()), getRegularTableHtml(3, [3, 2, 1], [4, 6, 12], [33.33, 50, 100], true),
"should have converted a 3x[3,2,1] grid to an equivalent table");
});
QUnit.test('convert a multi-row regular overflowing grid', async function (assert) {
@@ -108,35 +108,35 @@ QUnit.module('convert_inline', {}, function () {
// 2x[13,1]
let $editable = $(`<div>${getRegularGridHtml(2, [13, 1])}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(),
assert.strictEqual(removeComments($editable.html()),
getRegularTableHtml(1, 12, 1, 8.33).slice(0, -8) +
`<tr><td colspan="12" width="100%" style="width: 100%;">(0, 12)</td></tr>` +
`<tr><td colspan="12" width="100%" style="width: 100%;">(1, 0)</td></tr></table>`,
`<tr><td colspan="12">(0, 12)</td></tr>` +
`<tr><td colspan="12">(1, 0)</td></tr></table>`,
"should have converted a 2x[13,1] grid to an equivalent table (overflowing)");
// 2x[1,13]
$editable = $(`<div>${getRegularGridHtml(2, [1, 13])}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(),
getRegularTableHtml(2, [1, 12], [12, 1], [100, 8.33]).slice(0, -8) +
`<tr><td colspan="12" width="100%" style="width: 100%;">(1, 12)</td></tr></table>`,
assert.strictEqual(removeComments($editable.html()),
getRegularTableHtml(2, [1, 12], [12, 1], [100, 8.33], true).slice(0, -8) +
`<tr><td colspan="12">(1, 12)</td></tr></table>`,
"should have converted a 2x[1,13] grid to an equivalent table (overflowing)");
// 3x[1,13,6]
$editable = $(`<div>${getRegularGridHtml(3, [1, 13, 6])}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(),
getRegularTableHtml(2, [1, 12], [12, 1], [100, 8.33]).slice(0, -8) +
`<tr><td colspan="12" width="100%" style="width: 100%;">(1, 12)</td></tr>` +
assert.strictEqual(removeComments($editable.html()),
getRegularTableHtml(2, [1, 12], [12, 1], [100, 8.33], true).slice(0, -8) +
`<tr><td colspan="12">(1, 12)</td></tr>` +
getRegularTableHtml(1, 6, 2, 16.67).replace(/\(0,/g, `(2,`).replace(/^<table[^<]*>/, ''),
"should have converted a 3x[1,13,6] grid to an equivalent table (overflowing)");
// 3x[1,6,13]
$editable = $(`<div>${getRegularGridHtml(3, [1, 6, 13])}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(),
getRegularTableHtml(3, [1, 6, 12], [12, 2, 1], [100, 16.67, 8.33]).slice(0, -8) +
`<tr><td colspan="12" width="100%" style="width: 100%;">(2, 12)</td></tr></table>`,
assert.strictEqual(removeComments($editable.html()),
getRegularTableHtml(3, [1, 6, 12], [12, 2, 1], [100, 16.67, 8.33], true).slice(0, -8) +
`<tr><td colspan="12">(2, 12)</td></tr></table>`,
"should have converted a 3x[1,6,13] grid to an equivalent table (overflowing)");
});
QUnit.test('convert a single-row irregular grid', async function (assert) {assert.expect(4);
@@ -145,13 +145,13 @@ QUnit.module('convert_inline', {}, function () {
// 1x2
let $editable = $(`<div>${getGridHtml([[8, 4]])}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(), getTableHtml([[[8, 66.67], [4, 33.33]]]),
assert.strictEqual(removeComments($editable.html()), getTableHtml([[[8, 66.67], [4, 33.33]]], true),
"should have converted a 1x2 irregular grid to an equivalent table");
// 1x3
$editable = $(`<div>${getGridHtml([[2, 3, 7]])}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(), getTableHtml([[[2, 16.67], [3, 25], [7, 58.33]]]),
assert.strictEqual(removeComments($editable.html()), getTableHtml([[[2, 16.67], [3, 25], [7, 58.33]]], true),
"should have converted a 1x3 grid to an equivalent table");
});
QUnit.test('convert a single-row irregular overflowing grid', async function (assert) {assert.expect(4);
@@ -160,20 +160,20 @@ QUnit.module('convert_inline', {}, function () {
// 1x2
let $editable = $(`<div>${getGridHtml([[8, 5]])}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(), getTableHtml([
assert.strictEqual(removeComments($editable.html()), getTableHtml([
[[8, 66.67], [4, 33.33, '']],
[[5, 41.67, '(0, 1)'], [7, 58.33, '']],
]),
], true),
"should have converted a 1x2 irregular overflowing grid to an equivalent table");
// 1x3
$editable = $(`<div>${getGridHtml([[7, 6, 9]])}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(), getTableHtml([
assert.strictEqual(removeComments($editable.html()), getTableHtml([
[[7, 58.33], [5, 41.67, '']],
[[6, 50, '(0, 1)'], [6, 50, '']],
[[9, 75, '(0, 2)'], [3, 25, '']],
]),
], true),
"should have converted a 1x3 irregular overflowing grid to an equivalent table");
});
QUnit.test('convert a multi-row irregular grid', async function (assert) {
@@ -182,13 +182,13 @@ QUnit.module('convert_inline', {}, function () {
// 2x2
let $editable = $(`<div>${getGridHtml([[1, 11], [2, 10]])}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(), getTableHtml([[[1, 8.33], [11, 91.67]], [[2, 16.67], [10, 83.33]]]),
assert.strictEqual(removeComments($editable.html()), getTableHtml([[[1, 8.33], [11, 91.67]], [[2, 16.67], [10, 83.33]]], true),
"should have converted a 2x2 irregular grid to an equivalent table");
// 2x[2,3]
$editable = $(`<div>${getGridHtml([[3, 9], [4, 6, 2]])}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(), getTableHtml([[[3, 25], [9, 75]], [[4, 33.33], [6, 50], [2, 16.67]]]),
assert.strictEqual(removeComments($editable.html()), getTableHtml([[[3, 25], [9, 75]], [[4, 33.33], [6, 50], [2, 16.67]]], true),
"should have converted a 2x[2,3] irregular grid to an equivalent table");
});
QUnit.test('convert a multi-row irregular overflowing grid', async function (assert) {
@@ -197,35 +197,35 @@ QUnit.module('convert_inline', {}, function () {
// 2x2 (both rows overflow)
let $editable = $(`<div>${getGridHtml([[6, 8], [7, 9]])}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(),
assert.strictEqual(removeComments($editable.html()),
getTableHtml([
[[6, 50], [6, 50, '']],
[[8, 66.67, '(0, 1)'], [4, 33.33, '']],
[[7, 58.33, '(1, 0)'], [5, 41.67, '']],
[[9, 75, '(1, 1)'], [3, 25, '']],
]),
], true),
"should have converted a 2x[1,13] irregular grid to an equivalent table (both rows overflowing)");
// 2x[2,3] (first row overflows)
$editable = $(`<div>${getGridHtml([[5, 8], [4, 2, 6]])}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(),
assert.strictEqual(removeComments($editable.html()),
getTableHtml([
[[5, 41.67], [7, 58.33, '']],
[[8, 66.67, '(0, 1)'], [4, 33.33, '']],
[[4, 33.33, '(1, 0)'], [2, 16.67, '(1, 1)'], [6, 50, '(1, 2)']],
]),
], true),
"should have converted a 2x[2,3] irregular grid to an equivalent table (first row overflowing)");
// 2x[3,2] (second row overflows)
$editable = $(`<div>${getGridHtml([[4, 2, 6], [5, 8]])}</div>`);
convertInline.bootstrapToTable($editable);
assert.strictEqual($editable.html(),
assert.strictEqual(removeComments($editable.html()),
getTableHtml([
[[4, 33.33], [2, 16.67], [6, 50]],
[[5, 41.67], [7, 58.33, '']],
[[8, 66.67, '(1, 1)'], [4, 33.33, '']],
]),
], true),
"should have converted a 2x[3,2] irregular grid to an equivalent table (second row overflowing)");
});
QUnit.test('convert a card to a table', async function (assert) {
@@ -247,7 +247,7 @@ QUnit.module('convert_inline', {}, function () {
convertInline.cardToTable($editable);
assert.strictEqual($editable.html(),
getRegularTableHtml(3, 1, 12, 100)
.split('style="').join('class="card" style="')
.replace('role=\"presentation\"', 'role=\"presentation\" class=\"card\"')
.replace(/<td[^>]*>\(0, 0\)<\/td>/,
`<td>` +
`<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%\" align=\"center\" ` +
+19 -1
View File
@@ -801,7 +801,7 @@ function getTableHtml(matrix) {
matrix.map((row, iRow) => (
`<tr>` +
row.map((col, iCol) => (
`<td colspan="${col[0]}" width="${col[1]}%" style="width: ${col[1]}%;">` +
`<td colspan="${col[0]}">` +
(col.length === 3 ? col[2] : `(${iRow}, ${iCol})`) +
`</td>`
)).join('') +
@@ -852,6 +852,23 @@ function getRegularTableHtml(nRows, nCols, colspan, width) {
);
return getTableHtml(matrix);
}
/**
* Take an HTML string and returns that string stripped from any HTML comments.
* By default, also removes the mso-hide class which is only there for outlook
* to hide elements when we use mso conditional comments.
*
* @param {string} html
* @param {boolean} [removeMsoHide=true]
* @returns {string}
*/
function removeComments(html, removeMsoHide=true) {
const cleanHtml = html.replace(/<!--(.*?)-->/g, '');
if (removeMsoHide) {
return cleanHtml.replaceAll(' class="mso-hide"', '').replace(/\s*mso-hide/g, '').replace(/mso-hide\s*/g, '');
} else {
return cleanHtml;
}
}
return {
wysiwygData: wysiwygData,
@@ -865,6 +882,7 @@ return {
getTableHtml: getTableHtml,
getRegularGridHtml: getRegularGridHtml,
getRegularTableHtml: getRegularTableHtml,
removeComments: removeComments,
};