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 3e68294cf8b..0158dd7e49c 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 @@ -8,9 +8,12 @@ var Dialog = require('wysiwyg.widgets.Dialog'); var _t = core._t; /** - * MediaDialog widget. Lets users change a media, including uploading a - * new image, font awsome or video and can change a media into an other - * media. + * Lets the user select a media. The media can be existing or newly uploaded. + * + * The media can be one of the following types: image, document, video or + * font awesome icon (only existing icons). + * + * The user may change a media into another one depending on the given options. */ var MediaDialog = Dialog.extend({ template: 'wysiwyg.widgets.media', @@ -18,7 +21,10 @@ var MediaDialog = Dialog.extend({ ['/web_editor/static/src/xml/wysiwyg.xml'] ), events: _.extend({}, Dialog.prototype.events, { - 'click a[data-toggle="tab"]': '_onTabChange', + 'click #editor-media-image-tab': '_onClickImageTab', + 'click #editor-media-document-tab': '_onClickDocumentTab', + 'click #editor-media-icon-tab': '_onClickIconTab', + 'click #editor-media-video-tab': '_onClickVideoTab', }), custom_events: _.extend({}, Dialog.prototype.custom_events || {}, { save_request: '_onSaveRequest', @@ -26,10 +32,15 @@ var MediaDialog = Dialog.extend({ /** * @constructor + * @param {Element} media */ init: function (parent, options, media) { - var self = this; - options = options || {}; + var $media = $(media); + + options = _.extend({}, options); + options.noDocuments = options.onlyImages || options.noDocuments; + options.noIcons = options.onlyImages || options.noIcons; + options.noVideos = options.onlyImages || options.noVideos; this._super(parent, _.extend({}, { title: _t("Select a Media"), @@ -44,86 +55,68 @@ var MediaDialog = Dialog.extend({ }, }); - this.media = media; - this.$media = $(media); - - this.multiImages = options.multiImages; - var onlyImages = options.onlyImages || this.multiImages; - this.noImages = options.noImages; - this.noDocuments = onlyImages || options.noDocuments; - this.noIcons = onlyImages || options.noIcons; - this.noVideos = onlyImages || options.noVideos; - - if (!this.noDocuments) { - this.documentDialog = new MediaModules.DocumentWidget(this, this.media, options); - this.documentDialog.tabToShow = 'document'; + if (!options.noImages) { + this.imageWidget = new MediaModules.ImageWidget(this, media, options); } - if (!this.noIcons) { - this.iconDialog = new MediaModules.IconWidget(this, this.media, options); - this.iconDialog.tabToShow = 'icon'; + if (!options.noDocuments) { + this.documentWidget = new MediaModules.DocumentWidget(this, media, options); } - if (!this.noVideos) { - this.videoDialog = new MediaModules.VideoWidget(this, this.media, options); - this.videoDialog.tabToShow = 'video'; + if (!options.noIcons) { + this.iconWidget = new MediaModules.IconWidget(this, media, options); } - if (!this.noImages) { - this.imageDialog = new MediaModules.ImageWidget(this, this.media, options); - this.imageDialog.tabToShow = 'image'; + if (!options.noVideos) { + this.videoWidget = new MediaModules.VideoWidget(this, media, options); } - this.active = this.imageDialog || this.documentDialog || this.iconDialog || this.videoDialog; - if (this.imageDialog && this.$media.is('img')) { - this.active = this.imageDialog; - } else if (this.documentDialog && this.$media.is('a.o_image')) { - this.active = this.documentDialog; - } else if (this.videoDialog && this.$media.hasClass('media_iframe_video')) { - this.active = this.videoDialog; - } else if (this.iconDialog && this.$media.is('span, i')) { - this.active = this.iconDialog; + if (this.imageWidget && $media.is('img')) { + this.activeWidget = this.imageWidget; + } else if (this.documentWidget && $media.is('a.o_image')) { + this.activeWidget = this.documentWidget; + } else if (this.videoWidget && $media.hasClass('media_iframe_video')) { + this.activeWidget = this.videoWidget; + } else if (this.iconWidget && $media.is('span, i')) { + this.activeWidget = this.iconWidget; + } else if (this.imageWidget) { + this.activeWidget = this.imageWidget; } - - this.opened(function () { - self.$('[href="#editor-media-' + self.active.tabToShow + '"]').tab('show'); - }); }, /** + * Adds the appropriate class to the current modal and appends the media + * widgets to their respective tabs. + * * @override */ start: function () { - var self = this; - var defs = [this._super.apply(this, arguments)]; - this.$modal.addClass('note-image-dialog'); + var promises = [this._super.apply(this, arguments)]; this.$modal.find('.modal-dialog').addClass('o_select_media_dialog'); - if (this.imageDialog) { - this.imageDialog.clear(); + if (this.imageWidget) { + this.imageWidget.clear(); } - if (this.documentDialog) { - this.documentDialog.clear(); + if (this.documentWidget) { + this.documentWidget.clear(); } - if (this.iconDialog) { - this.iconDialog.clear(); + if (this.iconWidget) { + this.iconWidget.clear(); } - if (this.videoDialog) { - this.videoDialog.clear(); + if (this.videoWidget) { + this.videoWidget.clear(); } - if (this.imageDialog) { - defs.push(this.imageDialog.appendTo(this.$("#editor-media-image"))); + if (this.imageWidget) { + promises.push(this.imageWidget.appendTo(this.$("#editor-media-image"))); } - if (this.documentDialog) { - defs.push(this.documentDialog.appendTo(this.$("#editor-media-document"))); + if (this.documentWidget) { + promises.push(this.documentWidget.appendTo(this.$("#editor-media-document"))); } - if (this.iconDialog) { - defs.push(this.iconDialog.appendTo(this.$("#editor-media-icon"))); + if (this.iconWidget) { + promises.push(this.iconWidget.appendTo(this.$("#editor-media-icon"))); } - if (this.videoDialog) { - defs.push(this.videoDialog.appendTo(this.$("#editor-media-video"))); + if (this.videoWidget) { + promises.push(this.videoWidget.appendTo(this.$("#editor-media-video"))); } - return Promise.all(defs).then(function () { - self._setActive(self.active); - }); + return Promise.all(promises); }, //-------------------------------------------------------------------------- @@ -131,35 +124,97 @@ var MediaDialog = Dialog.extend({ //-------------------------------------------------------------------------- /** + * Returns whether the document widget is currently active. + * + * @returns {boolean} + */ + isDocumentActive: function () { + return this.activeWidget === this.documentWidget; + }, + /** + * Returns whether the icon widget is currently active. + * + * @returns {boolean} + */ + isIconActive: function () { + return this.activeWidget === this.iconWidget; + }, + /** + * Returns whether the image widget is currently active. + * + * @returns {boolean} + */ + isImageActive: function () { + return this.activeWidget === this.imageWidget; + }, + /** + * Returns whether the video widget is currently active. + * + * @returns {boolean} + */ + isVideoActive: function () { + return this.activeWidget === this.videoWidget; + }, + /** + * Saves the currently selected media from the currently active widget. + * + * The save event data `final_data` will be one Element in general, but it + * will be an Array of Element if `multiImages` is set. + * * @override */ save: function () { var self = this; var _super = this._super; var args = arguments; - return Promise.resolve(this.active.save()).then(function (data) { + return Promise.resolve(this.activeWidget.save()).then(function (data) { self.final_data = data; return _super.apply(self, args); }); }, - //-------------------------------------------------------------------------- - // - //-------------------------------------------------------------------------- - - /** - * @private - * @param {Object} widget - */ - _setActive: function (widget) { - this.active = widget; - }, - //-------------------------------------------------------------------------- // Handlers //-------------------------------------------------------------------------- /** + * Sets the document widget as the active widget. + * + * @private + */ + _onClickDocumentTab: function () { + this.activeWidget = this.documentWidget; + }, + /** + * Sets the icon widget as the active widget. + * + * @private + */ + _onClickIconTab: function () { + this.activeWidget = this.iconWidget; + }, + /** + * Sets the image widget as the active widget. + * + * @private + */ + _onClickImageTab: function () { + this.activeWidget = this.imageWidget; + }, + /** + * Sets the video widget as the active widget. + * + * @private + */ + _onClickVideoTab: function () { + this.activeWidget = this.videoWidget; + }, + /** + * Handles save request from the child widgets. + * + * This is for usability, to allow the user to save from other ways than + * click on the modal button, such as double clicking a media to select it. + * * @private * @param {OdooEvent} ev */ @@ -167,22 +222,6 @@ var MediaDialog = Dialog.extend({ ev.stopPropagation(); this.save(); }, - /** - * @private - * @param {JQueryEvent} ev - */ - _onTabChange: function (ev) { - var $target = $(ev.target); - if ($target.is('[href="#editor-media-image"]')) { - this._setActive(this.imageDialog); - } else if ($target.is('[href="#editor-media-document"]')) { - this._setActive(this.documentDialog); - } else if ($target.is('[href="#editor-media-icon"]')) { - this._setActive(this.active = this.iconDialog); - } else if ($target.is('[href="#editor-media-video"]')) { - this._setActive(this.active = this.videoDialog); - } - }, }); return MediaDialog; diff --git a/addons/web_editor/static/src/xml/wysiwyg.xml b/addons/web_editor/static/src/xml/wysiwyg.xml index 9a93066ee48..00d2878f8c1 100644 --- a/addons/web_editor/static/src/xml/wysiwyg.xml +++ b/addons/web_editor/static/src/xml/wysiwyg.xml @@ -68,17 +68,17 @@