summaryrefslogtreecommitdiff
path: root/addons/web_editor
diff options
context:
space:
mode:
authorqsm-odoo <qsm@odoo.com>2018-07-27 12:42:10 +0200
committerqsm-odoo <qsm@odoo.com>2018-07-27 12:42:10 +0200
commit2b3017974bc7cd4b3a74f83c956224cfe4e5a918 (patch)
treeff6aab8dc6bfa7afbe9ef714ca157ebc0185d2fd /addons/web_editor
parent8ed8b46f6434a2a3adea69e0134317e30bf9b936 (diff)
parent519594e9cab9a6362ef7c3e911605e4507a0a008 (diff)
[MERGE] *: migrate Bootstrap 3.3.7 to 4.1.3
See sub-commits for details. task-49280 Closes https://github.com/odoo/odoo/pull/25045
Diffstat (limited to 'addons/web_editor')
-rw-r--r--addons/web_editor/controllers/main.py2
-rw-r--r--addons/web_editor/static/lib/summernote/src/js/Renderer.js20
-rw-r--r--addons/web_editor/static/lib/summernote/src/js/module/Button.js14
-rw-r--r--addons/web_editor/static/lib/summernote/src/js/module/Editor.js4
-rw-r--r--addons/web_editor/static/src/js/editor/rte.js4
-rw-r--r--addons/web_editor/static/src/js/editor/rte.summernote.js70
-rw-r--r--addons/web_editor/static/src/js/editor/snippets.editor.js34
-rw-r--r--addons/web_editor/static/src/js/editor/snippets.options.js90
-rw-r--r--addons/web_editor/static/src/js/editor/summernote.js6
-rw-r--r--addons/web_editor/static/src/js/editor/translator.js4
-rw-r--r--addons/web_editor/static/src/js/inline.js2
-rw-r--r--addons/web_editor/static/src/js/tours/rte.js24
-rw-r--r--addons/web_editor/static/src/js/widgets/ace.js12
-rw-r--r--addons/web_editor/static/src/js/widgets/widgets.js57
-rw-r--r--addons/web_editor/static/src/scss/web_editor.common.bootstrap.scss28
-rw-r--r--addons/web_editor/static/src/scss/web_editor.common.scss52
-rw-r--r--addons/web_editor/static/src/scss/web_editor.ui.scss334
-rw-r--r--addons/web_editor/static/src/scss/web_editor.variables.scss88
-rw-r--r--addons/web_editor/static/src/xml/ace.xml42
-rw-r--r--addons/web_editor/static/src/xml/backend.xml4
-rw-r--r--addons/web_editor/static/src/xml/editor.xml231
-rw-r--r--addons/web_editor/static/src/xml/snippets.xml24
-rw-r--r--addons/web_editor/views/editor.xml20
-rw-r--r--addons/web_editor/views/snippets.xml2
24 files changed, 581 insertions, 587 deletions
diff --git a/addons/web_editor/controllers/main.py b/addons/web_editor/controllers/main.py
index 22a1e514d88..7dbc3415f21 100644
--- a/addons/web_editor/controllers/main.py
+++ b/addons/web_editor/controllers/main.py
@@ -285,7 +285,7 @@ class Web_Editor(http.Controller):
if get_scss:
# Compile regex outside of the loop
# This will used to exclude library scss files from the result
- excluded_url_matcher = re.compile("^(.+/lib/.+)|(.+import_bootstrap.scss)$")
+ excluded_url_matcher = re.compile("^(.+/lib/.+)|(.+import_bootstrap.+\.scss)$")
# Load already customized scss files attachments
custom_attachments = request.env["ir.attachment"].search([("url", "=like", self._make_custom_scss_file_url("%%.%%", "%%"))])
diff --git a/addons/web_editor/static/lib/summernote/src/js/Renderer.js b/addons/web_editor/static/lib/summernote/src/js/Renderer.js
index 7fa1afe3adc..2c856d4b152 100644
--- a/addons/web_editor/static/lib/summernote/src/js/Renderer.js
+++ b/addons/web_editor/static/lib/summernote/src/js/Renderer.js
@@ -36,7 +36,7 @@ define([
return (dropdown ? '<div class="btn-group' +
(className ? ' ' + className : '') + '">' : '') +
'<button type="button"' +
- ' class="btn btn-default btn-sm' +
+ ' class="btn btn-secondary btn-sm' +
((!dropdown && className) ? ' ' + className : '') +
(dropdown ? ' dropdown-toggle' : '') +
'"' +
@@ -162,7 +162,7 @@ define([
style: function (lang, options) {
var items = options.styleTags.reduce(function (memo, v) {
var label = lang.style[v === 'p' ? 'normal' : v];
- return memo + '<li><a data-event="formatBlock" href="#" data-value="' + v + '">' +
+ return memo + '<li><a class="dropdown-item" data-event="formatBlock" href="#" data-value="' + v + '">' +
(
(v === 'p' || v === 'pre') ? label :
'<' + v + '>' + label + '</' + v + '>'
@@ -225,12 +225,12 @@ define([
});
var items = [
- '<li><div class="btn-group">',
+ '<li class="flex"><div class="btn-group flex-column">',
'<div class="note-palette-title">' + lang.color.background + '</div>',
'<div class="note-color-reset" data-event="backColor"',
' data-value="inherit" title="' + lang.color.transparent + '">' + lang.color.setTransparent + '</div>',
'<div class="note-color-palette" data-target-event="backColor"></div>',
- '</div><div class="btn-group">',
+ '</div><div class="btn-group flex-column">',
'<div class="note-palette-title">' + lang.color.foreground + '</div>',
'<div class="note-color-reset" data-event="foreColor" data-value="inherit" title="' + lang.color.reset + '">',
lang.color.resetToDefault,
@@ -450,12 +450,12 @@ define([
var roundedButton = tplIconButton(options.iconPrefix + options.icons.image.shapeRounded, {
title: lang.image.shapeRounded,
event: 'imageShape',
- value: 'img-rounded'
+ value: 'rounded'
});
var circleButton = tplIconButton(options.iconPrefix + options.icons.image.shapeCircle, {
title: lang.image.shapeCircle,
event: 'imageShape',
- value: 'img-circle'
+ value: 'rounded-circle'
});
var thumbnailButton = tplIconButton(options.iconPrefix + options.icons.image.shapeThumbnail, {
title: lang.image.shapeThumbnail,
@@ -536,7 +536,7 @@ define([
* @param {String} body
*/
var tplShortcut = function (title, keys) {
- var keyClass = 'note-shortcut-col col-xs-6 note-shortcut-';
+ var keyClass = 'note-shortcut-col col-6 note-shortcut-';
var body = [];
for (var i in keys) {
@@ -548,7 +548,7 @@ define([
}
}
- return '<div class="note-shortcut-row row"><div class="' + keyClass + 'title col-xs-offset-6">' + title + '</div></div>' +
+ return '<div class="note-shortcut-row row"><div class="' + keyClass + 'title offset-6">' + title + '</div></div>' +
'<div class="note-shortcut-row row">' + body.join('</div><div class="note-shortcut-row row">') + '</div>';
};
@@ -616,7 +616,7 @@ define([
};
var tplShortcutTable = function (lang, options) {
- var colClass = 'class="note-shortcut note-shortcut-col col-sm-6 col-xs-12"';
+ var colClass = 'class="note-shortcut note-shortcut-col col-md-6 col-12"';
var template = [
'<div ' + colClass + '>' + tplShortcutAction(lang, options) + '</div>' +
'<div ' + colClass + '>' + tplShortcutText(lang, options) + '</div>',
@@ -681,7 +681,7 @@ define([
},
help: function (lang, options) {
- var body = '<a class="modal-close pull-right" aria-hidden="true" tabindex="-1">' + lang.shortcut.close + '</a>' +
+ var body = '<a class="modal-close float-right" aria-hidden="true" tabindex="-1">' + lang.shortcut.close + '</a>' +
'<div class="title">' + lang.shortcut.shortcuts + '</div>' +
(agent.isMac ? tplShortcutTable(lang, options) : replaceMacKeys(tplShortcutTable(lang, options))) +
'<p class="text-center">' +
diff --git a/addons/web_editor/static/lib/summernote/src/js/module/Button.js b/addons/web_editor/static/lib/summernote/src/js/module/Button.js
index b7a1614d4db..c6d28494cd0 100644
--- a/addons/web_editor/static/lib/summernote/src/js/module/Button.js
+++ b/addons/web_editor/static/lib/summernote/src/js/module/Button.js
@@ -21,10 +21,10 @@ define([
* @param {Number} value
*/
var checkDropdownMenu = function ($btn, value) {
- $btn.find('.dropdown-menu li a').each(function () {
+ $btn.find('.dropdown-menu .dropdown-item').each(function () {
// always compare string to avoid creating another func.
var isChecked = ($(this).data('value') + '') === (value + '');
- this.className = isChecked ? 'checked' : '';
+ this.className = 'dropdown-item' + (isChecked ? ' checked' : '');
});
};
@@ -43,17 +43,17 @@ define([
if (styleInfo.image) {
var $img = $(styleInfo.image);
- btnState('button[data-event="imageShape"][data-value="img-rounded"]', function () {
- return $img.hasClass('img-rounded');
+ btnState('button[data-event="imageShape"][data-value="rounded"]', function () {
+ return $img.hasClass('rounded');
});
- btnState('button[data-event="imageShape"][data-value="img-circle"]', function () {
- return $img.hasClass('img-circle');
+ btnState('button[data-event="imageShape"][data-value="rounded-circle"]', function () {
+ return $img.hasClass('rounded-circle');
});
btnState('button[data-event="imageShape"][data-value="img-thumbnail"]', function () {
return $img.hasClass('img-thumbnail');
});
btnState('button[data-event="imageShape"]:not([data-value])', function () {
- return !$img.is('.img-rounded, .img-circle, .img-thumbnail');
+ return !$img.is('.rounded, .rounded-circle, .img-thumbnail');
});
var imgFloat = $img.css('float');
diff --git a/addons/web_editor/static/lib/summernote/src/js/module/Editor.js b/addons/web_editor/static/lib/summernote/src/js/module/Editor.js
index 99947c346cf..0b63f315cf9 100644
--- a/addons/web_editor/static/lib/summernote/src/js/module/Editor.js
+++ b/addons/web_editor/static/lib/summernote/src/js/module/Editor.js
@@ -740,7 +740,7 @@ define([
this.floatMe = function ($editable, value, $target) {
beforeCommand($editable);
// bootstrap
- $target.removeClass('pull-left pull-right');
+ $target.removeClass('float-left float-right');
if (value && value !== 'none') {
$target.addClass('pull-' + value);
}
@@ -760,7 +760,7 @@ define([
this.imageShape = function ($editable, value, $target) {
beforeCommand($editable);
- $target.removeClass('img-rounded img-circle img-thumbnail');
+ $target.removeClass('rounded rounded-circle img-thumbnail');
if (value) {
$target.addClass(value);
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);
},
});
diff --git a/addons/web_editor/static/src/scss/web_editor.common.bootstrap.scss b/addons/web_editor/static/src/scss/web_editor.common.bootstrap.scss
new file mode 100644
index 00000000000..b7ad30b1bc4
--- /dev/null
+++ b/addons/web_editor/static/src/scss/web_editor.common.bootstrap.scss
@@ -0,0 +1,28 @@
+
+// Automatically extend bootstrap to create theme background/text/button classes
+$theme-colors: () !default;
+$theme-colors: map-merge((
+ 'alpha': $color-alpha,
+ 'beta': $color-beta,
+ 'gamma': $color-gamma,
+ 'delta': $color-delta,
+ 'epsilon': $color-epsilon,
+), $theme-colors);
+
+// Extend grays with transparent ones (for some reason, BS4 create black-50 and
+// white-50 but does not allow overridding that with variables). Also add black
+// and white ones too as they were also not added by BS4...
+$grays: () !default;
+$grays: map-merge((
+ 'black-25': $color-black-25,
+ 'black-50': $color-black-50,
+ 'black-75': $color-black-75,
+ 'white-25': $color-white-25,
+ 'white-50': $color-white-50,
+ 'white-75': $color-white-75,
+
+ // Note: those two needs to be redefined before bootstrap, otherwise they
+ // do not exist yet
+ 'black': $black,
+ 'white': $white,
+), $grays);
diff --git a/addons/web_editor/static/src/scss/web_editor.common.scss b/addons/web_editor/static/src/scss/web_editor.common.scss
index ed125d62c1c..11fa94cd010 100644
--- a/addons/web_editor/static/src/scss/web_editor.common.scss
+++ b/addons/web_editor/static/src/scss/web_editor.common.scss
@@ -32,7 +32,7 @@ html, body {
min-width: 20px;
}
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(sm) {
.table-responsive > table.table {
table-layout: auto;
}
@@ -71,7 +71,7 @@ img.padding-xl, .img.padding-xl, span.fa.padding-xl, iframe.padding-xl {
.fa-10x {
font-size: 10em;
}
-.fa.center-block {
+.fa.d-block.mx-auto {
text-align: center;
}
@@ -121,12 +121,8 @@ html[data-browser^="msie"] div.media_iframe_video iframe {
margin-left: 0;
}
-@media (max-width: $screen-xs-max) {
+@include media-breakpoint-down(sm) {
img:not(.cke_iframe), .media_iframe_video, span.fa, i.fa {
- -webkit-transform: none !important;
- -moz-transform: none !important;
- -ms-transform: none !important;
- -o-transform: none !important;
transform: none !important;
}
}
@@ -233,40 +229,8 @@ a.o_underline {
}
}
-// Create classes for theme colors...
-@include o-create-color-classes(alpha, $color-alpha);
-@include o-create-color-classes(beta, $color-beta);
-@include o-create-color-classes(gamma, $color-gamma);
-@include o-create-color-classes(delta, $color-delta);
-@include o-create-color-classes(epsilon, $color-epsilon);
-
-// ... and button classes
-@include o-create-color-btn-classes(alpha, $color-alpha);
-@include o-create-color-btn-classes(beta, $color-beta);
-@include o-create-color-btn-classes(gamma, $color-gamma);
-@include o-create-color-btn-classes(delta, $color-delta);
-@include o-create-color-btn-classes(epsilon, $color-epsilon);
-
-// Create classes for UI colors
-@include o-create-color-classes(primary, $brand-primary);
-@include o-create-color-classes(success, $state-success-bg, $content-color: $state-success-text);
-@include o-create-color-classes(info, $state-info-bg, $content-color: $state-info-text);
-@include o-create-color-classes(warning, $state-warning-bg, $content-color: $state-warning-text);
-@include o-create-color-classes(danger, $state-danger-bg, $content-color: $state-danger-text);
-
-// Create classes for greyscale colors
-@include o-create-color-classes('black', $gray-base);
-@include o-create-color-classes('gray-darker', $gray-darker);
-@include o-create-color-classes('gray-dark', $gray-dark);
-@include o-create-color-classes('gray', $gray);
-@include o-create-color-classes('gray-light', $gray-light);
-@include o-create-color-classes('gray-lighter', $gray-lighter);
-@include o-create-color-classes('white', $gray-white);
-
-// Create classes for greyscale transparent colours
-@include o-create-color-classes('black-25', $color-black-25);
-@include o-create-color-classes('black-50', $color-black-50);
-@include o-create-color-classes('black-75', $color-black-75);
-@include o-create-color-classes('white-25', $color-white-25);
-@include o-create-color-classes('white-50', $color-white-50);
-@include o-create-color-classes('white-75', $color-white-75);
+// Extend bootstrap to create background and text utilities for gray colors too
+@each $color, $value in $grays {
+ @include bg-variant(".bg-#{$color}", $value);
+ @include text-emphasis-variant(".text-#{$color}", $value);
+}
diff --git a/addons/web_editor/static/src/scss/web_editor.ui.scss b/addons/web_editor/static/src/scss/web_editor.ui.scss
index 179f814c4b3..eee93913dc2 100644
--- a/addons/web_editor/static/src/scss/web_editor.ui.scss
+++ b/addons/web_editor/static/src/scss/web_editor.ui.scss
@@ -22,7 +22,7 @@
z-index: $zindex-modal - 9;
background-color: rgba(0,0,0,0);
- @include o-transition(background-color, 400ms, $o-we-md-ease);
+ transition: background-color 400ms $o-we-md-ease 0s;
font-family: $o-we-font-family;
form.navbar-form {
@@ -31,7 +31,7 @@
margin: 0;
padding: 0;
@include o-position-absolute($right: -$o-we-sidebar-width);
- @include o-transition(right, 0.4s, $o-we-md-ease);
+ transition: right 0.4s $o-we-md-ease 0s;
border-left: 1px solid $o-we-color-divider;
background-color: inherit;
@@ -47,7 +47,7 @@
font-size: 13px;
font-family: $o-we-font-family;
- @include o-transition(all, 0.3s);
+ transition: all 0.3s ease 0s;
border: none;
border-radius: 0;
@@ -59,10 +59,10 @@
}
&.btn-primary {
- @include button-variant(white, $o-brand-primary, $o-brand-primary);
+ @include button-variant($o-brand-odoo, $o-brand-odoo);
}
- &.btn-default {
- @include button-variant(white, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0));
+ &.btn-secondary {
+ @include button-variant(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0));
&:hover {
background: rgba(black, 0.5);
@@ -100,8 +100,8 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
#oe_snippets {
@include o-w-preserve-btn;
- @include o-flex-display;
- @include o-flex-flow(column, nowrap);
+ display: flex;
+ flex-flow: column nowrap;
@include o-position-absolute(0, auto, 0, -$o-we-sidebar-width);
position: fixed;
width: $o-we-sidebar-width;
@@ -109,12 +109,12 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
font-family: Roboto, $font-family-sans-serif;
border-right: 1px solid $o-we-color-divider;
- @include o-transition(left, 400ms, $o-we-md-ease);
- @include o-linear-gradient(45deg, $o-we-color-normal, darken($o-we-color-normal, 10%));
+ transition: left 400ms $o-we-md-ease 0s;
+ background-image: linear-gradient(45deg, $o-we-color-normal, darken($o-we-color-normal, 10%));
box-shadow: 0px 10px 10px -10px black inset;
#snippets_menu {
- @include o-flex(0, 0, auto);
+ flex: 0 0 auto;
height: $o-navbar-height;
line-height: $o-navbar-height;
margin: 0;
@@ -133,9 +133,9 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
.o_panel_header {
color: #999999;
- @include o-flex-display;
- @include o-align-items(center);
- @include o-justify-content(center);
+ display: flex;
+ align-items: center;
+ justify-content: center;
padding: 3%;
color: white;
margin-bottom: 3%;
@@ -157,7 +157,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
margin: 0 0 6% 3%;
box-shadow: none;
background-color: transparent;
- @include user-select(none);
+ user-select: none;
cursor: pointer;
cursor: copy;
@@ -173,8 +173,8 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
}
&:hover .oe_snippet_thumbnail_img {
- @include o-transition(transform, 200ms, ease);
- @include scale(1.05);
+ transition: transform 200ms ease 0s;
+ transform: scale(1.05);
}
}
@@ -251,12 +251,12 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
// DROPZONES
@keyframes dropZoneInsert {
to {
- background-color: rgba($o-brand-primary, 0.2);
+ background-color: rgba($o-brand-odoo, 0.2);
}
}
#wrapwrap .oe_drop_zone {
- background-color: rgba($o-brand-primary, 0.05);
- @include o-animation(dropZoneInsert, 1s, linear, 0s, infinite, alternate);
+ background-color: rgba($o-brand-odoo, 0.05);
+ animation: dropZoneInsert 1s linear 0s infinite alternate;
&.oe_insert {
z-index: 999;
@@ -270,7 +270,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
height: $o-we-dropzone-size;
margin: (-$o-we-dropzone-size/2) 0;
- @include o-transition(margin, 400ms, linear);
+ transition: margin 400ms linear 0s;
&:after {
content: "";
@@ -282,7 +282,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
}
&.oe_vertical {
- border: 2px dashed $o-brand-primary;
+ border: 2px dashed $o-brand-odoo;
border-left: none;
border-right: none;
@@ -312,7 +312,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
height: 0;
background: transparent;
text-align: center;
- @include o-transition(opacity, 400ms, linear);
+ transition: opacity 400ms linear 0s;
&.o_keypress {
opacity: 0;
}
@@ -341,7 +341,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
border-radius: 0;
font-weight: normal;
- @include o-transition(all, 400ms);
+ transition: all 400ms ease 0s;
color: $o-we-color-text-light;
background-color: $o-we-color-light;
&:hover {
@@ -367,7 +367,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
}
}
&.oe_snippet_parent > i {
- @include scaleX(-1);
+ transform: scaleX(-1);
font-size: 12px;
}
@@ -397,19 +397,19 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
height: 2px;
background-color: $o-we-color-text-light;
@include o-position-absolute(46%);
- @include o-transition(all, 0.3s);
+ transition: all 0.3s ease 0s;
}
&:before {
right: 9px;
- @include rotate(45deg);
+ transform: rotate(45deg);
}
&:after {
right: 5px;
- @include rotate(-45deg);
+ transform: rotate(-45deg);
}
}
// Open menu
- &.open .btn {
+ &.show .btn {
background-color: $o-we-color-light;
&:before, &:after {
width: 9px;
@@ -419,7 +419,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
transform: translateX(5px) rotate(-45deg);
}
&:after {
- @include rotate(45deg);
+ transform: rotate(45deg);
}
}
@@ -430,99 +430,97 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
border: 1px solid $o-we-color-dark;
border-radius: 0;
background-color: $o-we-color-light;
- a {
+
+ .dropdown-item {
+ position: relative;
color: $o-we-color-text-light;
font-weight: normal;
font-size: 12px;
padding: 5px 35px 5px 20px;
- }
- > li {
- position: relative;
&:hover {
background-color: fade-out($o-we-color-dark, 0.5);
- > a {
- color: white;
- background: transparent;
- cursor: pointer;
- }
- > .dropdown-menu {
- display: block;
- left: 100%;
- top: 0;
-
- &.o_open_to_left {
- left: auto;
- right: 100%;
- }
- }
- }
- &.dropdown-submenu:before {
- @include o-position-absolute($top: 10px, $right: 10px);
- @include o-caret-right(3px);
- border-left-color: $o-we-color-text-light;
- }
- &.divider {
- background-color: $o-we-color-divider;
- margin: 0 8px;
+ color: white;
+ background: transparent;
+ cursor: pointer;
}
- &.active > a {
+ &.active {
color: white;
background-color: fade-out($o-we-color-dark, 0.5);
&:before {
@include o-position-absolute($top: 5px, $left: 5px);
content: "\f00c";
font-family: "FontAwesome";
- color: $o-brand-optional;
+ color: $o-brand-primary;
}
}
- &.dropdown-header {
- color: white;
- font-weight: bold;
- font-size: 12px;
- margin-top: 2px;
- &:hover {
- background-color: initial;
- }
+ > i {
+ width: 16px;
+ margin-right: 8px;
+ }
+ }
- &.o_main_header {
- padding-left: 8px;
- }
- &.o_parent_editor_header {
- color: wheat;
- font-weight: 400;
- font-size: 10px;
- margin: 7px 0 4px 4px;
- &::before {
- content: "\f148";
- @include o-position-absolute($top: 2px, $left: 8px);
- font-family: FontAwesome;
- @include scaleX(-1);
- }
- ~ li:not(.dropdown-header) {
- a {
- font-size: 11px;
- padding: 4px 35px 4px 20px;
- opacity: 0.8;
- &:hover {
- opacity: 1;
- }
- }
- }
- }
+ .dropdown-submenu {
+ position: relative;
+
+ &::before {
+ @include o-position-absolute($top: 10px, $right: 10px);
+ @include o-caret-right(3px);
+ border-left-color: $o-we-color-text-light;
}
- &.separator {
+ &:hover > .dropdown-menu {
display: block;
- margin: 4px 35px 4px 20px;
- height: 1px;
- background: rgba($o-we-color-text-light, 0.1);
+ left: 100%;
+ top: 0;
+
+ &.o_open_to_left {
+ left: auto;
+ right: 100%;
+ }
}
+ }
- > a > i {
- width: 16px;
- margin-right: 8px;
+ .dropdown-divider {
+ display: block;
+ height: 1px;
+ background: rgba($o-we-color-text-light, 0.1);
+ margin: 0 8px;
+ }
+
+ .dropdown-header {
+ color: white;
+ font-weight: bold;
+ font-size: 12px;
+ margin-top: 2px;
+
+ &:hover {
+ background-color: initial;
+ }
+
+ &.o_main_header {
+ padding-left: 8px;
+ }
+ &.o_parent_editor_header {
+ color: wheat;
+ font-weight: 400;
+ font-size: 10px;
+ margin: 7px 0 4px 4px;
+ &::before {
+ content: "\f148";
+ @include o-position-absolute($top: 2px, $left: 8px);
+ font-family: FontAwesome;
+ transform: scaleX(-1);
+ }
+ ~ .dropdown-item {
+ font-size: 11px;
+ padding: 4px 35px 4px 20px;
+ opacity: 0.8;
+ &:hover {
+ opacity: 1;
+ }
+ }
}
}
}
@@ -548,7 +546,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
position: relative;
border: 0 solid $o-we-handles-accent-color;
- @include o-transition(background, 300ms);
+ transition: background 300ms ease 0s;
&:hover, &.o_active {
background-color: rgba($o-we-handles-accent-color, 0.2);
@@ -711,11 +709,11 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
height: $o-navbar-height;
border: none;
border-radius: 0;
- padding: $padding-base-vertical $padding-base-horizontal; // force this because of themes
+ padding: $btn-padding-y $btn-padding-y; // force this because of themes
background-color: $o-we-color-dark;
color: $o-we-color-text-normal;
border-top: 2px solid transparent;
- @include o-transition(all, 0.3s);
+ transition: all 0.3s ease 0s;
> .fa {
color: $o-we-color-text-normal;
@@ -749,7 +747,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
> .btn-group {
margin-top: -2px;
- &.open, .btn-group.open {
+ &.show, .btn-group.show {
.dropdown-toggle {
border-top: 2px solid white;
background-color: $o-we-color-darker;
@@ -767,7 +765,9 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
border-radius: 0;
background-color: $o-we-color-darker;
color: $o-we-color-text-normal;
- > li > a {
+ white-space: normal;
+
+ .dropdown-item {
width: 100%;
color: $o-we-color-text-light;
@@ -831,7 +831,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
.note-popover .popover, .note-editor {
.dropdown-menu {
- > li > a {
+ .dropdown-item {
> i {
visibility: hidden;
}
@@ -910,14 +910,13 @@ table.colorpicker {
&:focus, &:active, &:focus:active {
outline: none;
}
- }
- &:hover, &.active {
- > a {
+ &.active {
+ background-color: $o-we-tab-active-bg!important;
color: white;
}
}
- &.active > a {
- background-color: $o-we-tab-active-bg!important;
+ &:hover > a {
+ color: white;
}
}
}
@@ -972,7 +971,7 @@ table.colorpicker {
&.selected:after {
content: "\f00c";
font-family: "FontAwesome";
- color: $brand-success;
+ color: theme-color('success');
}
&[data-event="foreColor"] {
@@ -1030,7 +1029,7 @@ body.editor_enable {
}
&.editor_has_snippets {
- @include o-transition(padding-left, 400ms, $o-we-md-ease);
+ transition: padding-left 400ms $o-we-md-ease 0s;
padding-left: $o-we-sidebar-width!important;
#oe_snippets {
@@ -1069,11 +1068,11 @@ body.editor_enable {
@keyframes fadeInDownSmall {
0% {
opacity: 0;
- @include translate(0, -5px);
+ transform: translate(0, -5px);
}
100% {
opacity: 1;
- @include translate(0, 0);
+ transform: translate(0, 0);
}
}
@keyframes fadeInOut {
@@ -1091,14 +1090,14 @@ body.editor_enable {
}
}
@keyframes inputHighlighter {
- from { background: $o-brand-optional; }
+ from { background: $o-brand-primary; }
to { width: 0; background: transparent; }
}
// INPUTS
.o_switch {
- @include o-flex-display;
- @include o-align-items(center);
+ display: flex;
+ align-items: center;
font-weight: normal;
cursor: pointer;
@@ -1113,7 +1112,7 @@ body.editor_enable {
width: $o-we-switch-size * 1.8;
margin-right: 0.5em;
display: inline-block;
- @include transition(all 0.3s $o-we-md-ease);
+ transition: all 0.3s $o-we-md-ease;
&:after {
content: "";
@@ -1124,14 +1123,14 @@ body.editor_enable {
margin-top: 0.1ex;
margin-left: 0.1ex;
border-radius: 100rem;
- @include transition(all 0.3s $o-we-md-ease);
+ transition: all 0.3s $o-we-md-ease;
box-shadow: 0 1px 1px darken($o-we-switch-inactive-color,35%), inset 0 0 0 1px lighten($o-we-switch-inactive-color,10%);
}
}
&:checked + span {
box-shadow: none;
- @include o-linear-gradient(0deg, $o-we-color-success, darken($o-we-color-success, 10%));
+ background-image: linear-gradient(0deg, $o-we-color-success, darken($o-we-color-success, 10%));
&:after {
margin-left: ($o-we-switch-size*1.8 - $o-we-switch-size) + 0.1;
@@ -1142,7 +1141,7 @@ body.editor_enable {
> input {
&:not(:checked) + span {
box-shadow: none;
- @include o-linear-gradient(0deg, lighten($brand-danger, 5%), darken($brand-danger, 5%));
+ background-image: linear-gradient(0deg, lighten(theme-color('danger'), 5%), darken(theme-color('danger'), 5%));
}
}
}
@@ -1174,7 +1173,7 @@ body.editor_enable {
font-weight: normal;
@include o-position-absolute($top: 10px, $left: 5px);
pointer-events: none;
- @include transition(0.2s ease all);
+ transition: 0.2s ease all;
}
/* active state */
@@ -1193,7 +1192,7 @@ body.editor_enable {
bottom: 1px;
@include o-position-absolute;
background: #5264AE;
- @include transition(0.2s ease all);
+ transition: 0.2s ease all;
}
.bar:before {
left: 50%;
@@ -1218,28 +1217,28 @@ body.editor_enable {
/* active state */
input:focus ~ .highlight {
- @include animation(inputHighlighter 0.3s ease);
+ animation: inputHighlighter 0.3s ease;
}
}
// DRAG&DROP ANIMATIONS
.oe_snippet_body {
opacity: 0;
- @include o-animation(fadeInDownSmall, 700ms, $fill-mode: forwards);
+ animation: fadeInDownSmall 700ms forwards;
}
// ACE EDITOR
.o_ace_view_editor {
background: $o-we-ace-color;
color: white;
- @include o-flex-display;
- @include o-flex-flow(column, nowrap);
+ display: flex;
+ flex-flow: column nowrap;
opacity: 0.97;
.o_ace_view_editor_title {
- @include o-flex(0, 0, auto);
- @include o-flex-display;
- @include o-align-items(center);
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
padding: $grid-gutter-width/4;
> .o_ace_type_switcher > button::after {
@@ -1248,27 +1247,27 @@ body.editor_enable {
}
> * {
- @include o-flex(0, 0, auto);
+ flex: 0 0 auto;
margin: 0 $grid-gutter-width/4;
&.o_include_option {
- @include o-flex-display;
- @include o-align-items(center);
+ display: flex;
+ align-items: center;
font-size: 11px;
- > .o_checkbox {
+ > .custom-control {
margin-right: $grid-gutter-width/4;
}
}
&.o_res_list {
- @include o-flex(1, 1, auto);
+ flex: 1 1 auto;
min-width: 60px;
}
}
}
#ace-view-id {
- @include o-flex(0, 0, auto);
+ flex: 0 0 auto;
padding: $grid-gutter-width/4 $grid-gutter-width/2;
background-color: lighten($o-we-ace-color, 10%);
}
@@ -1277,13 +1276,13 @@ body.editor_enable {
content: "";
z-index: 1000;
display: block;
- background-color: $brand-danger;
+ background-color: theme-color('danger');
opacity: 0.5;
pointer-events: none;
}
height: 70%; // in case flex is not supported
- @include o-flex(1, 1, auto);
+ flex: 1 1 auto;
.ace_gutter {
cursor: ew-resize;
@@ -1334,7 +1333,7 @@ body.editor_enable {
body .modal {
// SELECT MEDIA
.o_select_media_dialog {
- width: 80%;
+ max-width: 80%;
.modal-body {
.nav-tabs .active > a[href="#editor-media-icon"] {
@@ -1342,9 +1341,6 @@ body .modal {
}
li.search {
- ul.pager li:last-child{
- margin-left: 2px;
- }
.form-group {
position: relative;
margin: 0 10px 0 0;
@@ -1358,9 +1354,11 @@ body .modal {
}
}
- .well {
- border-color: $gray-lighter;
+ .card {
+ border-color: gray('200');
border-top-width: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
}
.o_existing_attachment_cell {
@@ -1383,7 +1381,7 @@ body .modal {
.o_image {
border: $o-border-image solid transparent;
cursor: pointer;
- @include o-transition(opacity, 400ms);
+ transition: opacity 400ms ease 0s;
&.o_webimage {
width: 100%;
@@ -1396,7 +1394,7 @@ body .modal {
}
}
&.o_selected .o_image {
- border-color: $o-brand-primary;
+ border-color: $o-brand-odoo;
box-shadow: 0px 0px 2px 2px $o-brand-secondary;
}
&:hover .o_existing_attachment_remove {
@@ -1424,7 +1422,7 @@ body .modal {
}
#editor-media-image, #editor-media-document {
- .well {
+ .card {
label {
margin: auto 10px;
}
@@ -1436,13 +1434,13 @@ body .modal {
}
// VIDEO TAB
- #editor-media-video .well {
+ #editor-media-video .card {
padding: 0;
- @include o-flex-display;
- @include o-flex-flow(row, wrap);
+ display: flex;
+ flex-flow: row wrap;
.o_video_dialog_form {
- @include o-flex(1, 1, auto);
+ flex: 1 1 auto;
min-width: 0;
padding: 20px;
@@ -1464,10 +1462,10 @@ body .modal {
display: none;
}
}
- &.has-error > .o_validate_feedback > .fa-exclamation-triangle {
+ &.o_has_error > .o_validate_feedback > .fa-exclamation-triangle {
display: block;
}
- &.has-success > .o_validate_feedback > .fa-check {
+ &.o_has_success > .o_validate_feedback > .fa-check {
display: block;
}
}
@@ -1475,10 +1473,10 @@ body .modal {
#video-preview {
position: relative;
- @include o-flex(1, 0, 50%);
- @include o-flex-display;
- @include o-flex-flow(column, nowrap);
- @include o-justify-content(center);
+ flex: 1 0 50%;
+ display: flex;
+ flex-flow: column nowrap;
+ justify-content: center;
@include o-we-preview-box(0 19px);
border: none;
@@ -1493,7 +1491,7 @@ body .modal {
max-height: 100%;
&.alert {
- @include o-animation(fadeInDownSmall, 700ms, $fill-mode: forwards);
+ animation: fadeInDownSmall 700ms forwards;
margin: 0 auto;
}
}
@@ -1523,7 +1521,7 @@ body .modal {
border: 1px dotted #888787;
background-image: url(/web/image);
background-position: center center;
- @include o-background-size(cover);
+ background-size: cover;
}
.el {
@include o-position-absolute(10px, 0, 10px, 0);
@@ -1566,7 +1564,7 @@ body .modal {
}
}
.o_bg_img_opt_ui_info {
- @include animation(fadeInOut 2s ease forwards);
+ animation: fadeInOut 2s ease forwards;
@include o-position-absolute($bottom: 1px, $right: 0);
display: block;
padding: 3px 13px;
@@ -1587,7 +1585,7 @@ body .modal {
display: block;
width: 100%;
height: 1px;
- background: fade-out(lighten($o-brand-optional, 30%), 0.5);
+ background: fade-out(lighten($o-brand-primary, 30%), 0.5);
pointer-events: none;
&.grid-2 {
top: 66.66%
@@ -1616,7 +1614,7 @@ body .modal {
box-shadow: 0 0 1px #333;
pointer-events: none;
&.o_with_transition {
- @include o-transition(all, 0.2s);
+ transition: all 0.2s ease 0s;
}
&:before {
pointer-events: none;
@@ -1631,7 +1629,7 @@ body .modal {
border-radius: 100em;
opacity: 1;
box-shadow: 0 0 0 100em rgba(0, 0, 0, 0.33);
- @include o-transition(opacity, 0.2s);
+ transition: opacity 0.2s ease 0s;
}
}
}
@@ -1661,7 +1659,7 @@ body .modal {
}
}
.o_link_dialog_preview {
- border-left: 1px solid $gray-lighter;
+ border-left: 1px solid gray('200');
}
}
// Crop Dialog
@@ -1669,13 +1667,13 @@ body .modal {
height: 350px;
.cropper-point {
background-color: white;
- @include o-transition(all, 400ms, $o-we-md-ease);
- @include o-transform(scale(1.5, 1.5));
+ transition: all 400ms $o-we-md-ease 0s;
+ transform: scale(1.5, 1.5);
border-radius: 10px;
box-shadow: 0 0 1px 1px rgba(23, 23, 23, 0.5);
opacity: 1;
&:hover {
- @include o-transform(scale(2.5, 2.5));
+ transform: scale(2.5, 2.5);
}
}
.cropper-line {
diff --git a/addons/web_editor/static/src/scss/web_editor.variables.scss b/addons/web_editor/static/src/scss/web_editor.variables.scss
index 2d36b3e9756..203b27fc886 100644
--- a/addons/web_editor/static/src/scss/web_editor.variables.scss
+++ b/addons/web_editor/static/src/scss/web_editor.variables.scss
@@ -27,7 +27,7 @@ $o-we-md-ease: cubic-bezier(0.19, 1, 0.22, 1) !default;
// Editor
$o-we-dropzone-size: 40px !default;
$o-we-dropzone-border-width: 2px !default;
-$o-we-dropzone-border: $o-we-dropzone-border-width dashed $o-brand-primary !default;
+$o-we-dropzone-border: $o-we-dropzone-border-width dashed $o-brand-odoo !default;
$o-we-handle-edge-size: 1px !default;
$o-we-handle-border-width: 1px !default;
@@ -49,7 +49,7 @@ $o-we-switch-inactive-color: $o-we-color-paper !default;
padding: $padding;
border-top: 1px solid black;
border-bottom: 1px solid white;
- @include o-linear-gradient(-150deg, $o-we-color-dark, $o-we-color-darker);
+ background-image: linear-gradient(-150deg, $o-we-color-dark, $o-we-color-darker);
color: $color-text;
}
@@ -62,12 +62,12 @@ $o-we-switch-inactive-color: $o-we-color-paper !default;
}
-// ============ Preservetion mixins ===============
+// ============ Preservation mixins ===============
// Used to preserve web_editor and website UI from themes customizations
@mixin o-w-preserve-base {
font-family: $o-we-font-family;
- line-height: 1.42857143;
+ line-height: 1.5;
color: $o-we-color-divider;
.text-muted {
@@ -78,7 +78,7 @@ $o-we-switch-inactive-color: $o-we-color-paper !default;
@mixin o-w-preserve-headings {
h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
font-family: $o-we-font-family;
- line-height: 1.42857143;
+ line-height: 1.5;
color: $o-we-color-dark;
font-weight: bold;
}
@@ -86,14 +86,14 @@ $o-we-switch-inactive-color: $o-we-color-paper !default;
@mixin o-w-preserve-links {
a:not(.o_btn_preview) {
- color: $o-brand-optional;
+ color: $o-brand-primary;
&:focus, &:active, &:focus:active {
outline: none!important;
}
}
- .label {
+ .badge {
&:hover a, a {
color: #fff;
}
@@ -105,21 +105,21 @@ $o-we-switch-inactive-color: $o-we-color-paper !default;
height: 34px;
padding: 6px 12px;
font-size: 14px;
- line-height: 1.42857143;
+ line-height: 1.5;
border: 1px solid $o-we-color-text-light;
color: #555;
background-color: #fff;
border-radius: 0;
}
- .has-error {
- .form-control {
- border-color: $state-danger-text;
+ .was-validated {
+ .form-control:invalid {
+ border-color: $danger;
}
}
select.form-control {
- @include o-appearance(none);
+ appearance: none;
background: url('data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPScxLjEnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycgeG1 sbnM6eGxpbms9J2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnIHdpZHRoPScyNCcgaGVpZ2 h0PScyNCcgdmlld0JveD0nMCAwIDI0IDI0Jz48cGF0aCBpZD0nc3ZnXzEnIGQ9J203LjQwNiw3L jgyOGw0LjU5NCw0LjU5NGw0LjU5NCwtNC41OTRsMC40MDYsMS40MDZsLTUsNC43NjZsLTUsLTQu NzY2bDAuNDA2LC0xLjQwNnonIGZpbGw9JyM4ODgnLz48L3N2Zz4=');
background-position: 100% 65%;
background-repeat: no-repeat;
@@ -144,14 +144,14 @@ $o-we-switch-inactive-color: $o-we-color-paper !default;
@mixin o-w-preserve-tabs {
.nav-tabs {
- border-bottom: 1px solid $gray-lighter;
+ border-bottom: 1px solid gray('200');
> li {
> a {
- line-height: 1.42857143;
+ line-height: 1.5;
color: $o-we-color-light;
&:hover {
- border-color: $gray-lighter;
+ border-color: gray('200');
}
}
@@ -159,7 +159,7 @@ $o-we-switch-inactive-color: $o-we-color-paper !default;
&, &:hover, &:focus {
color: $o-we-color-normal;
background-color: $o-we-color-paper;
- border-color: $gray-lighter;
+ border-color: gray('200');
border-bottom-color: transparent;
}
}
@@ -169,61 +169,57 @@ $o-we-switch-inactive-color: $o-we-color-paper !default;
@mixin o-w-preserve-btn {
.btn:not(.o_btn_preview) {
- border-width: 1px;
border-radius: 0;
font-weight: normal;
- @include button-size(6px, 12px, 14px, 1.42857143, 0);
+ @include button-size(.375rem, .75rem, 1rem, 1.5, 0);
&.btn-primary {
- @include button-variant(white, $o-brand-optional, darken($o-brand-optional,5%));
+ @include button-variant($o-brand-primary, $o-brand-primary);
}
- &.btn-default {
- @include button-variant($o-we-color-normal, white, $o-we-color-text-light);
+ &.btn-secondary {
+ @include button-variant($o-we-color-paper, $o-we-color-paper);
+ color: $o-brand-primary;
}
&.btn-link {
- @include button-variant($o-brand-optional, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0));
+ @include button-variant($o-we-color-paper, $o-we-color-paper);
+ color: $o-brand-primary;
}
&.btn-success {
- @include button-variant(white, $o-we-color-success, darken($o-we-color-success, 5%));
+ @include button-variant($o-we-color-success, $o-we-color-success);
}
&.btn-info {
- @include button-variant(white, $o-we-color-info, darken($o-we-color-info, 5%));
+ @include button-variant($o-we-color-info, $o-we-color-info);
}
&.btn-warning {
- @include button-variant(white, $o-we-color-warning, darken($o-we-color-warning, 5%));
+ @include button-variant($o-we-color-warning, $o-we-color-warning);
}
&.btn-danger {
- @include button-variant(white, $o-we-color-danger, darken($o-we-color-danger, 5%));
+ @include button-variant($o-we-color-danger, $o-we-color-danger);
}
&.btn-lg {
- @include button-size(10px, 16px, 18px, 1.3333333, 0);
+ @include button-size(.5rem, 1rem, 1.25rem, 1.5, 0);
}
&.btn-sm {
- @include button-size(5px, 10px, 12px, 1.5, 0);
- }
- &.btn-xs {
- @include button-size(1px, 5px, 12px, 1.5, 0);
+ @include button-size(.25rem, .5rem, .875rem, 1.5, 0);
}
}
}
-@mixin o-w-preserve-wells {
- .well {
+@mixin o-w-preserve-cards {
+ .card {
padding: 19px;
margin-bottom: 20px;
background-color: $o-we-color-paper;
- border: 1px solid darken($o-we-color-paper,5%);
+ border: 1px solid darken($o-we-color-paper, 5%);
border-radius: 0;
- @include box-shadow(none);
+ box-shadow: none;
}
}
// Edition colors
// Colors
-$gray-white: #fff !default;
-
$color-alpha: #1cc1a9 !default;
$color-beta: #875A7B !default;
$color-gamma: #BA3C3D !default;
@@ -238,24 +234,6 @@ $color-white-25: rgba(white, 0.25) !default;
$color-white-50: rgba(white, 0.5) !default;
$color-white-75: rgba(white, 0.75) !default;
-@mixin o-create-color-classes($name, $color, $complementary: o-get-most-contrast($color, $text-color, #FFF), $content-color: $color) {
- .bg-#{$name} {
- background-color: $color;
- color: $complementary;
- .text-muted {
- color: rgba($complementary, 0.4);
- }
- }
- body .text-#{$name} { // body to make the rules more important that bg-* ones
- color: $content-color;
- }
-}
-@mixin o-create-color-btn-classes($name, $color, $complementary: o-get-most-contrast($color, $text-color, #FFF), $border-color: darken($color, 5%)) {
- .btn-#{$name} {
- @include button-variant($complementary, $color, $border-color);
- }
-}
-
// Translations
$o-we-content-to-translate-color: rgb(255, 255, 90) !default;
$o-we-translated-content-color: rgb(120, 215, 110) !default;
diff --git a/addons/web_editor/static/src/xml/ace.xml b/addons/web_editor/static/src/xml/ace.xml
index de713540a67..1d59a94c827 100644
--- a/addons/web_editor/static/src/xml/ace.xml
+++ b/addons/web_editor/static/src/xml/ace.xml
@@ -5,36 +5,42 @@
<div class="o_ace_view_editor">
<div class="form-inline o_ace_view_editor_title">
<div class="btn-group o_ace_type_switcher">
- <button type="button" class="btn btn-sm btn-info dropdown-toggle" data-toggle="dropdown">XML (HTML)</button>
- <ul class="dropdown-menu" role="menu">
- <li><a role="menuitem" href="#" class="o_ace_type_switcher_choice" data-type="xml">XML (HTML)</a></li>
- <li><a role="menuitem" href="#" class="o_ace_type_switcher_choice" data-type="scss">SCSS (CSS)</a></li>
- </ul>
+ <button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown">XML (HTML)</button>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" href="#" class="dropdown-item o_ace_type_switcher_choice" data-type="xml">XML (HTML)</a>
+ <a role="menuitem" href="#" class="dropdown-item o_ace_type_switcher_choice" data-type="scss">SCSS (CSS)</a>
+ </div>
</div>
<select id="ace-view-list" class="o_res_list"/>
- <select id="ace-scss-list" class="o_res_list hidden"/>
+ <select id="ace-scss-list" class="o_res_list d-none"/>
<label class="o_include_option oe_include_bundles">
- <div class="o_checkbox">
- <input type="checkbox" class="js_include_bundles" t-att-checked="widget.options.includeBundles ? 'checked' : undefined"/><span/>
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox" id="o_ace_view_editor_include_bundle"
+ class="custom-control-input js_include_bundles"
+ t-att-checked="widget.options.includeBundles ? 'checked' : undefined"/>
+ <label for="o_ace_view_editor_include_bundle"
+ class="custom-control-label">Include Asset Bundles</label>
</div>
- Include Asset Bundles
</label>
- <label class="o_include_option o_include_all_scss hidden">
- <div class="o_checkbox">
- <input type="checkbox" class="js_include_all_scss" t-att-checked="widget.options.includeAllSCSS ? 'checked' : undefined"/><span/>
+ <label class="o_include_option o_include_all_scss d-none">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox" id="o_ace_view_editor_include_all_scss"
+ class="custom-control-input js_include_all_scss"
+ t-att-checked="widget.options.includeAllSCSS ? 'checked' : undefined"/>
+ <label for="o_ace_view_editor_include_all_scss"
+ class="custom-control-label">Include All SCSS Files</label>
</div>
- Include All SCSS Files
</label>
<div class="o_button_section">
- <button data-action="save" type="submit" class="btn btn-sm btn-primary">Save</button>
- <button data-action="close" type="button" class="btn btn-sm btn-default">Close</button>
+ <button data-action="save" type="submit" class="btn btn-primary">Save</button>
+ <button data-action="close" type="button" class="btn btn-secondary">Close</button>
</div>
</div>
<div id="ace-view-id">
<span/>
- <div class="pull-right">
- <button data-action="reset" type="button" class="btn btn-xs btn-danger"><i class="fa fa-undo"/> Reset</button>
- <button data-action="format" type="button" class="btn btn-xs btn-link">Format</button>
+ <div class="float-right">
+ <button data-action="reset" type="button" class="btn btn-sm btn-danger"><i class="fa fa-undo"/> Reset</button>
+ <button data-action="format" type="button" class="btn btn-sm btn-link">Format</button>
</div>
</div>
<div id="ace-view-editor"/>
diff --git a/addons/web_editor/static/src/xml/backend.xml b/addons/web_editor/static/src/xml/backend.xml
index 40be4f05d07..146d96fe1e5 100644
--- a/addons/web_editor/static/src/xml/backend.xml
+++ b/addons/web_editor/static/src/xml/backend.xml
@@ -8,8 +8,8 @@
</t>
<t t-name="web_editor.FieldTextHtml.button.translate">
- <div class="btn-group pull-right">
- <button t-if="widget.field.translate" class="o_field_translate btn btn-default btn-sm btn-small" style="height: 24px; padding: 1px 17px 0px 5px" aria-label="Translate" title="Translate">
+ <div class="btn-group float-right">
+ <button t-if="widget.field.translate" class="o_field_translate btn btn-secondary" style="height: 24px; padding: 1px 17px 0px 5px" aria-label="Translate" title="Translate">
<span class="fa fa-language fa-lg oe_input_icon"/>
</button>
</div>
diff --git a/addons/web_editor/static/src/xml/editor.xml b/addons/web_editor/static/src/xml/editor.xml
index 3c3085bfe79..7bac85692e2 100644
--- a/addons/web_editor/static/src/xml/editor.xml
+++ b/addons/web_editor/static/src/xml/editor.xml
@@ -9,8 +9,8 @@
<div id="web_editor-top-edit">
<div id="web_editor-toolbars"/>
<form class="navbar-form text-muted">
- <button type="button" class="btn btn-sm btn-default" data-action="cancel"><i class="fa fa-times"/> Discard</button>
- <button type="button" class="btn btn-sm btn-primary" data-action="save"><i class="fa fa-floppy-o"/> Save</button>
+ <button type="button" class="btn btn-secondary" data-action="cancel"><i class="fa fa-times"/> Discard</button>
+ <button type="button" class="btn btn-primary" data-action="save"><i class="fa fa-floppy-o"/> Save</button>
</form>
</div>
</t>
@@ -29,16 +29,16 @@
<!--=================-->
<!-- Alt Dialog (allows to change alt and title of page images) -->
- <form t-name="web_editor.dialog.alt" action="#" class="form-horizontal">
- <div class="form-group">
- <label class="col-sm-3 control-label" for="alt">Description (alt tag)</label>
- <div class="col-sm-8">
+ <form t-name="web_editor.dialog.alt" action="#">
+ <div class="form-group row">
+ <label class="col-md-3 col-form-label" for="alt">Description (alt tag)</label>
+ <div class="col-md-8">
<input class="form-control" id="alt" required="required" t-att-value="widget.alt" type="text"/>
</div>
</div>
- <div class="form-group">
- <label class="col-sm-3 control-label" for="title">Tooltip</label>
- <div class="col-sm-8">
+ <div class="form-group row">
+ <label class="col-md-3 col-form-label" for="title">Tooltip</label>
+ <div class="col-md-8">
<input class="form-control" id="title" required="required" t-att-value="widget.title" type="text"/>
</div>
</div>
@@ -47,30 +47,26 @@
<!-- Media Dialog (allows to choose an img/pictogram/video) -->
<div t-name="web_editor.dialog.media">
<ul class="nav nav-tabs" role="tablist">
- <li class="active"><a role="tab" href="#editor-media-image" aria-controls="editor-media-image" data-toggle="tab" t-att-class="widget.noImages ? 'hidden' : ''">Image</a></li>
- <li><a role="tab" href="#editor-media-document" aria-controls="editor-media-document" data-toggle="tab" t-att-class="widget.noDocuments ? 'hidden' : ''">Document</a></li>
- <li><a role="tab" href="#editor-media-icon" aria-controls="editor-media-icon" data-toggle="tab" t-att-class="widget.noIcons ? 'hidden' : ''">Pictogram</a></li>
- <li><a role="tab" href="#editor-media-video" aria-controls="editor-media-video" data-toggle="tab" t-att-class="widget.noVideos ? 'hidden' : ''">Video</a></li>
- <li class="search pull-right">
- <ul class="pager mb0 mt0">
- <li class="previous">
- <a role="button" class="btn btn-default disabled" href="#"><i class="fa fa-angle-left"/>&#32;Previous</a>
- </li>
- <li class="next">
- <a role="button" class="btn btn-default disabled" href="#">Next&#32;<i class="fa fa-angle-right"/></a>
- </li>
- </ul>
- </li>
- <li class="search pull-right">
+ <li class="nav-item"><a role="tab" href="#editor-media-image" aria-controls="editor-media-image" data-toggle="tab" t-attf-class="nav-link#{widget.noImages ? ' d-none' : ''}">Image</a></li>
+ <li class="nav-item"><a role="tab" href="#editor-media-document" aria-controls="editor-media-document" data-toggle="tab" t-attf-class="nav-link#{widget.noDocuments ? ' d-none' : ''}">Document</a></li>
+ <li class="nav-item"><a role="tab" href="#editor-media-icon" aria-controls="editor-media-icon" data-toggle="tab" t-attf-class="nav-link#{widget.noIcons ? ' d-none' : ''}">Pictogram</a></li>
+ <li class="nav-item"><a role="tab" href="#editor-media-video" aria-controls="editor-media-video" data-toggle="tab" t-attf-class="nav-link#{widget.noVideos ? ' d-none' : ''}">Video</a></li>
+ <li class="nav-item ml-auto search">
<div class="form-group">
<input class="form-control" id="icon-search" type="search"/>
<span class="fa fa-search" title="Search" role="img" aria-label="Search"/>
</div>
</li>
+ <li class="nav-item search">
+ <div class="btn-group">
+ <a role="button" class="btn btn-secondary disabled previous" href="#"><i class="fa fa-angle-left"/>&#32;Previous</a>
+ <a role="button" class="btn btn-secondary disabled next" href="#">Next&#32;<i class="fa fa-angle-right"/></a>
+ </div>
+ </li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
- <div role="tabpanel" class="tab-pane fade in active" id="editor-media-image"/>
+ <div role="tabpanel" class="tab-pane fade" id="editor-media-image"/>
<div role="tabpanel" class="tab-pane fade" id="editor-media-document"/>
<div role="tabpanel" class="tab-pane fade" id="editor-media-icon"/>
<div role="tabpanel" class="tab-pane fade" id="editor-media-video"/>
@@ -88,37 +84,36 @@
<input type="hidden" name="filters" t-att-value="widget.firstFilters.join('_')"/>
<input t-if="widget.options.res_id" type="hidden" name="res_id" t-att-value="widget.options.res_id"/>
<input t-if="widget.options.res_model" type="hidden" name="res_model" t-att-value="widget.options.res_model"/>
- <div class="well">
- <div class="form-group pull-left">
- <input type="file" class="hidden" name="upload" t-att-accept="widget.accept" multiple="multiple"/>
- <input type="hidden" name="disable_optimization" value=""/>
- <div class="btn-group">
- <button class="btn btn-primary o_upload_image_button" type="button">Upload an image</button>
- <button class="btn btn-primary dropdown-toggle" data-toggle="dropdown" type="button">
- <span class="caret"/>
- <span class="sr-only">Alternate Upload</span>
- </button>
- <ul class="dropdown-menu" role="menu">
- <li>
- <a role="menuitem" class="o_upload_image_button_no_optimization">Upload image without optimization</a>
- </li>
- </ul>
- </div>
- </div>
- <div>
- <span class="text-muted">— or —</span>
- <label for="imageurl">Add an image URL</label>
- <div class="form-group btn-group">
- <input type="text" class="form-control url pull-left" id="imageurl" name="url" placeholder="https://www.odoo.com/logo.png" style="width: 250px;"/>
- <button type="button" class="btn btn-default o_upload_image_url_button" disabled="disabled">Add</button>
+ <div class="card">
+ <div class="card-body">
+ <div class="form-inline">
+ <input type="file" class="d-none" name="upload" t-att-accept="widget.accept" multiple="multiple"/>
+ <input type="hidden" name="disable_optimization" value=""/>
+ <div class="btn-group">
+ <button class="btn btn-primary o_upload_image_button" type="button">Upload an image</button>
+ <button class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" type="button">
+ <span class="sr-only">Alternate Upload</span>
+ </button>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" class="dropdown-item o_upload_image_button_no_optimization">Upload image without optimization</a>
+ </div>
+ </div>
+ <span class="text-muted">— or —</span>
+ <label for="imageurl">Add an image URL</label>
+ <div class="input-group">
+ <input type="text" class="form-control url" id="imageurl" name="url" placeholder="https://www.odoo.com/logo.png" style="width: 250px;"/>
+ <div class="input-group-append">
+ <button type="button" class="btn btn-secondary o_upload_image_url_button" disabled="disabled">Add</button>
+ </div>
+ </div>
</div>
</div>
</div>
- <div class="help-block"/>
+ <div class="form-text"/>
<div class="existing-attachments">
<t t-call="web_editor.dialog.image.existing"/>
</div>
- <iframe class="hidden" name="fileframe"/>
+ <iframe class="d-none" name="fileframe"/>
</form>
</t>
<t t-name="web_editor.dialog.image.existing">
@@ -129,9 +124,9 @@
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
<h3 class="modal-title">Select a Picture</h3>
</header>
- <main class="modal-body has-error">
+ <main class="modal-body o_has_error">
<div class="existing-attachments"/>
- <div class="help-block"/>
+ <div class="form-text"/>
</main>
<footer class="modal-footer">
<a data-dismiss="modal" href="#" aria-label="Discard">Discard</a>
@@ -143,7 +138,7 @@
<t t-name="web_editor.dialog.image.existing.content">
<div class="existing-attachments">
<div class="row mt16" t-as="row" t-foreach="rows">
- <div class="col-sm-2 o_existing_attachment_cell" t-as="attachment" t-foreach="row">
+ <div class="col-2 o_existing_attachment_cell" t-as="attachment" t-foreach="row">
<i t-if="attachment.res_model === 'ir.ui.view'" class="fa fa-times o_existing_attachment_remove" title="This file is a public view attachment" role="img" aria-label="This file is a public view attachment" t-att-data-id="attachment.id"/>
<i t-else="" class="fa fa-times o_existing_attachment_remove" title="This file is attached to the current record" role="img" aria-label="This file is attached to the current record" t-att-data-id="attachment.id"/>
<div class="o_attachment_border" t-att-style="attachment.res_model === 'ir.ui.view' ? null : 'border: 1px solid #5cb85c;'"><div t-att-data-src="attachment.src" t-att-data-url="attachment.url" role="img" t-att-aria-label="attachment.name" t-att-title="attachment.name" t-att-data-id="attachment.id" t-att-data-mimetype="attachment.mimetype" class="o_image o_image_loading"/></div>
@@ -152,7 +147,7 @@
</div>
</t>
<t t-name="web_editor.dialog.image.existing.error">
- <div class="help-block">
+ <div class="form-text">
<p>The image could not be deleted because it is used in the
following pages or views:</p>
<ul t-as="view" t-foreach="views">
@@ -187,18 +182,18 @@
</t>
<!-- Video choosing part of the Media Dialog -->
- <t t-name="web_editor.dialog.video">
- <form action="#" class="form-inline well">
+ <div t-name="web_editor.dialog.video" class="card">
+ <form action="#" class="form-inline card-body">
<div class="o_video_dialog_form">
<div class="form-group" id="o_video_form_group">
<label class="mt8" for="o_video_text">Video code <small class="text-muted">(URL or Embed)</small></label>
<textarea class="form-control url" id="o_video_text" placeholder="Copy-paste your URL or embed code here"/>
- <label class="control-label o_validate_feedback" for="o_video_text"><i class="fa fa-check" role="img" aria-label="Checked" title="Checked"/><i class="fa fa-exclamation-triangle" role="img" aria-label="Attention" title="Attention"/></label>
+ <label class="col-form-label o_validate_feedback" for="o_video_text"><i class="fa fa-check" role="img" aria-label="Checked" title="Checked"/><i class="fa fa-exclamation-triangle" role="img" aria-label="Attention" title="Attention"/></label>
</div>
<div class="text-right">
<small class="text-muted">Accepts <b><i>Youtube</i></b>, <b><i>Instagram</i></b>, <b><i>Vine.co</i></b>, <b><i>Vimeo</i></b>, <b><i>Dailymotion</i></b> and <b><i>Youku</i></b> videos</small>
</div>
- <div class="o_video_dialog_options hidden mt48">
+ <div class="o_video_dialog_options d-none mt48">
<small class="text-muted">Options</small>
<ul class="list-group">
<li class="list-group-item o_yt_option o_vim_option o_dm_option">
@@ -226,35 +221,35 @@
</div>
</div>
<div id="video-preview">
- <div class="o_video_dialog_preview_text small mt16 mb8 hidden">Preview</div>
+ <div class="o_video_dialog_preview_text small mt16 mb8 d-none">Preview</div>
<div class="media_iframe_video">
<div class="media_iframe_video_size"/>
<iframe class="o_video_dialog_iframe" allowfullscreen="allowfullscreen" frameborder="0" src=""/>
</div>
</div>
</form>
- </t>
+ </div>
<!-- Link Dialog (allows to choose a style and content for a link on the page) -->
<div t-name="web_editor.dialog.link" class="o_link_dialog">
<div class="row">
- <form class="col-md-8 form-horizontal">
- <div t-attf-class="form-group#{widget.needLabel ? '' : ' hidden'}">
- <label class="control-label col-sm-3" for="o_link_dialog_label_input">Link Label</label>
- <div class="col-sm-9">
+ <form class="col-lg-8">
+ <div t-attf-class="form-group row#{widget.needLabel ? '' : ' d-none'}">
+ <label class="col-form-label col-md-3" for="o_link_dialog_label_input">Link Label</label>
+ <div class="col-md-9">
<input type="text" name="label" class="form-control" id="o_link_dialog_label_input" required="required" t-att-value="widget.data.text"/>
</div>
</div>
- <div class="form-group">
- <label class="control-label col-sm-3" for="o_link_dialog_url_input">URL or Email</label>
- <div class="col-sm-9">
+ <div class="form-group row">
+ <label class="col-form-label col-md-3" for="o_link_dialog_url_input">URL or Email</label>
+ <div class="col-md-9">
<input type="text" name="url" class="form-control" id="o_link_dialog_url_input" required="required"/>
</div>
</div>
- <div class="form-group">
- <label class="control-label col-sm-3">Size</label>
- <div class="col-sm-9">
- <select name="link_style_size" class="form-control col-sm-3 link-style">
+ <div class="form-group row">
+ <label class="col-form-label col-md-3">Size</label>
+ <div class="col-md-9">
+ <select name="link_style_size" class="form-control col-md-3 link-style">
<option value="xs">Extra Small</option>
<option value="sm">Small</option>
<option value="" selected="selected">Medium</option>
@@ -262,26 +257,26 @@
</select>
</div>
</div>
- <div class="form-group">
- <label class="control-label col-sm-3">Color</label>
- <div class="col-sm-9">
+ <div class="form-group row">
+ <label class="col-form-label col-md-3">Color</label>
+ <div class="col-md-9">
<div class="o_link_dialog_color">
<label role="button" t-attf-class="o_link_dialog_color_item o_btn_preview btn btn-link text-center" data-color="">
<span>L</span>
- <input class="hidden link-style" name="link_style_color" type="radio" value=""/>
+ <input class="d-none link-style" name="link_style_color" type="radio" value=""/>
<i class="fa"/>
</label>
- <t t-foreach="['primary', 'default', 'success', 'info', 'warning', 'danger', 'alpha', 'beta', 'gamma', 'delta', 'epsilon']" t-as="color">
+ <t t-foreach="['primary', 'secondary', 'success', 'info', 'warning', 'danger', 'alpha', 'beta', 'gamma', 'delta', 'epsilon']" t-as="color">
<label role="button" t-attf-class="o_link_dialog_color_item o_btn_preview btn btn-#{color}" t-attf-aria-label="Color for #{color}" t-attf-title="Color for #{color}">
- <input type="radio" name="link_style_color" class="hidden link-style" t-att-value="color"/>
+ <input type="radio" name="link_style_color" class="d-none link-style" t-att-value="color"/>
<i class="fa"/>
</label>
</t>
</div>
</div>
</div>
- <div class="form-group">
- <div class="col-sm-offset-3 col-sm-9">
+ <div class="form-group row">
+ <div class="offset-md-3 col-md-9">
<label class="o_switch">
<input type="checkbox" name="is_new_window" t-att-checked="widget.data.isNewWindow ? 'checked' : undefined"/>
<span/>
@@ -290,7 +285,7 @@
</div>
</div>
</form>
- <div class="col-md-4 o_link_dialog_preview">
+ <div class="col-lg-4 o_link_dialog_preview">
<div class="form-group text-center">
<label>Preview</label>
<div style="overflow: auto; max-width: 100%; max-height: 200px;">
@@ -313,31 +308,31 @@
</div>
<t t-else="">
<div class="o_crop_area">
- <img class="img img-responsive o_cropper_image" t-att-src="widget.imageData.originalSrc"/>
+ <img class="img img-fluid o_cropper_image" t-att-src="widget.imageData.originalSrc"/>
</div>
<div class="o_crop_options text-center mt16">
<div class="btn-group" title="Aspect Ratio" data-toggle="buttons">
<t t-foreach="widget.aspectRatioList" t-as="ratio">
<t t-set="is_active" t-value="ratio[1] === widget.imageData.aspectRatio"/>
- <a href="#" t-attf-class="btn btn-default#{is_active and ' active' or ''}" data-event="ratio" t-att-data-label="ratio[1]" t-att-data-value="ratio[2]">
+ <a href="#" t-attf-class="btn btn-secondary#{is_active and ' active' or ''}" data-event="ratio" t-att-data-label="ratio[1]" t-att-data-value="ratio[2]">
<t t-esc="ratio[0]"/>
</a>
</t>
</div>
<div class="btn-group" role="group">
- <a href="#" class="btn btn-default" title="Zoom In" data-event="zoom" data-value="0.1"><i class="fa fa-search-plus"/></a>
- <a href="#" class="btn btn-default" title="Zoom Out" data-event="zoom" data-value="-0.1"><i class="fa fa-search-minus"/></a>
+ <a href="#" class="btn btn-secondary" title="Zoom In" data-event="zoom" data-value="0.1"><i class="fa fa-search-plus"/></a>
+ <a href="#" class="btn btn-secondary" title="Zoom Out" data-event="zoom" data-value="-0.1"><i class="fa fa-search-minus"/></a>
</div>
<div class="btn-group" role="group">
- <a href="#" class="btn btn-default" title="Rotate Left" data-event="rotate" data-value="-45"><i class="fa fa-rotate-left"/></a>
- <a href="#" class="btn btn-default" title="Rotate Right" data-event="rotate" data-value="45"><i class="fa fa-rotate-right"/></a>
+ <a href="#" class="btn btn-secondary" title="Rotate Left" data-event="rotate" data-value="-45"><i class="fa fa-rotate-left"/></a>
+ <a href="#" class="btn btn-secondary" title="Rotate Right" data-event="rotate" data-value="45"><i class="fa fa-rotate-right"/></a>
</div>
<div class="btn-group" role="group">
- <a href="#" class="btn btn-default" title="Flip Horizontal" data-event="flip" data-value="horizontal" data-x="1"><i class="fa fa-arrows-h"/></a>
- <a href="#" class="btn btn-default" title="Flip Vertical" data-event="flip" data-value="vertical" data-y="1"><i class="fa fa-arrows-v"/></a>
+ <a href="#" class="btn btn-secondary" title="Flip Horizontal" data-event="flip" data-value="horizontal" data-x="1"><i class="fa fa-arrows-h"/></a>
+ <a href="#" class="btn btn-secondary" title="Flip Vertical" data-event="flip" data-value="vertical" data-y="1"><i class="fa fa-arrows-v"/></a>
</div>
<div class="btn-group" role="group">
- <a href="#" class="btn btn-default" title="Reset Image" data-event="reset"><i class="fa fa-refresh"/> Reset Image</a>
+ <a href="#" class="btn btn-secondary" title="Reset Image" data-event="reset"><i class="fa fa-refresh"/> Reset Image</a>
</div>
</div>
</t>
@@ -367,10 +362,10 @@
</div>
</div>
<div class="o_bg_img_opt" data-value="contain">
- <form class="form-horizontal">
- <div class="form-group">
- <label class="col-sm-2 control-label" for="repeatInput">Repeat</label>
- <div class="col-sm-5">
+ <form>
+ <div class="form-group row">
+ <label class="col-md-2 col-form-label" for="repeatInput">Repeat</label>
+ <div class="col-md-5">
<div class="checkbox">
<label>
<input type="checkbox" id="o_bg_img_opt_contain_repeat"/>
@@ -380,25 +375,29 @@
</div>
</form>
</div>
- <form class="o_bg_img_opt form-horizontal" data-value="custom">
+ <form class="o_bg_img_opt" data-value="custom">
<fieldset>
<legend>Background size</legend>
<p>Sets the width and height of the background image in percent of the parent element.</p>
- <div class="form-group">
- <label class="col-sm-3 control-label" for="o_bg_img_opt_custom_size_x">Background width</label>
- <div class="col-sm-5">
+ <div class="form-group row">
+ <label class="col-md-3 col-form-label" for="o_bg_img_opt_custom_size_x">Background width</label>
+ <div class="col-md-5">
<div class="input-group">
- <input type="number" min="0" max="100" class="form-control input-sm" id="o_bg_img_opt_custom_size_x" placeholder="auto"/>
- <div class="input-group-addon">%</div>
+ <input type="number" min="0" max="100" class="form-control form-control-sm" id="o_bg_img_opt_custom_size_x" placeholder="auto"/>
+ <div class="input-group-append">
+ <div class="input-group-text">%</div>
+ </div>
</div>
</div>
</div>
- <div class="form-group">
- <label class="col-sm-3 control-label" for="o_bg_img_opt_custom_size_y">Background height</label>
- <div class="col-sm-5">
+ <div class="form-group row">
+ <label class="col-md-3 col-form-label" for="o_bg_img_opt_custom_size_y">Background height</label>
+ <div class="col-md-5">
<div class="input-group">
- <input type="number" min="0" max="100" class="form-control input-sm" id="o_bg_img_opt_custom_size_y" placeholder="auto"/>
- <div class="input-group-addon">%</div>
+ <input type="number" min="0" max="100" class="form-control form-control-sm" id="o_bg_img_opt_custom_size_y" placeholder="auto"/>
+ <div class="input-group-append">
+ <div class="input-group-text">%</div>
+ </div>
</div>
</div>
</div>
@@ -406,21 +405,25 @@
<fieldset>
<legend>Background position</legend>
<p>Set the starting position of the background image.</p>
- <div class="form-group">
- <label class="col-sm-3 control-label" for="o_bg_img_opt_custom_pos_x">Horizontal</label>
- <div class="col-sm-5">
+ <div class="form-group row">
+ <label class="col-md-3 col-form-label" for="o_bg_img_opt_custom_pos_x">Horizontal</label>
+ <div class="col-md-5">
<div class="input-group">
- <input type="number" min="0" max="100" class="form-control input-sm" id="o_bg_img_opt_custom_pos_x" placeholder="auto"/>
- <div class="input-group-addon">%</div>
+ <input type="number" min="0" max="100" class="form-control form-control-sm" id="o_bg_img_opt_custom_pos_x" placeholder="auto"/>
+ <div class="input-group-append">
+ <div class="input-group-text">%</div>
+ </div>
</div>
</div>
</div>
- <div class="form-group">
- <label class="col-sm-3 control-label" for="o_bg_img_opt_custom_pos_y">Vertical</label>
- <div class="col-sm-5">
+ <div class="form-group row">
+ <label class="col-md-3 col-form-label" for="o_bg_img_opt_custom_pos_y">Vertical</label>
+ <div class="col-md-5">
<div class="input-group">
- <input type="number" min="0" max="100" class="form-control input-sm" id="o_bg_img_opt_custom_pos_y" placeholder="auto"/>
- <div class="input-group-addon">%</div>
+ <input type="number" min="0" max="100" class="form-control form-control-sm" id="o_bg_img_opt_custom_pos_y" placeholder="auto"/>
+ <div class="input-group-append">
+ <div class="input-group-text">%</div>
+ </div>
</div>
</div>
</div>
diff --git a/addons/web_editor/static/src/xml/snippets.xml b/addons/web_editor/static/src/xml/snippets.xml
index dcd245f9a3e..93fc31c7de9 100644
--- a/addons/web_editor/static/src/xml/snippets.xml
+++ b/addons/web_editor/static/src/xml/snippets.xml
@@ -10,14 +10,14 @@
</div>
<div class="oe_overlay_options" contentEditable="false">
<div class="btn-group">
- <a role="button" href="#" class="btn btn-default btn-sm oe_snippet_parent" title="Select Parent Container" aria-label="Select Parent Container"><i class="fa fa-lg fa-level-up"/></a>
- <div class="dropdown oe_options hidden btn-group">
- <a role="button" href="#" data-toggle="dropdown" class="btn btn-primary btn-sm" title="Customize">Customize</a>
- <ul class="dropdown-menu" role="menu"/>
+ <a role="button" href="#" class="btn btn-secondary oe_snippet_parent" title="Select Parent Container" aria-label="Select Parent Container"><i class="fa fa-lg fa-level-up"/></a>
+ <div class="dropdown oe_options d-none btn-group">
+ <a role="button" href="#" data-toggle="dropdown" class="btn btn-primary" title="Customize">Customize</a>
+ <div class="dropdown-menu" role="menu"/>
</div>
- <a role="button" href="#" class="btn btn-default btn-sm oe_snippet_move" title="Drag to Move" aria-label="Drag to Move"><i class="fa fa-arrows ml4 mr4"></i></a>
- <a role="button" href="#" class="btn btn-default btn-sm oe_snippet_clone" title="Duplicate Container" aria-label="Duplicate Container"><i class="fa fa-files-o ml4 mr4"></i></a>
- <a role="button" href="#" class="btn btn-default btn-sm oe_snippet_remove" title="Remove Block" aria-label="Remove Block"><i class="fa fa-trash-o ml4 mr4"></i></a>
+ <a role="button" href="#" class="btn btn-secondary oe_snippet_move" title="Drag to Move" aria-label="Drag to Move"><i class="fa fa-arrows ml4 mr4"></i></a>
+ <a role="button" href="#" class="btn btn-secondary oe_snippet_clone" title="Duplicate Container" aria-label="Duplicate Container"><i class="fa fa-files-o ml4 mr4"></i></a>
+ <a role="button" href="#" class="btn btn-secondary oe_snippet_remove" title="Remove Block" aria-label="Remove Block"><i class="fa fa-trash-o ml4 mr4"></i></a>
</div>
</div>
</div>
@@ -32,7 +32,7 @@
</div>
</div>
<div class="o_colorpicker_sections">
- <ul class="nav nav-pills o_colorpicker_section_menu"/>
+ <ul class="nav nav-pills flex-column o_colorpicker_section_menu"/>
<div class="tab-content o_colorpicker_section_tabs"/>
</div>
</div>
@@ -40,10 +40,10 @@
<!-- t-field options -->
<t t-name="web_editor.many2one.button">
<div class="btn-group">
- <a role="button" href="#" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" title="Search Contact" aria-label="Search Contact"><i class="fa fa-search"></i></a>
- <ul class="dropdown-menu contact_menu" role="menu">
- <li><a role="menuitem"><input href="#" type="email" placeholder="Search"/></a></li>
- </ul>
+ <a role="button" href="#" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" title="Search Contact" aria-label="Search Contact"><i class="fa fa-search"></i></a>
+ <div class="dropdown-menu contact_menu" role="menu">
+ <a role="menuitem" class="dropdown-item"><input href="#" type="email" placeholder="Search"/></a>
+ </div>
</div>
</t>
diff --git a/addons/web_editor/views/editor.xml b/addons/web_editor/views/editor.xml
index 3d7d36f18a9..9fa14472206 100644
--- a/addons/web_editor/views/editor.xml
+++ b/addons/web_editor/views/editor.xml
@@ -66,6 +66,12 @@
</xpath>
</template>
+<template id="_assets_backend_helpers" inherit_id="web._assets_backend_helpers">
+ <xpath expr="//link[last()]" position="after">
+ <link rel="stylesheet" type="text/scss" href="/web_editor/static/src/scss/web_editor.common.bootstrap.scss"/>
+ </xpath>
+</template>
+
<template id="assets_backend" inherit_id="web.assets_backend" name="Web Editor Backend Assets (used in backend interface)">
<xpath expr="link[last()]" position="after">
<link rel="stylesheet" type="text/scss" href="/web_editor/static/src/scss/web_editor.common.scss"/> <!-- not in common because compiled differently with context -->
@@ -76,6 +82,12 @@
</xpath>
</template>
+<template id="_assets_frontend_helpers" inherit_id="web._assets_frontend_helpers">
+ <xpath expr="//link[last()]" position="after">
+ <link rel="stylesheet" type="text/scss" href="/web_editor/static/src/scss/web_editor.common.bootstrap.scss"/>
+ </xpath>
+</template>
+
<template id="assets_frontend" inherit_id="web.assets_frontend" name="Web Editor Frontend Assets (used in public odoo)" priority="15">
<xpath expr="//link[last()]" position="after">
<link rel="stylesheet" type="text/scss" href="/web_editor/static/src/scss/web_editor.common.scss"/> <!-- not in common because compiled differently with context -->
@@ -149,11 +161,9 @@
</div>
<div class="o_colorpicker_section" data-name="grayscale" data-icon-class="fa fa-database">
<button data-color="white">White</button>
- <button data-color="gray-lighter">Gray Lighter</button>
- <button data-color="gray-light">Gray Light</button>
- <button data-color="gray">Gray</button>
- <button data-color="gray-dark">Gray Dark</button>
- <button data-color="gray-darker">Gray Darker</button>
+ <t t-foreach="[100, 200, 300, 400, 500, 600, 700, 800, 900]" t-as="gray">
+ <button t-att-data-color="gray">Gray <t t-esc="gray"/></button>
+ </t>
<button data-color="black">Black</button>
</div>
<div class="o_colorpicker_section" data-name="ui" data-icon-class="fa fa-paint-brush">
diff --git a/addons/web_editor/views/snippets.xml b/addons/web_editor/views/snippets.xml
index 096ea58a2ce..3d5cb0165ba 100644
--- a/addons/web_editor/views/snippets.xml
+++ b/addons/web_editor/views/snippets.xml
@@ -12,7 +12,7 @@
</div>
</div>
- <div id="snippet_options" class="hidden">
+ <div id="snippet_options" class="d-none">
<t t-call="web_editor.snippet_options"/>
</div>
</template>