summaryrefslogtreecommitdiff
path: root/addons/website/static/src/js/widgets/theme.js
diff options
context:
space:
mode:
Diffstat (limited to 'addons/website/static/src/js/widgets/theme.js')
-rw-r--r--addons/website/static/src/js/widgets/theme.js582
1 files changed, 392 insertions, 190 deletions
diff --git a/addons/website/static/src/js/widgets/theme.js b/addons/website/static/src/js/widgets/theme.js
index 36f59a23762..a5e0731e4b0 100644
--- a/addons/website/static/src/js/widgets/theme.js
+++ b/addons/website/static/src/js/widgets/theme.js
@@ -3,26 +3,118 @@ odoo.define('website.theme', function (require) {
var config = require('web.config');
var core = require('web.core');
-var ColorpickerDialog = require('wysiwyg.widgets.ColorpickerDialog');
var Dialog = require('web.Dialog');
+var Widget = require('web.Widget');
var weWidgets = require('wysiwyg.widgets');
+var ColorpickerDialog = require('wysiwyg.widgets.ColorpickerDialog');
var websiteNavbarData = require('website.navbar');
var _t = core._t;
var templateDef = null;
+var QuickEdit = Widget.extend({
+ xmlDependencies: ['/website/static/src/xml/website.editor.xml'],
+ template: 'website.theme_customize_active_input',
+ events: {
+ 'keydown input': '_onInputKeydown',
+ 'click .btn-primary': '_onSaveClick',
+ 'click .btn-secondary': '_onResetClick',
+ },
+
+ /**
+ * @constructor
+ */
+ init: function (parent, value, unit) {
+ this._super.apply(this, arguments);
+ this.value = value;
+ this.unit = unit;
+ },
+ /**
+ * @override
+ */
+ start: function () {
+ this.$input = this.$('input');
+ this.$input.select();
+ return this._super.apply(this, arguments);
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @param {string} [value]
+ */
+ _save: function (value) {
+ if (value === undefined) {
+ value = parseFloat(this.$input.val());
+ value = isNaN(value) ? 'null' : (value + this.unit);
+ }
+ this.trigger_up('QuickEdit:save', {
+ value: value,
+ });
+ this.destroy();
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @param {Event} ev
+ */
+ _onInputKeydown: function (ev) {
+ var inputValue = this.$input.val();
+ var value = 0;
+ if (inputValue !== '') {
+ value = parseFloat(this.$input.val());
+ if (isNaN(value)) {
+ return;
+ }
+ }
+ switch (ev.which) {
+ case $.ui.keyCode.UP:
+ this.$input.val(value + 1);
+ break;
+ case $.ui.keyCode.DOWN:
+ this.$input.val(value - 1);
+ break;
+ case $.ui.keyCode.ENTER:
+ // Do not listen to change events, we want the user to be able
+ // to confirm in all cases.
+ this._save();
+ break;
+ }
+ },
+ /**
+ * @private
+ */
+ _onSaveClick: function () {
+ this._save();
+ },
+ /**
+ * @private
+ */
+ _onResetClick: function () {
+ this._save('null');
+ },
+});
+
var ThemeCustomizeDialog = Dialog.extend({
xmlDependencies: (Dialog.prototype.xmlDependencies || [])
.concat(['/website/static/src/xml/website.editor.xml']),
template: 'website.theme_customize',
events: {
- 'change [data-xmlid], [data-enable], [data-disable]': '_onChange',
- 'click .checked [data-xmlid], .checked [data-enable], .checked [data-disable]': '_onChange',
- 'click .o_theme_customize_color': '_onColorClick',
+ 'change .o_theme_customize_option_input': '_onChange',
+ 'click .checked .o_theme_customize_option_input[type="radio"]': '_onChange',
},
+ CUSTOM_BODY_IMAGE_XML_ID: 'option_custom_body_image',
+
/**
* @constructor
*/
@@ -58,29 +150,53 @@ var ThemeCustomizeDialog = Dialog.extend({
*/
start: function () {
var self = this;
- this._generateDialogHTML();
+
+ this.PX_BY_REM = parseFloat($(document.documentElement).css('font-size'));
+
this.$modal.addClass('o_theme_customize_modal');
+ this.style = window.getComputedStyle(document.documentElement);
+
+ var $tabs;
+ var loadDef = this._loadViews().then(function (data) {
+ self._generateDialogHTML(data);
+ $tabs = self.$('[data-toggle="tab"]');
+
+ // Hide the tab navigation if only one tab
+ if ($tabs.length <= 1) {
+ $tabs.closest('.nav').addClass('d-none');
+ }
+ });
+
// Enable the first option tab or the given default tab
- var $tabs = this.$('[data-toggle="tab"]');
this.opened().then(function () {
$tabs.eq(self.defaultTab).tab('show');
- var $colorPreview = self.$('.o_theme_customize_color_previews:visible');
- var $primary = $colorPreview.find('.o_theme_customize_color[data-color="primary"]');
- var $alpha = $colorPreview.find('.o_theme_customize_color[data-color="alpha"]');
- var $secondary = $colorPreview.find('.o_theme_customize_color[data-color="secondary"]');
- var $beta = $colorPreview.find('.o_theme_customize_color[data-color="beta"]');
- var sameAlphaPrimary = $primary.find('.o_color_preview').css('background-color') === $alpha.find('.o_color_preview').css('background-color');
- var sameBetaSecondary = $secondary.find('.o_color_preview').css('background-color') === $beta.find('.o_color_preview').css('background-color');
+ // Hack to hide primary/secondary if they are equal to alpha/beta
+ // (this is the case with default values but not in some themes).
+ var $primary = self.$('.o_theme_customize_color[data-color="primary"]');
+ var $alpha = self.$('.o_theme_customize_color[data-color="alpha"]');
+ var $secondary = self.$('.o_theme_customize_color[data-color="secondary"]');
+ var $beta = self.$('.o_theme_customize_color[data-color="beta"]');
+
+ var sameAlphaPrimary = $primary.css('background-color') === $alpha.css('background-color');
+ var sameBetaSecondary = $secondary.css('background-color') === $beta.css('background-color');
+
if (!sameAlphaPrimary) {
- $alpha.find('.o_color_name').text(_t("Extra Color"));
- $primary.removeClass('d-none').addClass('d-flex');
+ $alpha.prev().text(_t("Extra Color"));
}
if (!sameBetaSecondary) {
- $beta.find('.o_color_name').text(_t("Extra Color"));
- $secondary.removeClass('d-none').addClass('d-flex');
+ $beta.prev().text(_t("Extra Color"));
}
+
+ $primary = $primary.closest('.o_theme_customize_option');
+ $alpha = $alpha.closest('.o_theme_customize_option');
+ $secondary = $secondary.closest('.o_theme_customize_option');
+ $beta = $beta.closest('.o_theme_customize_option');
+
+ $primary.toggleClass('d-none', sameAlphaPrimary);
+ $secondary.toggleClass('d-none', sameBetaSecondary);
+
if (!sameAlphaPrimary && sameBetaSecondary) {
$beta.insertBefore($alpha);
} else if (sameAlphaPrimary && !sameBetaSecondary) {
@@ -88,17 +204,7 @@ var ThemeCustomizeDialog = Dialog.extend({
}
});
- // Hide the tab navigation if only one tab
- if ($tabs.length <= 1) {
- $tabs.closest('.nav').addClass('d-none');
- }
-
- this.$inputs = this.$('[data-xmlid], [data-enable], [data-disable]');
-
- return $.when(
- this._super.apply(this, arguments),
- this._loadViews()
- );
+ return $.when(this._super.apply(this, arguments), loadDef);
},
//--------------------------------------------------------------------------
@@ -108,7 +214,47 @@ var ThemeCustomizeDialog = Dialog.extend({
/**
* @private
*/
- _generateDialogHTML: function () {
+ _chooseBodyCustomImage: function () {
+ var self = this;
+ var def = $.Deferred();
+ var $image = $('<img/>');
+ var editor = new weWidgets.MediaDialog(this, {
+ onlyImages: true,
+ firstFilters: ['background'],
+ }, $image[0]);
+
+ editor.on('save', this, function (media) { // TODO use scss customization instead (like for user colors)
+ var src = $(media).attr('src');
+ self._rpc({
+ model: 'ir.model.data',
+ method: 'get_object_reference',
+ args: ['website', this.CUSTOM_BODY_IMAGE_XML_ID],
+ }).then(function (data) {
+ return self._rpc({
+ model: 'ir.ui.view',
+ method: 'save',
+ args: [
+ data[1],
+ '#wrapwrap { background-image: url("' + src + '"); }',
+ '//style',
+ ],
+ });
+ }).always(def.resolve.bind(def));
+ });
+ editor.on('cancel', this, function () {
+ def.resolve();
+ });
+
+ editor.open();
+
+ return def;
+ },
+ /**
+ * @private
+ * @param {Object} data - @see this._loadViews
+ */
+ _generateDialogHTML: function (data) {
+ var self = this;
var $contents = this.$el.children('content');
if ($contents.length === 0) {
return;
@@ -148,8 +294,21 @@ var ThemeCustomizeDialog = Dialog.extend({
this.$('[title]').tooltip();
+ this.$inputs = self.$('.o_theme_customize_option_input');
+ // Enable data-xmlid="" inputs if none of their neighbors were enabled
+ _.each(this.$inputs.filter('[data-xmlid=""]'), function (input) {
+ var $input = $(input);
+ var $neighbors = self.$inputs.filter('[name="' + $input.attr('name') + '"]').not($input);
+ if ($neighbors.length && !$neighbors.filter(':checked').length) {
+ $input.prop('checked', true);
+ }
+ });
+ this._setActive();
+ this._updateValues();
+
function _processItems($items, $container) {
var optionsName = _.uniqueId('option-');
+ var alone = ($items.length === 1);
_.each($items, function (item) {
var $item = $(item);
@@ -159,37 +318,47 @@ var ThemeCustomizeDialog = Dialog.extend({
case 'OPT':
var widgetName = $item.data('widget');
- // Build the options template
- var $option = $(core.qweb.render('website.theme_customize_modal_option', {
- name: optionsName,
- id: $item.attr('id') || _.uniqueId('o_theme_customize_input_id_'),
+ var xmlid = $item.data('xmlid');
- string: $item.attr('string'),
+ var renderingOptions = _.extend({
+ string: $item.attr('string') || data.names[xmlid.split(',')[0].trim()],
icon: $item.data('icon'),
font: $item.data('font'),
+ }, $item.data());
- xmlid: $item.data('xmlid'),
- enable: $item.data('enable'),
- disable: $item.data('disable'),
- reload: $item.data('reload'),
-
+ // Build the options template
+ var $option = $(core.qweb.render('website.theme_customize_modal_option', _.extend({
+ alone: alone,
+ name: xmlid === undefined ? _.uniqueId('option-') : optionsName,
+ id: $item.attr('id') || _.uniqueId('o_theme_customize_input_id_'),
+ checked: xmlid === undefined || xmlid && (!_.difference(self._getXMLIDs($item), data.enabled).length),
widget: widgetName,
- }));
+ }, renderingOptions)));
+ $option.find('input')
+ .addClass('o_theme_customize_option_input')
+ .attr({
+ 'data-xmlid': xmlid,
+ 'data-enable': $item.data('enable'),
+ 'data-disable': $item.data('disable'),
+ 'data-reload': $item.data('reload'),
+ });
if (widgetName) {
- var $widget = $(core.qweb.render('website.theme_customize_' + widgetName));
- $option.append($widget);
+ var $widget = $(core.qweb.render('website.theme_customize_widget_' + widgetName, renderingOptions));
+ $option.find('label').append($widget);
}
+ var $final;
if ($container.hasClass('form-row')) {
- $col = $('<div/>', {
+ $final = $('<div/>', {
class: _.str.sprintf('col-%s', $item.data('col') || 6),
});
- $col.append($option);
- $container.append($col);
+ $final.append($option);
} else {
- $container.append($option);
+ $final = $option;
}
+ $final.attr('data-depends', $item.data('depends'));
+ $container.append($final);
break;
case 'LIST':
@@ -201,6 +370,10 @@ var ThemeCustomizeDialog = Dialog.extend({
$container.append($col);
_processItems($item.children(), $listContainer);
break;
+
+ default:
+ _processItems($item.children(), $container);
+ break;
}
});
}
@@ -209,29 +382,11 @@ var ThemeCustomizeDialog = Dialog.extend({
* @private
*/
_loadViews: function () {
- var self = this;
return this._rpc({
route: '/website/theme_customize_get',
params: {
- xml_ids: this._getXMLIDs(this.$inputs),
+ 'xml_ids': this._getXMLIDs(this.$inputs || this.$('[data-xmlid]')),
},
- }).done(function (data) {
- self.$inputs.prop('checked', false);
- _.each(self.$inputs.filter('[data-xmlid]:not([data-xmlid=""])'), function (input) {
- var $input = $(input);
- if (!_.difference(self._getXMLIDs($input), data[0]).length) {
- $input.prop('checked', true);
- }
- });
- _.each(self.$inputs.filter('[data-xmlid=""]'), function (input) {
- var $input = $(input);
- if (!self.$inputs.filter('[name="' + $input.attr('name') + '"]:checked').length) {
- $input.prop('checked', true);
- }
- });
- self._setActive();
- }).fail(function (d, error) {
- Dialog.alert(this, error.data.message);
});
},
/**
@@ -260,63 +415,126 @@ var ThemeCustomizeDialog = Dialog.extend({
/**
* @private
*/
- _processChange: function ($inputs) {
+ _makeSCSSCusto: function (url, values) {
+ return this._rpc({
+ route: '/website/make_scss_custo',
+ params: {
+ 'url': url,
+ 'values': values,
+ },
+ });
+ },
+ /**
+ * @private
+ */
+ _pickColor: function (colorElement) {
var self = this;
- this.$modal.addClass('o_theme_customize_loading');
-
- var bodyCustomImageXMLID = 'option_custom_body_image';
- var $inputBodyCustomImage = $inputs.filter('[data-xmlid*="website.' + bodyCustomImageXMLID + '"]:checked');
- if (!$inputBodyCustomImage.length) {
- return $.when();
- }
+ var $color = $(colorElement);
+ var colorName = $color.data('color');
+ var colorType = $color.data('colorType');
var def = $.Deferred();
- var $image = $('<img/>');
- var editor = new weWidgets.MediaDialog(this, {
- onlyImages: true,
- firstFilters: ['background'],
- }, $image[0]);
- editor.on('save', this, function (media) { // TODO use scss customization instead (like for user colors)
- var src = $(media).attr('src');
- self._rpc({
- model: 'ir.model.data',
- method: 'get_object_reference',
- args: ['website', bodyCustomImageXMLID],
- }).then(function (data) {
- return self._rpc({
- model: 'ir.ui.view',
- method: 'save',
- args: [
- data[1],
- '#wrapwrap { background-image: url("' + src + '"); }',
- '//style',
- ],
- });
- }).then(function () {
- def.resolve();
- });
+ var colorpicker = new ColorpickerDialog(this, {
+ defaultColor: $color.css('background-color'),
});
- editor.on('cancel', this, function () {
- def.resolve();
+ var chosenColor = undefined;
+ colorpicker.on('colorpicker:saved', this, function (ev) {
+ ev.stopPropagation();
+ chosenColor = ev.data.cssColor;
});
+ colorpicker.on('closed', this, function (ev) {
+ if (chosenColor === undefined) {
+ def.resolve();
+ return;
+ }
- editor.open();
+ var baseURL = '/website/static/src/scss/options/colors/';
+ var url = _.str.sprintf('%suser_%scolor_palette.scss', baseURL, (colorType ? (colorType + '_') : ''));
+
+ var colors = {};
+ colors[colorName] = chosenColor;
+ if (colorName === 'alpha') {
+ colors['beta'] = 'null';
+ colors['gamma'] = 'null';
+ colors['delta'] = 'null';
+ colors['epsilon'] = 'null';
+ }
+
+ self._makeSCSSCusto(url, colors).always(def.resolve.bind(def));
+ });
+ colorpicker.open();
return def;
},
/**
* @private
*/
+ _processChange: function ($inputs) {
+ var self = this;
+ var defs = [];
+
+ var $options = $inputs.closest('.o_theme_customize_option');
+
+ // Handle body image changes
+ var $bodyImageInputs = $inputs.filter('[data-xmlid*="website.' + this.CUSTOM_BODY_IMAGE_XML_ID + '"]:checked');
+ defs = defs.concat(_.map($bodyImageInputs, function () {
+ return self._chooseBodyCustomImage();
+ }));
+
+ // Handle color changes
+ var $colors = $options.find('.o_theme_customize_color');
+ defs = defs.concat(_.map($colors, function (colorElement) {
+ return self._pickColor($(colorElement));
+ }));
+
+ // Handle input changes
+ var $inputsData = $options.find('.o_theme_customize_input');
+ defs = defs.concat(_.map($inputsData, function (inputData, i) {
+ return self._quickEdit($(inputData));
+ }));
+
+ return $.when.apply($, defs);
+ },
+ /**
+ * @private
+ */
+ _quickEdit: function ($inputData) {
+ var text = $inputData.text().trim();
+ var value = parseFloat(text) || '';
+ var unit = text.match(/([^\s\d]+)$/)[1];
+
+ var def = $.Deferred();
+ var qEdit = new QuickEdit(this, value, unit);
+ qEdit.on('QuickEdit:save', this, function (ev) {
+ ev.stopPropagation();
+
+ var value = ev.data.value;
+ // Convert back to rem if needed
+ if ($inputData.data('unit') === 'rem' && unit === 'px' && value !== 'null') {
+ value = parseFloat(value) / this.PX_BY_REM + 'rem';
+ }
+
+ var values = {};
+ values[$inputData.data('value')] = value;
+ this._makeSCSSCusto('/website/static/src/scss/options/user_values.scss', values)
+ .always(def.resolve.bind(def));
+ });
+ qEdit.appendTo($inputData.closest('.o_theme_customize_option'));
+ return def;
+ },
+ /**
+ * @private
+ */
_setActive: function () {
var self = this;
// Look at all options to see if they are enabled or disabled
- var $enable = this.$inputs.filter('[data-xmlid]:checked');
+ var $enable = this.$inputs.filter(':checked');
// Mark the labels as checked accordingly
this.$('label').removeClass('checked');
- $enable.closest('label').addClass('checked');
+ $enable.closest('label:not(.o_switch)').addClass('checked');
// Mark the option sets as checked if all their option are checked/unchecked
var $sets = this.$inputs.filter('[data-enable], [data-disable]').not('[data-xmlid]');
@@ -329,15 +547,21 @@ var ThemeCustomizeDialog = Dialog.extend({
if (self._getInputs($set.data('disable')).filter(':checked').length) {
checked = false;
}
- $set.prop('checked', checked).closest('label').toggleClass('checked', checked);
+ $set.prop('checked', checked).closest('label:not(.o_switch)').toggleClass('checked', checked);
});
// Make the hidden sections visible if their dependencies are met
_.each(this.$('[data-depends]'), function (hidden) {
var $hidden = $(hidden);
var depends = $hidden.data('depends');
- var nbDependencies = depends ? depends.split(',').length : 0;
- var enabled = self._getInputs(depends).filter(':checked').length === nbDependencies;
+ var dependencies = depends ? depends.split(/\s*,\s*/g) : [];
+ var enabled = _.all(dependencies, function (dep) {
+ var toBeChecked = (dep[0] !== '!');
+ if (!toBeChecked) {
+ dep = dep.substr(1);
+ }
+ return self._getInputs(dep).is(':checked') === toBeChecked;
+ });
$hidden.toggleClass('d-none', !enabled);
});
},
@@ -345,6 +569,11 @@ var ThemeCustomizeDialog = Dialog.extend({
* @private
*/
_updateStyle: function (enable, disable, reload) {
+ var self = this;
+
+ var $loading = $('<i/>', {class: 'fa fa-refresh fa-spin'});
+ this.$modal.find('.modal-title').append($loading);
+
if (reload || config.debug === 'assets') {
window.location.href = $.param.querystring('/website/theme_customize_reload', {
href: window.location.href,
@@ -355,18 +584,19 @@ var ThemeCustomizeDialog = Dialog.extend({
return $.Deferred();
}
- var self = this;
return this._rpc({
route: '/website/theme_customize',
params: {
- enable: enable,
- disable: disable,
- get_bundle: true,
+ 'enable': enable,
+ 'disable': disable,
+ 'get_bundle': true,
},
}).then(function (bundles) {
+ var $allLinks = $();
var defs = _.map(bundles, function (bundleContent, bundleName) {
var linkSelector = 'link[href*="' + bundleName + '"]';
var $links = $(linkSelector);
+ $allLinks = $allLinks.add($links);
var $newLinks = $(bundleContent).filter(linkSelector);
var linksLoaded = $.Deferred();
@@ -382,14 +612,51 @@ var ThemeCustomizeDialog = Dialog.extend({
window.location.reload();
});
$links.last().after($newLinks);
- return linksLoaded.then(function () {
- $links.remove();
- });
+ return linksLoaded;
});
-
- return $.when.apply($, defs).then(function () {
- self.$modal.removeClass('o_theme_customize_loading');
+ return $.when.apply($, defs).always(function () {
+ $loading.remove();
+ $allLinks.remove();
});
+ }).then(function () {
+ // Some animations may depend on the variables that were
+ // customized, so we have to restart them.
+ self.trigger_up('animation_start_demand');
+ });
+ },
+ /**
+ * @private
+ */
+ _updateValues: function () {
+ var self = this;
+ // Put user values
+ _.each(this.$('.o_theme_customize_color'), function (el) {
+ var $el = $(el);
+ var value = self.style.getPropertyValue('--' + $el.data('color')).trim();
+ $el.css('background-color', value);
+ });
+ _.each(this.$('.o_theme_customize_input'), function (el) {
+ var $el = $(el);
+ var value = self.style.getPropertyValue('--' + $el.data('value')).trim();
+
+ // Convert rem values to px values
+ if (_.str.endsWith(value, 'rem')) {
+ value = parseFloat(value) * self.PX_BY_REM + 'px';
+ }
+
+ var $span = $el.find('span');
+ $span.removeClass().text('');
+ switch (value) {
+ case '':
+ case 'false':
+ case 'true':
+ // When null or a boolean value, shows an icon which tells
+ // the user that there is no numeric/text value
+ $span.addClass('fa fa-ban text-danger');
+ break;
+ default:
+ $span.text(value);
+ }
});
},
@@ -406,6 +673,11 @@ var ThemeCustomizeDialog = Dialog.extend({
// Checkout the option that changed
var $option = $(ev.currentTarget);
+ if ($option.is(':disabled')) {
+ return;
+ }
+ this.$inputs.prop('disabled', true);
+
var $options = $option;
var checked = $option.is(':checked');
@@ -437,91 +709,21 @@ var ThemeCustomizeDialog = Dialog.extend({
// Update the style according to the whole set of options
self._processChange($options).then(function () {
- self._updateStyle(
+ return self._updateStyle(
self._getXMLIDs($enable),
self._getXMLIDs($disable),
$option.data('reload') && window.location.href.match(new RegExp($option.data('reload')))
);
+ }).then(function () {
+ self._updateValues();
+ self.$inputs.prop('disabled', false);
});
},
- /**
- * @private
- * @param {Event} ev
- */
- _onColorClick: function (ev) {
- var self = this;
- var $color = $(ev.currentTarget);
- var colorName = $color.data('color');
- var colorType = $color.data('colorType');
-
- var colorpicker = new ColorpickerDialog(this, {
- defaultColor: $color.find('.o_color_preview').css('background-color'),
- });
- colorpicker.on('colorpicker:saved', this, function (ev) {
- ev.stopPropagation();
-
- // TODO improve to be more efficient
- self._rpc({
- route: '/web_editor/get_assets_editor_resources',
- params: {
- key: 'website.layout',
- get_views: false,
- get_scss: true,
- get_js: false,
- bundles: false,
- bundles_restriction: [],
- only_user_custom_files: false,
- },
- }).then(function (data) {
- var files = data.scss[0][1];
- var file = _.find(files, function (file) {
- var baseURL = '/website/static/src/scss/options/colors/';
- return file.url === _.str.sprintf('%suser_%scolor_palette.scss', baseURL, (colorType ? (colorType + '_') : ''));
- });
-
- var colors = {};
- colors[colorName] = ev.data.cssColor;
- if (colorName === 'alpha') {
- colors['beta'] = 'null';
- colors['gamma'] = 'null';
- colors['delta'] = 'null';
- colors['epsilon'] = 'null';
- }
-
- var updatedFileContent = file.arch;
- _.each(colors, function (colorValue, colorName) {
- var pattern = _.str.sprintf("'%s': %%s,\n", colorName);
- var regex = new RegExp(_.str.sprintf(pattern, ".+"));
- var replacement = _.str.sprintf(pattern, colorValue);
- if (regex.test(updatedFileContent)) {
- updatedFileContent = updatedFileContent
- .replace(regex, replacement);
- } else {
- updatedFileContent = updatedFileContent
- .replace(/( *)(.*hook.*)/, _.str.sprintf('$1%s$1$2', replacement));
- }
- });
-
- return self._rpc({
- route: '/web_editor/save_scss_or_js',
- params: {
- url: file.url,
- bundle_xmlid: 'web.assets_common',
- content: updatedFileContent,
- file_type: 'scss',
- },
- });
- }).then(function () {
- return self._updateStyle();
- });
- });
- colorpicker.open();
- },
});
var ThemeCustomizeMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({
actions: _.extend({}, websiteNavbarData.WebsiteNavbarActionWidget.prototype.actions || {}, {
- customize_theme: '_openThemeCustomizeDialog',
+ 'customize_theme': '_openThemeCustomizeDialog',
}),
/**