[IMP] web_editor,mass_mailing,website: lazy load wysiwyg

In order to improve the loading time of the odoo backend, only load
the wysiwyg before starting an html_field.

task-3493014

Part-of: odoo/odoo#134464
This commit is contained in:
Nicolas Bayet
2023-10-12 13:16:42 +00:00
parent 94fbc58c1b
commit fac09ae974
18 changed files with 79 additions and 69 deletions
+4
View File
@@ -134,6 +134,7 @@ For more specific needs, you may also assign custom-defined actions
'mail/static/src/core/web/**/*',
'mail/static/src/**/common/**/*',
'mail/static/src/**/web/**/*',
('remove', 'mail/static/src/core/web/wysiwyg.js'),
('remove', 'mail/static/src/**/*.dark.scss'),
# discuss (loaded last to fix dependencies)
('remove', 'mail/static/src/discuss/**/*'),
@@ -144,6 +145,9 @@ For more specific needs, you may also assign custom-defined actions
('remove', 'mail/static/src/discuss/**/*.dark.scss'),
'mail/static/src/views/fields/**/*',
],
'web_editor.backend_assets_wysiwyg': [
'mail/static/src/core/web/wysiwyg.js',
],
"web.assets_web_dark": [
'mail/static/src/**/*.dark.scss',
],
+2 -2
View File
@@ -96,7 +96,7 @@
('include', 'mass_mailing.assets_mail_themes'),
('include', 'web.assets_frontend'),
('after', 'web/static/lib/bootstrap/scss/_variables.scss', 'mass_mailing/static/src/scss/mass_mailing.ui.scss'),
('include', 'web_editor.assets_wysiwyg'),
('include', 'web_editor.backend_assets_wysiwyg'),
('include', 'web_editor.assets_legacy_wysiwyg'),
'mass_mailing/static/src/scss/mass_mailing_mail.scss',
@@ -115,7 +115,7 @@
'mass_mailing/static/src/xml/mailing_portal_subscription_feedback.xml',
'mass_mailing/static/src/xml/mailing_portal_subscription_form.xml',
],
'web_editor.assets_wysiwyg': [
'web_editor.backend_assets_wysiwyg': [
'mass_mailing/static/src/js/mass_mailing_wysiwyg.js',
'mass_mailing/static/src/scss/mass_mailing.wysiwyg.scss',
],
@@ -12,7 +12,6 @@ import { useService } from "@web/core/utils/hooks";
import { HtmlField, htmlField } from "@web_editor/js/backend/html_field";
import { MassMailingMobilePreviewDialog } from "./mass_mailing_mobile_preview";
import { getRangePosition } from '@web_editor/js/editor/odoo-editor/src/utils/utils';
import { MassMailingWysiwyg } from '@mass_mailing/js/mass_mailing_wysiwyg';
import { utils as uiUtils } from "@web/core/ui/ui_service";
import { useSubEnv, status } from "@odoo/owl";
@@ -24,10 +23,6 @@ export class MassMailingHtmlField extends HtmlField {
inlineField: { type: String, optional: true },
iframeHtmlClass: { type: String, optional: true },
}
static components = {
...HtmlField.components,
Wysiwyg: MassMailingWysiwyg,
}
setup() {
super.setup();
@@ -616,6 +611,11 @@ export class MassMailingHtmlField extends HtmlField {
}
await super._setupReadonlyIframe();
}
async _lazyloadWysiwyg() {
await super._lazyloadWysiwyg(...arguments);
const wysiwygModule = await odoo.loader.modules.get('@mass_mailing/js/mass_mailing_wysiwyg');
this.Wysiwyg = wysiwygModule.MassMailingWysiwyg;
}
}
export const massMailingHtmlField = {
@@ -1,10 +1,10 @@
/** @odoo-module **/
import { loadBundle } from "@web/core/assets";
import { attachComponent } from "@web/legacy/utils";
import { Wysiwyg } from "@web_editor/js/wysiwyg/wysiwyg";
import { closestElement } from "@web_editor/js/editor/odoo-editor/src/OdooEditor";
import { Toolbar } from "@web_editor/js/editor/toolbar";
import { requireWysiwygLegacyModule } from "@web_editor/js/frontend/loader";
import "@web_editor/js/wysiwyg/wysiwyg_iframe";
export class MassMailingWysiwyg extends Wysiwyg {
@@ -114,7 +114,8 @@ export class MassMailingWysiwyg extends Wysiwyg {
* @override
*/
async _createSnippetsMenuInstance(options={}) {
const { MassMailingSnippetsMenu } = await requireWysiwygLegacyModule('@mass_mailing/js/snippets.editor');
await loadBundle('web_editor.assets_legacy_wysiwyg');
const { MassMailingSnippetsMenu } = await odoo.loader.modules.get('@mass_mailing/js/snippets.editor');
return new MassMailingSnippetsMenu(this, Object.assign({
wysiwyg: this,
selectorEditableArea: '.o_editable',
-1
View File
@@ -208,7 +208,6 @@
'web_editor/static/src/scss/web_editor.common.scss',
'web_editor/static/src/scss/web_editor.backend.scss',
'web_editor/static/src/js/frontend/loader.js',
'web_editor/static/src/js/backend/**/*',
'web_editor/static/src/xml/backend.xml',
+4 -4
View File
@@ -170,6 +170,9 @@ Odoo Web Editor widget.
'web_editor/static/src/xml/wysiwyg.xml',
'web_editor/static/src/xml/wysiwyg_colorpicker.xml',
],
'web_editor.backend_assets_wysiwyg': [
('include', 'web_editor.assets_wysiwyg'),
],
'web.assets_backend': [
'web_editor/static/src/js/editor/odoo-editor/src/base_style.scss',
'web_editor/static/lib/vkbeautify/**/*',
@@ -183,11 +186,8 @@ Odoo Web Editor widget.
'web_editor/static/src/scss/web_editor.common.scss',
'web_editor/static/src/scss/web_editor.backend.scss',
'web_editor/static/src/js/frontend/loader.js',
'web_editor/static/src/js/backend/**/*',
'web_editor/static/src/xml/backend.xml',
('include', 'web_editor.assets_wysiwyg'),
],
"web.assets_web_dark": [
'web_editor/static/src/scss/odoo-editor/powerbox.dark.scss',
@@ -210,7 +210,6 @@ Odoo Web Editor widget.
'web_editor/static/src/scss/web_editor.common.scss',
'web_editor/static/src/scss/web_editor.frontend.scss',
'web_editor/static/src/js/frontend/loader.js',
'web_editor/static/src/js/frontend/loadWysiwygFromTextarea.js',
],
@@ -239,6 +238,7 @@ Odoo Web Editor widget.
'web.qunit_suite_tests': [
('include', 'web_editor.assets_legacy_wysiwyg'),
('include', 'web_editor.backend_assets_wysiwyg'),
'web_editor/static/tests/**/*',
'web_editor/static/src/js/editor/odoo-editor/test/utils.js'
@@ -4,7 +4,6 @@ import { registry } from "@web/core/registry";
import { _t } from "@web/core/l10n/translation";
import { standardFieldProps } from "@web/views/fields/standard_field_props";
import { QWebPlugin } from '@web_editor/js/backend/QWebPlugin';
import { MoveNodePlugin } from '@web_editor/js/wysiwyg/MoveNodePlugin';
import { TranslationButton } from "@web/views/fields/translation_button";
import { useDynamicPlaceholder } from "@web/views/fields/dynamic_placeholder_hook";
import {
@@ -18,7 +17,7 @@ import {
getRangePosition
} from '@web_editor/js/editor/odoo-editor/src/utils/utils';
import { toInline } from '@web_editor/js/backend/convert_inline';
import { getBundle } from '@web/core/assets';
import { getBundle, loadBundle } from '@web/core/assets';
import {
Component,
useRef,
@@ -31,13 +30,16 @@ import {
status,
} from "@odoo/owl";
import { uniqueId } from '@web/core/utils/functions';
import { Wysiwyg, stripHistoryIds } from '../wysiwyg/wysiwyg';
// Ensure `@web/views/fields/html/html_field` is loaded first as this module
// must override the html field in the registry.
import '@web/views/fields/html/html_field';
let stripHistoryIds;
export class HtmlField extends Component {
static template = "web_editor.HtmlField";
static components = {
TranslationButton,
Wysiwyg,
};
static defaultProps = { dynamicPlaceholder: false };
static props = {
@@ -92,6 +94,7 @@ export class HtmlField extends Component {
if (this.props.cssReadonlyAssetId) {
this.cssReadonlyAsset = await getBundle(this.props.cssReadonlyAssetId);
}
await this._lazyloadWysiwyg();
});
this._lastRecordInfo = {
res_model: this.props.record.resModel,
@@ -239,6 +242,7 @@ export class HtmlField extends Component {
res_id: this.props.record.resId,
},
fieldId: this.props.id,
editorPlugins: [...(wysiwygOptions.editorPlugins || []), QWebPlugin, this.MoveNodePlugin],
};
}
/**
@@ -393,6 +397,19 @@ export class HtmlField extends Component {
}
}
}
async _lazyloadWysiwyg() {
// In some bundle (eg. `web.qunit_suite_tests`), the following module is already included.
let wysiwygModule = await odoo.loader.modules.get('@web_editor/js/wysiwyg/wysiwyg');
this.MoveNodePlugin = (await odoo.loader.modules.get('@web_editor/js/wysiwyg/MoveNodePlugin'))?.MoveNodePlugin;
// Otherwise, load the module.
if (!wysiwygModule) {
await loadBundle('web_editor.backend_assets_wysiwyg');
wysiwygModule = await odoo.loader.modules.get('@web_editor/js/wysiwyg/wysiwyg');
this.MoveNodePlugin = (await odoo.loader.modules.get('@web_editor/js/wysiwyg/MoveNodePlugin')).MoveNodePlugin;
}
stripHistoryIds = wysiwygModule.stripHistoryIds;
this.Wysiwyg = wysiwygModule.Wysiwyg;
}
_isDirty() {
const strippedPropValue = stripHistoryIds(String(this.props.record.data[this.props.name]));
const strippedEditingValue = stripHistoryIds(this.getEditingValue());
@@ -685,7 +702,6 @@ export const htmlField = {
minHeight: options.minHeight,
maxHeight: options.maxHeight,
resizable: 'resizable' in options ? options.resizable : false,
editorPlugins: [QWebPlugin, MoveNodePlugin],
};
if ('collaborative' in options) {
wysiwygOptions.collaborative = options.collaborative;
@@ -16,10 +16,11 @@
<textarea t-ref="codeView" class="o_codeview" t-att-value="markupValue"/>
</t>
<t t-else="">
<Wysiwyg
options="this.wysiwygOptions"
startWysiwyg.bind="this.startWysiwyg"
editingValue="this.currentEditingValue" />
<t t-component="this.Wysiwyg" t-props="{
'options': this.wysiwygOptions,
'startWysiwyg': this.startWysiwyg.bind(this),
'editingValue': this.currentEditingValue,
}" />
</t>
<t t-if="isTranslatable">
<span t-attf-style="font-size: 15px; position: absolute; right: {{this.props.codeview ? '40px' : '5px'}}; top: 5px;">
@@ -2,7 +2,6 @@
import { loadBundle } from "@web/core/assets";
import { useWowlService, attachComponent } from '@web/legacy/utils';
import { requireLegacyModule } from '@web_editor/js/frontend/loader';
export async function loadWysiwygFromTextarea(parent, textarea, options) {
var loading = textarea.nextElementSibling;
@@ -16,9 +15,8 @@ export async function loadWysiwygFromTextarea(parent, textarea, options) {
currentOptions.value = '<p><br></p>';
}
const { Wysiwyg } = await requireLegacyModule('@web_editor/js/wysiwyg/wysiwyg', async () => {
await loadBundle("web_editor.assets_wysiwyg");
});
await loadBundle("web_editor.assets_wysiwyg");
const { Wysiwyg } = await odoo.loader.modules.get('@web_editor/js/wysiwyg/wysiwyg');
let wysiwyg;
class LegacyWysiwyg extends Wysiwyg {
constructor(...args) {
@@ -1,17 +0,0 @@
/** @odoo-module **/
import { loadBundle } from "@web/core/assets";
export async function loadLegacyWysiwygAssets(additionnalAssets = []) {
const xmlids = ["web_editor.assets_legacy_wysiwyg", ...additionnalAssets];
await loadBundle({ assetLibs: xmlids });
}
export async function requireLegacyModule(moduleName, loadCallback = () => {}) {
await loadCallback();
return odoo.loader.modules.get(moduleName)[Symbol.for('default')] || odoo.loader.modules.get(moduleName);
}
export async function requireWysiwygLegacyModule(moduleName) {
return requireLegacyModule(moduleName, loadLegacyWysiwygAssets);
}
@@ -41,7 +41,6 @@ import {
markup,
status,
} from "@odoo/owl";
import { requireWysiwygLegacyModule } from "@web_editor/js/frontend/loader";
import { isCSSColor } from '@web/core/utils/colors';
import { EmojiPicker } from '@web/core/emoji_picker/emoji_picker';
@@ -273,6 +272,7 @@ export class Wysiwyg extends Component {
onHistoryResetFromSteps: () => {},
autostart: true,
dropImageAsAttachment: true,
editorPlugins: [],
}
init() {
this.id = ++id;
@@ -1651,7 +1651,7 @@ export class Wysiwyg extends Component {
* @returns {widget}
*/
async _createSnippetsMenuInstance(options={}) {
const snippetsEditor = await requireWysiwygLegacyModule('@web_editor/js/editor/snippets.editor');
const snippetsEditor = await odoo.loader.modules.get('@web_editor/js/editor/snippets.editor')[Symbol.for('default')];
const { SnippetsMenu } = snippetsEditor;
return new SnippetsMenu(this, Object.assign({
wysiwyg: this,
+6 -2
View File
@@ -258,6 +258,12 @@
('include', 'web_editor.assets_legacy_wysiwyg'),
('include', 'website.assets_wysiwyg'),
],
'website.backend_assets_all_wysiwyg': [
('include', 'web_editor.backend_assets_wysiwyg'),
('include', 'web_editor.assets_legacy_wysiwyg'),
('include', 'website.assets_wysiwyg'),
'website/static/src/components/wysiwyg_adapter/wysiwyg_adapter.js',
],
'web_editor.assets_media_dialog': [
'website/static/src/components/media_dialog/image_selector.js',
],
@@ -284,7 +290,6 @@
'website/static/src/components/burger_menu/burger_menu.js',
'website/static/src/components/switch/switch.js',
'website/static/src/components/switch/switch.scss',
'website/static/src/components/wysiwyg_adapter/wysiwyg_adapter.js',
'website/static/src/components/wysiwyg_adapter/page_options.js',
'website/static/src/components/translator/translator.js',
'website/static/src/components/translator/translator.scss',
@@ -293,7 +298,6 @@
'website/static/src/services/website_custom_menus.js',
'website/static/src/js/tours/homepage.js',
'website/static/src/systray_items/*',
'web_editor/static/src/xml/editor.xml',
'website/static/src/client_actions/*/*.xml',
'website/static/src/components/website_loader/*.xml',
'website/static/src/js/backend/**/*',
@@ -2,7 +2,6 @@
import { _t } from "@web/core/l10n/translation";
import { useService } from '@web/core/utils/hooks';
import { WysiwygAdapterComponent } from '../wysiwyg_adapter/wysiwyg_adapter';
import { useActiveElement } from '@web/core/ui/ui_service';
import {
markup,
@@ -39,6 +38,8 @@ export class WebsiteEditorComponent extends Component {
onWillStart(async () => {
await this.websiteService.loadWysiwyg();
const adapterModule = await odoo.loader.modules.get('@website/components/wysiwyg_adapter/wysiwyg_adapter');
this.WysiwygAdapterComponent = adapterModule.WysiwygAdapterComponent;
});
useEffect(isPublicRootReady => {
@@ -149,5 +150,4 @@ export class WebsiteEditorComponent extends Component {
this.websiteContext.edition = false;
}
}
WebsiteEditorComponent.components = { WysiwygAdapterComponent };
WebsiteEditorComponent.template = 'website.WebsiteEditorComponent';
@@ -7,18 +7,19 @@
<div t-if="state.showWysiwyg"
t-ref="wysiwyg-adapter"
t-att-class="{ o_w_wysiwyg_transition: !this.state.reloading, o_w_wysiwyg: this.websiteContext.snippetsLoaded }">
<WysiwygAdapterComponent
editingValue="this.wysiwygOptions.value"
options="this.wysiwygOptions"
snippetSelector="this.reloadSelector"
willReload.bind="this.willReload"
reloadCallback.bind="this.reload"
quitCallback.bind="this.quit"
wysiwygReady.bind="this.wysiwygReady"
editableElements="this.editableElements"
savableSelector="this.savableSelector"
beforeEditorActive="this.beforeEditorActive"
removeWelcomeMessage="this.props.removeWelcomeMessage"/>
<t t-component="this.WysiwygAdapterComponent" t-props="{
'editingValue': this.wysiwygOptions.value,
'options': this.wysiwygOptions,
'snippetSelector': this.reloadSelector,
'willReload': this.willReload.bind(this),
'reloadCallback': this.reload.bind(this),
'quitCallback': this.quit.bind(this),
'wysiwygReady': this.wysiwygReady.bind(this),
'editableElements': this.editableElements,
'savableSelector': this.savableSelector,
'beforeEditorActive': this.beforeEditorActive,
'removeWelcomeMessage': this.props.removeWelcomeMessage,
}" />
</div>
</t>
</templates>
@@ -6,7 +6,6 @@ import legacyEnv from '@web/legacy/js/common_env';
import { useService, useBus } from "@web/core/utils/hooks";
import { useHotkey } from '@web/core/hotkeys/hotkey_hook';
import { Wysiwyg } from "@web_editor/js/wysiwyg/wysiwyg";
import { requireWysiwygLegacyModule } from "@web_editor/js/frontend/loader";
import weUtils from '@web_editor/js/common/utils';
import { isMediaElement } from '@web_editor/js/editor/odoo-editor/src/utils/utils';
@@ -324,10 +323,10 @@ export class WysiwygAdapterComponent extends Wysiwyg {
// destroy, options will have wrong social media values).
// It would also survive (multi) website switch, not fetching the values
// from the accessed website.
const mod = await requireWysiwygLegacyModule('@website/snippets/s_social_media/options');
const mod = await odoo.loader.modules.get('@website/snippets/s_social_media/options')[Symbol.for('default')];
mod.clearDbSocialValuesCache();
const formOptionsMod = await requireWysiwygLegacyModule('@website/snippets/s_website_form/options');
const formOptionsMod = await odoo.loader.modules.get('@website/snippets/s_website_form/options')[Symbol.for('default')];
formOptionsMod.clearAllFormsInfo();
this._restoreMegaMenus();
@@ -853,7 +852,7 @@ export class WysiwygAdapterComponent extends Wysiwyg {
* @override
*/
async _createSnippetsMenuInstance(options = {}) {
const snippetsEditor = await requireWysiwygLegacyModule('@website/js/editor/snippets.editor');
const snippetsEditor = await odoo.loader.modules.get('@website/js/editor/snippets.editor')[Symbol.for('default')];
const { SnippetsMenu } = snippetsEditor;
return new SnippetsMenu(this, Object.assign({
wysiwyg: this,
@@ -219,7 +219,7 @@ export const websiteService = {
websites = [...(await orm.searchRead('website', [], ['domain', 'id', 'name']))];
},
async loadWysiwyg() {
await loadBundle("website.assets_all_wysiwyg");
await loadBundle('website.backend_assets_all_wysiwyg');
},
blockPreview(showLoader, processId) {
if (!blockingProcesses.length) {
+3 -1
View File
@@ -35,10 +35,12 @@
'website_blog/static/src/snippets/s_blog_posts/options.js',
],
'website.assets_editor': [
'website_blog/static/src/js/wysiwyg_adapter.js',
'website_blog/static/src/js/tours/website_blog.js',
'website_blog/static/src/js/systray_items/*.js',
],
'website.backend_assets_all_wysiwyg': [
'website_blog/static/src/js/wysiwyg_adapter.js',
],
'web.assets_tests': [
'website_blog/static/tests/**/*',
],
+3 -1
View File
@@ -104,9 +104,11 @@
],
'website.assets_editor': [
'website_sale/static/src/js/systray_items/*.js',
'website_sale/static/src/js/components/wysiwyg_adapter/wysiwyg_adapter.js',
'website_sale/static/src/xml/website_sale_utils.xml',
],
'website.backend_assets_all_wysiwyg': [
'website_sale/static/src/js/components/wysiwyg_adapter/wysiwyg_adapter.js',
],
'web.assets_tests': [
'website_sale/static/tests/**/*',
],