From 3046f7ab9d92ad47aef33b3200806afb9a43d4d2 Mon Sep 17 00:00:00 2001 From: abd-msyukyu-odoo Date: Fri, 15 Sep 2023 12:39:14 +0200 Subject: [PATCH] [IMP] web, web_editor: knowledge file command overhaul preparations - Allow providing a custom `MediaDialog` class through `openMediaDialog` to allow Knowledge custom behaviors. - Export the rendering part of `save` for the `MediaDialog` so it can be overridden. task-3172056 Part-of: odoo/odoo#127021 --- .../components/media_dialog/media_dialog.js | 161 ++++++++++-------- .../static/src/js/wysiwyg/wysiwyg.js | 3 +- 2 files changed, 88 insertions(+), 76 deletions(-) diff --git a/addons/web_editor/static/src/components/media_dialog/media_dialog.js b/addons/web_editor/static/src/components/media_dialog/media_dialog.js index cb1cc65bfc1..f71f517d0e2 100644 --- a/addons/web_editor/static/src/components/media_dialog/media_dialog.js +++ b/addons/web_editor/static/src/components/media_dialog/media_dialog.js @@ -132,6 +132,91 @@ export class MediaDialog extends Component { } } + /** + * Render the selected media for insertion in the editor + * + * @param {Array} selectedMedia + * @returns {Array} + */ + async renderMedia(selectedMedia) { + const elements = await TABS[this.state.activeTab].Component.createElements(selectedMedia, { rpc: this.rpc, orm: this.orm }); + elements.forEach(element => { + if (this.props.media) { + element.classList.add(...this.props.media.classList); + const style = this.props.media.getAttribute('style'); + if (style) { + element.setAttribute('style', style); + } + if (this.state.activeTab === TABS.IMAGES.id) { + if (this.props.media.dataset.shape) { + element.dataset.shape = this.props.media.dataset.shape; + } + if (this.props.media.dataset.shapeColors) { + element.dataset.shapeColors = this.props.media.dataset.shapeColors; + } + if (this.props.media.dataset.shapeFlip) { + element.dataset.shapeFlip = this.props.media.dataset.shapeFlip; + } + if (this.props.media.dataset.shapeRotate) { + element.dataset.shapeRotate = this.props.media.dataset.shapeRotate; + } + if (this.props.media.dataset.hoverEffect) { + element.dataset.hoverEffect = this.props.media.dataset.hoverEffect; + } + if (this.props.media.dataset.hoverEffectColor) { + element.dataset.hoverEffectColor = this.props.media.dataset.hoverEffectColor; + } + if (this.props.media.dataset.hoverEffectStrokeWidth) { + element.dataset.hoverEffectStrokeWidth = this.props.media.dataset.hoverEffectStrokeWidth; + } + if (this.props.media.dataset.hoverEffectIntensity) { + element.dataset.hoverEffectIntensity = this.props.media.dataset.hoverEffectIntensity; + } + } + } + for (const otherTab of Object.keys(TABS).filter(key => key !== this.state.activeTab)) { + for (const property of TABS[otherTab].Component.mediaSpecificStyles) { + element.style.removeProperty(property); + } + element.classList.remove(...TABS[otherTab].Component.mediaSpecificClasses); + const extraClassesToRemove = []; + for (const name of TABS[otherTab].Component.mediaExtraClasses) { + if (typeof(name) === 'string') { + extraClassesToRemove.push(name); + } else { // Regex + for (const className of element.classList) { + if (className.match(name)) { + extraClassesToRemove.push(className); + } + } + } + } + // Remove classes that do not also exist in the target type. + element.classList.remove(...extraClassesToRemove.filter(candidateName => { + for (const name of TABS[this.state.activeTab].Component.mediaExtraClasses) { + if (typeof(name) === 'string') { + if (candidateName === name) { + return false; + } + } else { // Regex + for (const className of element.classList) { + if (className.match(candidateName)) { + return false; + } + } + } + } + return true; + })); + } + element.classList.remove(...this.initialIconClasses); + element.classList.remove('o_modified_image_to_save'); + element.classList.remove('oe_edited_link'); + element.classList.add(...TABS[this.state.activeTab].Component.mediaSpecificClasses); + }); + return elements; + } + selectMedia(media, tabId, multiSelect) { if (multiSelect) { const isMediaSelected = this.selectedMedia[tabId].map(({ id }) => id).includes(media.id); @@ -159,81 +244,7 @@ export class MediaDialog extends Component { const saveSelectedMedia = selectedMedia.length && (this.state.activeTab !== TABS.ICONS.id || selectedMedia[0].initialIconChanged || !this.props.media); if (saveSelectedMedia) { - const elements = await TABS[this.state.activeTab].Component.createElements(selectedMedia, { rpc: this.rpc, orm: this.orm }); - elements.forEach(element => { - if (this.props.media) { - element.classList.add(...this.props.media.classList); - const style = this.props.media.getAttribute('style'); - if (style) { - element.setAttribute('style', style); - } - if (this.state.activeTab === TABS.IMAGES.id) { - if (this.props.media.dataset.shape) { - element.dataset.shape = this.props.media.dataset.shape; - } - if (this.props.media.dataset.shapeColors) { - element.dataset.shapeColors = this.props.media.dataset.shapeColors; - } - if (this.props.media.dataset.shapeFlip) { - element.dataset.shapeFlip = this.props.media.dataset.shapeFlip; - } - if (this.props.media.dataset.shapeRotate) { - element.dataset.shapeRotate = this.props.media.dataset.shapeRotate; - } - if (this.props.media.dataset.hoverEffect) { - element.dataset.hoverEffect = this.props.media.dataset.hoverEffect; - } - if (this.props.media.dataset.hoverEffectColor) { - element.dataset.hoverEffectColor = this.props.media.dataset.hoverEffectColor; - } - if (this.props.media.dataset.hoverEffectStrokeWidth) { - element.dataset.hoverEffectStrokeWidth = this.props.media.dataset.hoverEffectStrokeWidth; - } - if (this.props.media.dataset.hoverEffectIntensity) { - element.dataset.hoverEffectIntensity = this.props.media.dataset.hoverEffectIntensity; - } - } - } - for (const otherTab of Object.keys(TABS).filter(key => key !== this.state.activeTab)) { - for (const property of TABS[otherTab].Component.mediaSpecificStyles) { - element.style.removeProperty(property); - } - element.classList.remove(...TABS[otherTab].Component.mediaSpecificClasses); - const extraClassesToRemove = []; - for (const name of TABS[otherTab].Component.mediaExtraClasses) { - if (typeof(name) === 'string') { - extraClassesToRemove.push(name); - } else { // Regex - for (const className of element.classList) { - if (className.match(name)) { - extraClassesToRemove.push(className); - } - } - } - } - // Remove classes that do not also exist in the target type. - element.classList.remove(...extraClassesToRemove.filter(candidateName => { - for (const name of TABS[this.state.activeTab].Component.mediaExtraClasses) { - if (typeof(name) === 'string') { - if (candidateName === name) { - return false; - } - } else { // Regex - for (const className of element.classList) { - if (className.match(candidateName)) { - return false; - } - } - } - } - return true; - })); - } - element.classList.remove(...this.initialIconClasses); - element.classList.remove('o_modified_image_to_save'); - element.classList.remove('oe_edited_link'); - element.classList.add(...TABS[this.state.activeTab].Component.mediaSpecificClasses); - }); + const elements = await this.renderMedia(selectedMedia); if (this.props.multiImages) { this.props.save(elements); } else { diff --git a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js index f77d635e403..c6de341b79e 100644 --- a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js +++ b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js @@ -1496,6 +1496,7 @@ export class Wysiwyg extends Component { * @param {object} params * @param {Node} [params.node] Optionnal * @param {Node} [params.htmlClass] Optionnal + * @param {Class} [params.MediaDialog] Optional */ openMediaDialog(params = {}) { const sel = this.odooEditor.document.getSelection(); @@ -1512,7 +1513,7 @@ export class Wysiwyg extends Component { const editable = OdooEditorLib.closestElement(params.node || range.startContainer, '.o_editable') || this.odooEditor.editable; const { resModel, resId, field, type } = this._getRecordInfo(editable); - this.env.services.dialog.add(MediaDialog, { + this.env.services.dialog.add(params.MediaDialog || MediaDialog, { resModel, resId, useMediaLibrary: !!(field && (resModel === 'ir.ui.view' && field === 'arch' || type === 'html')),