From 324e1387bdc786175072fff6492ed361f5f6fb93 Mon Sep 17 00:00:00 2001 From: vishal padhiyar <visp@odoo.com> Date: Wed, 28 Jun 2023 11:33:15 +0530 Subject: [PATCH] [FIX] web_editor: remove unwanted styles and tags Before this commit: When pasting text from outside odoo, it often includes additional tags such as <b> and <P>, along with unwanted styles. After this commit: When pasting text from outside odoo, those extra tags and styles are now removed. task-3378093 closes odoo/odoo#127393 Signed-off-by: David Monjoie (dmo) <dmo@odoo.com> --- .../js/editor/odoo-editor/src/OdooEditor.js | 19 +++--- .../editor/odoo-editor/src/utils/sanitize.js | 9 ++- .../odoo-editor/test/spec/copyPaste.test.js | 57 +++++++++++++----- .../odoo-editor/test/spec/htmlTables.test.js | 60 +++++++++---------- .../editor/odoo-editor/test/spec/list.test.js | 36 +++++------ 5 files changed, 105 insertions(+), 76 deletions(-) diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js b/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js index 808a578b2307..8560e10ba6eb 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js @@ -174,7 +174,6 @@ export const CLIPBOARD_WHITELISTS = { ], attributes: ['class', 'href', 'src', 'target'], styledTags: ['SPAN', 'B', 'STRONG', 'I', 'S', 'U', 'FONT', 'TD'], - styles: ['text-decoration', 'font-weight', 'background-color', 'color', 'font-style', 'text-decoration-line', 'font-size'] }; // Commands that don't require a DOM selection but take an argument instead. @@ -3109,7 +3108,12 @@ export class OdooEditor extends EventTarget { * @param {Node} node */ _cleanForPaste(node) { - if (!this._isWhitelisted(node) || this._isBlacklisted(node)) { + if ( + !this._isWhitelisted(node) || + this._isBlacklisted(node) || + // Google Docs have their html inside a B tag with custom id. + node.id && node.id.startsWith('docs-internal-guid') + ) { if (!node.matches || node.matches(CLIPBOARD_BLACKLISTS.remove.join(','))) { node.remove(); } else { @@ -3146,14 +3150,8 @@ export class OdooEditor extends EventTarget { for (const attribute of [...node.attributes]) { // Keep allowed styles on nodes with allowed tags. if (CLIPBOARD_WHITELISTS.styledTags.includes(node.nodeName) && attribute.name === 'style') { - const spanInlineStyles = attribute.value.split(';').map(x => x.trim()); - const allowedSpanInlineStyles = spanInlineStyles.filter(rawStyle => { - return CLIPBOARD_WHITELISTS.styles.includes(rawStyle.split(':')[0].trim()); - }); node.removeAttribute(attribute.name); - if (allowedSpanInlineStyles.length > 0) { - node.setAttribute(attribute.name, allowedSpanInlineStyles.join(';')); - } else if (['SPAN', 'FONT'].includes(node.tagName)) { + if (['SPAN', 'FONT'].includes(node.tagName)) { for (const unwrappedNode of unwrapContents(node)) { this._cleanForPaste(unwrappedNode); } @@ -3189,12 +3187,11 @@ export class OdooEditor extends EventTarget { okClass instanceof RegExp ? okClass.test(item) : okClass === item, ); } else { - const allowedSpanStyles = CLIPBOARD_WHITELISTS.styles.map(s => `span[style*="${s}"]`); return ( item.nodeType === Node.TEXT_NODE || ( item.matches && - item.matches([...CLIPBOARD_WHITELISTS.nodes, ...allowedSpanStyles].join(',')) + item.matches(CLIPBOARD_WHITELISTS.nodes) ) ); } diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/src/utils/sanitize.js b/addons/web_editor/static/src/js/editor/odoo-editor/src/utils/sanitize.js index 94b6a892810d..18b7e1df0f08 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/src/utils/sanitize.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/src/utils/sanitize.js @@ -18,6 +18,7 @@ import { isArtificialVoidElement, EMAIL_REGEX, URL_REGEX_WITH_INFOS, + unwrapContents, } from './utils.js'; const NOT_A_NUMBER = /[^\d]/g; @@ -220,12 +221,16 @@ class Sanitize { // Remove empty blocks in <li> if ( node.nodeName === 'P' && - node.parentElement.tagName === 'LI' && - isEmptyBlock(node) + node.parentElement.tagName === 'LI' ) { const parent = node.parentElement; const restoreCursor = node.isConnected && preserveCursor(this.root.ownerDocument); + if (isEmptyBlock(node)) { + node.remove(); + } else { + unwrapContents(node); + } node.remove(); fillEmpty(parent); if (restoreCursor) { diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/copyPaste.test.js b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/copyPaste.test.js index 24fdf3bf7564..122ae9bb24c5 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/copyPaste.test.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/copyPaste.test.js @@ -237,7 +237,34 @@ describe('Paste', () => { stepFunction: async editor => { await pasteHtml(editor, 'a<span style="text-decoration: underline">bc</span>d'); }, - contentAfter: '<p>123a<span style="text-decoration: underline">bc</span>d[]</p>', + contentAfter: '<p>123abcd[]</p>', + }); + }); + it('should remove unwanted styles and b tag when pasting from paragraph from gdocs', async () => { + await testEditor(BasicEditor, { + contentBefore: '<p>[]<br></p>', + stepFunction: async editor => { + await pasteHtml(editor, `<meta charset="utf-8"><b style="font-weight:normal;" id="docs-internal-guid-ddad60c5-7fff-0a8f-fdd5-c1107201fe26"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">test1</span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">test2</span></p></b>`); + }, + contentAfter: '<p>test1</p><p>test2[]<br></p>', + }); + }); + it('should remove unwanted b tag and p tag with unwanted styles when pasting list from gdocs', async () => { + await testEditor(BasicEditor, { + contentBefore: '<p>[]<br></p>', + stepFunction: async editor => { + await pasteHtml(editor, '<meta charset="utf-8"><b style="font-weight:normal;" id="docs-internal-guid-5d8bcf85-7fff-ebec-8604-eedd96f2d601"><ul style="margin-top:0;margin-bottom:0;padding-inline-start:48px;"><li dir="ltr" style="list-style-type:disc;font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;" aria-level="1"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;" role="presentation"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Google</span></p></li><li dir="ltr" style="list-style-type:disc;font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;" aria-level="1"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;" role="presentation"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Test</span></p></li><li dir="ltr" style="list-style-type:disc;font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;" aria-level="1"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;" role="presentation"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">test2</span></p></li></ul></b>'); + }, + contentAfter: '<ul><li>Google</li><li>Test</li><li>test2</li></ul><p>[]<br></p>', + }); + }); + it('should remove unwanted styles and keep tags when pasting list from gdoc', async () => { + await testEditor(BasicEditor, { + contentBefore: '<p>[]<br></p>', + stepFunction: async editor => { + await pasteHtml(editor, '<meta charset="utf-8"><b style="font-weight:normal;" id="docs-internal-guid-477946a8-7fff-f959-18a4-05014997e161"><ul style="margin-top:0;margin-bottom:0;padding-inline-start:48px;"><li dir="ltr" style="list-style-type:disc;font-size:20pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;" aria-level="1"><h1 dir="ltr" style="line-height:1.38;margin-top:20pt;margin-bottom:0pt;" role="presentation"><span style="font-size:20pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Google</span></h1></li><li dir="ltr" style="list-style-type:disc;font-size:20pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;" aria-level="1"><h1 dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:6pt;" role="presentation"><span style="font-size:20pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Test</span></h1></li><li dir="ltr" style="list-style-type:disc;font-size:20pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;" aria-level="1"><h1 dir="ltr" style="line-height:1.38;margin-top:20pt;margin-bottom:0pt;" role="presentation"><span style="font-size:20pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">test2</span></h1></li></ul></b>'); + }, + contentAfter: '<ul><li><h1>Google</h1></li><li><h1>Test</h1></li><li><h1>test2</h1></li></ul><p>[]<br></p>', }); }); }); @@ -666,7 +693,7 @@ describe('Paste', () => { stepFunction: async editor => { await pasteHtml(editor, complexHtmlData); }, - contentAfter: '<p>1<b style="font-weight: bolder">23</b> 4[]abcd</p>', + contentAfter: '<p>1<b>23</b> 4[]abcd</p>', }); }); it('should paste a text in a p', async () => { @@ -675,7 +702,7 @@ describe('Paste', () => { stepFunction: async editor => { await pasteHtml(editor, complexHtmlData); }, - contentAfter: '<p>ab1<b style="font-weight: bolder">23</b> 4[]cd</p>', + contentAfter: '<p>ab1<b>23</b> 4[]cd</p>', }); }); it('should paste a text in a span', async () => { @@ -684,7 +711,7 @@ describe('Paste', () => { stepFunction: async editor => { await pasteHtml(editor, complexHtmlData); }, - contentAfter: '<p>a<span>b1<b style="font-weight: bolder">23</b> 4[]c</span>d</p>', + contentAfter: '<p>a<span>b1<b>23</b> 4[]c</span>d</p>', }); }); }); @@ -695,7 +722,7 @@ describe('Paste', () => { stepFunction: async editor => { await pasteHtml(editor, complexHtmlData); }, - contentAfter: '<p>a1<b style="font-weight: bolder">23</b> 4[]d</p>', + contentAfter: '<p>a1<b>23</b> 4[]d</p>', }); }); it('should paste a text in a span', async () => { @@ -704,7 +731,7 @@ describe('Paste', () => { stepFunction: async editor => { await pasteHtml(editor, complexHtmlData); }, - contentAfter: '<p>a<span>b1<b style="font-weight: bolder">23</b> 4[]e</span>f</p>', + contentAfter: '<p>a<span>b1<b>23</b> 4[]e</span>f</p>', }); }); it('should paste a text when selection across two span', async () => { @@ -713,14 +740,14 @@ describe('Paste', () => { stepFunction: async editor => { await pasteHtml(editor, complexHtmlData); }, - contentAfter: '<p>a<span>b1<b style="font-weight: bolder">23</b> 4[]e</span>f</p>', + contentAfter: '<p>a<span>b1<b>23</b> 4[]e</span>f</p>', }); await testEditor(BasicEditor, { contentBefore: '<p>a<span>b[c</span>- -<span>d]e</span>f</p>', stepFunction: async editor => { await pasteHtml(editor, complexHtmlData); }, - contentAfter: '<p>a<span>b1<b style="font-weight: bolder">23</b> 4[]e</span>f</p>', + contentAfter: '<p>a<span>b1<b>23</b> 4[]e</span>f</p>', }); }); it('should paste a text when selection across two p', async () => { @@ -729,14 +756,14 @@ describe('Paste', () => { stepFunction: async editor => { await pasteHtml(editor, complexHtmlData); }, - contentAfter: '<div>a<p>b1<b style="font-weight: bolder">23</b> 4[]e</p>f</div>', + contentAfter: '<div>a<p>b1<b>23</b> 4[]e</p>f</div>', }); await testEditor(BasicEditor, { contentBefore: '<div>a<p>b[c</p>- -<p>d]e</p>f</div>', stepFunction: async editor => { await pasteHtml(editor, complexHtmlData); }, - contentAfter: '<div>a<p>b1<b style="font-weight: bolder">23</b> 4[]e</p>f</div>', + contentAfter: '<div>a<p>b1<b>23</b> 4[]e</p>f</div>', }); }); it('should paste a text when selection leave a span', async () => { @@ -745,14 +772,14 @@ describe('Paste', () => { stepFunction: async editor => { await pasteHtml(editor, complexHtmlData); }, - contentAfter: '<div>ab<span>c1<b style="font-weight: bolder">23</b> 4[]</span>f</div>', + contentAfter: '<div>ab<span>c1<b>23</b> 4[]</span>f</div>', }); await testEditor(BasicEditor, { contentBefore: '<div>a[b<span>c]d</span>ef</div>', stepFunction: async editor => { await pasteHtml(editor, complexHtmlData); }, - contentAfter: '<div>a1<b style="font-weight: bolder">23</b> 4[]<span>d</span>ef</div>', + contentAfter: '<div>a1<b>23</b> 4[]<span>d</span>ef</div>', }); }); it('should paste a text when selection across two element', async () => { @@ -761,21 +788,21 @@ describe('Paste', () => { stepFunction: async editor => { await pasteHtml(editor, complexHtmlData); }, - contentAfter: '<div>1a<p>b1<b style="font-weight: bolder">23</b> 4[]<span>e</span>f</p></div>', + contentAfter: '<div>1a<p>b1<b>23</b> 4[]<span>e</span>f</p></div>', }); await testEditor(BasicEditor, { contentBefore: '<div>2a<span>b[c</span><p>d]e</p>f</div>', stepFunction: async editor => { await pasteHtml(editor, complexHtmlData); }, - contentAfter: '<div>2a<span>b1<b style="font-weight: bolder">23</b> 4[]</span>e<br>f</div>', + contentAfter: '<div>2a<span>b1<b>23</b> 4[]</span>e<br>f</div>', }); await testEditor(BasicEditor, { contentBefore: '<div>3a<p>b[c</p><p>d]e</p>f</div>', stepFunction: async editor => { await pasteHtml(editor, complexHtmlData); }, - contentAfter: '<div>3a<p>b1<b style="font-weight: bolder">23</b> 4[]e</p>f</div>', + contentAfter: '<div>3a<p>b1<b>23</b> 4[]e</p>f</div>', }); }); }); diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/htmlTables.test.js b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/htmlTables.test.js index 19cc5204d131..f857f8075cfc 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/htmlTables.test.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/htmlTables.test.js @@ -221,24 +221,24 @@ describe('Paste HTML tables', () => { <tbody><tr> - <td class="" style="color: #495057;font-size: 10.0pt;font-style: italic"><span class="" style="color: #495057;font-size: 10.0pt;font-weight: 400;font-style: italic;text-decoration: none">Italic - then also </span><span class="" style="color: #495057;font-size: 10.0pt;font-weight: 700;font-style: italic;text-decoration: none">BOLD</span></td> - <td class="" style="color: #495057;font-size: 10.0pt;font-style: italic"><s>Italic strike</s></td> + <td class="">Italic + then also BOLD</td> + <td class=""><s>Italic strike</s></td> </tr> <tr> - <td class="" style="color: #495057;font-size: 10.0pt;font-weight: 700"><span class="" style="color: #495057;font-size: 10.0pt;font-weight: 700;font-style: normal;text-decoration: none">Just bold </span><span class="" style="color: #495057;font-size: 10.0pt;font-weight: 400;font-style: italic;text-decoration: none">Just Italic</span></td> - <td class="" style="color: #495057;font-size: 10.0pt;font-weight: 700;text-decoration: underline">Bold underline</td> + <td class="">Just bold Just Italic</td> + <td class="">Bold underline</td> </tr> <tr> - <td class="" style="color: red;font-size: 10.0pt">Color text</td> - <td class="" style="color: red;font-size: 10.0pt;text-decoration: underline"><s>Color strike and underline</s></td> + <td class="">Color text</td> + <td class=""><s>Color strike and underline</s></td> </tr> <tr> - <td class="" style="color: #495057;font-size: 10.0pt;background-color: yellow">Color background</td> - <td class="" style="color: red;font-size: 10.0pt;background-color: yellow">Color text on color background</td> + <td class="">Color background</td> + <td class="">Color text on color background</td> </tr> <tr> - <td class="" style="font-size: 14.0pt">14pt MONO TEXT + <td class="">14pt MONO TEXT </td> </tr> </tbody></table><p> @@ -328,33 +328,33 @@ describe('Paste HTML tables', () => { <tbody> <tr> - <td style="font-weight:normal;font-style:italic;color:#495057"> - <span style="font-size:10pt;font-style:italic;color:#495057">Italic then also - </span><span style="font-size:10pt;font-weight:bold;font-style:italic;color:#495057">BOLD</span> + <td> + Italic then also + BOLD </td> - <td style="font-style:italic;text-decoration:line-through;color:#495057">Italic strike</td> + <td>Italic strike</td> </tr> <tr> - <td style="font-weight:bold;color:#495057"> - <span style="font-size:10pt;font-weight:bold;font-style:normal;color:#495057">Just - Bold </span><span style="font-size:10pt;font-style:italic;color:#495057">Just - Italic</span> + <td> + Just + Bold Just + Italic </td> - <td style="font-weight:bold;text-decoration:underline;color:#495057">Bold underline</td> + <td>Bold underline</td> </tr> <tr> - <td><span style="color:#ff0000">Color text</span></td> - <td style="text-decoration:underline line-through;color:#ff0000">Color + <td>Color text</td> + <td>Color strike and underline</td> </tr> <tr> - <td style="background-color:#ffff00;font-weight:normal;color:#495057">Color background + <td>Color background </td> - <td style="background-color:#ffff00;color:#ff0000">Color + <td>Color text on color background</td> </tr> <tr> - <td style="font-size:14pt;font-weight:normal">14pt MONO TEXT</td> + <td>14pt MONO TEXT</td> </tr> </tbody> </table><p> @@ -471,21 +471,21 @@ describe('Paste HTML tables', () => { </tr> <tr> <td> - <font style="color: rgb(255, 0, 0)">Color text</font> + Color text </td> <td><u><s> - <font style="color: rgb(255, 0, 0)">Color strike and underline</font> + Color strike and underline </s></u></td> </tr> <tr> - <td style="background-color: rgb(255, 255, 0)">Color background</td> - <td style="background-color: rgb(255, 255, 0)"> - <font style="color: rgb(255, 0, 0)">Color text on color background</font> + <td>Color background</td> + <td> + Color text on color background </td> </tr> <tr> <td> - <font style="font-size: 14pt">14pt MONO TEXT</font> + 14pt MONO TEXT </td> </tr> </tbody></table><p> diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/list.test.js b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/list.test.js index 170f23f1a87f..d3c9e39337c7 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/list.test.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/list.test.js @@ -2676,7 +2676,7 @@ describe('List', () => { stepFunction: deleteForward, // Paragraphs in list items are treated as nonsense. contentAfter: - '<ul><li><p>abc</p></li><li><p>def[]ghi</p></li><li><p>klm</p></li></ul>', + '<ul><li>abc</li><li>def[]ghi</li><li>klm</li></ul>', }); await testEditor(BasicEditor, { contentBefore: @@ -2697,7 +2697,7 @@ describe('List', () => { // Two paragraphs in a checklist item = Two list items. // Paragraphs in list items are treated as nonsense. contentAfter: - '<ul class="o_checklist"><li class="o_checked"><p>abc</p></li><li><p><b>de</b>fg[]<b>hij</b>klm</p></li><li class="o_checked"><p>nop</p></li></ul>', + '<ul class="o_checklist"><li class="o_checked">abc</li><li><b>de</b>fg[]<b>hij</b>klm</li><li class="o_checked">nop</li></ul>', }); }); it('should treat two blocks in a checklist item and keep the blocks', async () => { @@ -2707,7 +2707,7 @@ describe('List', () => { '<ul class="o_checklist"><li class="o_checked"><p>abc</p></li><li><p>def[]</p><p>ghi</p></li><li class="o_checked"><p>klm</p></li></ul>', stepFunction: deleteForward, contentAfter: - '<ul class="o_checklist"><li class="o_checked"><p>abc</p></li><li><p>def[]ghi</p></li><li class="o_checked"><p>klm</p></li></ul>', + '<ul class="o_checklist"><li class="o_checked">abc</li><li>def[]ghi</li><li class="o_checked">klm</li></ul>', }); await testEditor(BasicEditor, { removeCheckIds: true, @@ -2725,7 +2725,7 @@ describe('List', () => { '<ul><li><p>abc</p></li><li><p><b>de</b>fg[]</p><p><b>hij</b>klm</p></li><li><p>nop</p></li></ul>', stepFunction: deleteForward, contentAfter: - '<ul><li><p>abc</p></li><li><p><b>de</b>fg[]<b>hij</b>klm</p></li><li><p>nop</p></li></ul>', + '<ul><li>abc</li><li><b>de</b>fg[]<b>hij</b>klm</li><li>nop</li></ul>', }); }); }); @@ -4839,7 +4839,7 @@ describe('List', () => { await deleteBackward(editor); await deleteBackward(editor); }, - contentAfter: '<ul><li><p>a[]b</p></li></ul>', + contentAfter: '<ul><li>a[]b</li></ul>', }); await testEditor(BasicEditor, { contentBefore: @@ -4848,7 +4848,7 @@ describe('List', () => { await deleteBackward(editor); await deleteBackward(editor); }, - contentAfter: '<ul><li><p>a[]b</p></li></ul>', + contentAfter: '<ul><li>a[]b</li></ul>', }); }); it('should merge an ordered list item that is in an unordered list item into a non-indented list item', async () => { @@ -4945,7 +4945,7 @@ describe('List', () => { await deleteBackward(editor); await deleteBackward(editor); }, - contentAfter: '<ol><li><p>a[]b</p></li></ol>', + contentAfter: '<ol><li>a[]b</li></ol>', }); await testEditor(BasicEditor, { contentBefore: @@ -4954,7 +4954,7 @@ describe('List', () => { await deleteBackward(editor); await deleteBackward(editor); }, - contentAfter: '<ol><li><p>a[]b</p></li></ol>', + contentAfter: '<ol><li>a[]b</li></ol>', }); }); it('should merge an unordered list item that is in an ordered list item into a non-indented list item', async () => { @@ -5072,7 +5072,7 @@ describe('List', () => { await deleteBackward(editor); await deleteBackward(editor); }, - contentAfter: '<ul><li><p>a[]b</p></li></ul>', + contentAfter: '<ul><li>a[]b</li></ul>', }); await testEditor(BasicEditor, { contentBefore: @@ -5081,7 +5081,7 @@ describe('List', () => { await deleteBackward(editor); await deleteBackward(editor); }, - contentAfter: '<ul><li><p>a[]b</p></li></ul>', + contentAfter: '<ul><li>a[]b</li></ul>', }); }); it('should merge an checklist list item that is in an unordered list item into a non-indented list item', async () => { @@ -5195,7 +5195,7 @@ describe('List', () => { }, // Paragraphs in list items are kept unless empty contentAfter: - '<ul class="o_checklist"><li class="o_checked"><p>a[]b</p></li></ul>', + '<ul class="o_checklist"><li class="o_checked">a[]b</li></ul>', }); await testEditor(BasicEditor, { removeCheckIds: true, @@ -5207,7 +5207,7 @@ describe('List', () => { }, // Paragraphs in list items are kept unless empty contentAfter: - '<ul class="o_checklist"><li class="o_checked"><p>a[]b</p></li></ul>', + '<ul class="o_checklist"><li class="o_checked">a[]b</li></ul>', }); }); it('should merge an unordered list item that is in an checklist list item into a non-indented list item', async () => { @@ -5338,7 +5338,7 @@ describe('List', () => { stepFunction: deleteBackward, // Paragraphs in list items are treated as nonsense. contentAfter: - '<ol><li><p>abc</p></li><li><p>def[]ghi</p></li><li><p>klm</p></li></ol>', + '<ol><li>abc</li><li>def[]ghi</li><li>klm</li></ol>', }); await testEditor(BasicEditor, { contentBefore: @@ -5358,7 +5358,7 @@ describe('List', () => { // Two paragraphs in a list item = Two list items. // Paragraphs in list items are treated as nonsense. contentAfter: - '<ol><li><p>abc</p></li><li><p><b>de</b>fg[]<b>hij</b>klm</p></li><li><p>nop</p></li></ol>', + '<ol><li>abc</li><li><b>de</b>fg[]<b>hij</b>klm</li><li>nop</li></ol>', }); }); it('should treat two blocks in a list item and keep blocks', async () => { @@ -5368,7 +5368,7 @@ describe('List', () => { stepFunction: deleteBackward, // Paragraphs in list items are treated as nonsense. contentAfter: - '<ul><li><p>abc</p></li><li><p>def[]ghi</p></li><li><p>klm</p></li></ul>', + '<ul><li>abc</li><li>def[]ghi</li><li>klm</li></ul>', }); await testEditor(BasicEditor, { contentBefore: @@ -5388,7 +5388,7 @@ describe('List', () => { // Two paragraphs in a list item = Two list items. // Paragraphs in list items are treated as nonsense. contentAfter: - '<ul><li><p>abc</p></li><li><p><b>de</b>fg[]<b>hij</b>klm</p></li><li><p>nop</p></li></ul>', + '<ul><li>abc</li><li><b>de</b>fg[]<b>hij</b>klm</li><li>nop</li></ul>', }); }); it('should treat two blocks in a list item and keep blocks', async () => { @@ -5399,7 +5399,7 @@ describe('List', () => { stepFunction: deleteBackward, // Paragraphs in list items are treated as nonsense. contentAfter: - '<ul class="o_checklist"><li class="o_checked"><p>abc</p></li><li class="o_checked"><p>def[]ghi</p></li><li class="o_checked"><p>klm</p></li></ul>', + '<ul class="o_checklist"><li class="o_checked">abc</li><li class="o_checked">def[]ghi</li><li class="o_checked">klm</li></ul>', }); await testEditor(BasicEditor, { removeCheckIds: true, @@ -5421,7 +5421,7 @@ describe('List', () => { // Two paragraphs in a list item = Two list items. // Paragraphs in list items are treated as nonsense. contentAfter: - '<ul class="o_checklist"><li class="o_checked"><p>abc</p></li><li class="o_checked"><p><b>de</b>fg[]<b>hij</b>klm</p></li><li class="o_checked"><p>nop</p></li></ul>', + '<ul class="o_checklist"><li class="o_checked">abc</li><li class="o_checked"><b>de</b>fg[]<b>hij</b>klm</li><li class="o_checked">nop</li></ul>', }); }); }); -- GitLab