[FIX] web_editor: power box disappears in collaborative fix

Before this commit:

Power box uses Patience diff algorithm to check the text added by the user for
search, it previously used the entire editable for differences, which caused
the issue in collaborative. When one user type something on a different node,
the change would affect the editable and be considered in diff, causing updates
in other users powerbox.

After this commit:

Instead of checking the entire editable for the diff, we now check the current
block node where the power box was opened. This prevents scenarios where other
users powerbox would update when one user would type on same block node.

task-3212128

X-original-commit: 976c10b749e59963c8a27ac4764f1746d46d5e09
Part-of: odoo/odoo#141785
This commit is contained in:
Deependra Solanki
2023-11-20 11:13:17 +00:00
parent 01ad9b9213
commit 1f4bb22d8e
2 changed files with 24 additions and 2 deletions
@@ -1,6 +1,6 @@
/** @odoo-module **/
import { patienceDiff } from './patienceDiff.js';
import { getRangePosition } from '../utils/utils.js';
import { closestBlock, getRangePosition } from '../utils/utils.js';
const REGEX_RESERVED_CHARS = /[\\^$.*+?()[\]{}|]/g;
/**
@@ -114,9 +114,11 @@ export class Powerbox {
commands = commands.filter(command => !command.isDisabled || !command.isDisabled()).sort(order);
commands = this._groupCommands(commands, categories).flatMap(group => group[1]);
const selection = this.document.getSelection();
const currentBlock = (selection && closestBlock(selection.anchorNode)) || this.editable;
this._context = {
commands, categories, filteredCommands: commands, selectedCommand: undefined,
initialTarget: this.editable, initialValue: this.editable.textContent,
initialTarget: currentBlock, initialValue: currentBlock.textContent,
lastText: undefined,
}
this.isOpen = true;
@@ -33,6 +33,26 @@ describe('Powerbox', () => {
},
});
});
it('should not filter the powerbox contents when collaborator type on two different blocks', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>ab</p><p>c[]d</p>',
stepFunction: async editor => {
await insertText(editor, '/');
await insertText(editor, 'heading');
setSelection(editor.editable.firstChild, 1);
window.chai.expect(editor.powerbox.isOpen).to.be.true;
// Mimick a collaboration scenario where another user types
// random text, using `insert` as it won't trigger keyup.
editor.execCommand('insert', 'random text');
window.chai.expect(editor.powerbox.isOpen).to.be.true;
setSelection(editor.editable.lastChild, 9);
window.chai.expect(editor.powerbox.isOpen).to.be.true;
await insertText(editor, '1');
window.chai.expect(editor.powerbox.isOpen).to.be.true;
window.chai.expect(getCurrentCommandNames(editor.powerbox)).to.eql(['Heading 1']);
},
});
});
it('should execute command and remove term and hot character on Enter', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>ab[]</p>',