[IMP] web_editor: prevent behaviors when an element is protected

In order to be able to create dynamic widgets to the editor, this
commit reinforce the concept of data-oe-protected by preventing the
default behavior for _applyRawCommand, on paste, on input and on
keydown.

closes odoo/odoo#141385

Signed-off-by: Geelen Sébastien (sge) <sge@odoo.com>
This commit is contained in:
Nicolas Bayet
2023-11-08 01:22:01 +00:00
parent 06bfcfff9a
commit d041044dbb
3 changed files with 18 additions and 4 deletions
@@ -2449,6 +2449,9 @@ export class OdooEditor extends EventTarget {
*/
_applyRawCommand(method, ...args) {
const sel = this.document.getSelection();
if (sel.anchorNode && isProtected(sel.anchorNode)) {
return;
}
if (
!(SELECTIONLESS_COMMANDS.includes(method) && args.length) && (
!this.editable.contains(sel.anchorNode) ||
@@ -3553,6 +3556,9 @@ export class OdooEditor extends EventTarget {
_onInput(ev) {
// See if the Powerbox should be opened. If so, it will open at the end.
const newSelection = this.document.getSelection();
if (newSelection.anchorNode && isProtected(newSelection.anchorNode)) {
return;
}
const shouldOpenPowerbox = newSelection.isCollapsed && newSelection.rangeCount &&
ev.data === '/' && this.powerbox && !this.powerbox.isOpen &&
(!this.options.getPowerboxElement || !!this.options.getPowerboxElement());
@@ -3792,6 +3798,10 @@ export class OdooEditor extends EventTarget {
* @private
*/
_onKeyDown(ev) {
const selection = this.document.getSelection();
if (selection.anchorNode && isProtected(selection.anchorNode)) {
return;
}
this.keyboardType =
ev.key === 'Unidentified' ? KEYBOARD_TYPES.VIRTUAL : KEYBOARD_TYPES.PHYSICAL;
this._currentKeyPress = ev.key;
@@ -4702,8 +4712,11 @@ export class OdooEditor extends EventTarget {
* Handle safe pasting of html or plain text into the editor.
*/
_onPaste(ev) {
ev.preventDefault();
const sel = this.document.getSelection();
if (sel.anchorNode && isProtected(sel.anchorNode)) {
return;
}
ev.preventDefault();
const files = getImageFiles(ev.clipboardData);
const odooEditorHtml = ev.clipboardData.getData('text/odoo-editor');
const clipboardHtml = ev.clipboardData.getData('text/html');
@@ -585,7 +585,8 @@ describe('Collaboration', () => {
clientInfos.c1.editor.historyStep();
const pTrue = clientInfos.c1.editor.editable.querySelector('#true');
setSelection(pTrue, 0);
clientInfos.c1.editor.execCommand('insert', 'a');
pTrue.prepend(clientInfos.c1.editor.document.createTextNode('a'));
clientInfos.c1.editor.historyStep();
const pFalse = clientInfos.c1.editor.editable.querySelector('#false');
setSelection(pFalse, 0);
clientInfos.c1.editor.execCommand('insert', 'a');
@@ -6739,8 +6739,8 @@ X[]
stepFunction: async editor => {
await insertText(editor, 'bc');
const protectedParagraph = editor.editable.querySelector('[data-oe-protected="true"] > p');
setSelection(protectedParagraph, 1);
await insertText(editor, 'b');
protectedParagraph.append(document.createTextNode('b'));
editor.historyStep();
editor.historyUndo();
},
contentAfterEdit: unformat(`