From 423a479ca7469af11b0d0803e789a7d7a516c4ff Mon Sep 17 00:00:00 2001 From: Deependra Solanki Date: Fri, 1 Sep 2023 16:48:15 +0530 Subject: [PATCH] [FIX] web_editor: fix checklist strike through issue Before this commit: When in a checklist where first and second checklist are marked done after selecting first and second checklist and deleting it the third checklist would be marked as done. After this commit: Deleting previous done checklist would not affect the current checklist. task-3203889 closes odoo/odoo#152387 X-original-commit: 2ddda7a66076ef99e1aa4ba9d463b0fd2f73626d Signed-off-by: Antoine Guenet (age) Signed-off-by: Deependra Solanki (deso) --- .../js/editor/odoo-editor/src/OdooEditor.js | 24 ++++++++-- .../editor/odoo-editor/test/spec/list.test.js | 48 +++++++++++++++++++ 2 files changed, 67 insertions(+), 5 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 6abe41ccd45..d02e4bc94f9 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 @@ -2172,6 +2172,10 @@ export class OdooEditor extends EventTarget { } } let insertedZws; + let { startContainer: start, startOffset, endContainer: end, endOffset } = range; + const startBlock = closestBlock(start); + const endBlock = closestBlock(end); + const [firstLeafOfStartBlock, lastLeafOfEndBlock] = [firstLeaf(startBlock), lastLeaf(endBlock)]; if (sel && !sel.isCollapsed && !range.startOffset && !range.startContainer.previousSibling) { // Insert a zero-width space before the selection if the selection // is non-collapsed and at the beginning of its parent, so said @@ -2184,12 +2188,16 @@ export class OdooEditor extends EventTarget { range.startContainer.before(zws); insertedZws = zws; } - let { startContainer: start, startOffset, endContainer: end, endOffset } = range; - const [startBlock, endBlock] = [closestBlock(start), closestBlock(end)]; + // Do not join blocks in the following cases: + // 1. start and end share a common ancestor block with the range + // 2. selection spans multiple TDs + // 3. selection starts at beginning of startBlock and ends at end of + // endBlock const doJoin = - (startBlock !== closestBlock(range.commonAncestorContainer) || - endBlock !== closestBlock(range.commonAncestorContainer)) - && (startBlock.tagName !== 'TD' && endBlock.tagName !== 'TD'); + !(startBlock === closestBlock(range.commonAncestorContainer) && + endBlock === closestBlock(range.commonAncestorContainer)) + && (startBlock.tagName !== 'TD' && endBlock.tagName !== 'TD') + && !(firstLeafOfStartBlock === start && lastLeafOfEndBlock === end); let next = nextLeaf(end, this.editable); // Get the boundaries of the range so as to get the state to restore. @@ -2210,6 +2218,12 @@ export class OdooEditor extends EventTarget { const contents = range.extractContents(); setSelection(start, nodeSize(start)); + const startLi = closestElement(start, 'li'); + // Uncheck a list item with empty text in multi-list selection. + if (startLi && startLi.classList.contains('o_checked') && + startLi.textContent === '\u200B' && closestElement(end, 'li') !== startLi) { + startLi.classList.remove('o_checked'); + } range = getDeepRange(this.editable, { sel }); // Restore unremovables removed by extractContents. [...contents.querySelectorAll('*')].filter(isUnremovable).forEach(n => { 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 d7b7852160e..8bd7e368438 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 @@ -5426,6 +5426,15 @@ describe('List', () => { '

a[]i

  1. jk
', }); }); + it('should not join the next list with the first one on delete range', async () => { + await testEditor(BasicEditor, { + contentBefore: + '
  1. ab
  2. [cd
  3. ef]
  4. gh
', + stepFunction: deleteBackward, + contentAfter: + '
  1. ab
  2. []
  3. gh
', + }); + }); }); describe('Unordered', () => { it('should delete text within a list item', async () => { @@ -5518,6 +5527,15 @@ describe('List', () => { '

a[]i

  • jk
', }); }); + it('should not join the next list with the first one on delete range', async () => { + await testEditor(BasicEditor, { + contentBefore: + '
  • ab
  • [cd
  • ef]
  • gh
', + stepFunction: deleteBackward, + contentAfter: + '
  • ab
  • []
  • gh
', + }); + }); }); describe('Checklist', () => { it('should delete text within a checklist item', async () => { @@ -5678,6 +5696,36 @@ describe('List', () => { '

a[]i

  • jk
', }); }); + it('should not join the next list with the first one on delete range', async () => { + await testEditor(BasicEditor, { + removeCheckIds: true, + contentBefore: + '
  • ab
  • [cd
  • ef]
  • gh
', + stepFunction: deleteBackward, + contentAfter: + '
  • ab
  • []
  • gh
', + }); + }); + it('should remove the o_checked class on delete range', async () => { + await testEditor(BasicEditor, { + removeCheckIds: true, + contentBefore: + '', + stepFunction: deleteBackward, + contentAfter: + '
  • ab
  • []
  • gh
', + }); + }); + it('should remove the o_checked class on delete range (2)', async () => { + await testEditor(BasicEditor, { + removeCheckIds: true, + contentBefore: + '
  • ab
  • [cd

  • ef]
  • gh
', + stepFunction: deleteBackward, + contentAfter: + '
  • ab
  • []

  • gh
', + }); + }); }); describe('Mixed', () => { describe('Ordered to unordered', () => {