232 lines
8.6 KiB
JavaScript
232 lines
8.6 KiB
JavaScript
/** @odoo-module **/
|
|
|
|
import { _t } from "@web/core/l10n/translation";
|
|
import snippetsEditor from "@web_editor/js/editor/snippets.editor";
|
|
import { MassMailingMobilePreviewDialog } from "./mass_mailing_mobile_preview";
|
|
import { markup, useEffect, useState } from "@odoo/owl";
|
|
|
|
export class MassMailingSnippetsMenu extends snippetsEditor.SnippetsMenu {
|
|
static tabs = Object.assign({}, snippetsEditor.SnippetsMenu.tabs, {
|
|
DESIGN: 'design',
|
|
});
|
|
static optionsTabStructure = [
|
|
['design-options', _t("Design Options")],
|
|
];
|
|
|
|
static template = "mass_mailing.SnippetsMenu";
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Public
|
|
//--------------------------------------------------------------------------
|
|
|
|
/**
|
|
* @override
|
|
*/
|
|
setup() {
|
|
super.setup();
|
|
this.fieldConfig = useState(this.env.fieldConfig);
|
|
|
|
let firstRender = true;
|
|
useEffect(
|
|
(selectedTheme) => {
|
|
// Avoid running this on first render as the template is already
|
|
// loaded for the selected theme by the normal flow.
|
|
if (firstRender) {
|
|
firstRender = false;
|
|
return;
|
|
}
|
|
this._loadSnippetsTemplates().then(() => {
|
|
this.reloadSnippetDropzones();
|
|
});
|
|
},
|
|
() => [this.fieldConfig.selectedTheme]
|
|
);
|
|
// When the scrollable changes, it invalidates the current drag and
|
|
// drop config. In the case of the snippetsMenu, it can be altered,
|
|
// But in the case of snippetEditor, destroying them should be good
|
|
// enough.
|
|
useEffect(
|
|
($scrollable) => {
|
|
this._mutex.exec(async () => {
|
|
this.options.$scrollable = $scrollable;
|
|
this._makeSnippetDraggable();
|
|
await this._destroyEditors();
|
|
});
|
|
},
|
|
() => [this.fieldConfig.$scrollable]
|
|
);
|
|
}
|
|
/**
|
|
* @override
|
|
*/
|
|
start() {
|
|
return super.start().then(() => {
|
|
this.$editable = this.options.wysiwyg.getEditable();
|
|
});
|
|
}
|
|
/**
|
|
* @override
|
|
*/
|
|
async callPostSnippetDrop($target) {
|
|
$target.find('img[loading=lazy]').removeAttr('loading');
|
|
return super.callPostSnippetDrop(...arguments);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Private
|
|
//--------------------------------------------------------------------------
|
|
|
|
/**
|
|
* @override
|
|
*/
|
|
_computeSnippetTemplates(html) {
|
|
this.env.switchImages(this.fieldConfig.selectedTheme, $(html));
|
|
html.querySelectorAll('img').forEach(img => img.setAttribute("loading", "lazy"));
|
|
// TODO: Remove in master and remove the background filter from the snippet
|
|
const cover_snippet = html.querySelector("[data-oe-type='snippet'] [data-snippet='s_cover']");
|
|
if (cover_snippet) {
|
|
cover_snippet.querySelector('.o_we_bg_filter.bg-black-50').remove();
|
|
cover_snippet.querySelector('h1').classList.remove("text-white");
|
|
cover_snippet.querySelector('p').classList.remove("text-white");
|
|
}
|
|
return super._computeSnippetTemplates(html);
|
|
}
|
|
/**
|
|
* @override
|
|
*/
|
|
_onClick(ev) {
|
|
super._onClick(...arguments);
|
|
var srcElement = ev.target || (ev.originalEvent && (ev.originalEvent.target || ev.originalEvent.originalTarget)) || ev.srcElement;
|
|
// When we select something and move our cursor too far from the editable area, we get the
|
|
// entire editable area as the target, which causes the tab to shift from OPTIONS to BLOCK.
|
|
// To prevent unnecessary tab shifting, we provide a selection for this specific case.
|
|
if (srcElement.classList.contains('o_mail_wrapper') || srcElement.querySelector('.o_mail_wrapper')) {
|
|
const selection = this.options.wysiwyg.odooEditor.document.getSelection();
|
|
if (selection.anchorNode) {
|
|
const parent = selection.anchorNode.parentElement;
|
|
if (parent) {
|
|
srcElement = parent;
|
|
}
|
|
this._activateSnippet($(srcElement));
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* @override
|
|
*/
|
|
_insertDropzone($hook) {
|
|
const $hookParent = $hook.parent();
|
|
const $dropzone = super._insertDropzone(...arguments);
|
|
$dropzone.attr('data-editor-message', $hookParent.attr('data-editor-message'));
|
|
$dropzone.attr('data-editor-sub-message', $hookParent.attr('data-editor-sub-message'));
|
|
return $dropzone;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Handler
|
|
//--------------------------------------------------------------------------
|
|
|
|
/**
|
|
* @override
|
|
*/
|
|
_onDropZoneOver() {
|
|
this.$editable.find('.o_editable').css('background-color', '');
|
|
}
|
|
/**
|
|
* @override
|
|
*/
|
|
_onDropZoneOut() {
|
|
const $oEditable = this.$editable.find('.o_editable');
|
|
if ($oEditable.find('.oe_drop_zone.oe_insert:not(.oe_vertical):only-child').length) {
|
|
$oEditable[0].style.setProperty('background-color', 'transparent', 'important');
|
|
}
|
|
}
|
|
/**
|
|
* @override
|
|
*/
|
|
_onDropZoneStart() {
|
|
const $oEditable = this.$editable.find('.o_editable');
|
|
if ($oEditable.find('.oe_drop_zone.oe_insert:not(.oe_vertical):only-child').length) {
|
|
$oEditable[0].style.setProperty('background-color', 'transparent', 'important');
|
|
}
|
|
}
|
|
/**
|
|
* @override
|
|
*/
|
|
_onDropZoneStop() {
|
|
const $oEditable = this.$editable.find('.o_editable');
|
|
$oEditable.css('background-color', '');
|
|
if (!$oEditable.find('.oe_drop_zone.oe_insert:not(.oe_vertical):only-child').length) {
|
|
$oEditable.attr('contenteditable', true);
|
|
}
|
|
// Refocus again to save updates when calling `_onWysiwygBlur`
|
|
this.$editable.focus();
|
|
}
|
|
/**
|
|
* @override
|
|
*/
|
|
_onSnippetRemoved() {
|
|
super._onSnippetRemoved(...arguments);
|
|
const $oEditable = this.$editable.find('.o_editable');
|
|
if (!$oEditable.children().length) {
|
|
$oEditable.empty(); // remove any superfluous whitespace
|
|
$oEditable.attr('contenteditable', false);
|
|
}
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
_onDesignTabClick() {
|
|
this._enableFakeOptionsTab(MassMailingSnippetsMenu.tabs.DESIGN);
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
_onFullscreenBtnClick(ev) {
|
|
$("body").toggleClass("o_field_widgetTextHtml_fullscreen");
|
|
const full = $("body").hasClass("o_field_widgetTextHtml_fullscreen");
|
|
$(window).trigger("resize"); // induce a resize() call and let other backend elements know (the navbar extra items management relies on this)
|
|
if (this.env.onToggleFullscreen) {
|
|
// `onToggleFullscreen` in the `env` is deprecated, use the wysiwyg function instead
|
|
this.env.onToggleFullscreen();
|
|
}
|
|
this.options.wysiwyg.onToggleFullscreen?.(full);
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
_onCodeViewBtnClick(ev) {
|
|
const $codeview = this.options.wysiwyg.$iframe.contents().find("textarea.o_codeview");
|
|
this.options.wysiwyg.odooEditor.observerUnactive();
|
|
$codeview.toggleClass("d-none");
|
|
this.options.wysiwyg.getEditable().toggleClass("d-none");
|
|
this.options.wysiwyg.odooEditor.observerActive();
|
|
|
|
if ($codeview.hasClass("d-none")) {
|
|
this.options.wysiwyg.setValue(this.options.getCodeViewValue($codeview[0]));
|
|
this.options.wysiwyg.odooEditor.sanitize();
|
|
this.options.wysiwyg.odooEditor.historyStep(true);
|
|
} else {
|
|
$codeview.val(this.options.wysiwyg.getValue());
|
|
}
|
|
this.activateSnippet(false);
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
_onMobilePreviewBtnClick(ev) {
|
|
const btn = ev.target.closest(".btn");
|
|
btn.setAttribute("disabled", true); // Prevent double execution when double-clicking on the button
|
|
const mailingHtml = new DOMParser().parseFromString(this.options.wysiwyg.getValue(), "text/html");
|
|
[...mailingHtml.querySelectorAll("a")].forEach(el => {
|
|
el.style.setProperty("pointer-events", "none");
|
|
});
|
|
this.mobilePreview = this.dialog.add(MassMailingMobilePreviewDialog, {
|
|
title: _t("Mobile Preview"),
|
|
preview: markup(mailingHtml.body.innerHTML),
|
|
}, {
|
|
onClose: () => btn.removeAttribute("disabled"),
|
|
});
|
|
}
|
|
}
|