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', () => { '