diff options
| author | Vincent Schippefilt <vsc@odoo.com> | 2019-03-06 14:02:33 +0100 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2019-03-06 20:07:17 +0100 |
| commit | 2e8222dee737215cbad0dd3556d6ec0ffe60bf00 (patch) | |
| tree | 83cf89fa39aa53a86ef044c661b5ed5c52231446 /addons/web_editor/static/src | |
| parent | a3dfd04ad670b425df4d36ff714a4d4e260ff5a9 (diff) | |
[REF] web_editor: adapt code after jQuery update
Part of task 1896658
Co-authored-by: Aaron Bohy <aab@odoo.com>
Co-authored-by: Christophe Matthieu <chm@odoo.com>
Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com>
Co-authored-by: David Monjoie <dmo@odoo.com>
Co-authored-by: Martin Geubelle <mge@odoo.com>
Co-authored-by: svs-odoo <svs@odoo.com>
Co-authored-by: Vincent Schippefilt <vsc@odoo.com>
Diffstat (limited to 'addons/web_editor/static/src')
15 files changed, 256 insertions, 240 deletions
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 f1dc4a8fccc..185d0c84963 100644 --- a/addons/web_editor/static/src/js/backend/field_html.js +++ b/addons/web_editor/static/src/js/backend/field_html.js @@ -6,10 +6,12 @@ var basic_fields = require('web.basic_fields'); var core = require('web.core'); var Wysiwyg = require('web_editor.wysiwyg.root'); var field_registry = require('web.field_registry'); +// must wait for web/ to add the default html widget, otherwise it would override the web_editor one +require('web._field_registry'); var TranslatableFieldMixin = basic_fields.TranslatableFieldMixin; var QWeb = core.qweb; -var assetsLoaded = false; +var assetsLoaded; /** * FieldHtml Widget @@ -39,24 +41,24 @@ var FieldHtml = basic_fields.DebouncedField.extend(TranslatableFieldMixin, { * @override */ willStart: function () { + var self = this; this._onUpdateIframeId = 'onLoad_' + _.uniqueId('FieldHtml'); - var defAsset = null; + var defAsset; 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(); + assetsLoaded = new Promise(function (resolve) { + var wysiwyg = new Wysiwyg(self, {}); + wysiwyg.attachTo($('<textarea>')).then(function () { + wysiwyg.destroy(); + resolve(); + }); }); } - return $.when(this._super(), assetsLoaded, defAsset); + return Promise.all([this._super(), assetsLoaded, defAsset]); }, /** * @override @@ -95,8 +97,8 @@ var FieldHtml = basic_fields.DebouncedField.extend(TranslatableFieldMixin, { return this._super(); } var _super = this._super.bind(this); - return this.wysiwyg.save().then(function (isDirty, html) { - self._isDirty = isDirty; + return this.wysiwyg.save().then(function (result) { + self._isDirty = result.isDirty; _super(); }); }, @@ -131,7 +133,7 @@ var FieldHtml = basic_fields.DebouncedField.extend(TranslatableFieldMixin, { this.$content.html(value); } } - return $.when(); + return Promise.resolve(); }, //-------------------------------------------------------------------------- @@ -268,8 +270,10 @@ var FieldHtml = basic_fields.DebouncedField.extend(TranslatableFieldMixin, { } this.$el.empty(); - - var def = $.Deferred(); + var resolver; + var def = new Promise(function (resolve) { + resolver = resolve; + }); if (this.nodeOptions.cssReadonly) { this.$iframe = $('<iframe class="o_readonly"/>'); this.$iframe.appendTo(this.$el); @@ -278,14 +282,14 @@ var FieldHtml = basic_fields.DebouncedField.extend(TranslatableFieldMixin, { // inject content in iframe - this.$iframe.data('load-def', def); // for unit test + this.$iframe.data('loadDef', def); // for unit test window.top[this._onUpdateIframeId] = function (_avoidDoubleLoad) { if (_avoidDoubleLoad !== avoidDoubleLoad) { console.warn('Wysiwyg iframe double load detected'); return; } self.$content = $('#iframe_target', self.$iframe[0].contentWindow.document.body); - def.resolve(); + resolver(); }; this.$iframe.one('load', function onLoad() { @@ -326,7 +330,7 @@ var FieldHtml = basic_fields.DebouncedField.extend(TranslatableFieldMixin, { } else { this.$content = $('<div class="o_readonly"/>').html(value); this.$content.appendTo(this.$el); - def.resolve(); + resolver(); } def.then(function () { diff --git a/addons/web_editor/static/src/js/common/ace.js b/addons/web_editor/static/src/js/common/ace.js index 2f9108b4d0d..8fc1d0ac1f9 100644 --- a/addons/web_editor/static/src/js/common/ace.js +++ b/addons/web_editor/static/src/js/common/ace.js @@ -189,10 +189,10 @@ var ViewEditor = Widget.extend({ * @override */ willStart: function () { - return $.when( + return Promise.all([ this._super.apply(this, arguments), this._loadResources() - ); + ]); }, /** * Initializes the library and initial view once the DOM is ready. It also @@ -432,7 +432,7 @@ var ViewEditor = Widget.extend({ * is loading the activate views, index them and build their hierarchy. * * @private - * @returns {Deferred} + * @returns {Promise} */ _loadResources: function () { // Reset resources @@ -523,14 +523,14 @@ var ViewEditor = Widget.extend({ * @private * @param {integer|string} [resID] (default to the currently selected one) * @param {string} [type] (default to the currently selected one) - * @returns {Deferred} + * @returns {Promise} */ _resetResource: function (resID, type) { resID = resID || this._getSelectedResource(); type = type || this.currentType; if (this.currentType === 'xml') { - return $.Defered().reject(_t("Reseting views is not supported yet")); + return Promise.reject(_t("Reseting views is not supported yet")); } else { var resource = type === 'scss' ? this.scss[resID] : this.js[resID]; return this._rpc({ @@ -543,22 +543,20 @@ var ViewEditor = Widget.extend({ } }, /** - * Saves an unique SCSS or JS file. + * Saves a unique SCSS or JS file. * * @private * @param {Object} session - contains the 'id' (url) and the 'text' of the * SCSS or JS file to save. - * @return {Deferred} status indicates if the save is finished or if an + * @return {Promise} status indicates if the save is finished or if an * error occured. */ _saveSCSSorJS: function (session) { - var def = $.Deferred(); - var self = this; var sessionIdEndsWithJS = _.string.endsWith(session.id, '.js'); var bundleXmlID = sessionIdEndsWithJS ? this.js[session.id].bundle_xmlid : this.scss[session.id].bundle_xmlid; var fileType = sessionIdEndsWithJS ? 'js' : 'scss'; - self._rpc({ + return self._rpc({ route: '/web_editor/save_asset', params: { url: session.id, @@ -568,19 +566,14 @@ var ViewEditor = Widget.extend({ }, }).then(function () { self._toggleDirtyInfo(session.id, fileType, false); - def.resolve(); - }, function (source, error) { - def.reject(session, error); }); - - return def; }, /** * Saves every resource that has been modified. If one cannot be saved, none * is saved and an error message is displayed. * * @private - * @return {Deferred} status indicates if the save is finished or if an + * @return {Promise} status indicates if the save is finished or if an * error occured. */ _saveResources: function () { @@ -609,7 +602,7 @@ var ViewEditor = Widget.extend({ } } }).bind(this)); - if (errorFound) return $.Deferred().reject(errorFound); + if (errorFound) return Promise.reject(errorFound); var defs = []; var mutex = new concurrency.Mutex(); @@ -623,8 +616,10 @@ var ViewEditor = Widget.extend({ }); }).bind(this)); - return $.when.apply($, defs).fail((function (session, error) { - Dialog.alert(this, '', { + var self = this; + return Promise.all(defs).guardedCatch(function (results) { + var error = results[1]; + Dialog.alert(self, '', { title: _t("Server error"), $content: $('<div/>').html( _t("A server error occured. Please check you correctly signed in and that the file you are saving is correctly formatted.") @@ -632,34 +627,32 @@ var ViewEditor = Widget.extend({ + error ) }); - }).bind(this)); + }); }, /** * Saves an unique XML view. * * @private * @param {Object} session - the 'id' and the 'text' of the view to save. - * @returns {Deferred} status indicates if the save is finished or if an + * @returns {Promise} status indicates if the save is finished or if an * error occured. */ _saveView: function (session) { - var def = $.Deferred(); - var self = this; - this._rpc({ - model: 'ir.ui.view', - method: 'write', - args: [[session.id], {arch: session.text}], - }, { - noContextKeys: 'lang', - }).then(function () { - self._toggleDirtyInfo(session.id, 'xml', false); - def.resolve(); - }, function (source, error) { - def.reject(session, error); + return new Promise(function (resolve, reject) { + self._rpc({ + model: 'ir.ui.view', + method: 'write', + args: [[session.id], {arch: session.text}], + }, { + noContextKeys: 'lang', + }).then(function () { + self._toggleDirtyInfo(session.id, 'xml', false); + resolve(); + }, function (source, error) { + reject(session, error); + }); }); - - return def; }, /** * Shows a line which produced an error. Red color is added to the editor, diff --git a/addons/web_editor/static/src/js/wysiwyg/plugin/dropzone.js b/addons/web_editor/static/src/js/wysiwyg/plugin/dropzone.js index 8727a6aa8a1..74703b90e45 100644 --- a/addons/web_editor/static/src/js/wysiwyg/plugin/dropzone.js +++ b/addons/web_editor/static/src/js/wysiwyg/plugin/dropzone.js @@ -30,7 +30,7 @@ var DropzonePlugin = Plugins.dropzone.extend({ * Clean up then drops HTML or plain text into the editor. * * @private - * @param {String} html + * @param {String} html * @param {Boolean} textOnly true to allow only dropping plain text */ _dropHTML: function (html, textOnly) { @@ -80,24 +80,25 @@ var DropzonePlugin = Plugins.dropzone.extend({ spinners.push(spinner); // save images as attachments - var def = $.Deferred(); - defs.push(def); - // Get image's Base64 string - var reader = new FileReader(); - reader.addEventListener('load', function (e) { - self._uploadImage(e.target.result, file.name).then(function (attachment) { - // Make the HTML - var image = self.document.createElement('img'); - image.setAttribute('style', 'width: 100%;'); - image.src = '/web/content/' + attachment.id + '/' + attachment.name; - image.alt = attachment.name; - $(spinner).replaceWith(image); - images.push(image); - def.resolve(image); - $(image).trigger('dropped'); + var def = new Promise(function (resolve) { + // Get image's Base64 string + var reader = new FileReader(); + reader.addEventListener('load', function (e) { + self._uploadImage(e.target.result, file.name).then(function (attachment) { + // Make the HTML + var image = self.document.createElement('img'); + image.setAttribute('style', 'width: 100%;'); + image.src = '/web/content/' + attachment.id + '/' + attachment.name; + image.alt = attachment.name; + $(spinner).replaceWith(image); + images.push(image); + resolve(image); + $(image).trigger('dropped'); + }); }); + reader.readAsDataURL(file); }); - reader.readAsDataURL(file); + defs.push(def); }); this.trigger_up('drop_images', { @@ -105,16 +106,17 @@ var DropzonePlugin = Plugins.dropzone.extend({ promises: defs, }); - $.when.apply($, defs).then(function () { + Promise.all(defs).then(function () { var defs = []; $(images).each(function () { if (!this.height) { - var def = $.Deferred(); + var def = new Promise(function (resolve) { + $(this).one('load error abort', resolve); + }); defs.push(def); - $(this).one('load error abort', def.resolve.bind(def)); } }); - $.when.apply($, defs).then(function () { + Promise.all(defs).then(function () { if (images.length === 1) { range = self.context.invoke('editor.setRange', _.last(images), 0); range.select(); diff --git a/addons/web_editor/static/src/js/wysiwyg/plugin/link.js b/addons/web_editor/static/src/js/wysiwyg/plugin/link.js index 89ec8de8887..1b75339bf54 100644 --- a/addons/web_editor/static/src/js/wysiwyg/plugin/link.js +++ b/addons/web_editor/static/src/js/wysiwyg/plugin/link.js @@ -27,6 +27,17 @@ var LinkPlugin = Plugins.linkDialog.extend({ //-------------------------------------------------------------------------- /** + * @param {Object} layoutInfo + */ + show: function () { + var self = this; + var linkInfo = this.context.invoke('editor.getLinkInfo'); + this.context.invoke('editor.saveRange'); + return this.showLinkDialog(linkInfo) + .then(function (linkInfo) {}) + .guardedCatch(function () {}); + }, + /** * @override * @param {Object} linkInfo * @returns {Promise} @@ -145,64 +156,67 @@ var LinkPlugin = Plugins.linkDialog.extend({ linkInfo.needLabel = !linkInfo.text.length; } - var def = $.Deferred(); - var linkDialog = new LinkDialog(this.options.parent, { - onClose: function () { - setTimeout(function () { - self.context.invoke('editor.focus'); - }); - } - }, - _.omit(linkInfo, 'range') - ); - - linkDialog.on('save', this, this._wrapCommand(function (newLinkInfo) { - var isCollapsed = linkInfo.range.isCollapsed(); - linkInfo.range.select(); - var $anchor; - if (linkInfo.isAnchor) { - $anchor = $(dom.ancestor(r.sc, dom.isAnchor)); - $anchor.css(newLinkInfo.style || {}); - if (newLinkInfo.isNewWindow) { - $anchor.attr('target', '_blank'); + var def = new Promise(function (resolve, reject) { + var linkDialog = new LinkDialog(self.options.parent, { + onClose: function () { + setTimeout(function () { + self.context.invoke('editor.focus'); + }); + } + }, + _.omit(linkInfo, 'range') + ); + + linkDialog.on('save', self, self._wrapCommand(function (newLinkInfo) { + var isCollapsed = linkInfo.range.isCollapsed(); + linkInfo.range.select(); + newLinkInfo.range = linkInfo.range; + + var $anchor; + if (linkInfo.isAnchor) { + $anchor = $(dom.ancestor(r.sc, dom.isAnchor)); + $anchor.css(newLinkInfo.style || {}); + if (newLinkInfo.isNewWindow) { + $anchor.attr('target', '_blank'); + } else { + $anchor.removeAttr('target'); + } } else { - $anchor.removeAttr('target'); + self.context.invoke('editor.saveRange'); + self.context.invoke('editor.createLink', newLinkInfo); + var range = self.context.invoke('editor.createRange'); + var anchor = dom.ancestor(range.sc.childNodes[range.so] || range.sc, dom.isAnchor); + $anchor = $(anchor); + if (isCollapsed) { + // move the range just after the link + var point = dom.nextPoint({ + node: anchor, + offset: dom.nodeLength(anchor), + }); + range = self.context.invoke('editor.setRange', point.node, point.offset); + range.select(); + } else { + $anchor.selectContent(); + } } - } else { - self.context.invoke('editor.saveRange'); - def.resolve(_.clone(newLinkInfo)); - var range = self.context.invoke('editor.createRange'); - var anchor = dom.ancestor(range.sc.childNodes[range.so] || range.sc, dom.isAnchor); - $anchor = $(anchor); - if (isCollapsed) { - // move the range just after the link - var point = dom.nextPoint({ - node: anchor, - offset: dom.nodeLength(anchor), - }); - range = self.context.invoke('editor.setRange', point.node, point.offset); - range.select(); - } else { - $anchor.selectContent(); + if ((dom.isImg(media) || dom.isIcon(media)) && !$anchor.find(media).length) { + $(media).remove(); } - } - if ((dom.isImg(media) || dom.isIcon(media)) && !$anchor.find(media).length) { - $(media).remove(); - } - $anchor.attr('class', newLinkInfo.className); - $anchor.attr('href', newLinkInfo.url); - self.context.invoke('editor.saveRange'); - self.context.invoke('editor.saveTarget', $anchor[0]); - self.context.triggerEvent('focusnode', $anchor[0]); - })); - linkDialog.on('closed', this, function () { - def.reject(); - this.context.invoke('editor.restoreRange'); - this.context.invoke('LinkPopover.update'); + $anchor.attr('class', newLinkInfo.className); + $anchor.attr('href', newLinkInfo.url); + self.context.invoke('editor.saveRange'); + self.context.invoke('editor.saveTarget', $anchor[0]); + self.context.triggerEvent('focusnode', $anchor[0]); + resolve(linkInfo); + })); + linkDialog.on('closed', self, function () { + this.context.invoke('editor.restoreRange'); + this.context.invoke('LinkPopover.update'); + reject(); + }); + linkDialog.open(); }); - - linkDialog.open(); - return def.promise(); + return def; }, /** * Remove the current link, keep its contents. diff --git a/addons/web_editor/static/src/js/wysiwyg/plugin/media.js b/addons/web_editor/static/src/js/wysiwyg/plugin/media.js index 2cdfbe70cfe..242d31f68b9 100644 --- a/addons/web_editor/static/src/js/wysiwyg/plugin/media.js +++ b/addons/web_editor/static/src/js/wysiwyg/plugin/media.js @@ -455,7 +455,7 @@ var MediaPlugin = AbstractPlugin.extend({ this.showImageDialog(); } }, - /** + /** * @private **/ _onKeydown: function () { @@ -813,7 +813,7 @@ var ImagePlugin = AbstractMediaPlugin.extend({ }); } }).get(); - return $.when.apply($, defs); + return Promise.all(defs); }, /** * Add the image popovers' buttons: diff --git a/addons/web_editor/static/src/js/wysiwyg/plugin_registry.js b/addons/web_editor/static/src/js/wysiwyg/plugin_registry.js index bdd59cb41d2..65e9440240b 100644 --- a/addons/web_editor/static/src/js/wysiwyg/plugin_registry.js +++ b/addons/web_editor/static/src/js/wysiwyg/plugin_registry.js @@ -11,22 +11,22 @@ var WysiwygRegistry = Registry.extend({ this._super(); this._jobs = []; this._xmlDependencies = []; - this._def = $.when(); + this._loadingDef = Promise.resolve(); }, start: function (wysiwyg) { - var defs = [this._def]; var fn; + var defs = [this._loadingDef]; while ((fn = this._jobs.shift())) { defs.push(fn(wysiwyg)); } + var xmlPath; while ((xmlPath = this._xmlDependencies.shift())) { defs.push(ajax.loadXML(xmlPath, core.qweb)); } - if (defs.length !== 1) { - this._def = $.when.apply($, defs); - } - return this._def.state() === 'resolved' ? $.when() : this._def; + + this._loadingDef = Promise.all(defs); + return this._loadingDef; }, addJob: function (job) { this._jobs.push(job); diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/crop_dialog.js b/addons/web_editor/static/src/js/wysiwyg/widgets/crop_dialog.js index 5996fabc254..cb1feaf3f4d 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/crop_dialog.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/crop_dialog.js @@ -99,7 +99,7 @@ var CropImageDialog = Dialog.extend({ _.extend(self.imageData, res); })); } - return $.when.apply($, defs); + return Promise.all(defs); }, /** * @override diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js b/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js index 2135e56397b..236725dcace 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js @@ -108,7 +108,7 @@ var LinkDialog = Dialog.extend({ var $url = this.$('input[name="url"]'); $url.closest('.form-group').addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid'); $url.focus(); - return $.Deferred().reject(); + return Promise.reject(); } this.data.text = data.label; this.data.url = data.url; diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/media.js b/addons/web_editor/static/src/js/wysiwyg/widgets/media.js index e8a93e7c5f3..44793603027 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/media.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/media.js @@ -119,10 +119,10 @@ var ImageWidget = MediaWidget.extend({ * @override */ willStart: function () { - return $.when( + return Promise.all([ this._super.apply(this, arguments), this.search('', true) - ); + ]); }, /** * @override @@ -345,14 +345,15 @@ var ImageWidget = MediaWidget.extend({ class: 'img-fluid', src: $div.data('url') || $div.data('src'), }); - var def = $.Deferred(); - $img[0].onload = def.resolve.bind(def); - $div.addClass('o_webimage').append($img); - return def; + var prom = new Promise(function (resolve, reject) { + $img[0].onload = resolve(); + $div.addClass('o_webimage').append($img); + }); + return prom; } }); if (withEffect) { - $.when.apply($, imageDefs).then(function () { + Promise.all(imageDefs).then(function () { _.delay(function () { $divs.removeClass('o_image_loading'); }, 400); @@ -374,9 +375,9 @@ var ImageWidget = MediaWidget.extend({ return this.media; } - var def = $.when(); + var prom; if (!img.access_token) { - def = this._rpc({ + prom = this._rpc({ model: 'ir.attachment', method: 'generate_access_token', args: [[img.id]] @@ -385,7 +386,7 @@ var ImageWidget = MediaWidget.extend({ }); } - return def.then(function () { + return Promise.resolve(prom).then(function () { if (!img.isDocument) { if (img.access_token && self.options.res_model !== 'ir.ui.view') { img.src += _.str.sprintf('?access_token=%s', img.access_token); @@ -464,61 +465,64 @@ var ImageWidget = MediaWidget.extend({ _uploadFile: function () { return this._mutex.exec(this._uploadImageIframe.bind(this)); }, + /** + * @returns {Promise} + */ _uploadImageIframe: function () { var self = this; - var def = $.Deferred(); - /** - * @todo file upload cannot be handled with _rpc smoothly. This uses the - * form posting in iframe trick to handle the upload. - */ - var $iframe = this.$('iframe'); - $iframe.on('load', function () { - var iWindow = $iframe[0].contentWindow; - - var attachments = iWindow.attachments || []; - var error = iWindow.error; - - self.$('.well > span').remove(); - self.$('.well > div').show(); - _.each(attachments, function (record) { - record.src = record.url || _.str.sprintf('/web/image/%s/%s', record.id, encodeURI(record.name)); // Name is added for SEO purposes - record.isDocument = !(/gif|jpe|jpg|png/.test(record.mimetype)); - }); - if (error || !attachments.length) { - _processFile(null, error || !attachments.length); - } - self.images = attachments; - for (var i = 0 ; i < attachments.length ; i++) { - _processFile(attachments[i], error); - } - - if (self.options.onUpload) { - self.options.onUpload(attachments); - } - - def.resolve(); - - function _processFile(attachment, error) { - var $button = self.$('.o_upload_image_button'); - if (!error) { - $button.addClass('btn-success'); - self._toggleImage(attachment, true); - } else { - $button.addClass('btn-danger'); - self.$el.addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid'); - self.$el.find('.form-text').text(error); + return new Promise(function (resolve) { + + /** + * @todo file upload cannot be handled with _rpc smoothly. This uses the + * form posting in iframe trick to handle the upload. + */ + var $iframe = self.$('iframe'); + $iframe.on('load', function () { + var iWindow = $iframe[0].contentWindow; + + var attachments = iWindow.attachments || []; + var error = iWindow.error; + + self.$('.well > span').remove(); + self.$('.well > div').show(); + _.each(attachments, function (record) { + record.src = record.url || _.str.sprintf('/web/image/%s/%s', record.id, encodeURI(record.name)); // Name is added for SEO purposes + record.isDocument = !(/gif|jpe|jpg|png/.test(record.mimetype)); + }); + if (error || !attachments.length) { + _processFile(null, error || !attachments.length); + } + self.images = attachments; + for (var i = 0 ; i < attachments.length ; i++) { + _processFile(attachments[i], error); } - if (!self.multiImages) { - self.trigger_up('save_request'); + if (self.options.onUpload) { + self.options.onUpload(attachments); } - } - }); - this.$el.submit(); - this.$('.o_file_input').val(''); + resolve(); + + function _processFile(attachment, error) { + var $button = self.$('.o_upload_image_button'); + if (!error) { + $button.addClass('btn-success'); + self._toggleImage(attachment, true); + } else { + $button.addClass('btn-danger'); + self.$el.addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid'); + self.$el.find('.form-text').text(error); + } - return def; + if (!self.multiImages) { + self.trigger_up('save_request'); + } + } + }); + self.$el.submit(); + + self.$('.o_file_input').val(''); + }); }, @@ -734,7 +738,7 @@ var IconWidget = MediaWidget.extend({ this.$('div.font-icons-icons').html( QWeb.render('wysiwyg.widgets.font-icons.icons', {iconsParser: iconsParser}) ); - return $.when(); + return Promise.resolve(); }, //-------------------------------------------------------------------------- diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/media_dialog.js b/addons/web_editor/static/src/js/wysiwyg/widgets/media_dialog.js index f214d210b52..5ece0e9ee3f 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/media_dialog.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/media_dialog.js @@ -127,7 +127,7 @@ var MediaDialog = Dialog.extend({ defs.push(this.videoDialog.appendTo(this.$("#editor-media-video"))); } - return $.when.apply($, defs).then(function () { + return Promise.all(defs).then(function () { self._setActive(self.active); }); }, @@ -143,7 +143,7 @@ var MediaDialog = Dialog.extend({ var self = this; var _super = this._super; var args = arguments; - return $.when(this.active.save()).then(function (data) { + return Promise.resolve(this.active.save()).then(function (data) { self.final_data = data; // In the case of multi images selection we suppose this was not to // replace an old media, so we only retrieve the images and save. diff --git a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js index 3b2a63fa48e..7a1bb9c3f88 100644 --- a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js +++ b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js @@ -78,7 +78,7 @@ var Wysiwyg = Widget.extend({ if (this._summernote.invoke('HelperPlugin.hasJinja', value)) { this._summernote.invoke('codeview.forceActivate'); } - return $.when(); + return Promise.resolve(); }, /** * @override @@ -214,7 +214,7 @@ var Wysiwyg = Widget.extend({ * - in init option beforeSave * - receive editable jQuery DOM as attribute * - called after deactivate codeview if needed - * @returns {$.Promise} + * @returns {Promise} * - resolve with true if the content was dirty */ save: function () { @@ -225,7 +225,7 @@ var Wysiwyg = Widget.extend({ } else { this.$target.html(html); } - return $.when(isDirty, html); + return Promise.resolve({isDirty:isDirty, html:html}); }, /** * @param {String} value @@ -479,7 +479,7 @@ var Wysiwyg = Widget.extend({ this.$el.removeClass('card'); - return $.when(); + return Promise.resolve(); }, //-------------------------------------------------------------------------- @@ -714,7 +714,7 @@ Wysiwyg.getRange = function (node) { }; }; /** - * @param {Node} startNode + * @param {Node} startNode * @param {Number} startOffset * @param {Node} endNode * @param {Number} endOffset 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 0d75f360731..aacdfff9e0c 100644 --- a/addons/web_editor/static/src/js/wysiwyg/wysiwyg_iframe.js +++ b/addons/web_editor/static/src/js/wysiwyg/wysiwyg_iframe.js @@ -47,7 +47,7 @@ Wysiwyg.include({ if (this.options.iframeCssAssets) { this.defAsset = ajax.loadAsset(this.options.iframeCssAssets); } else { - this.defAsset = $.when({cssLibs: [], cssContents: []}); + this.defAsset = Promise.resolve({cssLibs: [], cssContents: []}); } this.$target = this.$el; return this.defAsset @@ -139,6 +139,7 @@ Wysiwyg.include({ * @returns {Promise} */ _loadIframe: function () { + var self = this; this.$iframe = $('<iframe class="wysiwyg_iframe">').css({ 'min-height': '400px', width: '100%' @@ -146,19 +147,19 @@ Wysiwyg.include({ var avoidDoubleLoad = 0; // this bug only appears on some configurations. // resolve deferred on load - - var def = $.Deferred(); - this.$iframe.data('load-def', def); // for unit test - window.top[this._onUpdateIframeId] = function (_avoidDoubleLoad) { - if (_avoidDoubleLoad !== avoidDoubleLoad) { - console.warn('Wysiwyg iframe double load detected'); - return; - } - delete window.top[this._onUpdateIframeId]; - var $iframeTarget = this.$iframe.contents().find('#iframe_target'); - $iframeTarget.append(this.$target); - def.resolve(); - }.bind(this); + var def = new Promise(function (resolve) { + window.top[self._onUpdateIframeId] = function (_avoidDoubleLoad) { + if (_avoidDoubleLoad !== avoidDoubleLoad) { + console.warn('Wysiwyg iframe double load detected'); + return; + } + delete window.top[self._onUpdateIframeId]; + var $iframeTarget = self.$iframe.contents().find('#iframe_target'); + $iframeTarget.append(self.$target); + resolve(); + }; + }); + this.$iframe.data('loadDef', def); // for unit test // inject content in iframe @@ -182,7 +183,7 @@ Wysiwyg.include({ this.$iframe.insertAfter(this.$target); - return def.promise(); + return def; }, }); diff --git a/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js b/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js index 9ed6a89f6b6..66d8557d9c5 100644 --- a/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js +++ b/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js @@ -92,7 +92,7 @@ var SnippetEditor = Widget.extend({ }); } - return $.when.apply($, defs); + return Promise.all(defs); }, /** * @override @@ -161,7 +161,7 @@ var SnippetEditor = Widget.extend({ }); var $parent = this.$target.parent(); - this.$target.find('*').andSelf().tooltip('dispose'); + this.$target.find('*').addBack().tooltip('dispose'); this.$target.remove(); this.$el.remove(); @@ -325,7 +325,7 @@ var SnippetEditor = Widget.extend({ this.$el.find('[data-toggle="dropdown"]').dropdown(); - return $.when.apply($, defs); + return Promise.all(defs); }, //-------------------------------------------------------------------------- @@ -654,7 +654,7 @@ var SnippetsMenu = Widget.extend({ $(range && range.sc).closest('.o_default_snippet_text').removeClass('o_default_snippet_text'); }); - return $.when.apply($, defs).then(function () { + return Promise.all(defs).then(function () { // Trigger a resize event once entering edit mode as the snippets // menu will take part of the screen width (delayed because of // animation). (TODO wait for real animation end) @@ -675,9 +675,7 @@ var SnippetsMenu = Widget.extend({ } core.bus.off('deactivate_snippet', this, this._onDeactivateSnippet); core.bus.off('snippet_editor_clean_for_save', this, this._onCleanForSaveDemand); - if (this._defLoadSnippets.state() === "pending") { - delete this.cacheSnippetTemplate[this.options.snippets]; - } + delete this.cacheSnippetTemplate[this.options.snippets]; }, //-------------------------------------------------------------------------- @@ -722,8 +720,8 @@ var SnippetsMenu = Widget.extend({ /** * Sets the instance variables $editor, $body and selectorEditableArea. * - * @param {JQuery} $editor - * @param {String} selectorEditableArea + * @param {JQuery} $editor + * @param {String} selectorEditableArea */ setSelectorEditableArea: function ($editor, selectorEditableArea) { this.selectorEditableArea = selectorEditableArea; @@ -908,7 +906,7 @@ var SnippetsMenu = Widget.extend({ * @param {jQuery|false} $snippet * The DOM element whose editor need to be enabled. Only disable the * current one if false is given. - * @returns {Deferred<SnippetEditor>} + * @returns {Promise<SnippetEditor>} * (might be async when an editor must be created) */ _activateSnippet: function ($snippet) { @@ -917,7 +915,7 @@ var SnippetsMenu = Widget.extend({ $snippet = globalSelector.closest($snippet); } if (this.$activeSnippet && this.$activeSnippet[0] === $snippet[0]) { - return $.when($snippet.data('snippet-editor')); + return Promise.resolve($snippet.data('snippet-editor')); } } var editor = null; @@ -937,7 +935,7 @@ var SnippetsMenu = Widget.extend({ return editor; }); } - return $.when(editor); + return Promise.resolve(editor); }, /** * @private @@ -958,7 +956,7 @@ var SnippetsMenu = Widget.extend({ * @param {function} callback * Given two arguments: the snippet editor associated to the snippet * being managed and the DOM element of this snippet. - * @returns {Deferred} (might be async if snippet editors need to be created + * @returns {Promise} (might be async if snippet editors need to be created * and/or the callback is async) */ _callForEachChildSnippet: function ($snippet, callback) { @@ -971,7 +969,7 @@ var SnippetsMenu = Widget.extend({ } }); }); - return $.when.apply($, defs); + return Promise.all(defs); }, /** * Creates and returns a set of helper functions which can help finding @@ -1222,13 +1220,13 @@ var SnippetsMenu = Widget.extend({ * * @private * @param {jQuery} $snippet - * @returns {Deferred<SnippetEditor>} + * @returns {Promise<SnippetEditor>} */ _createSnippetEditor: function ($snippet) { var self = this; var snippetEditor = $snippet.data('snippet-editor'); if (snippetEditor) { - return $.when(snippetEditor); + return Promise.resolve(snippetEditor); } var def; @@ -1237,7 +1235,7 @@ var SnippetsMenu = Widget.extend({ def = this._createSnippetEditor($parent); } - return $.when(def).then(function (parentEditor) { + return Promise.resolve(def).then(function (parentEditor) { snippetEditor = new SnippetEditor(parentEditor || self, $snippet, self.templateOptions, self.getEditableArea(), self.options); self.snippetEditors.push(snippetEditor); return snippetEditor.appendTo(self.$snippetEditorArea); @@ -1348,7 +1346,7 @@ var SnippetsMenu = Widget.extend({ $toInsert.removeClass('oe_snippet_body'); if (!dropped && ui.position.top > 3 && ui.position.left + 50 > self.$el.outerWidth()) { - var $el = $.nearest({x: ui.position.left, y: ui.position.top}, '.oe_drop_zone').first(); + var $el = $.nearest({x: ui.position.left, y: ui.position.top}, '.oe_drop_zone', {container: document.body}).first(); if ($el.length) { $el.after($toInsert); dropped = true; diff --git a/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.options.js b/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.options.js index 802311f09d0..9ab2896540b 100644 --- a/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.options.js +++ b/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.options.js @@ -1245,7 +1245,7 @@ registry.many2one = SnippetOption.extend({ * * @private * @param {string} name - * @returns {Deferred} + * @returns {Promise} */ _findExisting: function (name) { var self = 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 f88ae46376f..c4ee569ae88 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 @@ -121,7 +121,7 @@ Wysiwyg.include({ } var defs = []; this.trigger_up('ready_to_save', {defs: defs}); - return $.when.apply($, defs) + return Promise.all(defs) .then(this.snippets.cleanForSave.bind(this.snippets)) .then(this._super.bind(this)); }, |
