diff options
| author | Christophe Matthieu <chm@odoo.com> | 2019-01-28 09:39:56 +0000 |
|---|---|---|
| committer | Christophe Matthieu <chm@odoo.com> | 2019-02-14 15:11:19 +0000 |
| commit | b49745e52d7a7bc27afd416206dcd5fa242aa07a (patch) | |
| tree | ae6a047da7e77b951db241e1342278ce543972e2 /addons/web_editor/static/src/js | |
| parent | 7daa85dd12ff522be510bc2f8db1d968cae7d891 (diff) | |
[IMP] web_editor: lazy load the wysiwyg
Issue: wysiwyg asset slow down the loading of the website, error
inadvertently introduced: https://github.com/odoo/odoo/pull/29775
The assets are now loaded assynchroneously, when the editor is needed,
its assets will be loaded.
closes odoo/odoo#30700
Diffstat (limited to 'addons/web_editor/static/src/js')
8 files changed, 114 insertions, 85 deletions
diff --git a/addons/web_editor/static/src/js/backend/convert_inline.js b/addons/web_editor/static/src/js/backend/convert_inline.js index 3b09bef5f31..b6b36a388ef 100644 --- a/addons/web_editor/static/src/js/backend/convert_inline.js +++ b/addons/web_editor/static/src/js/backend/convert_inline.js @@ -1,7 +1,6 @@ odoo.define('web_editor.convertInline', function (require) { 'use strict'; -var fonts = require('wysiwyg.fonts'); var FieldHtml = require('web_editor.field.html'); /** @@ -189,6 +188,8 @@ function getMatchedCSSRules(a) { * converted to images */ function fontToImg($editable) { + var fonts = odoo.__DEBUG__.services["wysiwyg.fonts"]; + $editable.find('.fa').each(function () { var $font = $(this); var icon, content; diff --git a/addons/web_editor/static/src/js/backend/field_html.js b/addons/web_editor/static/src/js/backend/field_html.js index 69e32fb815e..b78fcc1d35f 100644 --- a/addons/web_editor/static/src/js/backend/field_html.js +++ b/addons/web_editor/static/src/js/backend/field_html.js @@ -4,12 +4,12 @@ odoo.define('web_editor.field.html', function (require) { var ajax = require('web.ajax'); var basic_fields = require('web.basic_fields'); var core = require('web.core'); -var Wysiwyg = require('web_editor.wysiwyg'); +var Wysiwyg = require('web_editor.wysiwyg.root'); var field_registry = require('web.field_registry'); var TranslatableFieldMixin = basic_fields.TranslatableFieldMixin; - var QWeb = core.qweb; +var assetsLoaded = false; /** * FieldHtml Widget @@ -40,8 +40,23 @@ var FieldHtml = basic_fields.DebouncedField.extend(TranslatableFieldMixin, { */ willStart: function () { this._onUpdateIframeId = 'onLoad_' + _.uniqueId('FieldHtml'); - var defAsset = this.nodeOptions.cssReadonly && ajax.loadAsset(this.nodeOptions.cssReadonly); - return $.when(this._super().then(Wysiwyg.prepare.bind(Wysiwyg, this)), defAsset); + var defAsset = null; + if (this.nodeOptions.cssReadonly) { + defAsset = ajax.loadAsset(this.nodeOptions.cssReadonly); + } + + if (!assetsLoaded) { // avoid flickering when begin to edit + assetsLoaded = $.Deferred(); + var wysiwyg = new Wysiwyg(this, {}); + wysiwyg.attachTo($('<textarea>')).then(function () { + wysiwyg.destroy(); + var def = assetsLoaded; + assetsLoaded = true; + def.resolve(); + }); + } + + return $.when(this._super(), assetsLoaded, defAsset); }, /** * @override @@ -147,7 +162,7 @@ var FieldHtml = basic_fields.DebouncedField.extend(TranslatableFieldMixin, { // by default this is synchronous because the assets are already loaded in willStart // but it can be async in the case of options such as iframe, snippets... return this.wysiwyg.attachTo(this.$target).then(function () { - self.$content = self.wysiwyg.$el; + self.$content = self.wysiwyg.$editor; self._onLoadWysiwyg(); }); }, @@ -444,7 +459,7 @@ var FieldHtml = basic_fields.DebouncedField.extend(TranslatableFieldMixin, { position: 'absolute', right: '+5px', }); - var $toolbar = this.$content.closest('.note-editor').find('.note-toolbar'); + var $toolbar = this.$content.find('.note-toolbar'); $toolbar.css('position', 'relative'); $toolbar.append($button); }, diff --git a/addons/web_editor/static/src/js/common/ace.js b/addons/web_editor/static/src/js/common/ace.js index f242129c4a8..2f9108b4d0d 100644 --- a/addons/web_editor/static/src/js/common/ace.js +++ b/addons/web_editor/static/src/js/common/ace.js @@ -191,7 +191,6 @@ var ViewEditor = Widget.extend({ willStart: function () { return $.when( this._super.apply(this, arguments), - ajax.loadLibs(this), this._loadResources() ); }, diff --git a/addons/web_editor/static/src/js/wysiwyg/plugin/font.js b/addons/web_editor/static/src/js/wysiwyg/plugin/font.js index c52712d7a02..cd4d80a9a45 100644 --- a/addons/web_editor/static/src/js/wysiwyg/plugin/font.js +++ b/addons/web_editor/static/src/js/wysiwyg/plugin/font.js @@ -534,6 +534,11 @@ registry.addJob(function (wysiwyg) { if ('web_editor.colorpicker' in QWeb.templates) { return; } + + if (wysiwyg.isDestroyed()) { + throw new Error('The Wysiwyg are destroyed before this loading'); + } + var options = {}; wysiwyg.trigger_up('getRecordInfo', { recordInfo: options, diff --git a/addons/web_editor/static/src/js/wysiwyg/root.js b/addons/web_editor/static/src/js/wysiwyg/root.js new file mode 100644 index 00000000000..5dd48b6acf7 --- /dev/null +++ b/addons/web_editor/static/src/js/wysiwyg/root.js @@ -0,0 +1,62 @@ +odoo.define('web_editor.wysiwyg.root', function (require) { +'use strict'; + +var Widget = require('web.Widget'); + +var assetsLoaded = false; + +var WysiwygRoot = Widget.extend({ + assetLibs: ['web_editor.compiled_assets_wysiwyg'], + + publicMethods: ['isDirty', 'save', 'getValue', 'setValue', 'getEditable', 'on', 'trigger'], + + /** + * @see 'web_editor.wysiwyg' module + **/ + init: function (parent, params) { + this._super.apply(this, arguments); + this._params = params; + this.$editor = null; + }, + /** + * Load assets + * + * @override + **/ + willStart: function () { + var self = this; + + var $target = this.$el; + this.$el = null; + + return this._super().then(function () { + if (!assetsLoaded) { + var Wysiwyg = odoo.__DEBUG__.services['web_editor.wysiwyg']; + _.each(['getRange', 'setRange', 'setRangeFromNode'], function (methodName) { + WysiwygRoot[methodName] = Wysiwyg[methodName].bind(Wysiwyg); + }); + assetsLoaded = true; + } + + var Wysiwyg = self._getWysiwygContructor(); + var instance = new Wysiwyg(self, self._params); + self._params = null; + + _.each(self.publicMethods, function (methodName) { + self[methodName] = instance[methodName].bind(instance); + }); + + return instance.attachTo($target).then(function () { + self.$editor = instance.$el; + }); + }); + }, + + _getWysiwygContructor: function () { + return odoo.__DEBUG__.services['web_editor.wysiwyg']; + } +}); + +return WysiwygRoot; + +}); diff --git a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js index 8cf1026158d..44f7dd2c6a8 100644 --- a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js +++ b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js @@ -19,7 +19,10 @@ var Wysiwyg = Widget.extend({ wysiwyg_blur: '_onWysiwygBlur', }, defaultOptions: { - codeview: config.debug + codeview: config.debug, + recordInfo: { + context: {}, + }, }, /** @@ -694,41 +697,6 @@ var Wysiwyg = Widget.extend({ //-------------------------------------------------------------------------- /** - * Load wysiwyg assets if needed. - * - * @see Wysiwyg.createReadyFunction - * @param {Widget} parent - * @returns {$.Promise} - */ -Wysiwyg.prepare = (function () { - var assetsLoaded = false; - var def; - return function prepare(parent) { - if (assetsLoaded) { - return $.when(); - } - if (def) { - return def; - } - def = $.Deferred(); - var timeout = setTimeout(function () { - throw _t("Can't load assets of the wysiwyg editor"); - }, 10000); - var wysiwyg = new Wysiwyg(parent, { - recordInfo: { - context: {}, - } - }); - wysiwyg.attachTo($('<textarea>')).then(function () { - assetsLoaded = true; - clearTimeout(timeout); - wysiwyg.destroy(); - def.resolve(); - }); - return def; - }; -})(); -/** * @param {Node} node (editable or node inside) * @returns {Object} * @returns {Node} sc - start container diff --git a/addons/web_editor/static/src/js/wysiwyg/wysiwyg_iframe.js b/addons/web_editor/static/src/js/wysiwyg/wysiwyg_iframe.js index 7bfe76e3d24..9de5c6b4cb7 100644 --- a/addons/web_editor/static/src/js/wysiwyg/wysiwyg_iframe.js +++ b/addons/web_editor/static/src/js/wysiwyg/wysiwyg_iframe.js @@ -3,7 +3,9 @@ odoo.define('web_editor.wysiwyg.iframe', function (require) { var Wysiwyg = require('web_editor.wysiwyg'); var ajax = require('web.ajax'); +var core = require('web.core'); +var qweb = core.qweb; var _fnSummernoteMaster = $.fn.summernote; var _summernoteMaster = $.summernote; @@ -165,48 +167,14 @@ Wysiwyg.include({ console.warn('Wysiwyg immediate iframe double load detected'); return; } - var cwindow = this.$iframe[0].contentWindow; - cwindow.document + var iframeContent = qweb.render('wysiwyg.iframeContent', { + asset: asset, + updateIframeId: this._onUpdateIframeId, + avoidDoubleLoad: _avoidDoubleLoad + }); + this.$iframe[0].contentWindow.document .open("text/html", "replace") - .write( - '<head>' + - '<meta charset="utf-8">' + - '<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>\n' + - '<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>\n' + - _.map(asset.cssLibs, function (cssLib) { - return '<link type="text/css" rel="stylesheet" href="' + cssLib + '"/>'; - }).join('\n') + '\n' + - _.map(asset.cssContents, function (cssContent) { - return '<style type="text/css">' + cssContent + '</style>'; - }).join('\n') + '\n' + - _.map(asset.jsContents, function (jsContent) { - if (jsContent.indexOf('<inline asset>') !== -1) { - return '<script type="text/javascript">' + jsContent + '</script>'; - } - }).join('\n') + '\n' + - '</head>\n' + - '<body class="o_in_iframe">\n' + - '<div id="iframe_target" style="height: calc(100vh - 6px);"></div>\n' + - '<script type="text/javascript">' + - 'window.$ = window.jQuery = window.top.jQuery;' + - 'var _summernoteMaster = $.summernote;' + - 'var _fnSummernoteMaster = $.fn.summernote;' + - 'delete $.summernote;' + - 'delete $.fn.summernote;' + - '</script>\n' + - '<script type="text/javascript" src="/web_editor/static/lib/summernote/summernote.js"></script>\n' + - '<script type="text/javascript">' + - 'window._summernoteSlave = $.summernote;' + - 'window._summernoteSlave.iframe = true;' + - 'window._summernoteSlave.lang = _summernoteMaster.lang;' + - 'window._fnSummenoteSlave = $.fn.summernote;' + - '$.summernote = _summernoteMaster;' + - '$.fn.summernote = _fnSummernoteMaster;' + - 'if (window.top.' + this._onUpdateIframeId + ') {' + - 'window.top.' + this._onUpdateIframeId + '(' + _avoidDoubleLoad + ')' + - '}' + - '</script>\n' + - '</body>'); + .write(iframeContent); }.bind(this)); }.bind(this)); diff --git a/addons/web_editor/static/src/js/wysiwyg_snippets/wysiwyg_snippets.js b/addons/web_editor/static/src/js/wysiwyg_snippets/wysiwyg_snippets.js index 0f411343486..5df48ebf2f9 100644 --- a/addons/web_editor/static/src/js/wysiwyg_snippets/wysiwyg_snippets.js +++ b/addons/web_editor/static/src/js/wysiwyg_snippets/wysiwyg_snippets.js @@ -15,6 +15,7 @@ Wysiwyg.include({ snippet_cloned: '_onSnippetCloned', snippet_dropped: '_onSnippetDropped', snippet_focused: '_onSnippetFocused', + reload_snippet_dropzones: '_onReloadSnippetDropzones', }), selectorEditableArea: '.note-editable', @@ -173,6 +174,14 @@ Wysiwyg.include({ context.invoke('MediaPlugin.hidePopovers'); }, /** + * trigger reload_snippet_dropzones on snippets + * + * @private + */ + _onReloadSnippetDropzones: function () { + this.snippets.trigger('reload_snippet_dropzones'); + }, + /** * Triggered when a snippet is cloned in the editable area * * @private @@ -258,4 +267,6 @@ $.fn.extend({ }, }); +return Wysiwyg; + }); |
