odoo.define('website.theme', function (require) { 'use strict'; var ajax = require('web.ajax'); var core = require('web.core'); var session = require('web.session'); var Widget = require('web.Widget'); var weContext = require('web_editor.context'); var websiteNavbarData = require('website.navbar'); var QWeb = core.qweb; var templateDef = null; var ThemeCustomizeDialog = Widget.extend({ template: 'website.theme_customize', events: { 'change input[data-xmlid],input[data-enable],input[data-disable]': 'change_selection', 'mousedown label:has(input[data-xmlid],input[data-enable],input[data-disable])': function (event) { var self = this; this.time_select = _.defer(function () { var input = $(event.target).find('input').length ? $(event.target).find('input') : $(event.target).parent().find('input'); self.on_select(input, event); }); }, 'click .close': 'close', 'click': 'click', }, willStart: function () { if (templateDef === null) { templateDef = this._rpc({ model: 'ir.ui.view', method: 'read_template', args: ['website.theme_customize', weContext.get()], }).then(function (data) { return QWeb.add_template(data); }); } return $.when(this._super.apply(this, arguments), templateDef); }, start: function () { var self = this; this.timer = null; this.reload = false; this.flag = false; this.active_select_tags(); this.$inputs = this.$('input[data-xmlid],input[data-enable],input[data-disable]'); setTimeout(function () {self.$el.addClass('in');}, 0); this.keydown_escape = function (event) { if (event.keyCode === 27) { self.close(); } }; $(document).on('keydown', this.keydown_escape); return this.load_xml_data().then(function () { self.flag = true; }); }, active_select_tags: function () { var uniqueID = 0; var self = this; var $selects = this.$('select:has(option[data-xmlid],option[data-enable],option[data-disable])'); $selects.each(function () { uniqueID++; var $select = $(this); var $options = $select.find('option[data-xmlid], option[data-enable], option[data-disable]'); $options.each(function () { var $option = $(this); var $input = $(''); $input.attr('id', $option.attr('id')); $input.attr('data-xmlid', $option.data('xmlid')); $input.attr('data-enable', $option.data('enable')); $input.attr('data-disable', $option.data('disable')); $option.removeAttr('id'); $option.data('input', $input); $input.on('update', function () { $option.attr('selected', $(this).prop('checked')); }); self.$el.append($input); }); $select.data('value', $options.first()); $options.first().attr('selected', true); }); $selects.change(function () { var $option = $(this).find('option:selected'); $(this).data('value').data('input').prop('checked', true).change(); $(this).data('value', $option); $option.data('input').change(); }); }, load_xml_data: function () { var self = this; $('#theme_error').remove(); return this._rpc({ route: '/website/theme_customize_get', params: { xml_ids: this.get_xml_ids(this.$inputs), }, }).done(function (data) { self.$inputs.filter('[data-xmlid=""]').prop('checked', true).change(); self.$inputs.filter('[data-xmlid]:not([data-xmlid=""])').each(function () { if (!_.difference(self.get_xml_ids($(this)), data[1]).length) { $(this).prop('checked', false).trigger('change', true); } if (!_.difference(self.get_xml_ids($(this)), data[0]).length) { $(this).prop('checked', true).trigger('change', true); } }); }).fail(function (d, error) { $('body').prepend($('
').text(error.data.message)); }); }, get_inputs: function (string) { return this.$inputs.filter('#'+string.split(/\s*,\s*/).join(', #')); }, get_xml_ids: function ($inputs) { var xml_ids = []; $inputs.each(function () { if ($(this).data('xmlid') && $(this).data('xmlid').length) { xml_ids = xml_ids.concat($(this).data('xmlid').split(/\s*,\s*/)); } }); return xml_ids; }, update_style: function (enable, disable, reload) { if (this.$el.hasClass('loading')) { return; } this.$el.addClass('loading'); if (!reload && session.debug !== 'assets') { var self = this; return this._rpc({ route: '/website/theme_customize', params: { enable: enable, disable: disable, get_bundle: true, }, }).then(function (bundleHTML) { var $links = $('link[href*=".assets_frontend"]'); var $newLinks = $(bundleHTML).filter('link'); var linksLoaded = $.Deferred(); var nbLoaded = 0; $newLinks.on('load', function (e) { if (++nbLoaded >= $newLinks.length) { linksLoaded.resolve(); } }); $newLinks.on('error', function (e) { linksLoaded.reject(); window.location.hash = 'theme=true'; window.location.reload(); }); $links.last().after($newLinks); return linksLoaded.then(function () { $links.remove(); self.$el.removeClass('loading'); }); }); } else { var href = '/website/theme_customize_reload'+ '?href='+encodeURIComponent(window.location.href)+ '&enable='+encodeURIComponent(enable.join(','))+ '&disable='+encodeURIComponent(disable.join(',')); window.location.href = href; return $.Deferred(); } }, enable_disable: function ($inputs, enable) { $inputs.each(function () { var check = $(this).prop('checked'); var $label = $(this).closest('label'); $(this).prop('checked', enable); if (enable) $label.addClass('checked'); else $label.removeClass('checked'); if (check !== enable) { $(this).change(); } }); }, change_selection: function (event, init_mode) { var self = this; clearTimeout(this.time_select); if (this.$el.hasClass('loading')) return; // prevent to change selection when css is loading var $option = $(event.target).is('input') ? $(event.target) : $('input', event.target), $options = $option, checked = $option.prop('checked'); if (checked) { var $inputs; if ($option.data('enable')) { $inputs = this.get_inputs($option.data('enable')); $options = $options.add($inputs.filter(':not(:checked)')); this.enable_disable($inputs, true); } if ($option.data('disable')) { $inputs = this.get_inputs($option.data('disable')); $options = $options.add($inputs.filter(':checked')); this.enable_disable($inputs, false); } $option.closest('label').addClass('checked'); } else { $option.closest('label').removeClass('checked'); } var $enable = this.$inputs.filter('[data-xmlid]:checked'); $enable.closest('label').addClass('checked'); var $disable = this.$inputs.filter('[data-xmlid]:not(:checked)'); $disable.closest('label').removeClass('checked'); var $sets = this.$inputs.filter('input[data-enable]:not([data-xmlid]), input[data-disable]:not([data-xmlid])'); $sets.each(function () { var $set = $(this); var checked = true; if ($set.data('enable')) { self.get_inputs($(this).data('enable')).each(function () { if (!$(this).prop('checked')) checked = false; }); } if ($set.data('disable')) { self.get_inputs($(this).data('disable')).each(function () { if ($(this).prop('checked')) checked = false; }); } if (checked) { $set.prop('checked', true).closest('label').addClass('checked'); } else { $set.prop('checked', false).closest('label').removeClass('checked'); } $set.trigger('update'); }); if (this.flag && $option.data('reload') && document.location.href.match(new RegExp( $option.data('reload') ))) { this.reload = true; } clearTimeout(this.timer); if (this.flag) { this.timer = _.defer(function () { if (!init_mode) self.on_select($options, event); self.update_style(self.get_xml_ids($enable), self.get_xml_ids($disable), self.reload); self.reload = false; }); } else { this.timer = _.defer(function () { if (!init_mode) self.on_select($options, event); self.reload = false; }); } }, /* Method call when the user change the selection or click on an input * @values: all changed inputs */ on_select: function ($inputs, event) { clearTimeout(this.time_select); }, click: function (event) { if (!$(event.target).closest('#theme_customize_modal > *').length) { this.close(); } }, close: function () { var self = this; $(document).off('keydown', this.keydown_escape); $('#theme_error').remove(); $('link[href*=".assets_"]').removeAttr('data-loading'); this.$el.removeClass('in'); this.$el.addClass('out'); setTimeout(function () {self.destroy();}, 500); } }); var ThemeCustomizeMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({ actions: _.extend({}, websiteNavbarData.WebsiteNavbarActionWidget.prototype.actions || {}, { customize_theme: '_openThemeCustomizeDialog', }), /** * Automatically opens the theme customization dialog if the corresponding * hash is in the page URL. * * @override */ start: function () { var def; if ((window.location.hash || '').indexOf('theme=true') > 0) { def = this._openThemeCustomizeDialog(); window.location.hash = ''; } return $.when(this._super.apply(this, arguments), def); }, //-------------------------------------------------------------------------- // Actions //-------------------------------------------------------------------------- /** * Instantiates and opens the theme customization dialog. * * @private * @returns {Deferred} */ _openThemeCustomizeDialog: function () { return new ThemeCustomizeDialog(this).appendTo(document.body); }, }); websiteNavbarData.websiteNavbarRegistry.add(ThemeCustomizeMenu, '#theme_customize'); return ThemeCustomizeDialog; });