[ADD] theme 13.0

This commit is contained in:
Design
2021-05-11 15:59:09 +02:00
committed by Jeremy Kersten
commit a2747ad88b
2859 changed files with 66469 additions and 0 deletions
@@ -0,0 +1,19 @@
odoo.define('theme_common.compatibility_editor', function (require) {
'use strict';
var sOptions = require('web_editor.snippets.options');
sOptions.registry.background.include({
/**
* @override
*/
background: function (previewMode, value, $opt) {
this._super.apply(this, arguments);
var customClass = this.$target.attr('class').match(/\b(bg-img-\d+)\b/);
if (customClass) {
this.$target.removeClass(customClass[1]);
}
},
});
});
@@ -0,0 +1,79 @@
odoo.define('theme_common.s_animated_boxes_editor', function (require) {
'use strict';
var s_options = require('web_editor.snippets.options');
s_options.registry.s_animated_boxes = s_options.Class.extend({
start: function () {
var self = this;
self.add_btn_edit_slide();
setTimeout(function () {
if (self.$target.find(".slide").length > 0) {
self.$overlay.data('$optionsSection').find(".createSlide").addClass("hide");
self.$overlay.data('$optionsSection').find(".deleteSlide").removeClass("hide");
self.$overlay.data('$optionsSection').find(".btn-showSlide").removeClass("hide");
} else {
self.$overlay.data('$optionsSection').find(".createSlide").removeClass("hide");
self.$overlay.data('$optionsSection').find(".deleteSlide").addClass("hide");
self.$overlay.data('$optionsSection').find(".btn-showSlide").addClass("hide");
}
}, 100);
},
add_btn_edit_slide: function () {
var self = this;
self.$overlay.data('$optionsSection').append('<a href="#" class="btn-showSlide" title="Lock slide" style="width: auto; padding: 0 5px;"><i class="fa fa-toggle-off"></i> Edit Slide</a> ');
self.$overlay.data('$optionsSection').on('click', '.btn-showSlide', _.bind(this.toggle_slide, this));
},
create_slide: function (previewMode, value, $li) {
var self = this,
slide = '<div class="slide editable bg-success animated text-center dur-200ms insetShadow" anim="o_anim_fade_in_down" del="0" dur="200"><div class="v-align"><h3>Your new slide</h3></div></div>';
self.$target.append(slide);
self.$overlay.data('$optionsSection').find(".btn-showSlide").removeClass("hide");
self.$overlay.data('$optionsSection').find(".createSlide").addClass("hide");
self.$overlay.data('$optionsSection').find(".deleteSlide").removeClass("hide");
},
delete_slide: function (previewMode, value, $li) {
var self = this;
self.$target.find(".slide").remove();
self.$overlay.data('$optionsSection').find(".btn-showSlide").addClass("hide");
self.$overlay.data('$optionsSection').find(".createSlide").removeClass("hide");
self.$overlay.data('$optionsSection').find(".deleteSlide").addClass("hide");
},
toggle_slide: function () {
var a = this.$overlay.data('$optionsSection').find(".btn-showSlide"),
i = a.find("i"),
t = this.$target,
s = t.find(".slide");
if (!t.hasClass("showSlide")) {
t.addClass("showSlide"); i.addClass("fa-toggle-on").removeClass("fa-toggle-off"); i.css("color", "#FFF");
s.addClass("visible");
} else {
t.removeClass("showSlide"); i.removeClass("fa-toggle-on").addClass("fa-toggle-off"); i.css("color", "");
s.removeClass("visible");
}
},
onFocus: function () {
this._adapt_items_height();
},
onBlur: function () {
this._adapt_items_height();
},
cleanForSave: function() {
this.$target.removeClass("showSlide")
.find(".slide").removeClass("visible");
this._adapt_items_height();
},
_adapt_items_height: function () {
var $items = this.$target.closest(".s_animated_boxes").find(".item");
var min_height = _.reduce($items.find(".v-align"), function (memo, item) {
return Math.max(memo, $(item).outerHeight(true) + 40);
}, 200);
$items.css("height", min_height);
},
});
});
@@ -0,0 +1,15 @@
odoo.define('theme_common.s_animated_boxes_frontend', function (require) {
'use strict';
var publicWidget = require('web.public.widget');
/**
* This is a fix for some apple devices.
* The slide of animated boxes widget is shown on hover or click on mobile
* devices, but iOS only activates :hover if the element targeted is
* clickable.
*/
publicWidget.registry._fixAnimatedBoxesAppleClick = publicWidget.registry._fixAppleCollapse.extend({
selector: '.s_animated_boxes .item',
});
});
@@ -0,0 +1,82 @@
odoo.define('theme_common.s_css_slider_editor', function (require) {
'use strict';
var s_options = require('web_editor.snippets.options');
s_options.registry.s_css_slider_slide = s_options.Class.extend({
newSlideUrl: "/web/image/theme_common.image_content_23",
start: function () {
var self = this;
self.reset();
this.trigger_up('widgets_start_request', {
editableMode: true,
$target: this.$target,
});
setTimeout(function () {
self.$overlay.data('$optionsSection').find(".js_s_css_slider_addSlide").on('click', function () { self.addSlide(); });
self.$overlay.data('$optionsSection').find(".js_s_css_slider_removeSlide").on('click', function () { self.removeSlide(); });
}, 100);
$(document.body).on("media-saved", function () {
self.resizeImgsEditor();
});
},
resizeImgsEditor: function () {
var self = this;
setTimeout(function () {
self.trigger_up('widgets_start_request', {
editableMode: true,
$target: self.$target,
});
});
},
reset: function () {
var self= this;
self.$target.find(".s_css_slider_pagination").remove().end()
.find("span").unbind("click.s_css");
},
addSlide: function () {
var self = this;
var $currentSlide = self.$target.find(".slider .slide.selected");
$currentSlide.clone().insertAfter($currentSlide).removeClass("selected");
_.defer(function () {
self.reset();
self.trigger_up('widgets_start_request', {
editableMode: true,
$target: self.$target,
});
});
},
removeSlide: function () {
var self = this;
var $currentSlide = self.$target.find(".slider .slide.selected");
$currentSlide.remove();
_.defer(function () {
self.reset();
self.trigger_up('widgets_start_request', {
editableMode: true,
$target: self.$target,
});
});
},
cleanForSave: function () {
var self = this;
self.$target
.find(".s_css_slider_pagination").remove().end()
.find(".navigation .prev").addClass("inactive").end()
.find(".navigation .next").removeClass("inactive").end()
.find(".slider .slide").removeClass("selected move-left").end()
.find(".slider .slide").first().addClass("selected");
},
});
});
@@ -0,0 +1,122 @@
odoo.define('theme_common.s_css_slider_frontend', function (require) {
'use strict';
var publicWidget = require('web.public.widget');
publicWidget.registry.s_css_slider = publicWidget.Widget.extend({
selector: ".s_css_slider",
disabledInEditableMode: false,
start: function () {
var self = this;
var $container = self.$target;
$container.find(".s_css_slider_pagination").remove();
// create slider pagination
var sliderPagination = self.createSliderPagination($container);
self.bindEvents($container, sliderPagination);
$(window).on("resize", function () {
self.resizeImgs($container);
}).trigger("resize");
return this._super.apply(this, arguments);
},
bindEvents: function ($container, sliderPagination) {
var self = this,
$next_btn = $container.find('.next'),
$prev_btn = $container.find('.prev');
$next_btn.on('click.s_css', function (e) {
self.nextSlide($container, sliderPagination);
});
$prev_btn.on('click.s_css', function (e) {
self.prevSlide($container, sliderPagination);
});
if ($container.hasClass("autoplay") && this.editableMode !== true) {
var interval;
var autoplay = function () {
interval = setInterval(function () {
if (!$next_btn.hasClass("inactive")) {
self.nextSlide($container, sliderPagination);
} else {
self.prevSlide($container, sliderPagination, 0);
}
}, 3000);
};
autoplay();
$container.hover(function () { clearInterval(interval); });
$container.mouseleave(function () { autoplay(); });
}
sliderPagination.on('click.s_css', function () {
var selectedDot = $(this);
if (!selectedDot.hasClass('selected')) {
var selectedPosition = selectedDot.index(),
activePosition = $container.find('.slider .selected').index();
if ( activePosition < selectedPosition) {
self.nextSlide($container, sliderPagination, selectedPosition);
} else {
self.prevSlide($container, sliderPagination, selectedPosition);
}
}
});
},
resizeImgs: function ($container) {
var cont_h = $container.height(),
imgs = $container.find(".slide img");
imgs.each(function () {
var $img = $(this),
img_h = $img.height();
if (img_h > cont_h) {
$img.css("width", "100%");
$img.css("margin-top", (cont_h - img_h)/2);
}
});
},
createSliderPagination: function ($container) {
var wrapper = $('<ul class="s_css_slider_pagination"></ul>').insertAfter($container.find('.navigation'));
$container.find('.slider .slide').each(function (index) {
var dotWrapper = (index === 0) ? $('<li class="selected"></li>') : $('<li></li>'),
dot = $('<a href="#0"></a>').appendTo(dotWrapper);
dotWrapper.appendTo(wrapper);
dot.text(index+1);
});
return wrapper.children('li');
},
nextSlide: function ($container, $pagination, $n) {
var self = this,
visibleSlide = $container.find('.slider .selected'),
navigationDot = $container.find('.s_css_slider_pagination .selected');
if (typeof $n === 'undefined') $n = visibleSlide.index() + 1;
visibleSlide.removeClass('selected');
$container.find('.slider .slide').eq($n).addClass('selected').prevAll().addClass('move-left');
navigationDot.removeClass('selected');
$pagination.eq($n).addClass('selected');
self.updateNavigation($container, $container.find('.slider .slide').eq($n));
},
prevSlide: function ($container, $pagination, $n) {
var self = this,
visibleSlide = $container.find('.slider .selected'),
navigationDot = $container.find('.s_css_slider_pagination .selected');
if (typeof $n === 'undefined') $n = visibleSlide.index() - 1;
visibleSlide.removeClass('selected');
$container.find('.slider .slide').eq($n).addClass('selected').removeClass('move-left').nextAll().removeClass('move-left');
navigationDot.removeClass('selected');
$pagination.eq($n).addClass('selected');
self.updateNavigation($container, $container.find('.slider .slide').eq($n));
},
updateNavigation: function ($container, $active) {
$container.find('.prev').toggleClass('inactive', $active.is(':first-child'));
$container.find('.next').toggleClass('inactive', $active.is(':last-child'));
},
});
});
@@ -0,0 +1,149 @@
odoo.define('theme_common.s_google_map_editor', function (require) {
'use strict';
var Dialog = require('web_editor.widget').Dialog;
var core = require('web.core');
var sOptions = require('web_editor.snippets.options');
var googleScriptLoaded = require('theme_common.s_google_map_frontend').googleScriptLoaded;
var _t = core._t;
sOptions.registry.map = sOptions.Class.extend({
xmlDependencies: ['/theme_common/static/src/xml/s_google_map_modal.xml'],
defaultLocation: '(50.854975,4.3753899)',
/**
* @override
*/
onBuilt: function () {
this._super.apply(this, arguments);
this.map('click', null, null);
},
//--------------------------------------------------------------------------
// Options
//--------------------------------------------------------------------------
/**
* Opens the customization dialog.
*
* @see this.selectClass for parameters
*/
map: function (previewMode, value, $opt) {
var self = this;
this.dialog = new Dialog(this, {
size: 'medium',
title: _t("Customize your map"),
buttons: [
{text: _t("Save"), classes: 'btn-primary', close: true, click: function () {
if (!this.$('#placeBk').val()) {
this.$('#placeBk').val(self.defaultLocation);
}
self.$target.attr({
'data-map-gps': this.$('#placeBk').val(),
'data-pin-style': this.$('#pin_style').val(),
'data-pin-address': this.$('#pin_address').val(),
});
self.trigger_up('widgets_start_request', {
editableMode: true,
$target: self.$target,
});
}},
{text: _t("Cancel"), close: true}
],
$content: $(core.qweb.render('theme_common.s_google_map_modal'))
});
this.dialog.opened().then((function () {
this.$('#pin_address').val(self.$target.attr('data-pin-address'));
this.$('#pin_style').val(self.$target.attr('data-pin-style'));
this.$('#placeBk').val(self.$target.attr('data-map-gps'));
var autocomplete = new google.maps.places.Autocomplete(this.$('#pin_address').get(0), {types: ['geocode']});
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var place = autocomplete.getPlace();
self.dialog.$('#placeBk').val(place.geometry ? place.geometry.location : self.defaultLocation);
});
}).bind(this.dialog));
googleScriptLoaded.then(function () {
self.dialog.open();
});
},
/**
* Adapts map's type.
*
* @see this.selectClass for parameters
*/
mapType: function (previewMode, value, $opt) {
this.$target.attr('data-map-type', value);
this.$target.attr('data-map-color', '');
this.trigger_up('widgets_start_request', {
editableMode: true,
$target: this.$target,
});
},
/**
* Adapts map's color.
*
* @see this.selectClass for parameters
*/
mapColor: function (previewMode, value, $opt) {
this.$target.attr('data-map-color', value);
this.trigger_up('widgets_start_request', {
editableMode: true,
$target: this.$target,
});
},
/**
* Adapts map's zoom.
*
* @see this.selectClass for parameters
*/
mapZoom: function (previewMode, value, $opt) {
this.$target.attr('data-map-zoom', value);
this.trigger_up('widgets_start_request', {
editableMode: true,
$target: this.$target,
});
},
/**
* Adapts map's location.
*
* @see this.selectClass for parameters
*/
mapGps: function (previewMode, value, $opt) {
this.$target.attr('data-map-gps', value);
this.trigger_up('widgets_start_request', {
editableMode: true,
$target: this.$target,
});
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* @override
*/
_setActive: function () {
this.$el.find('[data-map-type]')
.removeClass('active')
.filter('[data-map-type="' + this.$target.attr('data-map-type') + '"]')
.addClass('active');
this.$el.find('[data-map-color]')
.removeClass('active')
.filter('[data-map-color="' + this.$target.attr('data-map-color') + '"]')
.addClass('active');
this.$el.find('[data-map-zoom]')
.removeClass('active')
.filter('[data-map-zoom="' + this.$target.attr('data-map-zoom') + '"]')
.addClass('active');
this.$el.find('[data-map-gps]')
.removeClass('active')
.filter('[data-map-gps="' + this.$target.attr('data-map-gps') + '"]')
.addClass('active');
},
});
});
@@ -0,0 +1,146 @@
odoo.define('theme_common.s_google_map_frontend', function (require) {
'use strict';
var core = require('web.core');
var publicWidget = require('web.public.widget');
var googleScriptLoaded = $.Deferred();
var _t = core._t;
publicWidget.registry.s_google_map = publicWidget.Widget.extend({
selector: '.s_google_map',
disabledInEditableMode: false,
/**
* @override
*/
start: function () {
var self = this;
var defs = [this._super.apply(this, arguments)];
if (typeof google !== 'object' || typeof google.maps !== 'object') {
if (!publicWidget.registry.s_google_map.isScriptLoading) {
publicWidget.registry.s_google_map.isScriptLoading = true;
window.odoo_s_google_map_redraw_all = function odoo_s_google_map_redraw_all() {
self.trigger_up('widgets_start_request', {
editableMode: self.editableMode,
$target: $('section.s_google_map'),
});
publicWidget.registry.s_google_map.isScriptLoading = false;
googleScriptLoaded.resolve();
};
defs.push(this._rpc({
route: '/theme_common/google_maps_api_key',
}).then(function (data) {
var key_param = '';
var data_json = JSON.parse(data);
if (!data_json.google_maps_api_key) {
publicWidget.registry.s_google_map.isScriptLoading = false;
if (self.editableMode) {
self.$loadingWarning = $('<div/>', {
class: 'alert alert-warning alert-link',
}).append($('<a/>', {
href: "#",
text: _t("Cannot load google map, check your configuration !"),
})).click(function (e) {
window.location.href = "/web#action=website.action_website_configuration";
});
self.$('.map_container').append(self.$loadingWarning);
}
return;
}
key_param = '&key=' + data_json.google_maps_api_key;
$('head').append($('<script/>', {
type: "text/javascript",
src: "https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places&callback=odoo_s_google_map_redraw_all" + key_param,
}));
}));
}
return $.when.apply($, defs);
}
// Define a default map's colors set
var std = [];
new google.maps.StyledMapType(std, {name: "Std Map"});
// Default options, will be overwritten by the user
var myOptions = {
zoom: 12,
center: new google.maps.LatLng(50.854975,4.3753899),
mapTypeId: google.maps.MapTypeId.ROADMAP,
panControl: false,
zoomControl: false,
mapTypeControl: false,
streetViewControl: false,
scrollwheel: false,
mapTypeControlOptions: {
mapTypeIds: [google.maps.MapTypeId.ROADMAP, 'map_style']
}
};
// Render Map
var mapC = this.$target.find('.map_container');
var map = new google.maps.Map(mapC.get(0), myOptions);
// Update GPS position
var p = this.$target.attr('data-map-gps').substring(1).slice(0, -1).split(',');
var gps = new google.maps.LatLng(p[0], p[1]);
map.setCenter(gps);
// Update Map on screen resize
google.maps.event.addDomListener(window, 'resize', function () {
map.setCenter(gps);
});
// Create Marker & Infowindow
if (this.$target.attr('data-pin-style') === "flat") {
new google.maps.Marker({
map: map,
animation: google.maps.Animation.DROP,
position: new google.maps.LatLng(p[0],p[1]),
icon: "/theme_common/static/src/img/snippets/s_google_map_marker.png",
});
} else {
new google.maps.Marker({
map: map,
animation: google.maps.Animation.DROP,
position: new google.maps.LatLng(p[0], p[1])
});
}
map.setMapTypeId(google.maps.MapTypeId[this.$target.attr('data-map-type')]); // Update Map Type
map.setZoom(parseInt(this.$target.attr('data-map-zoom'))); // Update Map Zoom
// Update Map Color
if (this.$target.attr('data-map-color') !== "") {
var mapColor = eval("this." + this.$target.attr('data-map-color'));
var thisMap = new google.maps.StyledMapType(mapColor, {name: "Styled Map"});
map.mapTypes.set('map_style', thisMap);
map.setMapTypeId('map_style');
}
return $.when.apply($, defs);
},
/**
* @override
*/
destroy: function () {
this._super.apply(this, arguments);
if (this.$loadingWarning) {
this.$loadingWarning.remove();
}
},
});
// This allows to save if the google maps script is already loading or not.
// This script cannot be loaded 2 times, so if we have 2 snippets in the same
// page we don't want to load the script 2 times.
// And we cannot put the script in an asset because we don't want to load it
// on each page, but only on pages with a google maps snippet...
publicWidget.registry.s_google_map.prototype.isScriptLoading = false;
return {
googleScriptLoaded: googleScriptLoaded,
};
});
@@ -0,0 +1,30 @@
odoo.define('theme_common.s_mini_nav_bar', function (require) {
'use strict';
var publicWidget = require('web.public.widget');
publicWidget.registry.miniNavbarScroll = publicWidget.Widget.extend({
selector: '.s_mini_nav_bar a[href*="#"]:not([href="#"])',
events: {
'click': '_onClick',
},
//----------------------------------------------------------------------
// Handlers
//----------------------------------------------------------------------
/**
* Called on click on the mini navbar link -> scroll to the section.
*
* @private
*/
_onClick: function (ev) {
var index = $(this).parent().index();
var target = $('.o_scroll_nav').get(index);
if (target) {
ev.preventDefault();
$('html,body').animate({ scrollTop: $(target).offset().top }, 1000);
}
},
});
});
@@ -0,0 +1,45 @@
odoo.define('theme_common.s_progress_bar', function (require) {
'use strict';
var s_options = require('web_editor.snippets.options');
s_options.registry.progress = s_options.Class.extend({
start: function () {
if (this.$overlay) {
this.bind_move_progress();
}
this._super();
},
bind_move_progress: function () {
var self = this;
var $e = this.$overlay.find(".o_handle.e").removeClass("readonly");
var $parent = this.$target.parent();
var pos = $parent.offset();
var width = $parent.width();
var time;
function move(event) {
clearTimeout(time);
time = setTimeout(function () {
var value = (event.clientX - pos.left)/width*100 | 0;
if (value > 100 ) value = 100;
if (value < 0 ) value = 0;
self.$target.text( self.$target.text().replace(/[0-9]+/, value) );
self.$target.attr("data-value", value);
if (value < 3 ) value = 3;
self.$target.css("width", value + "%");
},5);
}
$e.on("mousedown", function () {
self.$overlay.addClass('d-none');
$(document)
.on("mousemove", move)
.one("mouseup", function () {
self.$overlay.removeClass('d-none');
$(document).off("mousemove", move);
self.trigger_up('cover_update');
});
});
},
});
});
@@ -0,0 +1,40 @@
odoo.define('theme_common.s_showcase_editor.js', function (require) {
'use strict';
var s_options = require('web_editor.snippets.options');
s_options.registry.s_showcase = s_options.Class.extend({
onClone: function () {
this._reset_alignment();
},
onRemove: function () {
this._reset_alignment(this.$target);
},
_reset_alignment: function ($exclude) {
var $features = this.$target.closest(".s_showcase").find(".feature").not($exclude);
// Remove classes used in the previus implementation
$features.removeClass('offset-md-2');
// Wait until the $clone element is in place
setTimeout(function () {
$features.unwrap('.row');
_.each($features, function (feat, i) {
var even = (i % 2 === 0);
$(feat)
.toggleClass('text-right', even)
.toggleClass('text-left', !even)
.toggleClass('offset-lg-2', !even);
});
// Re-wrap in rows
for (var i = 0; i < $features.length; i+=2) {
$features.slice(i, i + 2).wrapAll("<div class='row'/>");
}
}, 100);
}
});
});
@@ -0,0 +1,43 @@
odoo.define('theme_common.s_showcase_slider_editor.js', function (require) {
'use strict';
var s_options = require('web_editor.snippets.options');
require("theme_common.s_showcase_slider_frontend");
s_options.registry.s_showcase_slider = s_options.Class.extend({
start: function () {
this._super.apply(this, arguments);
this.$target.on("transitionIsFinished", (function () {
this.trigger_up('cover_update');
}).bind(this));
_.delay((function () { // FIXME ...
this.$overlay.data('$optionsSection').find(".js_s_ss_addSlide").on('click', this.addSlide.bind(this));
this.$overlay.data('$optionsSection').find(".js_s_ss_removeSlide").on('click', this.removeSlide.bind(this));
}).bind(this), 100);
},
resetSlides: function (active) {
this.trigger_up('widgets_start_request', {
editableMode: true,
$target: this.$target,
});
this.$target.toggleClass("active", !!active);
},
addSlide: function () {
var $currentSlide = this.$target.find(".s_ss_slider > .selected");
$currentSlide.after("<li><img class=\"o_not-animable\" src=\"/web/image/theme_common.image_content_23\"/></li>");
this.resetSlides(true);
},
removeSlide: function () {
if (this.$target.find(".s_ss_slider").children().length <= 1) return;
var $currentSlide = this.$target.find(".s_ss_slider > .selected");
$currentSlide.remove();
this.resetSlides(true);
},
});
});
@@ -0,0 +1,130 @@
odoo.define("theme_common.s_showcase_slider_frontend", function (require) {
"use strict";
var publicWidget = require('web.public.widget');
publicWidget.registry.s_showcase_slider = publicWidget.Widget.extend({
selector: ".s_showcase_slider",
start: function () {
_.defer(this.bindEvents.bind(this)); // FIXME delayed to counter a web_editor bug which off all click event
this.createPagination();
return this._super.apply(this, arguments);
},
destroy: function () {
this._super.apply(this, arguments);
_.defer(this.unbindEvents.bind(this)); // FIXME delayed to counter a web_editor bug which off all click event
this.destroyPagination();
this.$target.removeClass("active");
},
bindEvents: function () {
// Enlarge image on click if not already enlarged
this.$target.on("click.s_showcase_slider", ".s_ss_slider", (function (e) {
if (this.$target.hasClass("active")) return;
this.$target
.addClass("active")
.one("webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend", (function () {
$("body, html").animate({
scrollTop: this.$target.offset().top - 70
}, 200);
this.$target.trigger("transitionIsFinished");
}).bind(this));
}).bind(this));
// Close the enlarged image on close icon click
this.$target.on("click.s_showcase_slider", ".s_ss_close", (function (e) {
this.$target.removeClass("active");
}).bind(this));
// Handle click navigation
this.$target.on("click.s_showcase_slider", ".s_ss_prev", this.prevSlide.bind(this));
this.$target.on("click.s_showcase_slider", ".s_ss_next", this.nextSlide.bind(this));
this.$target.on("click.s_showcase_slider", ".s_ss_slider_pagination > li > a", (function (e) {
e.preventDefault();
var $selectedDot = $(e.currentTarget).parent();
if ($selectedDot.hasClass("selected")) return;
this.changeSlide($selectedDot.index());
}).bind(this));
// Keyboard slider navigation
$(document).on("keyup.s_showcase_slider", (function (e) {
if (!this.$target.hasClass("active")) return;
switch (e.which) {
case $.ui.keyCode.LEFT:
this.prevSlide();
break;
case $.ui.keyCode.RIGHT:
this.nextSlide();
break;
case $.ui.keyCode.ESCAPE:
this.$target.removeClass("active");
break;
}
}).bind(this));
},
unbindEvents: function () {
this.$target.off(".s_showcase_slider");
$(document).off(".s_showcase_slider");
},
createPagination: function () { // FIXME pagination should be saved with editor but keep this for compatibility
this.$target.find(".s_ss_slider_pagination").remove(); // Remove saved-with-editor pagination
this.$pagination = $("<ul/>", {class: "s_ss_slider_pagination"});
this.$pagination.insertAfter(this.$target.find(".s_ss_slider_navigation"));
var nbSlides = this.$target.find(".s_ss_slider").children().length;
for (var i = 0 ; i < nbSlides ; i++) {
this.$pagination.append("<li><a href=\"#\"></a></li>");
}
this.$pagination.children().eq(this.getCurrentIndex()).addClass("selected");
},
destroyPagination: function () {
if (this.$pagination) {
this.$pagination.remove();
this.$pagination = null;
}
},
prevSlide: function () {
var nbSlides = this.$target.find(".s_ss_slider").children().length;
var currentIndex = this.getCurrentIndex();
this.changeSlide(currentIndex > 0 ? (currentIndex - 1) : (nbSlides - 1));
},
nextSlide: function () {
var nbSlides = this.$target.find(".s_ss_slider").children().length;
var currentIndex = this.getCurrentIndex();
this.changeSlide((currentIndex + 1) % nbSlides);
},
getCurrentIndex: function () {
return this.$target.find(".s_ss_slider > .selected").index();
},
changeSlide: function (n) {
var $slides = this.$target.find(".s_ss_slider > li").removeClass("selected");
this.$target.find(".s_ss_slider_pagination > li").removeClass("selected");
var $slide = $slides.eq(n).addClass("selected");
$slides.removeClass("move-left");
$slide.prevAll().addClass("move-left");
this.$pagination.children().eq(n).addClass("selected");
this.updateNavigation();
},
updateNavigation: function () {
var $active = this.$target.find(".s_ss_slider > .selected");
this.$target.find(".s_ss_prev").toggleClass("inactive", $active.is(":first-child"));
this.$target.find(".s_ss_next").toggleClass("inactive", $active.is(":last-child"));
},
});
});