[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:
@@ -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', () => {
|
||||
|
||||
Reference in New Issue
Block a user