diff options
Diffstat (limited to 'addons/web_editor/static/src/js')
10 files changed, 155 insertions, 148 deletions
diff --git a/addons/web_editor/static/src/js/editor/rte.js b/addons/web_editor/static/src/js/editor/rte.js index f4f7f82506b..06caaf65990 100644 --- a/addons/web_editor/static/src/js/editor/rte.js +++ b/addons/web_editor/static/src/js/editor/rte.js @@ -316,7 +316,7 @@ var RTEWidget = Widget.extend({ $('body').addClass('editor_enable'); - $(document) + $(document.body) .tooltip({ selector: '[data-oe-readonly]', container: 'body', @@ -364,7 +364,7 @@ var RTEWidget = Widget.extend({ $(document).off('click.rte keyup.rte mousedown.rte activate.rte mouseup.rte'); $(document).off('content_changed').removeClass('o_is_inline_editable').removeData('rte'); - $(document).tooltip('destroy'); + $(document).tooltip('dispose'); $('body').removeClass('editor_enable'); this.trigger('rte:stop'); }, diff --git a/addons/web_editor/static/src/js/editor/rte.summernote.js b/addons/web_editor/static/src/js/editor/rte.summernote.js index 3626d5d3ec0..b641839286c 100644 --- a/addons/web_editor/static/src/js/editor/rte.summernote.js +++ b/addons/web_editor/static/src/js/editor/rte.summernote.js @@ -85,10 +85,6 @@ renderer.tplPopovers = function (lang, options) { var $linkPopover = $popover.find('.note-link-popover'); var $airPopover = $popover.find('.note-air-popover'); - if (window === window.top) { - $popover.children().addClass("hidden-xs"); - } - //////////////// image popover // add center button for images @@ -104,11 +100,11 @@ renderer.tplPopovers = function (lang, options) { var $padding = $('<div class="btn-group"/>'); $padding.insertBefore($imagePopover.find('.btn-group:first')); var dropdown_content = [ - '<li><a data-event="padding" href="#" data-value="">'+_t('None')+'</a></li>', - '<li><a data-event="padding" href="#" data-value="small">'+_t('Small')+'</a></li>', - '<li><a data-event="padding" href="#" data-value="medium">'+_t('Medium')+'</a></li>', - '<li><a data-event="padding" href="#" data-value="large">'+_t('Large')+'</a></li>', - '<li><a data-event="padding" href="#" data-value="xl">'+_t('Xl')+'</a></li>', + '<li><a class="dropdown-item" data-event="padding" href="#" data-value="">'+_t('None')+'</a></li>', + '<li><a class="dropdown-item" data-event="padding" href="#" data-value="small">'+_t('Small')+'</a></li>', + '<li><a class="dropdown-item" data-event="padding" href="#" data-value="medium">'+_t('Medium')+'</a></li>', + '<li><a class="dropdown-item" data-event="padding" href="#" data-value="large">'+_t('Large')+'</a></li>', + '<li><a class="dropdown-item" data-event="padding" href="#" data-value="xl">'+_t('Xl')+'</a></li>', ]; $(tplIconButton('fa fa-plus-square-o', { title: _t('Padding'), @@ -121,10 +117,10 @@ renderer.tplPopovers = function (lang, options) { title: _t('Shadow'), event: 'imageShape', value: 'shadow' - })).insertAfter($imagePopover.find('[data-event="imageShape"][data-value="img-circle"]')); + })).insertAfter($imagePopover.find('[data-event="imageShape"][data-value="rounded-circle"]')); // add spin for fa - var $spin = $('<div class="btn-group hidden only_fa"/>').insertAfter($button.parent()); + var $spin = $('<div class="btn-group d-none only_fa"/>').insertAfter($button.parent()); $(tplIconButton('fa fa-refresh', { title: _t('Spin'), event: 'imageShape', @@ -132,7 +128,7 @@ renderer.tplPopovers = function (lang, options) { })).appendTo($spin); // resize for fa - var $resizefa = $('<div class="btn-group hidden only_fa"/>') + var $resizefa = $('<div class="btn-group d-none only_fa"/>') .insertAfter($imagePopover.find('.btn-group:has([data-event="resize"])')); for (var size=1; size<=5; size++) { $(tplButton('<span class="note-fontsize-10">'+size+'x</span>', { @@ -142,7 +138,7 @@ renderer.tplPopovers = function (lang, options) { })).appendTo($resizefa); } var $colorfa = $airPopover.find('.note-color').clone(); - $colorfa.find("ul.dropdown-menu").css('min-width', '172px'); + $colorfa.find(".dropdown-menu").css('min-width', '172px'); $resizefa.after($colorfa); // show dialog box and delete @@ -168,7 +164,7 @@ renderer.tplPopovers = function (lang, options) { var $alt = $('<div class="btn-group"/>'); $alt.appendTo($imagePopover.find('.popover-content')); - $alt.append('<button class="btn btn-default btn-sm btn-small" data-event="alt"><strong>' + _t('Description') + ': </strong><span class="o_image_alt"/></button>'); + $alt.append('<button class="btn btn-secondary" data-event="alt"><strong>' + _t('Description') + ': </strong><span class="o_image_alt"/></button>'); //////////////// link popover @@ -187,16 +183,16 @@ renderer.tplPopovers = function (lang, options) { while (node && (!node.tagName || (!node.tagName || formats.indexOf(node.tagName.toLowerCase()) === -1))) { node = node.parentNode; } - $format.parent().removeClass('active'); + $format.removeClass('active'); $format.filter('[data-value="'+(node ? node.tagName.toLowerCase() : "p")+'"]') - .parent().addClass("active"); + .addClass("active"); }); //////////////// tooltip setTimeout(function () { $airPopover.add($linkPopover).add($imagePopover).find("button") - .tooltip('destroy') + .tooltip('dispose') .tooltip({ container: 'body', trigger: 'hover', @@ -220,22 +216,22 @@ eventHandler.modules.popover.button.update = function ($container, oStyle) { fn_boutton_update.call(this, $container, oStyle); - $container.find('.note-color').removeClass("hidden"); + $container.find('.note-color').removeClass('d-none'); if (oStyle.image) { - $container.find('[data-event]').parent().removeClass("active"); + $container.find('[data-event]').removeClass("active"); - $container.find('a[data-event="padding"][data-value="small"]').parent().toggleClass("active", $(oStyle.image).hasClass("padding-small")); - $container.find('a[data-event="padding"][data-value="medium"]').parent().toggleClass("active", $(oStyle.image).hasClass("padding-medium")); - $container.find('a[data-event="padding"][data-value="large"]').parent().toggleClass("active", $(oStyle.image).hasClass("padding-large")); - $container.find('a[data-event="padding"][data-value="xl"]').parent().toggleClass("active", $(oStyle.image).hasClass("padding-xl")); - $container.find('a[data-event="padding"][data-value=""]').parent().toggleClass("active", !$container.find('.active a[data-event="padding"]').length); + $container.find('a[data-event="padding"][data-value="small"]').toggleClass("active", $(oStyle.image).hasClass("padding-small")); + $container.find('a[data-event="padding"][data-value="medium"]').toggleClass("active", $(oStyle.image).hasClass("padding-medium")); + $container.find('a[data-event="padding"][data-value="large"]').toggleClass("active", $(oStyle.image).hasClass("padding-large")); + $container.find('a[data-event="padding"][data-value="xl"]').toggleClass("active", $(oStyle.image).hasClass("padding-xl")); + $container.find('a[data-event="padding"][data-value=""]').toggleClass("active", !$container.find('.active a[data-event="padding"]').length); $(oStyle.image).addClass('o_we_selected_image'); if (dom.isImgFont(oStyle.image)) { - $container.find('.btn-group:not(.only_fa):has(button[data-event="resize"],button[data-value="img-thumbnail"])').addClass("hidden"); - $container.find('.only_fa').removeClass("hidden"); + $container.find('.btn-group:not(.only_fa):has(button[data-event="resize"],button[data-value="img-thumbnail"])').addClass('d-none'); + $container.find('.only_fa').removeClass('d-none'); $container.find('button[data-event="resizefa"][data-value="2"]').toggleClass("active", $(oStyle.image).hasClass("fa-2x")); $container.find('button[data-event="resizefa"][data-value="3"]').toggleClass("active", $(oStyle.image).hasClass("fa-3x")); $container.find('button[data-event="resizefa"][data-value="4"]').toggleClass("active", $(oStyle.image).hasClass("fa-4x")); @@ -246,8 +242,8 @@ eventHandler.modules.popover.button.update = function ($container, oStyle) { $container.find('button[data-event="imageShape"][data-value="shadow"]').toggleClass("active", $(oStyle.image).hasClass("shadow")); } else { - $container.find('.hidden:not(.only_fa)').removeClass("hidden"); - $container.find('.only_fa').addClass("hidden"); + $container.find('.d-none:not(.only_fa)').removeClass('d-none'); + $container.find('.only_fa').addClass('d-none'); var width = ($(oStyle.image).attr('style') || '').match(/(^|;|\s)width:\s*([0-9]+%)/); if (width) { width = width[2]; @@ -260,15 +256,15 @@ eventHandler.modules.popover.button.update = function ($container, oStyle) { $container.find('button[data-event="imageShape"][data-value="shadow"]').toggleClass("active", $(oStyle.image).hasClass("shadow")); if (!$(oStyle.image).is("img")) { - $container.find('.btn-group:has(button[data-event="imageShape"])').addClass("hidden"); + $container.find('.btn-group:has(button[data-event="imageShape"])').addClass('d-none'); } - $container.find('.note-color').addClass("hidden"); + $container.find('.note-color').addClass('d-none'); } - $container.find('button[data-event="floatMe"][data-value="left"]').toggleClass("active", $(oStyle.image).hasClass("pull-left")); - $container.find('button[data-event="floatMe"][data-value="center"]').toggleClass("active", $(oStyle.image).hasClass("center-block")); - $container.find('button[data-event="floatMe"][data-value="right"]').toggleClass("active", $(oStyle.image).hasClass("pull-right")); + $container.find('button[data-event="floatMe"][data-value="left"]').toggleClass("active", $(oStyle.image).hasClass("float-left")); + $container.find('button[data-event="floatMe"][data-value="center"]').toggleClass("active", $(oStyle.image).hasClass("d-block mx-auto")); + $container.find('button[data-event="floatMe"][data-value="right"]').toggleClass("active", $(oStyle.image).hasClass("float-right")); $(oStyle.image).trigger('attributes_change'); } @@ -360,9 +356,9 @@ eventHandler.modules.editor.floatMe = function ($editable, sValue) { var $target = $(getImgTarget($editable)); $editable.data('NoteHistory').recordUndo(); switch (sValue) { - case 'center': $target.toggleClass('center-block').removeClass('pull-right pull-left'); break; - case 'left': $target.toggleClass('pull-left').removeClass('pull-right center-block'); break; - case 'right': $target.toggleClass('pull-right').removeClass('pull-left center-block'); break; + case 'center': $target.toggleClass('d-block mx-auto').removeClass('float-right float-left'); break; + case 'left': $target.toggleClass('float-left').removeClass('float-right d-block mx-auto'); break; + case 'right': $target.toggleClass('float-right').removeClass('float-left d-block mx-auto'); break; } }; eventHandler.modules.editor.imageShape = function ($editable, sValue) { @@ -895,7 +891,7 @@ eventHandler.attach = function (oLayoutInfo, options) { if (!show_tooltip) return; $target.tooltip({title: _t('Double-click to edit'), trigger: 'manuel', container: 'body'}).tooltip('show'); setTimeout(function () { - $target.tooltip('destroy'); + $target.tooltip('dispose'); }, 800); }, 400); }); diff --git a/addons/web_editor/static/src/js/editor/snippets.editor.js b/addons/web_editor/static/src/js/editor/snippets.editor.js index cbaa7a2fbbc..e3a8803619a 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -76,7 +76,7 @@ var SnippetEditor = Widget.extend({ var $clone = $(this).clone().css({width: '24px', height: '24px', border: 0}); $clone.find('.oe_overlay_options >:not(:contains(.oe_snippet_move)), .o_handle').remove(); $clone.find(':not(.glyphicon)').css({position: 'absolute', top: 0, left: 0}); - $clone.appendTo('body').removeClass('hidden'); + $clone.appendTo('body').removeClass('d-none'); return $clone; }, start: _.bind(self._onDragAndDropStart, self), @@ -153,7 +153,7 @@ var SnippetEditor = Widget.extend({ }); var $parent = this.$target.parent(); - this.$target.find('*').andSelf().tooltip('destroy'); + this.$target.find('*').andSelf().tooltip('dispose'); this.$target.remove(); this.$el.remove(); @@ -199,7 +199,7 @@ var SnippetEditor = Widget.extend({ // Attach own and parent options on the current overlay var $style_button = this.$el.find('.oe_options'); - var $ul = $style_button.find('ul:first'); + var $ul = $style_button.find('.dropdown-menu:first'); var $headers = $ul.find('.dropdown-header:data(editor)'); _.each($headers, (function (el) { var $el = $(el); @@ -214,11 +214,11 @@ var SnippetEditor = Widget.extend({ count++; } }); - $el.toggleClass('hidden', count === 0); + $el.toggleClass('d-none', count === 0); }).bind(this)); // Activate the overlay - $style_button.toggleClass('hidden', $ul.children(':not(.o_main_header):not(.divider):not(.hidden)').length === 0); + $style_button.toggleClass('d-none', $ul.children(':not(.o_main_header):not(.dropdown-divider):not(.d-none)').length === 0); this.cover(); this.$el.toggleClass('oe_active', !!focus); @@ -262,13 +262,13 @@ var SnippetEditor = Widget.extend({ _initializeOptions: function () { var self = this; var $styles = this.$el.find('.oe_options'); - var $ul = $styles.find('ul:first'); + var $ul = $styles.find('.dropdown-menu:first'); this.styles = {}; this.selectorSiblings = []; this.selectorChildren = []; var i = 0; - $ul.append($('<li/>', {class: 'dropdown-header o_main_header', text: this._getName()}).data('editor', this)); + $ul.append($('<div/>', {class: 'dropdown-header o_main_header', text: this._getName()}).data('editor', this)); var defs = _.map(this.templateOptions, function (val, option_id) { if (!val.selector.is(self.$target)) { return; @@ -277,7 +277,7 @@ var SnippetEditor = Widget.extend({ if (val['drop-in']) self.selectorChildren.push(val['drop-in']); var optionName = val.option; - var $el = val.$el.children('li').clone(true).addClass('snippet-option-' + optionName); + var $el = val.$el.children().clone(true).addClass('snippet-option-' + optionName); var option = new (options.registry[optionName] || options.Class)( self, val.base_target ? self.$target.find(val.base_target).eq(0) : self.$target, @@ -288,7 +288,7 @@ var SnippetEditor = Widget.extend({ option.__order = i++; return option.attachTo($el); }); - $ul.append($('<li/>', {class: 'divider'})); + $ul.append($('<div/>', {class: 'dropdown-divider'})); var $parents = this.$target.parents(); _.each($parents, function (parent) { @@ -296,7 +296,7 @@ var SnippetEditor = Widget.extend({ if (parentEditor) { for (var styleName in parentEditor.styles) { if (!parentEditor.styles[styleName].preventChildPropagation) { - $ul.append($('<li/>', {class: 'dropdown-header o_parent_editor_header', text: parentEditor._getName()}).data('editor', parentEditor)); + $ul.append($('<div/>', {class: 'dropdown-header o_parent_editor_header', text: parentEditor._getName()}).data('editor', parentEditor)); break; } } @@ -304,7 +304,7 @@ var SnippetEditor = Widget.extend({ }); if (!this.selectorSiblings.length && !this.selectorChildren.length) { - this.$el.find('.oe_snippet_move, .oe_snippet_clone').addClass('hidden'); + this.$el.find('.oe_snippet_move, .oe_snippet_clone').addClass('d-none'); } this.$el.find('[data-toggle="dropdown"]').dropdown(); @@ -362,7 +362,7 @@ var SnippetEditor = Widget.extend({ }; self.$target.after('<div class="oe_drop_clone" style="display: none;"/>'); self.$target.detach(); - self.$el.addClass('hidden'); + self.$el.addClass('d-none'); var $selectorSiblings; for (var i = 0 ; i < self.selectorSiblings.length ; i++) { @@ -419,7 +419,7 @@ var SnippetEditor = Widget.extend({ } $clone.after(this.$target); - this.$el.removeClass('hidden'); + this.$el.removeClass('d-none'); $('body').removeClass('move-important'); $clone.remove(); @@ -987,7 +987,7 @@ var SnippetsMenu = Widget.extend({ self.templateOptions.push(option); selectors.push(option.selector); }); - $styles.addClass('hidden'); + $styles.addClass('d-none'); globalSelector.closest = function ($from) { var $temp; @@ -1052,7 +1052,7 @@ var SnippetsMenu = Widget.extend({ if (moduleID) { $snippet.addClass('o_snippet_install'); var $installBtn = $('<a/>', { - class: 'btn btn-primary btn-sm o_install_btn', + class: 'btn btn-primary o_install_btn', target: '_blank', href: '/web#id=' + moduleID + '&view_type=form&model=ir.module.module&action=base.open_module_tree', text: _t("Install"), @@ -1218,14 +1218,14 @@ var SnippetsMenu = Widget.extend({ $('.oe_drop_zone').droppable({ over: function () { dropped = true; - $(this).first().after($toInsert).addClass('hidden'); + $(this).first().after($toInsert).addClass('d-none'); }, out: function () { var prev = $toInsert.prev(); if (this === prev[0]) { dropped = false; $toInsert.detach(); - $(this).removeClass('hidden'); + $(this).removeClass('d-none'); } }, }); diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js index 097f3d3b12f..199c3a0b8ad 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -17,10 +17,10 @@ var _t = core._t; */ var SnippetOption = Widget.extend({ events: { - 'mouseenter a': '_onLinkEnter', - 'click a': '_onLinkClick', + 'mouseenter': '_onLinkEnter', + 'click': '_onLinkClick', 'mouseleave': '_onMouseleave', - 'mouseleave ul': '_onMouseleave', + 'mouseleave .dropdown-menu': '_onMouseleave', }, /** * When editing a snippet, its options are shown alongside the ones of its @@ -30,7 +30,7 @@ var SnippetOption = Widget.extend({ preventChildPropagation: false, /** - * The option `$el` is supposed to be the associated <li/> element in the + * The option `$el` is supposed to be the associated DOM element in the * options dropdown. The option controls another DOM element: the snippet it * customizes, which can be found at `$target`. Access to the whole edition * overlay is possible with `$overlay` (this is not recommended though). @@ -115,18 +115,18 @@ var SnippetOption = Widget.extend({ /** * Default option method which allows to select one and only one class in * the option classes set and set it on the associated snippet. The common - * case is having a subdropdown with each <li/> having a `data-select-class` + * case is having a subdropdown with each item having a `data-select-class` * value allowing to choose the associated class. * * @param {boolean|string} previewMode * - truthy if the option is enabled for preview or if leaving it (in * that second case, the value is 'reset') * - false if the option should be activated for good - * @param {*} value - the class to activate ($li.data('selectClass')) - * @param {jQuery} $li - the related DOMElement option + * @param {*} value - the class to activate ($opt.data('selectClass')) + * @param {jQuery} $opt - the related DOMElement option */ - selectClass: function (previewMode, value, $li) { - var $group = $li && $li.closest('.dropdown-submenu'); + selectClass: function (previewMode, value, $opt) { + var $group = $opt && $opt.closest('.dropdown-submenu'); if (!$group || !$group.length) { $group = this.$el; } @@ -141,12 +141,12 @@ var SnippetOption = Widget.extend({ /** * Default option method which allows to select one or multiple classes in * the option classes set and set it on the associated snippet. The common - * case is having a subdropdown with each <li/> having a `data-toggle-class` + * case is having a subdropdown with each item having a `data-toggle-class` * value allowing to toggle the associated class. * * @see this.selectClass */ - toggleClass: function (previewMode, value, $li) { + toggleClass: function (previewMode, value, $opt) { var $lis = this.$el.find('[data-toggle-class]').addBack('[data-toggle-class]'); var classes = $lis.map(function () {return $(this).data('toggleClass');}).get().join(' '); var activeClasses = $lis.filter('.active, :has(.active)').map(function () {return $(this).data('toggleClass');}).get().join(' '); @@ -163,7 +163,7 @@ var SnippetOption = Widget.extend({ /** * Override the helper method to search inside the $target element instead - * of the dropdown <li/> element. + * of the dropdown item element. * * @override */ @@ -225,13 +225,13 @@ var SnippetOption = Widget.extend({ * - truthy if the option is enabled for preview or if leaving it (in * that second case, the value is 'reset') * - false if the option should be activated for good - * @param {jQuery} $li - the related DOMElement option + * @param {jQuery} $opt - the related DOMElement option */ - _select: function (previewMode, $li) { + _select: function (previewMode, $opt) { var self = this; // Options can say they respond to strong choice - if (previewMode && ($li.data('noPreview') || $li.parent().data('noPreview'))) { + if (previewMode && ($opt.data('noPreview') || $opt.parent().data('noPreview'))) { return; } // If it is not preview mode, the user selected the option for good @@ -243,7 +243,7 @@ var SnippetOption = Widget.extend({ // Search for methods (data-...) (i.e. data-toggle-class) on the // selected (sub)option and its parents - var el = $li[0]; + var el = $opt[0]; var methods = []; do { methods.push([el, el.dataset]); @@ -302,20 +302,25 @@ var SnippetOption = Widget.extend({ * @param {Event} ev */ _onLinkEnter: function (ev) { - var $li = $(ev.currentTarget).parent(); - if ($li.is('.dropdown-submenu')) { - var $menu = $li.children('.dropdown-menu'); + var $opt = $(ev.target); + if (!$opt.hasClass('dropdown-item')) { + return; + } + + var $dsmenu = $opt.parent('.dropdown-submenu'); + if ($dsmenu.length) { + var $menu = $dsmenu.children('.dropdown-menu'); // FIXME if ($menu.length) { - var menuRightPosition = $li.offset().left + $li.outerWidth() + $menu.outerWidth(); + var menuRightPosition = $dsmenu.offset().left + $dsmenu.outerWidth() + $menu.outerWidth(); $menu.toggleClass('o_open_to_left', menuRightPosition > $(window).outerWidth()); } } - if (!$li.is(':hasData')) { + if (!$opt.is(':hasData')) { return; } this.__click = false; - this._select(true, $li); + this._select(true, $opt); this.$target.trigger('snippet-option-preview', [this]); }, /** @@ -325,13 +330,14 @@ var SnippetOption = Widget.extend({ * @param {Event} ev */ _onLinkClick: function (ev) { - var $li = $(ev.currentTarget).parent(':hasData'); - if (!$li.length) { + var $opt = $(ev.target); + if (!$opt.hasClass('dropdown-item') || !$opt.is(':hasData')) { return; } + ev.preventDefault(); this.__click = true; - this._select(false, $li); + this._select(false, $opt); this.$target.trigger('snippet-option-change', [this]); }, /** @@ -660,10 +666,10 @@ registry.colorpicker = SnippetOption.extend({ var $palette_def = $tabs.find('div[data-name="' + self.data.paletteDefault + '"]'); var pos = $tabs.find('> div').index($palette_def); - $toggles.children('li').eq(pos).addClass('active'); + $toggles.children('li').eq(pos).find('a').addClass('active'); $palette_def.addClass('active'); } else { - $toggles.find('li').first().addClass('active'); + $toggles.find('li').first().find('a').addClass('active'); $tabs.find('div').first().addClass('active'); } @@ -678,7 +684,7 @@ registry.colorpicker = SnippetOption.extend({ $toggles.parent().empty().append($clpicker); } - this.$el.find('li').append($pt); + this.$el.find('.dropdown-menu').append($pt); } var classes = []; @@ -781,7 +787,7 @@ registry.background = SnippetOption.extend({ * * @see this.selectClass for parameters */ - background: function (previewMode, value, $li) { + background: function (previewMode, value, $opt) { if (previewMode === 'reset' && value === undefined) { // No background has been selected and we want to reset back to the // original custom image @@ -800,25 +806,25 @@ registry.background = SnippetOption.extend({ /** * @override */ - selectClass: function (previewMode, value, $li) { - this.background(previewMode, '', $li); - this._super(previewMode, value ? (value + ' oe_img_bg') : value, $li); + selectClass: function (previewMode, value, $opt) { + this.background(previewMode, '', $opt); + this._super(previewMode, value ? (value + ' oe_img_bg') : value, $opt); }, /** * Opens a media dialog to add a custom background image. * * @see this.selectClass for parameters */ - chooseImage: function (previewMode, value, $li) { + chooseImage: function (previewMode, value, $opt) { // Put fake image in the DOM, edit it and use it as background-image - var $image = $('<img/>', {class: 'hidden', src: value}).appendTo(this.$target); + var $image = $('<img/>', {class: 'd-none', src: value}).appendTo(this.$target); var $editable = this.$target.closest('.o_editable'); var _editor = new weWidgets.MediaDialog(this, { onlyImages: true, firstFilters: ['background'], res_model: $editable.data('oe-model'), - res_id: $editable.data('oe-id'), + res_id: $editable.data('oe-id'), }, null, $image[0]).open(); _editor.on('save', this, function () { @@ -881,7 +887,7 @@ registry.background = SnippetOption.extend({ this._super.apply(this, arguments); var src = this._getSrcFromCssValue(); - this.$el.find('li[data-background]') + this.$el.find('[data-background]') .removeClass('active') .filter(function () { var bgOption = $(this).data('background'); @@ -889,7 +895,7 @@ registry.background = SnippetOption.extend({ }) .addClass('active'); - this.$el.find('li[data-choose-image]').toggleClass('active', this.$target.hasClass('oe_custom_bg')); + this.$el.find('[data-choose-image]').toggleClass('active', this.$target.hasClass('oe_custom_bg')); }, /** * Sets the given value as custom background image. @@ -926,7 +932,7 @@ registry.background_position = SnippetOption.extend({ * @override */ onFocus: function () { - this.$el.toggleClass('hidden', this.$target.css('background-image') === 'none'); + this.$el.toggleClass('d-none', this.$target.css('background-image') === 'none'); }, //-------------------------------------------------------------------------- @@ -938,7 +944,7 @@ registry.background_position = SnippetOption.extend({ * * @see this.selectClass for parameters */ - backgroundPosition: function (previewMode, value, $li) { + backgroundPosition: function (previewMode, value, $opt) { var self = this; this.previous_state = [this.$target.attr('class'), this.$target.css('background-size'), this.$target.css('background-position')]; @@ -988,7 +994,7 @@ registry.background_position = SnippetOption.extend({ var img_url = /\(['"]?([^'"]+)['"]?\)/g.exec(self.$target.css('background-image')); img_url = (img_url && img_url[1]) || ''; - var $img = $('<img/>', {class: 'img img-responsive', src: img_url}); + var $img = $('<img/>', {class: 'img img-fluid', src: img_url}); $img.on('load', function () { self._bindImageEvents($img); }); @@ -1153,8 +1159,8 @@ registry.many2one = SnippetOption.extend({ // move menu item setTimeout(function () { - if (self.$overlay.find('.oe_options').hasClass('hidden')) { - self.$btn.css('height', '0').find('> a').addClass('hidden'); + if (self.$overlay.find('.oe_options').hasClass('d-none')) { + self.$btn.css('height', '0').find('> a').addClass('d-none'); self.$ul.show().css({ 'top': '-24px', 'margin': '0', 'padding': '2px 0', 'position': 'relative' }); diff --git a/addons/web_editor/static/src/js/editor/summernote.js b/addons/web_editor/static/src/js/editor/summernote.js index 657a8bbac8c..784aab3493e 100644 --- a/addons/web_editor/static/src/js/editor/summernote.js +++ b/addons/web_editor/static/src/js/editor/summernote.js @@ -958,15 +958,15 @@ range.WrappedRange.prototype.isContentEditable = function () { renderer.tplButtonInfo.fontsize = function (lang, options) { var items = options.fontSizes.reduce(function (memo, v) { - return memo + '<li><a data-event="fontSize" href="#" data-value="' + v + '">' + + return memo + '<a data-event="fontSize" href="#" class="dropdown-item" data-value="' + v + '">' + '<i class="fa fa-check"></i> ' + v + - '</a></li>'; + '</a>'; }, ''); var sLabel = '<span class="note-current-fontsize">11</span>'; return renderer.getTemplate().button(sLabel, { title: lang.font.size, - dropdown: '<ul class="dropdown-menu">' + items + '</ul>' + dropdown: '<div class="dropdown-menu">' + items + '</div>' }); }; diff --git a/addons/web_editor/static/src/js/editor/translator.js b/addons/web_editor/static/src/js/editor/translator.js index e3ba65a54d7..a24e438affc 100644 --- a/addons/web_editor/static/src/js/editor/translator.js +++ b/addons/web_editor/static/src/js/editor/translator.js @@ -63,7 +63,7 @@ var AttributeTranslateDialog = weWidgets.Dialog.extend({ var $group = $('<div/>', {class: 'form-group'}).appendTo(this.$el); _.each(this.translation, function (node, attr) { var $node = $(node); - var $label = $('<label class="control-label"></label>').text(attr); + var $label = $('<label class="col-form-label"></label>').text(attr); var $input = $('<input class="form-control"/>').val($node.html()); $input.on('change keyup', function () { var value = $input.val(); @@ -138,7 +138,7 @@ var TranslatorMenuBar = Widget.extend({ var translation = $node.data('translation') || {}; var trans = $node.attr(attr); var match = trans.match(/<span [^>]*data-oe-translation-id="([0-9]+)"[^>]*>(.*)<\/span>/); - var $trans = $(trans).addClass('hidden o_editable o_editable_translatable_attribute').appendTo('body'); + var $trans = $(trans).addClass('d-none o_editable o_editable_translatable_attribute').appendTo('body'); $trans.data('$node', $node).data('attribute', attr); translation[attr] = $trans[0]; $node.attr(attr, match[2]); diff --git a/addons/web_editor/static/src/js/inline.js b/addons/web_editor/static/src/js/inline.js index 7409f9190f3..fb2247313bd 100644 --- a/addons/web_editor/static/src/js/inline.js +++ b/addons/web_editor/static/src/js/inline.js @@ -10,7 +10,7 @@ var snippet_editor = require('web_editor.snippet.editor'); weWidgets.MediaDialog.include({ start: function () { - this.$('[href="#editor-media-video"]').addClass('hidden'); + this.$('[href="#editor-media-video"]').addClass('d-none'); return this._super.apply(this, arguments); }, }); diff --git a/addons/web_editor/static/src/js/tours/rte.js b/addons/web_editor/static/src/js/tours/rte.js index 82c31da5259..54736b4a290 100644 --- a/addons/web_editor/static/src/js/tours/rte.js +++ b/addons/web_editor/static/src/js/tours/rte.js @@ -29,15 +29,15 @@ tour.register('rte', { '<section>\n'+ ' <div class="container" style="width: 600px;">\n'+ ' <div class="row">\n'+ - ' <div class="col-md-6 mt16">\n'+ + ' <div class="col-lg-6 mt16">\n'+ '<h1 id="text_content_id">Batnae municipium in Anthemusia</h1> \n'+ ' <p>Batnae municipium in Anthemusia conditum Macedonum manu priscorum ab Euphrate flumine brevi spatio disparatur, refertum mercatoribus opulentis, ubi annua sollemnitate prope Septembris initium mensis ad.</p>\n'+ ' <p> Quam <img style="width: 25%" src="/web/static/src/img/logo.png"/> quidem <span class="fa fa-flag fa-2x"></span> partem accusationis admiratus sum et moleste tuli potissimum esse Atratino datam. Neque enim decebat neque aetas.</p>\n'+ ' <p>Et hanc quidem praeter oppida multa duae civitates exornant Seleucia opus Seleuci regis, et Claudiopolis quam deduxit coloniam Claudius Caesar. Isaura enim antehac nimium potens, olim subversa ut rebellatrix.</p>'+ '<p>Harum trium sententiarum nulli prorsus assentior.</p>\n'+ ' </div>\n'+ - ' <div class="col-md-6 mt16">\n'+ - ' <img class="img img-responsive shadow mb16" src="/web/static/src/img/logo.png" alt="Odoo text and image block">\n'+ + ' <div class="col-lg-6 mt16">\n'+ + ' <img class="img img-fluid shadow mb16" src="/web/static/src/img/logo.png" alt="Odoo text and image block">\n'+ ' </div>\n'+ ' </div>\n'+ '</section>\n'; @@ -67,7 +67,7 @@ tour.register('rte', { trigger: ".note-color button.dropdown-toggle", }, { content: "change text color", - trigger: ".btn-group.open button[data-event=foreColor]:first", + trigger: ".btn-group.show button[data-event=foreColor]:first", }, { content: "change selection to change text bg-color again", trigger: '#editable_area > section .row > div:first h1 font:eq(2)', @@ -169,7 +169,7 @@ tour.register('rte', { }, { content: "click on create link", trigger: '.note-image-popover:visible button[data-event="showLinkDialog"]', - extra_trigger: '#editable_area > section .row > div:first span.fa.pull-right', + extra_trigger: '#editable_area > section .row > div:first span.fa.float-right', }, { content: "insert a link url", trigger: 'input[name="url"]', @@ -177,19 +177,19 @@ tour.register('rte', { }, { content: "click on color style", trigger: '.o_link_dialog_color > .o_link_dialog_color_item.btn-success', - extra_trigger: 'a#link-preview:containsRegex(/^<span [^>]+><\\/span>$/) > span.fa.fa-3x.pull-right', + extra_trigger: 'a#link-preview:containsRegex(/^<span [^>]+><\\/span>$/) > span.fa.fa-3x.float-right', }, { content: "save link", trigger: '.modal-footer > .btn-primary', - extra_trigger: 'a#link-preview.btn.btn-success span.fa.fa-3x.pull-right', + extra_trigger: 'a#link-preview.btn.btn-success span.fa.fa-3x.float-right', }, { content: "click on other picture", trigger: '#editable_area > section .row > div:last img', - extra_trigger: 'body:not(:has(#link-preview)) a.btn[href^="http://"]:has(span.fa.fa-3x.pull-right)', + extra_trigger: 'body:not(:has(#link-preview)) a.btn[href^="http://"]:has(span.fa.fa-3x.float-right)', }, { content: "click on create link again", trigger: '.note-image-popover:visible button[data-event="showLinkDialog"]', - extra_trigger: '#editable_area > section .row > div:first span.fa.pull-right', + extra_trigger: '#editable_area > section .row > div:first span.fa.float-right', }, { content: "insert an email", trigger: 'input[name="url"]', @@ -288,11 +288,11 @@ tour.register('rte_inline', { ' <tbody>\n'+ ' <tr>\n'+ ' <td valign="center" width="270">\n'+ - ' <img src="/logo.png" alt="Your Logo" class="img-circle img-thumbnail">\n'+ + ' <img src="/logo.png" alt="Your Logo" class="rounded-circle img-thumbnail">\n'+ ' </td>\n'+ ' <td valign="center" width="270">\n'+ ' <a href="https://www.facebook.com/Odoo"><span class="fa fa-facebook-square fa-2x text-primary"></span></a>\n'+ - ' <span style="color: rgb(255, 0, 0);" class="fa fa-4x fa-google-plus-square pull-right"></span>\n'+ + ' <span style="color: rgb(255, 0, 0);" class="fa fa-4x fa-google-plus-square float-right"></span>\n'+ ' </td>\n'+ ' </tr>\n'+ ' </tbody>\n'+ @@ -311,7 +311,7 @@ tour.register('rte_inline', { trigger: '#wrapwrap img:first[width][height][style*="-radius"][style*="1px"][style*="padding"]', }, { content: "check the font image src", - trigger: '#wrapwrap img:eq(1)[src^="/web_editor/font_to_img/"][src$="/rgb(51,122,183)/28"]', + trigger: '#wrapwrap img:eq(1)[src^="/web_editor/font_to_img/"][src$="/rgb(0,123,255)/32"]', }, { content: "check the font class to css", trigger: '#wrapwrap img:eq(1)[height]:not([class*="fa"])', diff --git a/addons/web_editor/static/src/js/widgets/ace.js b/addons/web_editor/static/src/js/widgets/ace.js index a92c56cae05..c6cbb43295f 100644 --- a/addons/web_editor/static/src/js/widgets/ace.js +++ b/addons/web_editor/static/src/js/widgets/ace.js @@ -252,7 +252,7 @@ var ViewEditor = Widget.extend({ if (!this.sortedViews.length || !this.sortedSCSS.length) { _.defer((function () { this._switchType(this.sortedViews.length ? 'xml' : 'scss'); - this.$typeSwitcherBtn.parent('.btn-group').addClass('hidden'); + this.$typeSwitcherBtn.parent('.btn-group').addClass('d-none'); }).bind(this)); } @@ -365,7 +365,7 @@ var ViewEditor = Widget.extend({ } this.$lists[this.currentType].select2('val', resID); - this.$resetButton.toggleClass('hidden', this.currentType === 'xml' || !this.scss[resID].customized); + this.$resetButton.toggleClass('d-none', this.currentType === 'xml' || !this.scss[resID].customized); }, /** * Formats the current resource being vizualized. @@ -662,12 +662,12 @@ var ViewEditor = Widget.extend({ _switchType: function (type) { this.currentType = type; this.$typeSwitcherBtn.html(this.$typeSwitcherChoices.filter('[data-type=' + type + ']').html()); - _.each(this.$lists, function ($list, _type) { $list.toggleClass('hidden', type !== _type); }); + _.each(this.$lists, function ($list, _type) { $list.toggleClass('d-none', type !== _type); }); this.$lists[type].change(); - this.$includeBundlesArea.toggleClass('hidden', this.currentType === 'scss' || !session.debug); - this.$includeAllSCSSArea.toggleClass('hidden', this.currentType === 'xml' || !session.debug || this.options.defaultBundlesRestriction.length === 0); - this.$formatButton.toggleClass('hidden', this.currentType === 'scss'); + this.$includeBundlesArea.toggleClass('d-none', this.currentType === 'scss' || !session.debug); + this.$includeAllSCSSArea.toggleClass('d-none', this.currentType === 'xml' || !session.debug || this.options.defaultBundlesRestriction.length === 0); + this.$formatButton.toggleClass('d-none', this.currentType === 'scss'); }, /** * Updates the select option DOM element associated with a particular resID diff --git a/addons/web_editor/static/src/js/widgets/widgets.js b/addons/web_editor/static/src/js/widgets/widgets.js index 5f00723865d..b1a480ae56e 100644 --- a/addons/web_editor/static/src/js/widgets/widgets.js +++ b/addons/web_editor/static/src/js/widgets/widgets.js @@ -313,9 +313,9 @@ var ImageWidget = MediaWidget.extend({ } if (!self.$media.is('img')) { // Note: by default the images receive the bootstrap opt-in - // img-responsive class. We cannot make them all responsive + // img-fluid class. We cannot make them all responsive // by design because of libraries and client databases img. - self._replaceMedia($('<img/>', {class: 'img-responsive o_we_custom_image'})); + self._replaceMedia($('<img/>', {class: 'img-fluid o_we_custom_image'})); } self.$media.attr('src', img.src); @@ -450,7 +450,7 @@ var ImageWidget = MediaWidget.extend({ .values() .value(); - this.$('.help-block').empty(); + this.$('.form-text').empty(); this.$('.existing-attachments').replaceWith(QWeb.render('web_editor.dialog.image.existing.content', {rows: rows})); @@ -459,7 +459,7 @@ var ImageWidget = MediaWidget.extend({ var $div = $(el); if (/gif|jpe|jpg|png/.test($div.data('mimetype'))) { var $img = $('<img/>', { - class: 'img-responsive', + class: 'img-fluid', src: $div.data('url') || $div.data('src'), }); var def = $.Deferred(); @@ -538,7 +538,8 @@ var ImageWidget = MediaWidget.extend({ self._toggleImage(attachment, true); } else { $button.addClass('btn-danger'); - self.$el.addClass('has-error').find('.help-block').text(error); + self.$el.addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid'); + self.$el.find('.form-text').text(error); } if (!self.multiImages) { @@ -576,7 +577,8 @@ var ImageWidget = MediaWidget.extend({ _onImageSelection: function () { var $form = this.$('form'); this.$el.addClass('nosave'); - $form.removeClass('has-error').find('.help-block').empty(); + $form.removeClass('o_has_error').find('.form-control, .custom-select').removeClass('is-invalid'); + $form.find('.form-text').empty(); this.$('.o_upload_image_button').removeClass('btn-danger btn-success'); this._uploadImage(); }, @@ -585,7 +587,7 @@ var ImageWidget = MediaWidget.extend({ */ _onRemoveClick: function (ev) { var self = this; - var $helpBlock = this.$('.help-block').empty(); + var $helpBlock = this.$('.form-text').empty(); var $a = $(ev.currentTarget); var id = parseInt($a.data('id'), 10); var attachment = _.findWhere(this.records, {id: id}); @@ -611,9 +613,9 @@ var ImageWidget = MediaWidget.extend({ */ _onSearchInput: function (ev) { var $input = $(ev.currentTarget); - var $button = $input.next('button'); + var $button = $input.next('.input-group-append').children(); var emptyValue = ($input.val() === ''); - $button.toggleClass('btn-default', emptyValue).toggleClass('btn-primary', !emptyValue) + $button.toggleClass('btn-secondary', emptyValue).toggleClass('btn-primary', !emptyValue) .prop('disabled', emptyValue); }, /** @@ -987,8 +989,8 @@ var VideoWidget = MediaWidget.extend({ _updateVideo: function () { // Reset the feedback this.$content.empty(); - this.$('#o_video_form_group').removeClass('has-error has-success'); - this.$('.o_video_dialog_options li').addClass('hidden'); + this.$('#o_video_form_group').removeClass('o_has_error o_has_success').find('.form-control, .custom-select').removeClass('is-invalid is-valid'); + this.$('.o_video_dialog_options li').addClass('d-none'); // Check video code var $textarea = this.$('textarea#o_video_text'); @@ -1017,20 +1019,23 @@ var VideoWidget = MediaWidget.extend({ var $opt_box = this.$('.o_video_dialog_options'); // Show / Hide preview elements - this.$el.find('.o_video_dialog_preview_text, .media_iframe_video_size').add($opt_box).toggleClass('hidden', !query.$video); + this.$el.find('.o_video_dialog_preview_text, .media_iframe_video_size').add($opt_box).toggleClass('d-none', !query.$video); // Toggle validation classes - this.$el.find('#o_video_form_group').toggleClass('has-error', !query.$video).toggleClass('has-success', !!query.$video); + this.$el.find('#o_video_form_group') + .toggleClass('o_has_error', !query.$video).find('.form-control, .custom-select').toggleClass('is-invalid', !query.$video) + .end() + .toggleClass('o_has_success', !!query.$video).find('.form-control, .custom-select').toggleClass('is-valid', !!query.$video); // Individually show / hide options base on the video provider - $opt_box.find('li.o_' + query.type + '_option').removeClass('hidden'); + $opt_box.find('li.o_' + query.type + '_option').removeClass('d-none'); // Hide the entire options box if no options are available - $opt_box.toggleClass('hidden', $opt_box.find('li:not(.hidden)').length === 0); + $opt_box.toggleClass('d-none', $opt_box.find('li:not(.d-none)').length === 0); if (query.type === 'yt') { // Youtube only: If 'hide controls' is checked, hide 'fullscreen' // and 'youtube logo' options too - this.$('input#o_video_hide_fullscreen, input#o_video_hide_yt_logo').closest('li').toggleClass('hidden', this.$('input#o_video_hide_controls').is(':checked')); + this.$('input#o_video_hide_fullscreen, input#o_video_hide_yt_logo').closest('li').toggleClass('d-none', this.$('input#o_video_hide_controls').is(':checked')); } var $content = query.$video; @@ -1099,7 +1104,7 @@ var MediaDialog = Dialog.extend({ events : _.extend({}, Dialog.prototype.events, { 'input input#icon-search': '_onSearchInput', 'shown.bs.tab a[data-toggle="tab"]': '_onTabChange', - 'click .pager > li > a:not(.disabled)': '_onPagerClick', + 'click .previous:not(.disabled), .next:not(.disabled)': '_onPagerClick', }), custom_events: _.extend({}, Dialog.prototype.custom_events || {}, { save_request: '_onSaveRequest', @@ -1268,10 +1273,10 @@ var MediaDialog = Dialog.extend({ */ _updateControlPanel: function () { var cpConfig = this.active.getControlPanelConfig(); - this.$('li.search').toggleClass("hidden", !cpConfig.searchEnabled); - this.$('li.previous, li.next').toggleClass("hidden", !cpConfig.pagerEnabled); - this.$('li.previous > a').toggleClass("disabled", !cpConfig.pagerLeftEnabled); - this.$('li.next > a').toggleClass("disabled", !cpConfig.pagerRightEnabled); + this.$('li.search').toggleClass('d-none', !cpConfig.searchEnabled); + this.$('.previous, .next').toggleClass('d-none', !cpConfig.pagerEnabled); + this.$('.previous').toggleClass("disabled", !cpConfig.pagerLeftEnabled); + this.$('.next').toggleClass("disabled", !cpConfig.pagerRightEnabled); }, //-------------------------------------------------------------------------- @@ -1282,7 +1287,7 @@ var MediaDialog = Dialog.extend({ * @private */ _onPagerClick: function (ev) { - this.active.goToPage(this.active.page + ($(ev.currentTarget).parent().hasClass('previous') ? -1 : 1)); + this.active.goToPage(this.active.page + ($(ev.currentTarget).hasClass('previous') ? -1 : 1)); this._updateControlPanel(); }, /** @@ -1470,14 +1475,14 @@ var LinkDialog = Dialog.extend({ var data = this._getData(); if (data === null) { var $url = this.$('input[name="url"]'); - $url.closest('.form-group').addClass('has-error'); + $url.closest('.form-group').addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid'); $url.focus(); return $.Deferred().reject(); } this.data.text = data.label; this.data.url = data.url; this.data.className = data.classes.replace(/\s+/gi, ' ').replace(/^\s+|\s+$/gi, ''); - if (data.classes.replace(/(^|[ ])(btn-default|btn-success|btn-primary|btn-info|btn-warning|btn-danger)([ ]|$)/gi, ' ')) { + if (data.classes.replace(/(^|[ ])(btn-secondary|btn-success|btn-primary|btn-info|btn-warning|btn-danger)([ ]|$)/gi, ' ')) { this.data.style = {'background-color': '', 'color': ''}; } this.data.isNewWindow = data.isNewWindow; @@ -1554,9 +1559,9 @@ var LinkDialog = Dialog.extend({ * @private */ _onURLInput: function (ev) { - $(ev.currentTarget).closest('.form-group').removeClass('has-error'); + $(ev.currentTarget).closest('.form-group').removeClass('o_has_error').find('.form-control, .custom-select').removeClass('is-invalid'); var isLink = $(ev.currentTarget).val().indexOf('@') < 0; - this.$('input[name="is_new_window"]').closest('.form-group').toggleClass('hidden', !isLink); + this.$('input[name="is_new_window"]').closest('.form-group').toggleClass('d-none', !isLink); }, }); |
