[FIX] web_editor: paste odoo-editor html in iframe
Before this commit, pasting html content that had been copied from the the Editor failed to paste any content when inside an iframe. This happened because the DOMPurify library was not configured to use the iframe's window for Node prototypes, which led `instanceof` checks to fail, removing nodes a result. Additionally, commit [1] did not do the job completely: while the document for creating the document fragment became the one received as parameter, the DOMParser constructor remained the one from the window in which the JS code is executed, which might be different from the received document's window. This mismatch happens in particularly when the editable is inside an iframe. task-3575496 [1]: https://github.com/odoo/odoo/commit/c74d01279e49fadc5f509cfc3f6baf43d2b532d1 closes odoo/odoo#144744 Signed-off-by: Geelen Sébastien (sge) <sge@odoo.com>
This commit is contained in:
@@ -4748,7 +4748,9 @@ export class OdooEditor extends EventTarget {
|
||||
}
|
||||
if (odooEditorHtml && targetSupportsHtmlContent) {
|
||||
const fragment = parseHTML(this.document, odooEditorHtml);
|
||||
DOMPurify.sanitize(fragment, { IN_PLACE: true });
|
||||
// Instantiate DOMPurify with the correct window.
|
||||
this.DOMPurify ??= DOMPurify(this.document.defaultView);
|
||||
this.DOMPurify.sanitize(fragment, { IN_PLACE: true });
|
||||
if (fragment.hasChildNodes()) {
|
||||
this._applyCommand('insert', fragment);
|
||||
}
|
||||
|
||||
@@ -2725,7 +2725,7 @@ export function rgbToHex(rgb = '', node = null) {
|
||||
|
||||
export function parseHTML(document, html) {
|
||||
const fragment = document.createDocumentFragment();
|
||||
const parser = new DOMParser();
|
||||
const parser = new document.defaultView.DOMParser();
|
||||
const parsedDocument = parser.parseFromString(html, 'text/html');
|
||||
fragment.replaceChildren(...parsedDocument.body.childNodes);
|
||||
return fragment;
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
pasteHtml,
|
||||
pasteOdooEditorHtml,
|
||||
} from "../utils.js";
|
||||
import {CLIPBOARD_WHITELISTS} from "../../src/OdooEditor.js";
|
||||
import { CLIPBOARD_WHITELISTS, setSelection } from "../../src/OdooEditor.js";
|
||||
|
||||
describe('Copy', () => {
|
||||
describe('range collapsed', async () => {
|
||||
@@ -2219,4 +2219,33 @@ describe('Paste', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('editable in iframe', () => {
|
||||
it('should paste odoo-editor html', async () => {
|
||||
// Setup
|
||||
const testContainer = document.querySelector('#editor-test-container');
|
||||
const iframe = document.createElement('iframe');
|
||||
testContainer.append(iframe);
|
||||
const iframeDocument = iframe.contentDocument;
|
||||
const editable = iframeDocument.createElement('div');
|
||||
iframeDocument.body.append(editable);
|
||||
const editor = new BasicEditor(editable, { document: iframeDocument });
|
||||
|
||||
// Action: paste
|
||||
setSelection(editable.querySelector('p'), 0);
|
||||
const clipboardData = new DataTransfer();
|
||||
clipboardData.setData('text/odoo-editor', '<p>text<b>bold text</b>more text</p>');
|
||||
await triggerEvent(editor.editable, 'paste', { clipboardData });
|
||||
|
||||
// Clean-up
|
||||
editor.clean();
|
||||
editor.destroy();
|
||||
iframe.remove();
|
||||
|
||||
// Assertion
|
||||
window.chai.expect(editable.innerHTML).to.be.equal(
|
||||
'<p>text<b>bold text</b>more text<br></p>',
|
||||
'should paste content in the paragraph'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user