[FIX] web_editor: allow a snippet to use the same option multiple times

If two snippet options are declared using the same data-js="..." and
that they end up targeting the same snippet in some cases, only one of
those two snippet options was shown.

This case occurred in a theme (avantgarde) for the map snippet.

closes odoo/odoo#38551

X-original-commit: 2072bfd9981eebc8c8d8d03d2f44f0e4a2489692
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
fw-bot
2019-10-11 22:35:19 +00:00
parent 1049fabfa6
commit 817ce6bd6b
@@ -384,7 +384,14 @@ var SnippetEditor = Widget.extend({
val.data,
this.options
);
this.styles[optionName || _.uniqueId('option')] = option;
var key = optionName || _.uniqueId('option');
if (this.styles[key]) {
// If two snippet options use the same option name (and so use
// the same JS option), store the subsequent ones with a unique
// ID (TODO improve)
key = _.uniqueId(key);
}
this.styles[key] = option;
option.__order = i++;
var $optionSection = $(core.qweb.render('web_editor.customize_block_option'));
$optionSection.append($el);
@@ -581,27 +588,35 @@ var SnippetEditor = Widget.extend({
* @param {OdooEvent} ev
*/
_onOptionUpdate: function (ev) {
var self = this;
// If multiple option names are given, we suppose it should not be
// propagated to parent editor
if (ev.data.optionNames) {
ev.stopPropagation();
var self = this;
_.each(ev.data.optionNames, function (name) {
var option = self.styles[name];
if (option) {
option.notify(ev.data.name, ev.data.data);
}
notifyForEachMatchedOption(name);
});
}
// If one option name is given, we suppose it should be handle by the
// first parent editor which can do it
if (ev.data.optionName) {
var option = this.styles[ev.data.optionName];
if (option) {
if (notifyForEachMatchedOption(ev.data.optionName)) {
ev.stopPropagation();
option.notify(ev.data.name, ev.data.data);
}
}
function notifyForEachMatchedOption(name) {
var regex = new RegExp('^' + name + '\\d+$');
var hasOption = false;
for (var key in self.styles) {
if (key === name || regex.test(key)) {
self.styles[key].notify(ev.data.name, ev.data.data);
hasOption = true;
}
}
return hasOption;
}
},
/**
* Called when the 'remove' button is clicked.