[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) <age@odoo.com>
Signed-off-by: Deependra Solanki (deso) <deso@odoo.com>
This commit is contained in:
Deependra Solanki
2024-02-02 05:33:08 +00:00
parent 215343379c
commit 423a479ca7
2 changed files with 67 additions and 5 deletions
@@ -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 => {
@@ -5426,6 +5426,15 @@ describe('List', () => {
'<h1>a[]i</h1><custom-block style="display: block;"><ol><li>jk</li></ol></custom-block>',
});
});
it('should not join the next list with the first one on delete range', async () => {
await testEditor(BasicEditor, {
contentBefore:
'<ol><li>ab</li><li>[cd</li><li>ef]</li><li>gh</li></ol>',
stepFunction: deleteBackward,
contentAfter:
'<ol><li>ab</li><li>[]<br></li><li>gh</li></ol>',
});
});
});
describe('Unordered', () => {
it('should delete text within a list item', async () => {
@@ -5518,6 +5527,15 @@ describe('List', () => {
'<h1>a[]i</h1><custom-block style="display: block;"><ul><li>jk</li></ul></custom-block>',
});
});
it('should not join the next list with the first one on delete range', async () => {
await testEditor(BasicEditor, {
contentBefore:
'<ul><li>ab</li><li>[cd</li><li>ef]</li><li>gh</li></ul>',
stepFunction: deleteBackward,
contentAfter:
'<ul><li>ab</li><li>[]<br></li><li>gh</li></ul>',
});
});
});
describe('Checklist', () => {
it('should delete text within a checklist item', async () => {
@@ -5678,6 +5696,36 @@ describe('List', () => {
'<h1>a[]i</h1><custom-block style="display:block;"><ul class="o_checklist"><li class="o_checked">jk</li></ul></custom-block>',
});
});
it('should not join the next list with the first one on delete range', async () => {
await testEditor(BasicEditor, {
removeCheckIds: true,
contentBefore:
'<ul class="o_checklist"><li>ab</li><li class="o_checked">[cd</li><li>ef]</li><li>gh</li></ul>',
stepFunction: deleteBackward,
contentAfter:
'<ul class="o_checklist"><li>ab</li><li>[]<br></li><li>gh</li></ul>',
});
});
it('should remove the o_checked class on delete range', async () => {
await testEditor(BasicEditor, {
removeCheckIds: true,
contentBefore:
'<ul class="o_checklist"><li>ab</li><li class="o_checked"><a href="#">[cd</a></li><li>ef]</li><li>gh</li></ul>',
stepFunction: deleteBackward,
contentAfter:
'<ul class="o_checklist"><li>ab</li><li>[]<br></li><li>gh</li></ul>',
});
});
it('should remove the o_checked class on delete range (2)', async () => {
await testEditor(BasicEditor, {
removeCheckIds: true,
contentBefore:
'<ul class="o_checklist"><li>ab</li><li class="o_checked"><h1>[cd</h1></li><li>ef]</li><li>gh</li></ul>',
stepFunction: deleteBackward,
contentAfter:
'<ul class="o_checklist"><li>ab</li><li><h1>[]<br></h1></li><li>gh</li></ul>',
});
});
});
describe('Mixed', () => {
describe('Ordered to unordered', () => {