summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorqsm-odoo <qsm@odoo.com>2019-08-27 14:47:47 +0000
committerqsm-odoo <qsm@odoo.com>2019-08-28 09:04:55 +0000
commit4f27e52cabb77b8b1a9637a11185ddf882adc9af (patch)
treeb4b752daef0050988604260d43802413c856bbd7
parent05f9b1f4e680ef05fccf2b9b324ec24282daa65d (diff)
[IMP] web_editor, *: introduce and restore new web_editor UI
* mass_mailing, note, website, website_blog, website_form, website_mass_mailing, website_sale This commit, unfortunately, mixes three things: - Restoring as much as possible the scss organisation to allow styling the web_editor UI properly. - Fixing some bugs like a border around the page once the editor is loaded, no ability to scroll the snippets, etc - Introducing a whole new UI for snippet options: a left panel instead of the old dropdown & button overlay. Note: this commit also do some linting and ES6 convertion even though some of it has been done in the parent commit. Note 2: some elements that were removed are still styled in the POS apps but this is because part of a feature was removed while leaving dead code behind, this is handled in another PR which is to be merged (https://github.com/odoo/odoo/pull/36136). Part of https://github.com/odoo/odoo/pull/36068 task-1942370 closes odoo/odoo#36068 Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
-rw-r--r--addons/mass_mailing/static/src/js/mass_mailing_snippets.js1
-rw-r--r--addons/mass_mailing/static/src/scss/mass_mailing.ui.scss38
-rw-r--r--addons/mass_mailing/views/snippets_themes.xml15
-rw-r--r--addons/note/static/src/scss/note.scss6
-rw-r--r--addons/web_editor/static/src/js/editor/editor.js4
-rw-r--r--addons/web_editor/static/src/js/editor/snippets.editor.js511
-rw-r--r--addons/web_editor/static/src/js/editor/snippets.options.js121
-rw-r--r--addons/web_editor/static/src/scss/web_editor.backend.scss7
-rw-r--r--addons/web_editor/static/src/scss/web_editor.variables.scss72
-rw-r--r--addons/web_editor/static/src/scss/wysiwyg.scss439
-rw-r--r--addons/web_editor/static/src/scss/wysiwyg_iframe.scss13
-rw-r--r--addons/web_editor/static/src/scss/wysiwyg_snippets.scss832
-rw-r--r--addons/web_editor/static/src/xml/snippets.xml38
-rw-r--r--addons/web_editor/static/tests/test_utils.js58
-rw-r--r--addons/web_editor/views/editor.xml3
-rw-r--r--addons/web_editor/views/snippets.xml19
-rw-r--r--addons/website/static/src/js/editor/snippets.options.js3
-rw-r--r--addons/website/static/src/js/tours/banner.js10
-rw-r--r--addons/website/static/src/scss/website.editor.ui.scss4
-rw-r--r--addons/website/static/src/scss/website.wysiwyg.scss380
-rw-r--r--addons/website/static/tests/tours/rte.js2
-rw-r--r--addons/website/views/snippets.xml580
-rw-r--r--addons/website_blog/static/src/js/tours/website_blog.js6
-rw-r--r--addons/website_blog/static/src/js/website_blog.editor.js4
-rw-r--r--addons/website_blog/views/snippets.xml150
-rw-r--r--addons/website_form/static/tests/tours/website_form_editor.js107
-rw-r--r--addons/website_form/views/snippets.xml40
-rw-r--r--addons/website_mass_mailing/static/src/scss/website_mass_mailing.editor.scss2
-rw-r--r--addons/website_sale/static/src/js/website_sale.editor.js6
-rw-r--r--addons/website_sale/static/src/scss/website_sale.editor.scss6
-rw-r--r--addons/website_sale/views/snippets.xml68
31 files changed, 1498 insertions, 2047 deletions
diff --git a/addons/mass_mailing/static/src/js/mass_mailing_snippets.js b/addons/mass_mailing/static/src/js/mass_mailing_snippets.js
index fe8093b17d9..ad4864d0b07 100644
--- a/addons/mass_mailing/static/src/js/mass_mailing_snippets.js
+++ b/addons/mass_mailing/static/src/js/mass_mailing_snippets.js
@@ -20,7 +20,6 @@ options.registry.mass_mailing_sizing_x = options.Class.extend({
this.isIMG = this.$target.is("img");
if (this.isIMG) {
this.$overlay.find(".o_handle.w").addClass("readonly");
- this.$overlay.find(".oe_snippet_move, .oe_snippet_clone").addClass('d-none');
}
var $body = $(this.ownerDocument.body);
diff --git a/addons/mass_mailing/static/src/scss/mass_mailing.ui.scss b/addons/mass_mailing/static/src/scss/mass_mailing.ui.scss
index 7aec2b165e9..e39e04498e6 100644
--- a/addons/mass_mailing/static/src/scss/mass_mailing.ui.scss
+++ b/addons/mass_mailing/static/src/scss/mass_mailing.ui.scss
@@ -9,18 +9,18 @@
.o_mail_theme_selector {
> a {
@include o-position-absolute(0, 0, auto, 0);
- height: $o-wysiwyg-toolbar-height;
- line-height: $o-wysiwyg-toolbar-height;
+ height: $o-we-toolbar-height;
+ line-height: $o-we-toolbar-height;
border-radius: 0;
- background-color: $o-wysiwyg-bg-color;
- color: $o-wysiwyg-color;
+ background-color: $o-we-bg-color;
+ color: $o-we-color;
display: flex;
justify-content: center;
align-items: center;
box-shadow: none !important;
&:hover, &:focus, &:active {
- color: $o-wysiwyg-color-light;
+ color: $o-we-color-light;
}
i {
@@ -30,7 +30,7 @@
&.show > a {
color: white;
- background-color: $o-wysiwyg-color;
+ background-color: $o-we-color;
}
.dropdown-menu {
@@ -42,7 +42,7 @@
margin: 0;
border-radius: 0;
overflow: auto;
- background-color: $o-wysiwyg-bg-color;
+ background-color: $o-we-bg-color;
z-index: 1050;
&.show {
@@ -61,7 +61,7 @@
display: none;
background-size: cover;
padding-top: 50%;
- border: 1px solid $o-wysiwyg-border-color;
+ border: 1px solid $o-we-border-color;
&.logo {
@@ -71,7 +71,7 @@
&:hover {
- background-color: $o-wysiwyg-bg-color;
+ background-color: $o-we-bg-color;
.o_thumb {
border: 1px solid black;
@@ -80,7 +80,7 @@
&.selected .o_thumb {
border: 2px solid $o-brand-odoo;
- background-color: $o-wysiwyg-bg-color;
+ background-color: $o-we-bg-color;
}
}
}
@@ -113,8 +113,8 @@ body.o_force_mail_theme_choice {
.o_thumb {
display: none;
padding-top: 107%;
- border: 1px solid $o-wysiwyg-color-light;
- border-top: 1px solid $o-wysiwyg-border-color;
+ border: 1px solid $o-we-color-light;
+ border-top: 1px solid $o-we-border-color;
box-shadow: 0 5px 10px rgba(black, 0.8);
will-change: transform;
backface-visibility: hidden;
@@ -135,7 +135,7 @@ body.o_force_mail_theme_choice {
}
&:hover {
- background-color: $o-wysiwyg-color;
+ background-color: $o-we-color;
.o_thumb {
box-shadow: 0 5px 30px 1px rgba(black, 0.6);
@@ -174,14 +174,16 @@ body.o_force_mail_theme_choice {
}
}
-.o_basic_theme.o_in_iframe {
+body.editor_enable.o_basic_theme.o_in_iframe {
padding-left: 0px !important;
+
+ #web_editor-top-edit .note-popover .popover {
+ left: 0 !important;
+ }
+
#oe_snippets {
display: none;
}
- .note-editor.o_snippets_loaded {
- padding-left: 0px!important;
- }
}
.note-editable .o_layout {
@@ -191,7 +193,7 @@ body.o_force_mail_theme_choice {
#web_editor-toolbars .popover .note-color {
.note-back-color-preview .dropdown-toggle,
.note-fore-color-preview .dropdown-toggle {
- height: $o-wysiwyg-toolbar-height - 1;
+ height: $o-we-toolbar-height - 1;
}
}
diff --git a/addons/mass_mailing/views/snippets_themes.xml b/addons/mass_mailing/views/snippets_themes.xml
index ac6c75ba128..b268850e6f7 100644
--- a/addons/mass_mailing/views/snippets_themes.xml
+++ b/addons/mass_mailing/views/snippets_themes.xml
@@ -2,11 +2,11 @@
<odoo>
<!-- Snippets & Themes Menu -->
<template id="email_designer_snippets" inherit_id="web_editor.snippets" primary="True">
- <xpath expr="//h2[@id='snippets_menu']" position="replace">
- <t t-set="company_id" t-value="res_company"/>
- <h2 id="snippets_menu">Select a template</h2>
+ <xpath expr="//div[@id='snippets_menu']" position="inside">
+ <button type="button" disabled="disabled">Select a template</button>
</xpath>
<xpath expr="//div[@id='o_scroll']" position="replace">
+ <t t-set="company_id" t-value="res_company"/>
<div id="o_scroll">
<div id="email_designer_themes">
<div data-name="basic"
@@ -72,7 +72,6 @@
</div>
</div>
</xpath>
-
<xpath expr="//div[@id='snippet_options']" position="inside">
<t t-call="mass_mailing.snippet_options"/>
</xpath>
@@ -811,10 +810,10 @@
<div data-js="colorpicker"
data-selector=".note-editable > div:not(.o_layout), .note-editable .oe_structure > div, td, th"
data-exclude=".o_mail_no_colorpicker, .o_mail_no_options">
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-eyedropper"/>Background Color</a>
- <div class="dropdown-menu" role="menu"/>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-eyedropper"/> Background Color</we-toggler>
+ <we-collapse/>
+ </we-collapse-area>
</div>
</template>
</odoo>
diff --git a/addons/note/static/src/scss/note.scss b/addons/note/static/src/scss/note.scss
index f060c58d74e..2e15d5de46b 100644
--- a/addons/note/static/src/scss/note.scss
+++ b/addons/note/static/src/scss/note.scss
@@ -8,13 +8,9 @@
margin-bottom: 0;
}
.oe_form_field.oe_memo {
- margin: 0 ($input-btn-padding-x-lg * -1);
+ margin: 0;
padding: 0;
min-height: 200px;
-
- .note-editor {
- border: none;
- }
}
&.o_form_readonly {
.oe_memo {
diff --git a/addons/web_editor/static/src/js/editor/editor.js b/addons/web_editor/static/src/js/editor/editor.js
index 07947db56e4..31c31e5ce6a 100644
--- a/addons/web_editor/static/src/js/editor/editor.js
+++ b/addons/web_editor/static/src/js/editor/editor.js
@@ -106,7 +106,9 @@ var EditorMenuBar = Widget.extend({
// Snippets menu
if (self.snippetsMenu) {
- defs.push(this.snippetsMenu.insertAfter(this.$el));
+ // TODO improve this, the editor can be relocated so here,
+ // 'insertAfter(this.$el)' won't work.
+ defs.push(this.snippetsMenu.appendTo(this.$el.parent()));
}
this.rte.editable().find('*').off('mousedown mouseup click');
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 1f0bda9a1fc..fdb79ebd04a 100644
--- a/addons/web_editor/static/src/js/editor/snippets.editor.js
+++ b/addons/web_editor/static/src/js/editor/snippets.editor.js
@@ -1,6 +1,7 @@
odoo.define('web_editor.snippet.editor', function (require) {
'use strict';
+var concurrency = require('web.concurrency');
var core = require('web.core');
var dom = require('web.dom');
var Widget = require('web.Widget');
@@ -22,13 +23,9 @@ var SnippetEditor = Widget.extend({
template: 'web_editor.snippet_overlay',
xmlDependencies: ['/web_editor/static/src/xml/snippets.xml'],
events: {
- 'click .oe_snippet_parent': '_onParentButtonClick',
- 'click .oe_snippet_clone': '_onCloneClick',
- 'click .oe_snippet_remove': '_onRemoveClick',
- 'mousedown .oe_options [data-toggle="dropdown"]:first': '_onOpenCusomize',
+ 'mousedown': '_onUIMouseDown',
},
custom_events: {
- cover_update: '_onCoverUpdate',
'option_update': '_onOptionUpdate',
},
@@ -49,57 +46,57 @@ var SnippetEditor = Widget.extend({
this.$target = $(target);
this.$target.data('snippet-editor', this);
this.templateOptions = templateOptions;
+ this.isTargetParentEditable = false;
+ this.isTargetMovable = false;
},
/**
* @override
*/
start: function () {
- var self = this;
var defs = [this._super.apply(this, arguments)];
- // Hide parent button if no parent
- var $parent = globalSelector.closest(this.$target.parent());
- if (!$parent.length) {
- this.$('.oe_snippet_parent').remove();
- }
-
// Initialize the associated options (see snippets.options.js)
defs.push(this._initializeOptions());
+ var $customize = this._customize$Elements[this._customize$Elements.length - 1];
+
+ this.isTargetParentEditable = this.$target.parent().is(':o_editable');
+ this.isTargetMovable = this.isTargetParentEditable && this.isTargetMovable;
// Initialize move/clone/remove buttons
- if (!this.$target.is(':o_editable')) {
- this.$el.find('.oe_snippet_move, .oe_snippet_clone, .oe_snippet_remove').remove();
- } else {
+ if (this.isTargetMovable) {
this.dropped = false;
this.$el.draggable({
greedy: true,
appendTo: this.$body,
cursor: 'move',
- handle: '.oe_snippet_move',
+ handle: '.o_move_handle',
cursorAt: {
left: 18,
top: 14
},
- helper: function () {
- 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(self.$body).removeClass('d-none');
+ helper: () => {
+ var $clone = this.$el.clone().css({width: '24px', height: '24px', border: 0});
+ $clone.appendTo(this.$body).removeClass('d-none');
return $clone;
},
- start: _.bind(self._onDragAndDropStart, self),
- stop: _.bind(self._onDragAndDropStop, self)
+ start: this._onDragAndDropStart.bind(this),
+ stop: this._onDragAndDropStop.bind(this),
});
+ } else {
+ this.$('.o_move_handle').addClass('d-none');
+ $customize.find('.oe_snippet_clone').addClass('d-none');
}
- this.$target.on('transitionstart.snippet_editor, animationstart.snippet_editor', function () {
- self._targetIsAnimated = true;
+ if (!this.isTargetParentEditable) {
+ $customize.find('.oe_snippet_remove').addClass('d-none');
+ }
+
+ this.$target.on('transitionstart.snippet_editor, animationstart.snippet_editor', () => {
+ this._targetIsAnimated = true;
});
- this.$target.on('transitionend.snippet_editor, animationend.snippet_editor', function () {
- self._targetIsAnimated = false;
- if (self.$el.is('.oe_active')) {
- self.cover();
- }
+ this.$target.on('transitionend.snippet_editor, animationend.snippet_editor', () => {
+ this._targetIsAnimated = false;
+ this.cover();
});
return Promise.all(defs);
@@ -143,9 +140,10 @@ var SnippetEditor = Widget.extend({
* Makes the editor overlay cover the associated snippet.
*/
cover: function () {
- if (this._targetIsAnimated) {
+ if (this._targetIsAnimated || !this.isShown() || !this.$target.length) {
// Do not cover a target being animated, it will be covered once the
- // animation is completed.
+ // animation is completed. Also ignore if the overlay is not shown
+ // yet or that the $target element has been removed.
return;
}
var offset = this.$target.offset();
@@ -161,6 +159,24 @@ var SnippetEditor = Widget.extend({
this.$el.toggleClass('o_top_cover', offset.top < this.$editable.offset().top);
},
/**
+ * @returns {boolean}
+ */
+ isOpened: function () {
+ return this.$el && this.$el.hasClass('o_we_options_opened');
+ },
+ /**
+ * @return {boolean}
+ */
+ isShown: function () {
+ return this.$el && this.$el.parent().length && this.$el.hasClass('oe_active');
+ },
+ /**
+ * @return {boolean}
+ */
+ isSticky: function () {
+ return this.$el && this.$el.hasClass('o_we_sticky');
+ },
+ /**
* Removes the associated snippet from the DOM and destroys the associated
* editor (itself).
*/
@@ -176,6 +192,7 @@ var SnippetEditor = Widget.extend({
},
});
+ this.trigger_up('go_to_parent', {$snippet: this.$target});
var $parent = this.$target.parent();
this.$target.find('*').addBack().tooltip('dispose');
this.$target.remove();
@@ -217,51 +234,25 @@ var SnippetEditor = Widget.extend({
* snippet options are moved to the editor overlay.
*
* @param {boolean} focus - true to display, false to hide
+ * @param {boolean} [previewMode=false]
+ * @param {boolean} [onlyOverlay=false]
*/
- toggleFocus: function (focus) {
+ toggleFocus: function (focus, previewMode, onlyOverlay) {
if (!this.$el) {
return;
}
- var do_action = (focus ? _do_action_focus : _do_action_blur);
-
- // Attach own and parent options on the current overlay
- var $style_button = this.$el.find('.oe_options');
- var $ul = $style_button.find('.dropdown-menu:first');
- var $headers = $ul.find('.dropdown-header:data(editor)');
- _.each($headers, (function (el) {
- var $el = $(el);
- var styles = _.values($el.data('editor').styles);
- if ($el.data('editor') !== this) {
- styles = _.filter(styles, function (option) { return !option.preventChildPropagation; });
- }
- var count = 0;
- _.each(_.sortBy(styles, '__order').reverse(), function (style) {
- if (do_action(style, $el)) {
- count++;
- }
- });
- $el.toggleClass('d-none', count === 0);
- }).bind(this));
-
- // Activate the overlay
- $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);
-
- if (focus) {
- this.trigger_up('snippet_focused');
+ if (!previewMode && !onlyOverlay) {
+ this._toggleOptions(focus ? (this._customize$Elements.length - 1) : false);
}
-
- function _do_action_focus(style, $dest) {
- style.$el.insertAfter($dest);
- style.onFocus();
- return (style.$el.length > 0);
- }
- function _do_action_blur(style, $dest) {
- style.$el.detach();
- style.onBlur();
- return false;
+ this._toggleOverlay(!!focus, previewMode ? undefined : !!focus);
+ },
+ /**
+ * @param {boolean} [isTextEdition=false]
+ */
+ toggleTextEdition: function (isTextEdition) {
+ if (this.$el) {
+ this.$el.toggleClass('o_keypress', !!isTextEdition && this.isShown());
}
},
@@ -291,58 +282,112 @@ var SnippetEditor = Widget.extend({
* @private
*/
_initializeOptions: function () {
- var self = this;
- var $styles = this.$el.find('.oe_options');
- var $ul = $styles.find('.dropdown-menu:first');
+ this._customize$Elements = [];
this.styles = {};
this.selectorSiblings = [];
this.selectorChildren = [];
+ var $element = this.$target.parent();
+ while ($element.length) {
+ var parentEditor = $element.data('snippet-editor');
+ if (parentEditor) {
+ this._customize$Elements = this._customize$Elements
+ .concat(parentEditor._customize$Elements);
+ break;
+ }
+ $element = $element.parent();
+ }
+
+ var $optionsSection = $(core.qweb.render('web_editor.customize_block_options_section', {
+ name: this._getName(),
+ })).data('editor', this);
+ $optionsSection.on('mouseover', this._onOptionsSectionMouseOver.bind(this));
+ $optionsSection.on('mouseleave', this._onOptionsSectionMouseLeave.bind(this));
+ $optionsSection.on('click', this._onOptionsSectionClick.bind(this));
+ $optionsSection.on('click', '.oe_snippet_clone', this._onCloneClick.bind(this));
+ $optionsSection.on('click', '.oe_snippet_remove', this._onRemoveClick.bind(this));
+ this._customize$Elements.push($optionsSection);
+
var i = 0;
- $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)) {
+ var defs = _.map(this.templateOptions, val => {
+ if (!val.selector.is(this.$target)) {
return;
}
- if (val['drop-near']) self.selectorSiblings.push(val['drop-near']);
- if (val['drop-in']) self.selectorChildren.push(val['drop-in']);
+ if (val['drop-near']) {
+ this.selectorSiblings.push(val['drop-near']);
+ }
+ if (val['drop-in']) {
+ this.selectorChildren.push(val['drop-in']);
+ }
var optionName = val.option;
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,
- self.$el,
+ this,
+ val.base_target ? this.$target.find(val.base_target).eq(0) : this.$target,
+ this.$el,
val.data,
- self.options
+ this.options
);
- self.styles[optionName || _.uniqueId('option')] = option;
+ this.styles[optionName || _.uniqueId('option')] = option;
option.__order = i++;
- return option.attachTo($el);
+ var $optionSection = $(core.qweb.render('web_editor.customize_block_option'));
+ $optionSection.append($el);
+ return option.attachTo($optionSection);
});
- $ul.append($('<div/>', {class: 'dropdown-divider mt-2'}));
- var $parents = this.$target.parents();
- _.each($parents, function (parent) {
- var parentEditor = $(parent).data('snippet-editor');
- if (parentEditor) {
- for (var styleName in parentEditor.styles) {
- if (!parentEditor.styles[styleName].preventChildPropagation) {
- $ul.append($('<div/>', {class: 'dropdown-header o_parent_editor_header', text: parentEditor._getName()}).data('editor', parentEditor));
- break;
- }
- }
- }
- });
-
- if (!this.selectorSiblings.length && !this.selectorChildren.length) {
- this.$el.find('.oe_snippet_move, .oe_snippet_clone').addClass('d-none');
- }
+ this.isTargetMovable = (this.selectorSiblings.length > 0 || this.selectorChildren.length > 0);
this.$el.find('[data-toggle="dropdown"]').dropdown();
return Promise.all(defs);
},
+ /**
+ * @private
+ * @param {integer|false} index
+ */
+ _toggleOptions: function (index) {
+ if (index === false || !this._customize$Elements[index].parent().length) {
+ this.trigger_up('update_customize_elements', {
+ customize$Elements: index !== false ? this._customize$Elements : [],
+ });
+ }
+ this._customize$Elements.forEach(($el, i) => {
+ var open = (i === index);
+
+ $el.toggleClass('o_we_closed', !open);
+
+ var editor = $el.data('editor');
+ editor.$el.toggleClass('o_we_options_opened', open);
+
+ var styles = _.values(editor.styles);
+ $el.toggleClass('d-none', styles.length === 0);
+ _.each(_.sortBy(styles, '__order').reverse(), function (style) {
+ if (open) {
+ style.$el.appendTo($el);
+ style.onFocus();
+ } else {
+ style.$el.detach();
+ style.onBlur();
+ }
+ });
+ });
+ },
+ /**
+ * @private
+ * @param {boolean} show - whether the overlay should be shown or not
+ * @param {boolean} [sticky]
+ * whether the overlay should be sticky or not (if the value is
+ * undefined, the stickyness is left unchanged)
+ */
+ _toggleOverlay: function (show, sticky) {
+ this.$el.toggleClass('oe_active', show);
+ this.cover();
+
+ if (sticky !== undefined) {
+ this.$el.toggleClass('o_we_sticky', sticky);
+ }
+ },
//--------------------------------------------------------------------------
// Handlers
@@ -356,7 +401,7 @@ var SnippetEditor = Widget.extend({
*/
_onCloneClick: function (ev) {
ev.preventDefault();
- this.trigger_up('cover_will_change');
+ ev.stopPropagation();
this.trigger_up('snippet_will_be_cloned', {$target: this.$target});
@@ -378,15 +423,6 @@ var SnippetEditor = Widget.extend({
$clone.trigger('content_changed');
},
/**
- * Called when the overlay dimensions/positions should be recomputed.
- *
- * @private
- */
- _onCoverUpdate: function () {
- this.trigger_up('cover_will_change');
- this.cover();
- },
- /**
* Called when the snippet is starting to be dragged thanks to the 'move'
* button.
*
@@ -440,8 +476,6 @@ var SnippetEditor = Widget.extend({
self.dropped = false;
},
});
-
- this.trigger_up('cover_will_change');
},
/**
* Called when the snippet is dropped after being dragged thanks to the
@@ -504,6 +538,47 @@ var SnippetEditor = Widget.extend({
});
},
/**
+ * @private
+ */
+ _onOptionsSectionMouseOver: function (ev) {
+ var $optionsSection = $(ev.currentTarget);
+ if (!$optionsSection.hasClass('o_we_closed')) {
+ return;
+ }
+
+ this.trigger_up('activate_snippet', {
+ $snippet: this.$target,
+ previewMode: true,
+ });
+ },
+ /**
+ * @private
+ */
+ _onOptionsSectionMouseLeave: function (ev) {
+ this.trigger_up('activate_snippet', {
+ $snippet: false,
+ previewMode: true,
+ });
+ },
+ /**
+ * @private
+ */
+ _onOptionsSectionClick: function (ev) {
+ var $optionsSection = $(ev.currentTarget);
+ if (!$optionsSection.hasClass('o_we_closed')) {
+ return;
+ }
+
+ this.trigger_up('activate_snippet', {
+ $snippet: this.$target,
+ previewMode: false,
+ onlyOverlay: true,
+ });
+ var $neighbors = $optionsSection.nextAll('we-customizeblock-options');
+ var editor = $neighbors.length ? $neighbors.last().data('editor') : this;
+ editor._toggleOptions($optionsSection.index());
+ },
+ /**
* Called when a child editor/option asks for another option to perform a
* specific action/react to a specific event.
*
@@ -511,7 +586,6 @@ var SnippetEditor = Widget.extend({
* @param {OdooEvent} ev
*/
_onOptionUpdate: function (ev) {
- this.trigger_up('cover_will_change');
// If multiple option names are given, we suppose it should not be
// propagated to parent editor
if (ev.data.optionNames) {
@@ -535,28 +609,6 @@ var SnippetEditor = Widget.extend({
}
},
/**
- * Called when the user opens the customize menu.
- *
- * @private
- * @param {OdooEvent} ev
- */
- _onOpenCusomize: function (ev) {
- this.trigger_up('request_history_undo_record', {$target: this.$target});
- },
-
- /**
- * Called when the 'parent' button is clicked.
- *
- * @private
- * @param {Event} ev
- */
- _onParentButtonClick: function (ev) {
- ev.preventDefault();
- this.trigger_up('go_to_parent', {
- $snippet: this.$target,
- });
- },
- /**
* Called when the 'remove' button is clicked.
*
* @private
@@ -564,10 +616,24 @@ var SnippetEditor = Widget.extend({
*/
_onRemoveClick: function (ev) {
ev.preventDefault();
- this.trigger_up('cover_will_change');
+ ev.stopPropagation();
this.trigger_up('request_history_undo_record', {$target: this.$target});
this.removeSnippet();
},
+ /**
+ * The UI is displayed on hover and become sticky once the related target is
+ * clicked. If we click the UI while it is not sticky, it should become
+ * sticky.
+ *
+ * @private
+ */
+ _onUIMouseDown: function (ev) {
+ if (!this.isOpened()) {
+ this.trigger_up('activate_snippet', {
+ $snippet: this.$target,
+ });
+ }
+ }
});
/**
@@ -576,16 +642,21 @@ var SnippetEditor = Widget.extend({
var SnippetsMenu = Widget.extend({
id: 'oe_snippets',
cacheSnippetTemplate: {},
- activeSnippets: [],
+ events: {
+ 'click we-collapse-area > we-toggler': '_onCollapseTogglerClick',
+ },
custom_events: {
'activate_insertion_zones': '_onActivateInsertionZones',
+ 'activate_snippet': '_onActivateSnippet',
'call_for_each_child_snippet': '_onCallForEachChildSnippet',
+ 'cover_update': '_onOverlaysCoverUpdate',
'deactivate_snippet': '_onDeactivateSnippet',
'drag_and_drop_stop': '_onDragAndDropStop',
'go_to_parent': '_onGoToParent',
'remove_snippet': '_onRemoveSnippet',
'snippet_removed': '_onSnippetRemoved',
'reload_snippet_dropzones': '_disableUndroppableSnippets',
+ 'update_customize_elements': '_onUpdateCustomizeElements',
},
/**
@@ -613,8 +684,8 @@ var SnippetsMenu = Widget.extend({
if (!this.options.snippets) {
this.options.snippets = 'web_editor.snippets';
}
- this.$activeSnippet = false;
this.snippetEditors = [];
+ this._activateSnippetMutex = new concurrency.Mutex();
this.setSelectorEditableArea(options.$el, options.selectorEditableArea);
},
@@ -622,7 +693,6 @@ var SnippetsMenu = Widget.extend({
* @override
*/
start: function () {
- var self = this;
var defs = [this._super.apply(this, arguments)];
this.ownerDocument = this.$el[0].ownerDocument;
this.$document = $(this.ownerDocument);
@@ -631,8 +701,12 @@ var SnippetsMenu = Widget.extend({
// Fetch snippet templates and compute it
- defs.push(this.loadSnippets().then(function (html) {
- return self._computeSnippetTemplates(html);
+ defs.push(this.loadSnippets().then(html => {
+ return this._computeSnippetTemplates(html);
+ }).then(() => {
+ this.customizePanel = document.createElement('div');
+ this.customizePanel.classList.add('o_we_customize_panel', 'd-none');
+ this.$el.append(this.customizePanel);
}));
// Prepare snippets editor environment
@@ -653,7 +727,14 @@ var SnippetsMenu = Widget.extend({
});
var $target = $(srcElement);
- if ($target.closest('.oe_overlay, .note-popover').length) {
+ if ($target.closest('#snippets_menu').length) {
+ this._activateSnippet(false);
+ return;
+ }
+ if (!$target.closest('body > *').length) {
+ return;
+ }
+ if ($target.closest('#web_editor-top-edit, #oe_snippets, #oe_manipulators, .o_technical_modal, .oe_drop_zone').length) {
return;
}
this._activateSnippet($target);
@@ -663,23 +744,23 @@ var SnippetsMenu = Widget.extend({
core.bus.on('snippet_editor_clean_for_save', this, this._onCleanForSaveDemand);
// Adapt overlay covering when the window is resized / content changes
- var debouncedCoverUpdate = _.debounce(function () {
- self.updateCurrentSnippetEditorOverlay();
- }, 200);
+ var debouncedCoverUpdate = _.throttle(() => {
+ this.updateCurrentSnippetEditorOverlay();
+ }, 50);
this.$window.on('resize.snippets_menu', debouncedCoverUpdate);
this.$window.on('content_changed.snippets_menu', debouncedCoverUpdate);
// On keydown add a class on the active overlay to hide it and show it
// again when the mouse moves
- this.$document.on('keydown.snippets_menu', function () {
- if (self.$activeSnippet && self.$activeSnippet.data('snippet-editor')) {
- self.$activeSnippet.data('snippet-editor').$el.addClass('o_keypress');
- }
+ this.$document.on('keydown.snippets_menu', () => {
+ this.snippetEditors.forEach(editor => {
+ editor.toggleTextEdition(true);
+ });
});
- this.$document.on('mousemove.snippets_menu, mousedown.snippets_menu', function () {
- if (self.$activeSnippet && self.$activeSnippet.data('snippet-editor')) {
- self.$activeSnippet.data('snippet-editor').$el.removeClass('o_keypress');
- }
+ this.$document.on('mousemove.snippets_menu, mousedown.snippets_menu', () => {
+ this.snippetEditors.forEach(editor => {
+ editor.toggleTextEdition(false);
+ });
});
// Auto-selects text elements with a specific class and remove this
@@ -694,12 +775,19 @@ var SnippetsMenu = Widget.extend({
$(range && range.sc).closest('.o_default_snippet_text').removeClass('o_default_snippet_text');
});
- return Promise.all(defs).then(function () {
+ return Promise.all(defs).then(() => {
+ this.$('[data-title]').tooltip({
+ delay: 0,
+ title: function () {
+ return this.classList.contains('active') ? false : this.dataset.title;
+ },
+ });
+
// Trigger a resize event once entering edit mode as the snippets
// menu will take part of the screen width (delayed because of
// animation). (TODO wait for real animation end)
- setTimeout(function () {
- self.$window.trigger('resize');
+ setTimeout(() => {
+ this.$window.trigger('resize');
}, 1000);
});
},
@@ -782,11 +870,9 @@ var SnippetsMenu = Widget.extend({
* Updates the cover dimensions of the current snippet editor.
*/
updateCurrentSnippetEditorOverlay: function () {
- if (this.$activeSnippet && this.$activeSnippet.data('snippet-editor')) {
- this.$activeSnippet.data('snippet-editor').cover();
- }
this.snippetEditors = _.filter(this.snippetEditors, function (snippetEditor) {
if (snippetEditor.$target.closest('body').length) {
+ snippetEditor.cover();
return true;
}
snippetEditor.destroy();
@@ -946,38 +1032,36 @@ var SnippetsMenu = Widget.extend({
* first parent which is one is used instead.
*
* @param {jQuery|false} $snippet
- * The DOM element whose editor need to be enabled. Only disable the
- * current one if false is given.
+ * The DOM element whose editor (and its parent ones) need to be
+ * enabled. Only disable the current one if false is given.
+ * @param {boolean} [previewMode=false]
+ * @param {boolean} [onlyOverlay=false]
* @returns {Promise<SnippetEditor>}
* (might be async when an editor must be created)
*/
- _activateSnippet: function ($snippet) {
- if ($snippet) {
- if (!globalSelector.is($snippet)) {
+ _activateSnippet: function ($snippet, previewMode, onlyOverlay) {
+ return this._activateSnippetMutex.exec(() => {
+ // First disable all shown editors and also sticky ones if not in
+ // preview mode (so new sticky ones have to be shown)
+ this.snippetEditors.forEach(editor => {
+ if (!previewMode || editor.isShown() && !editor.isSticky()) {
+ editor.toggleFocus(false, previewMode, onlyOverlay);
+ }
+ });
+ // Take the first parent of the provided DOM (or itself) which
+ // should have an associated snippet editor and create + enable it.
+ if ($snippet && $snippet.length) {
$snippet = globalSelector.closest($snippet);
+ if (!$snippet.length) {
+ return Promise.resolve(null);
+ }
+ return this._createSnippetEditor($snippet).then(editor => {
+ editor.toggleFocus(true, previewMode, onlyOverlay);
+ return editor;
+ });
}
- if (this.$activeSnippet && this.$activeSnippet[0] === $snippet[0]) {
- return Promise.resolve($snippet.data('snippet-editor'));
- }
- }
- var editor = null;
- if (this.$activeSnippet) {
- editor = this.$activeSnippet.data('snippet-editor');
- if (editor) {
- editor.toggleFocus(false);
- }
- this.$activeSnippet = false;
- }
- if ($snippet && $snippet.length) {
- var self = this;
- this.trigger_up('activate_snippet', $snippet);
- return this._createSnippetEditor($snippet).then(function (editor) {
- self.$activeSnippet = $snippet;
- editor.toggleFocus(true);
- return editor;
- });
- }
- return Promise.resolve(editor);
+ return Promise.resolve(null);
+ });
},
/**
* @private
@@ -1362,7 +1446,7 @@ var SnippetsMenu = Widget.extend({
}
}
- $toInsert = $baseBody.clone().data('name', $baseBody.data('name'));
+ $toInsert = $baseBody.clone().attr('data-name', $baseBody.data('name'));
if (!$selectorSiblings.length && !$selectorChildren.length) {
console.warn($snippet.find('.oe_snippet_thumbnail_title').text() + " have not insert action: data-drop-near or data-drop-in");
@@ -1390,8 +1474,6 @@ var SnippetsMenu = Widget.extend({
}
},
});
-
- self.trigger_up('cover_will_change');
},
stop: function (ev, ui) {
$toInsert.removeClass('oe_snippet_body');
@@ -1435,9 +1517,6 @@ var SnippetsMenu = Widget.extend({
editor.buildSnippet();
}).then(function () {
$target.trigger('content_changed');
- if ($target.closest('body').length) { // can be destroyed (eg in test)
- self._activateSnippet($target);
- }
});
});
} else {
@@ -1481,6 +1560,15 @@ var SnippetsMenu = Widget.extend({
this._activateInsertionZones(ev.data.$selectorSiblings, ev.data.$selectorChildren);
},
/**
+ * Called when a child editor asks to deactivate the current snippet
+ * overlay.
+ *
+ * @private
+ */
+ _onActivateSnippet: function (ev) {
+ this._activateSnippet(ev.data.$snippet, ev.data.previewMode, ev.data.onlyOverlay);
+ },
+ /**
* Called when a child editor asks to operate some operation on all child
* snippet of a DOM element.
*
@@ -1500,6 +1588,24 @@ var SnippetsMenu = Widget.extend({
this.cleanForSave();
},
/**
+ * @private
+ * @param {*} ev
+ */
+ _onCollapseTogglerClick: function (ev) {
+ this.$('we-collapse-area > we-toggler').not(ev.currentTarget).removeClass('active');
+ ev.currentTarget.classList.toggle('active');
+ },
+ /**
+ * Called when the overlay dimensions/positions should be recomputed.
+ *
+ * @private
+ */
+ _onOverlaysCoverUpdate: function () {
+ this.snippetEditors.forEach(editor => {
+ editor.cover();
+ });
+ },
+ /**
* Called when a child editor asks to deactivate the current snippet
* overlay.
*
@@ -1548,6 +1654,23 @@ var SnippetsMenu = Widget.extend({
_onSnippetRemoved: function () {
this._disableUndroppableSnippets();
},
+ /**
+ * @private
+ * @param {OdooEvent} ev
+ */
+ _onUpdateCustomizeElements: function (ev) {
+ while (this.customizePanel.firstChild) {
+ this.customizePanel.removeChild(this.customizePanel.firstChild);
+ }
+ ev.data.customize$Elements.forEach($el => {
+ this.customizePanel.appendChild($el[0]);
+ });
+ var customize = !!ev.data.customize$Elements.length;
+ this.$('#o_scroll').toggleClass('d-none', customize);
+ this.$('.o_we_add_snippet_btn').toggleClass('active', !customize);
+ this.customizePanel.classList.toggle('d-none', !customize);
+ this.$('.o_we_customize_snippet_btn').toggleClass('active', customize);
+ },
});
return {
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 893fd8adebb..63f0c38c7c3 100644
--- a/addons/web_editor/static/src/js/editor/snippets.options.js
+++ b/addons/web_editor/static/src/js/editor/snippets.options.js
@@ -18,23 +18,16 @@ var _t = core._t;
var SnippetOption = Widget.extend({
events: {
'mouseenter': '_onLinkEnter',
- 'mouseenter a': '_onLinkEnter',
+ 'mouseenter we-button': '_onLinkEnter',
'click': '_onLinkClick',
- 'click a': '_onLinkClick',
+ 'click we-button': '_onLinkClick',
'mouseleave': '_onMouseleave',
- 'mouseleave a': '_onMouseleave',
- 'mouseleave .dropdown-menu': '_onMouseleave',
+ 'mouseleave we-button': '_onMouseleave',
},
- /**
- * When editing a snippet, its options are shown alongside the ones of its
- * parent snippets. The parent options are only shown if the following flag
- * is set to false (default).
- */
- preventChildPropagation: false,
/**
- * The option `$el` is supposed to be the associated DOM element in the
- * options dropdown. The option controls another DOM element: the snippet it
+ * The option `$el` is supposed to be the associated DOM UI element.
+ * 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).
*
@@ -120,7 +113,7 @@ 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 item having a `data-select-class`
+ * case is having a sub-collapse with each item having a `data-select-class`
* value allowing to choose the associated class.
*
* @param {boolean|string} previewMode
@@ -131,12 +124,14 @@ var SnippetOption = Widget.extend({
* @param {jQuery} $opt - the related DOMElement option
*/
selectClass: function (previewMode, value, $opt) {
- var $group = $opt && $opt.parents('.dropdown-submenu').last();
+ var $group = $opt && $opt.parents('we-collapse-area').last();
if (!$group || !$group.length) {
$group = this.$el;
}
- var $lis = $group.find('[data-select-class]').addBack('[data-select-class]');
- var classes = $lis.map(function () {return $(this).data('selectClass');}).get().join(' ');
+ var $lis = $group.find('[data-select-class]');
+ var classes = $lis.map(function () {
+ return $(this).data('selectClass');
+ }).get().join(' ');
this.$target.removeClass(classes);
if (value) {
@@ -146,15 +141,19 @@ 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 item having a `data-toggle-class`
+ * case is having a sub-collapse with each item having a `data-toggle-class`
* value allowing to toggle the associated class.
*
* @see this.selectClass
*/
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(' ');
+ var $lis = this.$el.find('[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(' ');
this.$target.removeClass(classes).addClass(activeClasses);
if (value && previewMode !== 'reset') {
@@ -168,7 +167,7 @@ var SnippetOption = Widget.extend({
/**
* Override the helper method to search inside the $target element instead
- * of the dropdown item element.
+ * of the UI item element.
*
* @override
*/
@@ -211,7 +210,7 @@ var SnippetOption = Widget.extend({
*/
_reset: function () {
var self = this;
- var $actives = this.$el.find('.active').addBack('.active');
+ var $actives = this.$el.find('we-button.active');
_.each($actives, function (activeElement) {
var $activeElement = $(activeElement);
self.__methodNames = _.without.apply(_, [self.__methodNames].concat(_.keys($activeElement.data())));
@@ -233,8 +232,6 @@ var SnippetOption = Widget.extend({
* @param {jQuery} $opt - the related DOMElement option
*/
_select: function (previewMode, $opt) {
- var self = this;
-
// Options can say they respond to strong choice
if (previewMode && ($opt.data('noPreview') || $opt.parent().data('noPreview'))) {
return;
@@ -244,7 +241,6 @@ var SnippetOption = Widget.extend({
if (!previewMode) {
this._reset();
this.trigger_up('request_history_undo_record', {$target: this.$target});
- this.$target.trigger('content_changed');
}
// Search for methods (data-...) (i.e. data-toggle-class) on the
@@ -275,6 +271,8 @@ var SnippetOption = Widget.extend({
if (!previewMode) {
this._setActive();
}
+
+ this.$target.trigger('content_changed');
},
/**
* Tweaks the option DOM elements to show the selected value according to
@@ -286,7 +284,6 @@ var SnippetOption = Widget.extend({
_setActive: function () {
var self = this;
this.$el.find('[data-toggle-class]')
- .addBack('[data-toggle-class]')
.removeClass('active')
.filter(function () {
var className = $(this).data('toggleClass');
@@ -295,25 +292,20 @@ var SnippetOption = Widget.extend({
.addClass('active');
// Get submenus which are not inside submenus
- var $submenus = this.$el.find('.dropdown-submenu')
- .addBack('.dropdown-submenu')
- .not('.dropdown-submenu .dropdown-submenu');
+ var $submenus = this.$el.find('we-collapse-area')
+ .not('we-collapse-area we-collapse-area');
// Add unique active class for each submenu active item
_.each($submenus, function (submenu) {
- var $elements = _getSelectClassElements($(submenu));
+ var $elements = $(submenu).find('[data-select-class]');
_processSelectClassElements($elements);
});
// Add unique active class for out-of-submenu active item
- var $externalElements = _getSelectClassElements(this.$el)
- .not('.dropdown-submenu *, .dropdown-submenu');
+ var $externalElements = this.$el.find('[data-select-class]')
+ .not('we-collapse-area *, we-collapse-area');
_processSelectClassElements($externalElements);
- function _getSelectClassElements($el) {
- return $el.find('[data-select-class]')
- .addBack('[data-select-class]');
- }
function _processSelectClassElements($elements) {
var maxNbClasses = -1;
$elements.removeClass('active')
@@ -343,20 +335,11 @@ var SnippetOption = Widget.extend({
* @param {Event} ev
*/
_onLinkEnter: function (ev) {
- var $opt = $(ev.target).closest('.dropdown-item');
+ var $opt = $(ev.target).closest('we-button');
if (!$opt.length) {
return;
}
- var $dsmenu = $opt.parent('.dropdown-submenu');
- if ($dsmenu.length) {
- var $menu = $dsmenu.children('.dropdown-menu'); // FIXME
- if ($menu.length) {
- var menuRightPosition = $dsmenu.offset().left + $dsmenu.outerWidth() + $menu.outerWidth();
- $menu.toggleClass('o_open_to_left', menuRightPosition > $(window).outerWidth());
- }
- }
-
if (!$opt.is(':hasData')) {
return;
}
@@ -371,7 +354,7 @@ var SnippetOption = Widget.extend({
* @param {Event} ev
*/
_onLinkClick: function (ev) {
- var $opt = $(ev.target).closest('.dropdown-item');
+ var $opt = $(ev.target).closest('we-button');
if (ev.isDefaultPrevented() || !$opt.length || !$opt.is(':hasData')) {
return;
}
@@ -403,8 +386,6 @@ var SnippetOption = Widget.extend({
var registry = {};
registry.sizing = SnippetOption.extend({
- preventChildPropagation: true,
-
/**
* @override
*/
@@ -413,11 +394,8 @@ registry.sizing = SnippetOption.extend({
var def = this._super.apply(this, arguments);
this.$handles = this.$overlay.find('.o_handle');
- var resizeValues = this._getSize();
- _.each(resizeValues, function (value, key) {
- self.$handles.filter('.' + key).toggleClass('readonly', !value);
- });
+ var resizeValues = this._getSize();
this.$handles.on('mousedown', function (ev) {
ev.preventDefault();
@@ -522,8 +500,19 @@ registry.sizing = SnippetOption.extend({
* @override
*/
onFocus: function () {
+ var resizeValues = this._getSize();
+ _.each(resizeValues, (value, key) => {
+ this.$handles.filter('.' + key).toggleClass('readonly', !value);
+ });
+
this._onResize();
},
+ /**
+ * @override
+ */
+ onBlur: function () {
+ this.$handles.addClass('readonly');
+ },
//--------------------------------------------------------------------------
// Public
@@ -596,6 +585,9 @@ registry.sizing = SnippetOption.extend({
width: ml,
left: '-' + ml,
});
+ this.$overlay.find('.o_handle.e').css({
+ width: 0,
+ });
_.each(this.$overlay.find(".o_handle.n, .o_handle.s"), function (handle) {
var $handle = $(handle);
var direction = $handle.hasClass('n') ? 'top': 'bottom';
@@ -671,7 +663,7 @@ registry.colorpicker = SnippetOption.extend({
var $clpicker = $(qweb.render('web_editor.colorpicker'));
_.each($clpicker.find('.o_colorpicker_section'), function (elem) {
- $(elem).prepend("<div class='text-muted mt8'>" + elem.dataset.display + "</div>");
+ $(elem).prepend("<div>" + elem.dataset.display + "</div>");
});
// Retrieve excluded palettes list
@@ -705,7 +697,7 @@ registry.colorpicker = SnippetOption.extend({
}
$pt.find('.o_colorpicker_section_tabs').append($clpicker);
- this.$el.find('.dropdown-menu').append($pt);
+ this.$el.find('we-collapse').append($pt);
}
var classes = [];
@@ -945,7 +937,7 @@ registry.background = SnippetOption.extend({
_setCustomBackground: function (value) {
this.__customImageSrc = value;
this.background(false, this.__customImageSrc);
- this.$target.addClass('oe_custom_bg');
+ this.$target.toggleClass('oe_custom_bg', !!value);
this._setActive();
this.$target.trigger('snippet-option-change', [this]);
},
@@ -1193,7 +1185,7 @@ registry.many2one = SnippetOption.extend({
// create search button and bind search bar
this.$btn = $(qweb.render('web_editor.many2one.button'))
- .insertAfter(this.$overlay.find('.oe_options'));
+ .prependTo(this.$el);
this.$ul = this.$btn.find('ul');
this.$search = this.$ul.find('li:first');
@@ -1203,17 +1195,10 @@ registry.many2one = SnippetOption.extend({
// move menu item
setTimeout(function () {
- 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'
- });
- } else {
- self.$btn.find('a').on('click', function (e) {
- self._clear();
- });
- }
- },0);
+ self.$btn.find('a').on('click', function (e) {
+ self._clear();
+ });
+ }, 0);
// bind search input
this.$search.find('input')
diff --git a/addons/web_editor/static/src/scss/web_editor.backend.scss b/addons/web_editor/static/src/scss/web_editor.backend.scss
index ecbe42721f3..385bb370fd7 100644
--- a/addons/web_editor/static/src/scss/web_editor.backend.scss
+++ b/addons/web_editor/static/src/scss/web_editor.backend.scss
@@ -3,7 +3,7 @@
word-wrap: break-word;
.note-editable {
- min-height: 180px;
+ min-height: 330px;
font: inherit !important;
font-family: inherit !important;
line-height: inherit !important;
@@ -23,13 +23,16 @@
width: 100%;
margin: 0;
padding: 0;
- border: 0;
ul > li > p {
margin: 0px;
}
min-height: 300px;
min-height: -webkit-calc(100vh - 170px);
min-height: calc(100vh - 170px);
+
+ &.o_readonly {
+ border: none;
+ }
}
.rounded {
border-radius: .25rem !important;
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 fd821c547c2..b03277b2b95 100644
--- a/addons/web_editor/static/src/scss/web_editor.variables.scss
+++ b/addons/web_editor/static/src/scss/web_editor.variables.scss
@@ -2,14 +2,22 @@
/// This files regroups the variables and mixins which are specific to the editor.
///
-$o-we-font-family: Roboto, 'Montserrat', "Segoe UI","Helvetica Neue",Helvetica,Arial,sans-serif !default;
+$o-we-font-family: Roboto, 'Montserrat', 'Segoe UI', 'Helvetica Neue', Helvetica, Arial, sans-serif !default;
+
+$o-we-font-size: 13px;
+$o-we-bg-color: #F7F7F7 !default;
+$o-we-bg-color-dark: #a7a7a7 !default;
+$o-we-color: #212629 !default;
+$o-we-border-width: 1px !default;
+$o-we-border-color: rgba(0, 0, 0, 0.125) !default;
+$o-we-dropdown-bg-color: #FFFFFF;
+$o-we-dropdown-color: inherit;
$o-we-color-dark: #2c2c36 !default;
$o-we-color-darker: darken($o-we-color-dark, 2%) !default;
$o-we-color-divider: #33363e !default;
$o-we-color-light: #4e525b !default;
-$o-we-color-normal: #50545d !default;
-$o-we-color-paper: #fcfcfc !default;
+$o-we-color-normal: #3D4047 !default;
$o-we-color-text-normal: #999999 !default;
$o-we-color-text-light: #d4d5d7 !default;
$o-we-color-text-lighter: #ebecee !default;
@@ -18,58 +26,38 @@ $o-we-color-warning: #f0ad4e !default;
$o-we-color-success: #40ad67 !default;
$o-we-color-info: #6999a8 !default;
-$o-we-sidebar-width: 210px !default;
+$o-we-sidebar-width: 230px !default;
-$o-we-tab-active-bg: #3D4048 !default;
+$o-we-handles-offset-to-hide: 10000px !default;
+$o-we-handles-btn-size: 18px !default;
+$o-we-handles-accent-color: #00e2ff !default;
+$o-we-handles-accent-color-preview: $o-enterprise-color !default;
+$o-we-handle-edge-size: 8px !default;
+$o-we-handle-border-width: 2px !default;
+$o-we-handle-border-width-preview: 6px !default;
// Transitions
$o-we-md-ease: cubic-bezier(0.19, 1, 0.22, 1) !default;
// Editor
-$o-we-dropzone-size: 40px !default;
+$o-we-dropzone-size: 30px !default; // $grid-gutter-width (todo: allow to use the variable)
$o-we-dropzone-border-width: 2px !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;
-$o-we-handles-offset-to-hide: 10000px !default;
-$o-we-handles-accent-color: #00e2ff !default;
-$o-we-handles-btn-size: 18px !default;
-
-$o-we-overlay-option-size: 25px !default;
-
$o-we-ace-color: #2F3129 !default;
$o-we-switch-size: 2ex !default;
-$o-we-switch-inactive-color: $o-we-color-paper !default;
+$o-we-switch-inactive-color: $o-we-bg-color !default;
// Checklist
$o-checklist-margin-left: 20px;
$o-checklist-checkmark-width: 2px;
$o-checklist-before-size: 13px;
-$o-wysiwyg-zindex: 1000;
-
-$o-wysiwyg-md-ease: cubic-bezier(0.19, 1, 0.22, 1) !default;
-
-$o-wysiwyg-font-family: Roboto,
-"Montserrat",
-"Segoe UI",
-"Helvetica Neue",
-Helvetica,
-Arial,
-sans-serif;
-
-$o-wysiwyg-toolbar-height: 32px;
-
-$o-wysiwyg-color: #212629 !default;
-$o-wysiwyg-color-light: #616669 !default;
-$o-wysiwyg-color-danger: #912629 !default;
-$o-wysiwyg-color-success: #219629 !default;
-$o-wysiwyg-bg-color: #f7f7f7 !default;
-$o-wysiwyg-bg-color-dark: #a7a7a7 !default;
-$o-wysiwyg-border-color: #a9a9a9 !default;
+$o-we-zindex: 1000;
+$o-we-overlay-zindex: $o-we-zindex - 10;
+$o-we-toolbar-height: 32px;
// ============ 'Preview' component Mixins ===============
// Create a "preview" work-area to edit/customize specific elements
@@ -191,7 +179,7 @@ $o-wysiwyg-border-color: #a9a9a9 !default;
.modal-content {
border-radius: 0;
- background-color: $o-we-color-paper;
+ background-color: $o-we-bg-color;
.modal-header {
border-bottom-color: #e9ecef;
@@ -222,7 +210,7 @@ $o-wysiwyg-border-color: #a9a9a9 !default;
&.active {
&, &:hover, &:focus {
color: $o-we-color-normal;
- background-color: $o-we-color-paper;
+ background-color: $o-we-bg-color;
border-color: #dee2e6 #dee2e6 #FFFFFF;
}
}
@@ -242,11 +230,11 @@ $o-wysiwyg-border-color: #a9a9a9 !default;
@include button-variant($o-brand-primary, $o-brand-primary);
}
&.btn-secondary {
- @include button-variant($o-we-color-paper, $o-we-color-paper);
+ @include button-variant($o-we-bg-color, $o-we-bg-color);
color: $o-brand-primary;
}
&.btn-link {
- @include button-variant($o-we-color-paper, $o-we-color-paper);
+ @include button-variant($o-we-bg-color, $o-we-bg-color);
color: $o-brand-primary;
}
&.btn-success {
@@ -268,8 +256,8 @@ $o-wysiwyg-border-color: #a9a9a9 !default;
.card {
padding: 19px;
margin-bottom: 20px;
- background-color: $o-we-color-paper;
- border: 1px solid darken($o-we-color-paper, 5%);
+ background-color: $o-we-bg-color;
+ border: 1px solid darken($o-we-bg-color, 5%);
border-radius: 0;
box-shadow: none;
}
diff --git a/addons/web_editor/static/src/scss/wysiwyg.scss b/addons/web_editor/static/src/scss/wysiwyg.scss
index cd8fa7bcf44..90180133f12 100644
--- a/addons/web_editor/static/src/scss/wysiwyg.scss
+++ b/addons/web_editor/static/src/scss/wysiwyg.scss
@@ -1,322 +1,168 @@
-// NOTE EDITOR
+// Use css variables to control the default style of the editor so that an
+// external assets bundle can influence it without duplicating the css.
+:root {
+ --o-we-toolbar-height: #{$o-we-toolbar-height};
-body.editor_enable {
- padding-top: $o-wysiwyg-toolbar-height !important;
-}
+ --o-we-bg-color: #{$o-we-bg-color};
+ --o-we-bg-color-dark: #{$o-we-bg-color-dark};
+ --o-we-color: #{$o-we-color};
+ --o-we-color-accent: #{$o-we-color};
-#wrapwrap {
- height: calc(100vh - #{$o-wysiwyg-toolbar-height});
- border: 1px solid $o-wysiwyg-border-color;
- border-left: 0;
- border-top: 0;
+ --o-we-dropdown-bg-color: #{$o-we-dropdown-bg-color};
+ --o-we-dropdown-color: #{$o-we-dropdown-color};
- .btn {
- -webkit-user-select: none;
- }
+ --o-we-snippets-bg-color: #{$o-we-bg-color};
+ --o-we-snippets-color: #{$o-we-color};
}
-// TOP BAR (EDIT)
+// EDITOR TOP BAR AND POPOVER
+body.editor_enable {
+ padding-top: var(--o-we-toolbar-height) !important;
+}
#web_editor-top-edit {
- height: $o-wysiwyg-toolbar-height;
- background-color: $o-wysiwyg-bg-color;
- z-index: $o-wysiwyg-zindex - 2;
+ @include o-position-absolute(0, 0, auto, 0);
position: fixed;
- top: 0px;
- right: 0px;
- left: 0px;
- white-space: nowrap;
- border: 1px solid $o-wysiwyg-border-color;
- border-bottom: 1px solid rgba(0, 0, 0, 0.125);
-
- transition: background-color 400ms $o-we-md-ease 0s;
- font-family: $o-we-font-family;
-}
-
-.note-editor.note-frame {
- background-color: inherit;
-
- .note-editing-area .note-editable {
- background-color: transparent !important;
- color: inherit;
- padding-left: 0;
- padding-right: 0;
- }
-
- &.fullscreen {
- background-color: #fff;
+ z-index: $o-we-zindex;
+ height: var(--o-we-toolbar-height);
+ background-color: var(--o-we-bg-color);
+
+ .note-popover .popover {
+ top: 0 !important;
+ left: 0 !important;
+ right: 0 !important;
+ border: none !important;
}
}
-.note-editor:not(.note-frame) .note-editing-area {
- overflow: visible;
-}
-
-#web_editor-top-edit .note-popover .popover {
- height: $o-wysiwyg-toolbar-height - 2;
- top: 0 !important;
- left: 0 !important;
- padding: 0;
+.wysiwyg_iframe,
+.note-editor {
+ border: $o-we-border-width solid $o-we-border-color;
margin: 0;
- border: 0;
- width: auto;
- text-align: center;
- box-shadow: none;
- background-color: $o-wysiwyg-bg-color;
- z-index: $o-wysiwyg-zindex;
-
- .popover-body {
- height: $o-wysiwyg-toolbar-height - 2;
-
- > .btn-group {
- height: $o-wysiwyg-toolbar-height - 2;
- margin-top: 0;
- }
-
- .btn {
- height: $o-wysiwyg-toolbar-height - 2;
- border-top: 0;
- }
- }
+ padding: 0;
}
+.note-popover .popover .popover-body,
+.panel-heading.note-toolbar {
+ height: var(--o-we-toolbar-height);
+ padding-bottom: 0;
+ border-bottom: $o-we-border-width solid $o-we-border-color;
+ background-color: var(--o-we-bg-color);
+ font-family: $o-we-font-family;
+ white-space: nowrap;
-#web_editor-toolbars .popover,
-.note-popover.popover .popover-content,
-.note-editor .note-toolbar {
- font-family: $o-wysiwyg-font-family;
-
- h1,
- h2,
- h3,
- h4,
- h5,
- h6,
- .h1,
- .h2,
- .h3,
- .h4,
- .h5,
- .h6 {
- font-family: $o-wysiwyg-font-family;
- }
-
- .btn {
+ // Main layout of buttons
+ .btn-group, .btn {
+ width: auto !important;
+ height: 100% !important;
+ margin-top: 0;
+ margin-bottom: 0;
+ background: transparent;
border: none;
border-radius: 0;
- background-color: inherit;
+ }
+ .btn-secondary {
color: inherit;
- transition: all 0.3s ease 0s;
+ }
+
+ // Active buttons and opened dropdowns
+ .btn {
+ padding: 0.5em 0.75em !important;
+ border-left: 1px solid transparent;
+ border-right: 1px solid transparent;
+ color: var(--o-we-color);
+ font-size: $o-we-font-size !important;
- >.fa {
- color: inherit;
+ &.active {
+ background-color: var(--o-we-bg-color-dark);
+ color: var(--o-we-color-accent);
}
&:hover {
- border-top: 2px solid inherit;
- color: inherit;
-
- >.fa {
- color: inherit;
- }
+ color: var(--o-we-color-accent);
}
- .o_image_alt {
- @include o-text-overflow(inline-block);
- max-width: 100px;
+ &:focus, &:active, &:focus:active {
+ @extend %we-active-button;
}
-
- &.active {
- background-color: inherit;
- color: inherit;
- box-shadow: inset 0 3px 10px rgba(0, 0, 0, 0.5);
-
- >.fa {
- color: inherit;
- }
+ }
+ .btn-group.show {
+ > .btn {
+ @extend %we-active-button;
}
-
- &.o_disabled {
- opacity: 0.5;
- pointer-events: none;
+ &::after {
+ content: '';
+ @include o-position-absolute(100%, $o-we-border-width, auto, $o-we-border-width);
+ height: $o-we-border-width;
+ background-color: var(--o-we-dropdown-bg-color);
}
}
-
- .note-btn-group {
- margin: 0;
- }
-
- >.btn-group {
- margin-top: 0;
-
- &.show,
- .btn-group.show {
- .dropdown-toggle {
- border-top: 2px solid white;
- background-color: $o-wysiwyg-bg-color-dark;
- box-shadow: none;
-
- >.fa,
- >span {
- color: inherit;
- }
- }
- }
+ %we-active-button {
+ border-left-color: $o-we-border-color;
+ border-right-color: $o-we-border-color;
+ background: var(--o-we-dropdown-bg-color);
+ box-shadow: none !important;
+ outline: none !important;
}
-
.dropdown-menu {
- margin: 0;
+ margin-top: 0;
+ border: $o-we-border-width solid $o-we-border-color;
+ border-top-color: transparent;
border-radius: 0;
- background-color: $o-wysiwyg-bg-color;
- color: inherit;
- white-space: normal;
-
- .dropdown-item {
- width: 100%;
- color: inherit;
-
- >.fa {
- color: inherit;
- }
-
- &:hover {
- background-color: $o-wysiwyg-bg-color-dark;
- color: inherit;
-
- >.fa {
- color: inherit;
- }
- }
- }
+ background-color: var(--o-we-dropdown-bg-color);
+ color: var(--o-we-dropdown-color);
+ box-shadow: none;
}
-
- .note-para .dropdown-menu {
+ .dropdown-menu.show { // To overcome .note-XXX .dropdown-menu rules
min-width: 0;
- white-space: nowrap;
}
+ .dropdown-item { // To overcome summernote rules breaking this in iframes
+ display: block;
+ max-width: none;
+ overflow: visible;
+ color: var(--o-we-color);
- .note-color {
-
- .note-back-color-preview,
- .note-fore-color-preview {
- .dropdown-toggle {
- padding: 0px 7px;
- height: 35px;
- width: auto;
- border-top: none;
- border-bottom: 3px solid;
-
- &:after {
- display: none;
- }
- }
- }
-
- .dropdown-menu {
- min-width: 180px;
-
- .note-custom-color {
- cursor: pointer;
- border-radius: 5px;
-
- &:hover {
- background-color: gray('400');
- color: black
- }
- }
- }
-
- .dropdown-toggle:after {
- display: none;
- }
-
- .note-palette:first-child {
- width: 100%;
-
- .note-color-reset,
- .note-custom-color {
- width: 162px;
- }
-
- .note-color-reset {
- padding: 0 3px !important;
- height: 32px;
- }
-
- .note-holder,
- .note-color-palette .note-color-row,
- .note-custom-color-palette .note-color-row {
- height: auto !important;
-
- &::after {
- content: "";
- display: table;
- clear: both;
- }
-
- .note-color-btn {
- float: left;
- height: 20px;
- width: 20px;
- margin: 1px 1px 0 0;
- border: 1px solid black;
- cursor: pointer;
- @include o-alpha-button-preview;
-
- &.o_small {
- width: 16px;
- height: 16px;
- margin: 3px 3px 2px 2px;
- border-radius: 50%;
- }
-
- &.o_clear {
- clear: both;
- }
+ &:hover {
+ background-color: var(--o-we-bg-color) !important;
+ color: var(--o-we-color-accent) !important;
- &.o_btn_transparent {
- display: none;
- }
- }
+ > * {
+ color: inherit !important;
}
}
}
-}
-
-.note-popover.popover.note-hint-popover .popover-content {
- height: auto;
-}
-.note-popover,
-.note-editor {
- .modal .modal-footer p {
- display: none;
+ // Specific elements
+ .o_image_alt {
+ @include o-text-overflow();
+ max-width: 150px;
}
-}
-
-.note-handle {
- pointer-events: none;
-
- .note-control-selection {
- z-index: 1;
- overflow: hidden;
-
- .note-control-se {
- border-top: 0;
- border-left: 0;
- background: transparent;
- }
+ .note-color-palette div .note-color-btn {
+ border-color: var(--o-we-dropdown-bg-color);
}
}
-.o_fake_editable:not([data-oe-model]):focus {
- outline: none;
+// ANIMATIONS
+@keyframes fadeInDownSmall {
+ 0% {
+ opacity: 0;
+ transform: translate(0, -5px);
+ }
+ 100% {
+ opacity: 1;
+ transform: translate(0, 0);
+ }
}
-.note-editor.dragover .note-dropzone {
- z-index: $o-wysiwyg-zindex + 1;
+@keyframes inputHighlighter {
+ from {
+ background: $o-brand-primary;
+ }
+ to {
+ width: 0;
+ background: transparent;
+ }
}
// MODALS
-
body .modal {
// SELECT MEDIA
@@ -362,7 +208,7 @@ body .modal {
@include o-position-absolute($top: 0, $right: 0);
border-radius: 0 0 0 2px;
&:hover {
- color: $o-wysiwyg-color-danger;
+ color: $o-we-color-danger;
}
}
@@ -390,7 +236,7 @@ body .modal {
}
.font-icons-icons {
- >span {
+ > span {
text-align: center;
font-size: 22px;
margin: 5px;
@@ -401,8 +247,8 @@ body .modal {
&.o_selected {
cursor: auto;
- background-color: $o-wysiwyg-bg-color-dark;
- box-shadow: 0px 0px 0px 1px $o-wysiwyg-color-success;
+ background-color: $o-we-bg-color-dark;
+ box-shadow: 0px 0px 0px 1px $o-we-color-success;
}
}
}
@@ -421,7 +267,7 @@ body .modal {
position: relative;
width: 100%;
- >textarea {
+ > textarea {
width: 100%;
min-height: 95px;
padding-bottom: 25px;
@@ -460,7 +306,7 @@ body .modal {
.cropper-point {
background-color: white;
- transition: all 400ms $o-wysiwyg-md-ease 0s;
+ 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);
@@ -482,7 +328,7 @@ body .modal {
// LINK EDITOR DIALOG COLOR SELECTOR
.o_link_dialog {
- .o_link_dialog_color>.o_link_dialog_color_item {
+ .o_link_dialog_color > .o_link_dialog_color_item {
position: relative;
width: 30px;
height: 30px;
@@ -490,7 +336,7 @@ body .modal {
border: 2px solid rgba(0, 0, 0, 0.25);
border-radius: 50%;
- input:checked+i::before {
+ input:checked + i::before {
content: "\f00c";
@include o-position-absolute($top: 6px, $left: 5px);
}
@@ -498,7 +344,7 @@ body .modal {
&.btn-link {
padding: 3px 9px;
- >span {
+ > span {
text-decoration: underline;
}
}
@@ -511,7 +357,7 @@ body .modal {
.o_we_image_optimize_dialog {
.o_we_title_label {
- font-size: 1rem;
+ font-size: $o-we-font-size;
}
.o_we_preview_area {
max-height: 400px;
@@ -539,32 +385,3 @@ img.o_we_selected_image {
img.o_we_custom_image.mx-auto {
display: block;
}
-
-// ENTER IN EDIT MODE
-
-.note-editor .css_editable_mode_display {
- border: 1px dashed rgba(153, 153, 153, 0.5);
- display: block !important;
-}
-
-.note-editable {
-
- li,
- p,
- h1,
- h2,
- h3,
- h4,
- h5,
- h6 {
- &:empty:after {
- content: "\00a0"
- }
- }
-}
-
-.wysiwyg_iframe {
- margin: 0;
- padding: 0;
- border: 0;
-}
diff --git a/addons/web_editor/static/src/scss/wysiwyg_iframe.scss b/addons/web_editor/static/src/scss/wysiwyg_iframe.scss
index e1af34e41fa..e7554317994 100644
--- a/addons/web_editor/static/src/scss/wysiwyg_iframe.scss
+++ b/addons/web_editor/static/src/scss/wysiwyg_iframe.scss
@@ -16,21 +16,8 @@ iframe.wysiwyg_iframe.o_fullscreen {
body.o_in_iframe {
background-color: $o-view-background-color;
- overflow: auto;
-
- .note-editable {
- height: calc(100vh - #{$o-wysiwyg-toolbar-height} - 2px);
- }
.note-statusbar {
display: none;
}
-
- #web_editor-toolbars .popover .btn {
- font-size: 1rem;
- }
-
- .o_mail_theme_selector .btn {
- font-size: 1rem;
- }
}
diff --git a/addons/web_editor/static/src/scss/wysiwyg_snippets.scss b/addons/web_editor/static/src/scss/wysiwyg_snippets.scss
index 6b576acecba..70665b4861f 100644
--- a/addons/web_editor/static/src/scss/wysiwyg_snippets.scss
+++ b/addons/web_editor/static/src/scss/wysiwyg_snippets.scss
@@ -2,86 +2,74 @@
/// This file contains all variables and mixins that are specific to the editor.
///
-$o-wysiwyg-handles-accent-color: #00e2ff !default;
-$o-wysiwyg-handle-edge-size: 1px !default;
-$o-wysiwyg-dropzone-size: 40px !default;
-$o-wysiwyg-sidebar-width: 210px !default;
-$o-wysiwyg-sidebar-height: 36px !default;
-$o-wysiwyg-overlay-option-size: 25px !default;
-$o-wysiwyg-handles-btn-size: 18px !default;
-$o-wysiwyg-handle-border-width: 1px !default;
-
-$o-wysiwyg-handles-offset-to-hide: 10000px !default;
-
// OVERRIDES FOR EDITOR WITH SNIPPETS
body.editor_enable.editor_has_snippets {
padding-left: $o-we-sidebar-width !important;
#web_editor-top-edit .note-popover .popover {
- margin: 0 0 0 $o-we-sidebar-width;
- }
-}
-
-// NOTE EDITOR
-.note-editor.o_snippets_loaded {
- transition: padding-left 400ms $o-wysiwyg-md-ease 0s;
- padding-left: 210px !important;
-}
-
-.note-editor.note-frame .note-editing-area .o_wrap_editable_snippets {
- overflow: auto;
-
- .note-editable {
- overflow: visible;
+ left: $o-we-sidebar-width !important;
}
}
-.o_in_iframe .note-editor.o_snippets_loaded .note-editable {
- padding-top: 30px;
-}
-
// SNIPPET PANEL
#oe_snippets {
@include o-w-preserve-btn;
+ @include o-position-absolute(0, auto, 0, -$o-we-sidebar-width);
+ position: fixed;
+ z-index: $o-we-zindex;
display: flex;
flex-flow: column nowrap;
- position: fixed;
- top: 0;
- width: $o-wysiwyg-sidebar-width;
- z-index: $o-wysiwyg-zindex - 1;
+ width: $o-we-sidebar-width;
- font-family: Roboto, $font-family-sans-serif;
- border-right: 1px solid #aaa;
- transition: left 400ms $o-wysiwyg-md-ease 0s;
- background-image: linear-gradient(45deg, $o-wysiwyg-bg-color, darken($o-wysiwyg-bg-color, 10%));
+ border-right: $o-we-border-width solid $o-we-border-color;
+ background-color: var(--o-we-snippets-bg-color);
+ color: var(--o-we-snippets-color);
box-shadow: 0px 10px 10px -10px black inset;
- border: 1px solid $o-wysiwyg-border-color;
+ font-family: Roboto, $font-family-sans-serif;
+
+ transition: left 400ms $o-we-md-ease 0s;
+
+ &.o_loaded {
+ left: 0 !important;
+ }
#snippets_menu {
flex: 0 0 auto;
- height: $o-wysiwyg-toolbar-height;
- line-height: $o-wysiwyg-sidebar-height;
- margin: 0;
- padding: 0;
- background: $o-wysiwyg-bg-color;
- text-align: center;
- font-weight: normal;
- font-size: 17px;
- color: $o-wysiwyg-color;
- font-family: $o-wysiwyg-font-family;
+ display: flex;
+ height: var(--o-we-toolbar-height);
+ background: var(--o-we-bg-color);
+ color: var(--o-we-color);
+ font-family: $o-we-font-family;
+
+ > button {
+ flex: 1 1 auto;
+ border: none;
+ background: transparent;
+ color: inherit;
+ @include o-text-overflow();
+
+ &.active {
+ background: var(--o-we-snippets-bg-color);
+ color: var(--o-we-snippets-color);
+ }
+ }
}
- #o_scroll {
+ > #o_scroll, > .o_we_customize_panel {
+ flex: 1 1 auto;
height: 100%;
overflow: auto;
+ }
+
+ > #o_scroll {
.o_panel_header {
display: flex;
align-items: center;
justify-content: center;
padding: 3%;
- color: $o-wysiwyg-color;
+ color: inherit;
margin-bottom: 3%;
i {
@@ -149,24 +137,156 @@ body.editor_enable.editor_has_snippets {
}
}
- &:nth-child(2n+1) {
+ &:nth-child(2n + 1) {
clear: left;
}
}
}
}
- &.o_loaded {
- left: 0 !important;
+ > .o_we_customize_panel {
+
+ we-button, we-toggler {
+ cursor: pointer;
+ @include o-text-overflow(inline-block);
+ padding: 0.25rem 0.5rem;
+ margin: 0;
+ background-color: var(--o-we-bg-color-dark);
+ color: var(--o-we-color);
+ line-height: 1.5;
+ font-weight: 500;
+ white-space: nowrap;
+ }
+
+ %we-icon-button {
+ position: relative;
+
+ &::after {
+ position: absolute;
+ width: 1em;
+ right: 0.5em;
+ text-align: center;
+ font-family: FontAwesome;
+ }
+ }
+
+ @mixin we-icon-button($icon, $color: null) {
+ @extend %we-icon-button;
+ padding-right: 0.5em + 1em + 0.5em;
+
+ &::after {
+ content: $icon;
+ color: $color;
+ }
+ }
+
+ we-customizeblock-options {
+ display: block;
+ border: $o-we-border-width solid var(--o-we-snippets-color);
+ color: var(--o-we-snippets-color);
+ margin-top: 0.25rem;
+
+ > we-title {
+ display: flex;
+ align-items: center;
+ margin: 0.25rem 0;
+ padding: 0 0.5rem;
+ font-weight: bold;
+ color: inherit !important;
+
+ @include we-icon-button('\f107');
+
+ > we-button-group {
+ flex: 0 0 auto;
+ display: block;
+ margin-left: auto;
+ text-align: center;
+
+ > we-button {
+ margin-left: 0.25rem;
+ width: 1.5rem;
+ padding: 0.125rem;
+ }
+ }
+ }
+ }
+
+ we-customizeblock-option {
+ position: relative;
+ display: block;
+ overflow: hidden;
+ max-height: 500px;
+ transition: max-height 200ms ease 0s;
+
+ > * {
+ display: block;
+ margin-top: 0.25rem;
+ }
+
+ we-button, we-toggler {
+ display: block;
+ text-align: left;
+ border-radius: 0;
+ }
+ we-button {
+ &.we-button-hover-icon:hover {
+ @include we-icon-button('\f040');
+ }
+
+ &.active {
+ @include we-icon-button('\f00c', $o-we-color-success);
+ }
+ }
+ we-collapse {
+ position: relative;
+ display: block;
+ max-height: 0;
+ overflow: hidden;
+ transition: max-height 200ms ease 0s;
+ }
+ we-toggler {
+ @include we-icon-button('\f104');
+
+ &.active {
+ @include we-icon-button('\f107');
+
+ + we-collapse {
+ max-height: 500px;
+ }
+ }
+ }
+
+ .dropdown-menu {
+ // FIXME temporary fix for m2o option for example
+ position: static !important;
+ }
+ }
+
+ we-customizeblock-options.o_we_closed {
+ cursor: pointer;
+
+ > we-title {
+ @include we-icon-button('\f104');
+ }
+ > we-customizeblock-option {
+ max-height: 0;
+ transition-duration: 25ms;
+
+ + we-customizeblock-option {
+ margin-top: 0;
+ }
+ }
+ }
}
}
.oe_snippet {
// No root because can be drag and drop (and the helper is in the body)
position: relative;
+ z-index: $o-we-zindex;
width: 100px;
- background-color: $o-wysiwyg-bg-color;
- z-index: $o-wysiwyg-zindex;
+ background-color: var(--o-we-snippets-bg-color);
+ color: var(--o-we-snippets-color);
> :not(.oe_snippet_thumbnail) {
display: none !important;
@@ -178,7 +298,7 @@ body.editor_enable.editor_has_snippets {
.oe_snippet_thumbnail_img {
width: 100%;
height: 0;
- border: 1px solid $o-wysiwyg-border-color;
+ border: $o-we-border-width solid $o-we-border-color;
padding-bottom: 75%;
background-size: cover;
background-position: center center;
@@ -193,16 +313,14 @@ body.editor_enable.editor_has_snippets {
.oe_snippet_thumbnail_title {
display: block;
- border: 1px solid $o-wysiwyg-bg-color;
padding: 5px;
font-size: 12px;
font-weight: 300;
text-shadow: none;
- color: $o-wysiwyg-color;
}
&:hover .oe_snippet_thumbnail_title {
- color: $o-wysiwyg-color-light;
+ color: var(--o-we-color-accent);
}
}
}
@@ -212,66 +330,59 @@ body.editor_enable.editor_has_snippets {
.o_colorpicker_sections {
font-size: 14px;
- .o_colorpicker_section_tabs {
- width: 225px;
- height: 100%;
- }
-
button {
float: left;
- height: 25px;
- width: 25px;
- margin: 1px 1px 0 2px;
- border: 1px solid black;
+ width: percentage(1 / 8);
+ padding-top: percentage(1 / 8);
+ margin: 0;
+ border: none;
+ box-shadow: inset 0 0 0 1px var(--o-we-snippets-bg-color);
}
- div[data-group="transparent_grayscale"] button {
- @include o-alpha-button-preview;
-
- &.o_small {
- width: 23px;
- height: 23px;
- margin: 2px;
- border-radius: 50%;
- }
+ .o_colorpicker_section {
- &:hover,
- &.selected {
- box-shadow: 0px 0px 2px 2px $o-wysiwyg-color;
+ > :first-child {
+ margin: 8px 0 4px;
}
+ button {
+ position: relative;
- &.selected:before {
- content: "\f00c";
- font-family: "FontAwesome";
- padding-top: 1px;
- color: theme-color('success');
- }
+ &.o_small {
+ border-radius: 50%;
+ }
- &[data-event="foreColor"] {
- background-color: $o-wysiwyg-bg-color;
+ &:hover,
+ &.selected {
+ box-shadow: inset 0 0 1px 1px var(--o-we-snippets-bg-color);
+ }
- &:before {
- background-color: rgba(white, 0.3);
+ &.selected::before {
+ @include o-position-absolute(0, 0, 0, 0);
+ content: "\f00c" !important;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-family: FontAwesome !important;
+ color: $o-we-color-success;
}
- }
- &.o_btn_transparent::before {
- background-color: transparent;
+ &.o_btn_transparent::before {
+ background-color: transparent;
+ }
}
- }
- .note-color-palette>div {
- clear: both;
- }
+ &[data-name="transparent_grayscale"] button {
+ @include o-alpha-button-preview;
- .note-color-row {
- height: 28px;
+ &::before, &::after {
+ box-shadow: inherit;
+ }
+ }
}
}
.note-palette-title {
- padding: 10px 0px 10px 10px;
- color: $o-wysiwyg-color-light;
+ padding: 10px 0 10px 10px;
font-weight: bold;
}
@@ -282,14 +393,14 @@ body.editor_enable.editor_has_snippets {
.note-color-reset {
font-size: 20px !important;
- color: desaturate(rgba($o-wysiwyg-color-danger, 0.6), 40%);
+ color: desaturate(rgba($o-we-color-danger, 0.6), 40%);
margin: 1px 0 0;
padding: 0;
cursor: pointer;
&:hover {
background: transparent !important;
- color: $o-wysiwyg-color-danger;
+ color: $o-we-color-danger;
}
}
}
@@ -298,50 +409,26 @@ body.editor_enable.editor_has_snippets {
// DROPZONES
@keyframes dropZoneInsert {
to {
- background-color: rgba($o-brand-odoo, 0.2);
+ background-color: rgba($o-brand-odoo, 0.3);
}
}
-.note-editable .oe_drop_zone {
- background-color: rgba($o-brand-odoo, 0.05);
+.oe_drop_zone {
+ background-color: rgba($o-brand-odoo, 0.15);
animation: dropZoneInsert 1s linear 0s infinite alternate;
&.oe_insert {
- z-index: $o-wysiwyg-zindex - 1;
-
- border: 2px dashed $o-wysiwyg-border-color;
- border-top: none;
- border-bottom: none;
-
position: relative;
+ z-index: $o-we-overlay-zindex;
width: 100%;
- height: $o-wysiwyg-dropzone-size;
- margin: (-$o-wysiwyg-dropzone-size/2) 0;
-
- &:after {
- content: "";
- display: block;
- width: 100%;
- height: 50%;
- border-bottom: 2px dashed $o-wysiwyg-border-color;
- box-sizing: content-box;
- }
+ height: $o-we-dropzone-size;
+ margin: (-$o-we-dropzone-size/2) 0;
+ border: 2px dashed $o-we-border-color;
&.oe_vertical {
- border: 2px dashed $o-brand-odoo;
- border-left: none;
- border-right: none;
-
- width: $o-wysiwyg-dropzone-size;
+ width: $o-we-dropzone-size;
float: left;
- margin: 0 (-$o-wysiwyg-dropzone-size/2);
-
- &:after {
- width: 50%;
- height: 100%;
- border-bottom: none;
- border-right: 2px dashed $o-wysiwyg-border-color;
- }
+ margin: 0 (-$o-we-dropzone-size/2);
}
}
}
@@ -349,13 +436,14 @@ body.editor_enable.editor_has_snippets {
// MANIPULATORS
#oe_manipulators {
position: relative;
- z-index: 1;
+ z-index: $o-we-overlay-zindex;
// SNIPPET MANIPULATORS
.oe_overlay {
@include o-position-absolute;
display: none;
height: 0;
+ border-color: $o-we-handles-accent-color-preview;
background: transparent;
text-align: center;
transition: opacity 400ms linear 0s;
@@ -363,381 +451,82 @@ body.editor_enable.editor_has_snippets {
&.o_keypress {
opacity: 0;
}
-
&.oe_active {
display: block;
}
-
- // OVERLAY OPTIONS
- >.oe_overlay_options {
- font-family: $o-wysiwyg-font-family;
- @include o-position-absolute($bottom: 0, $left: 0);
- width: 250px; // the parent oe_overlay has a width equal to the snippet width, the 250px is there to force the options to stay on one line without overriding bootstrap .btn-group
- text-align: left;
- z-index: $o-wysiwyg-zindex + 1;
-
- >.btn-group {
- white-space: nowrap;
- border: 0;
-
- .btn {
- display: inline-block;
- width: $o-wysiwyg-overlay-option-size;
- height: $o-wysiwyg-overlay-option-size;
- padding: 0;
- border: 1px solid $o-wysiwyg-bg-color;
- line-height: $o-wysiwyg-overlay-option-size;
- font-size: 11px;
- border-radius: 0;
- font-weight: normal;
-
- transition: all 400ms ease 0s;
- color: $o-wysiwyg-color;
- background-color: $o-wysiwyg-bg-color;
-
- &:hover {
- color: $o-wysiwyg-color-light;
- background-color: lighten($o-wysiwyg-bg-color, 10%);
- }
-
- &.oe_snippet_remove {
- color: $o-wysiwyg-color;
- background-color: $o-wysiwyg-color-danger;
- border-color: darken($o-wysiwyg-color-danger, 20%);
-
- >.fa {
- color: $o-wysiwyg-color;
- }
-
- &:hover {
- background-color: darken($o-wysiwyg-color-danger, 20%);
- }
- }
-
- &.oe_snippet_parent>i {
- transform: scaleX(-1);
- font-size: 12px;
- }
-
- >.fa {
- color: $o-wysiwyg-color;
- line-height: inherit;
- vertical-align: top;
- }
- }
-
- // CUSTOMIZE MENU BUTTON
- >.oe_options {
- .btn {
- width: auto;
- padding: 0 25px 0 5px;
- background-color: $o-wysiwyg-bg-color;
- text-transform: uppercase;
-
- &:hover,
- &:active,
- &:focus {
- background-color: lighten($o-wysiwyg-bg-color, 5%);
- border-color: lighten($o-wysiwyg-bg-color, 10%);
- }
-
- &:before,
- &:after {
- content: "";
- width: 7px;
- height: 2px;
- background-color: $o-wysiwyg-color-light;
- @include o-position-absolute(46%);
- transition: all 0.3s ease 0s;
- }
-
- &:before {
- right: 9px;
- transform: rotate(45deg);
- }
-
- &:after {
- right: 5px;
- transform: rotate(-45deg);
- }
- }
-
- // Open menu
- &.show .btn {
-
- &:active,
- &:focus,
- &:active:focus {
- box-shadow: none;
- }
-
- &:before,
- &:after {
- width: 9px;
- }
-
- &:before {
- right: 10px;
- transform: translateX(5px) rotate(-45deg);
- }
-
- &:after {
- transform: rotate(45deg);
- }
- }
-
- // CUSTOMIZE MENU
- .dropdown-menu {
- margin: -1px 0 0 0;
- padding: 0;
- border: 1px solid $o-wysiwyg-bg-color;
- border-radius: 0;
- background-color: $o-wysiwyg-bg-color;
-
- .dropdown-item {
- position: relative;
- color: $o-wysiwyg-color-light;
- font-weight: normal;
- font-size: 12px;
- padding: 5px 40px 5px 10px;
-
- &:hover {
- background: transparent;
- cursor: pointer;
- }
-
- &.active {
- &:before {
- @include o-position-absolute($top: 5px, $right: 5px);
- content: "\f00c";
- font-family: "FontAwesome";
- color: $o-brand-primary;
- }
- }
-
- >i {
- width: 15px;
- margin-right: 10px;
- text-align: center;
- }
- }
-
- .dropdown-submenu {
- position: relative;
-
- &::before {
- @include o-position-absolute($top: 12px, $right: 10px);
- @include o-caret-right(4px);
- border-left-color: $o-wysiwyg-color-light;
- }
-
- &:hover>.dropdown-menu {
- display: block;
- left: 100%;
- top: 0;
-
- &.o_open_to_left {
- left: auto;
- right: 100%;
- }
- }
- }
-
- .dropdown-divider {
- display: block;
- height: 1px;
- border-top: 1px solid #666;
- margin: 0;
- }
-
- .dropdown-header {
- color: $o-wysiwyg-color-light;
- font-size: 11px;
- margin-top: 2px;
- text-transform: uppercase;
-
- &:hover {
- background-color: initial;
- }
-
- &.o_main_header {
- padding-left: 10px;
- }
-
- &.o_parent_editor_header {
- position: relative;
- color: $o-wysiwyg-color-light;
- font-weight: 400;
- font-size: 10px;
- margin: 10px 0 0 10px;
- text-transform: uppercase;
- padding-bottom: .25em;
-
- &::before {
- content: "\f148";
- @include o-position-absolute($top: 5px, $left: 4px);
- font-family: FontAwesome;
- transform: scaleX(-1);
- }
-
- ~.dropdown-submenu .dropdown-item,
- ~.dropdown-item {
- font-size: 11px;
- opacity: 0.7;
-
- &:hover {
- opacity: 1;
- }
- }
-
- ~.dropdown-submenu::before {
- @include o-position-absolute($top: 10px, $right: 10px);
- }
- }
- }
- }
- }
- }
- }
-
- &.o_top_cover>.oe_overlay_options {
- bottom: auto;
- top: 1px;
- right: 1px;
+ &.o_we_options_opened {
+ z-index: 1;
}
// HANDLES
- >.o_handles {
- @include o-position-absolute(-$o-wysiwyg-handles-offset-to-hide, 0, auto, 0);
- z-index: $o-wysiwyg-zindex;
-
- &:hover>.o_handle {
- background-color: rgba($o-wysiwyg-handles-accent-color, 0.05);
- }
-
- >.o_handle {
+ > .o_handles {
+ @include o-position-absolute(-$o-we-handles-offset-to-hide, 0, auto, 0);
+ border-color: inherit;
+ > .o_handle, > .o_move_handle {
position: relative;
- border: 0 solid $o-wysiwyg-handles-accent-color;
- transition: background 300ms ease 0s;
-
- &:hover,
- &.o_active {
- background-color: rgba($o-wysiwyg-handles-accent-color, 0.2);
-
- &:before {
- content: '';
- @include o-position-absolute(0, $left: 50%);
- width: 1px;
- height: 100%;
- margin-left: -1px;
- background-color: rgba($o-wysiwyg-handles-accent-color, 0.5);
- }
-
- &.w:before {
- @include o-position-absolute(50%, $left: 0);
- width: 100%;
- height: 1px;
- }
-
- &:after {
- border-color: darken($o-wysiwyg-handles-accent-color, 10%);
- background-color: darken($o-wysiwyg-handles-accent-color, 20%);
- }
- }
- &:after {
- display: block;
- width: $o-wysiwyg-handles-btn-size;
- height: $o-wysiwyg-handles-btn-size;
- border: solid 1px darken($o-wysiwyg-handles-accent-color, 10%);
- line-height: $o-wysiwyg-handles-btn-size - 2;
- font-size: 14px;
- font-family: FontAwesome;
- background-color: darken($o-wysiwyg-handles-accent-color, 20%);
- color: white;
+ &.w {
+ @include o-position-absolute($o-we-handles-offset-to-hide, auto, -$o-we-handles-offset-to-hide, 0);
+ width: $o-we-handle-edge-size;
}
- &.w:after,
- &.e:after {
- content: "\f07e";
+ &.e {
+ @include o-position-absolute($o-we-handles-offset-to-hide, 0, -$o-we-handles-offset-to-hide, auto);
+ width: $o-we-handle-edge-size;
}
- &.s:after,
- &.n:after {
- content: "\f07d";
+ &.n {
+ @include o-position-absolute($o-we-handles-offset-to-hide, 0, auto, 0);
+ height: $o-we-handle-edge-size;
}
- &.o_handle_start {
-
- &.w:after,
- &.e:after {
- content: '\f061';
- }
-
- &.n:after,
- &.s:after {
- content: '\f063';
- }
+ &.s {
+ @include o-position-absolute(auto, 0, -$o-we-handles-offset-to-hide, 0);
+ height: $o-we-handle-edge-size;
}
+ }
- &.o_handle_end {
-
- &.w:after,
- &.e:after {
- content: '\f060';
- }
-
- &.n:after,
- &.s:after {
- content: '\f062';
- }
- }
+ > .o_handle {
+ border: 0 dashed transparent;
+ border-color: inherit;
+ transition: background 300ms ease 0s;
&.w {
- @include o-position-absolute($o-wysiwyg-handles-offset-to-hide, auto, -$o-wysiwyg-handles-offset-to-hide, 0);
- width: $o-wysiwyg-handle-edge-size;
- border-width: $o-wysiwyg-handle-border-width;
+ border-width: $o-we-handle-border-width-preview;
border-right-width: 0;
cursor: e-resize;
&:after {
@include o-position-absolute($top: 50%, $left: 40%);
- margin-top: -$o-wysiwyg-handles-btn-size/2;
+ margin-top: -$o-we-handles-btn-size/2;
}
}
-
&.e {
- @include o-position-absolute($o-wysiwyg-handles-offset-to-hide, 0, -$o-wysiwyg-handles-offset-to-hide, auto);
- width: $o-wysiwyg-handle-edge-size;
- border-right-width: $o-wysiwyg-handle-border-width;
+ border-right-width: $o-we-handle-border-width-preview;
cursor: w-resize;
&:after {
@include o-position-absolute($top: 50%, $right: 40%);
- margin-top: -$o-wysiwyg-handles-btn-size/2;
+ margin-top: -$o-we-handles-btn-size/2;
}
}
-
&.n {
- @include o-position-absolute($o-wysiwyg-handles-offset-to-hide, 0, auto, 0);
- border-top-width: $o-wysiwyg-handle-border-width;
+ border-top-width: $o-we-handle-border-width-preview;
cursor: ns-resize;
&:after {
@include o-position-absolute($left: 50%, $top: 40%);
- margin-left: -$o-wysiwyg-handles-btn-size/2;
+ margin-left: -$o-we-handles-btn-size/2;
}
}
-
&.s {
- @include o-position-absolute(auto, 0, -$o-wysiwyg-handles-offset-to-hide, 0);
- border-bottom-width: $o-wysiwyg-handle-border-width;
+ border-bottom-width: $o-we-handle-border-width-preview;
cursor: ns-resize;
&:after {
@include o-position-absolute($left: 50%, $bottom: 40%);
- margin-left: -$o-wysiwyg-handles-btn-size/2;
+ margin-left: -$o-we-handles-btn-size/2;
}
}
@@ -753,6 +542,113 @@ body.editor_enable.editor_has_snippets {
}
}
}
+
+ > .o_move_handle {
+ cursor: pointer;
+ cursor: move;
+ }
+ }
+
+ &.o_we_sticky {
+ border-color: $o-we-handles-accent-color;
+
+ > .o_handles {
+ &:hover > .o_handle {
+ background-color: rgba($o-we-handles-accent-color, 0.05);
+ }
+ > .o_handle {
+ &:hover,
+ &.o_active {
+ background-color: rgba($o-we-handles-accent-color, 0.2);
+
+ &:before {
+ content: '';
+ @include o-position-absolute(0, $left: 50%);
+ width: 1px;
+ height: 100%;
+ margin-left: -1px;
+ background-color: rgba($o-we-handles-accent-color, 0.5);
+ }
+
+ &.w:before {
+ @include o-position-absolute(50%, $left: 0);
+ width: 100%;
+ height: 1px;
+ }
+
+ &:after {
+ border-color: darken($o-we-handles-accent-color, 10%);
+ background-color: darken($o-we-handles-accent-color, 20%);
+ }
+ }
+
+ &:after {
+ z-index: 1;
+ display: block;
+ width: $o-we-handles-btn-size;
+ height: $o-we-handles-btn-size;
+ border: solid 1px darken($o-we-handles-accent-color, 10%);
+ line-height: $o-we-handles-btn-size - 2;
+ font-size: 14px;
+ font-family: FontAwesome;
+ background-color: darken($o-we-handles-accent-color, 20%);
+ color: white;
+ }
+
+ &.w:after,
+ &.e:after {
+ content: "\f07e";
+ }
+
+ &.s:after,
+ &.n:after {
+ content: "\f07d";
+ }
+
+ &.o_handle_start {
+
+ &.w:after,
+ &.e:after {
+ content: '\f061';
+ }
+
+ &.n:after,
+ &.s:after {
+ content: '\f063';
+ }
+ }
+
+ &.o_handle_end {
+
+ &.w:after,
+ &.e:after {
+ content: '\f060';
+ }
+
+ &.n:after,
+ &.s:after {
+ content: '\f062';
+ }
+ }
+
+ &.w {
+ border-width: $o-we-handle-border-width;
+ border-right-width: 0;
+ }
+ &.e {
+ border-right-width: $o-we-handle-border-width;
+ }
+ &.n {
+ border-top-width: $o-we-handle-border-width;
+ }
+ &.s {
+ border-bottom-width: $o-we-handle-border-width;
+ }
+ }
+ }
+ }
+ &.o_we_options_opened > .o_handles > .o_handle {
+ border-style: solid;
}
}
diff --git a/addons/web_editor/static/src/xml/snippets.xml b/addons/web_editor/static/src/xml/snippets.xml
index 6e2ae656f2d..89819b44396 100644
--- a/addons/web_editor/static/src/xml/snippets.xml
+++ b/addons/web_editor/static/src/xml/snippets.xml
@@ -3,29 +3,41 @@
<t t-name="web_editor.snippet_overlay">
<div class="oe_overlay">
<div class="o_handles">
+ <!-- Visible overlay borders + allow to resize when not readonly -->
<div class="o_handle n readonly"/>
<div class="o_handle e readonly"/>
<div class="o_handle w readonly"/>
<div class="o_handle s readonly"/>
- </div>
- <div class="oe_overlay_options" contentEditable="false">
- <div class="btn-group">
- <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-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>
+
+ <!-- Invisible overlay borders which allow to drag and drop -->
+ <div class="o_move_handle n"/>
+ <div class="o_move_handle e"/>
+ <div class="o_move_handle w"/>
+ <div class="o_move_handle s"/>
</div>
</div>
</t>
+ <t t-name="web_editor.customize_block_options_section">
+ <we-customizeblock-options>
+ <we-title>
+ <span t-esc="name"/>
+ <we-button-group>
+ <we-button class="fa fa-files-o oe_snippet_clone"
+ title="Duplicate Container"
+ aria-label="Duplicate Container"/>
+ <we-button class="fa fa-trash-o oe_snippet_remove"
+ title="Remove Block"
+ aria-label="Remove Block"/>
+ </we-button-group>
+ </we-title>
+ </we-customizeblock-options>
+ </t>
+ <t t-name="web_editor.customize_block_option">
+ <we-customizeblock-option/>
+ </t>
<!-- options -->
<div t-name="web_editor.snippet.option.colorpicker" class="colorpicker">
- <div class="note-palette-title">Background Color</div>
<div class="btn-group palette-reset">
<div class="note-color-reset" data-event="foreColor" data-value="inherit" title="None" role="img" aria-label="No color">
<i class="fa fa-ban"/>
diff --git a/addons/web_editor/static/tests/test_utils.js b/addons/web_editor/static/tests/test_utils.js
index 3b1563d3182..7898ed63f95 100644
--- a/addons/web_editor/static/tests/test_utils.js
+++ b/addons/web_editor/static/tests/test_utils.js
@@ -79,25 +79,24 @@ MockServer.include({
'data-drop-in=".note-editable" data-drop-near="p, h1, h2, h3, blockquote, .s_hr"></div>' +
' <div data-js="sizing_y" data-selector=".s_hr, .test_option_all"></div>' +
' <div data-js="colorpicker" data-selector=".test_option_all">' +
- ' <div class="dropdown-submenu">' +
- ' <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-eyedropper"/>Background Color</a>' +
- ' <div class="dropdown-menu" role="menu"/>' +
- ' </div>' +
+ ' <we-collapse-area>' +
+ ' <we-toggler><i class="fa fa-eyedropper"/> Background Color</we-toggler>' +
+ ' <we-collapse/>' +
+ ' </we-collapse-area>' +
' </div>' +
' <div data-js="background" data-selector=".test_option_all">' +
- ' <a tabindex="-1" href="#" class="dropdown-item" data-choose-image="true" data-no-preview="true"><i class="fa fa-picture-o"/>Background Image</a>' +
+ ' <we-button data-choose-image="true" data-no-preview="true"><i class="fa fa-picture-o"/> Background Image</we-button>' +
' </div>' +
' <div data-js="option_test" data-selector=".s_hr">' +
- ' <div class="dropdown-submenu">' +
- ' <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-arrows-v"/>Alignment</a>' +
- ' <div class="dropdown-menu" role="menu">' +
- ' <a href="#" class="dropdown-item" data-select-class="align-items-start">Top</a>' +
- ' <a href="#" class="dropdown-item" data-select-class="align-items-center">Middle</a>' +
- ' <a href="#" class="dropdown-item" data-select-class="align-items-end">Bottom</a>' +
- ' <div class="dropdown-divider"/>' +
- ' <a href="#" class="dropdown-item" data-select-class="align-items-stretch">Equal height</a>' +
- ' </div>' +
- ' </div>' +
+ ' <we-collapse-area>' +
+ ' <we-toggler><i class="fa fa-arrows-v"/> Alignment</we-toggler>' +
+ ' <we-collapse>' +
+ ' <we-button data-select-class="align-items-start">Top</we-button>' +
+ ' <we-button data-select-class="align-items-center">Middle</we-button>' +
+ ' <we-button data-select-class="align-items-end">Bottom</we-button>' +
+ ' <we-button data-select-class="align-items-stretch">Equal height</we-button>' +
+ ' </we-collapse>' +
+ ' </we-collapse-area>' +
' </div>' +
'</div>';
return Promise.resolve(template);
@@ -255,25 +254,24 @@ function wysiwygData(data) {
'data-drop-in=".note-editable" data-drop-near="p, h1, h2, h3, blockquote, .s_hr"></div>' +
' <div data-js="sizing_y" data-selector=".s_hr, .test_option_all"></div>' +
' <div data-js="colorpicker" data-selector=".test_option_all">' +
- ' <div class="dropdown-submenu">' +
- ' <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-eyedropper"/>Background Color</a>' +
- ' <div class="dropdown-menu" role="menu"/>' +
- ' </div>' +
+ ' <we-collapse-area>' +
+ ' <we-toggler><i class="fa fa-eyedropper"/>Background Color</we-toggler>' +
+ ' <we-collapse/>' +
+ ' </we-collapse-area>' +
' </div>' +
' <div data-js="background" data-selector=".test_option_all">' +
- ' <a tabindex="-1" href="#" class="dropdown-item" data-choose-image="true" data-no-preview="true"><i class="fa fa-picture-o"/>Background Image</a>' +
+ ' <we-button data-choose-image="true" data-no-preview="true"><i class="fa fa-picture-o"/> Background Image</we-button>' +
' </div>' +
' <div data-js="option_test" data-selector=".s_hr">' +
- ' <div class="dropdown-submenu">' +
- ' <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-arrows-v"/>Alignment</a>' +
- ' <div class="dropdown-menu" role="menu">' +
- ' <a href="#" class="dropdown-item" data-select-class="align-items-start">Top</a>' +
- ' <a href="#" class="dropdown-item" data-select-class="align-items-center">Middle</a>' +
- ' <a href="#" class="dropdown-item" data-select-class="align-items-end">Bottom</a>' +
- ' <div class="dropdown-divider"/>' +
- ' <a href="#" class="dropdown-item" data-select-class="align-items-stretch">Equal height</a>' +
- ' </div>' +
- ' </div>' +
+ ' <we-collapse-area>' +
+ ' <we-toggler><i class="fa fa-arrows-v"/> Alignment</we-toggler>' +
+ ' <we-collapse>' +
+ ' <we-button data-select-class="align-items-start">Top</we-button>' +
+ ' <we-button data-select-class="align-items-center">Middle</we-button>' +
+ ' <we-button data-select-class="align-items-end">Bottom</we-button>' +
+ ' <we-button data-select-class="align-items-stretch">Equal height</we-button>' +
+ ' </we-collapse>' +
+ ' </we-collapse-area>' +
' </div>' +
'</div>';
}
diff --git a/addons/web_editor/views/editor.xml b/addons/web_editor/views/editor.xml
index c16aca1485a..484ca4994c4 100644
--- a/addons/web_editor/views/editor.xml
+++ b/addons/web_editor/views/editor.xml
@@ -19,6 +19,7 @@
<link rel="stylesheet" type="text/css" href="/web_editor/static/lib/cropper/css/cropper.css"/>
<script type="text/javascript" src="/web_editor/static/lib/cropper/js/cropper.js"/>
<script type="text/javascript" src="/web_editor/static/lib/jQuery.transfo.js"/>
+ <script type="text/javascript" src="/web_editor/static/lib/nearest/jquery.nearest.js"/>
<!-- odoo utils -->
@@ -30,11 +31,9 @@
<link rel="stylesheet" type="text/scss" href="/web_editor/static/src/scss/wysiwyg.scss"/>
<link rel="stylesheet" type="text/scss" href="/web_editor/static/src/scss/wysiwyg_iframe.scss"/>
-
<link rel="stylesheet" type="text/scss" href="/web_editor/static/src/scss/wysiwyg_snippets.scss"/>
<script type="text/javascript" src="/web_editor/static/src/js/wysiwyg/fonts.js"/>
- <script type="text/javascript" src="/web_editor/static/lib/nearest/jquery.nearest.js"/>
<script type="text/javascript" src="/web_editor/static/src/js/base.js"/>
<script type="text/javascript" src="/web_editor/static/src/js/editor/editor.js"/>
<script type="text/javascript" src="/web_editor/static/src/js/editor/rte.js"/>
diff --git a/addons/web_editor/views/snippets.xml b/addons/web_editor/views/snippets.xml
index 3a1c6614609..6bd1a5f1597 100644
--- a/addons/web_editor/views/snippets.xml
+++ b/addons/web_editor/views/snippets.xml
@@ -1,7 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="snippets">
- <h2 id="snippets_menu">Add blocks</h2>
+ <div id="snippets_menu">
+ <button type="button" class="o_we_add_snippet_btn active">
+ <i class="fa fa-plus"/> Add
+ </button>
+ <t t-set="customize_title">Select an element to customize it</t>
+ <button type="button" class="o_we_customize_snippet_btn"
+ t-att-data-title="customize_title"
+ disabled="disabled">
+ <i class="fa fa-cog"/> Customize
+ </button>
+ </div>
<div id="o_scroll">
<div id="snippet_structure" class="o_panel">
@@ -26,11 +36,8 @@
data-selector="[data-oe-many2one-model]:not([data-oe-readonly])"
data-no-check="true"/>
- <div data-js="content"
- data-selector=".s_hr"
- data-drop-near="p, h1, h2, h3, blockquote, .s_hr">
- </div>
-
+ <div data-selector=".s_hr"
+ data-drop-near="p, h1, h2, h3, blockquote, .s_hr"/>
</template>
<!-- default block -->
diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js
index d659677c478..d3f2e7e9730 100644
--- a/addons/website/static/src/js/editor/snippets.options.js
+++ b/addons/website/static/src/js/editor/snippets.options.js
@@ -1410,7 +1410,7 @@ options.registry.topMenuTransparency = options.Class.extend({
enabled = value;
},
});
- this.$el.find('[data-transparent]').addBack('[data-transparent]').toggleClass('active', !!enabled);
+ this.$el.find('[data-transparent]').toggleClass('active', !!enabled);
},
});
@@ -1465,7 +1465,6 @@ options.registry.topMenuColor = options.registry.colorpicker.extend({
*/
options.registry.anchorName = options.Class.extend({
xmlDependencies: ['/website/static/src/xml/website.editor.xml'],
- preventChildPropagation: true,
//--------------------------------------------------------------------------
// Public
diff --git a/addons/website/static/src/js/tours/banner.js b/addons/website/static/src/js/tours/banner.js
index 5febdf1c749..f4ddc040c69 100644
--- a/addons/website/static/src/js/tours/banner.js
+++ b/addons/website/static/src/js/tours/banner.js
@@ -24,10 +24,14 @@ tour.register("banner", {
position: "bottom",
run: "text",
}, {
- trigger: ".oe_overlay_options .oe_options",
+ trigger: ".o_we_customize_panel",
extra_trigger: "#wrapwrap .s_cover h1:not(:containsExact(\"Catchy Headline\"))",
content: _t("Customize any block through this menu. Try to change the background color of this block."),
- position: "top",
+ position: "right",
+}, {
+ trigger: '.o_we_add_snippet_btn',
+ content: _t("Go back to the blocks menu."),
+ position: 'bottom',
}, {
trigger: "#snippet_structure .oe_snippet:eq(3) .oe_snippet_thumbnail",
content: _t("Drag another block in your page, below the cover."),
@@ -35,7 +39,6 @@ tour.register("banner", {
run: "drag_and_drop #wrap",
}, {
trigger: "button[data-action=save]",
- extra_trigger: ".oe_overlay_options .oe_options",
content: _t("Click the <b>Save</b> button."),
position: "bottom",
}, {
@@ -69,7 +72,6 @@ tour.register("banner", {
run: "drag_and_drop #wrap",
}, {
trigger: "button[data-action=save]",
- extra_trigger: ".oe_overlay_options .oe_options",
content: _t("Click the <b>Save</b> button."),
position: "bottom",
}, {
diff --git a/addons/website/static/src/scss/website.editor.ui.scss b/addons/website/static/src/scss/website.editor.ui.scss
index 403b7929a92..bb51136ffac 100644
--- a/addons/website/static/src/scss/website.editor.ui.scss
+++ b/addons/website/static/src/scss/website.editor.ui.scss
@@ -8,7 +8,7 @@
>input {
display: none;
- +span {
+ + span {
background-color: $o-we-switch-inactive-color;
box-shadow: inset 0 0 0px 1px darken($o-we-switch-inactive-color, 10%);
border-radius: 100rem;
@@ -20,7 +20,7 @@
&:after {
content: "";
- background: $o-we-color-paper;
+ background: $o-we-bg-color;
display: block;
width: $o-we-switch-size - 0.2;
height: $o-we-switch-size - 0.2;
diff --git a/addons/website/static/src/scss/website.wysiwyg.scss b/addons/website/static/src/scss/website.wysiwyg.scss
index 1f5151f5da8..3206e4b027a 100644
--- a/addons/website/static/src/scss/website.wysiwyg.scss
+++ b/addons/website/static/src/scss/website.wysiwyg.scss
@@ -1,48 +1,27 @@
-//------------------------------------------------------------------------------
-// Modifications applied on normal website DOM while being in the editor.
-//------------------------------------------------------------------------------
-
-//------------------------------------------------------------------------------
-// Editor components style.
-//------------------------------------------------------------------------------
-
-body.editor_enable {
- padding-top: $o-navbar-height !important;
+// Override css variables to influence the default style of the editor without
+// duplicating the css.
+:root {
+ --o-we-toolbar-height: #{$o-navbar-height};
+ --o-we-bg-color: #{$o-we-color-dark};
+ --o-we-bg-color-dark: #{$o-we-color-darker};
+ --o-we-color: #{$o-we-color-text-normal};
+ --o-we-color-accent: #{$o-we-color-text-light};
+
+ --o-we-dropdown-bg-color: #{$o-we-color-darker};
+ --o-we-dropdown-color: #{$o-we-color-text-normal};
+
+ --o-we-snippets-bg-color: #{$o-we-color-normal};
+ --o-we-snippets-color: #{$o-we-color-text-light};
}
-#wrapwrap {
- height: calc(100vh - #{$o-navbar-height});
-}
-
-// TOP BAR (EDIT)
+// EDITOR TOP BAR AND POPOVER
#web_editor-top-edit {
- height: $o-navbar-height;
- background-color: $o-we-color-dark;
- border: 0;
- z-index: $zindex-modal - 9;
-
- .note-popover .popover {
- width: 100%;
- height: $o-navbar-height;
- text-align: left;
-
- .popover-body {
- height: $o-navbar-height;
-
- .btn {
- height: $o-navbar-height;
- }
- }
- }
-
form.navbar-form {
+ @include o-position-absolute(0, 0, 0, auto);
+ z-index: $zindex-popover + 5;
height: $o-navbar-height;
- z-index: 1060;
margin: 0;
padding: 0;
- position: absolute;
- top: -1px;
- right: -1px;
transition: right 0.4s $o-we-md-ease 0s;
border-left: 1px solid $o-we-color-divider;
@@ -96,19 +75,11 @@ body.editor_enable {
}
}
-body:not(.editor_enable) form.navbar-form {
+.note-statusbar {
display: none;
}
-// SNIPPETS
-#oe_snippets {
- border: 0;
- #snippets_menu {
- height: $o-navbar-height;
- }
-}
-
-// Translations
+// TRANSLATIONS
.oe_translate_examples li {
margin: 10px;
padding: 4px;
@@ -126,60 +97,10 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
}
}
-// NOTE EDITOR
-
-// SNIPPET PANEL
-#oe_snippets {
- @include o-w-preserve-btn;
- position: fixed;
- width: $o-we-sidebar-width;
- z-index: 1042;
-
- border-top: 0;
- border-right: 1px solid $o-we-color-divider;
- transition: left 400ms $o-we-md-ease 0s;
- background-image: linear-gradient(45deg, $o-we-color-normal, darken($o-we-color-normal, 10%));
-
- #snippets_menu {
- color: #999999;
- background: $o-we-color-dark;
- font-family: $o-we-font-family;
- height: $o-navbar-height;
- line-height: $o-navbar-height;
- }
-
- #o_scroll {
- .o_panel_header {
- color: #999999;
- }
- }
-}
-
-.oe_snippet {
- background-color: $o-we-color-normal;
-
- .oe_snippet_thumbnail {
- .oe_snippet_thumbnail_img {
- border: 1px solid $o-we-color-normal;
- }
-
- img.oe_snippet_thumbnail_img {}
-
- .oe_snippet_thumbnail_title {
- border: 1px solid $o-we-color-dark;
- color: $o-we-color-text-light;
- }
-
- &:hover .oe_snippet_thumbnail_title {
- color: $o-we-color-text-lighter;
- }
- }
-}
-
// SNIPPET OPTIONS
.colorpicker {
.o_colorpicker_sections {
- .note-color-palette>div {
+ .note-color-palette > div {
color: $o-we-color-text-light;
}
}
@@ -191,7 +112,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
clear: both;
}
- >button {
+ > button {
&:hover,
&.selected {
@@ -223,173 +144,22 @@ html[lang] > body.editor_enable [data-oe-translation-state] {
}
}
-// DROPZONES
-#wrapwrap .oe_drop_zone {
- &.oe_insert {
- height: $o-we-dropzone-size;
- margin: (-$o-we-dropzone-size/2) 0;
-
- &:after {
- border-bottom: $o-we-dropzone-border;
- }
-
- &.oe_vertical {
- width: $o-we-dropzone-size;
- margin: 0 (-$o-we-dropzone-size/2);
-
- &:after {
- border-right: $o-we-dropzone-border;
- }
- }
- }
-}
-
-// MANIPULATORS
-#oe_manipulators {
-
- // SNIPPET MANIPULATORS
- .oe_overlay {
-
- // OVERLAY OPTIONS
- >.oe_overlay_options {
- font-family: $o-we-font-family;
-
- >.btn-group {
- .btn {
- height: $o-we-overlay-option-size;
- border: 1px solid $o-we-color-dark;
- line-height: #{$o-we-overlay-option-size - 2px};
-
- color: $o-we-color-text-light;
- background-color: $o-we-color-light;
-
- &:hover {
- background-color: lighten($o-we-color-dark, 10%);
- }
-
- &.oe_snippet_remove {
- background-color: $o-we-color-danger;
- border-color: darken($o-we-color-danger, 20%);
-
- &:hover {
- background-color: darken($o-we-color-danger, 20%);
- }
- }
-
- >.fa {
- color: $o-we-color-text-light;
- }
- }
-
- // CUSTOMIZE MENU BUTTON
- >.oe_options {
- .btn {
- background-color: $o-we-color-dark;
- color: $o-we-color-text-light;
-
- &:hover,
- &:active,
- &:focus {
- background-color: lighten($o-we-color-dark, 5%);
- border-color: lighten($o-we-color-dark, 10%);
- }
-
- &:before,
- &:after {
- background-color: $o-we-color-text-light;
- }
- }
-
- // Open menu
- &.show .btn {
- // background-color: $o-we-color-light;
- }
-
- // CUSTOMIZE MENU
- .dropdown-menu {
- border: 1px solid $o-we-color-dark;
- background-color: $o-we-color-light;
-
- .dropdown-item {
- color: $o-we-color-text-light;
-
- &:hover {
- background-color: fade-out($o-we-color-dark, 0.5);
- }
-
- &.active {
- background-color: fade-out($o-we-color-dark, 0.5);
- }
- }
-
- .dropdown-header {
- color: wheat;
-
- &.o_parent_editor_header {
- color: wheat;
- }
- }
-
- .dropdown-submenu {
- &::before {
- border-left-color: $o-we-color-text-light;
- }
- }
- }
- }
- }
- }
-
- &.o_top_cover>.oe_overlay_options {
- top: $o-we-handle-border-width;
- right: $o-we-handle-border-width;
- }
-
- }
-}
-
-// Animations
-@keyframes fadeInDownSmall {
- 0% {
- opacity: 0;
- transform: translate(0, -5px);
- }
-
- 100% {
- opacity: 1;
- transform: translate(0, 0);
- }
-}
-
+// ANIMATIONS
@keyframes fadeInOut {
0% {
opacity: 0;
}
-
25% {
opacity: 1;
}
-
75% {
opacity: 1;
}
-
100% {
opacity: 0;
}
}
-@keyframes inputHighlighter {
- from {
- background: $o-brand-primary;
- }
-
- to {
- width: 0;
- background: transparent;
- }
-}
-
// MODALS
body .modal {
@@ -547,109 +317,3 @@ body .modal {
}
}
}
-
-.note-editor {
- &>.note-toolbar-wrapper .note-toolbar {
- height: $o-navbar-height;
-
- .btn {
- height: $o-navbar-height !important; // force this because of themes
- }
- }
-
- &>.note-statusbar {
- display: none;
- }
-
- &>.note-editing-area {
- overflow: visible;
- }
-}
-
-#web_editor-toolbars .popover,
-.note-popover,
-.note-editor>.note-toolbar-wrapper .note-toolbar {
- // force this because of themes
- background-color: $o-we-color-dark !important;
-
- .btn {
- background-color: $o-we-color-dark !important;
- color: $o-we-color-text-normal !important;
- border: none !important;
- padding: 0.0625rem 0.3125rem !important;
-
- >.fa {
- color: $o-we-color-text-normal !important;
- }
-
- &:hover {
- color: $o-we-color-text-light !important;
-
- >.fa {
- color: $o-we-color-text-light !important;
- }
- }
-
- &.active {
- background-color: $o-we-color-dark !important;
- color: $o-we-color-text-light !important;
-
- >.fa {
- color: $o-we-color-text-light !important;
- }
- }
- }
-
- >.btn-group {
- margin-top: 0 !important;
-
- &.show,
- .btn-group.show {
- .dropdown-toggle {
- border-top: 2px solid white !important;
- background-color: $o-we-color-darker !important;
- color: white !important;
- box-shadow: none !important;
-
- >.fa,
- >span {
- color: white !important;
- }
- }
- }
- }
-
- .dropdown-menu {
- margin: 0 !important;
- border-radius: 0 !important;
- background-color: $o-we-color-darker !important;
- color: $o-we-color-text-normal !important;
- white-space: normal !important;
-
- .dropdown-item {
- width: 100% !important;
- color: $o-we-color-text-light !important;
-
- >.fa {
- color: $o-we-color-text-light !important;
- }
-
- &:hover {
- background-color: $o-we-tab-active-bg !important;
- color: white !important;
-
- >.fa {
- color: white !important;
- }
- }
- }
- }
-
- .note-para .dropdown-menu {
- min-width: 147px !important;
- }
-
- .note-style .dropdown-item * {
- color: $o-we-color-text-light !important;
- }
-}
diff --git a/addons/website/static/tests/tours/rte.js b/addons/website/static/tests/tours/rte.js
index d8c8d768162..912cb6832e0 100644
--- a/addons/website/static/tests/tours/rte.js
+++ b/addons/website/static/tests/tours/rte.js
@@ -55,7 +55,7 @@ tour.register('rte_translator', {
run: 'drag_and_drop #wrap',
}, {
content: "change content",
- trigger: '.oe_overlay_options .oe_options:visible',
+ trigger: '#wrap',
run: function () {
$("#wrap p:first").replaceWith('<p>Write one or <font style="background-color: yellow;">two paragraphs <b>describing</b></font> your product or\
<font style="color: rgb(255, 0, 0);">services</font>. To be successful your content needs to be\
diff --git a/addons/website/views/snippets.xml b/addons/website/views/snippets.xml
index 159219b58d1..c42f86440a1 100644
--- a/addons/website/views/snippets.xml
+++ b/addons/website/views/snippets.xml
@@ -914,10 +914,10 @@
data-selector=".s_three_columns .row > div, .s_comparisons .row > div, .s_tabs .row > div"
data-target=".card"
data-palette-title="Box Color">
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-eyedropper"/>Color</a>
- <div class="dropdown-menu" role="menu"/>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-eyedropper"/> Color</we-toggler>
+ <we-collapse/>
+ </we-collapse-area>
</div>
<!-- COLOR | .s_hr -->
@@ -927,20 +927,20 @@
data-color-prefix="border-"
data-palette-exclude="transparent_grayscale, common"
data-palette-title="Separator Color">
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-eyedropper"/>Color</a>
- <div class="dropdown-menu" role="menu"/>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-eyedropper"/> Color</we-toggler>
+ <we-collapse/>
+ </we-collapse-area>
</div>
<!-- COLOR | .s_cards -->
<div data-js="colorpicker"
data-selector=".s_card, .accordion .card"
data-palette-title="Card Color">
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-eyedropper"/>Color</a>
- <div class="dropdown-menu" role="menu"/>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-eyedropper"/> Color</we-toggler>
+ <we-collapse/>
+ </we-collapse-area>
</div>
<!-- COLOR | .s_alert -->
@@ -948,314 +948,331 @@
data-selector=".s_alert"
data-color-prefix="alert-"
data-palette-title="Box Color">
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-eyedropper"/>Color</a>
- <div class="dropdown-menu" role="menu"/>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-eyedropper"/> Color</we-toggler>
+ <we-collapse/>
+ </we-collapse-area>
</div>
<!-- STYLES | .s_title -->
<div data-selector=".s_title" data-target="[class*='s_title_']">
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-font"/>Typography</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" data-select-class="s_title_boxed">Boxed</a>
- <a href="#" class="dropdown-item" data-select-class="s_title_lines">Line-On-Sides</a>
- <a href="#" class="dropdown-item" data-select-class="s_title_thin">Thin</a>
- <a href="#" class="dropdown-item" data-select-class="s_title_transparent">Transparent</a>
- <a href="#" class="dropdown-item" data-select-class="s_title_underlined">Underlined</a>
- <a href="#" class="dropdown-item" data-select-class="s_title_small_caps">Small Caps</a>
- <div class="dropdown-divider"/>
- <a href="#" class="dropdown-item" data-select-class="s_title_default">Default</a>
- </div>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-font"/> Typography</we-toggler>
+ <we-collapse>
+ <we-button data-select-class="s_title_boxed">Boxed</we-button>
+ <we-button data-select-class="s_title_lines">Line-On-Sides</we-button>
+ <we-button data-select-class="s_title_thin">Thin</we-button>
+ <we-button data-select-class="s_title_transparent">Transparent</we-button>
+ <we-button data-select-class="s_title_underlined">Underlined</we-button>
+ <we-button data-select-class="s_title_small_caps">Small Caps</we-button>
+ <we-divider/>
+ <we-button data-select-class="s_title_default">Default</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
<!-- H-ALIGN | .s_btn -->
<div data-selector=".s_btn, .s_share">
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-align-left"/>Alignment</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" data-select-class="text-left">Left</a>
- <a href="#" class="dropdown-item" data-select-class="text-center">Center</a>
- <a href="#" class="dropdown-item" data-select-class="text-right">Right</a>
- </div>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-align-left"/> Alignment</we-toggler>
+ <we-collapse>
+ <we-button data-select-class="text-left">Left</we-button>
+ <we-button data-select-class="text-center">Center</we-button>
+ <we-button data-select-class="text-right">Right</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
<div data-selector=".s_alert">
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-arrows"/>Size</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" data-select-class="s_alert_sm">Small</a>
- <a href="#" class="dropdown-item" data-select-class="s_alert_md">Medium</a>
- <a href="#" class="dropdown-item" data-select-class="s_alert_lg">Large</a>
- </div>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-arrows"/> Size</we-toggler>
+ <we-collapse>
+ <we-button data-select-class="s_alert_sm">Small</we-button>
+ <we-button data-select-class="s_alert_md">Medium</we-button>
+ <we-button data-select-class="s_alert_lg">Large</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
<div data-selector=".s_alert, .s_card">
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-arrows-h"/>Width</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" data-select-class="w-25">25%</a>
- <a href="#" class="dropdown-item" data-select-class="w-50">50%</a>
- <a href="#" class="dropdown-item" data-select-class="w-75">75%</a>
- <a href="#" class="dropdown-item" data-select-class="w-100">100%</a>
- </div>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-arrows-h"/> Width</we-toggler>
+ <we-collapse>
+ <we-button data-select-class="w-25">25%</we-button>
+ <we-button data-select-class="w-50">50%</we-button>
+ <we-button data-select-class="w-75">75%</we-button>
+ <we-button data-select-class="w-100">100%</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
<!-- STYLES | .s_rating -->
<div data-selector=".s_rating > div">
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item">Icon</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" data-select-class="s_rating_stars"><i class="fa fa-star"/>Stars</a>
- <a href="#" class="dropdown-item" data-select-class="s_rating_squares"><i class="fa fa-square"/>Squares</a>
- <a href="#" class="dropdown-item" data-select-class="s_rating_hearts"><i class="fa fa-heart"/>Hearts</a>
- <a href="#" class="dropdown-item" data-select-class="s_rating_bar"><i class="fa fa-tasks"/>Progress Bar</a>
- </div>
- </div>
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item">Value</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" data-select-class="">0</a>
- <a href="#" class="dropdown-item" data-select-class="s_rating_1">1/5</a>
- <a href="#" class="dropdown-item" data-select-class="s_rating_2">2/5</a>
- <a href="#" class="dropdown-item" data-select-class="s_rating_3">3/5</a>
- <a href="#" class="dropdown-item" data-select-class="s_rating_4">4/5</a>
- <a href="#" class="dropdown-item" data-select-class="s_rating_5">5/5</a>
- </div>
- </div>
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item">Size</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" data-select-class="s_rating_1x">Small</a>
- <a href="#" class="dropdown-item" data-select-class="s_rating_2x">Medium</a>
- <a href="#" class="dropdown-item" data-select-class="s_rating_3x">Big</a>
- </div>
- </div>
+ <we-collapse-area>
+ <we-toggler>Icon</we-toggler>
+ <we-collapse>
+ <we-button data-select-class="s_rating_stars"><i class="fa fa-fw fa-star"/> Stars</we-button>
+ <we-button data-select-class="s_rating_squares"><i class="fa fa-fw fa-square"/> Squares</we-button>
+ <we-button data-select-class="s_rating_hearts"><i class="fa fa-fw fa-heart"/> Hearts</we-button>
+ <we-button data-select-class="s_rating_bar"><i class="fa fa-fw fa-tasks"/> Progress Bar</we-button>
+ </we-collapse>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler>Value</we-toggler>
+ <we-collapse>
+ <we-button data-select-class="">0</we-button>
+ <we-button data-select-class="s_rating_1">1/5</we-button>
+ <we-button data-select-class="s_rating_2">2/5</we-button>
+ <we-button data-select-class="s_rating_3">3/5</we-button>
+ <we-button data-select-class="s_rating_4">4/5</we-button>
+ <we-button data-select-class="s_rating_5">5/5</we-button>
+ </we-collapse>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler>Size</we-toggler>
+ <we-collapse>
+ <we-button data-select-class="s_rating_1x">Small</we-button>
+ <we-button data-select-class="s_rating_2x">Medium</we-button>
+ <we-button data-select-class="s_rating_3x">Big</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
<!-- STYLES | .s_hr -->
<div data-selector=".s_hr" data-target="hr">
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-minus"/>Thickness</a>
- <div class="dropdown-menu" role="menu">
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-minus"/> Thickness</we-toggler>
+ <we-collapse>
<t t-foreach="range(1,6)" t-as="s_hr_thickness">
- <a href="#" class="dropdown-item" t-attf-data-select-class="s_hr_{{s_hr_thickness}}px"><t t-esc="s_hr_thickness"/>px</a>
+ <we-button t-attf-data-select-class="s_hr_{{s_hr_thickness}}px"><t t-esc="s_hr_thickness"/>px</we-button>
</t>
- </div>
- </div>
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-pencil"/>Style</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" data-select-class="s_hr_solid">Solid</a>
- <a href="#" class="dropdown-item" data-select-class="s_hr_dashed">Dashed</a>
- <a href="#" class="dropdown-item" data-select-class="s_hr_dotted">Dotted</a>
- <a href="#" class="dropdown-item" data-select-class="s_hr_double">Double</a>
- </div>
- </div>
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-arrows-h"/>Width</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" data-select-class="w-25">25%</a>
- <a href="#" class="dropdown-item" data-select-class="w-50">50%</a>
- <a href="#" class="dropdown-item" data-select-class="w-75">75%</a>
- <a href="#" class="dropdown-item" data-select-class="w-100">100%</a>
- </div>
- </div>
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-align-left"/>Alignment</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" data-select-class="mr-auto">Left</a>
- <a href="#" class="dropdown-item" data-select-class="mx-auto">Center</a>
- <a href="#" class="dropdown-item" data-select-class="ml-auto">Right</a>
- </div>
- </div>
+ </we-collapse>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-pencil"/> Style</we-toggler>
+ <we-collapse>
+ <we-button data-select-class="s_hr_solid">Solid</we-button>
+ <we-button data-select-class="s_hr_dashed">Dashed</we-button>
+ <we-button data-select-class="s_hr_dotted">Dotted</we-button>
+ <we-button data-select-class="s_hr_double">Double</we-button>
+ </we-collapse>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-arrows-h"/> Width</we-toggler>
+ <we-collapse>
+ <we-button data-select-class="w-25">25%</we-button>
+ <we-button data-select-class="w-50">50%</we-button>
+ <we-button data-select-class="w-75">75%</we-button>
+ <we-button data-select-class="w-100">100%</we-button>
+ </we-collapse>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-align-left"/> Alignment</we-toggler>
+ <we-collapse>
+ <we-button data-select-class="mr-auto">Left</we-button>
+ <we-button data-select-class="mx-auto">Center</we-button>
+ <we-button data-select-class="ml-auto">Right</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
<!-- Carousel | .s_carousel | .s_quotes_carousel -->
<div data-js="carousel"
data-selector=":not(.o_gallery > .container) > .carousel">
- <a href="#" class="dropdown-item" data-add-slide="true" data-no-preview="true"><i class="fa fa-plus-circle"/>Add Slide</a>
- <a href="#" class="dropdown-item" data-remove-slide="true" data-no-preview="true"><i class="fa fa-trash-o"/>Remove Slide</a>
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-clone"/>Transition</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" role="menuitem" data-select-class="slide">Slide</a>
- <a href="#" class="dropdown-item" role="menuitem" data-select-class="carousel-fade slide">Fade</a>
- <div class="dropdown-divider"/>
- <a href="#" class="dropdown-item" role="menuitem" data-select-class="">None</a>
- </div>
- </div>
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-magic"/>Style</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" role="menuitem" data-select-class="s_carousel_bordered">Bordered</a>
- <a href="#" class="dropdown-item" role="menuitem" data-select-class="s_carousel_boxed">Boxed</a>
- <a href="#" class="dropdown-item" role="menuitem" data-select-class="s_carousel_rounded">Rounded</a>
- <div class="dropdown-divider"/>
- <a href="#" class="dropdown-item" role="menuitem" data-select-class="s_carousel_default">Default</a>
- </div>
- </div>
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-clock-o"/>Speed</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" role="menuitem" data-interval="1000">1s</a>
- <a href="#" class="dropdown-item" role="menuitem" data-interval="2000">2s</a>
- <a href="#" class="dropdown-item" role="menuitem" data-interval="3000">3s</a>
- <a href="#" class="dropdown-item" role="menuitem" data-interval="5000">5s</a>
- <a href="#" class="dropdown-item" role="menuitem" data-interval="10000">10s</a>
- <a href="#" class="dropdown-item" role="menuitem" data-interval="0">Disable autoplay</a>
- </div>
- </div>
+ <we-button data-add-slide="true" data-no-preview="true">
+ <i class="fa fa-fw fa-plus-circle"/> Add Slide
+ </we-button>
+ <we-button data-remove-slide="true" data-no-preview="true">
+ <i class="fa fa-fw fa-trash-o"/> Remove Slide
+ </we-button>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-clone"/>Transition</we-toggler>
+ <we-collapse>
+ <we-button data-select-class="slide">Slide</we-button>
+ <we-button data-select-class="carousel-fade slide">Fade</we-button>
+ <we-divider/>
+ <we-button data-select-class="">None</we-button>
+ </we-collapse>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-magic"/> Style</we-toggler>
+ <we-collapse>
+ <we-button data-select-class="s_carousel_bordered">Bordered</we-button>
+ <we-button data-select-class="s_carousel_boxed">Boxed</we-button>
+ <we-button data-select-class="s_carousel_rounded">Rounded</we-button>
+ <we-divider/>
+ <we-button data-select-class="s_carousel_default">Default</we-button>
+ </we-collapse>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-clock-o"/> Speed</we-toggler>
+ <we-collapse>
+ <we-button data-interval="1000">1s</we-button>
+ <we-button data-interval="2000">2s</we-button>
+ <we-button data-interval="3000">3s</we-button>
+ <we-button data-interval="5000">5s</we-button>
+ <we-button data-interval="10000">10s</we-button>
+ <we-button data-interval="0">Disable autoplay</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
<div data-js="navTabs" data-selector="section .row > div" data-target=".nav-tabs">
- <a href="#" class="dropdown-item" data-add-tab="1" data-no-preview="true"><i class="fa fa-plus"/>Add Tab</a>
- <a href="#" class="dropdown-item" data-remove-tab="1" data-no-preview="true"><i class="fa fa-minus"/>Remove Tab</a>
+ <we-button data-add-tab="1" data-no-preview="true">
+ <i class="fa fa-fw fa-plus"/> Add Tab
+ </we-button>
+ <we-button data-remove-tab="1" data-no-preview="true">
+ <i class="fa fa-fw fa-minus"/> Remove Tab
+ </we-button>
</div>
<div data-js="gallery" data-selector=".o_gallery">
- <a href="#" class="dropdown-item" data-add-images="true" data-no-preview="true"><i class="fa fa-plus-circle"/>Add images</a>
- <a href="#" class="dropdown-item" data-remove-all-images="true" data-no-preview="true"><i class="fa fa-trash"/>Remove all images</a>
- <div class="dropdown-divider"/>
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-magic"/>Mode</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" role="menuitem" data-mode="nomode">Float</a>
- <a href="#" class="dropdown-item" role="menuitem" data-mode="masonry">Masonry</a>
- <a href="#" class="dropdown-item" role="menuitem" data-mode="grid">Grid</a>
- <a href="#" class="dropdown-item" role="menuitem" data-mode="slideshow">Slideshow</a>
- </div>
- </div>
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-clock-o"/>Slideshow speed</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" role="menuitem" data-interval="1000">1s</a>
- <a href="#" class="dropdown-item" role="menuitem" data-interval="2000">2s</a>
- <a href="#" class="dropdown-item" role="menuitem" data-interval="3000">3s</a>
- <a href="#" class="dropdown-item" role="menuitem" data-interval="5000">5s</a>
- <a href="#" class="dropdown-item" role="menuitem" data-interval="10000">10s</a>
- <a href="#" class="dropdown-item" role="menuitem" data-interval="0">Disable autoplay</a>
- </div>
- </div>
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-th"/>Columns</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" role="menuitem" data-columns="1">1</a>
- <a href="#" class="dropdown-item" role="menuitem" data-columns="2">2</a>
- <a href="#" class="dropdown-item" role="menuitem" data-columns="3">3</a>
- <a href="#" class="dropdown-item" role="menuitem" data-columns="4">4</a>
- <a href="#" class="dropdown-item" role="menuitem" data-columns="6">6</a>
- <a href="#" class="dropdown-item" role="menuitem" data-columns="12">12</a>
- </div>
- </div>
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-arrows-h"/>Images spacing</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_spc-none">None</a>
- <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_spc-small">Small</a>
- <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_spc-medium">Medium</a>
- <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_spc-big">Big</a>
- </div>
- </div>
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-paint-brush"/>Styling</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" role="menuitem" data-styling="">Square</a>
- <a href="#" class="dropdown-item" role="menuitem" data-styling="rounded">Rounded corners</a>
- <a href="#" class="dropdown-item" role="menuitem" data-styling="img-thumbnail">Thumbnails</a>
- <a href="#" class="dropdown-item" role="menuitem" data-styling="rounded-circle">Circle</a>
- <a href="#" class="dropdown-item" role="menuitem" data-styling="shadow">Shadows</a>
- </div>
- </div>
+ <we-button class="we-button-hover-icon" data-add-images="true" data-no-preview="true">
+ <i class="fa fa-fw fa-plus-circle"/> Add images
+ </we-button>
+ <we-button data-remove-all-images="true" data-no-preview="true">
+ <i class="fa fa-fw fa-trash"/> Remove all images
+ </we-button>
+ <we-divider/>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-magic"/> Mode</we-toggler>
+ <we-collapse>
+ <we-button data-mode="nomode">Float</we-button>
+ <we-button data-mode="masonry">Masonry</we-button>
+ <we-button data-mode="grid">Grid</we-button>
+ <we-button data-mode="slideshow">Slideshow</we-button>
+ </we-collapse>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-clock-o"/> Slideshow speed</we-toggler>
+ <we-collapse>
+ <we-button data-interval="1000">1s</we-button>
+ <we-button data-interval="2000">2s</we-button>
+ <we-button data-interval="3000">3s</we-button>
+ <we-button data-interval="5000">5s</we-button>
+ <we-button data-interval="10000">10s</we-button>
+ <we-button data-interval="0">Disable autoplay</we-button>
+ </we-collapse>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-th"/> Columns</we-toggler>
+ <we-collapse>
+ <we-button data-columns="1">1</we-button>
+ <we-button data-columns="2">2</we-button>
+ <we-button data-columns="3">3</we-button>
+ <we-button data-columns="4">4</we-button>
+ <we-button data-columns="6">6</we-button>
+ <we-button data-columns="12">12</we-button>
+ </we-collapse>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-arrows-h"/> Images spacing</we-toggler>
+ <we-collapse>
+ <we-button data-select-class="o_spc-none">None</we-button>
+ <we-button data-select-class="o_spc-small">Small</we-button>
+ <we-button data-select-class="o_spc-medium">Medium</we-button>
+ <we-button data-select-class="o_spc-big">Big</we-button>
+ </we-collapse>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-paint-brush"/> Styling</we-toggler>
+ <we-collapse>
+ <we-button data-styling="">Square</we-button>
+ <we-button data-styling="rounded">Rounded corners</we-button>
+ <we-button data-styling="img-thumbnail">Thumbnails</we-button>
+ <we-button data-styling="rounded-circle">Circle</we-button>
+ <we-button data-styling="shadow">Shadows</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
<div data-js="gallery_img" data-selector=".o_gallery img">
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-refresh"/>Re-order</a>
- <div class="dropdown-menu" role="menu" data-no-preview="true">
- <a href="#" class="dropdown-item" role="menuitem" data-position="first">Move to first</a>
- <a href="#" class="dropdown-item" role="menuitem" data-position="prev">Move to previous</a>
- <a href="#" class="dropdown-item" role="menuitem" data-position="next">Move to next</a>
- <a href="#" class="dropdown-item" role="menuitem" data-position="last">Move to last</a>
- </div>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-refresh"/> Re-order</we-toggler>
+ <we-collapse data-no-preview="true">
+ <we-button data-position="first">Move to first</we-button>
+ <we-button data-position="prev">Move to previous</we-button>
+ <we-button data-position="next">Move to next</we-button>
+ <we-button data-position="last">Move to last</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
<!-- Facebook Page -->
<div data-js="facebookPage" data-selector=".o_facebook_page">
- <a href="#" class="dropdown-item" data-fb-page-options="true" data-no-preview="true"><i class="fa fa-facebook"/>Options</a>
+ <we-button class="we-button-hover-icon" data-fb-page-options="true" data-no-preview="true">
+ <i class="fa fa-fw fa-facebook"/> Options
+ </we-button>
</div>
<!-- Accordion -->
<div data-js="collapse"
data-selector='.accordion > .card'
- data-drop-in='.accordion:has(> .card)'>
- </div>
+ data-drop-in='.accordion:has(> .card)'/>
<div data-js="layout_column"
data-selector="section"
data-target="> * > .row:not(.s_nb_column_fixed)">
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-columns"/>Number of columns</a>
- <div class="dropdown-menu" role="menu" data-no-preview="true">
- <a href="#" class="dropdown-item" role="menuitem" data-select-count="1">1</a>
- <a href="#" class="dropdown-item" role="menuitem" data-select-count="2">2</a>
- <a href="#" class="dropdown-item" role="menuitem" data-select-count="3">3</a>
- <a href="#" class="dropdown-item" role="menuitem" data-select-count="4">4</a>
- <a href="#" class="dropdown-item" role="menuitem" data-select-count="5">5</a>
- <a href="#" class="dropdown-item" role="menuitem" data-select-count="6">6</a>
- </div>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-columns"/> Number of columns</we-toggler>
+ <we-collapse data-no-preview="true">
+ <we-button data-select-count="1">1</we-button>
+ <we-button data-select-count="2">2</we-button>
+ <we-button data-select-count="3">3</we-button>
+ <we-button data-select-count="4">4</we-button>
+ <we-button data-select-count="5">5</we-button>
+ <we-button data-select-count="6">6</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
<!-- V-ALIGN -->
<div id="row_valign_snippet_option" data-selector=".s_text_image, .s_image_text, .s_three_columns" data-target=".row">
- <div class="dropdown-submenu">
- <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-arrows-v"/>Alignment</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" data-select-class="align-items-start">Top</a>
- <a href="#" class="dropdown-item" data-select-class="align-items-center">Middle</a>
- <a href="#" class="dropdown-item" data-select-class="align-items-end">Bottom</a>
- <div class="dropdown-divider"/>
- <a href="#" class="dropdown-item" data-select-class="align-items-stretch">Equal height</a>
- </div>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-arrows-v"/> Alignment</we-toggler>
+ <we-collapse>
+ <we-button data-select-class="align-items-start">Top</we-button>
+ <we-button data-select-class="align-items-center">Middle</we-button>
+ <we-button data-select-class="align-items-end">Bottom</we-button>
+ <we-divider/>
+ <we-button data-select-class="align-items-stretch">Equal height</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
<!-- Background Image -->
<div data-js="background"
data-selector="section, .parallax, :not(.o_gallery > .container) > .carousel"
data-exclude=".s_hr, .s_image_gallery">
- <a tabindex="-1" href="#" class="dropdown-item" data-choose-image="true" data-no-preview="true"><i class="fa fa-picture-o"/>Background Image</a>
+ <we-button class="we-button-hover-icon" data-choose-image="true" data-no-preview="true">
+ <i class="fa fa-fw fa-picture-o"/> Background Image
+ </we-button>
</div>
<!-- Background Image -->
<div data-js="background_position"
data-selector="section, .parallax, :not(.o_gallery > .container) > .carousel">
- <a tabindex="-1" href="#" class="dropdown-item background_position_li" data-background-position="true" data-no-preview="true"><i class="fa fa-arrows"/>Background Image Sizing</a>
+ <we-button class="we-button-hover-icon" data-background-position="true" data-no-preview="true">
+ <i class="fa fa-fw fa-arrows"/> Background Image Sizing
+ </we-button>
</div>
<!-- Parallax -->
<div data-js="parallax" data-selector=".parallax">
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-clock-o"/>Scroll Speed</a>
- <div class="dropdown-menu" role="menu" name="parallax-scroll">
- <a href="#" class="dropdown-item" role="menuitem" data-scroll="0">No-scroll</a>
- <div class="dropdown-divider" role="separator"/>
- <a href="#" class="dropdown-item" role="menuitem" data-scroll="1">Fixed</a>
- <div class="dropdown-divider" role="separator"/>
- <a href="#" class="dropdown-item" role="menuitem" data-scroll="0.6">Very Slow</a>
- <a href="#" class="dropdown-item" role="menuitem" data-scroll="1.2">Slow</a>
- <a href="#" class="dropdown-item" role="menuitem" data-scroll="1.6">Fast</a>
- <a href="#" class="dropdown-item" role="menuitem" data-scroll="2">Very Fast</a>
- </div>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-clock-o"/> Scroll Speed</we-toggler>
+ <we-collapse>
+ <we-button data-scroll="0">No-scroll</we-button>
+ <we-divider/>
+ <we-button data-scroll="1">Fixed</we-button>
+ <we-divider/>
+ <we-button data-scroll="0.6">Very Slow</we-button>
+ <we-button data-scroll="1.2">Slow</we-button>
+ <we-button data-scroll="1.6">Fast</we-button>
+ <we-button data-scroll="2">Very Fast</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
<!-- Color | Section -->
@@ -1263,10 +1280,10 @@
data-js="colorpicker"
data-selector="section, :not(.o_gallery > .container) > .carousel"
data-exclude=".parallax">
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-eyedropper"/>Background Color</a>
- <div class="dropdown-menu" role="menu"/>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-eyedropper"/> Background Color</we-toggler>
+ <we-collapse/>
+ </we-collapse-area>
</div>
<!-- FILTER | .s_parallax -->
@@ -1275,32 +1292,32 @@
data-palette-exclude="common, theme"
data-palette-default="transparent_grayscale"
data-palette-title="Overlay Color">
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-eyedropper"/>Filter</a>
- <div class="dropdown-menu" role="menu"/>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-eyedropper"/> Filter</we-toggler>
+ <we-collapse/>
+ </we-collapse-area>
</div>
<!-- Color | Columns -->
<div data-js="colorpicker"
data-selector="section .row > div"
data-exclude=".s_col_no_bgcolor, .s_col_no_bgcolor.row > div, .o_gallery .row > div">
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-eyedropper"/>Background Color</a>
- <div class="dropdown-menu" role="menu"/>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-eyedropper"/> Background Color</we-toggler>
+ <we-collapse/>
+ </we-collapse-area>
</div>
<div data-selector="section .row > div"
data-exclude=".s_col_no_bgcolor, .s_col_no_bgcolor.row > div, .o_gallery .row > div">
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-magic"/>Styles</a>
- <div class="dropdown-menu" role="menu">
- <a href="#" class="dropdown-item" role="menuitem" data-toggle-class="border">Border</a>
- <a href="#" class="dropdown-item" role="menuitem" data-toggle-class="rounded">Rounded</a>
- <a href="#" class="dropdown-item" role="menuitem" data-toggle-class="shadow">Shadow</a>
- </div>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-magic"/> Styles</we-toggler>
+ <we-collapse>
+ <we-button data-toggle-class="border">Border</we-button>
+ <we-button data-toggle-class="rounded">Rounded</we-button>
+ <we-button data-toggle-class="shadow">Shadow</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
<div data-js="sizing_y"
@@ -1309,22 +1326,21 @@
<div data-js="sizing_x"
data-selector=".row > div"
data-drop-near=".row > div"
- data-exclude=".s_col_no_resize.row > div">
- </div>
+ data-exclude=".s_col_no_resize.row > div"/>
<div id="so_snippet_addition"
data-selector="section, :not(.o_gallery > .container) > .carousel, .parallax"
data-drop-in=":not(p).oe_structure:not(.oe_structure_solo), :not(p)[data-oe-type=html], :not(p).oe_structure.oe_structure_solo:not(:has(> section, > div))"/>
- <div data-js="content"
+ <!-- Main content drop -->
+ <div id="so_content_addition"
data-selector="blockquote, .s_btn, .s_card, .s_alert, .o_facebook_page, .s_share, .s_rating, .s_hr"
data-drop-near="p, h1, h2, h3, blockquote, .s_btn, .s_card, .s_alert, .o_facebook_page, .s_share, .s_rating, .s_hr"
- data-drop-in=".content">
- </div>
+ data-drop-in=".content"/>
<div data-js="ul"
data-selector=":not(li) > ul:has(ul,ol), :not(li) > ol:has(ul,ol)">
- <a href="#" class="dropdown-item" data-toggle-class="o_ul_folded">Folded list</a>
+ <we-button data-toggle-class="o_ul_folded">Folded list</we-button>
</div>
<div data-js="menu_data"
@@ -1339,7 +1355,9 @@
<div data-js="topMenuTransparency"
data-selector="[data-main-object^='website.page('] #wrapwrap > header"
data-no-check="true">
- <a tabindex="-1" href="#" class="dropdown-item" data-transparent="true" data-no-preview="true"><i class="fa fa-eye-slash"/>Transparent</a>
+ <we-button data-transparent="true" data-no-preview="true">
+ <i class="fa fa-fw fa-eye-slash"/> Transparent
+ </we-button>
</div>
<div data-js="topMenuColor"
@@ -1348,17 +1366,19 @@
data-palette-default="transparent_grayscale"
data-palette-title="Top Menu Color"
data-no-check="true">
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-eyedropper"/>Background Color</a>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-fw fa-eyedropper"/> Background Color</we-toggler>
<div class="dropdown-menu"/>
- </div>
+ </we-collapse-area>
</div>
<!-- Anchor Name -->
<div data-js="anchorName"
data-selector=":not(p).oe_structure > *, :not(p)[data-oe-type=html] > *, .row > div"
data-exclude=".modal *">
- <a tabindex="-1" href="#" class="dropdown-item" data-no-preview="true" data-open-anchor-dialog=""><i class="fa fa-anchor"/>Anchor Name</a>
+ <we-button class="we-button-hover-icon" data-no-preview="true" data-open-anchor-dialog="">
+ <i class="fa fa-fw fa-anchor"/> Anchor Name
+ </we-button>
</div>
</template>
</odoo>
diff --git a/addons/website_blog/static/src/js/tours/website_blog.js b/addons/website_blog/static/src/js/tours/website_blog.js
index c8f04ed4659..ce35f60f40a 100644
--- a/addons/website_blog/static/src/js/tours/website_blog.js
+++ b/addons/website_blog/static/src/js/tours/website_blog.js
@@ -23,13 +23,9 @@ odoo.define("website_blog.tour", function (require) {
position: "top",
run: "text",
}, {
- trigger: "#oe_manipulators .oe_overlay.oe_active a.btn.btn-primary",
+ trigger: "we-button:containsExact(" + _t("Change Cover") + "):visible",
extra_trigger: "#wrap div[data-oe-expression=\"blog_post.name\"]:not(:containsExact(\"\"))",
content: _t("Set a blog post <b>cover</b>."),
- position: "bottom",
- }, {
- trigger: "a:containsExact(" + _t("Change Cover") + "):visible",
- content: _t("Click here to change your post cover."),
position: "right",
}, {
trigger: ".o_select_media_dialog .o_existing_attachment_cell:nth(1) img",
diff --git a/addons/website_blog/static/src/js/website_blog.editor.js b/addons/website_blog/static/src/js/website_blog.editor.js
index 19760a98e4d..de07e5440b2 100644
--- a/addons/website_blog/static/src/js/website_blog.editor.js
+++ b/addons/website_blog/static/src/js/website_blog.editor.js
@@ -236,7 +236,7 @@ options.registry.blog_cover = options.Class.extend({
var self = this;
var isRegularCover = this.$target.is('.o_wblog_post_page_cover_regular');
- _.each(this.$el, function (el) {
+ _.each(this.$el.children(), function (el) {
var $el = $(el);
if (!$el.is('[data-change]')) {
@@ -255,7 +255,7 @@ options.registry.blog_cover = options.Class.extend({
$el.find('.o_js_show_regular').toggleClass('d-none', !isRegularCover);
});
- this.$el.filter('[data-clear]').toggleClass('d-none', !self.$target.hasClass('o_wblog_has_cover'));
+ this.$el.find('[data-clear]').toggleClass('d-none', !self.$target.hasClass('o_wblog_has_cover'));
this.$filterValueOpts.removeClass('active');
this.$filterColorOpts.removeClass('active');
diff --git a/addons/website_blog/views/snippets.xml b/addons/website_blog/views/snippets.xml
index ea2d33b4c3b..7cad9db75ca 100644
--- a/addons/website_blog/views/snippets.xml
+++ b/addons/website_blog/views/snippets.xml
@@ -8,66 +8,66 @@
<xpath expr="//div[@id='snippet_options']" position="inside">
<div data-js="blog_cover" data-selector=".website_blog .o_blog_cover_container" data-no-check="true">
- <a href="#" class="dropdown-item" data-change="true" data-no-preview="true">Change Cover</a>
- <a href="#" class="dropdown-item" data-clear="true" data-no-preview="true">Remove Cover</a>
- <div class="dropdown-submenu">
- <a href="#" class="dropdown-item">Size</a>
- <div class="dropdown-menu" role="menu">
- <a role="menuitem" href="#" data-cover-opt="size" class="dropdown-item" data-select-class="o_wblog_has_cover cover_full">
+ <we-button data-change="true" data-no-preview="true">Change Cover</we-button>
+ <we-button data-clear="true" data-no-preview="true">Remove Cover</we-button>
+ <we-collapse-area>
+ <we-toggler>Size</we-toggler>
+ <we-collapse>
+ <we-button data-cover-opt="size" data-select-class="o_wblog_has_cover cover_full">
<span class="o_js_hide_regular">Full Screen</span>
<span class="o_js_show_regular">Large</span>
- </a>
- <a role="menuitem" href="#" data-cover-opt="size" class="dropdown-item o_wblog_cover_opt_size_default" data-select-class="o_wblog_has_cover cover_mid">
+ </we-button>
+ <we-button data-cover-opt="size" class="o_wblog_cover_opt_size_default" data-select-class="o_wblog_has_cover cover_mid">
<span class="o_js_hide_regular">Half Screen</span>
<span class="o_js_show_regular">Medium</span>
- </a>
- <a role="menuitem" href="#" data-cover-opt="size" class="dropdown-item" data-select-class="o_wblog_has_cover cover_auto">
+ </we-button>
+ <we-button data-cover-opt="size" data-select-class="o_wblog_has_cover cover_auto">
<span class="o_js_hide_regular">Fit text</span>
<span class="o_js_show_regular">Tiny</span>
- </a>
- </div>
- </div>
- <div class="dropdown-submenu">
- <a href="#" class="dropdown-item">Filter Intensity</a>
- <div class="dropdown-menu" role="menu">
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="filters" data-filter-value="0.0">None</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="filters" data-filter-value="0.2">Low</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="filters" data-filter-value="0.4">Medium</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="filters" data-filter-value="0.6">High</a>
- </div>
- </div>
- <div class="dropdown-submenu">
- <a href="#" class="dropdown-item">Filter Color</a>
- <div class="dropdown-menu" role="menu">
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="filters" data-filter-color="oe_black">Black</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="filters" data-filter-color="bg-primary">Primary</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="filters" data-filter-color="oe_none">White</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="filters" data-filter-color="oe_blue">Blue</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="filters" data-filter-color="oe_yellow">Yellow</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="filters" data-filter-color="oe_red">Red</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="filters" data-filter-color="oe_purple">Purple</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="filters" data-filter-color="oe_green">Green</a>
- </div>
- </div>
- <div class="dropdown-submenu">
- <a href="#" class="dropdown-item">Text Size</a>
- <div class="dropdown-menu" role="menu">
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="text_size" data-select-class="o_wblog_cover_font_hero">Hero</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="text_size" data-select-class="o_wblog_cover_font_huge">Huge</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="text_size" data-select-class="o_wblog_cover_font_big">Big</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="text_size" data-select-class="">Regular</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="text_size" data-select-class="o_wblog_cover_font_small">Small</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="text_size" data-select-class="o_wblog_cover_font_tiny">Tiny</a>
- </div>
- </div>
- <div class="dropdown-submenu">
- <a href="#" class="dropdown-item">Text Alignment</a>
- <div class="dropdown-menu" role="menu">
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="text_align" data-select-class="">Left</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="text_align" data-select-class="text-center">Centered</a>
- <a role="menuitem" href="#" class="dropdown-item" data-cover-opt="text_align" data-select-class="text-right">Right</a>
- </div>
- </div>
+ </we-button>
+ </we-collapse>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler>Filter Intensity</we-toggler>
+ <we-collapse>
+ <we-button data-cover-opt="filters" data-filter-value="0.0">None</we-button>
+ <we-button data-cover-opt="filters" data-filter-value="0.2">Low</we-button>
+ <we-button data-cover-opt="filters" data-filter-value="0.4">Medium</we-button>
+ <we-button data-cover-opt="filters" data-filter-value="0.6">High</we-button>
+ </we-collapse>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler>Filter Color</we-toggler>
+ <we-collapse>
+ <we-button data-cover-opt="filters" data-filter-color="oe_black">Black</we-button>
+ <we-button data-cover-opt="filters" data-filter-color="bg-primary">Primary</we-button>
+ <we-button data-cover-opt="filters" data-filter-color="oe_none">White</we-button>
+ <we-button data-cover-opt="filters" data-filter-color="oe_blue">Blue</we-button>
+ <we-button data-cover-opt="filters" data-filter-color="oe_yellow">Yellow</we-button>
+ <we-button data-cover-opt="filters" data-filter-color="oe_red">Red</we-button>
+ <we-button data-cover-opt="filters" data-filter-color="oe_purple">Purple</we-button>
+ <we-button data-cover-opt="filters" data-filter-color="oe_green">Green</we-button>
+ </we-collapse>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler>Text Size</we-toggler>
+ <we-collapse>
+ <we-button data-cover-opt="text_size" data-select-class="o_wblog_cover_font_hero">Hero</we-button>
+ <we-button data-cover-opt="text_size" data-select-class="o_wblog_cover_font_huge">Huge</we-button>
+ <we-button data-cover-opt="text_size" data-select-class="o_wblog_cover_font_big">Big</we-button>
+ <we-button data-cover-opt="text_size" data-select-class="">Regular</we-button>
+ <we-button data-cover-opt="text_size" data-select-class="o_wblog_cover_font_small">Small</we-button>
+ <we-button data-cover-opt="text_size" data-select-class="o_wblog_cover_font_tiny">Tiny</we-button>
+ </we-collapse>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler>Text Alignment</we-toggler>
+ <we-collapse>
+ <we-button data-cover-opt="text_align" data-select-class="">Left</we-button>
+ <we-button data-cover-opt="text_align" data-select-class="text-center">Centered</we-button>
+ <we-button data-cover-opt="text_align" data-select-class="text-right">Right</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
</xpath>
</template>
@@ -76,31 +76,31 @@
<template id="s_latest_posts_options" inherit_id="website.snippet_options">
<xpath expr="//div[@data-js='background']" position="before">
<div data-js="js_get_posts_selectBlog" data-selector=".s_latest_posts, .s_latest_posts_big_picture" data-target=".js_get_posts" data-no-check="true">
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-folder-open"/>Choose a blog</a>
- <div class="dropdown-menu">
- <a href="#" class="dropdown-item" data-filter-by-blog-id="0" data-no-preview="true">All blogs</a>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-folder-open"/> Choose a blog</we-toggler>
+ <we-collapse>
+ <we-button data-filter-by-blog-id="0" data-no-preview="true">All blogs</we-button>
<!-- the blog list will be generated in js -->
- </div>
- </div>
+ </we-collapse>
+ </we-collapse-area>
</div>
<div data-js="js_get_posts_limit" data-selector=".s_latest_posts, .s_latest_posts_big_picture" data-target=".js_get_posts" data-no-check="true">
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-sort-numeric-asc"/>Posts limit</a>
- <div class="dropdown-menu" data-no-preview="true">
- <a href="#" class="dropdown-item" data-posts-limit="1">1 post max</a>
- <a href="#" class="dropdown-item" data-posts-limit="2">2 posts max</a>
- <a href="#" class="dropdown-item" data-posts-limit="3">3 posts max</a>
- <a href="#" class="dropdown-item" data-posts-limit="4">4 posts max</a>
- <a href="#" class="dropdown-item" data-posts-limit="5">5 posts max</a>
- <a href="#" class="dropdown-item" data-posts-limit="6">6 posts max</a>
- <a href="#" class="dropdown-item" data-posts-limit="7">7 posts max</a>
- <a href="#" class="dropdown-item" data-posts-limit="8">8 posts max</a>
- <a href="#" class="dropdown-item" data-posts-limit="9">9 posts max</a>
- <a href="#" class="dropdown-item" data-posts-limit="10">10 posts max</a>
- </div>
- </div>
+ <we-collapse-area>
+ <we-toggler><i class="fa fa-sort-numeric-asc"/> Posts limit</we-toggler>
+ <we-collapse>
+ <we-button data-posts-limit="1">1 post max</we-button>
+ <we-button data-posts-limit="2">2 posts max</we-button>
+ <we-button data-posts-limit="3">3 posts max</we-button>
+ <we-button data-posts-limit="4">4 posts max</we-button>
+ <we-button data-posts-limit="5">5 posts max</we-button>
+ <we-button data-posts-limit="6">6 posts max</we-button>
+ <we-button data-posts-limit="7">7 posts max</we-button>
+ <we-button data-posts-limit="8">8 posts max</we-button>
+ <we-button data-posts-limit="9">9 posts max</we-button>
+ <we-button data-posts-limit="10">10 posts max</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
</xpath>
<xpath expr="//div[@data-js='layout_column']" position="attributes">
diff --git a/addons/website_form/static/tests/tours/website_form_editor.js b/addons/website_form/static/tests/tours/website_form_editor.js
index ffbbf897922..b489fc33bad 100644
--- a/addons/website_form/static/tests/tours/website_form_editor.js
+++ b/addons/website_form/static/tests/tours/website_form_editor.js
@@ -57,12 +57,8 @@ odoo.define('website_form_editor.tour', function(require) {
trigger: ".s_website_form[data-model_name]"
},
{
- content: "Click on Customize",
- trigger: ".oe_overlay_options [title='Customize']"
- },
- {
content: "Click on Add a model field",
- trigger: ".oe_overlay_options .dropdown-item[data-website_form_field_modal]"
+ trigger: "[data-website_form_field_modal]"
},
{
content: "Select the date field",
@@ -81,12 +77,12 @@ odoo.define('website_form_editor.tour', function(require) {
run: "text Test Date"
},
{
- content: "Click on Customize",
- trigger: ".oe_overlay_options [title='Customize']"
+ content: "Go to the row option",
+ trigger: 'we-customizeblock-options.o_we_closed:last',
},
{
content: "Click on Required",
- trigger: ".oe_overlay_options .dropdown-item[data-website_form_field_require]"
+ trigger: "[data-website_form_field_require]"
},
{
content: "Check the resulting field",
@@ -102,12 +98,8 @@ odoo.define('website_form_editor.tour', function(require) {
trigger: ".s_website_form[data-model_name]"
},
{
- content: "Click on Customize",
- trigger: ".oe_overlay_options [title='Customize']"
- },
- {
content: "Click on Add a model field",
- trigger: ".oe_overlay_options:visible .dropdown-item[data-website_form_field_modal]"
+ trigger: "[data-website_form_field_modal]"
},
{
content: "Select the record_name field",
@@ -126,12 +118,12 @@ odoo.define('website_form_editor.tour', function(require) {
run: "text Awesome Label"
},
{
- content: "Click on Customize",
- trigger: ".oe_overlay_options [title='Customize']"
+ content: "Go to the row option",
+ trigger: 'we-customizeblock-options.o_we_closed:last',
},
{
content: "Click on Hidden",
- trigger: ".oe_overlay_options .dropdown-item[data-toggle-class='o_website_form_field_hidden']"
+ trigger: "[data-toggle-class='o_website_form_field_hidden']"
},
{
content: "Check the resulting field",
@@ -148,12 +140,8 @@ odoo.define('website_form_editor.tour', function(require) {
trigger: ".s_website_form[data-model_name]"
},
{
- content: "Click on Customize",
- trigger: ".oe_overlay_options [title='Customize']"
- },
- {
content: "Click on Add a model field",
- trigger: ".oe_overlay_options .dropdown-item[data-website_form_field_modal]"
+ trigger: "[data-website_form_field_modal]"
},
{
content: "Select the body_html field",
@@ -172,12 +160,12 @@ odoo.define('website_form_editor.tour', function(require) {
run: "text Your Message"
},
{
- content: "Click on Customize",
- trigger: ".oe_overlay_options [title='Customize']"
+ content: "Go to the row option",
+ trigger: 'we-customizeblock-options.o_we_closed:last',
},
{
content: "Click on Required",
- trigger: ".oe_overlay_options .dropdown-item[data-website_form_field_require]"
+ trigger: "[data-website_form_field_require]"
},
{
content: "Check the resulting field",
@@ -193,12 +181,8 @@ odoo.define('website_form_editor.tour', function(require) {
trigger: ".s_website_form[data-model_name]"
},
{
- content: "Click on Customize",
- trigger: ".oe_overlay_options [title='Customize']"
- },
- {
content: "Click on Add a model field",
- trigger: ".oe_overlay_options .dropdown-item[data-website_form_field_modal]"
+ trigger: "[data-website_form_field_modal]"
},
{
content: "Select the recipient_ids field",
@@ -221,17 +205,8 @@ odoo.define('website_form_editor.tour', function(require) {
trigger: ".s_website_form[data-model_name]",
},
{
- content: "Click on Customize",
- trigger: ".oe_overlay_options [title='Customize']",
- run: function (actions) {
- actions.auto();
- // I didn't find any other way to make that submenu element appear
- $(".oe_options .dropdown-submenu .dropdown-menu").css("display", "block");
- }
- },
- {
content: "Click on Multiple Checkboxes in menu Add a custom field",
- trigger: ".oe_options .dropdown-item:contains('Multiple Checkboxes')"
+ trigger: "we-button:contains('Multiple Checkboxes')",
},
// Customize custom multiple checkboxes field
@@ -257,7 +232,7 @@ odoo.define('website_form_editor.tour', function(require) {
},
{
content: "Duplicate Option 3",
- trigger: ".oe_overlay_options:visible .oe_snippet_clone",
+ trigger: ".oe_snippet_clone:last",
},
{
content: "Change first Option 3 label",
@@ -274,12 +249,12 @@ odoo.define('website_form_editor.tour', function(require) {
trigger: ".col-form-label:contains('Products')"
},
{
- content: "Click on Customize",
- trigger: ".oe_overlay_options [title='Customize']"
+ content: "Go to the row option",
+ trigger: 'we-customizeblock-options.o_we_closed:last',
},
{
content: "Click on Required",
- trigger: ".oe_overlay_options .dropdown-item[data-website_form_field_require]"
+ trigger: "[data-website_form_field_require]"
},
{
content: "Check the resulting field",
@@ -298,12 +273,8 @@ odoo.define('website_form_editor.tour', function(require) {
trigger: ".s_website_form[data-model_name]",
},
{
- content: "Click on Customize",
- trigger: ".oe_overlay_options [title='Customize']"
- },
- {
content: "Click on Radio Buttons in menu Add a custom field",
- trigger: ".oe_options .dropdown-item:contains('Radio Buttons')"
+ trigger: "we-button:contains('Radio Buttons')"
},
// Customize Radio Buttons field
@@ -328,7 +299,7 @@ odoo.define('website_form_editor.tour', function(require) {
},
{
content: "Duplicate Option 3",
- trigger: ".oe_overlay_options:visible .oe_snippet_clone",
+ trigger: ".oe_snippet_clone:last",
},
{
content: "Change first Option 3 label",
@@ -345,20 +316,16 @@ odoo.define('website_form_editor.tour', function(require) {
trigger: ".col-form-label:contains('Service')"
},
{
- content: "Click on Customize",
- trigger: ".oe_overlay_options [title='Customize']"
+ content: "Go to the row option",
+ trigger: 'we-customizeblock-options.o_we_closed:last',
},
{
content: "Click on Required",
- trigger: ".oe_overlay_options .dropdown-item[data-website_form_field_require]"
- },
- {
- content: "Click on Customize",
- trigger: ".oe_overlay_options [title='Customize']"
+ trigger: "[data-website_form_field_require]"
},
{
content: "Click on Required",
- trigger: ".oe_overlay_options .dropdown-item[data-website_form_field_require]",
+ trigger: "[data-website_form_field_require]",
extra_trigger: ".form-field.o_website_form_custom.o_website_form_required_custom" +
":has(.col-form-label:contains('Service'))",
},
@@ -378,18 +345,10 @@ odoo.define('website_form_editor.tour', function(require) {
{
content: "Click on Form snippet",
trigger: ".s_website_form[data-model_name]",
- onend: function() {
- // I didn't find any other way to make that submenu element appear
- $(".oe_options > ul > li:has(ul) > ul").css("display", "block");
- }
- },
- {
- content: "Click on Customize",
- trigger: ".oe_overlay_options [title='Customize']"
},
{
content: "Click on Selection in menu Add a custom field",
- trigger: ".oe_options .dropdown-item:contains('Selection')"
+ trigger: "we-button:contains('Selection')",
},
// Customize custom selection field
@@ -414,7 +373,7 @@ odoo.define('website_form_editor.tour', function(require) {
},
{
content: "Duplicate Option 3",
- trigger: ".oe_overlay_options:visible .oe_snippet_clone",
+ trigger: ".oe_snippet_clone:last",
},
{
content: "Change first Option 3 label",
@@ -432,19 +391,19 @@ odoo.define('website_form_editor.tour', function(require) {
},
{
content: "Remove Germany Option",
- trigger: ".oe_overlay_options:visible .oe_snippet_remove",
+ trigger: ".oe_snippet_remove:last",
},
{
content: "Click on field",
trigger: ".col-form-label:contains('State')"
},
{
- content: "Click on Customize",
- trigger: ".oe_overlay_options [title='Customize']"
+ content: "Go to the row option",
+ trigger: 'we-customizeblock-options.o_we_closed:last',
},
{
content: "Click on Required",
- trigger: ".oe_overlay_options .dropdown-item[data-website_form_field_require]"
+ trigger: "[data-website_form_field_require]"
},
{
content: "Check the resulting snippet",
@@ -464,12 +423,8 @@ odoo.define('website_form_editor.tour', function(require) {
trigger: ".s_website_form[data-model_name]"
},
{
- content: "Click on Customize",
- trigger: ".oe_overlay_options [title='Customize']"
- },
- {
content: "Click on Add a model field",
- trigger: ".oe_overlay_options .dropdown-item[data-website_form_field_modal]"
+ trigger: "[data-website_form_field_modal]"
},
{
content: "Select the attachment_ids field",
diff --git a/addons/website_form/views/snippets.xml b/addons/website_form/views/snippets.xml
index b47e02eeda5..c485b64d8c3 100644
--- a/addons/website_form/views/snippets.xml
+++ b/addons/website_form/views/snippets.xml
@@ -30,29 +30,29 @@
<xpath expr="//div" position="after">
<!-- Form -->
<div data-js="website_form_editor" data-selector=".s_website_form">
- <a href="#" class="dropdown-item" data-website_form_model_modal="" data-no-preview="true">Change Form Parameters</a>
- <a href="#" class="dropdown-item" data-website_form_field_modal="" data-no-preview="true">Add an existing field</a>
- <div class="dropdown-submenu">
- <a href="#" class="dropdown-item">Add a custom field</a>
- <div class="dropdown-menu" role="menu" data-no-preview="true">
- <a href="#" class="dropdown-item" role="menuitem" data-website_form_custom_field="char">Text</a>
- <a href="#" class="dropdown-item" role="menuitem" data-website_form_custom_field="text">Long Text</a>
- <a href="#" class="dropdown-item" role="menuitem" data-website_form_custom_field="integer">Number</a>
- <a href="#" class="dropdown-item" role="menuitem" data-website_form_custom_field="float">Decimal Number</a>
- <a href="#" class="dropdown-item" role="menuitem" data-website_form_custom_field="boolean">Checkbox</a>
- <a href="#" class="dropdown-item" role="menuitem" data-website_form_custom_field="selection">Radio Buttons</a>
- <a href="#" class="dropdown-item" role="menuitem" data-website_form_custom_field="many2one">Selection</a>
- <a href="#" class="dropdown-item" role="menuitem" data-website_form_custom_field="one2many">Multiple Checkboxes</a>
- <a href="#" class="dropdown-item" role="menuitem" data-website_form_custom_field="date">Date</a>
- <a href="#" class="dropdown-item" role="menuitem" data-website_form_custom_field="datetime">Date &amp; Time</a>
- <a href="#" class="dropdown-item" role="menuitem" data-website_form_custom_field="binary">File Upload</a>
- </div>
- </div>
+ <we-button data-website_form_model_modal="" data-no-preview="true">Change Form Parameters</we-button>
+ <we-button data-website_form_field_modal="" data-no-preview="true">Add an existing field</we-button>
+ <we-collapse-area>
+ <we-toggler>Add a custom field</we-toggler>
+ <we-collapse data-no-preview="true">
+ <we-button data-website_form_custom_field="char">Text</we-button>
+ <we-button data-website_form_custom_field="text">Long Text</we-button>
+ <we-button data-website_form_custom_field="integer">Number</we-button>
+ <we-button data-website_form_custom_field="float">Decimal Number</we-button>
+ <we-button data-website_form_custom_field="boolean">Checkbox</we-button>
+ <we-button data-website_form_custom_field="selection">Radio Buttons</we-button>
+ <we-button data-website_form_custom_field="many2one">Selection</we-button>
+ <we-button data-website_form_custom_field="one2many">Multiple Checkboxes</we-button>
+ <we-button data-website_form_custom_field="date">Date</we-button>
+ <we-button data-website_form_custom_field="datetime">Date &amp; Time</we-button>
+ <we-button data-website_form_custom_field="binary">File Upload</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
<!-- Field -->
<div data-js='website_form_editor' data-selector=".form-field" data-drop-near=".form-field">
- <a href="#" class="dropdown-item" data-toggle-class="o_website_form_field_hidden" data-no-preview="true">Hidden</a>
+ <we-button data-toggle-class="o_website_form_field_hidden" data-no-preview="true">Hidden</we-button>
</div>
<!-- Add move, duplicate and remove controllers to checkboxes and radio buttons -->
@@ -63,7 +63,7 @@
<!-- Required option for fields that are not required fields of the model -->
<div data-js='website_form_editor_field' data-selector=".form-field:not(.o_website_form_required)">
- <a href="#" class="dropdown-item" data-website_form_field_require="" data-toggle-class="o_website_form_required_custom" data-no-preview="true">Required</a>
+ <we-button data-website_form_field_require="" data-toggle-class="o_website_form_required_custom" data-no-preview="true">Required</we-button>
</div>
<!-- Remove the duplicate options of model fields -->
diff --git a/addons/website_mass_mailing/static/src/scss/website_mass_mailing.editor.scss b/addons/website_mass_mailing/static/src/scss/website_mass_mailing.editor.scss
index 83c45749d6d..11de90aeb0f 100644
--- a/addons/website_mass_mailing/static/src/scss/website_mass_mailing.editor.scss
+++ b/addons/website_mass_mailing/static/src/scss/website_mass_mailing.editor.scss
@@ -1,7 +1,7 @@
.editor_enable {
.o_newsletter_modal {
// set z-index so customize options visible on dialog.
- z-index: $o-wysiwyg-zindex - 2;
+ z-index: $o-we-overlay-zindex - 5;
// just for fake backdrop effect
background-color: rgba(66, 66, 66, 0.4);
}
diff --git a/addons/website_sale/static/src/js/website_sale.editor.js b/addons/website_sale/static/src/js/website_sale.editor.js
index 507ee92882e..e4f271604b5 100644
--- a/addons/website_sale/static/src/js/website_sale.editor.js
+++ b/addons/website_sale/static/src/js/website_sale.editor.js
@@ -205,10 +205,10 @@ options.registry.WebsiteSaleProductsItem = options.Class.extend({
model: 'product.style',
method: 'search_read',
}).then(function (data) {
- var $ul = self.$el.find('div[name="style"]');
+ var $ul = self.$el.find('[name="style"]');
for (var k in data) {
$ul.append(
- $('<a class="dropdown-item" role="menuitem" data-style="' + data[k]['id'] + '" data-toggle-class="' + data[k]['html_class'] + '"/>')
+ $('<we-button data-style="' + data[k]['id'] + '" data-toggle-class="' + data[k]['html_class'] + '"/>')
.append(data[k]['name'])
);
}
@@ -222,7 +222,7 @@ options.registry.WebsiteSaleProductsItem = options.Class.extend({
*/
onFocus: function () {
var listLayoutEnabled = this.$target.closest('#products_grid').hasClass('o_wsale_layout_list');
- this.$el.find('.o_wsale_soptions_menu_sizes').closest('.dropdown-submenu')
+ this.$el.find('.o_wsale_soptions_menu_sizes').closest('we-collapse-area')
.toggleClass('d-none', listLayoutEnabled);
},
diff --git a/addons/website_sale/static/src/scss/website_sale.editor.scss b/addons/website_sale/static/src/scss/website_sale.editor.scss
index 2697fcae9e2..9a4f59d52f0 100644
--- a/addons/website_sale/static/src/scss/website_sale.editor.scss
+++ b/addons/website_sale/static/src/scss/website_sale.editor.scss
@@ -1,12 +1,12 @@
.o_wsale_soptions_menu_sizes {
table {
- margin-left: 20px;
+ margin: auto;
td {
margin: 0;
padding: 0;
- width: 20px;
- height: 20px;
+ width: 40px;
+ height: 40px;
border: 1px #dddddd solid;
cursor: pointer;
diff --git a/addons/website_sale/views/snippets.xml b/addons/website_sale/views/snippets.xml
index 0391a2fdcf9..17b8ebf69e7 100644
--- a/addons/website_sale/views/snippets.xml
+++ b/addons/website_sale/views/snippets.xml
@@ -43,27 +43,27 @@
<div data-js="WebsiteSaleGridLayout"
data-selector="#products_grid .o_wsale_products_grid_table_wrapper > table"
data-no-check="true">
- <a href="#" class="dropdown-item" role="menuitem" data-no-preview="true" data-choose-ppg="1">
- <i class="fa fa-cart-plus"/>Choose number of products
- </a>
- <div class="dropdown-submenu o_wsale_ppr_submenu" role="menuitem" aria-haspopup="true">
- <a tabindex="-1" href="#" class="dropdown-item" role="menuitem">
- <i class="fa fa-columns"/>Number of Columns
- </a>
- <div class="dropdown-menu" role="menu" data-no-preview="true">
- <a href="#" class="dropdown-item" role="menuitem" data-set-ppr="2">2</a>
- <a href="#" class="dropdown-item" role="menuitem" data-set-ppr="3">3</a>
- <a href="#" class="dropdown-item" role="menuitem" data-set-ppr="4">4</a>
- </div>
- </div>
+ <we-button data-no-preview="true" data-choose-ppg="1">
+ <i class="fa fa-cart-plus"/> Choose number of products
+ </we-button>
+ <we-collapse-area class="o_wsale_ppr_submenu">
+ <we-toggler>
+ <i class="fa fa-columns"/> Number of Columns
+ </we-toggler>
+ <we-collapse data-no-preview="true">
+ <we-button data-set-ppr="2">2</we-button>
+ <we-button data-set-ppr="3">3</we-button>
+ <we-button data-set-ppr="4">4</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
<div data-js="WebsiteSaleProductsItem"
data-selector="#products_grid .oe_product"
data-no-check="true">
- <div class="dropdown-submenu">
- <a tabindex="-1" href="#" class="dropdown-item">Size</a>
- <div class="dropdown-menu o_wsale_soptions_menu_sizes" role="menu">
+ <we-collapse-area>
+ <we-toggler>Size</we-toggler>
+ <we-collapse class="o_wsale_soptions_menu_sizes">
<table>
<tr>
<td/><td/><td/><td/>
@@ -78,29 +78,31 @@
<td/><td/><td/><td/>
</tr>
</table>
- </div>
- </div>
- <div class='dropdown-submenu' role="menuitem" aria-haspopup="true">
- <a tabindex="-1" href="#" class="dropdown-item">Styles</a>
- <div class="dropdown-menu" role="menu" data-no-preview="true" name="style"/>
- </div>
- <div class='dropdown-submenu' role="menuitem" aria-haspopup="true">
- <a tabindex="-1" href="#" class="dropdown-item">Promote</a>
- <div class="dropdown-menu" role="menu" data-no-preview="true">
- <a href="#" class="dropdown-item" role="menuitem" data-change-sequence="top">Push to top</a>
- <a href="#" class="dropdown-item" role="menuitem" data-change-sequence="up">Push up</a>
- <a href="#" class="dropdown-item" role="menuitem" data-change-sequence="down">Push down</a>
- <a href="#" class="dropdown-item" role="menuitem" data-change-sequence="bottom">Push to bottom</a>
- </div>
- </div>
+ </we-collapse>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler>Styles</we-toggler>
+ <we-collapse data-no-preview="true" name="style"/>
+ </we-collapse-area>
+ <we-collapse-area>
+ <we-toggler>Promote</we-toggler>
+ <we-collapse data-no-preview="true">
+ <we-button data-change-sequence="top">Push to top</we-button>
+ <we-button data-change-sequence="up">Push up</we-button>
+ <we-button data-change-sequence="down">Push down</we-button>
+ <we-button data-change-sequence="bottom">Push to bottom</we-button>
+ </we-collapse>
+ </we-collapse-area>
</div>
<div data-js="ProductsSearchBar"
data-selector=".s_wsale_products_searchbar_input">
- <a tabindex="-1" href="#" class="dropdown-item" data-no-preview="true" data-open-searchbar-settings=""><i class="fa fa-search"></i>Products Search Bar</a>
+ <we-button data-no-preview="true" data-open-searchbar-settings="">
+ <i class="fa fa-search"/> Products Search Bar
+ </we-button>
</div>
</xpath>
- <xpath expr="//div[@data-js='content']" position="attributes">
+ <xpath expr="//div[@id='so_content_addition']" position="attributes">
<attribute name="data-selector" add=".s_wsale_products_searchbar_input" separator=","/>
<attribute name="data-drop-near" add=".s_wsale_products_searchbar_input" separator=","/>
</xpath>